httpd-apreq-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r151386 [1/4] - in httpd/apreq/branches/multi-env-unstable: ./ build/ env/ env/c-modules/apreq_access_test/ env/c-modules/apreq_big_request_test/ env/c-modules/apreq_cookie_test/ env/c-modules/apreq_output_filter_test/ env/c-modules/apreq_redirect_test/ env/c-modules/apreq_request_test/ src/ t/
Date Fri, 04 Feb 2005 18:28:04 GMT
Author: joes
Date: Fri Feb  4 10:27:55 2005
New Revision: 151386

URL: http://svn.apache.org/viewcvs?view=rev&rev=151386
Log:
  Widespread API refactorization to remove apreq_jar_t and apreq_request_t:
  
  - Header includes reorganized; apreq_parsers.h added (back again).
  - Replaced apreq_jar_t and apreq_request_t with single apreq_env_handle_t.
  - Added const qualifier to "v" attribute of apreq_cookie_t and apreq_param_t.
  - Use union type-puns to drop const qualifiers inside the new
    apreq_value_to_cookie and apreq_value_to_param implementations
    (gcc generates same object code as the macro versions did).
  - Moved "flags" attribute from apreq_value_t to apreq_cookie_t and apreq_param_t.
  - Remove env argument from hooks and parsers.
  - Reduce apreq_env_module to minimal set of operations.
  - Replace apreq_log calls with apreq-specific error codes.
  - Hooks are called on each body param now, not just during file uploads.
  - Tie the cgi handle to its creator pool.

  Detailed changes by header file:

  [apreq.h]
  - Remove flags from apreq_value_t.
  - Remove const qualifier from apreq_value_t's "name" attribute.
  - Remove apreq_value_merge* and apreq_value_copy*.
  - Remove apreq_char_to_value, apreq_strtoval, and apreq_strlen.
  - Move apreq_enctype to apreq_env.h.
  - Move apreq_env_handle_t struct definition to apreq_env.h
  - Change signature of apreq_decode.
  - Move apreq_brigade_concat here, changed its signature and improved it alot.
  - Remove apreq_brigade_spoolfile.
  - Dropped APREQ_*_ENCTYPE, renamed some APREQ_$foo defaults APREQ_DEFAULT_$foo.
  - Added APREQ_ERROR_*.

  [apreq_cookie.h]
  - Remove apreq_env.h include.
  - Remove apreq_jar_t.
  - Add "flags" to apreq_cookie_t, add const qualifier to its "v" attr.
  - Remove apreq_jar* functions.
  - Add apreq_parse_cookie_header.
  - Move apreq_cookie, apreq_cookie_bake(2), and 
    apreq_ua_cookie_version to apreq_env.h.

  [apreq_params.h]
  - Remove apreq_env.h include.
  - Remove apreq_request_t.
  - Add "flags" to apreq_param_t, and const qualifier to its "v" attr.
  - Rename "bb" attribute "upload" in apreq_param_t.
  - Remove apreq_request* functions.
  - Remove apreq_parse_request.
  - Changed apreq_decode_param signature.
  - Replace env argument with apr_table_t in apreq_params_as_array,
    apreq_params_as_string,
  - Move remaining apreq_param* to apreq_env.h.
  - Move parser and hook sections to apreq_parsers.h.
  - Change apreq_upload(s) old apreq_request_t arg to apr_table_t.

  [apreq_parsers.h]
  - Acquire the hook and parser sections of original apreq_params.h.
  - Remove env argument from APREQ_PARSER_ARGS and APREQ_HOOK_ARGS
  - Augment apreq_hook_t and apreq_parser_t to replace missing env features.
  - Change apreq_make_parser and apreq_make_hook signatures.
  - Rename apreq_add_hook to apreq_parser_add_hook, returning apr_status_t.
  - Change apreq_parser signature.

  [apreq_env.h]
  - Remove read, log, pool, bucket_alloc, request, jar, and query_string methods.
  - Include apreq_parsers.h.
  - Reorganize apreq_env_module_t to provide hook, parser, jar, args,
    & body table ops.
  - Rename max_brigade to "brigade_limit", max_body to "read_limit".
  - Change related module sigs, including temp_dir, to get/set methods.
  - Add parser and read_limit args to apreq_env_make_custom_handle.
  - Drop "name" arg and APREQ_ENV_MODULE =~ s/_ENV//.
  - s/apreq_env_make/apreq_handle/ in the handle constructor names.

  [mod_apreq.c, apreq_env_apache2.h]
  - Changed APREQ_Max* configs to APREQ_BrigadeLimit and APREQ_ReadLimit.
  - Handle constructor renamed apreq_handle_apache2.

Added:
    httpd/apreq/branches/multi-env-unstable/src/apreq_parsers.h
    httpd/apreq/branches/multi-env-unstable/t/test_module.c
    httpd/apreq/branches/multi-env-unstable/t/test_module.h
Modified:
    httpd/apreq/branches/multi-env-unstable/CHANGES
    httpd/apreq/branches/multi-env-unstable/STATUS
    httpd/apreq/branches/multi-env-unstable/acinclude.m4
    httpd/apreq/branches/multi-env-unstable/build/get-version.sh
    httpd/apreq/branches/multi-env-unstable/env/apreq_env_apache2.h
    httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_access_test/mod_apreq_access_test.c
    httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_big_request_test/mod_apreq_big_request_test.c
    httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_cookie_test/mod_apreq_cookie_test.c
    httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_output_filter_test/mod_apreq_output_filter_test.c
    httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_redirect_test/mod_apreq_redirect_test.c
    httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_request_test/mod_apreq_request_test.c
    httpd/apreq/branches/multi-env-unstable/env/mod_apreq.c
    httpd/apreq/branches/multi-env-unstable/env/test_cgi.c
    httpd/apreq/branches/multi-env-unstable/src/Makefile.am
    httpd/apreq/branches/multi-env-unstable/src/README
    httpd/apreq/branches/multi-env-unstable/src/apreq.c
    httpd/apreq/branches/multi-env-unstable/src/apreq.h
    httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.c
    httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.h
    httpd/apreq/branches/multi-env-unstable/src/apreq_env.c
    httpd/apreq/branches/multi-env-unstable/src/apreq_env.h
    httpd/apreq/branches/multi-env-unstable/src/apreq_env_cgi.c
    httpd/apreq/branches/multi-env-unstable/src/apreq_env_custom.c
    httpd/apreq/branches/multi-env-unstable/src/apreq_params.c
    httpd/apreq/branches/multi-env-unstable/src/apreq_params.h
    httpd/apreq/branches/multi-env-unstable/src/apreq_parsers.c
    httpd/apreq/branches/multi-env-unstable/t/Makefile.am
    httpd/apreq/branches/multi-env-unstable/t/cookie.c
    httpd/apreq/branches/multi-env-unstable/t/params.c
    httpd/apreq/branches/multi-env-unstable/t/parsers.c
    httpd/apreq/branches/multi-env-unstable/t/test_apreq.h

Modified: httpd/apreq/branches/multi-env-unstable/CHANGES
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/CHANGES?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/CHANGES (original)
+++ httpd/apreq/branches/multi-env-unstable/CHANGES Fri Feb  4 10:27:55 2005
@@ -4,6 +4,89 @@
 
 @section v2_05 Changes with libapreq2-2.05
 
+- C API [joes]
+  Widespread API refactorization to remove apreq_jar_t and apreq_request_t:
+  
+  - Header includes reorganized; apreq_parsers.h added (back again).
+  - Replaced apreq_jar_t and apreq_request_t with single apreq_env_handle_t.
+  - Added const qualifier to "v" attribute of apreq_cookie_t and apreq_param_t.
+  - Use union type-puns to drop const qualifiers inside the new
+    apreq_value_to_cookie and apreq_value_to_param implementations
+    (gcc generates same object code as the macro versions did).
+  - Moved "flags" attribute from apreq_value_t to apreq_cookie_t and apreq_param_t.
+  - Remove env argument from hooks and parsers.
+  - Reduce apreq_env_module to minimal set of operations.
+  - Replace apreq_log calls with apreq-specific error codes.
+  - Hooks are called on each body param now, not just during file uploads.
+  - Tie the cgi handle to its creator pool.
+
+  Detailed changes by header file:
+
+  [apreq.h]
+  - Remove flags from apreq_value_t.
+  - Remove const qualifier from apreq_value_t's "name" attribute.
+  - Remove apreq_value_merge* and apreq_value_copy*.
+  - Remove apreq_char_to_value, apreq_strtoval, and apreq_strlen.
+  - Move apreq_enctype to apreq_env.h.
+  - Move apreq_env_handle_t struct definition to apreq_env.h
+  - Change signature of apreq_decode.
+  - Move apreq_brigade_concat here, changed its signature and improved it alot.
+  - Remove apreq_brigade_spoolfile.
+  - Dropped APREQ_*_ENCTYPE, renamed some APREQ_$foo defaults APREQ_DEFAULT_$foo.
+  - Added APREQ_ERROR_*.
+
+  [apreq_cookie.h]
+  - Remove apreq_env.h include.
+  - Remove apreq_jar_t.
+  - Add "flags" to apreq_cookie_t, add const qualifier to its "v" attr.
+  - Remove apreq_jar* functions.
+  - Add apreq_parse_cookie_header.
+  - Move apreq_cookie, apreq_cookie_bake(2), and 
+    apreq_ua_cookie_version to apreq_env.h.
+
+  [apreq_params.h]
+  - Remove apreq_env.h include.
+  - Remove apreq_request_t.
+  - Add "flags" to apreq_param_t, and const qualifier to its "v" attr.
+  - Rename "bb" attribute "upload" in apreq_param_t.
+  - Remove apreq_request* functions.
+  - Remove apreq_parse_request.
+  - Changed apreq_decode_param signature.
+  - Replace env argument with apr_table_t in apreq_params_as_array,
+    apreq_params_as_string,
+  - Move remaining apreq_param* to apreq_env.h.
+  - Move parser and hook sections to apreq_parsers.h.
+  - Change apreq_upload(s) old apreq_request_t arg to apr_table_t.
+
+  [apreq_parsers.h]
+  - Acquire the hook and parser sections of original apreq_params.h.
+  - Remove env argument from APREQ_PARSER_ARGS and APREQ_HOOK_ARGS
+  - Augment apreq_hook_t and apreq_parser_t to replace missing env features.
+  - Change apreq_make_parser and apreq_make_hook signatures.
+  - Rename apreq_add_hook to apreq_parser_add_hook, returning apr_status_t.
+  - Change apreq_parser signature.
+
+  [apreq_env.h]
+  - Remove read, log, pool, bucket_alloc, request, jar, and query_string methods.
+  - Include apreq_parsers.h.
+  - Reorganize apreq_env_module_t to provide hook, parser, jar, args,
+    & body table ops.
+  - Rename max_brigade to "brigade_limit", max_body to "read_limit".
+  - Change related module sigs, including temp_dir, to get/set methods.
+  - Add parser and read_limit args to apreq_env_make_custom_handle.
+  - Drop "name" arg and APREQ_ENV_MODULE =~ s/_ENV//.
+  - s/apreq_env_make/apreq_handle/ in the handle constructor names.
+
+  [mod_apreq.c, apreq_env_apache2.h]
+  - Changed APREQ_Max* configs to APREQ_BrigadeLimit and APREQ_ReadLimit.
+  - Handle constructor renamed apreq_handle_apache2.
+
+- C API [joes]
+  Make our "libtool current interface" number depend on apr's 
+  major number.  This allows libapreq2 to be installed into a 
+  system-wide location while avoiding ABI conflicts arising from
+  our apr-based interfaces.
+
 - C API [Max Kellermann]
   Introduce apreq_env_handle_t to replace the void *env usage.
   Also added apreq_env_custom for making private handles, and new 

Modified: httpd/apreq/branches/multi-env-unstable/STATUS
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/STATUS?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/STATUS (original)
+++ httpd/apreq/branches/multi-env-unstable/STATUS Fri Feb  4 10:27:55 2005
@@ -17,16 +17,20 @@
        place.
 
 
-     - joes: We will also remove apreq_jar_t and apreq_request_t.
-       Quick status update: I've implemented this, and have src/ 
-       and env/ compiling again here locally.  I'm working on the
-       tests now, and the (many, many) apidoc fixes, so it may be a 
-       few more days before I'm ready to commit these changes.
+     - joes: I removed apreq_jar_t and apreq_request_t.  The new
+       data structures should be ok, and all the C tests should pass.
+       The docs are in really bad shape now, but it didn't make
+       sense to fix those, at least until "apreq_env.h" is renamed 
+      "apreq_handle.h"  and both the custom & cgi modules have had 
+       time to improve.
 
 
 RELEASE SHOWSTOPPERS:
 
      - The api docs and perl glue are currently broken.
+     - Remove all "_env" tags, perhaps moving apreq_env.h to apreq_handle.h.
+     - Improve the APREQ_ERROR related code.
+     - Improve the custom & cgi module code.
 
 
 CURRENT VOTES:
@@ -47,12 +51,17 @@
 
 TODO:
 
-    - Perl glue, doc sync.
+    - Fix all the "//apreq_log" comments in the cgi tests.
 
-    - Hooks are called on each param now, not just on uploads.
-      This allows them to do more stuff (logging, diagnostics, taint checks).
+    - Let hooks interrupt parsers via APREQ_ERROR_INTERRUPT.  
+      Need a delete_hook method to make interrupts a useful
+      way of tuning parser behavior.
 
-    - Better error handling.
+    - Add a "memory_limit" setting to apreq_parser_t and apreq_module_t, 
+      which will control how much pool allocation the parser may use.
+
+    - Add a "header_limit" setting to control outgoing header size
+      (mainly for baking cookies) instead of using a compiled-in limit.
 
     - We need to add some basic charset support.  Long discussion 
       starts here:
@@ -65,10 +74,6 @@
     - Why must fprintf(stderr, ...), rather than
       apr_file_printf(err, ...), be used on Win32 in
       cgi_log() of src/apreq_env.c?
-
-    - The current tests don't cover these functions, 
-      so add CuTest tests for them:
-      -  apreq_merge_values()
 
     - CuTest needs va_arg to print comments for a failed unit test.
 

Modified: httpd/apreq/branches/multi-env-unstable/acinclude.m4
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/acinclude.m4?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/acinclude.m4 (original)
+++ httpd/apreq/branches/multi-env-unstable/acinclude.m4 Fri Feb  4 10:27:55 2005
@@ -53,7 +53,7 @@
                 APACHE2_INCLUDES=-I`$APACHE2_APXS -q INCLUDEDIR`
 
                 APR_MAJOR_VERSION=`$APACHE2_APXS -q APR_VERSION 2>/dev/null | cut -d. -f 1`
-                if test ${APR_MAJOR_VERSION:=0} -eq 0; then
+                if test ${APR_MAJOR_VERSION:="0"} -eq 0; then
                     apr_config=apr-config
                     apu_config=apu-config 
                 else
@@ -172,9 +172,19 @@
         get_version="$abs_srcdir/build/get-version.sh"
         version_hdr="$abs_srcdir/src/apreq_version.h"
 
-        APREQ_LIBTOOL_VERSION=`$get_version libtool $version_hdr APREQ`
+        # set version data
+
         APREQ_MAJOR_VERSION=`$get_version major $version_hdr APREQ`
-        APREQ_DOTTED_VERSION=`$get_version all $version_hdr APREQ`
+        APREQ_MINOR_VERSION=`$get_version minor $version_hdr APREQ`
+        APREQ_PATCH_VERSION=`$get_version patch $version_hdr APREQ`
+        APREQ_DOTTED_VERSION=`$get_version all  $version_hdr APREQ`
+
+        # XXX: APR_MAJOR_VERSION doesn't yet work for static builds
+        APREQ_LIBTOOL_CURRENT=`expr $APREQ_MAJOR_VERSION + $APREQ_MINOR_VERSION + $APR_MAJOR_VERSION`
+        APREQ_LIBTOOL_REVISION=$APREQ_PATCH_VERSION
+        APREQ_LIBTOOL_AGE=$APREQ_MINOR_VERSION
+
+        APREQ_LIBTOOL_VERSION="$APREQ_LIBTOOL_CURRENT:$APREQ_LIBTOOL_REVISION:$APREQ_LIBTOOL_AGE"
 
         APREQ_LIBNAME="apreq$APREQ_MAJOR_VERSION"
         APREQ_INCLUDES=""
@@ -215,7 +225,7 @@
 dnl
 dnl Saves a snapshot of the configure command-line for later reuse
 dnl
-AC_DEFUN(APR_CONFIG_NICE,[
+AC_DEFUN([APR_CONFIG_NICE],[
   rm -f $1
   cat >$1<<EOF
 #! /bin/sh

Modified: httpd/apreq/branches/multi-env-unstable/build/get-version.sh
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/build/get-version.sh?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/build/get-version.sh (original)
+++ httpd/apreq/branches/multi-env-unstable/build/get-version.sh Fri Feb  4 10:27:55 2005
@@ -8,12 +8,13 @@
 #
 #   get-version.sh all returns a dotted version number
 #   get-version.sh major returns just the major version number
-#   get-version.sh libtool returns a version "libtool -version-info" format
+#   get-version.sh minor returns just the minor version number
+#   get-version.sh patch returns just the match version number
 #
 
 if test $# != 3; then
   echo "USAGE: $0 CMD INCLUDEDIR PREFIX"
-  echo "  where CMD is one of: all, major, libtool"
+  echo "  where CMD is one of: all, major, minor, patch"
   exit 1
 fi
 
@@ -23,14 +24,15 @@
 major="`sed -n $major_sed $2`"
 minor="`sed -n $minor_sed $2`"
 patch="`sed -n $patch_sed $2`"
-ltmaj="`expr $major + $minor`"
 
 if test "$1" = "all"; then
   echo ${major}.${minor}.${patch}
 elif test "$1" = "major"; then
   echo ${major}
-elif test "$1" = "libtool"; then
-  echo ${ltmaj}:${patch}:${minor}
+elif test "$1" = "minor"; then
+  echo ${minor}
+elif test "$1" = "patch"; then
+  echo ${patch}
 else
   echo "ERROR: unknown version CMD ($1)"
   exit 1

Modified: httpd/apreq/branches/multi-env-unstable/env/apreq_env_apache2.h
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/env/apreq_env_apache2.h?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/env/apreq_env_apache2.h (original)
+++ httpd/apreq/branches/multi-env-unstable/env/apreq_env_apache2.h Fri Feb  4 10:27:55 2005
@@ -28,7 +28,7 @@
  * Create an apreq handle which communicates with an Apache 2
  * request_rec.
  */
-APREQ_DECLARE(apreq_env_handle_t*) apreq_env_make_apache2(request_rec *r);
+APREQ_DECLARE(apreq_env_handle_t*) apreq_handle_apache2(request_rec *r);
 
 #ifdef __cplusplus
  }

Modified: httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_access_test/mod_apreq_access_test.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_access_test/mod_apreq_access_test.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_access_test/mod_apreq_access_test.c (original)
+++ httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_access_test/mod_apreq_access_test.c Fri Feb  4 10:27:55 2005
@@ -30,7 +30,6 @@
 #define APACHE_HTTPD_TEST_PER_DIR_CREATE create_access_config 
 
 #include "apache_httpd_test.h"
-#include "apreq_params.h"
 #include "apreq_env.h"
 #include "apreq_env_apache2.h"
 #include "httpd.h"
@@ -67,7 +66,6 @@
 static int apreq_access_checker(request_rec *r)
 {
     apreq_env_handle_t *handle;
-    apreq_request_t *req;
     apreq_param_t *param;
     struct access_test_cfg *cfg = (struct access_test_cfg *)
         ap_get_module_config(r->per_dir_config, &apreq_access_test_module);
@@ -75,17 +73,25 @@
     if (!cfg || !cfg->param)
         return DECLINED;
 
-    handle = apreq_env_make_apache2(r);
-    req = apreq_request(handle, NULL);
-    param = apreq_param(req, cfg->param);
-    if (param) {
-        apreq_log(APREQ_DEBUG 0, handle, "%s => %s", cfg->param, param->v.data);
+    handle = apreq_handle_apache2(r);
+    param = apreq_param(handle, cfg->param);
+    if (param != NULL) {
+        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
+                      r, "ACCESS GRANTED: %s => %s", cfg->param, param->v.data);
         return OK;
     }
     else {
-        if (req->body)
-            apreq_log(APREQ_DEBUG HTTP_FORBIDDEN, handle, "%s not found in %d elts",
-                      cfg->param, apr_table_elts(req->body)->nelts);
+        const apr_table_t *t = apreq_params(r->pool, handle);
+        if (t != NULL) {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_EGENERAL, r, 
+                          "%s not found: parsing error detected (%d params)",
+                          cfg->param, apr_table_elts(t)->nelts);
+        }
+        else {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_EGENERAL, r, 
+                          "%s not found: paring error detected (no param table)",
+                          cfg->param);
+        }
         return HTTP_FORBIDDEN;
     }
 }

Modified: httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_big_request_test/mod_apreq_big_request_test.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_big_request_test/mod_apreq_big_request_test.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_big_request_test/mod_apreq_big_request_test.c (original)
+++ httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_big_request_test/mod_apreq_big_request_test.c Fri Feb  4 10:27:55 2005
@@ -27,7 +27,6 @@
 #define APACHE_HTTPD_TEST_HANDLER apreq_big_request_test_handler
 
 #include "apache_httpd_test.h"
-#include "apreq_params.h"
 #include "apreq_env.h"
 #include "apreq_env_apache2.h"
 #include "httpd.h"
@@ -42,18 +41,15 @@
 static int apreq_big_request_test_handler(request_rec *r)
 {
     apreq_env_handle_t *env;
-    apreq_request_t *req;
     apr_table_t *params;
     int count = 0;
 
     if (strcmp(r->handler, "apreq_big_request_test") != 0)
         return DECLINED;
 
-    env = apreq_env_make_apache2(r);
+    env = apreq_handle_apache2(r);
 
-    apreq_log(APREQ_DEBUG 0, env, "initializing request");
-    req = apreq_request(env, NULL);
-    params = apreq_params(r->pool, req);
+    params = apreq_params(r->pool, env);
     apr_table_do(dump_table, &count, params, NULL);
     ap_set_content_type(r, "text/plain");
     ap_rprintf(r, "%d", count);

Modified: httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_cookie_test/mod_apreq_cookie_test.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_cookie_test/mod_apreq_cookie_test.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_cookie_test/mod_apreq_cookie_test.c (original)
+++ httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_cookie_test/mod_apreq_cookie_test.c Fri Feb  4 10:27:55 2005
@@ -27,51 +27,67 @@
 #define APACHE_HTTPD_TEST_HANDLER apreq_cookie_test_handler
 
 #include "apache_httpd_test.h"
-#include "apreq_params.h"
 #include "apreq_env.h"
-#include "apreq_cookie.h"
 #include "apreq_env_apache2.h"
 #include "httpd.h"
+#include <assert.h>
+
+
+static int dump_table(void *ctx, const char *key, const char *value)
+{
+    request_rec *r = ctx;
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
+                  r, "[%s] => [%s]", key, value);
+    return 1;
+}
+
 
 static int apreq_cookie_test_handler(request_rec *r)
 {
-    apreq_env_handle_t *env;
-    apreq_request_t *req;
+    apreq_env_handle_t *req;
     apr_status_t s;
-    const apreq_jar_t *jar;
-    const apreq_param_t *test, *key;
+    const char *test, *key;
     apreq_cookie_t *cookie;
-    apr_ssize_t ssize;
     apr_size_t size;
     char *dest;
+    const apr_table_t *args;
 
     if (strcmp(r->handler, "apreq_cookie_test") != 0)
         return DECLINED;
 
-    env = apreq_env_make_apache2(r);
+    req = apreq_handle_apache2(r);
+
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, 
+                  "starting cookie tests");
+
+    apreq_args(req, &args);
+
+    apr_table_do(dump_table, r, args, NULL);
+
+    test = apr_table_get(args, "test");
+    key = apr_table_get(args, "key");
+
+    cookie = apreq_cookie(req, key);
 
-    apreq_log(APREQ_DEBUG 0, env, "initializing request");
-    req = apreq_request(env, NULL);
-    test = apreq_param(req, "test");
-    key = apreq_param(req, "key");
-
-    apreq_log(APREQ_DEBUG 0, env, "initializing cookie");
-    jar = apreq_jar(env, NULL);
-    cookie = apreq_cookie(jar, key->v.data);
     ap_set_content_type(r, "text/plain");
 
-    if (strcmp(test->v.data, "bake") == 0) {
-        s = apreq_cookie_bake(cookie, env);
+    if (strcmp(test, "bake") == 0) {
+        s = apreq_cookie_bake(cookie, req);
     }
-    else if (strcmp(test->v.data, "bake2") == 0) {
-        s = apreq_cookie_bake2(cookie, env);
+    else if (strcmp(test, "bake2") == 0) {
+        s = apreq_cookie_bake2(cookie, req);
     }
     else {
         size = strlen(cookie->v.data);
         dest = apr_palloc(r->pool, size + 1);
-        ssize = apreq_decode(dest, cookie->v.data, size);
-        ap_rprintf(r, "%s", dest);
+        s = apreq_decode(dest, &size, cookie->v.data, size);
+        if (s == APR_SUCCESS)
+            ap_rprintf(r, "%s", dest);
     }
+
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, s, r, 
+                  "finished cookie tests");
+
     return OK;
 }
 

Modified: httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_output_filter_test/mod_apreq_output_filter_test.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_output_filter_test/mod_apreq_output_filter_test.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_output_filter_test/mod_apreq_output_filter_test.c (original)
+++ httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_output_filter_test/mod_apreq_output_filter_test.c Fri Feb  4 10:27:55 2005
@@ -37,9 +37,7 @@
 static apr_status_t apreq_output_filter_test_init(ap_filter_t *f)
 {
     apreq_env_handle_t *handle;
-    apreq_request_t *req;
-    handle = apreq_env_make_apache2(f->r);
-    req = apreq_request(handle, NULL);
+    handle = apreq_handle_apache2(f->r);
     return APR_SUCCESS;
 }
 
@@ -50,10 +48,9 @@
 
 static int dump_table(void *data, const char *key, const char *value)
 {
-    apreq_env_handle_t *env;
     struct ctx_t *ctx = (struct ctx_t *)data;
-    env = apreq_env_make_apache2(ctx->r);
-    apreq_log(APREQ_DEBUG 0, env, "%s => %s", key, value);
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ctx->r, 
+                  "%s => %s", key, value);
     apr_brigade_printf(ctx->bb,NULL,NULL,"\t%s => %s\n", key, value);
     return 1;
 }
@@ -61,25 +58,30 @@
 static apr_status_t apreq_output_filter_test(ap_filter_t *f, apr_bucket_brigade *bb)
 {
     request_rec *r = f->r;
-    apreq_env_handle_t *env;
-    apreq_request_t *req;
+    apreq_env_handle_t *handle;
     apr_bucket_brigade *eos;
     struct ctx_t ctx = {r, bb};
+    const apr_table_t *t;
 
     if (!APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb)))
         return ap_pass_brigade(f->next,bb);
 
     eos = apr_brigade_split(bb, APR_BRIGADE_LAST(bb));
 
-    env = apreq_env_make_apache2(r);
-    req = apreq_request(env, NULL);
-    apreq_log(APREQ_DEBUG 0, env, "appending parsed data");
+    handle = apreq_handle_apache2(r);
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, 
+                  "appending parsed data");
+
     apr_brigade_puts(bb, NULL, NULL, "\n--APREQ OUTPUT FILTER--\nARGS:\n");
-    apr_table_do(dump_table, &ctx, req->args, NULL);
 
-    if (req->body) {
+    apreq_args(handle, &t);
+    if (t != NULL)
+        apr_table_do(dump_table, &ctx, t, NULL);
+
+    apreq_body(handle, &t);
+    if (t != NULL) {
         apr_brigade_puts(bb,NULL,NULL,"BODY:\n");
-        apr_table_do(dump_table,&ctx,req->body,NULL);
+        apr_table_do(dump_table, &ctx, t, NULL);
     }
     APR_BRIGADE_CONCAT(bb,eos);
     return ap_pass_brigade(f->next,bb);

Modified: httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_redirect_test/mod_apreq_redirect_test.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_redirect_test/mod_apreq_redirect_test.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_redirect_test/mod_apreq_redirect_test.c (original)
+++ httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_redirect_test/mod_apreq_redirect_test.c Fri Feb  4 10:27:55 2005
@@ -28,28 +28,27 @@
 #define APACHE_HTTPD_TEST_HANDLER apreq_redirect_test_handler
 
 #include "apache_httpd_test.h"
-#include "apreq_params.h"
 #include "apreq_env.h"
 #include "apreq_env_apache2.h"
 #include "httpd.h"
 
 static int apreq_redirect_test_handler(request_rec *r)
 {
-    apreq_env_handle_t *env;
-    apreq_request_t *req;
+    apreq_env_handle_t *req;
     const apreq_param_t *loc;
 
     if (strcmp(r->handler, "apreq_redirect_test") != 0)
         return DECLINED;
 
-    env = apreq_env_make_apache2(r);
+    req = apreq_handle_apache2(r);
 
-    req = apreq_request(env, NULL);
-    apreq_log(APREQ_DEBUG 0, env, "looking for new location");
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
+                  r, "looking for new location");
     loc = apreq_param(req, "location");
     if (!loc)
         return DECLINED;
-    apreq_log(APREQ_DEBUG 0, env, "redirecting to %s", loc->v.data);
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
+                  r, "redirecting to %s", loc->v.data);
     ap_internal_redirect(loc->v.data, r);
     return OK;
 }

Modified: httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_request_test/mod_apreq_request_test.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_request_test/mod_apreq_request_test.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_request_test/mod_apreq_request_test.c (original)
+++ httpd/apreq/branches/multi-env-unstable/env/c-modules/apreq_request_test/mod_apreq_request_test.c Fri Feb  4 10:27:55 2005
@@ -18,7 +18,7 @@
 #if CONFIG_FOR_HTTPD_TEST
 
 <Location /apreq_request_test>
-   APREQ_MaxBody 500K
+   APREQ_ReadLimit 500K
    SetHandler apreq_request_test
 </Location>
 
@@ -28,7 +28,6 @@
 #define APACHE_HTTPD_TEST_HANDLER apreq_request_test_handler
 
 #include "apache_httpd_test.h"
-#include "apreq_params.h"
 #include "apreq_env.h"
 #include "apreq_env_apache2.h"
 #include "httpd.h"
@@ -36,48 +35,44 @@
 static int dump_table(void *ctx, const char *key, const char *value)
 {
     request_rec *r = ctx;
-    apreq_env_handle_t *env;
-    env = apreq_env_make_apache2(r);
-    apreq_log(APREQ_DEBUG 0, env, "%s => %s", key, value);
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
+                  r, "%s => %s", key, value);
     ap_rprintf(r, "\t%s => %s\n", key, value);
     return 1;
 }
 
 static int apreq_request_test_handler(request_rec *r)
 {
-    apreq_env_handle_t *env;
-    apr_bucket_brigade *bb;
-    apreq_request_t *req;
+    apreq_env_handle_t *req;
+    const apr_table_t *t;
     apr_status_t s;
 
     if (strcmp(r->handler, "apreq_request_test") != 0)
         return DECLINED;
 
-    env = apreq_env_make_apache2(r);
+    req = apreq_handle_apache2(r);
 
-    apreq_log(APREQ_DEBUG 0, env, "initializing request");
-    req = apreq_request(env, NULL);
-    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
-
-    apreq_log(APREQ_DEBUG 0, env, "start parsing body");
-    while ((s =ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
-                              APR_BLOCK_READ, HUGE_STRING_LEN)) == APR_SUCCESS)
-    {
-        if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb)))
-            break;
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
+                  r, "starting apreq_request_test");
 
-        apr_brigade_cleanup(bb);
+    s = ap_discard_request_body(r);
 
-    }
-    apreq_log(APREQ_DEBUG s, env, "finished parsing body");
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, s,
+                  r, "discard request body");
 
     ap_set_content_type(r, "text/plain");
     ap_rputs("ARGS:\n",r);
-    apr_table_do(dump_table, r, req->args, NULL);
-    if (req->body) {
+    if (apreq_args(req, &t) == APR_SUCCESS)
+        apr_table_do(dump_table, r, t, NULL);
+
+    if (apreq_body(req, &t) == APR_SUCCESS) {
         ap_rputs("BODY:\n",r);
-        apr_table_do(dump_table, r, req->body, NULL);
+        apr_table_do(dump_table, r, t, NULL);
     }
+
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS,
+                  r, "finished apreq_request_test");
+
     return OK;
 }
 

Modified: httpd/apreq/branches/multi-env-unstable/env/mod_apreq.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/env/mod_apreq.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/env/mod_apreq.c (original)
+++ httpd/apreq/branches/multi-env-unstable/env/mod_apreq.c Fri Feb  4 10:27:55 2005
@@ -14,6 +14,8 @@
 **  limitations under the License.
 */
 
+#include "assert.h"
+
 #include "httpd.h"
 #include "http_config.h"
 #include "http_log.h"
@@ -29,60 +31,47 @@
 #include "apreq_cookie.h"
 #include "apreq_env_apache2.h"
 
-#define dR      struct env_config *c = (struct env_config*)env;\
-    request_rec *r = c->r;\
-    (void)r;
+static const char filter_name[] = "apreq";
 
 struct dir_config {
     const char         *temp_dir;
-    apr_off_t           max_body;
-    apr_ssize_t         max_brigade;
+    apr_uint64_t        read_limit;
+    apr_size_t          brigade_limit;
 };
 
-
-static void *apreq_create_dir_config(apr_pool_t *p, char *d)
-{
-    /* d == OR_ALL */
-    struct dir_config *dc = apr_palloc(p, sizeof *dc);
-    dc->temp_dir    = NULL;
-    dc->max_body    = -1;
-    dc->max_brigade = APREQ_MAX_BRIGADE_LEN;
-    return dc;
-}
-
-static void *apreq_merge_dir_config(apr_pool_t *p, void *a_, void *b_)
-{
-    struct dir_config *a = a_, *b = b_, *c = apr_palloc(p, sizeof *c);
-    c->temp_dir    = (b->temp_dir != NULL)    ? b->temp_dir    : a->temp_dir;
-    c->max_body    = (b->max_body >= 0)       ? b->max_body    : a->max_body;
-    c->max_brigade = (b->max_brigade >= 0)    ? b->max_brigade : a->max_brigade;
-    return c;
-}
-
-
 /* The "warehouse", stored in r->request_config */
-struct env_config {
+struct apache2_handle {
     apreq_env_handle_t  env;
     request_rec        *r;
-    apreq_jar_t        *jar;    /* Active jar for the current request_rec */
-    apreq_request_t    *req;    /* Active request for current request_rec */
-    ap_filter_t        *f;      /* Active apreq filter for this request_rec */
-    const char         *temp_dir; /* Temporary directory for spool files */
-    apr_off_t           max_body; /* Maximum bytes the parser may see */
-    apr_ssize_t         max_brigade; /* Maximum heap space for brigades */
+    apr_table_t        *jar, *args;
+    apr_status_t        jar_status, args_status;
+    ap_filter_t        *f;
 };
 
 /* Tracks the apreq filter state */
 struct filter_ctx {
-    request_rec        *r;     /* request that originally created this filter */
     apr_bucket_brigade *bb;    /* input brigade that's passed to the parser */
     apr_bucket_brigade *spool; /* copied prefetch data for downstream filters */
-    apr_status_t        status;/* APR_SUCCESS, APR_INCOMPLETE, or parse error */
+    apr_table_t        *body;
+    apreq_parser_t     *parser;
+    apreq_hook_t       *hook_queue;
+    apr_status_t        status;
     unsigned            saw_eos;      /* Has EOS bucket appeared in filter? */
-    apr_off_t           bytes_read;   /* Total bytes read into this filter. */
+    apr_uint64_t           bytes_read;   /* Total bytes read into this filter. */
+    apr_uint64_t           read_limit;   /* Max bytes the filter may show to parser */
+    apr_size_t          brigade_limit;
+    const char         *temp_dir;
 };
 
-static const char filter_name[] = "APREQ";
+static apr_status_t apreq_filter(ap_filter_t *f,
+                                 apr_bucket_brigade *bb,
+                                 ap_input_mode_t mode,
+                                 apr_read_type_e block,
+                                 apr_off_t readbytes);
+
+static void apreq_filter_make_context(ap_filter_t *f);
+
+
 
 /**
  * @defgroup mod_apreq Apache 2.X Filter Module
@@ -144,20 +133,20 @@
  *
  * <TABLE class="qref"><CAPTION>Per-directory commands for mod_apreq</CAPTION>
  * <TR><TH>Directive</TH><TH>Context</TH><TH>Default</TH><TH>Description</TH></TR>
- * <TR class="odd"><TD>APREQ_MaxBody</TD><TD>directory</TD><TD>-1 (Unlimited)</TD><TD>
+ * <TR class="odd"><TD>APREQ_ReadLimit</TD><TD>directory</TD><TD>-1 (Unlimited)</TD><TD>
  * Maximum number of bytes mod_apreq will send off to libapreq for parsing.  
  * mod_apreq will log this event and remove itself from the filter chain.
  * The APR_EGENERAL error will be reported to libapreq2 users via the return 
  * value of apreq_env_read().
  * </TD></TR>
- * <TR><TD>APREQ_MaxBrigade</TD><TD>directory</TD><TD> #APREQ_MAX_BRIGADE_LEN </TD><TD>
+ * <TR><TD>APREQ_BrigadeLimit</TD><TD>directory</TD><TD> #APREQ_MAX_BRIGADE_LEN </TD><TD>
  * Maximum number of bytes apreq will allow to accumulate
  * within a brigade.  Excess data will be spooled to a
  * file bucket appended to the brigade.
  * </TD></TR>
  * <TR class="odd"><TD>APREQ_TempDir</TD><TD>directory</TD><TD>NULL</TD><TD>
  * Sets the location of the temporary directory apreq will use to spool
- * overflow brigade data (based on the APREQ_MaxBrigade setting).
+ * overflow brigade data (based on the APREQ_BrigadeLimit setting).
  * If left unset, libapreq2 will select a platform-specific location via apr_temp_dir_get().
  * </TD></TR>
  * </TABLE>
@@ -171,288 +160,452 @@
  * @{
  */
 
+APR_INLINE
+static void filter_relocate(ap_filter_t *f)
+{
+    request_rec *r = f->r;
 
-#define APREQ_MODULE_NAME               "APACHE2"
-#define APREQ_MODULE_MAGIC_NUMBER       20050105
+    if (f != r->input_filters) {
+        ap_filter_t *top = r->input_filters;
+        ap_remove_input_filter(f);
+        r->input_filters = f;
+        f->next = top;
+    }
+}
 
-static void apache2_log(const char *file, int line, int level, 
-                        apr_status_t status, apreq_env_handle_t *env,
-                        const char *fmt, va_list vp)
+APR_INLINE
+static ap_filter_t *get_apreq_filter(apreq_env_handle_t *env)
 {
-    dR;
-    ap_log_rerror(file, line, level, status, r, 
-                  "%s", apr_pvsprintf(r->pool, fmt, vp));
-}
+    struct apache2_handle *handle = (struct apache2_handle *)env;
 
+    if (handle->f == NULL) {
+        handle->f = ap_add_input_filter(filter_name, NULL, 
+                                        handle->r, 
+                                        handle->r->connection);
+        /* ap_add_input_filter does not guarantee cfg->f == r->input_filters,
+         * so we reposition the new filter there as necessary.
+         */
+        filter_relocate(handle->f); 
+    }
 
-static const char *apache2_query_string(apreq_env_handle_t *env)
-{
-    dR;
-    return r->args;
+    return handle->f;
 }
 
-static apr_pool_t *apache2_pool(apreq_env_handle_t *env)
-{
-    dR;
-    return r->pool;
-}
 
-static apr_bucket_alloc_t *apache2_bucket_alloc(apreq_env_handle_t *env)
+APR_INLINE
+static void init_filter_context(ap_filter_t *f)
 {
-    dR;
-    return r->connection->bucket_alloc;
-}
+    request_rec *r = f->r;
+    struct filter_ctx *ctx = f->ctx;
+    apr_bucket_alloc_t *ba = r->connection->bucket_alloc;
+    const char *cl_header = apr_table_get(r->headers_in, "Content-Length");
+
+    if (cl_header != NULL) {
+        char *dummy;
+        apr_uint64_t content_length = apr_strtoi64(cl_header,&dummy,0);
+
+        if (dummy == NULL || *dummy != 0) {
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r,
+                          "Invalid Content-Length header (%s)", cl_header);
+            ctx->status = APREQ_ERROR_BADHEADER;
+            return;
+        }
+        else if (content_length > ctx->read_limit) {
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r,
+                          "Content-Length header (%s) exceeds configured "
+                          "max_body limit (%" APR_UINT64_T_FMT ")", 
+                          cl_header, ctx->read_limit);
+            ctx->status = APREQ_ERROR_OVERLIMIT;
+            return;
+        }
+    }
 
-static const char *apache2_header_in(apreq_env_handle_t *env, const char *name)
-{
-    dR;
-    return apr_table_get(r->headers_in, name);
+    if (ctx->parser == NULL) {
+        const char *ct_header = apr_table_get(r->headers_in, "Content-Type");
+
+        if (ct_header != NULL) {
+            apreq_parser_function_t pf = apreq_parser(ct_header);
+
+            if (pf != NULL) {
+                ctx->parser = apreq_make_parser(r->pool, ba, ct_header, pf,
+                                                ctx->brigade_limit,
+                                                ctx->temp_dir,
+                                                ctx->hook_queue,
+                                                NULL);
+            }
+            else {
+                ctx->status = APREQ_ERROR_NOPARSER;
+                return;
+            }
+        }
+        else {
+            ctx->status = APREQ_ERROR_NOPARSER;
+            return;
+        }
+    }
+    else {
+        if (ctx->parser->brigade_limit > ctx->brigade_limit)
+            ctx->parser->brigade_limit = ctx->brigade_limit;
+        if (ctx->temp_dir != NULL)
+            ctx->parser->temp_dir = ctx->temp_dir;
+        if (ctx->hook_queue != NULL)
+            apreq_parser_add_hook(ctx->parser, ctx->hook_queue);
+    }
+
+    ctx->hook_queue = NULL;
+    ctx->bb    = apr_brigade_create(r->pool, ba);
+    ctx->spool = apr_brigade_create(r->pool, ba);
+    ctx->body  = apr_table_make(r->pool, APREQ_DEFAULT_NELTS);
+    ctx->status = APR_INCOMPLETE;
 }
 
-/*
- * r->headers_out ~> r->err_headers_out ?
- * @bug Sending a Set-Cookie header on a 304
- * requires err_headers_out table.
- */
-static apr_status_t apache2_header_out(apreq_env_handle_t *env,
-                                       const char *name, char *value)
+
+static apr_status_t apreq_filter_read(ap_filter_t *f, apr_off_t bytes)
 {
-    dR;
-    apr_table_add(r->err_headers_out, name, value);
-    return APR_SUCCESS;
+    struct filter_ctx *ctx = f->ctx;
+    apr_status_t s;
+
+    if (ctx->status == APR_EINIT)
+        init_filter_context(f);
+
+    if (ctx->status != APR_INCOMPLETE || bytes == 0)
+        return ctx->status;
+
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, f->r,
+                  "prefetching %" APR_OFF_T_FMT " bytes", bytes);
+    s = ap_get_brigade(f, NULL, AP_MODE_READBYTES, APR_BLOCK_READ, bytes);
+    if (s != APR_SUCCESS) {
+        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, s, f->r, 
+                      "apreq filter error detected during prefetch");
+        return s;
+    }
+    return ctx->status;
 }
 
 
-static apreq_jar_t *apache2_jar(apreq_env_handle_t *env, apreq_jar_t *jar)
+static apr_status_t apache2_jar(apreq_env_handle_t *env, const apr_table_t **t)
 {
-    dR;
-    if (jar != NULL) {
-        apreq_jar_t *old = c->jar;
-        c->jar = jar;
-        return old;
+    struct apache2_handle *handle = (struct apache2_handle*)env;
+    request_rec *r = handle->r;
+
+    if (handle->jar_status == APR_EINIT) {
+        const char *cookies = apr_table_get(r->headers_in, "Cookie");
+        if (cookies != NULL) {
+            handle->jar = apr_table_make(handle->r->pool, APREQ_DEFAULT_NELTS);
+            handle->jar_status = 
+                apreq_parse_cookie_header(r->pool, handle->jar, cookies);
+        }
+        else
+            handle->jar_status = APREQ_ERROR_NODATA;
     }
-    return c->jar;
+
+    *t = handle->jar;
+    return handle->jar_status;
 }
 
-APR_INLINE
-static void apreq_filter_relocate(ap_filter_t *f)
+static apr_status_t apache2_args(apreq_env_handle_t *env, const apr_table_t **t)
 {
-    request_rec *r = f->r;
-    if (f != r->input_filters) {
-        ap_filter_t *top = r->input_filters;
-        ap_remove_input_filter(f);
-        r->input_filters = f;
-        f->next = top;
+    struct apache2_handle *handle = (struct apache2_handle*)env;
+    request_rec *r = handle->r;
+
+    if (handle->args_status == APR_EINIT) {
+        if (r->args != NULL) {
+            handle->args = apr_table_make(handle->r->pool, APREQ_DEFAULT_NELTS);
+            handle->args_status = 
+                apreq_parse_query_string(r->pool, handle->args, r->args);
+        }
+        else
+            handle->args_status = APREQ_ERROR_NODATA;
     }
+
+    *t = handle->args;
+    return handle->args_status;
 }
 
-static ap_filter_t *get_apreq_filter(apreq_env_handle_t *env)
+
+
+
+static apreq_cookie_t *apache2_jar_get(apreq_env_handle_t *env, const char *name)
 {
-    struct env_config *cfg = (struct env_config*)env;
-    request_rec *r = cfg->r;
+    struct apache2_handle *handle = (struct apache2_handle *)env;
+    const apr_table_t *t;
+    const char *val;
 
-    if (cfg->f != NULL)
-       return cfg->f;
+    if (handle->jar_status == APR_EINIT)
+        apache2_jar(env, &t);
+    else
+        t = handle->jar;
 
-    cfg->f = ap_add_input_filter(filter_name, NULL, r, r->connection);
+    if (t == NULL)
+        return NULL;
 
-/* ap_add_input_filter does not guarantee cfg->f == r->input_filters,
- * so we reposition the new filter there as necessary.
- */
+    val = apr_table_get(t, name);
+    if (val == NULL)
+        return NULL;
 
-    apreq_filter_relocate(cfg->f); 
-    return cfg->f;
+    return apreq_value_to_cookie(val);
 }
 
-static apreq_request_t *apache2_request(apreq_env_handle_t *env,
-                                        apreq_request_t *req)
+static apreq_param_t *apache2_args_get(apreq_env_handle_t *env, const char *name)
 {
-    dR;
+    struct apache2_handle *handle = (struct apache2_handle *)env;
+    const apr_table_t *t;
+    const char *val;
 
-    if (c->f == NULL)
-        get_apreq_filter(env);
+    if (handle->args_status == APR_EINIT)
+        apache2_args(env, &t);
+    else
+        t = handle->args;
 
-    if (req != NULL) {
-        apreq_request_t *old = c->req;
-        c->req = req;
-        return old;
-    }
+    if (t == NULL)
+        return NULL;
+
+    val = apr_table_get(t, name);
+    if (val == NULL)
+        return NULL;
 
-    return c->req;
+    return apreq_value_to_param(val);
 }
 
-APR_INLINE
-static void apreq_filter_make_context(ap_filter_t *f)
+
+
+static apr_status_t apache2_body(apreq_env_handle_t *env, const apr_table_t **t)
 {
-    request_rec *r = f->r;
-    apreq_env_handle_t *env = apreq_env_make_apache2(r);
-    struct env_config *cfg = (struct env_config*)env;
-    apreq_request_t *req = cfg->req;
+    ap_filter_t *f = get_apreq_filter(env);
     struct filter_ctx *ctx;
-    apr_bucket_alloc_t *alloc;
 
-    if (f == r->input_filters 
-        && r->proto_input_filters == f->next
-        && strcasecmp(f->next->frec->name, filter_name) == 0) 
-    {
-        /* Try to steal the context and parse data of the 
-           upstream apreq filter. */
-        ctx = f->next->ctx;
+    if (f->ctx == NULL)
+        apreq_filter_make_context(f);
 
-        switch (ctx->status) {
-        case APR_SUCCESS:
-        case APR_INCOMPLETE:
-            break;
-        default:
-            apreq_log(APREQ_DEBUG ctx->status, env, 
-                      "cannot steal context: bad filter status");
-            goto make_new_context;
-        }
+    ctx = f->ctx;
 
-        if (ctx->r != r) {
-            /* r is a new request (subrequest or internal redirect) */
-            apreq_request_t *old_req;
-
-            if (req != NULL) {
-                if (req->parser != NULL) {
-                    apreq_log(APREQ_DEBUG ctx->status, env,
-                              "cannot steal context: new parser detected");
-                    goto make_new_context;
-                }
-            }
-            else {
-                req = apache2_request(env, NULL);
-            }
+    switch (ctx->status) {
 
-            /* steal the parser output */
-            apreq_log(APREQ_DEBUG 0, env, "stealing parser output");
-            old_req = apache2_request(apreq_env_make_apache2(ctx->r), NULL);
-            req->parser = old_req->parser;
-            req->body = old_req->body;
-            req->body_status = old_req->body_status;
-            ctx->r = r;
-        }
-
-        /* steal the filter context */
-        apreq_log(APREQ_DEBUG 0, env, "stealing filter context");
-        f->ctx = f->next->ctx;
-        r->proto_input_filters = f;
-        ap_remove_input_filter(f->next);
-        return;
-    }
-
- make_new_context:
-    if (req != NULL && f == r->input_filters) {
-        if (req->body_status != APR_EINIT) {
-            req->body = NULL;
-            req->parser = NULL;
-            req->body_status = APR_EINIT;
-        }
+    case APR_EINIT:
+        init_filter_context(f);
+        if (ctx->status != APR_INCOMPLETE)
+            break;
+
+    case APR_INCOMPLETE:
+        while (apreq_filter_read(f, APREQ_DEFAULT_READ_BLOCK_SIZE) == APR_INCOMPLETE)
+            ;   /*loop*/
     }
 
-    alloc = r->connection->bucket_alloc;
-    ctx = apr_palloc(r->pool, sizeof *ctx);
-
-    f->ctx       = ctx;
-    ctx->r       = r;
-    ctx->bb      = apr_brigade_create(r->pool, alloc);
-    ctx->spool   = apr_brigade_create(r->pool, alloc);
-    ctx->status  = APR_INCOMPLETE;
-    ctx->saw_eos = 0;
-    ctx->bytes_read = 0;
-
-    if (cfg->max_body >= 0) {
-        const char *cl = apr_table_get(r->headers_in, "Content-Length");
-        if (cl != NULL) {
-            char *dummy;
-            apr_int64_t content_length = apr_strtoi64(cl,&dummy,0);
-
-            if (dummy == NULL || *dummy != 0) {
-                apreq_log(APREQ_ERROR APR_EGENERAL, env,
-                      "Invalid Content-Length header (%s)", cl);
-                ctx->status = APR_EGENERAL;
-                apache2_request(env, NULL)->body_status = APR_EGENERAL;
-            }
-            else if (content_length > (apr_int64_t)cfg->max_body) {
-                apreq_log(APREQ_ERROR APR_EGENERAL, env,
-                          "Content-Length header (%s) exceeds configured "
-                          "max_body limit (%" APR_OFF_T_FMT ")", 
-                          cl, cfg->max_body);
-                ctx->status = APR_EGENERAL;
-                apache2_request(env, NULL)->body_status = APR_EGENERAL;
-            }
-        }
+    *t = ctx->body;
+    return ctx->status;
+}
+static apreq_param_t *apache2_body_get(apreq_env_handle_t *env, const char *name)
+{
+    ap_filter_t *f = get_apreq_filter(env);
+    struct filter_ctx *ctx;
+    const char *val;
+
+    if (f->ctx == NULL)
+        apreq_filter_make_context(f);
+
+    ctx = f->ctx;
+
+    switch (ctx->status) {
+
+    case APR_EINIT:
+
+        init_filter_context(f);
+        if (ctx->status != APR_INCOMPLETE)
+            return NULL;
+        apreq_filter_read(f, APREQ_DEFAULT_READ_BLOCK_SIZE);
+
+    case APR_INCOMPLETE:
+
+        val = apr_table_get(ctx->body, name);
+        if (val != NULL)
+            return apreq_value_to_param(val);
+
+        do {
+            /* riff on Duff's device */
+            apreq_filter_read(f, APREQ_DEFAULT_READ_BLOCK_SIZE);
+
+    default:
+
+            val = apr_table_get(ctx->body, name);
+            if (val != NULL)
+                return apreq_value_to_param(val);
+
+        } while (ctx->status == APR_INCOMPLETE);
+
     }
+
+    return NULL;
 }
 
-/*
- * Reads data directly into the parser.
- */
+static
+apr_status_t apache2_parser_get(apreq_env_handle_t *env, 
+                                  const apreq_parser_t **parser)
+{
+    ap_filter_t *f = get_apreq_filter(env);
+    struct filter_ctx *ctx = f->ctx;
+
+    if (ctx == NULL) {
+        *parser = NULL;
+        return APR_EINIT;
+    }
+    *parser = ctx->parser;
+    return ctx->status;
+}
 
-static apr_status_t apache2_read(apreq_env_handle_t *env,
-                                 apr_read_type_e block,
-                                 apr_off_t bytes)
+static
+apr_status_t apache2_parser_set(apreq_env_handle_t *env, 
+                                apreq_parser_t *parser)
 {
-    ap_filter_t *f = get_apreq_filter(env); /*ensures correct filter for prefetch */
+    ap_filter_t *f = get_apreq_filter(env);
     struct filter_ctx *ctx;
-    apr_status_t s;
 
     if (f->ctx == NULL)
         apreq_filter_make_context(f);
+
     ctx = f->ctx;
-    if (ctx->status != APR_INCOMPLETE || bytes == 0)
-        return ctx->status;
 
-    apreq_log(APREQ_DEBUG 0, env, "prefetching %" APR_OFF_T_FMT " bytes", bytes);
-    s = ap_get_brigade(f, NULL, AP_MODE_READBYTES, block, bytes);
-    if (s != APR_SUCCESS)
-        return s;
-    return ctx->status;
+    if (ctx->parser == NULL) {
+        ctx->parser = parser;
+        return APR_SUCCESS;
+    }
+    else
+        return APREQ_ERROR_CONFLICT;
 }
 
 
-static const char *apache2_temp_dir(apreq_env_handle_t *env, const char *path)
+
+static
+apr_status_t apache2_hook_add(apreq_env_handle_t *env,
+                              apreq_hook_t *hook)
 {
-    dR;
+    ap_filter_t *f = get_apreq_filter(env);
+    struct filter_ctx *ctx;
 
-    if (path != NULL) {
-        const char *rv = c->temp_dir;
-        c->temp_dir = apr_pstrdup(r->pool, path);
-        return rv;
+    if (f->ctx == NULL)
+        apreq_filter_make_context(f);
+
+    ctx = f->ctx;
+
+    if (ctx->parser != NULL) {
+        return apreq_parser_add_hook(ctx->parser, hook);
     }
-    if (c->temp_dir == NULL) {
-        if (apr_temp_dir_get(&c->temp_dir, r->pool) != APR_SUCCESS)
-            c->temp_dir = NULL;
+    else if (ctx->hook_queue != NULL) {
+        apreq_hook_t *h = ctx->hook_queue;
+        while (h->next != NULL)
+            h = h->next;
+        h->next = hook;
     }
+    else {
+        ctx->hook_queue = hook;
+    }
+    return APR_SUCCESS;
 
-    return c->temp_dir;
 }
 
+static
+apr_status_t apache2_brigade_limit_set(apreq_env_handle_t *env,
+                                       apr_size_t bytes)
+{
+    ap_filter_t *f = get_apreq_filter(env);
+    struct filter_ctx *ctx;
+
+    if (f->ctx == NULL)
+        apreq_filter_make_context(f);
+
+    ctx = f->ctx;
+
+    if (ctx->status == APR_EINIT || ctx->brigade_limit > bytes) {
+        ctx->brigade_limit = bytes;
+        return APR_SUCCESS;
+    }
 
-static apr_off_t apache2_max_body(apreq_env_handle_t *env, apr_off_t bytes)
+    return APREQ_ERROR_CONFLICT;
+}
+
+static
+apr_status_t apache2_brigade_limit_get(apreq_env_handle_t *env,
+                                       apr_size_t *bytes)
 {
-    dR;
+    ap_filter_t *f = get_apreq_filter(env);
+    struct filter_ctx *ctx;
 
-    if (bytes >= 0) {
-        apr_off_t rv = c->max_body;
-        c->max_body = bytes;
-        return rv;
+    if (f->ctx == NULL)
+        apreq_filter_make_context(f);
+
+    ctx = f->ctx;
+    *bytes = ctx->brigade_limit;
+    return APR_SUCCESS;
+}
+
+static
+apr_status_t apache2_read_limit_set(apreq_env_handle_t *env,
+                                    apr_uint64_t bytes)
+{
+    ap_filter_t *f = get_apreq_filter(env);
+    struct filter_ctx *ctx;
+
+    if (f->ctx == NULL)
+        apreq_filter_make_context(f);
+
+    ctx = f->ctx;
+
+    if (ctx->read_limit > bytes && ctx->bytes_read < bytes) {
+        ctx->read_limit = bytes;
+        return APR_SUCCESS;
     }
-    return c->max_body;
+
+    return APREQ_ERROR_CONFLICT;
 }
 
+static
+apr_status_t apache2_read_limit_get(apreq_env_handle_t *env,
+                                    apr_uint64_t *bytes)
+{
+    ap_filter_t *f = get_apreq_filter(env);
+    struct filter_ctx *ctx;
+
+    if (f->ctx == NULL)
+        apreq_filter_make_context(f);
 
-static apr_ssize_t apache2_max_brigade(apreq_env_handle_t *env,
-                                       apr_ssize_t bytes)
+    ctx = f->ctx;
+    *bytes = ctx->read_limit;
+    return APR_SUCCESS;
+}
+
+static
+apr_status_t apache2_temp_dir_set(apreq_env_handle_t *env,
+                                  const char *path)
 {
-    struct env_config *c = (struct env_config*)env;
+    ap_filter_t *f = get_apreq_filter(env);
+    struct filter_ctx *ctx;
 
-    if (bytes >= 0) {
-        apr_ssize_t rv = c->max_brigade;
-        c->max_brigade = bytes;
-        return rv;
+    if (f->ctx == NULL)
+        apreq_filter_make_context(f);
+
+    ctx = f->ctx;
+    // init vs incomplete state?
+    if (ctx->temp_dir == NULL && ctx->bytes_read == 0) {
+        if (path != NULL)
+            ctx->temp_dir = apr_pstrdup(f->r->pool, path);
+        return APR_SUCCESS;
     }
-    return c->max_brigade;
+
+    return APREQ_ERROR_CONFLICT;
+}
+
+static
+apr_status_t apache2_temp_dir_get(apreq_env_handle_t *env,
+                                  const char **path)
+{
+    ap_filter_t *f = get_apreq_filter(env);
+    struct filter_ctx *ctx;
+
+    if (f->ctx == NULL)
+        apreq_filter_make_context(f);
+
+    ctx = f->ctx;
+    *path = ctx->parser ? ctx->parser->temp_dir : ctx->temp_dir;
+    return APR_SUCCESS;
 }
 
 
@@ -480,43 +633,37 @@
 static apr_status_t apreq_filter_init(ap_filter_t *f)
 {
     request_rec *r = f->r;
-    apreq_env_handle_t *env = apreq_env_make_apache2(r);
-    struct env_config *cfg = (struct env_config*)env;
-    ap_filter_t *in;
+    struct filter_ctx *ctx = f->ctx;
+    struct apache2_handle *handle = 
+        (struct apache2_handle *)apreq_handle_apache2(r);
 
-    if (f != r->proto_input_filters) {
+    if (ctx == NULL || ctx->status == APR_EINIT) {
         if (f == r->input_filters) {
-            cfg->f = f;
-            return APR_SUCCESS;
+            handle->f = f;
         }
-        for (in = r->input_filters; in != r->proto_input_filters; 
-             in = in->next)
-        {
-            if (f == in) {
-                if (strcasecmp(r->input_filters->frec->name, filter_name) == 0) {
-                    apreq_log(APREQ_DEBUG 0, env,
-                              "removing intermediate apreq filter");
-                    if (cfg->f == f)
-                        cfg->f = r->input_filters;
-                    ap_remove_input_filter(f);
-                }
-                else {
-                    apreq_log(APREQ_DEBUG 0, env,
-                              "relocating intermediate apreq filter");
-                    apreq_filter_relocate(f);
-                    cfg->f = f;
-                }
-                return APR_SUCCESS;
-            }
+        else if (r->input_filters->frec->filter_func.in_func == apreq_filter) {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r,
+                          "removing intermediate apreq filter");
+            if (handle->f == f)
+                handle->f = r->input_filters;
+            ap_remove_input_filter(f);
+        }
+        else {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r,
+                          "relocating intermediate apreq filter");
+            filter_relocate(f);
+            handle->f = f;
         }
+        return APR_SUCCESS;
     }
 
     /* else this is a protocol filter which may still be active.
      * if it is, we must deregister it now.
      */
-    if (cfg->f == f) {
-        apreq_log(APREQ_DEBUG 0, env, "disabling stale protocol filter");
-        cfg->f = NULL;
+    if (handle->f == f) {
+        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, 
+                     "disabling stale protocol filter");
+        handle->f = NULL;
     }
     return APR_SUCCESS;
 }
@@ -529,8 +676,6 @@
 {
     request_rec *r = f->r;
     struct filter_ctx *ctx;
-    apreq_env_handle_t *env;
-    struct env_config *cfg;
     apr_status_t rv;
 
     switch (mode) {
@@ -544,16 +689,26 @@
         return APR_ENOTIMPL;
     }
 
-    env = apreq_env_make_apache2(r);
-    cfg = (struct env_config*)env;
 
     if (f->ctx == NULL)
         apreq_filter_make_context(f);
 
     ctx = f->ctx;
 
-    if (cfg->f != f)
-        ctx->status = APR_SUCCESS;
+    switch (ctx->status) {
+
+    case APR_EINIT:
+        init_filter_context(f);
+        if (ctx->status == APR_INCOMPLETE)
+            break;
+
+    case APREQ_ERROR_NOPARSER:
+        assert(bb != NULL);
+        rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
+        ap_remove_input_filter(f);
+        return rv;
+    }
+
 
     if (bb != NULL) {
 
@@ -564,7 +719,8 @@
                 rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
             
                 if (rv != APR_SUCCESS) {
-                    apreq_log(APREQ_ERROR rv, env, "ap_get_brigade failed");
+                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, 
+                                 "ap_get_brigade failed");
                     return rv;
                 }
 
@@ -572,14 +728,14 @@
                 apr_brigade_length(bb, 1, &len);
                 ctx->bytes_read += len;
 
-                if (cfg->max_body >= 0 && ctx->bytes_read > cfg->max_body) {
-                    ctx->status = APR_EGENERAL;
-                    apache2_request(env, NULL)->body_status = APR_EGENERAL;
-                    apreq_log(APREQ_ERROR ctx->status, env, "Bytes read (" APR_OFF_T_FMT
-                              ") exceeds configured max_body limit (" APR_OFF_T_FMT ")",
-                              ctx->bytes_read, cfg->max_body);
+                if (ctx->bytes_read > ctx->read_limit) {
+                    ctx->status = APREQ_ERROR_OVERLIMIT;
+                    ap_log_rerror(APLOG_MARK, APLOG_ERR, ctx->status, r, 
+                                 "Bytes read (%" APR_UINT64_T_FMT
+                                 ") exceeds configured max_body limit (%"
+                                 APR_UINT64_T_FMT ")",
+                                 ctx->bytes_read, ctx->read_limit);
                 }
-
             }
             if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(ctx->bb)))
                 ctx->saw_eos = 1;
@@ -591,27 +747,23 @@
                 apr_bucket *e;
                 rv = apr_brigade_partition(bb, readbytes, &e);
                 if (rv != APR_SUCCESS && rv != APR_INCOMPLETE) {
-                    apreq_log(APREQ_ERROR rv, env, "partition failed");
+                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, 
+                                 "partition failed");
                     return rv;
                 }
                 if (APR_BUCKET_IS_EOS(e))
                     e = APR_BUCKET_NEXT(e);
                 ctx->spool = apr_brigade_split(bb, e);
-                APREQ_BRIGADE_SETASIDE(ctx->spool,r->pool);
+                APREQ_BRIGADE_SETASIDE(ctx->spool, r->pool);
             }
         }
 
         if (ctx->status != APR_INCOMPLETE) {
+
             if (APR_BRIGADE_EMPTY(ctx->spool)) {
                 ap_filter_t *next = f->next;
 
-                if (cfg->f != f) {
-                    apreq_log(APREQ_DEBUG ctx->status, env,
-                              "removing inactive filter (%d)",
-                              r->input_filters == f);
-
-                    ap_remove_input_filter(f);
-                }
+                ap_remove_input_filter(f);
                 if (APR_BRIGADE_EMPTY(bb))
                     return ap_get_brigade(next, bb, mode, block, readbytes);
             }
@@ -622,6 +774,7 @@
         /* bb == NULL, so this is a prefetch read! */
         apr_off_t total_read = 0;
 
+        /* XXX cache this thing in somewhere */
         bb = apr_brigade_create(ctx->bb->p, ctx->bb->bucket_alloc);
 
         while (total_read < readbytes) {
@@ -635,7 +788,7 @@
 
             rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
             if (rv != APR_SUCCESS) {
-                apreq_log(APREQ_ERROR rv, env, "ap_get_brigade failed");
+                /*XXX how should we handle this filter-chain error? */
                 return rv;
             }
             APREQ_BRIGADE_SETASIDE(bb, r->pool);
@@ -644,22 +797,24 @@
             apr_brigade_length(bb, 1, &len);
             total_read += len;
 
-            rv = apreq_brigade_concat(env, ctx->spool, bb);
+            rv = apreq_brigade_concat(r->pool, ctx->temp_dir, ctx->brigade_limit,
+                                      ctx->spool, bb);
             if (rv != APR_SUCCESS && rv != APR_EOF) {
-                apreq_log(APREQ_ERROR rv, env,
-                          "apreq_brigade_concat failed; APREQ_TempDir problem?");
-                return rv;
+                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+                          "apreq_brigade_concat failed; TempDir problem?");
+                /*XXX how should we handle this apreq-based error? */
+                return ctx->status = rv;
             }
         }
 
         ctx->bytes_read += total_read;
 
-        if (cfg->max_body >= 0 && ctx->bytes_read > cfg->max_body) {
-            ctx->status = APR_EGENERAL;
-            apache2_request(env, NULL)->body_status = APR_EGENERAL;
-            apreq_log(APREQ_ERROR ctx->status, env, "Bytes read (%" APR_OFF_T_FMT
-                      ") exceeds configured max_body limit (%" APR_OFF_T_FMT ")",
-                      ctx->bytes_read, cfg->max_body);
+        if (ctx->bytes_read > ctx->read_limit) {
+            ctx->status = APREQ_ERROR_OVERLIMIT;
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, ctx->status, r, 
+                         "Bytes read (%" APR_UINT64_T_FMT
+                         ") exceeds configured read limit (%" APR_UINT64_T_FMT ")",
+                         ctx->bytes_read, ctx->read_limit);
         }
 
         /* Adding "f" to the protocol filter chain ensures the 
@@ -681,27 +836,65 @@
         return APR_SUCCESS;
 
     if (ctx->status == APR_INCOMPLETE) {
-        apreq_request_t *req = apache2_request(env, NULL);
-
-        ctx->status = apreq_parse_request(req, ctx->bb);
+        ctx->status = APREQ_RUN_PARSER(ctx->parser, ctx->body, ctx->bb);
         apr_brigade_cleanup(ctx->bb);
     }
 
     return APR_SUCCESS;
 }
 
-static APREQ_ENV_MODULE(apache2, APREQ_MODULE_NAME,
-                        APREQ_MODULE_MAGIC_NUMBER);
+
+
+static const char *apache2_header_in(apreq_env_handle_t *env, const char *name)
+{
+    struct apache2_handle *handle = (struct apache2_handle *)env;
+    return apr_table_get(handle->r->headers_in, name);
+}
+
+static apr_status_t apache2_header_out(apreq_env_handle_t *env,
+                                       const char *name, char *value)
+{
+    struct apache2_handle *handle = (struct apache2_handle *)env;
+    apr_table_add(handle->r->err_headers_out, name, value);
+    return APR_SUCCESS;
+}
 
 static void register_hooks (apr_pool_t *p)
 {
+    apreq_register_parser(NULL,NULL);
     ap_register_input_filter(filter_name, apreq_filter, apreq_filter_init,
                              AP_FTYPE_PROTOCOL-1);
 }
 
 
-/* Configuration directives */
 
+/* Server configuration directives */
+
+static void *apreq_create_dir_config(apr_pool_t *p, char *d)
+{
+    /* d == OR_ALL */
+    struct dir_config *dc = apr_palloc(p, sizeof *dc);
+    dc->temp_dir      = NULL;
+    dc->read_limit    = (apr_uint64_t)-1;
+    dc->brigade_limit = APREQ_DEFAULT_BRIGADE_LIMIT;
+    return dc;
+}
+
+static void *apreq_merge_dir_config(apr_pool_t *p, void *a_, void *b_)
+{
+    struct dir_config *a = a_, *b = b_, *c = apr_palloc(p, sizeof *c);
+
+    c->temp_dir      = (b->temp_dir != NULL)            /* overrides ok */
+                      ? b->temp_dir : a->temp_dir;
+
+    c->brigade_limit = (b->brigade_limit == (apr_size_t)-1) /* overrides ok */
+                      ? a->brigade_limit : b->brigade_limit;
+
+    c->read_limit    = (b->read_limit < a->read_limit)  /* why min? */
+                      ? b->read_limit : a->read_limit;
+
+    return c;
+}
 
 static const char *apreq_set_temp_dir(cmd_parms *cmd, void *data,
                                       const char *arg)
@@ -716,8 +909,8 @@
     return NULL;
 }
 
-static const char *apreq_set_max_body(cmd_parms *cmd, void *data,
-                                      const char *arg)
+static const char *apreq_set_read_limit(cmd_parms *cmd, void *data,
+                                        const char *arg)
 {
     struct dir_config *conf = data;
     const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
@@ -725,16 +918,12 @@
     if (err != NULL)
         return err;
 
-    conf->max_body = apreq_atoi64f(arg);
-
-    if (conf->max_body < 0)
-        return "APREQ_MaxBody requires a non-negative integer.";
-
+    conf->read_limit = apreq_atoi64f(arg);
     return NULL;
 }
 
-static const char *apreq_set_max_brigade(cmd_parms *cmd, void *data,
-                                          const char *arg)
+static const char *apreq_set_brigade_limit(cmd_parms *cmd, void *data,
+                                           const char *arg)
 {
     struct dir_config *conf = data;
     const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
@@ -742,29 +931,26 @@
     if (err != NULL)
         return err;
 
-    conf->max_brigade = apreq_atoi64f(arg);
-
-    if (conf->max_brigade < 0)
-        return "APREQ_MaxBrigade requires a non-negative integer.";
-
+    conf->brigade_limit = apreq_atoi64f(arg);
     return NULL;
 }
 
+
 static const command_rec apreq_cmds[] =
 {
     AP_INIT_TAKE1("APREQ_TempDir", apreq_set_temp_dir, NULL, OR_ALL,
                   "Default location of temporary directory"),
-    AP_INIT_TAKE1("APREQ_MaxBody", apreq_set_max_body, NULL, OR_ALL,
+    AP_INIT_TAKE1("APREQ_ReadLimit", apreq_set_read_limit, NULL, OR_ALL,
                   "Maximum amount of data that will be fed into a parser."),
-    AP_INIT_TAKE1("APREQ_MaxBrigade", apreq_set_max_brigade, NULL, OR_ALL,
+    AP_INIT_TAKE1("APREQ_BrigadeLimit", apreq_set_brigade_limit, NULL, OR_ALL,
                   "Maximum in-memory bytes a brigade may use."),
     { NULL }
 };
 
 /** @} */
 
-module AP_MODULE_DECLARE_DATA apreq_module =
-{
+
+module AP_MODULE_DECLARE_DATA apreq_module = {
 	STANDARD20_MODULE_STUFF,
 	apreq_create_dir_config,
 	apreq_merge_dir_config,
@@ -774,31 +960,102 @@
 	register_hooks,
 };
 
-APREQ_DECLARE(apreq_env_handle_t*) apreq_env_make_apache2(request_rec *r) {
-    struct env_config *cfg =
-        ap_get_module_config(r->request_config, &apreq_module);
+
+static void apreq_filter_make_context(ap_filter_t *f)
+{
+    request_rec *r;
+    struct filter_ctx *ctx;
     struct dir_config *d;
 
-    if (cfg != NULL)
-        return &cfg->env;
+    r = f->r;
+    d = ap_get_module_config(r->per_dir_config, &apreq_module);
+
+    if (f == r->input_filters 
+        && r->proto_input_filters == f->next
+        && f->next->frec->filter_func.in_func == apreq_filter) 
+    {
+
+        ctx = f->next->ctx;
+
+        switch (ctx->status) {
+        case APR_INCOMPLETE:
+        case APR_SUCCESS:
+
+            if (d != NULL) {
+                ctx->temp_dir      = d->temp_dir;
+                ctx->read_limit    = d->read_limit;
+                ctx->brigade_limit = d->brigade_limit;
+
+                if (ctx->parser != NULL) {
+                    ctx->parser->temp_dir = d->temp_dir;
+                    ctx->parser->brigade_limit = d->brigade_limit;
+                }
+
+            }
+
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r,
+                          "stealing filter context");
+            f->ctx = ctx;
+            r->proto_input_filters = f;
+            ap_remove_input_filter(f->next);
+
+            return;
+
+        default:
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, ctx->status, r, 
+                          "cannot steal context: bad filter status");
+        }
+    }
 
-    d = ap_get_module_config(r->per_dir_config,
-                             &apreq_module);
-    cfg = apr_pcalloc(r->pool, sizeof *cfg);
-    ap_set_module_config(r->request_config, &apreq_module, cfg);
 
-    cfg->env.module = &apache2_module;
-    cfg->r = r;
+    ctx = apr_pcalloc(r->pool, sizeof *ctx);
+    ctx->status = APR_EINIT;
 
     if (d == NULL) {
-        cfg->max_body    = -1;
-        cfg->max_brigade = APREQ_MAX_BRIGADE_LEN;
+        ctx->read_limit    = (apr_uint64_t)-1;
+        ctx->brigade_limit = APREQ_DEFAULT_BRIGADE_LIMIT;
     } else {
-        apreq_log(APREQ_DEBUG 0, &cfg->env, "copying temp_dir %s", d->temp_dir);
-        cfg->temp_dir    = d->temp_dir;
-        cfg->max_body    = d->max_body;
-        cfg->max_brigade = d->max_brigade;
+        ctx->temp_dir      = d->temp_dir;
+        ctx->read_limit    = d->read_limit;
+        ctx->brigade_limit = d->brigade_limit;
+    }
+
+    f->ctx = ctx;
+}
+
+
+
+static APREQ_MODULE(apache2, 20050131);
+
+APREQ_DECLARE(apreq_env_handle_t *) apreq_handle_apache2(request_rec *r)
+{
+    struct apache2_handle *handle =
+        ap_get_module_config(r->request_config, &apreq_module);
+
+    if (handle != NULL) {
+        if (handle->f == NULL)
+            get_apreq_filter(&handle->env);
+        return &handle->env;
+    }
+    handle = apr_palloc(r->pool, sizeof *handle);
+    ap_set_module_config(r->request_config, &apreq_module, handle);
+
+    handle->env.module = &apache2_module;
+    handle->r = r;
+
+    handle->args_status = handle->jar_status = APR_EINIT;
+    handle->args = handle->jar = NULL;
+
+    handle->f = NULL;
+
+    if (0) {
+        apreq_param_t *hack;
+        handle->args = apr_table_make(r->pool, APREQ_DEFAULT_NELTS);
+        hack = apreq_make_param(r->pool, "foo", 3, "bar", 3);
+        apr_table_addn(handle->args, hack->v.name, hack->v.data);
+        handle->args_status = APR_SUCCESS;
     }
+    get_apreq_filter(&handle->env);
+    return &handle->env;
 
-    return &cfg->env;
 }

Modified: httpd/apreq/branches/multi-env-unstable/env/test_cgi.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/env/test_cgi.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/env/test_cgi.c (original)
+++ httpd/apreq/branches/multi-env-unstable/env/test_cgi.c Fri Feb  4 10:27:55 2005
@@ -16,8 +16,6 @@
 
 #include "apreq.h"
 #include "apreq_env.h"
-#include "apreq_params.h"
-#include "apreq_cookie.h"
 #include "apr_strings.h"
 #include "apr_lib.h"
 #include "apr_tables.h"
@@ -26,7 +24,7 @@
 static int dump_table(void *count, const char *key, const char *value)
 {
     int *c = (int *) count;
-    int value_len = apreq_strlen(value);
+    int value_len = apreq_value_to_param(value)->v.size;
     if (value_len) 
         *c += strlen(key) + value_len;
     return 1;
@@ -35,8 +33,7 @@
 int main(int argc, char const * const * argv)
 {
     apr_pool_t *pool;
-    apreq_env_handle_t *env;
-    apreq_request_t *req;
+    apreq_env_handle_t *req;
     const apreq_param_t *foo, *bar, *test, *key;
     apr_file_t *out;
 
@@ -50,15 +47,15 @@
         fprintf(stderr, "apr_pool_create failed\n");
         exit(-1);
     }
+    (void)apreq_register_parser(NULL,NULL);
 
-    env = apreq_env_make_cgi(pool);
+    req = apreq_handle_cgi(pool);
 
     apr_file_open_stdout(&out, pool);
 
-    apreq_log(APREQ_DEBUG 0, env, "%s", "Creating apreq_request");
-    req = apreq_request(env, NULL);
+//    apreq_log(APREQ_DEBUG 0, env, "%s", "Creating apreq_request");
 
-    apreq_log(APREQ_DEBUG 0, env, "%s", "Fetching the parameters");
+//    apreq_log(APREQ_DEBUG 0, env, "%s", "Fetching the parameters");
 
     foo = apreq_param(req, "foo");
     bar = apreq_param(req, "bar");
@@ -71,56 +68,56 @@
 
         if (foo) {
             apr_file_printf(out, "\t%s => %s\n", "foo", foo->v.data);
-            apreq_log(APREQ_DEBUG 0, env, "%s => %s", "foo", foo->v.data);
+//            apreq_log(APREQ_DEBUG 0, env, "%s => %s", "foo", foo->v.data);
         }
         if (bar) {
             apr_file_printf(out, "\t%s => %s\n", "bar", bar->v.data);
-            apreq_log(APREQ_DEBUG 0, env, "%s => %s", "bar", bar->v.data);
+//            apreq_log(APREQ_DEBUG 0, env, "%s => %s", "bar", bar->v.data);
         }
     }
     
     else if (test && key) {
-        const apreq_jar_t *jar = apreq_jar(env, NULL);
         apreq_cookie_t *cookie;
         char *dest;
+        apr_size_t dlen;
 
-        apreq_log(APREQ_DEBUG 0, env, "Fetching Cookie %s", key->v.data);
-        cookie = apreq_cookie(jar, key->v.data);
+//        apreq_log(APREQ_DEBUG 0, env, "Fetching Cookie %s", key->v.data);
+        cookie = apreq_cookie(req, key->v.data);
 
         if (cookie == NULL) {
-            apreq_log(APREQ_DEBUG APR_EGENERAL, env,
-                      "No cookie for %s found!", key->v.data);
+//            apreq_log(APREQ_DEBUG APR_EGENERAL, env,
+//                      "No cookie for %s found!", key->v.data);
             exit(-1);
         }
 
         if (strcmp(test->v.data, "bake") == 0) {
-            apreq_cookie_bake(cookie, env);
+            apreq_cookie_bake(cookie, req);
         }
         else if (strcmp(test->v.data, "bake2") == 0) {
-            apreq_cookie_bake2(cookie, env);
+            apreq_cookie_bake2(cookie, req);
         }
 
         apr_file_printf(out, "%s", "Content-Type: text/plain\n\n");
         dest = apr_pcalloc(pool, cookie->v.size + 1);
-        if (apreq_decode(dest, cookie->v.data, cookie->v.size) >= 0)
+        if (apreq_decode(dest, &dlen, cookie->v.data, cookie->v.size) == APR_SUCCESS)
             apr_file_printf(out, "%s", dest);
         else {
-            apreq_log(APREQ_ERROR APR_EGENERAL, env,
-                      "Bad cookie encoding: %s", 
-                      cookie->v.data);
+//            apreq_log(APREQ_ERROR APR_EGENERAL, env,
+//                      "Bad cookie encoding: %s", 
+//                      cookie->v.data);
             exit(-1);
         }
     }
 
     else { 
-        apr_table_t *params = apreq_params(pool, req);
+        const apr_table_t *params = apreq_params(pool, req);
         int count = 0;
         apr_file_printf(out, "%s", "Content-Type: text/plain\n\n");
 
-        apreq_log(APREQ_DEBUG 0, env, "Fetching all parameters");
+//        apreq_log(APREQ_DEBUG 0, env, "Fetching all parameters");
 
         if (params == NULL) {
-            apreq_log(APREQ_ERROR APR_EGENERAL, env, "No parameters found!");
+//            apreq_log(APREQ_ERROR APR_EGENERAL, env, "No parameters found!");
             exit(-1);
         }
         apr_table_do(dump_table, &count, params, NULL);

Modified: httpd/apreq/branches/multi-env-unstable/src/Makefile.am
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/src/Makefile.am?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/src/Makefile.am (original)
+++ httpd/apreq/branches/multi-env-unstable/src/Makefile.am Fri Feb  4 10:27:55 2005
@@ -5,10 +5,10 @@
 BUILT_SOURCES= @APR_LA@ @APU_LA@
 lib_LTLIBRARIES = libapreq2.la
 libapreq2_la_SOURCES = apreq.c apreq_version.c apreq_cookie.c \
-                       apreq_env_custom.c apreq_env_cgi.c \
+	               apreq_env_custom.c apreq_env_cgi.c \
                        apreq_params.c apreq_parsers.c apreq_env.c
 pkginclude_HEADERS = apreq.h apreq_version.h apreq_cookie.h \
-                  apreq_params.h  apreq_env.h
+                  apreq_params.h  apreq_parsers.h apreq_env.h
 libapreq2_la_LDFLAGS = -version-info @APREQ_LIBTOOL_VERSION@
 
 pkgincludedir = $(includedir)/@APREQ_LIBNAME@

Modified: httpd/apreq/branches/multi-env-unstable/src/README
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/src/README?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/src/README (original)
+++ httpd/apreq/branches/multi-env-unstable/src/README Fri Feb  4 10:27:55 2005
@@ -1,45 +1,14 @@
-No httpd header dependencies in src/; those go in env/.
-Only APR is used here.
-
-Data structures and relations:
-
-  BASIC VALUE TYPE:
-
-    apreq_value_t:  basic type for handling opaque data.  The type
-                    is meant to be extended by placing all "metadata"
-                    in front (within a larger structure).
-
-  COOKIES:
-
-    apreq_cookie_t: extends apreq_value_t to represent server-side
-                cookie data.
+dependency diagram:
 
-    apreq_jar_t: This struct is analogous to apreq_request_t for params.
+                            apreq.h
 
-  PARAMS:
+                      /        |         \ 
 
-    apreq_param_t: extends apreq_value_t to represent POST param data.
+       apreq_cookie.h   apreq_parsers.h   apreq_param.h
 
-    apreq_request_t: maintains arg/body tables which represent parsed data.
+                     \         |         /
 
-        REQUEST STATES:
-           req->body == NULL: No POST data has been read/parsed yet.  The 
-                              req->parser slot may be safely modified.
+                        apreq_handle.h
 
-           req->body != NULL: Some parsing has taken place, so req->parser
-                              cannot be modified now without risking
-                              loss of data.
-
-                status: (as returned by apreq_env_read and APREQ_RUN_PARSER)
-                         APR_INCOMPLETE: Parsing in progress.
-                         APR_SUCCESS: Parsing complete.
-                         <other>: parser error, parsing aborted.
-
-
-  PARSER EXTENSIONS:
-
-    apreq_parser_t: parser callback, with its associated configuration data.
-
-    apreq_hook_t: extends multipart/form-data parser by transforming incoming
-                  brigades which represent the contents of a file upload.
 
+Only APR is used here.



Mime
View raw message