diff options
Diffstat (limited to 'debian/perl-framework/c-modules/test_apr_uri')
-rw-r--r-- | debian/perl-framework/c-modules/test_apr_uri/mod_test_apr_uri.c | 354 |
1 files changed, 354 insertions, 0 deletions
diff --git a/debian/perl-framework/c-modules/test_apr_uri/mod_test_apr_uri.c b/debian/perl-framework/c-modules/test_apr_uri/mod_test_apr_uri.c new file mode 100644 index 0000000..195e1ba --- /dev/null +++ b/debian/perl-framework/c-modules/test_apr_uri/mod_test_apr_uri.c @@ -0,0 +1,354 @@ +#define HTTPD_TEST_REQUIRE_APACHE 2 + +#if CONFIG_FOR_HTTPD_TEST + +<Location /test_apr_uri> + SetHandler test-apr-uri +</Location> + +#endif + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2004 The Apache Software Foundation. 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. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" 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 name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``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 SOFTWARE FOUNDATION 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 Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + * Portions of this software are based upon public domain software + * originally written at the National Center for Supercomputing Applications, + * University of Illinois, Urbana-Champaign. + */ + +/* + * This module is intended to test the apr_uri routines by parsing a + * bunch of urls and comparing the results with what we expect to + * see. + * + * Usage: + * + * <Location /test-apr-uri> + * SetHandler test-apr-uri + * </Location> + * + * Then make a request to /test-apr-uri. An html apr_table_t 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 presence, 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; + apr_pool_t *sub; + char *input_uri; + char *strp; + apr_uri_t result; + unsigned expect; + int status; + unsigned failures; + + failures = 0; + + input_uri = apr_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; + + apr_pool_create_ex(&sub, r->pool, NULL, NULL); + status = apr_uri_parse(sub, input_uri, &result); + if (status == APR_SUCCESS) { +#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 != APR_SUCCESS) { + 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; + } + apr_pool_destroy(sub); + } + return failures; +} + +static int test_apr_uri_handler(request_rec *r) +{ + unsigned total_failures; + int i; + + r->allowed |= (AP_METHOD_BIT << M_GET); + if (r->method_number != M_GET) + return DECLINED; + + if (strcmp(r->handler, "test-apr-uri")) { + return DECLINED; + } + + r->content_type = "text/html"; + + ap_rputs( +DOCTYPE_HTML_2_0 "\n\ +<html><body>\n\ +<p>Key:\n\ +<dl>\n\ +<dt>row\n\ +<dd>entry number in the uri_tests array\n\ +<dt>u\n\ +<dd>fields under test\n\ +<dt>expected\n\ +<dd>fields expected in the result\n\ +<dt>status\n\ +<dd>response from parse_uri_components, or 500 if unexpected results\n\ +<dt>input uri\n\ +<dd>the uri given to parse_uri_components\n\ +</dl>\n\ +<p>The remaining fields are the pieces returned from parse_uri_components, and\n\ +the values we expected for each piece (resp.).\n\ +<p>Only failures are displayed.\n\ +<p>\n\ +<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 void test_apr_uri_register_hooks(apr_pool_t *p) +{ + ap_hook_handler(test_apr_uri_handler, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA test_apr_uri_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-dir config structures */ + NULL, /* merge per-dir config structures */ + NULL, /* create per-server config structures */ + NULL, /* merge per-server config structures */ + NULL, /* table of config file commands */ + test_apr_uri_register_hooks /* register hooks */ +}; |