summaryrefslogtreecommitdiffstats
path: root/debian/perl-framework/c-modules/input_body_filter/mod_input_body_filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'debian/perl-framework/c-modules/input_body_filter/mod_input_body_filter.c')
-rw-r--r--debian/perl-framework/c-modules/input_body_filter/mod_input_body_filter.c184
1 files changed, 184 insertions, 0 deletions
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 */
+};
+