From 86b2d4fefed0fc0b9a4023937d5cfedc079372b2 Mon Sep 17 00:00:00 2001 From: Sascha Schumann Date: Sun, 29 Oct 2000 14:52:15 +0000 Subject: [PATCH] Add Request Body filters. This is a much nicer concept than ap_get_req_body, since it is much more flexible and does not need to buffer everything in memory (PHP still does..). --- sapi/apache2filter/php_apache.h | 7 ++- sapi/apache2filter/sapi_apache2.c | 75 +++++++++++++++++++++---------- 2 files changed, 58 insertions(+), 24 deletions(-) diff --git a/sapi/apache2filter/php_apache.h b/sapi/apache2filter/php_apache.h index f1feb4f65ad..a5930f0689c 100644 --- a/sapi/apache2filter/php_apache.h +++ b/sapi/apache2filter/php_apache.h @@ -5,7 +5,12 @@ typedef struct php_struct { int state; ap_bucket_brigade *bb; ap_filter_t *f; - int post_index; + /* Length of post_data buffer */ + int post_len; + /* Index for reading from buffer */ + int post_idx; + /* Buffer for request body filter */ + char *post_data; } php_struct; void *merge_php_config(apr_pool_t *p, void *base_conf, void *new_conf); diff --git a/sapi/apache2filter/sapi_apache2.c b/sapi/apache2filter/sapi_apache2.c index e30b8e4fdb9..b80b12cd259 100644 --- a/sapi/apache2filter/sapi_apache2.c +++ b/sapi/apache2filter/sapi_apache2.c @@ -88,22 +88,22 @@ php_apache_sapi_send_headers(sapi_headers_struct *sapi_headers SLS_DC) static int php_apache_sapi_read_post(char *buf, uint count_bytes SLS_DC) { - long total; - long n; - long start; + int n; + int to_read; php_struct *ctx = SG(server_context); - - start = ctx->post_index; - for (total = 0; total < count_bytes; total += n) { - n = ap_get_req_body(ctx->f->r, count_bytes - total, &ctx->post_index); - if (n <= 0) break; - } - if (total > 0) { - memcpy(buf, &ctx->f->r->req_body[start], total); + to_read = ctx->post_len - ctx->post_idx; + n = MIN(to_read, count_bytes); + + if (n > 0) { + memcpy(buf, ctx->post_data + ctx->post_idx, n); + ctx->post_idx += n; + } else { + if (ctx->post_data) free(ctx->post_data); + ctx->post_data = NULL; } - return total; + return n; } static char * @@ -201,22 +201,50 @@ static sapi_module_struct sapi_module = { module MODULE_VAR_EXPORT php4_module; +#define INIT_CTX \ + if (ctx == NULL) { \ + /* Initialize filter context */ \ + SG(server_context) = f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx)); \ + ctx->bb = ap_brigade_create(f->c->pool); \ + } + +static int php_rbody_filter(ap_filter_t *f, ap_bucket_brigade *bb) +{ + php_struct *ctx; + long old_index; + ap_bucket *b; + const char *str; + apr_ssize_t n; + SLS_FETCH(); + + ctx = SG(server_context); + + INIT_CTX; + + AP_BRIGADE_FOREACH(b, bb) { + ap_bucket_read(b, &str, &n, 1); + if (n > 0) { + old_index = ctx->post_len; + ctx->post_len += n; + ctx->post_data = realloc(ctx->post_data, ctx->post_len + 1); + memcpy(ctx->post_data + old_index, str, n); + } + } + return ap_pass_brigade(f->next, bb); +} + static int php_filter(ap_filter_t *f, ap_bucket_brigade *bb) { - php_struct *ctx = f->ctx; + php_struct *ctx; ap_bucket *b; apr_status_t rv; const char *str; apr_ssize_t n; - void *conf = ap_get_module_config(f->r->per_dir_config, - &php4_module); + void *conf = ap_get_module_config(f->r->per_dir_config, &php4_module); SLS_FETCH(); - if (ctx == NULL) { - /* Initialize filter context */ - SG(server_context) = f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx)); - ctx->bb = ap_brigade_create(f->c->pool); - } + ctx = SG(server_context); + INIT_CTX; ctx->f = f; @@ -329,12 +357,12 @@ skip_execution: ok: php_request_shutdown(NULL); + SG(server_context) = 0; /* Pass EOS bucket to next filter to signal end of request */ - eos = ap_bucket_create_flush(); - AP_BRIGADE_INSERT_TAIL(bb, eos); eos = ap_bucket_create_eos(); AP_BRIGADE_INSERT_TAIL(bb, eos); - ap_pass_brigade(f->next, bb); + + return ap_pass_brigade(f->next, bb); } else ap_brigade_destroy(bb); @@ -363,6 +391,7 @@ static void php_register_hook(void) { ap_hook_child_init(php_apache_server_startup, NULL, NULL, AP_HOOK_MIDDLE); ap_register_output_filter("PHP", php_filter, AP_FTYPE_CONTENT); + ap_register_rbody_filter("PHP", php_rbody_filter, AP_FTYPE_CONTENT); } module MODULE_VAR_EXPORT php4_module = {