mirror of
https://github.com/apache/httpd.git
synced 2025-09-01 02:02:06 +03:00
Apache 1.3.9 baseline for the Apache 2.0 repository.
Obtained from: Apache 1.3.9 (minus unused files), tag APACHE_1_3_9 Submitted by: Apache Group git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@83751 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
354
modules/test/mod_test_util_uri.c
Normal file
354
modules/test/mod_test_util_uri.c
Normal file
@@ -0,0 +1,354 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-1999 The Apache Group. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the Apache Group
|
||||
* for use in the Apache HTTP server project (http://www.apache.org/)."
|
||||
*
|
||||
* 4. The names "Apache Server" and "Apache Group" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache"
|
||||
* nor may "Apache" appear in their names without prior written
|
||||
* permission of the Apache Group.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the Apache Group
|
||||
* for use in the Apache HTTP server project (http://www.apache.org/)."
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Group and was originally based
|
||||
* on public domain software written at the National Center for
|
||||
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
|
||||
* For more information on the Apache Group and the Apache HTTP server
|
||||
* project, please see <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This module is intended to test the util_uri routines by parsing a
|
||||
* bunch of urls and comparing the results with what we expect to
|
||||
* see.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* <Location /test-util-uri>
|
||||
* SetHandler test-util-uri
|
||||
* </Location>
|
||||
*
|
||||
* Then make a request to /test-util-uri. An html table of errors will
|
||||
* be output... and a total count of errors.
|
||||
*/
|
||||
|
||||
#include "httpd.h"
|
||||
#include "http_protocol.h"
|
||||
#include "http_config.h"
|
||||
#include "http_main.h"
|
||||
|
||||
typedef struct {
|
||||
const char *scheme;
|
||||
const char *user;
|
||||
const char *password;
|
||||
const char *hostname;
|
||||
const char *port_str;
|
||||
const char *path;
|
||||
const char *query;
|
||||
const char *fragment;
|
||||
} test_uri_t;
|
||||
|
||||
#define T_scheme 0x01
|
||||
#define T_user 0x02
|
||||
#define T_password 0x04
|
||||
#define T_hostname 0x08
|
||||
#define T_port_str 0x10
|
||||
#define T_path 0x20
|
||||
#define T_query 0x40
|
||||
#define T_fragment 0x80
|
||||
#define T_MAX 0x100
|
||||
|
||||
/* The idea is that we list here a bunch of url pieces that we want
|
||||
* stitched together in every way that's valid.
|
||||
*/
|
||||
static const test_uri_t uri_tests[] = {
|
||||
{ "http", "userid", "passwd", "hostname.goes.here", "80", "/path/goes/here", "query-here", "frag-here" },
|
||||
{ "http", "", "passwd", "hostname.goes.here", "80", "/path/goes/here", "query-here", "frag-here" },
|
||||
{ "http", "userid", "", "hostname.goes.here", "80", "/path/goes/here", "query-here", "frag-here" },
|
||||
{ "http", "userid", "passwd", "", "80", "/path/goes/here", "query-here", "frag-here" },
|
||||
{ "http", "userid", "passwd", "hostname.goes.here", "", "/path/goes/here", "query-here", "frag-here" },
|
||||
#if 0
|
||||
/* An empty path means two different things depending on whether this is a
|
||||
* relative or an absolute uri... consider <a href="#frag"> versus "GET
|
||||
* http://hostname HTTP/1.1". So this is why parse_uri_components returns
|
||||
* a NULL for path when it doesn't find one, instead of returning an empty
|
||||
* string.
|
||||
*
|
||||
* We don't really need to test it explicitly since path has no explicit
|
||||
* character that indicates its precense, and so we test empty paths all
|
||||
* the time by varying T_path in the loop. It would just cost us extra
|
||||
* code to special case the empty path string...
|
||||
*/
|
||||
{ "http", "userid", "passwd", "hostname.goes.here", "80", "", "query-here", "frag-here" },
|
||||
#endif
|
||||
{ "http", "userid", "passwd", "hostname.goes.here", "80", "/path/goes/here", "", "frag-here" },
|
||||
{ "http", "userid", "passwd", "hostname.goes.here", "80", "/path/goes/here", "query-here", "" },
|
||||
{ "https", "user@d", "pa:swd", "hostname.goes.here.", "", "/~path/goes/here", "query&query?crud", "frag-here?baby" }
|
||||
|
||||
};
|
||||
|
||||
static char *my_stpcpy(char *d, const char *s)
|
||||
{
|
||||
while((*d = *s)) {
|
||||
++d;
|
||||
++s;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
/* return the number of failures */
|
||||
static unsigned iterate_pieces(request_rec *r, const test_uri_t *pieces, int row)
|
||||
{
|
||||
unsigned u;
|
||||
pool *sub;
|
||||
char *input_uri;
|
||||
char *strp;
|
||||
uri_components result;
|
||||
unsigned expect;
|
||||
int status;
|
||||
unsigned failures;
|
||||
|
||||
failures = 0;
|
||||
|
||||
input_uri = ap_palloc(r->pool,
|
||||
strlen(pieces->scheme) + 3
|
||||
+ strlen(pieces->user) + 1
|
||||
+ strlen(pieces->password) + 1
|
||||
+ strlen(pieces->hostname) + 1
|
||||
+ strlen(pieces->port_str) + 1
|
||||
+ strlen(pieces->path) +
|
||||
+ strlen(pieces->query) + 1
|
||||
+ strlen(pieces->fragment) + 1
|
||||
+ 1);
|
||||
|
||||
for (u = 0; u < T_MAX; ++u) {
|
||||
strp = input_uri;
|
||||
expect = 0;
|
||||
|
||||
/* a scheme requires a hostinfo and vice versa */
|
||||
/* a hostinfo requires a hostname */
|
||||
if (u & (T_scheme|T_user|T_password|T_hostname|T_port_str)) {
|
||||
expect |= T_scheme;
|
||||
strp = my_stpcpy(strp, pieces->scheme);
|
||||
*strp++ = ':';
|
||||
*strp++ = '/';
|
||||
*strp++ = '/';
|
||||
/* can't have password without user */
|
||||
if (u & (T_user|T_password)) {
|
||||
expect |= T_user;
|
||||
strp = my_stpcpy(strp, pieces->user);
|
||||
if (u & T_password) {
|
||||
expect |= T_password;
|
||||
*strp++ = ':';
|
||||
strp = my_stpcpy(strp, pieces->password);
|
||||
}
|
||||
*strp++ = '@';
|
||||
}
|
||||
expect |= T_hostname;
|
||||
strp = my_stpcpy(strp, pieces->hostname);
|
||||
if (u & T_port_str) {
|
||||
expect |= T_port_str;
|
||||
*strp++ = ':';
|
||||
strp = my_stpcpy(strp, pieces->port_str);
|
||||
}
|
||||
}
|
||||
if (u & T_path) {
|
||||
expect |= T_path;
|
||||
strp = my_stpcpy(strp, pieces->path);
|
||||
}
|
||||
if (u & T_query) {
|
||||
expect |= T_query;
|
||||
*strp++ = '?';
|
||||
strp = my_stpcpy(strp, pieces->query);
|
||||
}
|
||||
if (u & T_fragment) {
|
||||
expect |= T_fragment;
|
||||
*strp++ = '#';
|
||||
strp = my_stpcpy(strp, pieces->fragment);
|
||||
}
|
||||
*strp = 0;
|
||||
|
||||
sub = ap_make_sub_pool(r->pool);
|
||||
status = ap_parse_uri_components(sub, input_uri, &result);
|
||||
if (status == HTTP_OK) {
|
||||
#define CHECK(f) \
|
||||
if ((expect & T_##f) \
|
||||
&& (result.f == NULL || strcmp(result.f, pieces->f))) { \
|
||||
status = HTTP_INTERNAL_SERVER_ERROR; \
|
||||
} \
|
||||
else if (!(expect & T_##f) && result.f != NULL) { \
|
||||
status = HTTP_INTERNAL_SERVER_ERROR; \
|
||||
}
|
||||
CHECK(scheme)
|
||||
CHECK(user)
|
||||
CHECK(password)
|
||||
CHECK(hostname)
|
||||
CHECK(port_str)
|
||||
CHECK(path)
|
||||
CHECK(query)
|
||||
CHECK(fragment)
|
||||
#undef CHECK
|
||||
}
|
||||
if (status != HTTP_OK) {
|
||||
ap_rprintf(r, "<tr><td>%d</td><td>0x%02x</td><td>0x%02x</td><td>%d</td><td>\"%s\"</td>", row, u, expect, status, input_uri);
|
||||
#define DUMP(f) \
|
||||
if (result.f) { \
|
||||
ap_rvputs(r, "<td>\"", result.f, "\"<br>", NULL); \
|
||||
} \
|
||||
else { \
|
||||
ap_rputs("<td>NULL<br>", r); \
|
||||
} \
|
||||
if (expect & T_##f) { \
|
||||
ap_rvputs(r, "\"", pieces->f, "\"</td>", NULL); \
|
||||
} \
|
||||
else { \
|
||||
ap_rputs("NULL</td>", r); \
|
||||
}
|
||||
DUMP(scheme);
|
||||
DUMP(user);
|
||||
DUMP(password);
|
||||
DUMP(hostname);
|
||||
DUMP(port_str);
|
||||
DUMP(path);
|
||||
DUMP(query);
|
||||
DUMP(fragment);
|
||||
#undef DUMP
|
||||
ap_rputs("</tr>\n", r);
|
||||
++failures;
|
||||
}
|
||||
ap_destroy_pool(sub);
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int test_util_uri(request_rec *r)
|
||||
{
|
||||
unsigned total_failures;
|
||||
int i;
|
||||
|
||||
r->allowed |= (1 << M_GET);
|
||||
if (r->method_number != M_GET)
|
||||
return DECLINED;
|
||||
|
||||
r->content_type = "text/html";
|
||||
ap_send_http_header(r);
|
||||
if(r->header_only) {
|
||||
return 0;
|
||||
}
|
||||
ap_hard_timeout("test_util_uri", r);
|
||||
|
||||
ap_rputs(
|
||||
DOCTYPE_HTML_2_0 "
|
||||
<html><body>
|
||||
<p>Key:
|
||||
<dl>
|
||||
<dt>row
|
||||
<dd>entry number in the uri_tests array
|
||||
<dt>u
|
||||
<dd>fields under test
|
||||
<dt>expected
|
||||
<dd>fields expected in the result
|
||||
<dt>status
|
||||
<dd>response from parse_uri_components, or 500 if unexpected results
|
||||
<dt>input uri
|
||||
<dd>the uri given to parse_uri_components
|
||||
</dl>
|
||||
<p>The remaining fields are the pieces returned from parse_uri_components, and
|
||||
the values we expected for each piece (resp.).
|
||||
<p>Only failures are displayed.
|
||||
<p>
|
||||
<table><tr><th>row</th><th>u</th><th>expect</th><th>status</th><th>input uri</th>", r);
|
||||
#define HEADER(f) ap_rprintf(r, "<th>" #f "<br>0x%02x</th>", T_##f)
|
||||
HEADER(scheme);
|
||||
HEADER(user);
|
||||
HEADER(password);
|
||||
HEADER(hostname);
|
||||
HEADER(port_str);
|
||||
HEADER(path);
|
||||
HEADER(query);
|
||||
HEADER(fragment);
|
||||
#undef HEADER
|
||||
|
||||
if (r->args) {
|
||||
i = atoi(r->args);
|
||||
total_failures = iterate_pieces(r, &uri_tests[i], i);
|
||||
}
|
||||
else {
|
||||
total_failures = 0;
|
||||
for (i = 0; i < sizeof(uri_tests) / sizeof(uri_tests[0]); ++i) {
|
||||
total_failures += iterate_pieces(r, &uri_tests[i], i);
|
||||
if (total_failures > 256) {
|
||||
ap_rprintf(r, "</table>\n<b>Stopped early to save your browser "
|
||||
"from certain death!</b>\nTOTAL FAILURES = %u\n",
|
||||
total_failures);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
ap_rprintf(r, "</table>\nTOTAL FAILURES = %u\n", total_failures);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static const handler_rec test_util_uri_handlers[] =
|
||||
{
|
||||
{"test-util-uri", test_util_uri},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
module test_util_uri_module = {
|
||||
STANDARD_MODULE_STUFF,
|
||||
NULL, /* initializer */
|
||||
NULL, /* dir config creater */
|
||||
NULL, /* dir merger --- default is to override */
|
||||
NULL, /* server config */
|
||||
NULL, /* merge server config */
|
||||
NULL, /* command table */
|
||||
test_util_uri_handlers, /* handlers */
|
||||
NULL, /* filename translation */
|
||||
NULL, /* check_user_id */
|
||||
NULL, /* check auth */
|
||||
NULL, /* check access */
|
||||
NULL, /* type_checker */
|
||||
NULL, /* fixups */
|
||||
NULL, /* logger */
|
||||
NULL /* header parser */
|
||||
};
|
Reference in New Issue
Block a user