/***************************** * This module was conceived by Dave Buchanan and Karl Royer and Ryan Bloom * The implementation was done by Ryan, so any bugs should be laid at his * doorstep. Any brilliant ideas (such as fixing this in a filter) go to * Dave and Karl. :-) */ #include "apr_strings.h" #include "ap_config.h" #include "util_filter.h" #include "httpd.h" #include "http_config.h" #include "http_request.h" #include "http_core.h" #include "http_protocol.h" #include "http_connection.h" #include "http_log.h" #include "http_main.h" #include "util_script.h" #include "http_core.h" #include "apr_hooks.h" module AP_MODULE_DECLARE_DATA apachecon_module; static apr_status_t apcon_filter_in(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes) { const char *str; const char *begin; int length; apr_bucket *e; apr_bucket *d; char data[256]; int i,j; ap_get_brigade(f->next, b, mode, block, readbytes); e = APR_BRIGADE_FIRST(b); if (e->type == NULL) { return APR_SUCCESS; } apr_bucket_read(e, &str, &length, 1); if (strncmp("GET ", str, strlen("GET "))) { return APR_SUCCESS; } apr_bucket_split(e, strlen("GET ")); e = APR_BUCKET_NEXT(e); apr_bucket_read(e, &str, &length, 1); /* this should work, because we are just searching for HTTP/1.0 or HTTP/1.1 */ begin = str + (strlen(str) - 3); do { begin--; } while (strncmp("HTTP", begin, 4) && (begin > str)); apr_bucket_split(e, begin - str - 1); apr_bucket_read(e, &str, &length, 1); i = 0; j = 0; while (i < length) { if (str[i] == ' ') { data[j++] = '%'; data[j++] = '2'; data[j++] = '0'; i++; } else if (str[i] == '\\') { data[j++] = '/'; i++; } else { data[j++] = str[i++]; } } d = apr_bucket_transient_create(data, j, b->bucket_alloc); apr_bucket_setaside(d, f->c->pool); APR_BUCKET_INSERT_AFTER(e, d); APR_BUCKET_REMOVE(e); apr_bucket_destroy(e); return APR_SUCCESS; } static int apcon_pre(conn_rec *c, void *csd) { ap_add_input_filter("APACHECON_IN", NULL, NULL, c); return OK; } static void hf_register_hook(apr_pool_t *p) { ap_hook_pre_connection(apcon_pre, NULL, NULL, APR_HOOK_MIDDLE); ap_register_input_filter("APACHECON_IN", apcon_filter_in, NULL, AP_FTYPE_CONNECTION); } module AP_MODULE_DECLARE_DATA apachecon_module = { STANDARD20_MODULE_STUFF, NULL, /* create per-directory config structure */ NULL, /* merge per-directory config structures */ NULL, /* create per-server config structure */ NULL, /* merge per-server config structures */ NULL, /* command apr_table_t */ hf_register_hook /* register hooks */ };