joes 2003/05/05 19:11:37
Modified: build README
env libapreq_cgi.c mod_apreq.c
glue/perl/t request.t
src apreq.c apreq.h apreq_cookie.c apreq_cookie.h
apreq_env.h apreq_params.c apreq_params.h
apreq_parsers.c apreq_parsers.h apreq_tables.c
apreq_tables.h
t env.c parsers.c performance.c
Log:
Major improvements to the apreq_parser API and mod_apreq filter.
Structural changes to the core:
APREQ_ENV is gone.
struct apreq_hook_t added (similar API to httpd's filter stack),
struct apreq_parser_t simplified,
struct apreq_request_t modified to hold config data (as in libapreq-1).
"passive-aggressive" parsing code added to apreq_param() (similar
to libapreq-1, but slightly less agressive :-).
Feature additions to mod_apreq.c:
Filter supports prefetch reads.
Filter should DTRT for subrequests & internal redirects.
Also cleaned up libapreq_cgi.c a little bit.
Revision Changes Path
1.3 +8 -3 httpd-apreq-2/build/README
Index: README
===================================================================
RCS file: /home/cvs/httpd-apreq-2/build/README,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- README 3 May 2003 05:22:33 -0000 1.2
+++ README 6 May 2003 02:11:35 -0000 1.3
@@ -4,9 +4,11 @@
-UPDATING THE httpd-apreq SITE:
+UPDATING THE httpd-apreq WEBSITE:
+ (cf: http://jakarta.apache.org/site/jakarta-site2.html )
-RedHat Linux:
+
+RedHat Linux Instructions:
1) Download and install j2re and j2sdk rpms from Sun's
website:
@@ -32,4 +34,7 @@
$ ant
$ cvs commit -m "..." xdocs/apreq/ docs/apreq/
- 5) Wait 24 hours for the changes to appear on the website.
+ 5) Login (via ssh) to httpd.apache.org and do
+
+ $ cd /www/httpd.apache.org
+ $ cvs update index.html apreq/
1.3 +52 -50 httpd-apreq-2/env/libapreq_cgi.c
Index: libapreq_cgi.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/env/libapreq_cgi.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- libapreq_cgi.c 17 Apr 2003 19:19:39 -0000 1.2
+++ libapreq_cgi.c 6 May 2003 02:11:35 -0000 1.3
@@ -61,7 +61,7 @@
#include <stdlib.h>
#include <stdio.h>
-#define dENV struct env_ctx *env = (struct env_ctx *)ctx
+#define dCTX struct env_ctx *ctx = (struct env_ctx *)env
/* the "warehouse" */
struct env_ctx {
@@ -69,87 +69,89 @@
apreq_request_t *req;
apreq_jar_t *jar;
apr_bucket_brigade *bb;
+ int loglevel;
};
-static const char env_name[] = "CGI";
+const char apreq_env[] = "CGI";
+
#define CRLF "\015\012"
-static apr_pool_t *env_pool(void *ctx)
+
+APREQ_DECLARE(apr_pool_t *)apreq_env_pool(void *env)
{
- dENV;
- return env->pool;
+ dCTX;
+ return ctx->pool;
}
-static const char *env_in(void *ctx, const char *name)
+APREQ_DECLARE(const char *)apreq_env_args(void *env)
+{
+ return getenv("QUERY_STRING");
+}
+APREQ_DECLARE(const char *)apreq_env_header_in(void *env,
+ const char *name)
{
- return getenv(name);
+ dCTX;
+ char *key = apr_pstrdup(ctx->pool, name);
+ char *k;
+ for (k = key; *k; ++k) {
+ if (*k == '-')
+ *k = '_';
+ else
+ *k = apr_toupper(k);
+ }
+
+
+ return getenv(key);
}
-static apr_status_t env_out(void *ctx, const char *name, char *value)
+APREQ_DECLARE(apr_status_t)apreq_env_header_out(void *ctx, const char *name,
+ char *value)
{
return printf("%s: %s" CRLF, name, value) > 0 ? APR_SUCCESS :
APR_EGENERAL;
}
-static const char *env_args(void *ctx)
-{
- return getenv("QUERY_STRING");
-}
-static void *env_jar(void *ctx, void *jar)
+APREQ_DECLARE(apreq_jar_t *) apreq_env_jar(void *env, apreq_jar_t *jar)
{
- dENV;
+ dCTX;
if (jar != NULL) {
- apreq_jar_t *old_jar = env->jar;
- env->jar = jar;
+ apreq_jar_t *old_jar = ctx->jar;
+ ctx->jar = jar;
return old_jar;
}
- return env->jar;
+ return ctx->jar;
}
-static void *env_request(void *ctx, void *req)
+APREQ_DECLARE(apreq_request_t *)apreq_env_request(void *env,
+ apreq_request_t *req)
{
- dENV;
+ dCTX;
if (req != NULL) {
- apreq_request_t *old_req = env->req;
- env->req = req;
+ apreq_request_t *old_req = ctx->req;
+ ctx->req = req;
return old_req;
}
- return env->req;
-}
-
-static apreq_cfg_t *env_cfg(void *ctx)
-{
- /* XXX: not implemented */
- return NULL;
-}
-
-
-static int dump_table(void *ctx, const char *key, const char *value)
-{
- dENV;
- dAPREQ_LOG;
- apreq_log(APREQ_DEBUG 0, env, "%s => %s", key, value);
- return 1;
+ return ctx->req;
}
-APREQ_LOG(env_log)
+APREQ_DECLARE_LOG(env_log)
{
+ dCTX;
+ va_list vp;
+ if (level < ctx->loglevel)
+ return;
+ va_start(vp, fmt);
+ fprintf(stderr, "[%s(%d)] %s\n", file, line,
+ apr_pvsprintf(ctx->pool,fmt,vp));
+ va_end(vp);
}
-const struct apreq_env APREQ_ENV =
+APREQ_DECLARE(apr_status_t) apreq_env_read(void *env, apr_read_type_e block,
+ apr_off_t bytes)
{
- env_name,
- env_pool,
- env_in,
- env_out,
- env_args,
- env_jar,
- env_request,
- env_cfg,
- env_log
- };
-
+ return APR_ENOTIMPL;
+}
1.12 +164 -134 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.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- mod_apreq.c 3 May 2003 05:22:33 -0000 1.11
+++ mod_apreq.c 6 May 2003 02:11:35 -0000 1.12
@@ -66,127 +66,166 @@
#include "apreq_parsers.h"
#include "apreq_cookie.h"
-#define dR request_rec *r = (request_rec *)ctx
+#define dR request_rec *r = (request_rec *)env
-/* the "warehouse" */
+/* the "warehouse"
+ * The parser body is attached to the filter-selected parser.
+ *
+ * request & jar are in r->request_config;
+ * parser config data inside parser_t
+ * (may need to be merged with server/request cfg)
+ *
+ */
-struct env_ctx {
- apreq_request_t *req;
+struct env_config {
apreq_jar_t *jar;
+ apreq_request_t *req;
+ ap_filter_t *f;
+};
+
+struct filter_ctx {
apr_bucket_brigade *bb_in;
- apr_bucket_brigade *bb_parse;
+ apr_bucket_brigade *bb_out;
+ apr_status_t status;
};
-static const char env_name[] = "APACHE2";
-static const char filter_name[] = "APREQ";
+const char apreq_env[] = "APACHE2";
+static const char filter_name[] = "APREQ";
module AP_MODULE_DECLARE_DATA apreq_module;
-static apr_pool_t *env_pool(void *ctx)
+APREQ_DECLARE_LOG(apreq_log)
{
dR;
- return r->pool;
+ va_list args;
+ va_start(args,fmt);
+ ap_log_rerror(file, line, level, status, r, "%s",
+ apr_pvsprintf(r->pool, fmt, args));
+ va_end(args);
}
-static const char *env_in(void *ctx, const char *name)
+
+APREQ_DECLARE(const char*)apreq_env_args(void *env)
{
dR;
- return apr_table_get(r->headers_in, name);
+ return r->args;
}
-static apr_status_t env_out(void *ctx, const char *name, char *value)
+APREQ_DECLARE(apr_pool_t *)apreq_env_pool(void *env)
{
dR;
- apr_table_addn(r->headers_out, name, value);
- return APR_SUCCESS;
+ return r->pool;
}
-static const char *env_args(void *ctx)
+APREQ_DECLARE(const char *)apreq_env_header_in(void *env, const char *name)
{
dR;
- return r->args;
+ return apr_table_get(r->headers_in, name);
}
-static APR_INLINE struct env_ctx *apreq_note(request_rec *r)
+APREQ_DECLARE(apr_status_t)apreq_env_header_out(void *env, const char *name,
+ char *value)
{
- struct env_ctx *ctx = (struct env_ctx *)
- apr_table_get(r->notes, filter_name);
+ dR;
+ apr_table_addn(r->headers_out, name, value);
+ return APR_SUCCESS;
+}
+
- if (ctx == NULL) {
- ctx = apr_palloc(r->pool, sizeof *ctx);
- ctx->req = NULL;
- ctx->jar = NULL;
- ctx->bb_in = ctx->bb_parse = NULL;
- apr_table_addn(r->notes, filter_name, (char *)ctx);
+APR_INLINE
+static struct env_config *get_cfg(request_rec *r)
+{
+ struct env_config *cfg =
+ ap_get_module_config(r->request_config, &apreq_module);
+ if (cfg == NULL) {
+ cfg = apr_pcalloc(r->pool, sizeof *cfg);
+ ap_set_module_config(r->request_config, &apreq_module, cfg);
}
- return ctx;
+ return cfg;
}
-static void *env_jar(void *ctx, void *jar)
+APREQ_DECLARE(apreq_jar_t *) apreq_env_jar(void *env, apreq_jar_t *jar)
{
dR;
- struct env_ctx *c = apreq_note(r);
-
+ struct env_config *c = get_cfg(r);
if (jar != NULL) {
- apreq_jar_t *oldjar = c->jar;
- c->jar = (apreq_jar_t *)jar;
- return oldjar;
- }
+ apreq_jar_t *old = c->jar;
+ c->jar = jar;
+ return old;
+ }
return c->jar;
}
+static ap_filter_t *get_apreq_filter(request_rec *r)
+{
+ struct env_config *cfg = get_cfg(r);
+ if (cfg->f != NULL)
+ return cfg->f;
-static void *env_request(void *ctx, void *req)
+ for (cfg->f = r->input_filters;
+ cfg->f != NULL && cfg->f->frec->ftype == AP_FTYPE_CONTENT_SET;
+ cfg->f = cfg->f->next)
+ {
+ if (strcmp(cfg->f->frec->name, filter_name) == 0)
+ return cfg->f;
+ }
+ return cfg->f = ap_add_input_filter(filter_name, NULL, r, r->connection);
+}
+
+APREQ_DECLARE(apreq_request_t *) apreq_env_request(void *env,
+ apreq_request_t *req)
{
dR;
- struct env_ctx *c = apreq_note(r);
+ struct env_config *c = get_cfg(r);
+ if (c->f == NULL)
+ get_apreq_filter(r);
if (req != NULL) {
- apreq_request_t *oldreq = c->req;
-
- /* XXX: this needs to be subrequest-friendly */
- if (oldreq == NULL) {
- dAPREQ_LOG;
- ap_filter_rec_t *f = ap_get_input_filter_handle(filter_name);
- if (r->main) {
- struct env_ctx *n = apreq_note(r->main);
- oldreq = n->req;
- }
-
-
- apreq_log(APREQ_DEBUG 0, r, "Adding APREQ filter to input
chain");
- /* XXX: SOMEHOW INJECT APREQ INPUT FILTER */
- ap_add_input_filter_handle(f, NULL, r, r->connection);
-
- }
-
- c->req = (apreq_request_t *)req;
- return oldreq;
+ apreq_request_t *old = c->req;
+ c->req = req;
+ return old;
}
return c->req;
}
-static apreq_cfg_t *env_cfg(void *ctx)
+APREQ_DECLARE(apr_status_t) apreq_env_read(void *env,
+ apr_read_type_e block,
+ apr_off_t bytes)
{
- /* XXX: not implemented */
- return NULL;
-}
-
+ dR;
+ ap_filter_t *f = get_apreq_filter(r);
+ if (f == NULL)
+ return APR_NOTFOUND;
-static int dump_table(void *ctx, const char *key, const char *value)
-{
- request_rec *r = ctx;
- ap_rprintf(r, "\t%s => %s\n", key, value);
- return 1;
+ return ap_get_brigade(f, NULL, AP_MODE_SPECULATIVE, block, bytes);
}
-static apr_status_t env_read(void *ctx, apr_bucket_brigade **bb,
- apr_read_type_e block, apr_off_t readbytes)
+static int apreq_filter_init(ap_filter_t *f)
{
- dR;
- /* XXX: prefetch */
- return APR_ENOTIMPL;
+ request_rec *r = f->r;
+ apr_bucket_alloc_t *alloc = apr_bucket_alloc_create(r->pool);
+ struct env_config *cfg = get_cfg(r);
+ struct filter_ctx *ctx;
+
+ if (f->ctx) {
+ apreq_log(APREQ_ERROR 500, r, "apreq filter is already
initialized!");
+ return 500; /* filter already initialized */
+ }
+ ctx = apr_palloc(r->pool, sizeof *ctx);
+ f->ctx = ctx;
+ ctx->bb_in = apr_brigade_create(r->pool, alloc);
+ ctx->bb_out = apr_brigade_create(r->pool, alloc);
+ ctx->status = APR_INCOMPLETE;
+
+ if (cfg->req == NULL)
+ cfg->req = apreq_request(r, r->args);
+
+ if (cfg->req->body == NULL)
+ cfg->req->body = apreq_table_make(r->pool, APREQ_NELTS);
+
+ apreq_log(APREQ_DEBUG 0, r, "filter initialized successfully");
+ return 0;
}
static apr_status_t apreq_filter(ap_filter_t *f,
@@ -196,78 +235,83 @@
apr_off_t readbytes)
{
request_rec *r = f->r;
- struct env_ctx *ctx;
+ struct apreq_request_t *req = apreq_request(r, NULL);
+ struct filter_ctx *ctx;
apr_status_t rv;
- dAPREQ_LOG;
+ apr_bucket *e;
+ int saw_eos = 0;
- /* just get out of the way of things we don't want. */
- if (mode != AP_MODE_READBYTES) {
- return ap_get_brigade(f->next, bb, mode, block, readbytes);
- }
+ if (f->ctx == NULL)
+ apreq_filter_init(f);
- if (f->ctx == NULL) {
- ctx = apreq_note(r);
- f->ctx = ctx;
- if (ctx->bb_in == NULL)
- ctx->bb_in = apr_brigade_create(r->pool, f->c->bucket_alloc);
- if (ctx->bb_parse == NULL)
- ctx->bb_parse = apr_brigade_create(r->pool, f->c->bucket_alloc);
- if (ctx->req == NULL) {
- ctx->req = apreq_request(r, r->args);
- }
- apreq_log(APREQ_DEBUG 0, r, "filter initialized");
- }
- else
- ctx = (struct env_ctx *)f->ctx;
-
- /* XXX configure filter & parser here */
-
-
- rv = ap_get_brigade(f->next, ctx->bb_in, AP_MODE_READBYTES,
- block, readbytes);
+ ctx = f->ctx;
+ switch (mode) {
- if (ctx->req->v.status == APR_INCOMPLETE) {
- int saw_eos = 0;
+ case AP_MODE_SPECULATIVE:
+ if (bb != NULL) { /* not a prefetch read */
+ if (APR_BRIGADE_EMPTY(ctx->bb_out))
+ return ap_get_brigade(f->next, bb, mode, block, readbytes);
- while (! APR_BRIGADE_EMPTY(ctx->bb_in)) {
- apr_bucket *e, *f = APR_BRIGADE_FIRST(ctx->bb_in);
- apr_bucket_copy(f, &e);
- apr_bucket_setaside(e, r->pool);
-
- APR_BUCKET_REMOVE(f);
- APR_BRIGADE_INSERT_TAIL(ctx->bb_parse, e);
- APR_BRIGADE_INSERT_TAIL(bb, f);
-
- if (APR_BUCKET_IS_EOS(e)) {
- saw_eos = 1;
- break;
+ APR_BRIGADE_FOREACH(e,ctx->bb_out) {
+ apr_bucket *b;
+ apr_bucket_copy(e,&b);
+ APR_BRIGADE_INSERT_TAIL(bb,b);
}
}
+ mode = AP_MODE_READBYTES;
+ bb = ctx->bb_out;
+ break;
+
+ case AP_MODE_EXHAUSTIVE:
+ case AP_MODE_READBYTES:
+ APR_BRIGADE_CONCAT(bb, ctx->bb_out);
+ break;
+
+ case AP_MODE_EATCRLF:
+ case AP_MODE_GETLINE:
+ if (!APR_BRIGADE_EMPTY(ctx->bb_out))
+ return APR_ENOTIMPL;
- apreq_log(APREQ_DEBUG 0, r, "filter parsing");
- rv = apreq_parse(ctx->req, ctx->bb_parse);
-
- if (rv == APR_INCOMPLETE && saw_eos == 1)
- return APR_EGENERAL; /* parser choked on EOS bucket */
+ default:
+ return ap_get_brigade(f->next, bb, mode, block, readbytes);
}
- else {
- APR_BRIGADE_CONCAT(bb, ctx->bb_in);
+ e = APR_BRIGADE_LAST(bb);
+ rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
+ if (rv != APR_SUCCESS || ctx->status != APR_INCOMPLETE)
+ return rv;
+
+ e = APR_BUCKET_NEXT(e);
+
+ for ( ;e != APR_BRIGADE_SENTINEL(bb); e = APR_BUCKET_NEXT(e)) {
+ apr_bucket *b;
+ apr_bucket_copy(e, &b);
+ apr_bucket_setaside(b, r->pool);
+ APR_BRIGADE_INSERT_TAIL(ctx->bb_in, b);
+
+ if (APR_BUCKET_IS_EOS(e)) {
+ saw_eos = 1;
+ break;
+ }
}
- apreq_log(APREQ_DEBUG 0, r, "filter returned(%d)", rv);
+ ctx->status = apreq_parse_request(req, ctx->bb_in);
+
+ if (ctx->status == APR_INCOMPLETE && saw_eos == 1)
+ ctx->status = APR_EOF; /* parser choked on EOS bucket */
+
+ apreq_log(APREQ_DEBUG rv, r, "filter parser returned(%d)", ctx->status);
return rv;
}
static void register_hooks (apr_pool_t *p)
{
- ap_register_input_filter(filter_name, apreq_filter, NULL,
+ ap_register_input_filter(filter_name, apreq_filter, apreq_filter_init,
AP_FTYPE_CONTENT_SET);
}
-
module AP_MODULE_DECLARE_DATA apreq_module =
{
STANDARD20_MODULE_STUFF,
@@ -278,17 +322,3 @@
NULL,
register_hooks, /* callback for registering hooks */
};
-
-const struct apreq_env APREQ_ENV =
-{
- env_name,
- env_pool,
- env_in,
- env_out,
- env_args,
- env_jar,
- env_request,
- env_cfg,
- (APREQ_LOG(*))ap_log_rerror
- };
-
1.2 +3 -3 httpd-apreq-2/glue/perl/t/request.t
Index: request.t
===================================================================
RCS file: /home/cvs/httpd-apreq-2/glue/perl/t/request.t,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- request.t 25 Apr 2003 03:17:48 -0000 1.1
+++ request.t 6 May 2003 02:11:35 -0000 1.2
@@ -9,10 +9,10 @@
my $location = '/apreq_test';
-ok t_cmp("ARGS:\n\ttest => 1\n",
+ok t_cmp("ARGS:\n\ttest => 1\nBODY:\n",
GET_BODY("$location?test=1"), "simple get query");
-
ok t_cmp("ARGS:\n\ttest => 2\nBODY:\n\tHTTPUPLOAD => b\n",
- $_ = UPLOAD_BODY("$location?test=2", content => "unused"),
+ UPLOAD_BODY("$location?test=2", content => "unused"),
"simple upload");
+
1.17 +21 -0 httpd-apreq-2/src/apreq.c
Index: apreq.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- apreq.c 23 Apr 2003 22:57:55 -0000 1.16
+++ apreq.c 6 May 2003 02:11:36 -0000 1.17
@@ -53,6 +53,7 @@
*/
#include "apreq.h"
+#include "apreq_env.h"
#include "apr_time.h"
#include "apr_strings.h"
#include "apr_lib.h"
@@ -108,6 +109,26 @@
if (arr->nelts > 0)
v->name = a->name;
return v;
+}
+
+APR_INLINE
+APREQ_DECLARE(const char *)apreq_enctype(void *env)
+{
+ char *enctype;
+ const char *ct = apreq_env_content_type(env), *semicolon;
+
+ if (ct == NULL)
+ return NULL;
+ else {
+ semicolon = strchr(ct, ';');
+ if (semicolon) {
+ enctype = apr_pstrdup(apreq_env_pool(env), ct);
+ enctype[semicolon - ct] = 0;
+ return enctype;
+ }
+ else
+ return ct;
+ }
}
APREQ_DECLARE(char *) apreq_expires(apr_pool_t *p, const char *time_str,
1.17 +3 -0 httpd-apreq-2/src/apreq.h
Index: apreq.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- apreq.h 4 May 2003 20:45:25 -0000 1.16
+++ apreq.h 6 May 2003 02:11:36 -0000 1.17
@@ -60,6 +60,9 @@
const apr_array_header_t *arr);
+APR_INLINE
+APREQ_DECLARE(const char *)apreq_enctype(void *env);
+
typedef enum { AS_IS, ENCODE, DECODE, QUOTE } apreq_join_t;
APREQ_DECLARE(const char *) apreq_join(apr_pool_t *p,
1.12 +26 -27 httpd-apreq-2/src/apreq_cookie.c
Index: apreq_cookie.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_cookie.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- apreq_cookie.c 21 Apr 2003 19:40:11 -0000 1.11
+++ apreq_cookie.c 6 May 2003 02:11:36 -0000 1.12
@@ -98,10 +98,10 @@
1 -> not found, keep going. */
}
-APREQ_DECLARE(apreq_cookie_version_t) apreq_ua_cookie_version(void *ctx)
+APREQ_DECLARE(apreq_cookie_version_t) apreq_ua_cookie_version(void *env)
{
- if (apreq_env_cookie2(ctx) == NULL) {
- apreq_jar_t *j = apreq_jar(ctx, NULL);
+ if (apreq_env_cookie2(env) == NULL) {
+ apreq_jar_t *j = apreq_jar(env, NULL);
if (j == NULL || apreq_jar_nelts(j) == 0)
return APREQ_COOKIE_VERSION;
@@ -273,10 +273,10 @@
return APR_SUCCESS;
}
-APREQ_DECLARE(apreq_jar_t *) apreq_jar(void *ctx,
+APREQ_DECLARE(apreq_jar_t *) apreq_jar(void *env,
const char *data)
{
- apr_pool_t *p = apreq_env_pool(ctx);
+ apr_pool_t *p = apreq_env_pool(env);
apreq_cookie_version_t version;
apreq_jar_t *j = NULL;
@@ -293,22 +293,21 @@
if (data == NULL) {
/* use the environment's cookie data */
- /* fetch ctx->jar (cached jar) */
- j = apreq_env_jar(ctx, NULL);
+ j = apreq_env_jar(env, NULL);
if ( j != NULL )
return j;
j = apr_palloc(p, sizeof *j);
j->pool = p;
- j->env = ctx;
+ j->env = env;
j->cookies = apreq_table_make(p, APREQ_NELTS);
- data = apreq_env_cookie(ctx);
+ data = apreq_env_cookie(env);
/* XXX: potential race condition here
between env_jar fetch and env_jar set. */
- apreq_env_jar(ctx,j); /* set (cache) ctx->jar */
+ apreq_env_jar(env,j);
if (data == NULL)
return j;
@@ -316,13 +315,13 @@
else {
j = apr_palloc(p, sizeof *j);
j->pool = p;
- j->env = ctx;
+ j->env = env;
j->cookies = apreq_table_make(p, APREQ_NELTS);
}
origin = data;
- apreq_log(APREQ_DEBUG 0, ctx, "parsing cookie data: %s", data);
+ apreq_log(APREQ_DEBUG 0, env, "parsing cookie data: %s", data);
/* parse data */
@@ -360,14 +359,14 @@
case '$':
if (c == NULL) {
- apreq_log(APREQ_ERROR APR_BADCH, ctx,
+ apreq_log(APREQ_ERROR APR_BADCH, env,
"Saw attribute, expecting NAME=VALUE cookie pair: %s",
data);
return j;
}
else if (version == NETSCAPE) {
c->v.status = APR_EMISMATCH;
- apreq_log(APREQ_ERROR c->v.status, ctx,
+ apreq_log(APREQ_ERROR c->v.status, env,
"Saw attribute in a Netscape Cookie header: %s",
data);
return j;
@@ -380,7 +379,7 @@
apr_pstrmemdup(p,value, vlen));
else {
c->v.status = status;
- apreq_log(APREQ_WARN c->v.status, ctx,
+ apreq_log(APREQ_WARN c->v.status, env,
"Ignoring bad attribute pair: %s", data);
}
break;
@@ -391,12 +390,12 @@
if (status == APR_SUCCESS) {
c = apreq_make_cookie(p, version, name, nlen,
value, vlen);
- apreq_log(APREQ_DEBUG status, ctx,
+ apreq_log(APREQ_DEBUG status, env,
"adding cookie: %s => %s", c->v.name, c->v.data);
apreq_add_cookie(j, c);
}
else {
- apreq_log(APREQ_WARN status, ctx,
+ apreq_log(APREQ_WARN status, env,
"Skipping bad NAME=VALUE pair: %s", data);
}
}
@@ -476,7 +475,7 @@
{
char s[APREQ_COOKIE_LENGTH];
- int n = apreq_serialize_cookie(s, APREQ_COOKIE_LENGTH,c);
+ int n = apreq_serialize_cookie(s, APREQ_COOKIE_LENGTH, c);
if ( n < APREQ_COOKIE_LENGTH )
return apr_pstrmemdup(p, s, n);
@@ -485,40 +484,40 @@
}
APREQ_DECLARE(apr_status_t) apreq_bake_cookie(const apreq_cookie_t *c,
- void *ctx)
+ void *env)
{
- char *s = apreq_cookie_as_string(apreq_env_pool(ctx),c);
+ char *s = apreq_cookie_as_string(apreq_env_pool(env),c);
dAPREQ_LOG;
if (s == NULL) {
- apreq_log(APREQ_ERROR APR_ENAMETOOLONG, ctx,
+ apreq_log(APREQ_ERROR APR_ENAMETOOLONG, env,
"Serialized cookie exceeds APREQ_COOKIE_LENGTH = %d",
APREQ_COOKIE_LENGTH);
return APR_ENAMETOOLONG;
}
- return apreq_env_set_cookie(ctx, s);
+ return apreq_env_set_cookie(env, s);
}
APREQ_DECLARE(apr_status_t) apreq_bake2_cookie(const apreq_cookie_t *c,
- void *ctx)
+ void *env)
{
- char *s = apreq_cookie_as_string(apreq_env_pool(ctx),c);
+ char *s = apreq_cookie_as_string(apreq_env_pool(env),c);
dAPREQ_LOG;
if ( s == NULL ) {
- apreq_log(APREQ_ERROR APR_ENAMETOOLONG, ctx,
+ apreq_log(APREQ_ERROR APR_ENAMETOOLONG, env,
"Serialized cookie exceeds APREQ_COOKIE_LENGTH = %d",
APREQ_COOKIE_LENGTH);
return APR_ENAMETOOLONG;
}
else if ( c->version == NETSCAPE ) {
- apreq_log(APREQ_ERROR APR_EMISMATCH, ctx,
+ apreq_log(APREQ_ERROR APR_EMISMATCH, env,
"Cannot bake2 a Netscape cookie: %s", s);
return APR_EMISMATCH;
}
- return apreq_env_set_cookie2(ctx, s);
+ return apreq_env_set_cookie2(env, s);
}
1.11 +5 -5 httpd-apreq-2/src/apreq_cookie.h
Index: apreq_cookie.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_cookie.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- apreq_cookie.h 21 Apr 2003 19:40:11 -0000 1.10
+++ apreq_cookie.h 6 May 2003 02:11:36 -0000 1.11
@@ -81,7 +81,7 @@
/**
* Parse the incoming "Cookie:" headers into a cookie jar.
*
- * @param ctx The current context.
+ * @param env The current environment.
* @param data String to parse as a HTTP-merged "Cookie" header.
* @remark "data = NULL" has special semantics. In this case,
* apreq_jar_parse will attempt to fetch a cached jar from the
@@ -94,7 +94,7 @@
*/
-APREQ_DECLARE(apreq_jar_t *) apreq_jar(void *ctx, const char *data);
+APREQ_DECLARE(apreq_jar_t *) apreq_jar(void *env, const char *data);
/**
* Returns a new cookie, made from the argument list.
@@ -159,7 +159,7 @@
* @param c The cookie.
*/
APREQ_DECLARE(apr_status_t) apreq_bake_cookie(const apreq_cookie_t *c,
- void *ctx);
+ void *env);
/* XXX: how about baking whole cookie jars, too ??? */
@@ -169,9 +169,9 @@
* @param c The cookie.
*/
APREQ_DECLARE(apr_status_t) apreq_bake2_cookie(const apreq_cookie_t *c,
- void *ctx);
+ void *env);
-APREQ_DECLARE(apreq_cookie_version_t) apreq_ua_cookie_version(void *ctx);
+APREQ_DECLARE(apreq_cookie_version_t) apreq_ua_cookie_version(void *env);
#ifdef __cplusplus
1.12 +33 -41 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.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- apreq_env.h 23 Apr 2003 17:24:12 -0000 1.11
+++ apreq_env.h 6 May 2003 02:11:36 -0000 1.12
@@ -1,11 +1,9 @@
#ifndef APREQ_ENV_H
#define APREQ_ENV_H
-#include "apreq.h"
-
-#ifdef __cplusplus
- extern "C" {
-#endif
+#include "apreq_params.h"
+#include "apreq_cookie.h"
+#include "apreq_parsers.h"
#ifdef HAVE_SYSLOG
#include <syslog.h>
@@ -14,6 +12,11 @@
#define LOG_PRIMASK 7
#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
#define APREQ_LOG_EMERG LOG_EMERG /* system is unusable */
#define APREQ_LOG_ALERT LOG_ALERT /* action must be taken
immediately */
#define APREQ_LOG_CRIT LOG_CRIT /* critical conditions */
@@ -46,56 +49,45 @@
#define APREQ_WARN APREQ_LOG_MARK, APREQ_LOG_WARNING,
#define APREQ_ERROR APREQ_LOG_MARK, APREQ_LOG_ERR,
-#define dAPREQ_LOG APREQ_LOG(*apreq_log) = APREQ_ENV.log
+#define dAPREQ_LOG /* APREQ_LOG(*apreq_log) = APREQ_ENV.log */
+
+extern const char apreq_env[];
+
+#define APREQ_DECLARE_LOG(f) APREQ_DECLARE_NONSTD(void)(f)(const char *file,
\
+ int line, int level, apr_status_t status, \
+ void *env, const char *fmt, ...)
-typedef struct apreq_cfg_t {
- apr_off_t max_len;
- char *temp_dir;
- int disable_uploads;
-} apreq_cfg_t;
-#define APREQ_LOG(f) void (f)(const char *file, int line, int level, \
- apr_status_t status, void *ctx, const char *fmt, ...)
+APREQ_DECLARE_LOG(apreq_log);
+APREQ_DECLARE(apr_pool_t *) apreq_env_pool(void *env);
-extern const struct apreq_env {
- const char *name;
- apr_pool_t *(*pool)(void *ctx);
- /* header access */
- const char *(*in)(void *ctx, const char *name);
- apr_status_t (*out)(void *ctx, const char *name, char *value);
+APREQ_DECLARE(apreq_jar_t *) apreq_env_jar(void *env, apreq_jar_t *jar);
+APREQ_DECLARE(apreq_request_t *) apreq_env_request(void *env,
+ apreq_request_t *req);
- /* raw (unparsed) query_string access */
- const char *(*args)(void *ctx);
- /* (get/set) cached core objects */
- void *(*jar)(void *ctx, void *jar);
- void *(*request)(void *ctx, void *req);
+APREQ_DECLARE(const char *) apreq_env_args(void *env);
+APREQ_DECLARE(const char *) apreq_env_header_in(void *env, const char *name);
- /* environment configuration */
- apreq_cfg_t *(*config)(void *ctx);
- /* core logging function */
- APREQ_LOG (*log);
+#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")
-} APREQ_ENV;
-#define apreq_env_name() APREQ_ENV.name
-#define apreq_env_pool(c) APREQ_ENV.pool(c)
+APREQ_DECLARE(apr_status_t)apreq_env_header_out(void *env,
+ const char *name,
+ char *val);
-#define apreq_env_jar(c,j) APREQ_ENV.jar(c,j)
-#define apreq_env_request(c,r) APREQ_ENV.request(c,r)
+#define apreq_env_set_cookie(e,s) apreq_env_header_out(e,"Set-Cookie",s)
+#define apreq_env_set_cookie2(e,s) apreq_env_header_out(e,"Set-Cookie2",s)
-#define apreq_env_config(c) APREQ_ENV.config(c)
-#define apreq_env_content_type(c) APREQ_ENV.in(c, "Content-Type")
-#define apreq_env_cookie(c) APREQ_ENV.in(c, "Cookie")
-#define apreq_env_cookie2(c) APREQ_ENV.in(c, "Cookie2")
-#define apreq_env_set_cookie(c,s) APREQ_ENV.out(c,"Set-Cookie",s)
-#define apreq_env_set_cookie2(c,s) APREQ_ENV.out(c,"Set-Cookie2",s)
-#define apreq_env_args(c) APREQ_ENV.args(c)
-#define apreq_env_get_brigade(c,bb) APREQ_ENV.get_brigade(c,bb)
+APREQ_DECLARE(apr_status_t) apreq_env_read(void *env,
+ apr_read_type_e block,
+ apr_off_t bytes);
#ifdef __cplusplus
1.15 +51 -60 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.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- apreq_params.c 23 Apr 2003 20:42:50 -0000 1.14
+++ apreq_params.c 6 May 2003 02:11:36 -0000 1.15
@@ -89,88 +89,52 @@
return param;
}
-APR_INLINE
-static const char * enctype(apr_pool_t *p, const char *ct)
-{
- char *enctype, *semicolon;
- if (ct == NULL)
- enctype = NULL;
- else {
- enctype = apr_pstrdup(p, ct);
- semicolon = strchr(enctype, ';');
- if (semicolon)
- *semicolon = 0;
- }
- return enctype;
-}
-
-APREQ_DECLARE(apreq_request_t *) apreq_request(void *ctx, const char *args)
+APREQ_DECLARE(apreq_request_t *) apreq_request(void *env, const char *args)
{
apreq_request_t *req;
- apreq_parser_t *parser;
+ apr_pool_t *p;
apr_status_t s;
if (args == NULL) {
- apreq_request_t *old_req = apreq_env_request(ctx,NULL);
- apr_pool_t *p;
-
+ apreq_request_t *old_req = apreq_env_request(env,NULL);
if (old_req != NULL)
return old_req;
- p = apreq_env_pool(ctx);
- args = apreq_env_args(ctx);
+ p = apreq_env_pool(env);
+ args = apreq_env_args(env);
- req = apr_palloc(p, sizeof(apreq_table_t *) + sizeof *req);
- req->pool = apreq_env_pool(ctx);
- *(apreq_table_t **)req->v.data = apreq_make_table(p, APREQ_NELTS);
- req->v.size = sizeof(apreq_table_t *);
- req->v.status = APR_EINIT;
- req->env = ctx;
+ req = apr_palloc(p, sizeof *req);
+ req->env = env;
req->args = apreq_make_table(p, APREQ_NELTS);
+ req->cfg = NULL;
req->body = NULL;
- req->v.name = enctype(p, apreq_env_content_type(ctx));
+ req->parser = apreq_parser(env, NULL);
+
/* XXX need to install copy/merge callbacks for apreq_param_t */
- parser = apreq_make_parser(p, APREQ_URL_ENCTYPE,
- apreq_parse_urlencoded, NULL, req);
- apreq_register_parser(req, parser);
- parser = apreq_make_parser(p, APREQ_MFD_ENCTYPE,
- apreq_parse_multipart, NULL, req);
- apreq_register_parser(req, parser);
/* XXX get/set race condition here wrt apreq_env_request? */
- old_req = apreq_env_request(ctx, req);
+ old_req = apreq_env_request(env, req);
+
if (old_req != NULL) {
- apreq_env_request(ctx, old_req); /* reset old_req */
+ apreq_env_request(env, old_req); /* reset old_req */
return old_req;
}
}
else {
- apr_pool_t *p = apreq_env_pool(ctx);
+ p = apreq_env_pool(env);
- req = apr_palloc(p, sizeof(apreq_table_t *) + sizeof *req);
- req->pool = apreq_env_pool(ctx);
- *(apreq_table_t **)req->v.data = apreq_make_table(p, APREQ_NELTS);
- req->v.size = sizeof(apreq_table_t *);
- req->v.status = APR_EINIT;
- req->env = ctx;
+ req = apr_palloc(p, sizeof *req);
+ req->env = env;
req->args = apreq_make_table(p, APREQ_NELTS);
+ req->cfg = NULL;
req->body = NULL;
- req->v.name = enctype(p, apreq_env_content_type(ctx));
+ req->parser = apreq_parser(env, NULL);
/* XXX need to install copy/merge callbacks for apreq_param_t */
- parser = apreq_make_parser(p, APREQ_URL_ENCTYPE,
- apreq_parse_urlencoded, NULL, req);
- apreq_register_parser(req, parser);
- parser = apreq_make_parser(p, APREQ_MFD_ENCTYPE,
- apreq_parse_multipart, NULL, req);
- apreq_register_parser(req, parser);
}
s = (args == NULL) ? APR_SUCCESS :
- apreq_split_params(req->pool, req->args, args);
-
- if (s == APR_SUCCESS)
- req->v.status = (req->v.name ? APR_INCOMPLETE : APR_SUCCESS);
+ apreq_split_params(p, req->args, args);
return req;
}
@@ -179,12 +143,23 @@
APREQ_DECLARE(apreq_param_t *)apreq_param(const apreq_request_t *req,
const char *name)
{
- const char *arg = apreq_table_get(req->args, name);
+ const char *val = apreq_table_get(req->args, name);
- if (arg)
- return UPGRADE(arg);
- else
- return req->body ? UPGRADE(apreq_table_get(req->body, name)) : NULL;
+ if (val)
+ return UPGRADE(val);
+ else if (req->body == NULL)
+ return NULL;
+
+ val = apreq_table_get(req->body, name);
+ if (val == NULL) {
+ apreq_cfg_t *cfg = req->cfg;
+
+ if (cfg && cfg->read_bytes) {
+ apreq_env_read(req->env, APR_NONBLOCK_READ, cfg->read_bytes);
+ val = apreq_table_get(req->body, name);
+ }
+ }
+ return val ? UPGRADE(val) : NULL;
}
@@ -303,4 +278,20 @@
v->size += apreq_encode(v->data + v->size, param->v.data, param->v.size);
return v->data;
+}
+
+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)
+ return APR_EINIT;
+
+ if (req->body == NULL)
+ req->body = apreq_table_make(apreq_env_pool(req->env),APREQ_NELTS);
+
+ return apreq_run_parser(req->parser, req->cfg, req->body, bb);
}
1.12 +9 -5 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.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- apreq_params.h 21 Apr 2003 20:16:24 -0000 1.11
+++ apreq_params.h 6 May 2003 02:11:36 -0000 1.12
@@ -60,6 +60,7 @@
#define APREQ_PARAM_H
#include "apreq_tables.h"
+#include "apreq_parsers.h"
#include "apr_buckets.h"
#ifdef __cplusplus
@@ -99,18 +100,18 @@
typedef struct apreq_request_t {
apreq_table_t *args; /* query_string params */
apreq_table_t *body;
-
- apr_pool_t *pool;
+ apreq_parser_t *parser;
+ apreq_cfg_t *cfg;
void *env;
- apreq_value_t v;
} apreq_request_t;
/**
* Creates an apreq_request_t object.
- * @param ctx The current request context.
+ * @param env The current request environment.
+ * @param args Local query string.
*/
-APREQ_DECLARE(apreq_request_t *)apreq_request(void *ctx, const char *args);
+APREQ_DECLARE(apreq_request_t *)apreq_request(void *env, const char *args);
/**
@@ -164,6 +165,9 @@
APREQ_DECLARE(char *) apreq_encode_param(apr_pool_t *pool,
const apreq_param_t *param);
+
+APREQ_DECLARE(apr_status_t)apreq_parse_request(apreq_request_t *req,
+ apr_bucket_brigade *bb);
#ifdef __cplusplus
}
1.22 +151 -138 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.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- apreq_parsers.c 24 Apr 2003 21:19:12 -0000 1.21
+++ apreq_parsers.c 6 May 2003 02:11:36 -0000 1.22
@@ -57,6 +57,7 @@
*/
#include "apreq_parsers.h"
+#include "apreq_params.h"
#include "apreq_env.h"
#include "apr_lib.h"
#include "apr_strings.h"
@@ -75,83 +76,80 @@
APREQ_DECLARE(apreq_parser_t *) apreq_make_parser(apr_pool_t *pool,
- const char *enctype,
- APREQ_PARSER(*parser),
- APREQ_HOOK(*hook),
- void *out)
+ const char *type,
+
APREQ_DECLARE_PARSER(*parser),
+ apreq_hook_t *hook)
{
apreq_parser_t *p = apr_palloc(pool, APREQ_CTX_MAXSIZE + sizeof *p);
-
- p->v.name = apr_pstrdup(pool, enctype);
- p->v.size = 0;
- p->v.status = APR_SUCCESS;
-
+ p->type = apr_pstrdup(pool,type);
p->parser = parser;
p->hook = hook;
- p->out = out;
+
return p;
}
-
-
-APREQ_DECLARE(apr_status_t) apreq_register_parser(apreq_request_t *req,
- apreq_parser_t *parser)
+APREQ_DECLARE(apreq_hook_t *) apreq_make_hook(apr_pool_t *pool,
+ APREQ_DECLARE_HOOK(*hook),
+ apreq_hook_t *next,
+ void *ctx)
{
- if (req->body == NULL)
- return apreq_table_add(*(apreq_table_t **)req->v.data, &parser->v);
- else
- return APR_EGENERAL;
+ apreq_hook_t *h = apr_palloc(pool, sizeof *h);
+ h->hook = hook;
+ h->next = next;
+ h->ctx = ctx;
+ return h;
}
-APREQ_DECLARE(apr_status_t) apreq_parse(apreq_request_t *req,
- apr_bucket_brigade *bb)
+APREQ_DECLARE(apr_status_t)apreq_add_hook(apreq_parser_t *p,
+ apreq_hook_t *h)
{
- dAPREQ_LOG;
+ apreq_hook_t *last = h;
- if (req->v.name == NULL) {
- if (req->v.status == APR_SUCCESS)
- return APR_SUCCESS;
- else
- return req->v.status = APR_EINIT;
- }
+ if (p == NULL || h == NULL)
+ return APR_EINIT;
- if (req->body == NULL) {
- const char *q = apreq_table_get(*(apreq_table_t **)req->v.data,
- req->v.name);
- if (q == NULL) {
- apreq_log(APREQ_DEBUG APR_NOTFOUND, req->env,
- "can't find %s parser", req->v.name);
- return req->v.status = APR_NOTFOUND;
- }
- req->body = apreq_table_make(req->pool, APREQ_NELTS);
+ while (last->next)
+ last = last->next;
- apreq_log(APREQ_DEBUG APR_SUCCESS, req->env,
- "found %s parser", req->v.name);
+ last->next = p->hook;
+ p->hook = h;
+ return APR_SUCCESS;
+}
- *(apreq_parser_t **)req->v.data =
- apreq_value_to_parser(apreq_strtoval(q));
+APREQ_DECLARE(apreq_parser_t *)apreq_parser(void *env,
+ APREQ_DECLARE_HOOK(*hook))
+{
+ apr_pool_t *pool = apreq_env_pool(env);
+ apreq_hook_t *h = NULL;
+ const char *type = apreq_env_content_type(env);
- req->v.size = sizeof(apreq_parser_t *);
- req->v.status = APR_INCOMPLETE;
- }
+ if (type == NULL)
+ return NULL;
- if (req->v.status == APR_INCOMPLETE) {
- apreq_parser_t *p = *(apreq_parser_t **)req->v.data;
- req->v.status = p->parser(req->pool, bb, p);
- }
+ if (hook)
+ h = apreq_make_hook(pool,hook,NULL,NULL);
+
+ if (!strncasecmp(type, APREQ_URL_ENCTYPE,strlen(APREQ_URL_ENCTYPE)))
+ return apreq_make_parser(pool, type, apreq_parse_urlencoded, h);
+
+ else if (!strncasecmp(type,APREQ_MFD_ENCTYPE,strlen(APREQ_MFD_ENCTYPE)))
+ return apreq_make_parser(pool, type, apreq_parse_multipart, h);
+
+ else
+ return NULL;
- return req->v.status;
}
/******************** application/x-www-form-urlencoded ********************/
-static apr_status_t split_urlword(apr_pool_t *pool, apreq_table_t *t,
+static apr_status_t split_urlword(apreq_table_t *t,
apr_bucket_brigade *bb,
const apr_size_t nlen,
const apr_size_t vlen)
{
+ apr_pool_t *pool = apreq_table_pool(t);
apreq_param_t *param = apr_palloc(pool, nlen + vlen + 1 + sizeof *param);
apr_size_t total, off;
apreq_value_t *v = ¶m->v;
@@ -229,30 +227,33 @@
v->data[off] = 0;
v->size = off;
- v->status = APR_SUCCESS;
- return apreq_table_add(t, v);
-
+ apreq_table_add(t, v);
+ return v->status = APR_SUCCESS;
}
+struct url_ctx {
+ apr_status_t status;
+};
-APREQ_DECLARE(apr_status_t) apreq_parse_urlencoded(apr_pool_t *pool,
- apr_bucket_brigade *bb,
- apreq_parser_t *parser)
-{
- apreq_request_t *req = (apreq_request_t *)parser->out;
- apreq_table_t *t = req->body;
- dAPREQ_LOG;
+APREQ_DECLARE_PARSER(apreq_parse_urlencoded)
+{
+ apr_pool_t *pool = apreq_table_pool(t);
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;
parse_url_brigade:
- parser->v.status = URL_NAME;
+ ctx->status = URL_NAME;
for (e = APR_BRIGADE_FIRST(bb), nlen = vlen = 0;
e != APR_BRIGADE_SENTINEL(bb);
@@ -263,8 +264,8 @@
apr_status_t s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ);
if (APR_BUCKET_IS_EOS(e)) {
- return parser->v.status == URL_NAME ? APR_SUCCESS :
- split_urlword(pool, t, bb, nlen+1, vlen);
+ return (ctx->status == URL_NAME) ? APR_SUCCESS :
+ split_urlword(t, bb, nlen+1, vlen);
}
if ( s != APR_SUCCESS )
return s;
@@ -272,15 +273,13 @@
parse_url_bucket:
- switch (parser->v.status) {
-
+ switch (ctx->status) {
case URL_NAME:
-
while (off < dlen) {
switch (data[off++]) {
case '=':
- parser->v.status = URL_VALUE;
+ ctx->status = URL_VALUE;
goto parse_url_bucket;
default:
++nlen;
@@ -288,14 +287,12 @@
}
break;
-
case URL_VALUE:
-
while (off < dlen) {
switch (data[off++]) {
case '&':
case ';':
- s = split_urlword(pool, t, bb, nlen+1, vlen+1);
+ s = split_urlword(t, bb, nlen+1, vlen+1);
if (s != APR_SUCCESS)
return s;
goto parse_url_brigade;
@@ -400,18 +397,21 @@
v->data[v->size] = 0;
- return apreq_table_add(t, v);
+ apreq_table_add(t, v);
+ return APR_SUCCESS;
}
+struct hdr_ctx {
+ apr_status_t status;
+};
-APREQ_DECLARE(apr_status_t) apreq_parse_headers(apr_pool_t *pool,
- apr_bucket_brigade *bb,
- apreq_parser_t *parser)
+APREQ_DECLARE_PARSER(apreq_parse_headers)
{
- apreq_table_t *t = (apreq_table_t *) parser->out;
+ apr_pool_t *pool = apreq_table_pool(t);
apr_ssize_t nlen, glen, vlen;
apr_bucket *e;
+ struct hdr_ctx *ctx;
/* use parser->v.status to maintain state */
#define HDR_NAME 0
@@ -420,13 +420,17 @@
#define HDR_NEWLINE 3
#define HDR_CONTINUE 4
+ if (parser->ctx == NULL)
+ parser->ctx = apr_pcalloc(pool, sizeof *ctx);
+
+ ctx = parser->ctx;
parse_hdr_brigade:
/* parse the brigade for CRLF_CRLF-terminated header block,
* each time starting from the front of the brigade.
*/
- parser->v.status = HDR_NAME;
+ ctx->status = HDR_NAME;
for (e = APR_BRIGADE_FIRST(bb), nlen = glen = vlen = 0;
e != APR_BRIGADE_SENTINEL(bb); e = APR_BUCKET_NEXT(e))
@@ -435,7 +439,7 @@
const char *data;
apr_status_t s;
if (APR_BUCKET_IS_EOS(e))
- return parser->v.status = APR_EOF;
+ return ctx->status = APR_EOF;
s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ);
@@ -454,7 +458,7 @@
* name value
*/
- switch (parser->v.status) {
+ switch (ctx->status) {
case HDR_NAME:
@@ -477,7 +481,7 @@
case ':':
++glen;
- parser->v.status = HDR_GAP;
+ ctx->status = HDR_GAP;
goto parse_hdr_bucket;
default:
@@ -499,11 +503,11 @@
break;
case '\n':
- parser->v.status = HDR_NEWLINE;
+ ctx->status = HDR_NEWLINE;
goto parse_hdr_bucket;
default:
- parser->v.status = HDR_VALUE;
+ ctx->status = HDR_VALUE;
++vlen;
goto parse_hdr_bucket;
}
@@ -516,7 +520,7 @@
while (off < dlen) {
++vlen;
if (data[off++] == '\n') {
- parser->v.status = HDR_NEWLINE;
+ ctx->status = HDR_NEWLINE;
goto parse_hdr_bucket;
}
}
@@ -532,7 +536,7 @@
case ' ':
case '\t':
- parser->v.status = HDR_CONTINUE;
+ ctx->status = HDR_CONTINUE;
++off;
vlen += 2;
break;
@@ -562,11 +566,11 @@
break;
case '\n':
- parser->v.status = HDR_NEWLINE;
+ ctx->status = HDR_NEWLINE;
goto parse_hdr_bucket;
default:
- parser->v.status = HDR_VALUE;
+ ctx->status = HDR_VALUE;
++vlen;
goto parse_hdr_bucket;
}
@@ -585,10 +589,12 @@
struct mfd_ctx {
void *hook_data;
- apreq_parser_t *hdr_parser;
+ apreq_table_t *info;
apr_bucket_brigade *bb;
+ apreq_parser_t *hdr_parser;
const apr_strmatch_pattern *pattern;
- char bdry[1];
+ char *bdry;
+ apr_status_t status;
};
@@ -752,14 +758,10 @@
}
-APREQ_DECLARE(apr_status_t) apreq_parse_multipart(apr_pool_t *pool,
- apr_bucket_brigade *bb,
- apreq_parser_t *parser)
+APREQ_DECLARE_PARSER(apreq_parse_multipart)
{
- apreq_request_t *req = (apreq_request_t *)parser->out;
- struct mfd_ctx *ctx = (struct mfd_ctx *) apreq_parser_ctx(parser);
-
-#define MAX_BLEN 80
+ apr_pool_t *pool = apreq_table_pool(t);
+ struct mfd_ctx *ctx = parser->ctx;
#define MFD_INIT 0
#define MFD_NEXTLINE 1
@@ -768,47 +770,55 @@
#define MFD_UPLOAD 4
#define MFD_ERROR -1
- if (parser->v.size == 0) {
- const char *bdry, *ct;
+ if (parser->ctx == NULL) {
+ char *ct;
apr_size_t blen;
apr_status_t s;
- ct = apreq_env_content_type(req->env);
- memcpy(ctx->bdry, CRLF "--", 4);
+ ctx = apr_pcalloc(pool, sizeof *ctx);
- s = nextval(&ct, "boundary", &bdry, &blen);
+ ct = strchr(parser->type, ';');
+ if (ct == NULL) {
+ return APR_EINIT;
+ }
+ *ct++ = 0;
- if (s != APR_SUCCESS)
+ s = nextval((const char **)&ct, "boundary",
+ (const char **)&ctx->bdry, &blen);
+ if (s != APR_SUCCESS) {
return s;
+ }
+ *--ctx->bdry = '-';
+ *--ctx->bdry = '-';
+ *--ctx->bdry = '\n';
+ *--ctx->bdry = '\r';
- if (blen > MAX_BLEN)
- return APR_ENAMETOOLONG;
-
- memcpy(ctx->bdry + 4, bdry, blen);
ctx->bdry[4 + blen] = 0;
ctx->pattern = apr_strmatch_precompile(pool,ctx->bdry,1);
- ctx->hdr_parser = apreq_make_parser(pool,"",NULL,NULL,NULL);
+ ctx->hdr_parser =
apreq_make_parser(pool,"",apreq_parse_headers,NULL);
+ ctx->info = NULL;
if (ctx->bb == NULL)
ctx->bb = apr_brigade_create(pool, bb->bucket_alloc);
- parser->v.status = MFD_INIT;
- parser->v.size = sizeof *ctx;
+ ctx->status = MFD_INIT;
+ parser->ctx = ctx;
}
mfd_parse_brigade:
- switch (parser->v.status) {
+ switch (ctx->status) {
case MFD_INIT:
{
apr_status_t s;
s = split_on_bdry(pool, ctx->bb, bb, NULL, ctx->bdry + 2);
- if (s != APR_SUCCESS)
+ if (s != APR_SUCCESS) {
+ printf("mfd init: split_on_bdry failed: %d\n",s);
return s;
-
- parser->v.status = MFD_NEXTLINE;
+ }
+ ctx->status = MFD_NEXTLINE;
}
/* fall through */
@@ -816,12 +826,13 @@
{
apr_status_t s;
s = split_on_bdry(pool, ctx->bb, bb, NULL, CRLF);
- if (s != APR_SUCCESS)
+ if (s != APR_SUCCESS) {
+ printf("split_on_bdry failed: '%s'\n", CRLF);
return s;
-
- parser->v.status = MFD_HEADER;
+ }
+ ctx->status = MFD_HEADER;
apr_brigade_cleanup(ctx->bb);
- ctx->hdr_parser->out = NULL;
+ ctx->info = NULL;
}
/* fall through */
@@ -830,30 +841,30 @@
apr_status_t s;
const char *cd, *name, *filename;
apr_size_t nlen, flen;
- apreq_table_t *t;
- if (ctx->hdr_parser->out == NULL)
- ctx->hdr_parser->out = apreq_make_table(pool, APREQ_NELTS);
+ if (ctx->info == NULL)
+ ctx->info = apreq_make_table(pool, APREQ_NELTS);
- s = apreq_parse_headers(pool, bb, ctx->hdr_parser);
+ s = apreq_run_parser(ctx->hdr_parser, cfg, ctx->info, bb);
if (s != APR_SUCCESS)
if (s == APR_EOF)
return APR_SUCCESS;
- else
+ else {
+ printf("header parser failed: %d\n", s);
return s;
-
- t = ctx->hdr_parser->out;
- cd = apreq_table_get(t, "Content-Disposition");
+ }
+ cd = apreq_table_get(ctx->info, "Content-Disposition");
if (cd == NULL) {
- parser->v.status = MFD_ERROR;
+ ctx->status = MFD_ERROR;
+ printf("Can't find Content-Disposition header.\n");
return APR_BADARG;
}
s = nextval(&cd, "name", &name, &nlen);
if (s != APR_SUCCESS) {
- parser->v.status = MFD_ERROR;
+ ctx->status = MFD_ERROR;
return APR_BADARG;
}
@@ -865,17 +876,17 @@
e = apr_bucket_transient_create(name, nlen,
ctx->bb->bucket_alloc);
APR_BRIGADE_INSERT_HEAD(ctx->bb,e);
- parser->v.status = MFD_PARAM;
+ ctx->status = MFD_PARAM;
}
else {
apreq_param_t *param = apreq_make_param(pool, name, nlen,
filename, flen);
- param->info = t;
+ param->info = ctx->info;
param->bb = apr_brigade_create(pool,
apr_bucket_alloc_create(pool));
- apreq_table_add(req->body, ¶m->v);
- parser->v.status = MFD_UPLOAD;
+ apreq_table_add(t, ¶m->v);
+ ctx->status = MFD_UPLOAD;
}
}
goto mfd_parse_brigade;
@@ -903,7 +914,7 @@
s = apr_brigade_length(ctx->bb, 1, &off);
if (s != APR_SUCCESS) {
- parser->v.status = MFD_ERROR;
+ ctx->status = MFD_ERROR;
return s;
}
len = off;
@@ -911,7 +922,7 @@
param->charset = APREQ_CHARSET;
param->language = NULL;
param->bb = NULL;
- param->info = ctx->hdr_parser->out;
+ param->info = ctx->info;
v = ¶m->v;
v->name = name;
@@ -919,12 +930,12 @@
apr_brigade_flatten(ctx->bb, v->data, &len);
v->size = len;
v->data[v->size] = 0;
- apreq_table_add(req->body, v);
- parser->v.status = MFD_NEXTLINE;
+ apreq_table_add(t, v);
+ ctx->status = MFD_NEXTLINE;
goto mfd_parse_brigade;
default:
- parser->v.status = MFD_ERROR;
+ ctx->status = MFD_ERROR;
return s;
}
@@ -940,7 +951,7 @@
apreq_param_t *param;
const apr_array_header_t *arr;
- arr = apreq_table_elts(req->body);
+ arr = apreq_table_elts(t);
param = apreq_value_to_param(*(apreq_value_t **)
(arr->elts + (arr->elt_size * (arr->nelts-1))));
@@ -948,7 +959,8 @@
case APR_INCOMPLETE:
if (parser->hook)
- return parser->hook(pool, param->bb, ctx->bb, parser);
+ return apreq_run_hook(parser->hook, pool, cfg,
+ param->bb, ctx->bb);
else {
APR_BRIGADE_CONCAT(param->bb, ctx->bb);
return s;
@@ -959,16 +971,17 @@
APR_BRIGADE_INSERT_TAIL(ctx->bb, eos);
if (parser->hook) {
- do s = parser->hook(pool, param->bb, ctx->bb, parser);
+ do s = apreq_run_hook(parser->hook, pool, cfg,
+ param->bb, ctx->bb);
while (s == APR_INCOMPLETE);
}
else
APR_BRIGADE_CONCAT(param->bb, ctx->bb);
- parser->v.status = MFD_NEXTLINE;
+ ctx->status = MFD_NEXTLINE;
goto mfd_parse_brigade;
default:
- parser->v.status = MFD_ERROR;
+ ctx->status = MFD_ERROR;
return s;
}
1.9 +48 -32 httpd-apreq-2/src/apreq_parsers.h
Index: apreq_parsers.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_parsers.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- apreq_parsers.h 18 Apr 2003 20:15:50 -0000 1.8
+++ apreq_parsers.h 6 May 2003 02:11:36 -0000 1.9
@@ -1,7 +1,7 @@
#ifndef APREQ_PARSERS_H
#define APREQ_PARSERS_H
-#include "apreq_params.h"
+#include "apreq_tables.h"
#include "apr_buckets.h"
#ifdef __cplusplus
@@ -14,21 +14,43 @@
* API: apreq_parsers.c
*/
-typedef struct apreq_parser_t apreq_parser_t;
-
-#define APREQ_PARSER(f) apr_status_t(f)(apr_pool_t *p, apr_bucket_brigade
*bb,\
- apreq_parser_t *parser)
-#define APREQ_HOOK(f) apr_status_t(f)(apr_pool_t *p, apr_bucket_brigade
*out, \
- apr_bucket_brigade *in, \
- apreq_parser_t *parser)
+typedef struct apreq_cfg_t {
+ char *temp_dir;
+ apr_off_t max_len;
+ int read_bytes;
+ int disable_uploads;
+} apreq_cfg_t;
+
+
+#define APREQ_DECLARE_PARSER(f) apr_status_t(f)(apreq_parser_t *parser, \
+ const apreq_cfg_t *cfg, \
+ apreq_table_t *t, \
+ apr_bucket_brigade *bb)
+
+#define APREQ_DECLARE_HOOK(f) apr_status_t(f)(apreq_hook_t *hook, \
+ apr_pool_t *pool, \
+ const apreq_cfg_t *cfg, \
+ apr_bucket_brigade *out, \
+ apr_bucket_brigade *in)
#define APREQ_CTX_MAXSIZE 128
+#define apreq_run_parser(psr,cfg,t,bb) psr->parser(psr,cfg,t,bb)
+#define apreq_run_hook(h,pool,cfg,out,in) h->hook(h,pool,cfg,out,in)
+
+typedef struct apreq_hook_t apreq_hook_t;
+typedef struct apreq_parser_t apreq_parser_t;
+
+struct apreq_hook_t {
+ APREQ_DECLARE_HOOK (*hook);
+ apreq_hook_t *next;
+ void *ctx;
+};
struct apreq_parser_t {
- APREQ_PARSER (*parser);
- APREQ_HOOK (*hook);
- void *out;
- apreq_value_t v; /* maintains (internal) parser state */
+ APREQ_DECLARE_PARSER (*parser);
+ const char *type;
+ apreq_hook_t *hook;
+ void *ctx;
};
@@ -38,27 +60,22 @@
#define apreq_parser_enctype(p) ((p)->v.name)
#define apreq_parser_ctx(p) ((p)->v.data)
-APREQ_DECLARE(apr_status_t) apreq_parse_headers(apr_pool_t *p,
- apr_bucket_brigade *bb,
- apreq_parser_t *parser);
-
-APREQ_DECLARE(apr_status_t) apreq_parse_urlencoded(apr_pool_t *pool,
- apr_bucket_brigade *bb,
- apreq_parser_t *parser);
-
-APREQ_DECLARE(apr_status_t) apreq_parse_multipart(apr_pool_t *pool,
- apr_bucket_brigade *bb,
- apreq_parser_t *parser);
-
+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_PARSER(*parser),
- APREQ_HOOK(*hook),
- void *out);
+
APREQ_DECLARE_PARSER(*parser),
+ apreq_hook_t *hook);
-APREQ_DECLARE(apr_status_t) apreq_register_parser(apreq_request_t *req,
- apreq_parser_t *parser);
+APREQ_DECLARE(apr_status_t)apreq_add_hook(apreq_parser_t *p,
+ apreq_hook_t *h);
+
+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_copy_parser(apr_pool_t *p,
const apreq_value_t *v);
@@ -66,9 +83,8 @@
APREQ_DECLARE(apr_status_t) apreq_merge_parsers(apr_pool_t *p,
const apr_array_header_t *a);
-APREQ_DECLARE(apr_status_t)apreq_parse(apreq_request_t *req,
- apr_bucket_brigade *bb);
-
+APREQ_DECLARE(apreq_parser_t *)apreq_parser(void *env,
+ APREQ_DECLARE_HOOK(*hook));
#ifdef __cplusplus
}
1.29 +22 -76 httpd-apreq-2/src/apreq_tables.c
Index: apreq_tables.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_tables.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- apreq_tables.c 3 May 2003 05:22:33 -0000 1.28
+++ apreq_tables.c 6 May 2003 02:11:36 -0000 1.29
@@ -219,20 +219,19 @@
static int search(const apreq_table_entry_t *const o,int *elt,
const char *key)
{
- register int idx = *elt;
- register CS_TYPE csum;
+ int idx = *elt;
+ CS_TYPE csum;
COMPUTE_KEY_CHECKSUM(key, csum);
while (1) {
- const int direction = (csum > idx[o].checksum) ? 1 :
- (csum < idx[o].checksum) ? -1 :
- strcasecmp(key,idx[o].key);
-
+ const int direction = (csum > idx[o].checksum) ? 1:
+ (csum < idx[o].checksum) ? -1 :
+ strcasecmp(key,idx[o].key);
if (direction < 0 && idx[o].tree[LEFT] >= 0)
- idx = idx[o].tree[LEFT];
+ idx = idx[o].tree[LEFT];
else if (direction > 0 && idx[o].tree[RIGHT] >= 0)
- idx = idx[o].tree[RIGHT];
+ idx = idx[o].tree[RIGHT];
else {
*elt = idx;
return direction;
@@ -452,60 +451,6 @@
x[o].color = BLACK;
}
-/*
- * Recursive function that combines two trees by root-inserting
- * the elements of the second (b) into the first (a). Note that
- * elements of the second tree must also be reindexed since their
- * origin is n entries away from a's origin (o).
- *
- */
-static int combine(apreq_table_entry_t *o, int a, int b, const int n)
-{
- int left, right, next;
-
- if (b < 0)
- return a;
-
- b += n;
-
- left = b[o].tree[LEFT];
- right = b[o].tree[RIGHT];
-
- for(next = b; next[o].tree[NEXT] >= 0; next = next[o].tree[NEXT])
- next[o].tree[NEXT] += n;
-
- if (a >= 0) {
- int rv = a;
- int parent = a[o].tree[UP];
-
- if (parent >= 0) {
- parent[o].tree[LR(a)] = b;
- a[o].tree[UP] = -1;
- }
-
- if (insert(o,&a,a,b+o) < 0) /* b is a new element for a's tree */
- rv = b;
-
- if (b[o].tree[UP] >= 0)
- PROMOTE(&a,b);
-
- b[o].tree[UP] = parent;
- b[o].tree[LEFT] = combine(o, b[o].tree[LEFT], left, n);
- b[o].tree[RIGHT] = combine(o, b[o].tree[RIGHT], right, n);
-
- return rv;
- }
- else {
- if (b[o].tree[UP] >= 0)
- b[o].tree[UP] += n;
- b[o].tree[LEFT] = combine(o, -1, left, n);
- b[o].tree[RIGHT] = combine(o, -1, right, n);
-
- return b;
- }
-
-}
-
/*****************************************************************
*
@@ -585,7 +530,7 @@
const apreq_table_t *t)
{
int idx;
- apreq_table_entry_t *o = (apreq_table_entry_t *)t->a.elts;
+ apreq_table_entry_t *const o = (apreq_table_entry_t *)t->a.elts;
apr_table_t *s = apr_table_make(p, t->a.nalloc);
for (idx = 0; idx < t->a.nelts; ++idx) {
@@ -643,6 +588,12 @@
}
APR_INLINE
+APREQ_DECLARE(apr_pool_t *) apreq_table_pool(apreq_table_t *t)
+{
+ return t->a.pool;
+}
+
+APR_INLINE
APREQ_DECLARE(apreq_value_copy_t *)apreq_table_copier(apreq_table_t *t,
apreq_value_copy_t *c)
{
@@ -669,7 +620,7 @@
{
apr_status_t status = APR_SUCCESS;
int idx;
- apreq_table_entry_t *o = (apreq_table_entry_t *)t->a.elts;
+ apreq_table_entry_t *const o = (apreq_table_entry_t *)t->a.elts;
apreq_value_t *a[APREQ_NELTS];
apr_array_header_t arr = { t->a.pool, sizeof(apreq_value_t *), 0,
APREQ_NELTS, (char *)a };
@@ -716,7 +667,7 @@
static int bury_table_entries(apreq_table_t *t, apr_array_header_t *q)
{
- apreq_table_entry_t *o = (apreq_table_entry_t *)t->a.elts;
+ apreq_table_entry_t *const o = (apreq_table_entry_t *)t->a.elts;
int j, m, rv=0, *p = (int *)q->elts;
register int n;
@@ -755,7 +706,7 @@
APREQ_DECLARE(int) apreq_table_exorcise(apreq_table_t *t)
{
- apreq_table_entry_t *o = (apreq_table_entry_t *)t->a.elts;
+ apreq_table_entry_t *const o = (apreq_table_entry_t *)t->a.elts;
int idx;
int a[APREQ_NELTS];
apr_array_header_t arr = { t->a.pool, sizeof(int), 0,
@@ -797,7 +748,7 @@
apr_array_header_t *keys)
{
int idx;
- apreq_table_entry_t *o = (apreq_table_entry_t *)t->a.elts;
+ apreq_table_entry_t *const o = (apreq_table_entry_t *)t->a.elts;
if (t->a.nelts == t->ghosts)
return APR_NOTFOUND;
@@ -933,6 +884,7 @@
const int n = t->a.nelts;
int idx;
apreq_table_entry_t *o;
+
if (t->ghosts == n) {
t->a.nelts = 0;
t->ghosts = s->ghosts;
@@ -968,13 +920,7 @@
insert(o, &t->root[hash], t->root[hash], idx+o);
}
}
-/*
- else {
- for (idx = 0; idx < TABLE_HASH_SIZE; ++idx)
- t->root[idx] = combine(o,t->root[idx],s->root[idx],n);
- }
-}
-*/
+
APREQ_DECLARE(apreq_table_t *) apreq_table_overlay(apr_pool_t *p,
const apreq_table_t *overlay,
@@ -1163,7 +1109,7 @@
idx = t->root[TABLE_HASH(*argp)];
if ( idx >= 0 && search(o,&idx,argp) == 0 )
while (idx >= 0) {
- rv = (*comp) (rec, idx[o].key, idx[o].val->data);
+ rv = (*comp) (rec, idx[o].val->name, idx[o].val->data);
idx = idx[o].tree[NEXT];
}
}
@@ -1171,7 +1117,7 @@
for (idx = 0; rv && (idx < t->a.nelts); ++idx)
/* if (idx[o].key) */
if (! DEAD(idx) )
- rv = (*comp) (rec, idx[o].key, idx[o].val->data);
+ rv = (*comp) (rec, idx[o].val->name, idx[o].val->data);
}
if (rv == 0) {
vdorv = 0;
1.17 +8 -0 httpd-apreq-2/src/apreq_tables.h
Index: apreq_tables.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_tables.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- apreq_tables.h 3 May 2003 05:22:33 -0000 1.16
+++ apreq_tables.h 6 May 2003 02:11:36 -0000 1.17
@@ -143,6 +143,14 @@
APREQ_DECLARE(int) apreq_table_nelts(const apreq_table_t *t);
#define apreq_table_is_empty(t) ( apreq_table_nelts(t) == 0 )
+/**
+ * Returns the pool associated to the table's underlying array.
+ * @param t The table.
+ */
+
+APR_INLINE
+APREQ_DECLARE(apr_pool_t *) apreq_table_pool(apreq_table_t *t);
+
/**
* Get/set method for the table's value copier.
1.7 +17 -34 httpd-apreq-2/t/env.c
Index: env.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/t/env.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- env.c 24 Apr 2003 20:17:17 -0000 1.6
+++ env.c 6 May 2003 02:11:37 -0000 1.7
@@ -68,74 +68,57 @@
static const char env_name[] = "CGI";
#define CRLF "\015\012"
-static apr_pool_t *env_pool(void *ctx)
+apr_bucket_brigade *bb;
+apreq_table_t *table;
+
+APREQ_DECLARE(apr_pool_t *)apreq_env_pool(void *env)
{
return p;
}
-static const char *env_in(void *ctx, const char *name)
+APREQ_DECLARE(const char *)apreq_env_header_in(void *env, const char *name)
{
- return ctx;
+ return env;
}
-static apr_status_t env_out(void *ctx, const char *name, char *value)
+APREQ_DECLARE(apr_status_t)apreq_env_header_out(void *env,
+ const char *name,
+ char *value)
{
return printf("%s: %s" CRLF, name, value) > 0 ? APR_SUCCESS :
APR_EGENERAL;
}
-static const char *env_args(void *ctx)
-{
- return NULL;
-}
-
-static void *env_jar(void *ctx, void *jar)
+APREQ_DECLARE(const char *)apreq_env_args(void *env)
{
return NULL;
}
-static void *env_request(void *ctx, void *req)
+APREQ_DECLARE(apreq_jar_t *)apreq_env_jar(void *env, apreq_jar_t *jar)
{
return NULL;
}
-static apreq_cfg_t *env_cfg(void *ctx)
+APREQ_DECLARE(apreq_request_t *)apreq_env_request(void *env,
+ apreq_request_t *req)
{
return NULL;
}
static int loglevel = 10;
-APREQ_LOG(env_log)
+APREQ_DECLARE_LOG(apreq_log)
{
va_list vp;
-
if (level < loglevel)
return;
va_start(vp, fmt);
fprintf(stderr, "[%s(%d)] %s\n", file, line, apr_pvsprintf(p,fmt,vp));
va_end(vp);
-
}
-
-static int dump_table(void *ctx, const char *key, const char *value)
+APREQ_DECLARE(apr_status_t) apreq_env_read(void *env, apr_read_type_e block,
+ apr_off_t bytes)
{
- dAPREQ_LOG;
- apreq_log(APREQ_DEBUG 0, ctx, "%s => %s", key, value);
- return 1;
+ return APR_ENOTIMPL;
}
-
-
-const struct apreq_env APREQ_ENV =
-{
- env_name,
- env_pool,
- env_in,
- env_out,
- env_args,
- env_jar,
- env_request,
- env_cfg,
- env_log
- };
1.3 +25 -22 httpd-apreq-2/t/parsers.c
Index: parsers.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/t/parsers.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- parsers.c 24 Apr 2003 21:19:12 -0000 1.2
+++ parsers.c 6 May 2003 02:11:37 -0000 1.3
@@ -74,15 +74,18 @@
"... contents of file1.txt ..." CRLF
"--AaB03x--" CRLF;
+extern apr_bucket_brigade *bb;
+extern apreq_table_t *table;
+extern apreq_cfg_t *config;
static void parse_urlencoded(CuTest *tc)
{
const char *val;
- apreq_request_t *r = apreq_request(APREQ_URL_ENCTYPE,"");
- apr_bucket_brigade *bb = apr_brigade_create(p,
- apr_bucket_alloc_create(p));
+ apreq_request_t *req = apreq_request(APREQ_URL_ENCTYPE,"");
+ apr_status_t rv;
+ CuAssertPtrNotNull(tc, req);
- CuAssertPtrNotNull(tc, r);
+ bb = apr_brigade_create(p, apr_bucket_alloc_create(p));
APR_BRIGADE_INSERT_HEAD(bb,
apr_bucket_immortal_create(url_data,strlen(url_data),
@@ -90,18 +93,17 @@
APR_BRIGADE_INSERT_TAIL(bb,
apr_bucket_eos_create(bb->bucket_alloc));
- CuAssertIntEquals(tc, APR_INCOMPLETE, r->v.status);
+ do rv = apreq_parse_request(req,bb);
+ while (rv == APR_INCOMPLETE);
- while (apreq_parse(r, bb) == APR_INCOMPLETE)
- ;
- CuAssertIntEquals(tc, APR_SUCCESS, r->v.status);
+ CuAssertIntEquals(tc, APR_SUCCESS, rv);
- val = apreq_table_get(r->body,"alpha");
+ val = apreq_table_get(req->body,"alpha");
CuAssertStrEquals(tc, "one", val);
- val = apreq_table_get(r->body,"beta");
+ val = apreq_table_get(req->body,"beta");
CuAssertStrEquals(tc, "two", val);
- val = apreq_table_get(r->body,"omega");
+ val = apreq_table_get(req->body,"omega");
CuAssertStrEquals(tc, "last", val);
}
@@ -111,12 +113,14 @@
const char *val;
apr_size_t dummy;
apreq_table_t *t;
- apreq_request_t *r = apreq_request(APREQ_MFD_ENCTYPE
+ apr_status_t rv;
+ apreq_request_t *req = apreq_request(APREQ_MFD_ENCTYPE
"; boundary=\"AaB03x\"" ,"");
apr_bucket_brigade *bb = apr_brigade_create(p,
apr_bucket_alloc_create(p));
- CuAssertPtrNotNull(tc, r);
+ CuAssertPtrNotNull(tc, req);
+ CuAssertStrEquals(tc, req->env, apreq_env_content_type(req->env));
APR_BRIGADE_INSERT_HEAD(bb,
apr_bucket_immortal_create(form_data,strlen(form_data),
@@ -124,21 +128,20 @@
APR_BRIGADE_INSERT_TAIL(bb,
apr_bucket_eos_create(bb->bucket_alloc));
- CuAssertIntEquals(tc, APR_INCOMPLETE, r->v.status);
-
- while (apreq_parse(r, bb) == APR_INCOMPLETE)
- ;
- CuAssertIntEquals(tc, APR_SUCCESS, r->v.status);
- CuAssertPtrNotNull(tc, r->body);
- CuAssertIntEquals(tc, 2, apreq_table_nelts(r->body));
+ do rv = apreq_parse_request(req,bb);
+ while (rv == APR_INCOMPLETE);
- val = apreq_table_get(r->body,"field1");
+ CuAssertIntEquals(tc, APR_SUCCESS, rv);
+ CuAssertPtrNotNull(tc, req->body);
+ CuAssertIntEquals(tc, 2, apreq_table_nelts(req->body));
+ return;
+ val = apreq_table_get(req->body,"field1");
CuAssertStrEquals(tc, "Joe owes =80100.", val);
t = apreq_value_to_param(apreq_strtoval(val))->info;
val = apreq_table_get(t, "content-transfer-encoding");
CuAssertStrEquals(tc,"quoted-printable", val);
- val = apreq_table_get(r->body, "pics");
+ val = apreq_table_get(req->body, "pics");
CuAssertStrEquals(tc, "file1.txt", val);
t = apreq_value_to_param(apreq_strtoval(val))->info;
bb = apreq_value_to_param(apreq_strtoval(val))->bb;
1.2 +26 -14 httpd-apreq-2/t/performance.c
Index: performance.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/t/performance.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- performance.c 3 May 2003 05:22:33 -0000 1.1
+++ performance.c 6 May 2003 02:11:37 -0000 1.2
@@ -73,6 +73,7 @@
static apreq_table_t *s = NULL;
static apreq_table_t *h = NULL;
+#define NELTS 16
#define LOOP 10000
#define FAIL(MSG) \
CuFail(tc, apr_psprintf(p, MSG ": APR = %.3f vs APREQ = %.3f
(microseconds)", \
@@ -160,15 +161,15 @@
apreq_delta = apr_time_now();
for (i=0; i<LOOP;++i) {
- apreq_table_t *t = init_apreq(APREQ_NELTS*2);
+ apreq_table_t *t = init_apreq(NELTS);
apreq_table_normalize(t);
}
apreq_delta = apr_time_now() - apreq_delta;
apr_delta = apr_time_now();
for (i=0; i<LOOP;++i) {
- apr_table_t *t = apr_table_make(p,APREQ_NELTS*2);
- apr_table_t *s = init_apr(APREQ_NELTS*2);
+ apr_table_t *t = apr_table_make(p,NELTS);
+ apr_table_t *s = init_apr(NELTS*2);
apr_table_overlap(t,s,APR_OVERLAP_TABLES_MERGE);
}
apr_delta = apr_time_now() - apr_delta;
@@ -201,8 +202,8 @@
static void perf_get_avg(CuTest *tc)
{
- apr_table_t *s = init_apr(APREQ_NELTS);
- apreq_table_t *t = init_apreq(APREQ_NELTS);
+ apr_table_t *s = init_apr(NELTS);
+ apreq_table_t *t = init_apreq(NELTS);
apr_time_t apr_delta, apreq_delta;
int j;
@@ -216,36 +217,47 @@
/*
- * nontrivial trees
- * ------------------
- *
+ * nontrivial trees
+ * ------------------
+ *
* (4) Accept-Encoding (7) Connection
* / \ / \
* (2) Accept Accept-Language (3) (9) Cookie Content-Type (10)
* \ /
* (5) Accept-Charset Content-Length (11)
+ *
+ * (checksum doesn't help here) (checksum is a big win except
+ * for the Content-Length path.)
+ *
+ *
+ * apr_hash: (0.5 ~ 0.6 microseconds / lookup)
+ * apreq_table: (0.3 ~ 0.4 microseconds / entry)
+ * apr_table: (0.2 ~ 0.3 microseconds / entry)
*/
static void perf_get(CuTest *tc)
{
apr_hash_t *h = init_hash();
- apr_table_t *s = init_apr(APREQ_NELTS);
- apreq_table_t *t = init_apreq(APREQ_NELTS);
+ apr_table_t *s = init_apr(NELTS);
+ apreq_table_t *t = init_apreq(NELTS);
apr_time_t apr_delta, apreq_delta;
int j;
- /* expected apr winners: "Accept", "Connection" "Cookie" */
- /* expected apreq winners: */
+ /* expected apr winners: "Accept", "Connection", "Cookie" */
+
RUN_GET("Accept-Encoding","");
- RUN_GET("Accept-Charset","");
RUN_GET("Accept-Language","");
+ RUN_GET("Accept-Charset","");
RUN_GET("Content-Length","");
- RUN_GET("Content-Type",""); /* apr wins by .05 microseconds now */
+ RUN_GET("Content-Type",""); /* apr typically wins by ~.05 microseconds,
+ or ~ 25 clock cycles on my 500Mhz CPU */
}
+
#ifdef footoo
+
static void table_set(CuTest *tc)
{
const char *val;