You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apreq-cvs@httpd.apache.org by jo...@apache.org on 2004/03/24 09:22:48 UTC
cvs commit: httpd-apreq-2/t parsers.c testall.c
joes 2004/03/24 00:22:48
Modified: . CHANGES STATUS
build version_check.pl xsbuilder.pl
env mod_apreq.c test_cgi.c
glue/perl/xsbuilder/Apache/Request Apache__Request.h
glue/perl/xsbuilder/maps apreq_functions.map
apreq_structures.map
src Makefile.am apreq.c apreq.h apreq_env.c apreq_env.h
apreq_params.c apreq_params.h apreq_parsers.c
apreq_version.h
t parsers.c testall.c
Removed: src apreq_parsers.h
Log:
Reformatted STATUS file, removing dates. Removed struct apreq_cfg_t and added corresponding
apreq_env hooks. Bumped version numbers (note- libapreq2.so.2.0.5 is not ABI compatible
with earlier versions). This is a large patch, but all existing tests should still pass.
Revision Changes Path
1.27 +153 -160 httpd-apreq-2/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/httpd-apreq-2/CHANGES,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- CHANGES 16 Feb 2004 20:50:30 -0000 1.26
+++ CHANGES 24 Mar 2004 08:22:47 -0000 1.27
@@ -3,167 +3,160 @@
@section v2_03_dev Changes with libapreq2-2.03-dev
+- Documentation [joes]
+ CHANGES file reformatted, removing dates & other clutter
+ as Stas suggests.
+
+- C API [joes]
+ Rewrote cgi_read() in apreq_env.c and reworked mod_apreq.c
+ to enforce apreq_env_max_body() settings.
+
+- C API [joes]
+ Fixed bug in url_parser code- missing context brigade was
+ needed to track key-value pairs which span multiple buckets.
+
+- C API [joes]
+ API modifications: removed struct apreq_cfg_t, adding
+ new apreq_env hooks max_body, max_brigade_len, and temp_dir.
+ Also folded apreq_parsers.h into apreq_params.h. These changes
+ make libapreq2.so.2.0.5 incompatible with earlier versions.
+
+- Perl API [stas]
+ Include ppport.h from blead-perl to support older perls.
+ Add a proper support for ithreads.
+
+- C API [Swen Schillig, joes]
+ Fixed bug in calculation of Netscape cookie expiration dates.
+ apr_time_t is measured in microseconds, not seconds, which
+ threw off the arithmetic; apr_time_from_sec was needed for
+ the conversion.
+
+- C API [Max Kellermann]
+ Fix segfault caused by invalid %-escape sequence in query string.
+
+
+@section v2_02_dev Changes with libapreq2-2.02-dev (released Nov 15, 2003)
+
+
+- Perl API [joes]
+ Fix bogus pool/cookie initializers in Apache::Cookie::set_attr(),
+ which caused Apache::Cookie::new to segfault. Bug
+ first reported to modperl list by Wolfgang Kubens.
+
+
+@section v2_01_dev Changes with libapreq2-2.01-dev (released Nov 10, 2003)
+
+
+- build system [joes]
+ Skip Apache::Test tests in env/ when Apache::Test is unavailable.
+ This allows the C API to be build and installed without requiring
+ Apache::Test (it is still a requirement for compiling the perl glue).
+
+- C API mod_apreq.c [joes]
+ Parser errors were creeping into the return value of apreq_filter,
+ which breaks the "transparent tee" paradigm. This caused bogus
+ "400 Bad Request" responses (first reported by Vladimir Dudo)
+ to occur when libapreq2 was used by an output filter during a GET
+ request (handled by apache2's default handler). The test suite
+ has been updated accordingly.
+
+- C API [joes]
+ Incorporate libapreq_cgi into libapreq2 as the default environment,
+ and add apreq_env_t and initializer apreq_env_module() to manage the
+ environment at runtime (determining the environment at load-time
+ was problematic on non-ELF systems).
+
+
+@section v2_0_0 Changes with libapreq2-2.00-dev (Oct 25, 2003)
+
+
+- C API: libapreq_cgi.c [randyk, joes]
+ CGI environment defined by env/libapreq_cgi.c is functional
+ (with tests added to env/t). This library may soon be incorporated
+ directly into libapreq2 as a default enviroment.
+
+- C API: mod_apreq.c [joes]
+ Added ctx->saw_eos to ensure we don't read from upstream filters
+ after receiving an eos bucket. Otherwise it was possible for
+ two eos buckets to appear when a prefetch read is involved, which
+ breaks other modules like mod_proxy. This bug was uncovered by
+ Philippe Chiasson. mod_apreq's apreq_env_majic_number bumped to
+ reflect the added fixes.
+
+- configure: --enable-perl-glue [joes]
+ The --enable-perl-glue option integrates the perl glue into the
+ normal Unix build cycle. It is disabled by default, but is silently
+ reenabled if the user configures the source tree via Makefile.PL.
+
+- C API [joes]
+ Added apreq_header_attribute() and fixed mfd parser to allow
+ "charset" attribute to appear in the Content-Type header. Sven
+ Geisler points out that Opera 7.20 does generate such headers.
+
+- C API [joes]
+ Added versioning API following http://apr.apache.org/versioning.html
+ apreq_env renamed apreq_env_name, and apreq_env_magic_number added
+ to provide versioning for environments (modules). The header files
+ are now installed to "include/apreq2", and the library is renamed
+ "libapreq2". Also added an apreq2-config script based on apu-config.
+
+- configure: static mod_apreq.c [Bojan Smojver, joes]
+ Add --with-apache2-src configure option, along with --with-apr-config
+ and --with-apu-config, and provide support for compiling mod_apreq
+ into httpd as a static apache module.
+
+- C API: mod_apreq.c [joes]
+ Support for internal redirects added to the mod_apreq filter.
+ This ensures any POST data prefetched in the main request
+ gets passed along to the subrequest handler(s).
+
+- C bugfix: apreq_decode [Graham Clark]
+ If the source and destination strings are represented by the same
+ pointer - e.g. if called as apreq_unescape(s) - string s is modified
+ incorrectly in general. Patch includes new unit test.
+
+- Perl API [joes]
+ Added $req->parse, $req->status, & "preparse" logic
+ to $req->param & $req->upload.
+
+- C API [joes]
+ Added "preparse" logic to apreq_params & apreq_uploads
+ to bring behavior in line with libapreq-1.x.
+
+- C API [joes]
+ Dropped param->charset.
+ Make apreq_brigade_concat public, so mod_apreq can use it
+ for its ctx->spool brigade.
+
+- Documentation [joes]
+ Updated Cookie_pod to reflect API changes over v1.X.
+
+- Documentation [joes]
+ Added doxygen links to Apache::Request and Apache::Cookie
+ perl docs.
+
+- C API [joes]
+ Added apreq_copy_brigade(bb) to apreq.h.
+
+- C API [joes]
+ The new filter-based design required a complete
+ departure from libapreq-1.X codebase. libapreq-2
+ is based solely on APR, and to be fully functional,
+ requires a supporting environment similar to Apache-2.
+ A person wishing to port libapreq-2 to a new environment
+ needs to provide definitions for the declarations in apreq_env.h.
+
+- Perl API [joes]
+ Aggregates are always collected into an APR::Table-based package.
+ New table packages: Apache::Cookie::Table, Apache::Request::Table,
+ and Apache::Upload::Table.
+
+- Perl API [joes]
+ Apache::Cookie->fetch now requires an "environment" argument ($r).
+ Its return value is blessed into the Apache::Cookie::Jar class.
-- February 16, 2004 - Perl API [stas]
-
-Include ppport.h from blead-perl to support older perls.
-
-Add a proper support for ithreads.
-
-- December 31, 2003 - C API [Swen Schillig, joes]
-
-Fixed bug in calculation of Netscape cookie expiration dates.
-apr_time_t is measured in microseconds, not seconds, which
-threw off the arithmetic; apr_time_from_sec was needed for
-the conversion.
-
-- December 11, 2003 - C API [Max Kellermann]
-
-Fix segfault caused by invalid %-escape sequence in query string.
-
-@section v2_02_dev Changes with libapreq2-2.02-dev
-
-- November 12, 2003 - Perl API [joes]
-
-Fix bogus pool/cookie initializers in Apache::Cookie::set_attr(),
-which caused Apache::Cookie::new to segfault. Bug
-first reported to modperl list by Wolfgang Kubens.
-
-
-@section v2_01_dev Changes with libapreq2-2.01-dev
-
-
-- November 7, 2003 - build system [joes]
-
-Skip Apache::Test tests in env/ when Apache::Test is unavailable.
-This allows the C API to be build and installed without requiring
-Apache::Test (it is still a requirement for compiling the perl glue).
-
-- November 7, 2003 - C API mod_apreq.c [joes]
-
-Parser errors were creeping into the return value of apreq_filter,
-which breaks the "transparent tee" paradigm. This caused bogus
-"400 Bad Request" responses (first reported by Vladimir Dudo)
-to occur when libapreq2 was used by an output filter during a GET
-request (handled by apache2's default handler). The test suite
-has been updated accordingly.
-
-- October 26, 2003 - C API [joes]
-
-Incorporate libapreq_cgi into libapreq2 as the default environment,
-and add apreq_env_t and initializer apreq_env_module() to manage the
-environment at runtime (determining the environment at load-time
-was problematic on non-ELF systems).
-
-
-@section v2_0_0 Changes with libapreq2-2.00-dev
-
-
-- October 24, 2003 - C API: libapreq_cgi.c [randyk, joes]
-
-CGI environment defined by env/libapreq_cgi.c is functional
-(with tests added to env/t). This library may soon be incorporated
-directly into libapreq2 as a default enviroment.
-
-- October 23, 2003 - C API: mod_apreq.c [joes]
-
-Added ctx->saw_eos to ensure we don't read from upstream filters
-after receiving an eos bucket. Otherwise it was possible for
-two eos buckets to appear when a prefetch read is involved, which
-breaks other modules like mod_proxy. This bug was uncovered by
-Philippe Chiasson. mod_apreq's apreq_env_majic_number bumped to
-reflect the added fixes.
-
-- October 17, 2003 - configure: --enable-perl-glue [joes]
-
-The --enable-perl-glue option integrates the perl glue into the
-normal Unix build cycle. It is disabled by default, but is silently
-reenabled if the user configures the source tree via Makefile.PL.
-
-- October 14, 2003 - C API [joes]
-
-Added apreq_header_attribute() and fixed mfd parser to allow
-"charset" attribute to appear in the Content-Type header. Sven
-Geisler points out that Opera 7.20 does generate such headers.
-
-- October 14, 2003 - C API [joes]
-
-Added versioning API following http://apr.apache.org/versioning.html
-apreq_env renamed apreq_env_name, and apreq_env_magic_number added
-to provide versioning for environments (modules). The header files
-are now installed to "include/apreq2", and the library is renamed
-"libapreq2". Also added an apreq2-config script based on apu-config.
-
-- October 8, 2003 - configure: static mod_apreq.c [Bojan Smojver, joes]
-
-Add --with-apache2-src configure option, along with --with-apr-config
-and --with-apu-config, and provide support for compiling mod_apreq
-into httpd as a static apache module.
-
-- October 1, 2003 - C API: mod_apreq.c [joes]
-
-Support for internal redirects added to the mod_apreq filter.
-This ensures any POST data prefetched in the main request
-gets passed along to the subrequest handler(s).
-
-- July 18, 2003 - C bugfix: apreq_decode [Graham Clark]
-
-If the source and destination strings are represented by the same
-pointer - e.g. if called as apreq_unescape(s) - string s is modified
-incorrectly in general. Patch includes new unit test.
-
-- July 16, 2003 - Perl API [joes]
-
-Added $req->parse, $req->status, & "preparse" logic
-to $req->param & $req->upload.
-
-- July 16, 2003 - C API [joes]
-
-Added "preparse" logic to apreq_params & apreq_uploads
-to bring behavior in line with libapreq-1.x.
-
-- July 15, 2003 - C API [joes]
-
-Dropped param->charset.
-Make apreq_brigade_concat public, so mod_apreq can use it
-for its ctx->spool brigade.
-
-- July 14, 2003 - Documentation [joes]
-
-Updated Cookie_pod to reflect API changes over v1.X.
-
-- June 30, 2003 - Documentation [joes]
-
-Added doxygen links to Apache::Request and Apache::Cookie
-perl docs.
-
-- June 30, 2003 - C API [joes]
-
-Added apreq_copy_brigade(bb) to apreq.h.
-
-- June 27, 2003 - C API [joes]
-
-The new filter-based design required a complete
-departure from libapreq-1.X codebase. libapreq-2
-is based solely on APR, and to be fully functional,
-requires a supporting environment similar to Apache-2.
-A person wishing to port libapreq-2 to a new environment
-needs to provide definitions for the declarations in apreq_env.h.
-
-- June 27, 2003 - Perl API [joes]
-
-Aggregates are always collected into an APR::Table-based package.
-New table packages: Apache::Cookie::Table, Apache::Request::Table,
-and Apache::Upload::Table.
-
-- June 27, 2003 - Perl API [joes]
-
-Apache::Cookie->fetch now requires an "environment" argument ($r).
-Its return value is blessed into the Apache::Cookie::Jar class.
-
-- June 27, 2003 - Perl API [joes]
-
-Two new request lookup functions:
+- Perl API [joes]
+ Two new request lookup functions:
-# $req->args - param lookup using only the query string
-# $req->body - param lookup using only the POST data
1.39 +3 -7 httpd-apreq-2/STATUS
Index: STATUS
===================================================================
RCS file: /home/cvs/httpd-apreq-2/STATUS,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -r1.38 -r1.39
--- STATUS 29 Feb 2004 03:32:57 -0000 1.38
+++ STATUS 24 Mar 2004 08:22:47 -0000 1.39
@@ -58,12 +58,6 @@
- symbol exports files:
-# aix needs .exp files
- - Clean up apreq_config_t, breaking binary compatibility by removing
- some useless fields in the struct.
-
- - Fix test_cgi.c (probably a httpd.conf issue) so it passes the
- Apache::Test tests on debian-amd64.
-
OPEN ISSUES:
@@ -79,6 +73,8 @@
- Fix build automake/libtool/autoconf build system so it works
properly on OSX & AIX.
+
+ - Apache::Request::config() is broken.
WISH LIST:
1.11 +1 -1 httpd-apreq-2/build/version_check.pl
Index: version_check.pl
===================================================================
RCS file: /home/cvs/httpd-apreq-2/build/version_check.pl,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- version_check.pl 28 Feb 2004 05:19:38 -0000 1.10
+++ version_check.pl 24 Mar 2004 08:22:47 -0000 1.11
@@ -35,7 +35,7 @@
libtool => { version => "1.4.2", test => \&gnu_version },
autoconf => { version => "2.53", test => \&gnu_version },
automake => { version => "1.4.0", test => \&gnu_version },
- doxygen => { version => "1.3", test => \&gnu_version },
+ doxygen => { version => "1.2", test => \&gnu_version },
);
my %build = (
1.21 +2 -2 httpd-apreq-2/build/xsbuilder.pl
Index: xsbuilder.pl
===================================================================
RCS file: /home/cvs/httpd-apreq-2/build/xsbuilder.pl,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- xsbuilder.pl 4 Dec 2003 06:48:18 -0000 1.20
+++ xsbuilder.pl 24 Mar 2004 08:22:47 -0000 1.21
@@ -163,8 +163,8 @@
for ($_[1]) {
::c_macro("APREQ_DECLARE", "apreq.h")->();
- ::c_macro("APREQ_DECLARE_HOOK", "apreq_parsers.h")->();
- ::c_macro("APREQ_DECLARE_PARSER", "apreq_parsers.h")->();
+ ::c_macro("APREQ_DECLARE_HOOK", "apreq_params.h")->();
+ ::c_macro("APREQ_DECLARE_PARSER", "apreq_params.h")->();
::c_macro("APR_DECLARE")->();
::c_macro("XS")-> ();
}
1.39 +120 -20 httpd-apreq-2/env/mod_apreq.c
Index: mod_apreq.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/env/mod_apreq.c,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -r1.38 -r1.39
--- mod_apreq.c 28 Feb 2004 07:48:14 -0000 1.38
+++ mod_apreq.c 24 Mar 2004 08:22:47 -0000 1.39
@@ -26,7 +26,6 @@
#include "apreq.h"
#include "apreq_env.h"
#include "apreq_params.h"
-#include "apreq_parsers.h"
#include "apreq_cookie.h"
#define dR request_rec *r = (request_rec *)env
@@ -36,6 +35,9 @@
apreq_jar_t *jar;
apreq_request_t *req;
ap_filter_t *f;
+ const char *temp_dir;
+ apr_off_t max_body;
+ apr_ssize_t max_brigade;
};
/** Tracks the filter state */
@@ -44,6 +46,7 @@
apr_bucket_brigade *spool;
apr_status_t status;
unsigned saw_eos;
+ apr_off_t bytes_read;
};
static const char filter_name[] = "APREQ";
@@ -76,7 +79,7 @@
#define APREQ_MODULE_NAME "APACHE2"
-#define APREQ_MODULE_MAGIC_NUMBER 20031107
+#define APREQ_MODULE_MAGIC_NUMBER 20040324
static void apache2_log(const char *file, int line, int level,
@@ -129,6 +132,8 @@
if (cfg == NULL) {
cfg = apr_pcalloc(r->pool, sizeof *cfg);
ap_set_module_config(r->request_config, &apreq_module, cfg);
+ cfg->max_body = -1;
+ cfg->max_brigade = APREQ_MAX_BRIGADE_LEN;
}
return cfg;
}
@@ -200,11 +205,35 @@
request_rec *r = f->r;
apr_bucket_alloc_t *alloc = apr_bucket_alloc_create(r->pool);
struct filter_ctx *ctx = apr_palloc(r->pool, sizeof *ctx);
+ struct env_config *cfg = get_cfg(r);
+
f->ctx = ctx;
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_BADARG, r,
+ "invalid Content-Length header (%s)", cl);
+ ctx->status = APR_BADARG;
+ }
+ else if (content_length > (apr_int64_t)cfg->max_body) {
+ apreq_log(APREQ_ERROR APR_EINIT, r,
+ "Content-Length header (%s) exceeds configured "
+ "max_body limit (" APR_OFF_T_FMT ")",
+ cl, cfg->max_body);
+ ctx->status = APR_EINIT;
+ }
+ }
+ }
}
/**
@@ -234,10 +263,58 @@
}
+static const char *apache2_temp_dir(void *env, const char *path)
+{
+ dR;
+ struct env_config *c = get_cfg(r);
+
+ if (path != NULL) {
+ const char *rv = c->temp_dir;
+ c->temp_dir = apr_pstrdup(r->pool, path);
+ return rv;
+ }
+ if (c->temp_dir == NULL) {
+ if (apr_temp_dir_get(&c->temp_dir, r->pool) != APR_SUCCESS)
+ c->temp_dir = NULL;
+ }
+
+ return c->temp_dir;
+}
+
+
+static apr_off_t apache2_max_body(void *env, apr_off_t bytes)
+{
+ dR;
+ struct env_config *c = get_cfg(r);
+
+ if (bytes >= 0) {
+ apr_off_t rv = c->max_body;
+ c->max_body = bytes;
+ return rv;
+ }
+ return c->max_body;
+}
+
+
+static apr_ssize_t apache2_max_brigade(void *env, apr_ssize_t bytes)
+{
+ dR;
+ struct env_config *c = get_cfg(r);
+
+ if (bytes >= 0) {
+ apr_ssize_t rv = c->max_brigade;
+ c->max_brigade = bytes;
+ return rv;
+ }
+ return c->max_brigade;
+}
+
+
static apr_status_t apreq_filter_init(ap_filter_t *f)
{
request_rec *r = f->r;
struct filter_ctx *ctx;
+ struct env_config *cfg = get_cfg(r);
/* We must be inside config.c:ap_invoke_handler ->
* ap_invoke_filter_init (r->input_filters), and
@@ -260,7 +337,6 @@
*/
if (!APR_BRIGADE_EMPTY(ctx->spool)) {
- struct env_config *cfg = get_cfg(r);
apreq_request_t *req = cfg->req;
/* Adding "f" to the protocol filter chain ensures the
@@ -277,7 +353,8 @@
*
*/
- apreq_log(APREQ_DEBUG 0, r, "dropping stale apreq filter (%d)", f);
+ apreq_log(APREQ_DEBUG 0, r, "dropping stale apreq filter (%p)", f);
+
if (req) {
req->parser = NULL;
req->body = NULL;
@@ -293,7 +370,7 @@
*/
apreq_filter_relocate(f);
}
- }
+ }
return APR_SUCCESS;
}
@@ -307,14 +384,13 @@
{
request_rec *r = f->r;
struct filter_ctx *ctx;
- apr_status_t rv;
+ struct env_config *cfg;
apreq_request_t *req;
+ apr_status_t rv;
if (f->ctx == NULL)
apreq_filter_make_context(f);
- ctx = f->ctx;
-
switch (mode) {
case AP_MODE_READBYTES:
case AP_MODE_EXHAUSTIVE:
@@ -324,20 +400,37 @@
return APR_ENOTIMPL;
}
- req = get_cfg(r)->req;
+ ctx = f->ctx;
+ cfg = get_cfg(r);
+ req = cfg->req;
if (bb != NULL) {
if (!ctx->saw_eos) {
- apr_bucket_brigade *tmp;
- rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
+
+ if (ctx->status == APR_INCOMPLETE) {
+ apr_bucket_brigade *tmp;
+ apr_off_t len;
+ rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
- if (rv != APR_SUCCESS) {
- apreq_log(APREQ_ERROR rv, r, "get_brigade failed");
- return rv;
+ if (rv != APR_SUCCESS) {
+ apreq_log(APREQ_ERROR rv, r, "get_brigade failed");
+ return rv;
+ }
+
+ tmp = apreq_brigade_copy(bb);
+ apr_brigade_length(tmp,0,&len);
+ ctx->bytes_read += len;
+ APR_BRIGADE_CONCAT(ctx->bb, tmp);
+
+ if (cfg->max_body >= 0 && ctx->bytes_read > cfg->max_body) {
+ ctx->status = APR_ENOSPC;
+ apreq_log(APREQ_ERROR ctx->status, r, "Bytes read (" APR_OFF_T_FMT
+ ") exceeds configured max_body limit (" APR_OFF_T_FMT ")",
+ ctx->bytes_read, cfg->max_body);
+ }
+
}
- tmp = apreq_copy_brigade(bb);
- APR_BRIGADE_CONCAT(ctx->bb, tmp);
if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(ctx->bb)))
ctx->saw_eos = 1;
}
@@ -359,7 +452,7 @@
if (ctx->status != APR_INCOMPLETE) {
if (APR_BRIGADE_EMPTY(ctx->spool)) {
- apreq_log(APREQ_DEBUG ctx->status,r,"removing filter(%d)",
+ apreq_log(APREQ_DEBUG ctx->status,r,"removing filter (%d)",
r->input_filters == f);
ap_remove_input_filter(f);
}
@@ -394,13 +487,21 @@
if (rv != APR_SUCCESS)
return rv;
- bb = apreq_copy_brigade(tmp);
+ bb = apreq_brigade_copy(tmp);
apr_brigade_length(bb,0,&len);
total_read += len;
- apreq_brigade_concat(r->pool, req->cfg, ctx->spool, tmp);
+ apreq_brigade_concat(r, ctx->spool, tmp);
APR_BRIGADE_CONCAT(ctx->bb, bb);
last = APR_BRIGADE_LAST(ctx->spool);
}
+ ctx->bytes_read += total_read;
+
+ if (cfg->max_body >= 0 && ctx->bytes_read > cfg->max_body) {
+ ctx->status = APR_ENOSPC;
+ apreq_log(APREQ_ERROR ctx->status, r, "Bytes read (" APR_OFF_T_FMT
+ ") exceeds configured max_body limit (" APR_OFF_T_FMT ")",
+ ctx->bytes_read, cfg->max_body);
+ }
}
else
return APR_SUCCESS;
@@ -434,4 +535,3 @@
NULL,
register_hooks, /* callback for registering hooks */
};
-
1.8 +0 -1 httpd-apreq-2/env/test_cgi.c
Index: test_cgi.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/env/test_cgi.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- test_cgi.c 28 Feb 2004 07:48:14 -0000 1.7
+++ test_cgi.c 24 Mar 2004 08:22:48 -0000 1.8
@@ -17,7 +17,6 @@
#include "apreq.h"
#include "apreq_env.h"
#include "apreq_params.h"
-#include "apreq_parsers.h"
#include "apreq_cookie.h"
#include "apr_strings.h"
#include "apr_lib.h"
1.20 +3 -0 httpd-apreq-2/glue/perl/xsbuilder/Apache/Request/Apache__Request.h
Index: Apache__Request.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/Apache/Request/Apache__Request.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- Apache__Request.h 28 Feb 2004 07:48:14 -0000 1.19
+++ Apache__Request.h 24 Mar 2004 08:22:48 -0000 1.20
@@ -161,6 +161,8 @@
req = apreq_xs_sv2(request,ST(0));
+ XSRETURN_UNDEF; /* XXX fixme (apreq_request_config is now gone)
+
for (j = 1; j + 1 < items; j += 2) {
STRLEN alen, vlen;
const char *attr = SvPVbyte(ST(j),alen),
@@ -169,6 +171,7 @@
if (status != APR_SUCCESS)
break;
}
+*/
XSRETURN_IV(status);
}
1.16 +1 -1 httpd-apreq-2/glue/perl/xsbuilder/maps/apreq_functions.map
Index: apreq_functions.map
===================================================================
RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/maps/apreq_functions.map,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- apreq_functions.map 17 Jul 2003 02:59:33 -0000 1.15
+++ apreq_functions.map 24 Mar 2004 08:22:48 -0000 1.16
@@ -24,7 +24,7 @@
########## Apache::Upload:: Functions ##########
MODULE=Apache::Request PACKAGE=Apache::Upload PREFIX=Apache__Upload_
- apr_bucket_brigade *:DEFINE_bb | apreq_copy_brigade(apreq_xs_rv2param(sv)->bb) | SV *:sv
+ apr_bucket_brigade *:DEFINE_bb | apreq_brigade_copy(apreq_xs_rv2param(sv)->bb) | SV *:sv
apr_table_t *:DEFINE_info | apreq_param_info(apreq_xs_rv2param(sv)) | SV *:sv
const char *:DEFINE_name | apreq_param_name(apreq_xs_rv2param(sv)) | SV *:sv
char *:DEFINE_filename | apreq_param_value(apreq_xs_rv2param(sv)) | SV *:sv
1.6 +0 -8 httpd-apreq-2/glue/perl/xsbuilder/maps/apreq_structures.map
Index: apreq_structures.map
===================================================================
RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/maps/apreq_structures.map,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- apreq_structures.map 28 Jun 2003 17:51:38 -0000 1.5
+++ apreq_structures.map 24 Mar 2004 08:22:48 -0000 1.6
@@ -1,12 +1,5 @@
########## APREQ structures ##########
-<apreq_cfg_t MODULE=Apache::Request>
- temp_dir
- max_len
- read_bytes
- disable_uploads
-</apreq_cfg_t>
-
#<apreq_value_t MODULE=Apache::Request>
# name
# status
@@ -15,7 +8,6 @@
#</apreq_value_t>
!<apreq_param_t MODULE=Apache::Request>
-! charset
! info
! bb
! v
1.16 +1 -1 httpd-apreq-2/src/Makefile.am
Index: Makefile.am
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/Makefile.am,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- Makefile.am 28 Feb 2004 05:19:38 -0000 1.15
+++ Makefile.am 24 Mar 2004 08:22:48 -0000 1.16
@@ -5,7 +5,7 @@
libapreq2_la_SOURCES = apreq.c apreq_version.c apreq_cookie.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_parsers.h
+ apreq_params.h apreq_env.h
libapreq2_la_LDFLAGS = -version-info @APREQ_LIBTOOL_VERSION@
pkgincludedir = $(includedir)/@APREQ_LIBNAME@
1.32 +7 -6 httpd-apreq-2/src/apreq.c
Index: apreq.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- apreq.c 28 Feb 2004 07:48:14 -0000 1.31
+++ apreq.c 24 Mar 2004 08:22:48 -0000 1.32
@@ -76,12 +76,12 @@
APREQ_DECLARE(const char *)apreq_enctype(void *env)
{
char *enctype;
- const char *ct = apreq_env_content_type(env), *semicolon;
+ const char *ct = apreq_env_content_type(env);
if (ct == NULL)
return NULL;
else {
- semicolon = strchr(ct, ';');
+ const char *semicolon = strchr(ct, ';');
if (semicolon) {
enctype = apr_pstrdup(apreq_env_pool(env), ct);
enctype[semicolon - ct] = 0;
@@ -568,7 +568,7 @@
const char *src, const apr_size_t slen)
{
apreq_value_t *rv;
- if (src == NULL || slen == 0)
+ if (src == NULL)
return NULL;
rv = apr_palloc(p, 3 * slen + sizeof *rv);
@@ -624,7 +624,7 @@
return s;
}
-
+/* this function now consumes the brigade, deleting buckets as it goes */
APREQ_DECLARE(apr_status_t) apreq_brigade_fwrite(apr_file_t *f,
apr_off_t *wlen,
apr_bucket_brigade *bb)
@@ -636,7 +636,7 @@
*wlen = 0;
for (e = APR_BRIGADE_FIRST(bb); e != APR_BRIGADE_SENTINEL(bb);
- e = APR_BUCKET_NEXT(e))
+ e = APR_BRIGADE_FIRST(bb))
{
apr_size_t len;
if (n == APREQ_NELTS) {
@@ -651,6 +651,7 @@
return s;
v[n++].iov_len = len;
+ apr_bucket_delete(e);
}
while (n > 0) {
@@ -702,7 +703,7 @@
}
APREQ_DECLARE(apr_bucket_brigade *)
- apreq_copy_brigade(const apr_bucket_brigade *bb)
+ apreq_brigade_copy(const apr_bucket_brigade *bb)
{
apr_bucket_brigade *copy;
apr_bucket *e;
1.38 +3 -1 httpd-apreq-2/src/apreq.h
Index: apreq.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq.h,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- apreq.h 28 Feb 2004 07:48:14 -0000 1.37
+++ apreq.h 24 Mar 2004 08:22:48 -0000 1.38
@@ -106,6 +106,8 @@
#define APREQ_XML_ENCTYPE "application/xml"
#define APREQ_NELTS 8
+#define APREQ_READ_AHEAD (64 * 1024)
+#define APREQ_MAX_BRIGADE_LEN (256 * 1024)
/**
* libapreq-2's pre-extensible string type
@@ -355,7 +357,7 @@
APREQ_DECLARE(apr_file_t *) apreq_brigade_spoolfile(apr_bucket_brigade *bb);
APREQ_DECLARE(apr_bucket_brigade *)
- apreq_copy_brigade(const apr_bucket_brigade *bb);
+ apreq_brigade_copy(const apr_bucket_brigade *bb);
APREQ_DECLARE(apr_status_t)
apreq_header_attribute(const char *hdr,
1.5 +111 -10 httpd-apreq-2/src/apreq_env.c
Index: apreq_env.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_env.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- apreq_env.c 28 Feb 2004 07:48:14 -0000 1.4
+++ apreq_env.c 24 Mar 2004 08:22:48 -0000 1.5
@@ -17,11 +17,11 @@
#include "apreq.h"
#include "apreq_env.h"
#include "apreq_params.h"
-#include "apreq_parsers.h"
#include "apreq_cookie.h"
#include "apr_strings.h"
#include "apr_lib.h"
#include "apr_env.h"
+#include "apr_file_io.h"
#include <stdlib.h>
#include <stdio.h>
@@ -89,13 +89,34 @@
return apreq_env->read(env,block,bytes);
}
+APREQ_DECLARE(const char *) apreq_env_temp_dir(void *env, const char *path)
+{
+ return apreq_env->temp_dir(env,path);
+}
+
+APREQ_DECLARE(apr_off_t) apreq_env_max_body(void *env, apr_off_t bytes)
+{
+ return apreq_env->max_body(env,bytes);
+}
+
+APREQ_DECLARE(apr_ssize_t) apreq_env_max_brigade(void *env, apr_ssize_t bytes)
+{
+ return apreq_env->max_brigade(env,bytes);
+}
+
+
#define dP apr_pool_t *p = (apr_pool_t *)env
static struct {
apreq_request_t *req;
apreq_jar_t *jar;
apr_status_t status;
-} ctx;
+ const char *temp_dir;
+ apr_off_t max_body;
+ apr_ssize_t max_brigade;
+ apr_bucket_brigade *in;
+ apr_off_t bytes_read;
+} ctx = {NULL, NULL, APR_SUCCESS, NULL, -1, APREQ_MAX_BRIGADE_LEN, NULL, 0};
#define CRLF "\015\012"
@@ -120,7 +141,7 @@
#define APREQ_MODULE_NAME "CGI"
-#define APREQ_MODULE_MAGIC_NUMBER 20031025
+#define APREQ_MODULE_MAGIC_NUMBER 20040324
static apr_pool_t *cgi_pool(void *env)
{
@@ -201,7 +222,9 @@
va_list vp)
{
dP;
- fprintf(stderr, "[%s(%d)] %s\n", file, line, apr_pvsprintf(p,fmt,vp));
+ char buf[256];
+ fprintf(stderr, "[%s(%d): %s] %s\n", file, line,
+ apr_strerror(status,buf,255),apr_pvsprintf(p,fmt,vp));
}
static apr_status_t cgi_read(void *env,
@@ -210,20 +233,98 @@
{
dP;
apreq_request_t *req = apreq_request(env, NULL);
+ apr_bucket *e;
+ apr_status_t s;
- if (req->body == NULL) {
+ if (ctx.in == NULL) {
apr_bucket_alloc_t *alloc = apr_bucket_alloc_create(p);
- apr_bucket_brigade *bb = apr_brigade_create(p, alloc);
apr_bucket *stdin_pipe, *eos = apr_bucket_eos_create(alloc);
apr_file_t *in;
apr_file_open_stdin(&in, p);
stdin_pipe = apr_bucket_pipe_create(in,alloc);
- APR_BRIGADE_INSERT_HEAD(bb, stdin_pipe);
- APR_BRIGADE_INSERT_TAIL(bb, eos);
- ctx.status = apreq_parse_request(req, bb);
+ ctx.in = apr_brigade_create(p, alloc);
+ APR_BRIGADE_INSERT_HEAD(ctx.in, stdin_pipe);
+ APR_BRIGADE_INSERT_TAIL(ctx.in, eos);
+ ctx.status = APR_INCOMPLETE;
+ }
+
+
+ if (ctx.status != APR_INCOMPLETE)
+ return ctx.status;
+
+ switch (s = apr_brigade_partition(ctx.in, bytes, &e)) {
+ apr_bucket_brigade *bb;
+ apr_off_t len;
+
+ case APR_SUCCESS:
+ bb = ctx.in;
+ ctx.in = apr_brigade_split(bb, e);
+ ctx.bytes_read += bytes;
+ if (ctx.max_body >= 0) {
+ if (ctx.bytes_read > ctx.max_body)
+ return ctx.status = APR_ENOSPC;
+ }
+ return ctx.status = apreq_parse_request(req, bb);
+
+ case APR_INCOMPLETE:
+ bb = ctx.in;
+ ctx.in = apr_brigade_split(bb, e);
+ s = apr_brigade_length(bb,1,&len);
+ if (s != APR_SUCCESS)
+ return ctx.status = s;
+ ctx.bytes_read += len;
+ if (ctx.max_body >= 0) {
+ if (ctx.bytes_read > ctx.max_body)
+ return ctx.status = APR_ENOSPC;
+ }
+ return ctx.status = apreq_parse_request(req, bb);
+
+ default:
+ return ctx.status = s;
+ }
+}
+
+
+static const char *cgi_temp_dir(void *env, const char *path)
+{
+ if (path != NULL) {
+ dP;
+ const char *rv = ctx.temp_dir;
+ ctx.temp_dir = apr_pstrdup(p, path);
+ return rv;
}
- return ctx.status;
+ if (ctx.temp_dir == NULL) {
+ dP;
+ if (apr_temp_dir_get(&ctx.temp_dir, p) != APR_SUCCESS)
+ ctx.temp_dir = NULL;
+ }
+
+ return ctx.temp_dir;
}
+
+
+static apr_off_t cgi_max_body(void *env, apr_off_t bytes)
+{
+ if (bytes >= 0) {
+ apr_off_t rv = ctx.max_body;
+ ctx.max_body = bytes;
+ return rv;
+ }
+ return ctx.max_body;
+}
+
+
+static apr_ssize_t cgi_max_brigade(void *env, apr_ssize_t bytes)
+{
+ if (bytes >= 0) {
+ apr_ssize_t rv = ctx.max_brigade;
+ ctx.max_brigade = bytes;
+ return rv;
+ }
+ return ctx.max_brigade;
+}
+
+
static APREQ_ENV_MODULE(cgi, APREQ_MODULE_NAME,
APREQ_MODULE_MAGIC_NUMBER);
1.22 +9 -3 httpd-apreq-2/src/apreq_env.h
Index: apreq_env.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_env.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- apreq_env.h 28 Feb 2004 07:48:14 -0000 1.21
+++ apreq_env.h 24 Mar 2004 08:22:48 -0000 1.22
@@ -19,7 +19,6 @@
#include "apreq_params.h"
#include "apreq_cookie.h"
-#include "apreq_parsers.h"
#ifdef HAVE_SYSLOG
#include <syslog.h>
@@ -87,7 +86,6 @@
APREQ_DECLARE(const char *) apreq_env_query_string(void *env);
APREQ_DECLARE(const char *) apreq_env_header_in(void *env, const char *name);
-
#define apreq_env_content_type(env) apreq_env_header_in(env, "Content-Type")
#define apreq_env_cookie(env) apreq_env_header_in(env, "Cookie")
#define apreq_env_cookie2(env) apreq_env_header_in(env, "Cookie2")
@@ -103,6 +101,10 @@
apr_read_type_e block,
apr_off_t bytes);
+APREQ_DECLARE(const char *) apreq_env_temp_dir(void *env, const char *path);
+APREQ_DECLARE(apr_off_t) apreq_env_max_body(void *env, apr_off_t bytes);
+APREQ_DECLARE(apr_ssize_t) apreq_env_max_brigade(void *env, apr_ssize_t bytes);
+
typedef struct apreq_env_t {
const char *name;
apr_uint32_t magic_number;
@@ -114,11 +116,15 @@
const char *(*header_in)(void *,const char *);
apr_status_t (*header_out)(void *, const char *,char *);
apr_status_t (*read)(void *,apr_read_type_e,apr_off_t);
+ const char *(*temp_dir)(void *, const char *);
+ apr_off_t (*max_body)(void *,apr_off_t);
+ apr_ssize_t (*max_brigade)(void *, apr_ssize_t);
} apreq_env_t;
#define APREQ_ENV_MODULE(pre, name, mmn) const apreq_env_t pre##_module = { \
name, mmn, pre##_log, pre##_pool, pre##_jar, pre##_request, \
- pre##_query_string, pre##_header_in, pre##_header_out, pre##_read }
+ pre##_query_string, pre##_header_in, pre##_header_out, pre##_read, \
+ pre##_temp_dir, pre##_max_body, pre##_max_brigade }
APREQ_DECLARE(const apreq_env_t *) apreq_env_module(const apreq_env_t *mod);
1.38 +13 -97 httpd-apreq-2/src/apreq_params.c
Index: apreq_params.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_params.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- apreq_params.c 28 Feb 2004 07:48:14 -0000 1.37
+++ apreq_params.c 24 Mar 2004 08:22:48 -0000 1.38
@@ -15,7 +15,6 @@
*/
#include "apreq_params.h"
-#include "apreq_parsers.h"
#include "apreq_env.h"
#include "apr_strings.h"
#include "apr_lib.h"
@@ -51,17 +50,8 @@
APREQ_DECLARE(apreq_request_t *) apreq_request(void *env, const char *qs)
{
apreq_request_t *req;
- apreq_cfg_t *cfg;
apr_pool_t *p;
- /** default parser configuration */
- static const apreq_cfg_t default_cfg = {
- MAX_LEN, /**< limit on POST data size */
- MAX_BRIGADE_LEN, /**< limit on brigade size */
- MAX_FIELDS, /**< maximum number of form fields */
- MAX_READ_AHEAD /**< maximum amount of prefetch data */
- };
-
if (qs == NULL) {
apreq_request_t *old_req = apreq_env_request(env,NULL);
if (old_req != NULL)
@@ -73,12 +63,9 @@
req = apr_palloc(p, sizeof *req);
req->env = env;
req->args = apr_table_make(p, APREQ_NELTS);
- req->cfg = apr_palloc(p, sizeof(apreq_cfg_t));
req->body = NULL;
req->parser = apreq_parser(env, NULL);
- /* XXX need to install copy/merge callbacks for apreq_param_t */
-
/* XXX get/set race condition here wrt apreq_env_request? */
old_req = apreq_env_request(env, req);
@@ -96,15 +83,11 @@
req = apr_palloc(p, sizeof *req);
req->env = env;
req->args = apr_table_make(p, APREQ_NELTS);
- req->cfg = apr_palloc(p, sizeof(apreq_cfg_t));
req->body = NULL;
req->parser = apreq_parser(env, NULL);
- /* XXX need to install copy/merge callbacks for apreq_param_t */
}
- *req->cfg = default_cfg;
-
if (qs != NULL) {
apr_status_t s = apreq_parse_query_string(p, req->args, qs);
if (s != APR_SUCCESS)
@@ -124,12 +107,11 @@
val = apr_table_get(req->body, name);
if (val == NULL) {
- if (req->cfg->read_ahead) {
- apreq_env_read(req->env, APR_BLOCK_READ, req->cfg->read_ahead);
- if (req->body)
- val = apr_table_get(req->body, name);
- }
+ apreq_env_read(req->env, APR_BLOCK_READ, APREQ_READ_AHEAD);
+ if (req->body)
+ val = apr_table_get(req->body, name);
}
+
return val ? apreq_value_to_param(apreq_strtoval(val)) : NULL;
}
@@ -137,11 +119,10 @@
APREQ_DECLARE(apr_table_t *) apreq_params(apr_pool_t *pool,
const apreq_request_t *req)
{
- if (req->cfg->read_ahead) {
- apr_status_t s;
- do s = apreq_env_read(req->env, APR_BLOCK_READ, req->cfg->read_ahead);
- while (s == APR_INCOMPLETE);
- }
+ apr_status_t s;
+
+ do s = apreq_env_read(req->env, APR_BLOCK_READ, APREQ_READ_AHEAD);
+ while (s == APR_INCOMPLETE);
return req->body ? apr_table_overlay(pool, req->args, req->body) :
apr_table_copy(pool, req->args);
@@ -253,8 +234,6 @@
APREQ_DECLARE(apr_status_t) apreq_parse_request(apreq_request_t *req,
apr_bucket_brigade *bb)
{
- apreq_cfg_t *cfg = req->cfg;
-
if (req->parser == NULL)
req->parser = apreq_parser(req->env,NULL);
if (req->parser == NULL)
@@ -263,7 +242,7 @@
if (req->body == NULL)
req->body = apr_table_make(apreq_env_pool(req->env),APREQ_NELTS);
- return apreq_run_parser(req->parser, req->cfg, req->body, bb);
+ return apreq_run_parser(req->parser, req->env, req->body, bb);
}
@@ -281,11 +260,9 @@
const apreq_request_t *req)
{
apr_table_t *t;
- if (req->cfg->read_ahead) {
- apr_status_t s;
- do s = apreq_env_read(req->env, APR_BLOCK_READ, req->cfg->read_ahead);
- while (s == APR_INCOMPLETE);
- }
+ apr_status_t s;
+ do s = apreq_env_read(req->env, APR_BLOCK_READ, APREQ_READ_AHEAD);
+ while (s == APR_INCOMPLETE);
if (req->body == NULL)
return NULL;
@@ -312,70 +289,9 @@
const char *key)
{
apreq_param_t *param = NULL;
- if (req->cfg->read_ahead)
- apreq_env_read(req->env, APR_BLOCK_READ, req->cfg->read_ahead);
+ apreq_env_read(req->env, APR_BLOCK_READ, APREQ_READ_AHEAD);
if (req->body == NULL)
return NULL;
apr_table_do(upload_get, ¶m, req->body, key, NULL);
return param;
-}
-
-APREQ_DECLARE(apr_status_t)
- apreq_request_config(apreq_request_t *req,
- const char *attr, apr_size_t alen,
- const char *val, apr_size_t vlen)
-{
- apreq_cfg_t *cfg = req->cfg;
- apr_pool_t *p;
-
- if (alen < 2)
- return APR_BADARG;
-
- if ( attr[0] == '-' || attr[0] == '$' ) {
- ++attr;
- --alen;
- }
-
- switch (apr_tolower(*attr)) {
-
- case 'p': /* POST_MAX */
- cfg->max_len = apreq_atoi64f(val);
- break;
-
- case 'd': /* DISABLE_UPLOADS */
- while (!apr_isdigit(*val)) {
- if (vlen == 0)
- return APR_BADARG;
- ++val;
- --vlen;
- }
- cfg->disable_uploads = *val - '0';
- break;
-
- case 'f': /* FIELD_LIMIT */
- cfg->max_fields = apreq_atoi64f(val);
- break;
-
- case 'b': /* BRIGADE_LIMIT */
- cfg->max_brigade_len = apreq_atoi64f(val);
- break;
-
- case 'r': /* READ_AHEAD */
- cfg->read_ahead = apreq_atoi64f(val);
- break;
-
- case 't': /* TEMP_DIR */
- p = apreq_env_pool(req->env);
- cfg->temp_dir = (vlen ? apr_pstrmemdup(p,val,vlen) : NULL);
- break;
-
- case 'u': /* UPLOAD_HOOK */
- /* XXX not implemented yet */
-
- default:
- return APR_ENOTIMPL;
-
- };
-
- return APR_SUCCESS;
}
1.27 +55 -6 httpd-apreq-2/src/apreq_params.h
Index: apreq_params.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_params.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- apreq_params.h 28 Feb 2004 07:48:14 -0000 1.26
+++ apreq_params.h 24 Mar 2004 08:22:48 -0000 1.27
@@ -18,7 +18,6 @@
#define APREQ_PARAM_H
#include "apreq.h"
-#include "apreq_parsers.h"
#ifdef __cplusplus
extern "C" {
@@ -43,6 +42,9 @@
apreq_value_t v; /**< underlying name/value/status info */
} apreq_param_t;
+typedef struct apreq_hook_t apreq_hook_t;
+typedef struct apreq_parser_t apreq_parser_t;
+
/** accessor macros */
#define apreq_value_to_param(ptr) apreq_attr_to_type(apreq_param_t, v, ptr)
#define apreq_param_name(p) ((p)->v.name)
@@ -63,7 +65,6 @@
apr_table_t *args; /**< parsed query_string */
apr_table_t *body; /**< parsed post data */
apreq_parser_t *parser; /**< active parser for this request */
- apreq_cfg_t *cfg; /**< parser configuration */
void *env; /**< request environment */
} apreq_request_t;
@@ -195,10 +196,58 @@
APREQ_DECLARE(apreq_param_t *) apreq_upload(const apreq_request_t *req,
const char *key);
-APREQ_DECLARE(apr_status_t)
- apreq_request_config(apreq_request_t *req,
- const char *attr, apr_size_t alen,
- const char *val, apr_size_t vlen);
+
+#define APREQ_DECLARE_PARSER(f) apr_status_t (f)(apreq_parser_t *parser, \
+ void *env, \
+ apr_table_t *t, \
+ apr_bucket_brigade *bb)
+
+#define APREQ_DECLARE_HOOK(f) apr_status_t (f)(apreq_hook_t *hook, \
+ void *env, \
+ const apreq_param_t *param, \
+ apr_bucket_brigade *bb)
+
+struct apreq_hook_t {
+ APREQ_DECLARE_HOOK (*hook);
+ apreq_hook_t *next;
+ void *ctx;
+};
+
+struct apreq_parser_t {
+ APREQ_DECLARE_PARSER (*parser);
+ const char *enctype;
+ apreq_hook_t *hook;
+ void *ctx;
+};
+
+
+#define apreq_run_parser(psr,env,t,bb) (psr)->parser(psr,env,t,bb)
+#define apreq_run_hook(h,env,param,bb) (h)->hook(h,env,param,bb)
+
+APREQ_DECLARE(apr_status_t) apreq_brigade_concat(void *env,
+ apr_bucket_brigade *out,
+ apr_bucket_brigade *in);
+
+
+APREQ_DECLARE_PARSER(apreq_parse_headers);
+APREQ_DECLARE_PARSER(apreq_parse_urlencoded);
+APREQ_DECLARE_PARSER(apreq_parse_multipart);
+
+APREQ_DECLARE(apreq_parser_t *) apreq_make_parser(apr_pool_t *pool,
+ const char *enctype,
+ APREQ_DECLARE_PARSER(*parser),
+ apreq_hook_t *hook,
+ void *ctx);
+
+APREQ_DECLARE(apreq_hook_t *) apreq_make_hook(apr_pool_t *pool,
+ APREQ_DECLARE_HOOK(*hook),
+ apreq_hook_t *next,
+ void *ctx);
+
+APREQ_DECLARE(apr_status_t)apreq_add_hook(apreq_parser_t *p,
+ apreq_hook_t *h);
+
+APREQ_DECLARE(apreq_parser_t *)apreq_parser(void *env, apreq_hook_t *hook);
/** @} */
#ifdef __cplusplus
1.40 +59 -88 httpd-apreq-2/src/apreq_parsers.c
Index: apreq_parsers.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_parsers.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- apreq_parsers.c 28 Feb 2004 07:48:14 -0000 1.39
+++ apreq_parsers.c 24 Mar 2004 08:22:48 -0000 1.40
@@ -14,7 +14,6 @@
** limitations under the License.
*/
-#include "apreq_parsers.h"
#include "apreq_params.h"
#include "apreq_env.h"
#include "apr_lib.h"
@@ -32,40 +31,14 @@
#define CRLF "\015\012"
#endif
-#ifndef apr_table_pool
-#define apr_table_pool(t) ((apr_array_header_t *)(t))->pool
-#endif
-
-#define SANITY_CHECK do { \
- apr_off_t off; \
- apr_status_t s = apr_brigade_length(bb, 0, &off); \
- if (s != APR_SUCCESS) \
- return s; \
- ctx->bytes_seen += off; \
- if (ck_sanity(cfg, ctx->bytes_seen, apr_table_elts(t)->nelts)) \
- return APR_EGENERAL; \
-} while (0)
-
-APR_INLINE
-static apr_status_t ck_sanity(const apreq_cfg_t *cfg,
- const apr_off_t bytes_seen,
- const int fields)
-{
- if (cfg->max_len < bytes_seen || cfg->max_fields < fields)
- return APR_EGENERAL;
- else
- return APR_SUCCESS;
-}
-
-
APREQ_DECLARE(apreq_parser_t *) apreq_make_parser(apr_pool_t *pool,
- const char *type,
+ const char *enctype,
APREQ_DECLARE_PARSER(*parser),
apreq_hook_t *hook,
void *ctx)
{
apreq_parser_t *p = apr_palloc(pool, sizeof *p);
- p->content_type = apr_pstrdup(pool,type);
+ p->enctype = apr_pstrdup(pool,enctype);
p->parser = parser;
p->hook = hook;
p->ctx = ctx;
@@ -131,7 +104,7 @@
const apr_size_t nlen,
const apr_size_t vlen)
{
- apr_pool_t *pool = apr_table_pool(t);
+ apr_pool_t *pool = apr_table_elts(t)->pool;
apreq_param_t *param = apr_palloc(pool, nlen + vlen + 1 + sizeof *param);
apr_size_t total, off;
apreq_value_t *v = ¶m->v;
@@ -212,27 +185,30 @@
}
struct url_ctx {
- apr_off_t bytes_seen;
- apr_status_t status;
+ apr_bucket_brigade *bb;
+ enum {
+ URL_NAME,
+ URL_VALUE
+ } status;
};
APREQ_DECLARE_PARSER(apreq_parse_urlencoded)
{
- apr_pool_t *pool = apr_table_pool(t);
+ apr_pool_t *pool = apr_table_elts(t)->pool;
apr_ssize_t nlen, vlen;
apr_bucket *e;
struct url_ctx *ctx;
-/* use parser->v.status to maintain state */
-#define URL_NAME 0
-#define URL_VALUE 1
-
if (parser->ctx == NULL) {
parser->ctx = apr_pcalloc(pool, sizeof *ctx);
+ ctx = parser->ctx;
+ ctx->bb = apr_brigade_create(pool, bb->bucket_alloc);
}
- ctx = parser->ctx;
+ else
+ ctx = parser->ctx;
- SANITY_CHECK;
+ APR_BRIGADE_CONCAT(ctx->bb, bb);
+ bb = ctx->bb;
parse_url_brigade:
@@ -244,12 +220,14 @@
{
apr_size_t off = 0, dlen;
const char *data;
- apr_status_t s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ);
+ apr_status_t s;
if (APR_BUCKET_IS_EOS(e)) {
- return (ctx->status == URL_NAME) ? APR_SUCCESS :
+ s = (ctx->status == URL_NAME) ? APR_SUCCESS :
split_urlword(t, bb, nlen+1, vlen);
+ return s;
}
+ s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ);
if ( s != APR_SUCCESS )
return s;
@@ -293,12 +271,13 @@
/********************* header parsing utils ********************/
-static apr_status_t split_header(apr_pool_t *pool, apr_table_t *t,
+static apr_status_t split_header(apr_table_t *t,
apr_bucket_brigade *bb,
const apr_size_t nlen,
const apr_size_t glen,
const apr_size_t vlen)
{
+ apr_pool_t *pool = apr_table_elts(t)->pool;
apreq_value_t *v = apr_palloc(pool, nlen + vlen + sizeof *v);
apr_size_t off;
@@ -385,31 +364,27 @@
}
struct hdr_ctx {
- apr_off_t bytes_seen;
- apr_status_t status;
+ enum {
+ HDR_NAME,
+ HDR_GAP,
+ HDR_VALUE,
+ HDR_NEWLINE,
+ HDR_CONTINUE
+ } status;
};
APREQ_DECLARE_PARSER(apreq_parse_headers)
{
- apr_pool_t *pool = apr_table_pool(t);
+ apr_pool_t *pool = apreq_env_pool(env);
apr_ssize_t nlen, glen, vlen;
apr_bucket *e;
struct hdr_ctx *ctx;
-/* use ctx->status to maintain state */
-#define HDR_NAME 0
-#define HDR_GAP 1
-#define HDR_VALUE 2
-#define HDR_NEWLINE 3
-#define HDR_CONTINUE 4
-
if (parser->ctx == NULL)
parser->ctx = apr_pcalloc(pool, sizeof *ctx);
ctx = parser->ctx;
- if (ck_sanity(cfg, cfg->max_len, apr_table_elts(t)->nelts))
- return APR_EGENERAL;
parse_hdr_brigade:
@@ -531,7 +506,7 @@
/* can parse brigade now */
if (off > 0)
apr_bucket_split(e, off);
- s = split_header(pool, t, bb, nlen, glen, vlen);
+ s = split_header(t, bb, nlen, glen, vlen);
if (s != APR_SUCCESS)
return s;
@@ -580,13 +555,18 @@
apreq_parser_t *hdr_parser;
const apr_strmatch_pattern *pattern;
char *bdry;
- apr_off_t bytes_seen;
- apr_status_t status;
+ enum {
+ MFD_INIT,
+ MFD_NEXTLINE,
+ MFD_HEADER,
+ MFD_PARAM,
+ MFD_UPLOAD,
+ MFD_ERROR
+ } status;
};
-static apr_status_t split_on_bdry(apr_pool_t *pool,
- apr_bucket_brigade *out,
+static apr_status_t split_on_bdry(apr_bucket_brigade *out,
apr_bucket_brigade *in,
const apr_strmatch_pattern *pattern,
const char *bdry)
@@ -670,8 +650,7 @@
#define MAX_FILE_BUCKET_LENGTH ((apr_off_t) 1 << (6 * sizeof(apr_size_t)))
-APREQ_DECLARE(apr_status_t) apreq_brigade_concat(apr_pool_t *pool,
- const apreq_cfg_t *cfg,
+APREQ_DECLARE(apr_status_t) apreq_brigade_concat(void *env,
apr_bucket_brigade *out,
apr_bucket_brigade *in)
{
@@ -689,26 +668,28 @@
if (! APR_BUCKET_IS_FILE(last)) {
apr_bucket_brigade *bb;
apr_file_t *file;
- apr_off_t len;
+ apr_off_t len, max_brigade = apreq_env_max_brigade(env,-1);
s = apr_brigade_length(out, 1, &len);
if (s != APR_SUCCESS)
return s;
- if (cfg && len < cfg->max_brigade_len) {
+
+ if (max_brigade >= 0 && len < max_brigade) {
APR_BRIGADE_CONCAT(out, in);
return APR_SUCCESS;
}
- s = apreq_file_mktemp(&file, pool, cfg ? cfg->temp_dir : NULL);
+ s = apreq_file_mktemp(&file, apreq_env_pool(env),
+ apreq_env_temp_dir(env,NULL));
if (s != APR_SUCCESS)
return s;
- s = apreq_brigade_fwrite(file, &wlen, out);
+ s = apreq_brigade_fwrite(file, &wlen, apreq_brigade_copy(out));
if (s != APR_SUCCESS)
return s;
- last = apr_bucket_file_create(file, wlen, 0, pool, out->bucket_alloc);
+ last = apr_bucket_file_create(file, wlen, 0, out->p, out->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(out, last);
}
@@ -736,17 +717,11 @@
APREQ_DECLARE_PARSER(apreq_parse_multipart)
{
- apr_pool_t *pool = apr_table_pool(t);
+ apr_pool_t *pool = apreq_env_pool(env);
struct mfd_ctx *ctx = parser->ctx;
apr_off_t off;
apr_status_t s;
-#define MFD_INIT 0
-#define MFD_NEXTLINE 1
-#define MFD_HEADER 2
-#define MFD_PARAM 3
-#define MFD_UPLOAD 4
-#define MFD_ERROR -1
if (parser->ctx == NULL) {
char *ct;
@@ -754,7 +729,7 @@
ctx = apr_pcalloc(pool, sizeof *ctx);
- ct = strchr(parser->content_type, ';');
+ ct = strchr(parser->enctype, ';');
if (ct == NULL) {
return APR_EINIT;
}
@@ -776,23 +751,19 @@
ctx->hdr_parser = apreq_make_parser(pool, "", apreq_parse_headers,
NULL,NULL);
ctx->info = NULL;
-
- if (ctx->bb == NULL)
- ctx->bb = apr_brigade_create(pool, bb->bucket_alloc);
+ ctx->bb = apr_brigade_create(pool, bb->bucket_alloc);
ctx->status = MFD_INIT;
parser->ctx = ctx;
}
- SANITY_CHECK;
-
mfd_parse_brigade:
switch (ctx->status) {
case MFD_INIT:
{
- s = split_on_bdry(pool, ctx->bb, bb, NULL, ctx->bdry + 2);
+ s = split_on_bdry(ctx->bb, bb, NULL, ctx->bdry + 2);
if (s != APR_SUCCESS) {
return s;
}
@@ -803,7 +774,7 @@
case MFD_NEXTLINE:
{
apr_status_t s;
- s = split_on_bdry(pool, ctx->bb, bb, NULL, CRLF);
+ s = split_on_bdry(ctx->bb, bb, NULL, CRLF);
if (s != APR_SUCCESS) {
return s;
}
@@ -822,7 +793,7 @@
if (ctx->info == NULL)
ctx->info = apr_table_make(pool, APREQ_NELTS);
- s = apreq_run_parser(ctx->hdr_parser, cfg, ctx->info, bb);
+ s = apreq_run_parser(ctx->hdr_parser, env, ctx->info, bb);
if (s != APR_SUCCESS)
return (s == APR_EOF) ? APR_SUCCESS : s;
@@ -866,7 +837,7 @@
case MFD_PARAM:
{
- apr_status_t s = split_on_bdry(pool, ctx->bb, bb,
+ apr_status_t s = split_on_bdry(ctx->bb, bb,
ctx->pattern, ctx->bdry);
apr_bucket *e;
apreq_param_t *param;
@@ -916,7 +887,7 @@
case MFD_UPLOAD:
{
- apr_status_t s = split_on_bdry(pool, ctx->bb, bb,
+ apr_status_t s = split_on_bdry(ctx->bb, bb,
ctx->pattern, ctx->bdry);
apreq_param_t *param;
const apr_array_header_t *arr;
@@ -930,11 +901,11 @@
case APR_INCOMPLETE:
if (parser->hook) {
- s = apreq_run_hook(parser->hook, pool, cfg, ctx->bb);
+ s = apreq_run_hook(parser->hook, env, param, ctx->bb);
if (s != APR_INCOMPLETE && s != APR_SUCCESS)
return s;
}
- s = apreq_brigade_concat(pool, cfg, param->bb, ctx->bb);
+ s = apreq_brigade_concat(env, param->bb, ctx->bb);
return (s == APR_SUCCESS) ? APR_INCOMPLETE : s;
case APR_SUCCESS:
@@ -942,13 +913,13 @@
apr_bucket *eos =
apr_bucket_eos_create(ctx->bb->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(ctx->bb, eos);
- s = apreq_run_hook(parser->hook, pool, cfg, ctx->bb);
+ s = apreq_run_hook(parser->hook, env, param, ctx->bb);
apr_bucket_delete(eos);
if (s != APR_SUCCESS)
return s;
}
- param->v.status = apreq_brigade_concat(pool, cfg,
+ param->v.status = apreq_brigade_concat(env,
param->bb, ctx->bb);
if (param->v.status != APR_SUCCESS)
1.8 +1 -1 httpd-apreq-2/src/apreq_version.h
Index: apreq_version.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_version.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- apreq_version.h 28 Feb 2004 07:48:14 -0000 1.7
+++ apreq_version.h 24 Mar 2004 08:22:48 -0000 1.8
@@ -60,7 +60,7 @@
#define APREQ_MINOR_VERSION 0
/** patch level */
-#define APREQ_PATCH_VERSION 4
+#define APREQ_PATCH_VERSION 5
/**
* This symbol is defined for internal, "development" copies of libapreq.
1.10 +0 -2 httpd-apreq-2/t/parsers.c
Index: parsers.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/t/parsers.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- parsers.c 28 Feb 2004 07:48:15 -0000 1.9
+++ parsers.c 24 Mar 2004 08:22:48 -0000 1.10
@@ -19,7 +19,6 @@
#include "apreq.h"
#include "apreq_params.h"
#include "apr_strings.h"
-#include "apreq_parsers.h"
#define CRLF "\015\012"
@@ -38,7 +37,6 @@
extern apr_bucket_brigade *bb;
extern apr_table_t *table;
-extern apreq_cfg_t *config;
static void parse_urlencoded(CuTest *tc)
{
1.12 +44 -1 httpd-apreq-2/t/testall.c
Index: testall.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/t/testall.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- testall.c 28 Feb 2004 07:48:15 -0000 1.11
+++ testall.c 24 Mar 2004 08:22:48 -0000 1.12
@@ -54,7 +54,7 @@
/* rigged environent for unit tests */
#define APREQ_MODULE_NAME "TEST"
-#define APREQ_MODULE_MAGIC_NUMBER 20031025
+#define APREQ_MODULE_MAGIC_NUMBER 20040324
#define CRLF "\015\012"
@@ -106,6 +106,49 @@
{
return APR_ENOTIMPL;
}
+
+static const char *test_temp_dir(void *env, const char *path)
+{
+ static const char *temp_dir;
+ if (path != NULL) {
+ const char *rv = temp_dir;
+ temp_dir = apr_pstrdup(p, path);
+ return rv;
+ }
+ if (temp_dir == NULL) {
+ if (apr_temp_dir_get(&temp_dir, p) != APR_SUCCESS)
+ temp_dir = NULL;
+ }
+
+ return temp_dir;
+}
+
+
+static apr_off_t test_max_body(void *env, apr_off_t bytes)
+{
+ static apr_off_t max_body = -1;
+ if (bytes >= 0) {
+ apr_off_t rv = max_body;
+ max_body = bytes;
+ return rv;
+ }
+ return max_body;
+}
+
+
+static apr_ssize_t test_max_brigade(void *env, apr_ssize_t bytes)
+{
+ static apr_ssize_t max_brigade = -1;
+
+ if (bytes >= 0) {
+ apr_ssize_t rv = max_brigade;
+ max_brigade = bytes;
+ return rv;
+ }
+ return max_brigade;
+}
+
+
static APREQ_ENV_MODULE(test, APREQ_MODULE_NAME,
APREQ_MODULE_MAGIC_NUMBER);