]> granicus.if.org Git - php/commitdiff
Add Request Body filters. This is a much nicer concept than
authorSascha Schumann <sas@php.net>
Sun, 29 Oct 2000 14:52:15 +0000 (14:52 +0000)
committerSascha Schumann <sas@php.net>
Sun, 29 Oct 2000 14:52:15 +0000 (14:52 +0000)
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
sapi/apache2filter/sapi_apache2.c

index f1feb4f65adfec69dd011b32e639127226965ae2..a5930f0689c48e7efd0ff2051c39a22f7d86d5a0 100644 (file)
@@ -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);
index e30b8e4fdb9c790492eaf58497bca10569c75c37..b80b12cd25953f1c7b55b25d6c14e6b4f01e40f7 100644 (file)
@@ -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 = {