summaryrefslogtreecommitdiffstats
path: root/debian/perl-framework/c-modules/test_apr_uri/mod_test_apr_uri.c
diff options
context:
space:
mode:
Diffstat (limited to 'debian/perl-framework/c-modules/test_apr_uri/mod_test_apr_uri.c')
-rw-r--r--debian/perl-framework/c-modules/test_apr_uri/mod_test_apr_uri.c354
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 */
+};