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.