summaryrefslogtreecommitdiffstats
path: root/debian/perl-framework/c-modules
diff options
context:
space:
mode:
Diffstat (limited to 'debian/perl-framework/c-modules')
-rw-r--r--debian/perl-framework/c-modules/authany/mod_authany.c172
-rw-r--r--debian/perl-framework/c-modules/client_add_filter/mod_client_add_filter.c54
-rw-r--r--debian/perl-framework/c-modules/eat_post/mod_eat_post.c61
-rw-r--r--debian/perl-framework/c-modules/echo_post/mod_echo_post.c102
-rw-r--r--debian/perl-framework/c-modules/echo_post_chunk/mod_echo_post_chunk.c93
-rw-r--r--debian/perl-framework/c-modules/fold/mod_fold.c33
-rw-r--r--debian/perl-framework/c-modules/httpd_test_util.c44
-rw-r--r--debian/perl-framework/c-modules/input_body_filter/mod_input_body_filter.c184
-rw-r--r--debian/perl-framework/c-modules/list_modules/mod_list_modules.c38
-rw-r--r--debian/perl-framework/c-modules/memory_track/mod_memory_track.c45
-rw-r--r--debian/perl-framework/c-modules/nntp_like/mod_nntp_like.c181
-rw-r--r--debian/perl-framework/c-modules/random_chunk/mod_random_chunk.c182
-rw-r--r--debian/perl-framework/c-modules/test_apr_uri/mod_test_apr_uri.c354
-rw-r--r--debian/perl-framework/c-modules/test_pass_brigade/mod_test_pass_brigade.c104
-rw-r--r--debian/perl-framework/c-modules/test_rwrite/mod_test_rwrite.c66
-rw-r--r--debian/perl-framework/c-modules/test_session/mod_test_session.c348
-rw-r--r--debian/perl-framework/c-modules/test_ssl/mod_test_ssl.c171
-rw-r--r--debian/perl-framework/c-modules/test_utilities/mod_test_utilities.c48
18 files changed, 2280 insertions, 0 deletions
diff --git a/debian/perl-framework/c-modules/authany/mod_authany.c b/debian/perl-framework/c-modules/authany/mod_authany.c
new file mode 100644
index 0000000..a5e146c
--- /dev/null
+++ b/debian/perl-framework/c-modules/authany/mod_authany.c
@@ -0,0 +1,172 @@
+#if CONFIG_FOR_HTTPD_TEST
+
+Alias /authany @DocumentRoot@
+<Location /authany>
+ require user any-user
+ AuthType Basic
+ AuthName authany
+ <IfDefine !APACHE1>
+ <IfVersion >= 2.3>
+ AuthBasicProvider any
+ </IfVersion>
+ </IfDefine>
+</Location>
+
+#endif
+
+#include "ap_mmn.h"
+
+/* do not accept empty "" strings */
+#define strtrue(s) (s && *s)
+
+#if AP_MODULE_MAGIC_AT_LEAST(20060110, 0)
+
+#include "ap_provider.h"
+#include "mod_auth.h"
+
+static authn_status authn_check_password(request_rec *r, const char *user,
+ const char *password)
+{
+ return strtrue(r->user) && strcmp(r->user, "guest") == 0
+ ? AUTH_GRANTED : AUTH_DENIED;
+}
+
+static const authn_provider authn_any_provider =
+{
+ &authn_check_password
+};
+
+static authz_status any_check_authorization(request_rec *r,
+ const char *requirement,
+ const void *dummy)
+{
+#if AP_MODULE_MAGIC_AT_LEAST(20100714,0)
+ if (!r->user)
+ return AUTHZ_DENIED_NO_USER;
+#endif
+
+ return strtrue(r->user) && strcmp(requirement, "any-user") == 0
+ ? AUTHZ_GRANTED : AUTHZ_DENIED;
+}
+
+static const authz_provider authz_any_provider =
+{
+ &any_check_authorization
+};
+
+static void extra_hooks(apr_pool_t *p)
+{
+ ap_register_provider(p, AUTHN_PROVIDER_GROUP,
+ "any", "0", &authn_any_provider);
+ ap_register_provider(p, AUTHZ_PROVIDER_GROUP,
+ "user", "0", &authz_any_provider);
+}
+
+#define APACHE_HTTPD_TEST_EXTRA_HOOKS extra_hooks
+
+#include "apache_httpd_test.h"
+
+#else /* < 2.3 */
+
+#ifdef APACHE2
+
+#include "apr_pools.h"
+
+static void extra_hooks(apr_pool_t *);
+
+#define APACHE_HTTPD_TEST_EXTRA_HOOKS extra_hooks
+
+#else
+
+#define APACHE_HTTPD_TEST_HOOK_ORDER APR_HOOK_FIRST
+#define APACHE_HTTPD_TEST_CHECK_USER_ID authany_handler
+#define APACHE_HTTPD_TEST_AUTH_CHECKER require_any_user
+
+#endif
+
+#include "apache_httpd_test.h"
+
+static int require_any_user(request_rec *r)
+{
+ const apr_array_header_t *requires = ap_requires(r);
+ require_line *rq;
+ int x;
+
+ if (!requires) {
+ return DECLINED;
+ }
+
+ rq = (require_line *) requires->elts;
+
+ for (x = 0; x < requires->nelts; x++) {
+ const char *line, *requirement;
+
+ line = rq[x].requirement;
+ requirement = ap_getword(r->pool, &line, ' ');
+
+ if ((strcmp(requirement, "user") == 0) &&
+ (strcmp(line, "any-user") == 0))
+ {
+ return OK;
+ }
+ }
+
+ return DECLINED;
+}
+
+static int authany_handler(request_rec *r)
+{
+ const char *sent_pw;
+ int rc = ap_get_basic_auth_pw(r, &sent_pw);
+ char *user;
+
+ if (rc != OK) {
+ return rc;
+ }
+
+ if (require_any_user(r) != OK) {
+ return DECLINED;
+ }
+
+#ifdef APACHE1
+ user = r->connection->user;
+#endif
+#ifdef APACHE2
+ user = r->user;
+#endif
+
+ if (!(strtrue(user) && strtrue(sent_pw))) {
+ ap_note_basic_auth_failure(r);
+#ifdef APACHE1
+ ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
+ "Both a username and password must be provided");
+#endif
+#ifdef APACHE2
+ ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
+ "Both a username and password must be provided");
+#endif
+ return HTTP_UNAUTHORIZED;
+ }
+
+ return OK;
+}
+
+#ifdef APACHE2
+static void extra_hooks(apr_pool_t *p)
+{
+ /* mod_authany and mod_ssl both specify APR_HOOK_FIRST as the
+ * ordering of their check-user-id hooks.
+ * mod_ssl's must run before mod_authany because it may need to
+ * generate the Basic auth information based on the certificate.
+ */
+ static const char * const modssl_runs_before[] = {"mod_ssl.c", NULL};
+
+ ap_hook_check_user_id(authany_handler, modssl_runs_before, NULL,
+ APR_HOOK_FIRST);
+ ap_hook_auth_checker(require_any_user, NULL, NULL, APR_HOOK_FIRST);
+}
+#endif
+
+#endif
+
+APACHE_HTTPD_TEST_MODULE(authany);
diff --git a/debian/perl-framework/c-modules/client_add_filter/mod_client_add_filter.c b/debian/perl-framework/c-modules/client_add_filter/mod_client_add_filter.c
new file mode 100644
index 0000000..ce5ef99
--- /dev/null
+++ b/debian/perl-framework/c-modules/client_add_filter/mod_client_add_filter.c
@@ -0,0 +1,54 @@
+#define HTTPD_TEST_REQUIRE_APACHE 2
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_protocol.h"
+#include "http_request.h"
+#include "http_log.h"
+#include "ap_config.h"
+
+/*
+ * in real life we'd never allow the client to configure filters.
+ * the purpose of this module is to let .t tests configure filters
+ * this allows to test non-filtered and filtered requests without
+ * duplicating lots of test configuration
+ */
+
+static int client_add_filter_header(void *data,
+ const char *key,
+ const char *val)
+{
+ request_rec *r = (request_rec *)data;
+
+ if (strcasecmp(key, "X-AddInputFilter") == 0) {
+ ap_add_input_filter(val, NULL, r, r->connection);
+ }
+ else if (strcasecmp(key, "X-AddOutputFilter") == 0) {
+ ap_add_output_filter(val, NULL, r, r->connection);
+ }
+
+ return 1;
+}
+
+static void client_add_filter_insert(request_rec *r)
+{
+ apr_table_do(client_add_filter_header, (void*)r,
+ r->headers_in, NULL);
+}
+
+static void client_add_filter_register_hooks(apr_pool_t *p)
+{
+ ap_hook_insert_filter(client_add_filter_insert,
+ NULL, NULL, APR_HOOK_LAST);
+}
+
+module AP_MODULE_DECLARE_DATA client_add_filter_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 */
+ client_add_filter_register_hooks /* register hooks */
+};
+
diff --git a/debian/perl-framework/c-modules/eat_post/mod_eat_post.c b/debian/perl-framework/c-modules/eat_post/mod_eat_post.c
new file mode 100644
index 0000000..560ba19
--- /dev/null
+++ b/debian/perl-framework/c-modules/eat_post/mod_eat_post.c
@@ -0,0 +1,61 @@
+#if CONFIG_FOR_HTTPD_TEST
+
+<Location /eat_post>
+ SetHandler eat_post
+</Location>
+
+#endif
+
+#define APACHE_HTTPD_TEST_HANDLER eat_post_handler
+
+#include "apache_httpd_test.h"
+
+/* like mod_echo_post.c but does not echo back the data,
+ * just sends back the number of bytes read
+ */
+static int eat_post_handler(request_rec *r)
+{
+ int rc;
+ long nrd, total = 0;
+#ifdef APACHE1
+ char buff[IOBUFSIZE];
+#else
+ char buff[AP_IOBUFSIZE];
+#endif
+
+ if (strcmp(r->handler, "eat_post")) {
+ return DECLINED;
+ }
+ if ((r->method_number != M_POST) && (r->method_number != M_PUT)) {
+ return DECLINED;
+ }
+
+ if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK) {
+#ifdef APACHE1
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r->server,
+ "[mod_eat_post] ap_setup_client_block failed: %d", rc);
+#else
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r->server,
+ "[mod_eat_post] ap_setup_client_block failed: %d", rc);
+#endif /* APACHE1 */
+ return rc;
+ }
+
+ if (!ap_should_client_block(r)) {
+ return OK;
+ }
+
+#ifdef APACHE1
+ ap_send_http_header(r);
+#endif
+
+ while ((nrd = ap_get_client_block(r, buff, sizeof(buff))) > 0) {
+ total += nrd;
+ }
+
+ ap_rprintf(r, "%ld\n", total);
+
+ return OK;
+}
+
+APACHE_HTTPD_TEST_MODULE(eat_post);
diff --git a/debian/perl-framework/c-modules/echo_post/mod_echo_post.c b/debian/perl-framework/c-modules/echo_post/mod_echo_post.c
new file mode 100644
index 0000000..ebda4d5
--- /dev/null
+++ b/debian/perl-framework/c-modules/echo_post/mod_echo_post.c
@@ -0,0 +1,102 @@
+#if CONFIG_FOR_HTTPD_TEST
+
+<Location /echo_post>
+ SetHandler echo_post
+</Location>
+
+#endif
+
+#define APACHE_HTTPD_TEST_HANDLER echo_post_handler
+
+#include "apache_httpd_test.h"
+
+static int echo_post_handler(request_rec *r)
+{
+ int rc;
+ long nrd, total = 0;
+ char buff[BUFSIZ];
+
+ if (strcmp(r->handler, "echo_post")) {
+ return DECLINED;
+ }
+ if (r->method_number != M_POST) {
+ return DECLINED;
+ }
+
+ if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK) {
+#ifdef APACHE1
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r->server,
+ "[mod_echo_post] ap_setup_client_block failed: %d", rc);
+#else
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r->server,
+ "[mod_echo_post] ap_setup_client_block failed: %d", rc);
+#endif /* APACHE1 */
+ return 0;
+ }
+
+ if (!ap_should_client_block(r)) {
+ return OK;
+ }
+
+#ifdef APACHE1
+ ap_send_http_header(r);
+#endif
+
+ if (r->args) {
+#ifdef APACHE1
+ ap_rprintf(r, "%ld:", r->remaining);
+#else
+ ap_rprintf(r, "%" APR_OFF_T_FMT ":", r->remaining);
+#endif /* APACHE1 */
+ }
+
+#ifdef APACHE1
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
+ "[mod_echo_post] going to echo %ld bytes",
+ r->remaining);
+#else
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "[mod_echo_post] going to echo %" APR_OFF_T_FMT " bytes",
+ r->remaining);
+#endif /* APACHE1 */
+
+ while ((nrd = ap_get_client_block(r, buff, sizeof(buff))) > 0) {
+#ifdef APACHE1
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
+ "[mod_echo_post] read %ld bytes (wanted %d, remaining=%ld)",
+ nrd, sizeof(buff), r->remaining);
+#else
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
+ "[mod_echo_post] read %ld bytes (wanted %" APR_SIZE_T_FMT
+ ", remaining=%" APR_OFF_T_FMT ")",
+ nrd, sizeof(buff), r->remaining);
+#endif /* APACHE1 */
+ ap_rwrite(buff, nrd, r);
+ total += nrd;
+ }
+
+ if (nrd < 0) {
+ ap_rputs("!!!ERROR!!!", r);
+#ifdef APACHE1
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
+ "[mod_echo_post] ap_get_client_block got error");
+#else
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "[mod_echo_post] ap_get_client_block got error");
+#endif /* APACHE1 */
+ }
+
+#ifdef APACHE1
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
+ "[mod_echo_post] done reading %ld bytes, %ld bytes remain",
+ total, r->remaining);
+#else
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "[mod_echo_post] done reading %ld bytes, %" APR_OFF_T_FMT " bytes remain",
+ total, r->remaining);
+#endif /* APACHE1 */
+
+ return OK;
+}
+
+APACHE_HTTPD_TEST_MODULE(echo_post);
diff --git a/debian/perl-framework/c-modules/echo_post_chunk/mod_echo_post_chunk.c b/debian/perl-framework/c-modules/echo_post_chunk/mod_echo_post_chunk.c
new file mode 100644
index 0000000..98cc4e1
--- /dev/null
+++ b/debian/perl-framework/c-modules/echo_post_chunk/mod_echo_post_chunk.c
@@ -0,0 +1,93 @@
+#if CONFIG_FOR_HTTPD_TEST
+
+<Location /echo_post_chunk>
+ SetHandler echo_post_chunk
+</Location>
+
+#endif
+
+#define APACHE_HTTPD_TEST_HANDLER echo_post_chunk_handler
+
+#include "apache_httpd_test.h"
+
+static int echo_post_chunk_handler(request_rec *r)
+{
+ int rc;
+ long nrd, total = 0;
+ char buff[BUFSIZ];
+ const char *trailer_header;
+
+ if (strcmp(r->handler, "echo_post_chunk")) {
+ return DECLINED;
+ }
+ if (r->method_number != M_POST) {
+ return DECLINED;
+ }
+
+ if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK) {
+#ifdef APACHE1
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r->server,
+ "[mod_echo_post_chunk] ap_setup_client_block failed: %d", rc);
+#else
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r->server,
+ "[mod_echo_post_chunk] ap_setup_client_block failed: %d", rc);
+#endif /* APACHE1 */
+ return 0;
+ }
+
+ if (!ap_should_client_block(r)) {
+ return OK;
+ }
+
+ if (r->args) {
+ ap_rprintf(r, "%" APR_OFF_T_FMT ":", r->remaining);
+ }
+
+ fprintf(stderr, "[mod_echo_post_chunk] going to echo "
+ "%" APR_OFF_T_FMT " bytes\n",
+ r->remaining);
+
+ while ((nrd = ap_get_client_block(r, buff, sizeof(buff))) > 0) {
+ fprintf(stderr,
+ "[mod_echo_post_chunk] read %ld bytes "
+ "(wanted %" APR_SIZE_T_FMT ", remaining=%" APR_OFF_T_FMT ")\n",
+ nrd, sizeof(buff), r->remaining);
+ total += nrd;
+ }
+
+ /* nrd < 0 is an error condition. Either the chunk size overflowed or the buffer
+ * size was insufficient. We can only deduce that the request is in error.
+ */
+ if (nrd < 0) {
+ return HTTP_BAD_REQUEST;
+ }
+#ifdef APACHE1
+ ap_send_http_header(r);
+#endif
+
+#ifdef APACHE1
+ trailer_header = ap_table_get(r->headers_in, "X-Chunk-Trailer");
+#elif (MODULE_MAGIC_COOKIE >= 0x41503235UL) && AP_MODULE_MAGIC_AT_LEAST(20140627,5)
+ trailer_header = apr_table_get(r->trailers_in, "X-Chunk-Trailer");
+#elif (MODULE_MAGIC_COOKIE == 0x41503234UL) && AP_MODULE_MAGIC_AT_LEAST(20120211,37)
+ trailer_header = apr_table_get(r->trailers_in, "X-Chunk-Trailer");
+#elif (MODULE_MAGIC_COOKIE == 0x41503232UL) && AP_MODULE_MAGIC_AT_LEAST(20051115,36)
+ trailer_header = apr_table_get(r->trailers_in, "X-Chunk-Trailer");
+#else
+ trailer_header = apr_table_get(r->headers_in, "X-Chunk-Trailer");
+#endif
+ if (!trailer_header) {
+ trailer_header = "No chunked trailer available!";
+ }
+
+ ap_rputs(trailer_header, r);
+
+ fprintf(stderr,
+ "[mod_echo_post_chunk] done reading %ld bytes, "
+ "%" APR_OFF_T_FMT " bytes remain\n",
+ total, r->remaining);
+
+ return OK;
+}
+
+APACHE_HTTPD_TEST_MODULE(echo_post_chunk);
diff --git a/debian/perl-framework/c-modules/fold/mod_fold.c b/debian/perl-framework/c-modules/fold/mod_fold.c
new file mode 100644
index 0000000..548cb67
--- /dev/null
+++ b/debian/perl-framework/c-modules/fold/mod_fold.c
@@ -0,0 +1,33 @@
+#if CONFIG_FOR_HTTPD_TEST
+
+<Location /fold>
+ SetHandler fold
+</Location>
+
+#endif
+
+#define APACHE_HTTPD_TEST_HANDLER fold_handler
+
+#include "apache_httpd_test.h"
+
+static int fold_handler(request_rec *r)
+{
+
+ if (!r->handler || strcasecmp(r->handler, "fold")) {
+ return DECLINED;
+ }
+
+ if (r->args) {
+ ap_set_content_type(r, r->args);
+ }
+ else {
+ ap_set_content_type(r, "text/html");
+ }
+
+ /* This doesn't work with CGI or asis, hence the tiny module */
+ apr_table_set(r->err_headers_out, "Foo", "Bar\r\n Baz");
+
+ return OK;
+}
+
+APACHE_HTTPD_TEST_MODULE(fold);
diff --git a/debian/perl-framework/c-modules/httpd_test_util.c b/debian/perl-framework/c-modules/httpd_test_util.c
new file mode 100644
index 0000000..bc8e608
--- /dev/null
+++ b/debian/perl-framework/c-modules/httpd_test_util.c
@@ -0,0 +1,44 @@
+/* poor man's optional functions
+ * if we didn't need to support 1.x we could use optional functions.
+ * just hack in this util functions with #define/#include/static for now.
+ *
+ * tho we could create our own version optional functions using
+ * the 1.3/2.0 dlsym-ish function to lookup function pointers given a
+ * mod_httpd_test_util.so and httpd_test_util.dynamic_load_handle
+ * but thats more trouble than it is worth at the moment.
+ */
+
+#ifdef WANT_HTTPD_TEST_SPLIT_QS_NUMBERS
+
+/* split query string in the form of GET /foo?1024,5000 */
+
+static int httpd_test_split_qs_numbers(request_rec *r, ...)
+{
+ va_list va;
+ char *endptr, *args = r->args;
+
+ if (!args) {
+ return 0;
+ }
+
+ va_start(va, r);
+
+ while (1) {
+ apr_size_t *s = va_arg(va, apr_size_t *);
+ if (!s) {
+ break;
+ }
+ *s = strtol(args, &endptr, 0);
+ if (endptr && (*endptr == ',')) {
+ ++endptr;
+ args = endptr;
+ }
+ }
+
+ va_end(va);
+
+ return 1;
+}
+
+#endif /* WANT_HTTPD_TEST_SPLIT_QS_NUMBERS */
+
diff --git a/debian/perl-framework/c-modules/input_body_filter/mod_input_body_filter.c b/debian/perl-framework/c-modules/input_body_filter/mod_input_body_filter.c
new file mode 100644
index 0000000..1a47341
--- /dev/null
+++ b/debian/perl-framework/c-modules/input_body_filter/mod_input_body_filter.c
@@ -0,0 +1,184 @@
+#define HTTPD_TEST_REQUIRE_APACHE 2
+
+#if CONFIG_FOR_HTTPD_TEST
+
+<Location /input_body_filter>
+ SetHandler input-body-filter
+ InputBodyFilter On
+</Location>
+
+#endif
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_protocol.h"
+#include "http_request.h"
+#include "http_log.h"
+#include "ap_config.h"
+#include "util_filter.h"
+#include "apr_buckets.h"
+#include "apr_strings.h"
+
+module AP_MODULE_DECLARE_DATA input_body_filter_module;
+
+#define INPUT_BODY_FILTER_NAME "INPUT_BODY_FILTER"
+
+typedef struct {
+ int enabled;
+} input_body_filter_dcfg_t;
+
+static void *input_body_filter_dcfg_create(apr_pool_t *p, char *dummy)
+{
+ input_body_filter_dcfg_t *dcfg =
+ (input_body_filter_dcfg_t *)apr_pcalloc(p, sizeof(*dcfg));
+
+ return dcfg;
+}
+
+static int input_body_filter_fixup_handler(request_rec *r)
+{
+ if ((r->method_number == M_POST) && r->handler &&
+ !strcmp(r->handler, "input-body-filter"))
+ {
+ r->handler = "echo_post";
+ }
+
+ return OK;
+}
+
+static int input_body_filter_response_handler(request_rec *r)
+{
+ if (strcmp(r->handler, "echo_post")) {
+ return DECLINED;
+ }
+
+ if (r->method_number != M_POST) {
+ ap_rputs("1..1\nok 1\n", r);
+ return OK;
+ }
+ else {
+ return DECLINED;
+ }
+}
+
+static void reverse_string(char *string, int len)
+{
+ register char *up, *down;
+ register unsigned char tmp;
+
+ up = string;
+ down = string + len - 1;
+
+ while (down > up) {
+ tmp = *up;
+ *up++ = *down;
+ *down-- = tmp;
+ }
+}
+
+typedef struct input_body_ctx_t {
+ apr_bucket_brigade *b;
+} input_body_ctx_t;
+
+static int input_body_filter_handler(ap_filter_t *f, apr_bucket_brigade *bb,
+ ap_input_mode_t mode,
+ apr_read_type_e block,
+ apr_off_t readbytes)
+{
+ request_rec *r = f->r;
+ conn_rec *c = r->connection;
+ apr_status_t rv;
+ input_body_ctx_t *ctx = f->ctx;
+
+ if (!ctx) {
+ f->ctx = ctx = apr_pcalloc(r->pool, sizeof(*ctx));
+ ctx->b = apr_brigade_create(r->pool, c->bucket_alloc);
+ }
+
+ if (APR_BRIGADE_EMPTY(ctx->b))
+ {
+ if ((rv = ap_get_brigade(f->next, ctx->b, mode, block,
+ readbytes)) != APR_SUCCESS) {
+ return rv;
+ }
+ }
+
+ while (!APR_BRIGADE_EMPTY(ctx->b)) {
+ const char *data;
+ apr_size_t len;
+ apr_bucket *bucket;
+
+ bucket = APR_BRIGADE_FIRST(ctx->b);
+
+ if (APR_BUCKET_IS_EOS(bucket)) {
+ APR_BUCKET_REMOVE(bucket);
+ APR_BRIGADE_INSERT_TAIL(bb, bucket);
+ break;
+ }
+
+ rv = apr_bucket_read(bucket, &data, &len, block);
+
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ APR_BUCKET_REMOVE(bucket);
+
+ if (len) {
+ char *reversed = apr_pstrndup(r->pool, data, len);
+ reverse_string(reversed, len);
+ bucket = apr_bucket_pool_create(reversed, len, r->pool,
+ c->bucket_alloc);
+ }
+
+ APR_BRIGADE_INSERT_TAIL(bb, bucket);
+ }
+
+ return OK;
+}
+
+static void input_body_filter_insert_filter(request_rec *r)
+{
+ input_body_filter_dcfg_t *dcfg =
+ ap_get_module_config(r->per_dir_config,
+ &input_body_filter_module);
+
+ if (dcfg->enabled) {
+ ap_add_input_filter(INPUT_BODY_FILTER_NAME, NULL, r, r->connection);
+ }
+}
+
+static void input_body_filter_register_hooks(apr_pool_t *p)
+{
+ ap_hook_fixups(input_body_filter_fixup_handler,
+ NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_handler(input_body_filter_response_handler,
+ NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_insert_filter(input_body_filter_insert_filter,
+ NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_register_input_filter(INPUT_BODY_FILTER_NAME,
+ input_body_filter_handler,
+ NULL,
+ AP_FTYPE_RESOURCE);
+}
+
+static const command_rec input_body_filter_cmds[] = {
+ AP_INIT_FLAG("InputBodyFilter", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(input_body_filter_dcfg_t, enabled),
+ OR_ALL, "Enable input body filter"),
+ { NULL }
+};
+
+module AP_MODULE_DECLARE_DATA input_body_filter_module = {
+ STANDARD20_MODULE_STUFF,
+ input_body_filter_dcfg_create, /* create per-dir config structures */
+ NULL, /* merge per-dir config structures */
+ NULL, /* create per-server config structures */
+ NULL, /* merge per-server config structures */
+ input_body_filter_cmds, /* table of config file commands */
+ input_body_filter_register_hooks /* register hooks */
+};
+
diff --git a/debian/perl-framework/c-modules/list_modules/mod_list_modules.c b/debian/perl-framework/c-modules/list_modules/mod_list_modules.c
new file mode 100644
index 0000000..40738a1
--- /dev/null
+++ b/debian/perl-framework/c-modules/list_modules/mod_list_modules.c
@@ -0,0 +1,38 @@
+#if CONFIG_FOR_HTTPD_TEST
+
+<Location /list_modules>
+ SetHandler list_modules
+</Location>
+
+#endif
+
+#define APACHE_HTTPD_TEST_HANDLER list_modules_handler
+
+#define CORE_PRIVATE /* for ap_top_module */
+#include "apache_httpd_test.h"
+
+static int list_modules_handler(request_rec *r)
+{
+ module *modp;
+
+ if (strcmp(r->handler, "list_modules")) {
+ return DECLINED;
+ }
+ if (r->method_number != M_GET) {
+ return DECLINED;
+ }
+
+#ifdef APACHE1
+#define ap_top_module top_module
+ ap_send_http_header(r);
+#endif
+
+ for (modp = ap_top_module; modp; modp = modp->next) {
+ ap_rvputs(r, modp->name, "\n", NULL);
+ }
+
+ return OK;
+}
+
+APACHE_HTTPD_TEST_MODULE(list_modules);
+
diff --git a/debian/perl-framework/c-modules/memory_track/mod_memory_track.c b/debian/perl-framework/c-modules/memory_track/mod_memory_track.c
new file mode 100644
index 0000000..25d11ca
--- /dev/null
+++ b/debian/perl-framework/c-modules/memory_track/mod_memory_track.c
@@ -0,0 +1,45 @@
+#if CONFIG_FOR_HTTPD_TEST
+
+<Location /memory_track>
+ SetHandler memory-track
+</Location>
+
+#endif
+
+#define APACHE_HTTPD_TEST_HANDLER memory_track_handler
+
+#include "apache_httpd_test.h"
+#include "ap_mpm.h"
+
+static int memory_track_handler(request_rec *r)
+{
+ int result;
+
+ if (strcmp(r->handler, "memory-track")) {
+ return DECLINED;
+ }
+ if (r->method_number != M_GET) {
+ return DECLINED;
+ }
+
+ /* t/apache/leaks.t not reliable with event. */
+ if (!ap_mpm_query(AP_MPMQ_IS_ASYNC, &result) && result) {
+ return HTTP_SERVICE_UNAVAILABLE;
+ }
+
+#if APR_POOL_DEBUG
+ {
+ conn_rec *c = r->connection;
+ apr_size_t n = apr_pool_num_bytes(c->pool, 1);
+
+ ap_rprintf(r, "connection,%ld,%lu\n", c->id, n);
+ }
+
+ return OK;
+#else
+ return HTTP_NOT_IMPLEMENTED;
+#endif
+}
+
+APACHE_HTTPD_TEST_MODULE(memory_track);
+
diff --git a/debian/perl-framework/c-modules/nntp_like/mod_nntp_like.c b/debian/perl-framework/c-modules/nntp_like/mod_nntp_like.c
new file mode 100644
index 0000000..0fad8ce
--- /dev/null
+++ b/debian/perl-framework/c-modules/nntp_like/mod_nntp_like.c
@@ -0,0 +1,181 @@
+#define HTTPD_TEST_REQUIRE_APACHE 2
+
+/*
+ * purpose of this module is to test protocol modules that need to
+ * send data to the client before reading any request data.
+ * in this case, mod_ssl needs to handshake before sending data to the client.
+ * t/protocol/nntp-like.t tests both with and without ssl
+ * to make sure the protocol code works in both cases.
+ */
+
+#if CONFIG_FOR_HTTPD_TEST
+
+<VirtualHost mod_nntp_like>
+ NNTPLike On
+</VirtualHost>
+
+<IfModule @ssl_module@>
+ <VirtualHost mod_nntp_like_ssl>
+ NNTPLike On
+ SSLEngine On
+ </VirtualHost>
+</IfModule>
+
+#endif
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_protocol.h"
+#include "http_connection.h"
+#include "http_request.h"
+#include "http_log.h"
+#include "ap_config.h"
+#include "util_filter.h"
+#include "apr_buckets.h"
+#include "apr_strings.h"
+
+module AP_MODULE_DECLARE_DATA nntp_like_module;
+
+typedef struct {
+ int enabled;
+} nntp_like_srv_cfg_t;
+
+static void *nntp_like_srv_cfg_create(apr_pool_t *p, server_rec *s)
+{
+ nntp_like_srv_cfg_t *cfg = apr_palloc(p, sizeof(*cfg));
+
+ cfg->enabled = 0;
+
+ return cfg;
+}
+
+static const char *nntp_like_cmd_enable(cmd_parms *cmd, void *dummy, int arg)
+{
+ nntp_like_srv_cfg_t *cfg =
+ ap_get_module_config(cmd->server->module_config,
+ &nntp_like_module);
+ cfg->enabled = arg;
+
+ return NULL;
+}
+
+/* this function just triggers the SSL handshake.
+ * normally that would happen in a protocol such as HTTP when
+ * the client request is read. however, with certain protocols
+ * such as NNTP, the server sends a response before the client
+ * sends a request
+ *
+ * if SSL is not enabled, this function is a noop
+ */
+static apr_status_t nntp_like_init_connection(conn_rec *c)
+{
+ apr_bucket_brigade *bb;
+ apr_status_t rv;
+
+ bb = apr_brigade_create(c->pool, c->bucket_alloc);
+
+ rv = ap_get_brigade(c->input_filters, bb, AP_MODE_INIT,
+ APR_BLOCK_READ, 0);
+
+ apr_brigade_destroy(bb);
+
+ return rv;
+}
+
+static apr_status_t nntp_like_send_welcome(conn_rec *c)
+{
+ apr_bucket *bucket;
+ apr_bucket_brigade *bb = apr_brigade_create(c->pool, c->bucket_alloc);
+
+#define NNTP_LIKE_WELCOME \
+ "200 localhost - ready\r\n"
+
+ bucket = apr_bucket_immortal_create(NNTP_LIKE_WELCOME,
+ sizeof(NNTP_LIKE_WELCOME)-1,
+ c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, bucket);
+ APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_flush_create(c->bucket_alloc));
+
+ return ap_pass_brigade(c->output_filters, bb);
+}
+
+static int nntp_like_pre_connection(conn_rec *c, void *csd)
+{
+ nntp_like_srv_cfg_t *cfg =
+ ap_get_module_config(c->base_server->module_config,
+ &nntp_like_module);
+
+ if (cfg->enabled) {
+ apr_socket_timeout_set(csd, c->base_server->keep_alive_timeout);
+ }
+
+ return DECLINED;
+}
+
+static int nntp_like_process_connection(conn_rec *c)
+{
+ apr_bucket_brigade *bb;
+ apr_status_t rv;
+ nntp_like_srv_cfg_t *cfg =
+ ap_get_module_config(c->base_server->module_config,
+ &nntp_like_module);
+
+ if (!cfg->enabled) {
+ return DECLINED;
+ }
+
+ /* handshake if talking over SSL */
+ if ((rv = nntp_like_init_connection(c)) != APR_SUCCESS) {
+ return rv;
+ }
+
+ /* send the welcome message */
+ if ((rv = nntp_like_send_welcome(c)) != APR_SUCCESS) {
+ return rv;
+ }
+
+ do {
+ bb = apr_brigade_create(c->pool, c->bucket_alloc);
+
+ if ((rv = ap_get_brigade(c->input_filters, bb,
+ AP_MODE_GETLINE,
+ APR_BLOCK_READ, 0)) != APR_SUCCESS ||
+ APR_BRIGADE_EMPTY(bb))
+ {
+ apr_brigade_destroy(bb);
+ break;
+ }
+
+ APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_flush_create(c->bucket_alloc));
+
+ rv = ap_pass_brigade(c->output_filters, bb);
+ } while (rv == APR_SUCCESS);
+
+ return OK;
+}
+
+static void nntp_like_register_hooks(apr_pool_t *p)
+{
+ ap_hook_pre_connection(nntp_like_pre_connection, NULL, NULL,
+ APR_HOOK_MIDDLE);
+ ap_hook_process_connection(nntp_like_process_connection,
+ NULL, NULL,
+ APR_HOOK_MIDDLE);
+}
+
+static const command_rec nntp_like_cmds[] =
+{
+ AP_INIT_FLAG("NNTPLike", nntp_like_cmd_enable, NULL, RSRC_CONF,
+ "enable nntp like protocol on this host"),
+ { NULL }
+};
+
+module AP_MODULE_DECLARE_DATA nntp_like_module = {
+ STANDARD20_MODULE_STUFF,
+ NULL, /* create per-dir config structures */
+ NULL, /* merge per-dir config structures */
+ nntp_like_srv_cfg_create, /* create per-server config structures */
+ NULL, /* merge per-server config structures */
+ nntp_like_cmds, /* table of config file commands */
+ nntp_like_register_hooks /* register hooks */
+};
diff --git a/debian/perl-framework/c-modules/random_chunk/mod_random_chunk.c b/debian/perl-framework/c-modules/random_chunk/mod_random_chunk.c
new file mode 100644
index 0000000..01da3e0
--- /dev/null
+++ b/debian/perl-framework/c-modules/random_chunk/mod_random_chunk.c
@@ -0,0 +1,182 @@
+#if CONFIG_FOR_HTTPD_TEST
+
+<Location /random_chunk>
+ SetHandler random_chunk
+</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 be used for testing chunked encoding. It
+ * generates a whole whack of output using ap_bputc() and ap_bputs(). It
+ * also exercises start_chunk() and end_chunk() in buff.c. To use it
+ * you should use a tool like netcat and the src/test/check_chunked
+ * tool. Add something like this to your access.conf file:
+ *
+ * <Location /rndchunk>
+ * SetHandler rndchunk
+ * </Location>
+ *
+ * Then fake requests such as:
+ *
+ * GET /rndchunk?0,1000000 HTTP/1.1
+ * Host: localhost
+ *
+ * The first arg is the random seed, the second is the number of
+ * "things" to do. You should try a few seeds.
+ *
+ * You should also edit main/buff.c and change DEFAULT_BUFSIZE (and
+ * CHUNK_HEADER_SIZE). Small values are particularly useful for
+ * finding bugs. Try a few different values.
+ *
+ * -djg
+ */
+
+#define APACHE_HTTPD_TEST_HANDLER random_chunk_handler
+
+#include "apache_httpd_test.h"
+
+#define MAX_SEGMENT 32
+#define ONE_WEIGHT (256-32)
+
+#define WANT_HTTPD_TEST_SPLIT_QS_NUMBERS
+#include "httpd_test_util.c"
+
+static int random_chunk_handler(request_rec *r)
+{
+ apr_size_t seed = 0;
+ apr_size_t count = 0;
+ int i;
+ char buf[MAX_SEGMENT + 1];
+ unsigned int len;
+ apr_size_t total = 0;
+
+ if (strcmp(r->handler, "random_chunk")) {
+ return DECLINED;
+ }
+
+ if (r->proto_num < HTTP_VERSION(1,1)) {
+ return DECLINED;
+ }
+
+ r->allowed |= (AP_METHOD_BIT << M_GET);
+
+ if (r->method_number != M_GET) {
+ return DECLINED;
+ }
+
+ r->content_type = "text/html";
+
+#ifdef APACHE1
+ ap_send_http_header(r);
+#endif
+ if (r->header_only) {
+ return OK;
+ }
+
+ httpd_test_split_qs_numbers(r, &seed, &count, NULL);
+
+ if (!count) {
+ ap_rputs("Must include args! ... "
+ "of the form <code>?seed,count</code>", r);
+ return 0;
+ }
+
+#ifdef WIN32
+ srand(seed); /* XXX: apr-ize */
+#else
+ srandom(seed); /* XXX: apr-ize */
+#endif
+
+ for (i = 0; i < count; ++i) {
+#ifdef WIN32
+ len = rand() % (MAX_SEGMENT + ONE_WEIGHT);
+#else
+ len = random() % (MAX_SEGMENT + ONE_WEIGHT);
+#endif
+
+ if (len >= MAX_SEGMENT) {
+ ap_rputc((i & 1) ? '0' : '1', r);
+ total += 1;
+ }
+ else if (len == 0) {
+ /* 1.x version used to do this; but chunk_filter does now */
+#if 0
+ ap_bsetflag(r->connection->client, B_CHUNK, 0);
+ ap_bsetflag(r->connection->client, B_CHUNK, 1);
+#endif
+ }
+ else {
+ memset(buf, '2' + len, len);
+ buf[len] = 0;
+ total += ap_rputs(buf, r);
+ }
+ }
+
+ ap_rprintf(r, "__END__:%" APR_SIZE_T_FMT, total);
+
+ fprintf(stderr, "[mod_random_chunk] sent %" APR_SIZE_T_FMT "bytes\n",
+ total);
+
+ return 0;
+}
+
+APACHE_HTTPD_TEST_MODULE(random_chunk);
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 */
+};
diff --git a/debian/perl-framework/c-modules/test_pass_brigade/mod_test_pass_brigade.c b/debian/perl-framework/c-modules/test_pass_brigade/mod_test_pass_brigade.c
new file mode 100644
index 0000000..99bc95a
--- /dev/null
+++ b/debian/perl-framework/c-modules/test_pass_brigade/mod_test_pass_brigade.c
@@ -0,0 +1,104 @@
+#define HTTPD_TEST_REQUIRE_APACHE 2
+
+#if CONFIG_FOR_HTTPD_TEST
+
+<Location /test_pass_brigade>
+ SetHandler test_pass_brigade
+</Location>
+
+#endif
+
+#define APACHE_HTTPD_TEST_HANDLER test_pass_brigade_handler
+
+#include "apache_httpd_test.h"
+
+#include "apr_buckets.h"
+
+#define WANT_HTTPD_TEST_SPLIT_QS_NUMBERS
+#include "httpd_test_util.c"
+
+/*
+ * mainly for testing / researching core_output_filter buffering
+ */
+
+static int test_pass_brigade_handler(request_rec *r)
+{
+ conn_rec *c = r->connection;
+ size_t total=0, remaining=1;
+ char *buff;
+ size_t buff_size = 8192;
+ apr_bucket_brigade *bb;
+
+ if (strcmp(r->handler, "test_pass_brigade")) {
+ return DECLINED;
+ }
+ if (r->method_number != M_GET) {
+ return DECLINED;
+ }
+
+ httpd_test_split_qs_numbers(r, &buff_size, &remaining, NULL);
+
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ "going to echo %" APR_SIZE_T_FMT " bytes with "
+ "buffer size=%" APR_SIZE_T_FMT "",
+ remaining, buff_size);
+
+ buff = malloc(buff_size);
+ memset(buff, 'a', buff_size);
+ bb = apr_brigade_create(r->pool, c->bucket_alloc);
+
+ while (total < remaining) {
+ int left = (remaining - total);
+ int len = left <= buff_size ? left : buff_size;
+ apr_bucket *bucket = apr_bucket_transient_create(buff, len,
+ c->bucket_alloc);
+ apr_status_t status;
+
+ apr_brigade_cleanup(bb);
+ APR_BRIGADE_INSERT_TAIL(bb, bucket);
+ if (len + total == remaining) {
+ bucket = apr_bucket_eos_create(c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, bucket);
+
+#if 0
+ /* ###### A FLUSH should not be strictly necessary here
+ * but inserting one apears to work around intermittent
+ * failures when running t/apache/pass_brigade.t under
+ * worker. */
+ bucket = apr_bucket_flush_create(c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, bucket);
+#endif
+
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ "[mod_test_pass_brigade] sending EOS");
+ }
+
+ status = ap_pass_brigade(r->output_filters->next, bb);
+
+ if (status != APR_SUCCESS) {
+ apr_brigade_destroy(bb);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
+ "[mod_test_pass_brigade] ap_pass_brigade failed");
+ free(buff);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ total += len;
+
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
+ "[mod_test_pass_brigade] wrote %d of %d bytes",
+ len, len);
+ }
+
+ apr_brigade_destroy(bb);
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ "[mod_test_pass_brigade] done writing %" APR_SIZE_T_FMT
+ " of %" APR_SIZE_T_FMT " bytes",
+ total, remaining);
+
+ free(buff);
+ return OK;
+}
+
+APACHE_HTTPD_TEST_MODULE(test_pass_brigade);
+
diff --git a/debian/perl-framework/c-modules/test_rwrite/mod_test_rwrite.c b/debian/perl-framework/c-modules/test_rwrite/mod_test_rwrite.c
new file mode 100644
index 0000000..64f1542
--- /dev/null
+++ b/debian/perl-framework/c-modules/test_rwrite/mod_test_rwrite.c
@@ -0,0 +1,66 @@
+#if CONFIG_FOR_HTTPD_TEST
+
+<Location /test_rwrite>
+ SetHandler test_rwrite
+</Location>
+
+#endif
+
+#define APACHE_HTTPD_TEST_HANDLER test_rwrite_handler
+
+#include "apache_httpd_test.h"
+
+#define WANT_HTTPD_TEST_SPLIT_QS_NUMBERS
+#include "httpd_test_util.c"
+
+static int test_rwrite_handler(request_rec *r)
+{
+ size_t total=0, remaining=1;
+ char *buff;
+ size_t buff_size = 8192;
+
+ if (strcmp(r->handler, "test_rwrite")) {
+ return DECLINED;
+ }
+ if (r->method_number != M_GET) {
+ return DECLINED;
+ }
+
+ if (r->args) {
+ remaining = atol(r->args);
+ }
+
+#ifdef APACHE1
+ ap_send_http_header(r);
+#endif
+
+ httpd_test_split_qs_numbers(r, &buff_size, &remaining, NULL);
+
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ "[mod_test_rwrite] going to echo %" APR_SIZE_T_FMT " bytes",
+ remaining);
+
+ buff = malloc(buff_size);
+ memset(buff, 'a', buff_size);
+
+ while (total < remaining) {
+ int left = (remaining - total);
+ int len = left <= buff_size ? left : buff_size;
+ long nrd = ap_rwrite(buff, len, r);
+ total += nrd;
+
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
+ "[mod_test_rwrite] wrote %ld of %d bytes", nrd, len);
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ "[mod_test_rwrite] done writing %" APR_SIZE_T_FMT
+ " of %" APR_SIZE_T_FMT " bytes",
+ total, remaining);
+
+ free(buff);
+ return OK;
+}
+
+APACHE_HTTPD_TEST_MODULE(test_rwrite);
+
diff --git a/debian/perl-framework/c-modules/test_session/mod_test_session.c b/debian/perl-framework/c-modules/test_session/mod_test_session.c
new file mode 100644
index 0000000..4099cbe
--- /dev/null
+++ b/debian/perl-framework/c-modules/test_session/mod_test_session.c
@@ -0,0 +1,348 @@
+#define HTTPD_TEST_REQUIRE_APACHE 2.3
+
+#if CONFIG_FOR_HTTPD_TEST
+
+<IfModule mod_session.c>
+ <Location /sessiontest>
+ Session Off
+ TestSession On
+ SetHandler test-session-handler
+ </Location>
+ <Location /sessiontest/on>
+ Session On
+ SessionHeader X-Test-Session-Override
+ </Location>
+ <Location /sessiontest/on/encode>
+ TestSessionEncoder On
+ </Location>
+ <IfModule mod_include.c>
+ Alias /sessiontest/on/env/on @DocumentRoot@/modules/session
+ <Directory @DocumentRoot@/modules/session>
+ Session On
+ SessionEnv Off
+ TestSession On
+ Options +IncludesNOEXEC
+ </Directory>
+ <Location /sessiontest/on/env>
+ SetHandler None
+ </Location>
+ <Location /sessiontest/on/env/on>
+ SessionEnv On
+ </Location>
+ </IfModule>
+ <Location /sessiontest/on/expire>
+ SessionMaxAge 100
+ </Location>
+ <IfModule mod_version.c>
+ <IfVersion >= 2.4.41>
+ <Location /sessiontest/on/expire/cache>
+ SessionExpiryUpdateInterval 50
+ </Location>
+ </IfVersion>
+ </IfModule>
+ <Location /sessiontest/on/include>
+ SessionInclude /sessiontest/on/include/yes
+ SessionExclude /sessiontest/on/include/yes/no
+ </Location>
+</IfModule>
+
+#endif
+
+#include "apr_strings.h"
+#include "mod_session.h"
+
+#define APACHE_HTTPD_TEST_EXTRA_HOOKS extra_hooks
+#define APACHE_HTTPD_TEST_CHILD_INIT test_session_init
+#define APACHE_HTTPD_TEST_HANDLER test_session_handler
+#define APACHE_HTTPD_TEST_COMMANDS test_session_cmds
+#define APACHE_HTTPD_TEST_PER_DIR_CREATE test_session_dcfg_create
+#define APACHE_HTTPD_TEST_PER_DIR_MERGE test_session_dcfg_merge
+
+#include "apache_httpd_test.h"
+
+#define TEST_SESSION_HANDLER "test-session-handler"
+#define TEST_SESSION_ENCODER "test-session-encoder"
+#define TEST_SESSION_NOTE "mod_test_session"
+#define TEST_SESSION_HEADER "X-Test-Session-Override"
+#define TEST_SESSION_ENCODING_PREFIX "TestEncoded:"
+
+typedef struct {
+ int session;
+ int session_set;
+ int encoder;
+ int encoder_set;
+} test_session_dcfg_t;
+
+typedef enum {
+ TEST_SESSION_ACTION_NONE,
+ TEST_SESSION_ACTION_GET,
+ TEST_SESSION_ACTION_SET
+} TestSessionAction;
+
+module AP_MODULE_DECLARE_DATA test_session_module;
+
+static APR_OPTIONAL_FN_TYPE(ap_session_get) *ap_session_get_fn = NULL;
+static APR_OPTIONAL_FN_TYPE(ap_session_set) *ap_session_set_fn = NULL;
+static APR_OPTIONAL_FN_TYPE(ap_session_load) *ap_session_load_fn = NULL;
+static APR_OPTIONAL_FN_TYPE(ap_session_save) *ap_session_save_fn = NULL;
+
+static void test_session_init(apr_pool_t *p, server_rec *s)
+{
+ ap_session_get_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_get);
+ ap_session_set_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_set);
+ ap_session_save_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_save);
+ ap_session_load_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_load);
+}
+
+static apr_status_t test_session_load(request_rec * r, session_rec ** z)
+{
+ session_rec *zz;
+ test_session_dcfg_t *dconf = ap_get_module_config(r->per_dir_config,
+ &test_session_module);
+ if (!dconf || !dconf->session)
+ return DECLINED;
+
+ zz = (session_rec *)apr_table_get(r->notes, TEST_SESSION_NOTE);
+
+ if (!zz) {
+ /* Create the session using the query string as the data. */
+ char *data = apr_pstrdup(r->pool, r->args);
+
+ if (data) {
+ int result = ap_unescape_urlencoded(data);
+ if (result)
+ return result;
+ }
+
+ zz = (session_rec *)apr_pcalloc(r->pool, sizeof(session_rec));
+ zz->pool = r->pool;
+ zz->entries = apr_table_make(r->pool, 10);
+ zz->encoded = data;
+ apr_table_setn(r->notes, TEST_SESSION_NOTE, (char *)zz);
+ }
+
+ *z = zz;
+ return OK;
+}
+
+static apr_status_t test_session_save(request_rec * r, session_rec * z)
+{
+ test_session_dcfg_t *dconf = ap_get_module_config(r->per_dir_config,
+ &test_session_module);
+ if (!dconf || !dconf->session)
+ return DECLINED;
+
+ /* Save the session into headers. */
+ apr_table_setn(r->headers_out, "X-Test-Session-Dirty",
+ z->dirty ? "1" : "0");
+
+ apr_table_set(r->headers_out, "X-Test-Session", z->encoded);
+
+ return OK;
+}
+
+static apr_status_t test_session_encode(request_rec * r, session_rec * z)
+{
+ test_session_dcfg_t *dconf = ap_get_module_config(r->per_dir_config,
+ &test_session_module);
+ if (!dconf || !dconf->encoder)
+ return DECLINED;
+
+ /* Simple encoding by adding a prefix. */
+ z->encoded = apr_pstrcat(r->pool, TEST_SESSION_ENCODING_PREFIX,
+ z->encoded, NULL);
+ return OK;
+}
+
+static apr_status_t test_session_decode(request_rec * r, session_rec * z)
+{
+ const size_t prefix_len = strlen(TEST_SESSION_ENCODING_PREFIX);
+ test_session_dcfg_t *dconf = ap_get_module_config(r->per_dir_config,
+ &test_session_module);
+ if (!dconf || !dconf->encoder || !z->encoded)
+ return DECLINED;
+
+ /* Simple decoding by removing a prefix. */
+ if (!strncmp(z->encoded, TEST_SESSION_ENCODING_PREFIX, prefix_len)) {
+ z->encoded += prefix_len;
+ return OK;
+ }
+
+ return HTTP_BAD_REQUEST;
+}
+
+static int test_session_get(request_rec *r, char *name)
+{
+ session_rec *z = NULL;
+ const char *value = NULL;
+ apr_status_t result = ap_session_load_fn(r, &z);
+
+ if (result == OK)
+ result = ap_session_get_fn(r, z, name, &value);
+
+ if (result == OK) {
+ if (value)
+ result = ap_rputs(value, r) > 0 ? OK : HTTP_INTERNAL_SERVER_ERROR;
+ else
+ result = HTTP_NOT_FOUND;
+ }
+
+ return result;
+}
+
+static int test_session_set(request_rec *r, char *name, char *value)
+{
+ session_rec *z = NULL;
+ apr_status_t result = ap_session_load_fn(r, &z);
+
+ if (result == OK)
+ result = ap_session_set_fn(r, z, name, value);
+
+ return result;
+}
+
+static int test_session_handler(request_rec *r)
+{
+ const char *overrides = NULL;
+
+ if (strcmp(r->handler, TEST_SESSION_HANDLER))
+ return DECLINED;
+
+ /* Copy the header for SessionHeader from the request to the response. */
+ if ((overrides = apr_table_get(r->headers_in, TEST_SESSION_HEADER)))
+ apr_table_setn(r->headers_out, TEST_SESSION_HEADER, overrides);
+
+ /* Additional commands to test the session API via POST. */
+ if (r->method_number == M_POST) {
+ char *fieldName = NULL;
+ char *fieldValue = NULL;
+ apr_array_header_t *pairs = NULL;
+ apr_status_t result;
+ TestSessionAction action;
+
+ if (!ap_session_get_fn || !ap_session_set_fn ||
+ !ap_session_load_fn || !ap_session_save_fn)
+ return HTTP_INTERNAL_SERVER_ERROR;
+
+ action = TEST_SESSION_ACTION_NONE;
+ result = ap_parse_form_data(r, NULL, &pairs, 3, 1024);
+
+ if (result != OK)
+ return result;
+
+ while (pairs && !apr_is_empty_array(pairs)) {
+ ap_form_pair_t *pair = (ap_form_pair_t *)apr_array_pop(pairs);
+ if (!strcmp(pair->name, "action")) {
+ apr_size_t len;
+ char *value = NULL;
+ result = apr_brigade_pflatten(pair->value, &value, &len,
+ r->pool);
+ if (result == OK && !strncmp(value, "get", len))
+ action = TEST_SESSION_ACTION_GET;
+ else if (result == OK && !strncmp(value, "set", len))
+ action = TEST_SESSION_ACTION_SET;
+ else
+ return HTTP_BAD_REQUEST;
+ }
+ else if (!strcmp(pair->name, "name")) {
+ apr_off_t off;
+ apr_size_t len;
+ apr_brigade_length(pair->value, 1, &off);
+ len = (apr_size_t)off;
+ fieldName = apr_pcalloc(r->pool, sizeof(char) * len + 1);
+ result = apr_brigade_flatten(pair->value, fieldName, &len);
+ }
+ else if (!strcmp(pair->name, "value")) {
+ apr_off_t off;
+ apr_size_t len;
+ apr_brigade_length(pair->value, 1, &off);
+ len = (apr_size_t)off;
+ fieldValue = apr_pcalloc(r->pool, sizeof(char) * len + 1);
+ result = apr_brigade_flatten(pair->value, fieldValue, &len);
+ }
+ else {
+ return HTTP_BAD_REQUEST;
+ }
+
+ if (result != OK)
+ return result;
+ }
+
+ switch (action) {
+ case TEST_SESSION_ACTION_GET:
+ return test_session_get(r, fieldName);
+
+ case TEST_SESSION_ACTION_SET:
+ return test_session_set(r, fieldName, fieldValue);
+
+ default:
+ return HTTP_BAD_REQUEST;
+ }
+ }
+
+ return OK;
+}
+
+static void *test_session_dcfg_create(apr_pool_t *p, char *dummy)
+{
+ return apr_pcalloc(p, sizeof(test_session_dcfg_t));
+}
+
+static void *test_session_dcfg_merge(apr_pool_t * p, void *basev, void *addv)
+{
+ test_session_dcfg_t *add = addv;
+ test_session_dcfg_t *base = basev;
+ test_session_dcfg_t *new = apr_pcalloc(p, sizeof(test_session_dcfg_t));
+
+ new->session = (add->session_set == 0) ? base->session : add->session;
+ new->session_set = add->session_set || base->session_set;
+ new->encoder = (add->encoder_set == 0) ? base->encoder : add->encoder;
+ new->encoder_set = add->encoder_set || base->encoder_set;
+
+ return new;
+}
+
+static const char *set_session_enable(cmd_parms * parms, void *dconf, int flag)
+{
+ test_session_dcfg_t *conf = dconf;
+
+ conf->session = flag;
+ conf->session_set = 1;
+
+ return NULL;
+}
+
+static const char *set_encoder_enable(cmd_parms * parms, void *dconf, int flag)
+{
+ test_session_dcfg_t *conf = dconf;
+
+ conf->encoder = flag;
+ conf->encoder_set = 1;
+
+ return NULL;
+}
+
+static const command_rec test_session_cmds[] = {
+ AP_INIT_FLAG("TestSession", set_session_enable, NULL, OR_ALL,
+ "Enable test sessions"),
+ AP_INIT_FLAG("TestSessionEncoder", set_encoder_enable, NULL, OR_ALL,
+ "Enable test session encoding"),
+ { NULL }
+};
+
+static void extra_hooks(apr_pool_t *pool)
+{
+ ap_hook_session_load(test_session_load,
+ NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_session_save(test_session_save,
+ NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_session_encode(test_session_encode,
+ NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_session_decode(test_session_decode,
+ NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+APACHE_HTTPD_TEST_MODULE(test_session);
diff --git a/debian/perl-framework/c-modules/test_ssl/mod_test_ssl.c b/debian/perl-framework/c-modules/test_ssl/mod_test_ssl.c
new file mode 100644
index 0000000..c9bc762
--- /dev/null
+++ b/debian/perl-framework/c-modules/test_ssl/mod_test_ssl.c
@@ -0,0 +1,171 @@
+#define HTTPD_TEST_REQUIRE_APACHE 2
+
+#if CONFIG_FOR_HTTPD_TEST
+
+<IfModule @ssl_module@>
+ <Location /test_ssl_var_lookup>
+ SetHandler test-ssl-var-lookup
+ SSLVerifyClient require
+ SSLVerifyDepth 10
+ </Location>
+
+ <Location /test_ssl_ext_lookup>
+ SetHandler test-ssl-ext-lookup
+ SSLVerifyClient require
+ SSLVerifyDepth 10
+ </Location>
+</IfModule>
+
+#endif
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_protocol.h"
+#include "http_log.h"
+#include "ap_config.h"
+#include "apr_optional.h"
+
+#if AP_MODULE_MAGIC_AT_LEAST(20040425, 0) /* simply include mod_ssl.h if using >= 2.1.0 */
+
+#include "mod_ssl.h"
+
+#if MODULE_MAGIC_COOKIE > 0x41503234UL || \
+ (MODULE_MAGIC_COOKIE == 0x41503234UL \
+ && AP_MODULE_MAGIC_AT_LEAST(20050919, 0)) /* ssl_ext_list() only in 2.4.x */
+#define HAVE_SSL_EXT_LIST
+static APR_OPTIONAL_FN_TYPE(ssl_ext_list) *ext_list;
+#elif AP_MODULE_MAGIC_AT_LEAST(20050127, 0) /* approx. when ssl_ext_lookup was added */
+#define HAVE_SSL_EXT_LOOKUP
+static APR_OPTIONAL_FN_TYPE(ssl_ext_lookup) *ext_lookup;
+#endif
+
+#else
+/* For use of < 2.0.x, inline the declaration: */
+
+APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
+ (apr_pool_t *, server_rec *,
+ conn_rec *, request_rec *,
+ char *));
+
+#endif
+
+static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *var_lookup;
+
+static void import_ssl_var_lookup(void)
+{
+ var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
+#ifdef HAVE_SSL_EXT_LOOKUP
+ ext_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_ext_lookup);
+#endif
+#ifdef HAVE_SSL_EXT_LIST
+ ext_list = APR_RETRIEVE_OPTIONAL_FN(ssl_ext_list);
+#endif
+}
+
+#if defined(HAVE_SSL_EXT_LOOKUP) || defined(HAVE_SSL_EXT_LIST)
+static int test_ssl_ext_lookup(request_rec *r)
+{
+ const char *value;
+
+ if (strcmp(r->handler, "test-ssl-ext-lookup")
+ || r->method_number != M_GET) {
+ return DECLINED;
+ }
+
+ if (!r->args) {
+ ap_rputs("no query", r);
+ return OK;
+ }
+
+#ifdef HAVE_SSL_EXT_LOOKUP
+ if (!ext_lookup) {
+ ap_rputs("ssl_ext_lookup not available", r);
+ return OK;
+ }
+
+ value = ext_lookup(r->pool, r->connection, 1, r->args);
+#else
+ if (!ext_list) {
+ ap_rputs("ssl_ext_list not available", r);
+ return OK;
+ }
+
+ {
+ apr_array_header_t *vals = ext_list(r->pool, r->connection, 1,
+ r->args);
+
+ if (vals) {
+ value = *(const char **)apr_array_pop(vals);
+ }
+ else {
+ value = NULL;
+ }
+ }
+#endif
+
+ if (!value) value = "NULL";
+
+ ap_rputs(value, r);
+
+ return OK;
+}
+
+#endif
+
+static int test_ssl_var_lookup(request_rec *r)
+{
+ const char *value;
+
+ if (strcmp(r->handler, "test-ssl-var-lookup")) {
+ return DECLINED;
+ }
+
+ if (r->method_number != M_GET) {
+ return DECLINED;
+ }
+
+ if (!r->args) {
+ ap_rputs("no query", r);
+ return OK;
+ }
+
+ apr_table_setn(r->subprocess_env, "THE_ARGS", r->args);
+
+ if (!var_lookup) {
+ ap_rputs("ssl_var_lookup is not available", r);
+ return OK;
+ }
+
+ value = var_lookup(r->pool, r->server,
+ r->connection, r, r->args);
+
+ if (value && *value) {
+ ap_rputs(value, r);
+ }
+ else {
+ ap_rputs("NULL", r);
+ }
+
+ return OK;
+}
+
+static void test_ssl_register_hooks(apr_pool_t *p)
+{
+ ap_hook_handler(test_ssl_var_lookup, NULL, NULL, APR_HOOK_MIDDLE);
+#if defined(HAVE_SSL_EXT_LOOKUP) || defined(HAVE_SSL_EXT_LIST)
+ ap_hook_handler(test_ssl_ext_lookup, NULL, NULL, APR_HOOK_MIDDLE);
+#endif
+ ap_hook_optional_fn_retrieve(import_ssl_var_lookup,
+ NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+module AP_MODULE_DECLARE_DATA test_ssl_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_ssl_register_hooks /* register hooks */
+};
+
diff --git a/debian/perl-framework/c-modules/test_utilities/mod_test_utilities.c b/debian/perl-framework/c-modules/test_utilities/mod_test_utilities.c
new file mode 100644
index 0000000..5236585
--- /dev/null
+++ b/debian/perl-framework/c-modules/test_utilities/mod_test_utilities.c
@@ -0,0 +1,48 @@
+#define HTTPD_TEST_REQUIRE_APACHE 2.4
+
+/**
+ * This module provides utility functions for other tests; it doesn't provide
+ * test cases of its own.
+ */
+
+#define APACHE_HTTPD_TEST_EXTRA_HOOKS util_register_hooks
+#include "apache_httpd_test.h"
+
+#include "apr_strings.h"
+#include "ap_expr.h"
+
+/**
+ * The util_strlen() ap_expr function simply returns the length of its string
+ * argument as a decimal string.
+ */
+static const char *util_strlen_func(ap_expr_eval_ctx_t *ctx, const void *data,
+ const char *arg)
+{
+ if (!arg) {
+ return NULL;
+ }
+
+ return apr_psprintf(ctx->p, "%" APR_SIZE_T_FMT, strlen(arg));
+}
+
+static int util_expr_lookup(ap_expr_lookup_parms *parms)
+{
+ switch (parms->type) {
+ case AP_EXPR_FUNC_STRING:
+ if (!strcasecmp(parms->name, "util_strlen")) {
+ *parms->func = util_strlen_func;
+ *parms->data = "dummy";
+ return OK;
+ }
+ break;
+ }
+
+ return DECLINED;
+}
+
+static void util_register_hooks(apr_pool_t *p)
+{
+ ap_hook_expr_lookup(util_expr_lookup, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+APACHE_HTTPD_TEST_MODULE(test_utilities);