httpd-apreq-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r151386 [3/4] - in httpd/apreq/branches/multi-env-unstable: ./ build/ env/ env/c-modules/apreq_access_test/ env/c-modules/apreq_big_request_test/ env/c-modules/apreq_cookie_test/ env/c-modules/apreq_output_filter_test/ env/c-modules/apreq_redirect_test/ env/c-modules/apreq_request_test/ src/ t/
Date Fri, 04 Feb 2005 18:28:04 GMT
Modified: httpd/apreq/branches/multi-env-unstable/src/apreq_env_cgi.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/src/apreq_env_cgi.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/src/apreq_env_cgi.c (original)
+++ httpd/apreq/branches/multi-env-unstable/src/apreq_env_cgi.c Fri Feb  4 10:27:55 2005
@@ -13,6 +13,7 @@
 **  See the License for the specific language governing permissions and
 **  limitations under the License.
 */
+#include <assert.h>
 
 #include "apreq.h"
 #include "apreq_env.h"
@@ -20,23 +21,46 @@
 #include "apr_lib.h"
 #include "apr_env.h"
 
-#define dP struct cgi_env *cgi_env = (struct cgi_env*)env; \
-    apr_pool_t *p = cgi_env->pool
+#define USER_DATA_KEY "apreq"
+
+/* Parroting APLOG_* ... */
+
+#define	CGILOG_EMERG	0	/* system is unusable */
+#define	CGILOG_ALERT	1	/* action must be taken immediately */
+#define	CGILOG_CRIT	2	/* critical conditions */
+#define	CGILOG_ERR	3	/* error conditions */
+#define	CGILOG_WARNING	4	/* warning conditions */
+#define	CGILOG_NOTICE	5	/* normal but significant condition */
+#define	CGILOG_INFO	6	/* informational */
+#define	CGILOG_DEBUG	7	/* debug-level messages */
+
+#define CGILOG_LEVELMASK 7
+#define CGILOG_MARK     __FILE__, __LINE__
+
+
+
+
+struct cgi_handle {
+    struct apreq_env_handle_t    env;
+
+    apr_pool_t                  *pool;
+    apr_bucket_alloc_t          *bucket_alloc;
+
+    apr_table_t                 *jar, *args, *body;
+    apr_status_t                 jar_status,
+                                 args_status,
+                                 body_status;
+
+    apreq_parser_t              *parser;
+    apreq_hook_t                *hook_queue;
+
+    const char                  *temp_dir;
+    apr_size_t                   brigade_limit;
+    apr_uint64_t                    read_limit;
+    apr_uint64_t                    bytes_read;
+
+    apr_bucket_brigade          *in;
 
-static struct {
-    apreq_request_t    *req;
-    apreq_jar_t        *jar;
-    apr_status_t        status;
-    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};
-
-struct cgi_env {
-    struct apreq_env_handle_t env;
-    apr_pool_t *pool;
 };
 
 #define CRLF "\015\012"
@@ -49,47 +73,29 @@
          }                                                              \
      } while (0)
 
-#define APREQ_MODULE_NAME         "CGI"
-#define APREQ_MODULE_MAGIC_NUMBER 20041130
-
-static apr_pool_t *cgi_pool(apreq_env_handle_t *env)
-{
-    struct cgi_env *cgi_env = (struct cgi_env*)env;
-
-    return cgi_env->pool;
-}
-
-static apr_status_t bucket_alloc_cleanup(void *data)
-{
-    apr_bucket_alloc_t *ba = data;
-    apr_bucket_alloc_destroy(ba);
-    return APR_SUCCESS;
-}
-
-
-static apr_bucket_alloc_t *cgi_bucket_alloc(apreq_env_handle_t *env)
-{
-    struct cgi_env *cgi_env = (struct cgi_env*)env;
-    apr_bucket_alloc_t *ba = apr_bucket_alloc_create(cgi_env->pool);
-
-    apr_pool_cleanup_register(cgi_env->pool, ba,
-                              bucket_alloc_cleanup,
-                              bucket_alloc_cleanup);
-    return ba;
-}
-
-static const char *cgi_query_string(apreq_env_handle_t *env)
-{
-    dP;
-    char *value = NULL, qs[] = "QUERY_STRING";
-    APREQ_ENV_STATUS(apr_env_get(&value, qs, p), qs);
-    return value;
-}
 
+typedef struct {
+    const char *t_name;
+    int      t_val;
+} TRANS;
+ 
+static const TRANS priorities[] = {
+    {"emerg",   CGILOG_EMERG},
+    {"alert",   CGILOG_ALERT},
+    {"crit",    CGILOG_CRIT},
+    {"error",   CGILOG_ERR},
+    {"warn",    CGILOG_WARNING},
+    {"notice",  CGILOG_NOTICE},
+    {"info",    CGILOG_INFO},
+    {"debug",   CGILOG_DEBUG},
+    {NULL,      -1},
+};
+ 
 static const char *cgi_header_in(apreq_env_handle_t *env,
                                  const char *name)
 {
-    dP;
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    apr_pool_t *p = handle->pool;
     char *key = apr_pstrcat(p, "HTTP_", name, NULL);
     char *k, *value = NULL;
     for (k = key; *k; ++k) {
@@ -105,269 +111,569 @@
             key += 5; /* strlen("HTTP_") */
         }
 
-    APREQ_ENV_STATUS(apr_env_get(&value, key, p), key);
+    apr_env_get(&value, key, p);
 
     return value;
 }
 
+
+
+
+static void cgi_log_error(const char *file, int line, int level,
+                          apr_status_t status, apreq_env_handle_t *env,
+                          const char *fmt, ...)
+{
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    apr_pool_t *p = handle->pool;
+    char buf[256];
+    char *log_level_string, *ra;
+    const char *remote_addr;
+    unsigned log_level = CGILOG_WARNING;
+    char date[APR_CTIME_LEN];
+    va_list vp;
+#ifndef WIN32
+    apr_file_t *err;
+#endif
+
+    va_start(vp, fmt);
+
+    if (apr_env_get(&log_level_string, "LOG_LEVEL", p) == APR_SUCCESS)
+        log_level = (log_level_string[0] - '0');
+
+    level &= CGILOG_LEVELMASK;
+
+    if (level < (int)log_level) {
+
+        if (apr_env_get(&ra, "REMOTE_ADDR", p) == APR_SUCCESS)
+            remote_addr = ra;
+        else
+            remote_addr = "address unavailable";
+
+        apr_ctime(date, apr_time_now());
+
+#ifndef WIN32
+
+        apr_file_open_stderr(&err, p);
+        apr_file_printf(err, "[%s] [%s] [%s] %s(%d): %s: %s\n",
+                        date, priorities[level].t_name, remote_addr, file, line,
+                        apr_strerror(status,buf,255),apr_pvsprintf(p,fmt,vp));
+        apr_file_flush(err);
+
+#else
+        fprintf(stderr, "[%s] [%s] [%s] %s(%d): %s: %s\n",
+                date, priorities[level].t_name, remote_addr, file, line,
+                apr_strerror(status,buf,255),apr_pvsprintf(p,fmt,vp));
+#endif
+    }
+
+    va_end(vp);
+
+}
+
 static apr_status_t cgi_header_out(apreq_env_handle_t *env, const char *name,
                                    char *value)
 {
-    dP;
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    apr_pool_t *p = handle->pool;
     apr_file_t *out;
     int bytes;
     apr_status_t s = apr_file_open_stdout(&out, p);
-    apreq_log(APREQ_DEBUG s, env, "Setting header: %s => %s", name, value);
+    cgi_log_error(CGILOG_MARK, CGILOG_DEBUG, s, env, 
+                  "Setting header: %s => %s", name, value);
     bytes = apr_file_printf(out, "%s: %s" CRLF, name, value);
     apr_file_flush(out);
     return bytes > 0 ? APR_SUCCESS : APR_EGENERAL;
 }
 
 
-static apreq_jar_t *cgi_jar(apreq_env_handle_t *env, apreq_jar_t *jar)
+APR_INLINE
+static const char *cgi_query_string(apreq_env_handle_t *env)
 {
-    (void)env;
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    char *value = NULL, qs[] = "QUERY_STRING";
+    apr_env_get(&value, qs, handle->pool);
+    return value;
+}
+
 
-    if (jar != NULL) {
-        apreq_jar_t *old_jar = ctx.jar;
-        ctx.jar = jar;
-        return old_jar;
+static void init_body(apreq_env_handle_t *env)
+{
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    const char *cl_header = cgi_header_in(env, "Content-Length");
+    apr_bucket_alloc_t *ba = handle->bucket_alloc;
+    apr_pool_t *pool = handle->pool;
+    apr_file_t *file;
+    apr_bucket *eos, *pipe;
+
+    handle->body  = apr_table_make(pool, APREQ_DEFAULT_NELTS);
+
+    if (cl_header != NULL) {
+        char *dummy;
+        apr_int64_t content_length = apr_strtoi64(cl_header, &dummy, 0);
+
+        if (dummy == NULL || *dummy != 0) {
+            handle->body_status = APREQ_ERROR_BADHEADER;
+            cgi_log_error(CGILOG_MARK, CGILOG_ERR, handle->body_status, env,
+                          "Invalid Content-Length header (%s)", cl_header);
+            return;
+        }
+        else if ((apr_uint64_t)content_length > handle->read_limit) {
+            handle->body_status = APREQ_ERROR_OVERLIMIT;
+            cgi_log_error(CGILOG_MARK, CGILOG_ERR, handle->body_status, env,
+                          "Content-Length header (%s) exceeds configured "
+                          "max_body limit (%" APR_UINT64_T_FMT ")", 
+                          cl_header, handle->read_limit);
+            return;
+        }
+    }
+
+    if (handle->parser == NULL) {
+        const char *ct_header = cgi_header_in(env, "Content-Type");
+
+        if (ct_header != NULL) {
+            apreq_parser_function_t pf = apreq_parser(ct_header);
+
+            if (pf != NULL) {
+                handle->parser = apreq_make_parser(handle->pool,
+                                                   ba,
+                                                   ct_header, 
+                                                   pf,
+                                                   handle->brigade_limit,
+                                                   handle->temp_dir,
+                                                   handle->hook_queue,
+                                                   NULL);
+            }
+            else {
+                handle->body_status = APREQ_ERROR_NOPARSER;
+                return;
+            }
+        }
+        else {
+            handle->body_status = APREQ_ERROR_NOHEADER;
+            return;
+        }
     }
+    else {
+        if (handle->parser->brigade_limit > handle->brigade_limit)
+            handle->parser->brigade_limit = handle->brigade_limit;
+        if (handle->temp_dir != NULL)
+            handle->parser->temp_dir = handle->temp_dir;
+        if (handle->hook_queue != NULL)
+            apreq_parser_add_hook(handle->parser, handle->hook_queue);
+    }
+
+    handle->hook_queue = NULL;
+    handle->in         = apr_brigade_create(pool, ba);
+
+    apr_file_open_stdin(&file, pool); // error status?    
+    pipe = apr_bucket_pipe_create(file, ba);
+    eos = apr_bucket_eos_create(ba);
+    APR_BRIGADE_INSERT_HEAD(handle->in, pipe);
+    APR_BRIGADE_INSERT_TAIL(handle->in, eos);
+
+    handle->body_status = APR_INCOMPLETE;
 
-    return ctx.jar;
 }
 
-static apreq_request_t *cgi_request(apreq_env_handle_t *env,
-                                    apreq_request_t *req)
+static apr_status_t cgi_read(apreq_env_handle_t *env,
+                             apr_off_t bytes)
 {
-    (void)env;
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    apr_bucket *e;
+    apr_status_t s;
+
+    if (handle->body_status == APR_EINIT)
+        init_body(env);
+
+    if (handle->body_status != APR_INCOMPLETE)
+        return handle->body_status;
+
+
+    switch (s = apr_brigade_partition(handle->in, bytes, &e)) {
+        apr_bucket_brigade *bb;
+        apr_off_t len;
+
+    case APR_SUCCESS:
+
+        bb = handle->in;
+        handle->in = apr_brigade_split(bb, e);
+        handle->bytes_read += bytes;
+
+        if (handle->bytes_read > handle->read_limit) {
+            handle->body_status = APREQ_ERROR_OVERLIMIT;
+            cgi_log_error(CGILOG_MARK, CGILOG_ERR, handle->body_status,
+                          env, "Bytes read (%" APR_UINT64_T_FMT
+                          ") exceeds configured limit (%" APR_UINT64_T_FMT ")",
+                          handle->bytes_read, handle->read_limit);
+            break;
+        }
 
-    if (req != NULL) {
-        apreq_request_t *old_req = ctx.req;
-        ctx.req = req;
-        return old_req;
+        handle->body_status =
+            APREQ_RUN_PARSER(handle->parser, handle->body, bb);
+        apr_brigade_destroy(bb);
+        break;
+
+
+    case APR_INCOMPLETE:
+
+        bb = handle->in;
+        handle->in = apr_brigade_split(bb, e);
+        s = apr_brigade_length(bb, 1, &len);
+
+        if (s != APR_SUCCESS) {
+            handle->body_status = s;
+            break;
+        }
+        handle->bytes_read += len;
+
+        if (handle->bytes_read > handle->read_limit) {
+            handle->body_status = APREQ_ERROR_OVERLIMIT;
+            cgi_log_error(CGILOG_MARK, CGILOG_ERR, handle->body_status, env,
+                          "Bytes read (%" APR_UINT64_T_FMT
+                          ") exceeds configured limit (%" APR_UINT64_T_FMT ")",
+                          handle->bytes_read, handle->read_limit);
+            
+            break;
+        }
+
+        handle->body_status =
+            APREQ_RUN_PARSER(handle->parser, handle->body, bb);
+        apr_brigade_destroy(bb);
+        break;
+
+    default:
+        handle->body_status = s;
     }
-    return ctx.req;
+
+    return handle->body_status;
 }
 
 
-typedef struct {
-    const char *t_name;
-    int      t_val;
-} TRANS;
 
-static const TRANS priorities[] = {
-    {"emerg",   APREQ_LOG_EMERG},
-    {"alert",   APREQ_LOG_ALERT},
-    {"crit",    APREQ_LOG_CRIT},
-    {"error",   APREQ_LOG_ERR},
-    {"warn",    APREQ_LOG_WARNING},
-    {"notice",  APREQ_LOG_NOTICE},
-    {"info",    APREQ_LOG_INFO},
-    {"debug",   APREQ_LOG_DEBUG},
-    {NULL,      -1},
-};
+static apr_status_t cgi_jar(apreq_env_handle_t *env,
+                            const apr_table_t **t)
+{
+    struct cgi_handle *handle = (struct cgi_handle *)env;
 
+    if (handle->jar_status == APR_EINIT) {
+        const char *cookies = cgi_header_in(env, "Cookie");
+        if (cookies != NULL) {
+            handle->jar = apr_table_make(handle->pool, APREQ_DEFAULT_NELTS);
+            handle->jar_status = 
+                apreq_parse_cookie_header(handle->pool, handle->jar, cookies);
+        }
+        else
+            handle->jar_status = APREQ_ERROR_NODATA;
+    }
+
+    *t = handle->jar;
+    return handle->jar_status;
+}
 
-static void cgi_log(const char *file, int line, int level,
-                    apr_status_t status, apreq_env_handle_t *env,
-                    const char *fmt, va_list vp)
+static apr_status_t cgi_args(apreq_env_handle_t *env,
+                             const apr_table_t **t)
 {
-    dP;
-    char buf[256];
-    char *log_level_string, *ra;
-    const char *remote_addr;
-    unsigned log_level = APREQ_LOG_WARNING;
-    char date[APR_CTIME_LEN];
-#ifndef WIN32
-    apr_file_t *err;
-#endif
+    struct cgi_handle *handle = (struct cgi_handle *)env;
 
+    if (handle->args_status == APR_EINIT) {
+        const char *query_string = cgi_query_string(env);
+        if (query_string != NULL) {
+            handle->args = apr_table_make(handle->pool, APREQ_DEFAULT_NELTS);
+            handle->args_status = 
+                apreq_parse_query_string(handle->pool, handle->args, query_string);
+        }
+        else
+            handle->args_status = APREQ_ERROR_NODATA;
+    }
 
-    if (apr_env_get(&log_level_string, "LOG_LEVEL", p) == APR_SUCCESS)
-        log_level = (log_level_string[0] - '0');
+    *t = handle->args;
+    return handle->args_status;
+}
 
-    level &= APREQ_LOG_LEVELMASK;
 
-    if (level > (int)log_level)
-        return;
 
-    if (apr_env_get(&ra, "REMOTE_ADDR", p) == APR_SUCCESS)
-        remote_addr = ra;
+
+static apreq_cookie_t *cgi_jar_get(apreq_env_handle_t *env,
+                                   const char *name)
+{
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    const apr_table_t *t;
+    const char *val;
+
+    if (handle->jar_status == APR_EINIT)
+        cgi_jar(env, &t);
     else
-        remote_addr = "address unavailable";
+        t = handle->jar;
 
-    apr_ctime(date, apr_time_now());
+    if (t == NULL)
+        return NULL;
 
-#ifndef WIN32
+    val = apr_table_get(t, name);
+    if (val == NULL)
+        return NULL;
 
-    apr_file_open_stderr(&err, p);
-    apr_file_printf(err, "[%s] [%s] [%s] %s(%d): %s: %s\n",
-                    date, priorities[level].t_name, remote_addr, file, line,
-                    apr_strerror(status,buf,255),apr_pvsprintf(p,fmt,vp));
-    apr_file_flush(err);
+    return apreq_value_to_cookie(val);
+}
 
-#else
-    fprintf(stderr, "[%s] [%s] [%s] %s(%d): %s: %s\n",
-            date, priorities[level].t_name, remote_addr, file, line,
-            apr_strerror(status,buf,255),apr_pvsprintf(p,fmt,vp));
-#endif
+static apreq_param_t *cgi_args_get(apreq_env_handle_t *env,
+                                   const char *name)
+{
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    const apr_table_t *t;
+    const char *val;
+
+    if (handle->args_status == APR_EINIT)
+        cgi_args(env, &t);
+    else
+        t = handle->args;
+
+    if (t == NULL)
+        return NULL;
 
+    val = apr_table_get(t, name);
+    if (val == NULL)
+        return NULL;
+
+    return apreq_value_to_param(val);
 }
 
-static apr_status_t cgi_read(apreq_env_handle_t *env,
-                             apr_read_type_e block,
-                             apr_off_t bytes)
+
+
+static apr_status_t cgi_body(apreq_env_handle_t *env,
+                             const apr_table_t **t)
 {
-    dP;
-    apreq_request_t *req = apreq_request(env, NULL);
-    apr_bucket *e;
-    apr_status_t s;
+    struct cgi_handle *handle = (struct cgi_handle *)env;
 
-    (void)block;
+    switch (handle->body_status) {
 
-    if (ctx.in == NULL) {
-        apr_bucket_alloc_t *alloc = apr_bucket_alloc_create(p);
-        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);
-        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.max_body >= 0) {
-            const char *cl = apreq_env_header_in(env, "Content-Length");
-            if (cl != NULL) {
-                char *dummy;
-                apr_int64_t content_length = apr_strtoi64(cl,&dummy,0);
-
-                if (dummy == NULL || *dummy != 0) {
-                    apreq_log(APREQ_ERROR APR_EGENERAL, env,
-                              "Invalid Content-Length header (%s)", cl);
-                    ctx.status = APR_EGENERAL;
-                    req->body_status = APR_EGENERAL;
-                }
-                else if (content_length > (apr_int64_t)ctx.max_body) {
-                    apreq_log(APREQ_ERROR APR_EGENERAL, env,
-                              "Content-Length header (%s) exceeds configured "
-                              "max_body limit (%" APR_OFF_T_FMT ")",
-                              cl, ctx.max_body);
-                    ctx.status = APR_EGENERAL;
-                    req->body_status = APR_EGENERAL;
-                }
-            }
-        }
+    case APR_EINIT:
+        init_body(env);
+        if (handle->body_status != APR_INCOMPLETE)
+            break;
+
+    case APR_INCOMPLETE:
+        while (cgi_read(env, APREQ_DEFAULT_READ_BLOCK_SIZE) == APR_INCOMPLETE)
+            ;   /*loop*/
     }
 
+    *t = handle->body;
+    return handle->body_status;
+}
 
-    if (ctx.status != APR_INCOMPLETE)
-        return ctx.status;
+static apreq_param_t *cgi_body_get(apreq_env_handle_t *env, 
+                                   const char *name)
+{
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    const char *val;
 
-    switch (s = apr_brigade_partition(ctx.in, bytes, &e)) {
-        apr_bucket_brigade *bb;
-        apr_off_t len;
+    switch (handle->body_status) {
 
-    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) {
-                apreq_log(APREQ_ERROR APR_EGENERAL, env,
-                          "Bytes read (%" APR_OFF_T_FMT
-                          ") exceeds configured limit (%" APR_OFF_T_FMT ")",
-                          ctx.bytes_read, ctx.max_body);
-                req->body_status = APR_EGENERAL;
-                return ctx.status = APR_EGENERAL;
-            }
-        }
-        ctx.status = apreq_parse_request(req, bb);
-        apr_brigade_cleanup(bb);
-        break;
+    case APR_EINIT:
+
+        init_body(env);
+        if (handle->body_status != APR_INCOMPLETE)
+            return NULL;
+        cgi_read(env, APREQ_DEFAULT_READ_BLOCK_SIZE);
 
     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) {
-                apreq_log(APREQ_ERROR APR_EGENERAL, env,
-                          "Bytes read (%" APR_OFF_T_FMT
-                          ") exceeds configured limit (%" APR_OFF_T_FMT ")",
-                          ctx.bytes_read, ctx.max_body);
-                req->body_status = APR_EGENERAL;
-                return ctx.status = APR_EGENERAL;
-            }
-        }
-        ctx.status = apreq_parse_request(req, bb);
-        apr_brigade_cleanup(bb);
-        break;
+
+        val = apr_table_get(handle->body, name);
+        if (val != NULL)
+            return apreq_value_to_param(val);
+
+        do {
+            /* riff on Duff's device */
+            cgi_read(env, APREQ_DEFAULT_READ_BLOCK_SIZE);
 
     default:
-        ctx.status = s;
+
+            val = apr_table_get(handle->body, name);
+            if (val != NULL)
+                return apreq_value_to_param(val);
+
+        } while (handle->body_status == APR_INCOMPLETE);
+
     }
 
-    return ctx.status;
+    return NULL;
 }
 
+static apr_status_t cgi_parser_get(apreq_env_handle_t *env, 
+                                   const apreq_parser_t **parser)
+{
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+
+    *parser = handle->parser;
+    return APR_SUCCESS;
+}
 
-static const char *cgi_temp_dir(apreq_env_handle_t *env, const char *path)
+static apr_status_t cgi_parser_set(apreq_env_handle_t *env, 
+                                   apreq_parser_t *parser)
 {
-    if (path != NULL) {
-        dP;
-        const char *rv = ctx.temp_dir;
-        ctx.temp_dir = apr_pstrdup(p, path);
-        return rv;
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+
+    if (handle->parser == NULL) {
+
+        if (handle->hook_queue != NULL) {
+            apr_status_t s = apreq_parser_add_hook(parser, handle->hook_queue);
+            if (s != APR_SUCCESS)
+                return s;
+        }
+        if (handle->temp_dir != NULL) {
+            parser->temp_dir = handle->temp_dir;
+        }
+        if (handle->brigade_limit < parser->brigade_limit) {
+            parser->brigade_limit = handle->brigade_limit;
+        }
+
+        handle->hook_queue = NULL;
+        handle->parser = parser;
+        return APR_SUCCESS;
     }
-    if (ctx.temp_dir == NULL) {
-        dP;
-        if (apr_temp_dir_get(&ctx.temp_dir, p) != APR_SUCCESS)
-            ctx.temp_dir = NULL;
+    else
+        return APREQ_ERROR_CONFLICT;
+}
+
+
+static apr_status_t cgi_hook_add(apreq_env_handle_t *env,
+                                     apreq_hook_t *hook)
+{
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+
+    if (handle->parser != NULL) {
+        return apreq_parser_add_hook(handle->parser, hook);
+    }
+    else if (handle->hook_queue != NULL) {
+        apreq_hook_t *h = handle->hook_queue;
+        while (h->next != NULL)
+            h = h->next;
+        h->next = hook;
+    }
+    else {
+        handle->hook_queue = hook;
     }
+    return APR_SUCCESS;
 
-    return ctx.temp_dir;
 }
 
+static apr_status_t cgi_brigade_limit_set(apreq_env_handle_t *env,
+                                          apr_size_t bytes)
+{
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    apr_size_t *limit = (handle->parser == NULL) 
+                      ? &handle->brigade_limit 
+                      : &handle->parser->brigade_limit;
+
+    if (*limit > bytes) {
+        *limit = bytes;
+        return APR_SUCCESS;
+    }
+
+    return APREQ_ERROR_CONFLICT;
+}
+
+static apr_status_t cgi_brigade_limit_get(apreq_env_handle_t *env,
+                                          apr_size_t *bytes)
+{
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    *bytes = (handle->parser == NULL) 
+           ?  handle->brigade_limit 
+           :  handle->parser->brigade_limit;
+
+    return APR_SUCCESS;
+}
 
-static apr_off_t cgi_max_body(apreq_env_handle_t *env, apr_off_t bytes)
+static apr_status_t cgi_read_limit_set(apreq_env_handle_t *env,
+                                       apr_uint64_t bytes)
 {
-    (void)env;
+    struct cgi_handle *handle = (struct cgi_handle *)env;
 
-    if (bytes >= 0) {
-        apr_off_t rv = ctx.max_body;
-        ctx.max_body = bytes;
-        return rv;
+    if (handle->read_limit > bytes && handle->bytes_read < bytes) {
+        handle->read_limit = bytes;
+        return APR_SUCCESS;
     }
-    return ctx.max_body;
+
+    return APREQ_ERROR_CONFLICT;
 }
 
 
-static apr_ssize_t cgi_max_brigade(apreq_env_handle_t *env, apr_ssize_t bytes)
+static apr_status_t cgi_read_limit_get(apreq_env_handle_t *env,
+                                       apr_uint64_t *bytes)
 {
-    (void)env;
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    *bytes = handle->read_limit;
+    return APR_SUCCESS;
+}
 
-    if (bytes >= 0) {
-        apr_ssize_t rv = ctx.max_brigade;
-        ctx.max_brigade = bytes;
-        return rv;
+
+static apr_status_t cgi_temp_dir_set(apreq_env_handle_t *env,
+                                     const char *path)
+{
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    const char **temp_dir = (handle->parser == NULL) 
+                          ? &handle->temp_dir
+                          : &handle->parser->temp_dir;
+
+
+    if (*temp_dir == NULL && handle->bytes_read == 0) {
+        if (path != NULL)
+            *temp_dir = apr_pstrdup(handle->pool, path);
+        return APR_SUCCESS;
     }
-    return ctx.max_brigade;
+
+    return APREQ_ERROR_CONFLICT;
 }
 
-APREQ_ENV_MODULE(cgi, APREQ_MODULE_NAME,
-                 APREQ_MODULE_MAGIC_NUMBER);
 
-APREQ_DECLARE(apreq_env_handle_t*) apreq_env_make_cgi(apr_pool_t *pool) {
-    struct cgi_env *handle;
+static apr_status_t cgi_temp_dir_get(apreq_env_handle_t *env,
+                                     const char **path)
+{
+    struct cgi_handle *handle = (struct cgi_handle *)env;
+    *path = (handle->parser == NULL)
+           ?  handle->temp_dir 
+           :  handle->parser->temp_dir;
+    return APR_SUCCESS;
+}
+
+
+
+
+static apr_status_t cgi_cleanup(void *data)
+{
+    struct cgi_handle *handle = data;
+    apr_bucket_alloc_destroy(handle->bucket_alloc);
+    return APR_SUCCESS;
+}
+
+static APREQ_MODULE(cgi, 20050130);
+
+APREQ_DECLARE(apreq_env_handle_t *)apreq_handle_cgi(apr_pool_t *pool)
+{
+    apr_bucket_alloc_t *ba;
+    struct cgi_handle *handle;
+    void *data;
+    
+    apr_pool_userdata_get(&data, USER_DATA_KEY, pool);
+
+    if (data != NULL)
+        return data;
+
+    handle = apr_pcalloc(pool, sizeof *handle);
+    ba = apr_bucket_alloc_create(pool);
+
+    /* check pool's userdata first. */
+
+    handle->env.module    = &cgi_module;
+    handle->pool          = pool;
+    handle->bucket_alloc  = ba;
+    handle->read_limit    = (apr_uint64_t) -1;
+    handle->brigade_limit = APREQ_DEFAULT_BRIGADE_LIMIT;
+
+    handle->args_status = 
+        handle->jar_status = 
+            handle->body_status = APR_EINIT;
 
-    handle = apr_pcalloc(pool, sizeof(*handle));
-    handle->env.module = &cgi_module;
-    handle->pool = pool;
+    apr_pool_userdata_setn(&handle->env, USER_DATA_KEY, cgi_cleanup, pool);
 
     return &handle->env;
 }

Modified: httpd/apreq/branches/multi-env-unstable/src/apreq_env_custom.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/src/apreq_env_custom.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/src/apreq_env_custom.c (original)
+++ httpd/apreq/branches/multi-env-unstable/src/apreq_env_custom.c Fri Feb  4 10:27:55 2005
@@ -14,252 +14,320 @@
 **  limitations under the License.
 */
 
-#include <apr_strings.h>
-
-#include "apreq.h"
+#include "apr_strings.h"
 #include "apreq_env.h"
 
+#define READ_BYTES (64 * 1024)
+
 struct custom_handle {
-    struct apreq_env_handle_t env;
-    apr_pool_t *pool;
-    const char *query_string;
-    apreq_request_t *request;
-    const char *content_type;
-    const char *cookie_string, *cookie2_string;
-    apreq_jar_t *jar;
-    const char *temp_dir;
-    apr_off_t max_body;
-    apr_ssize_t max_brigade;
-
-    /* body state */
-    apr_status_t status;
-    apr_off_t bytes_read;
-    apr_bucket_brigade *in;
+    struct apreq_env_handle_t    env;
+    const char                  *cookie_header, *cookie2_header;
+
+    apr_table_t                 *jar, *args, *body;
+    apr_status_t                 jar_status,
+                                 args_status,
+                                 body_status;
+
+    apreq_parser_t              *parser;
+
+    apr_uint64_t                 read_limit;
+    apr_uint64_t                 bytes_read;
+    apr_bucket_brigade          *in;
 };
 
-static apr_pool_t *custom_pool(apreq_env_handle_t *env) {
+
+static apr_status_t custom_parse_brigade(apreq_env_handle_t *env, apr_uint64_t bytes)
+{       
     struct custom_handle *handle = (struct custom_handle*)env;
+    apr_status_t s;
+    apr_bucket *e;
+
+    if (handle->body_status != APR_INCOMPLETE)
+        return handle->body_status;
+
+    switch (s = apr_brigade_partition(handle->in, bytes, &e)) {
+        apr_bucket_brigade *bb;
+        apr_uint64_t len;
+
+    case APR_SUCCESS:
+        bb = apr_brigade_split(handle->in, e);
+        handle->bytes_read += bytes;
+
+        if (handle->bytes_read > handle->read_limit) {
+            handle->body_status = APREQ_ERROR_OVERLIMIT;
+            break;
+        }
+
+        handle->body_status = 
+            APREQ_RUN_PARSER(handle->parser, handle->body, handle->in);
+
+        apr_brigade_cleanup(handle->in);
+        APR_BRIGADE_CONCAT(handle->in, bb);
+        break;
+
+    case APR_INCOMPLETE:
+        bb = apr_brigade_split(handle->in, e);
+        s = apr_brigade_length(handle->in, 1, &len);
+        if (s != APR_SUCCESS) {
+            handle->body_status = s;
+            break;
+        }
+        handle->bytes_read += len;
+
+        if (handle->bytes_read > handle->read_limit) {
+            handle->body_status = APREQ_ERROR_OVERLIMIT;
+            break;
+        }
+        handle->body_status = 
+            APREQ_RUN_PARSER(handle->parser, handle->body, handle->in);
+
+        apr_brigade_cleanup(handle->in);
+        APR_BRIGADE_CONCAT(handle->in, bb);
+        break;
+
+    default:
+        handle->body_status = s;
+    }
 
-    return handle->pool;
+    return handle->body_status;
 }
 
-static apr_status_t bucket_alloc_cleanup(void *data)
+
+
+static apr_status_t custom_jar(apreq_env_handle_t *env, const apr_table_t **t)
 {
-    apr_bucket_alloc_t *ba = data;
-    apr_bucket_alloc_destroy(ba);
-    return APR_SUCCESS;
+    struct custom_handle *handle = (struct custom_handle*)env;
+    *t = handle->jar;
+    return handle->jar_status;
 }
 
-static apr_bucket_alloc_t *custom_bucket_alloc(apreq_env_handle_t *env)
+static apr_status_t custom_args(apreq_env_handle_t *env, const apr_table_t **t)
 {
     struct custom_handle *handle = (struct custom_handle*)env;
-    apr_bucket_alloc_t *ba = apr_bucket_alloc_create(handle->pool);
-
-    apr_pool_cleanup_register(handle->pool, ba,
-                              bucket_alloc_cleanup,
-                              bucket_alloc_cleanup);
-    return ba;
+    *t = handle->args;
+    return handle->args_status;
 }
 
-static const char *custom_query_string(apreq_env_handle_t *env)
+static apr_status_t custom_body(apreq_env_handle_t *env, const apr_table_t **t)
 {
     struct custom_handle *handle = (struct custom_handle*)env;
-
-    return handle->query_string;
+    while (handle->body_status == APR_INCOMPLETE)
+        custom_parse_brigade(env, READ_BYTES);
+    *t = handle->body;
+    return handle->body_status;
 }
 
-static const char *custom_header_in(apreq_env_handle_t *env,
-                                    const char *name)
+
+
+static apreq_cookie_t *custom_jar_get(apreq_env_handle_t *env, const char *name)
 {
     struct custom_handle *handle = (struct custom_handle*)env;
+    const char *val;
 
-    if (strcasecmp(name, "Content-Type") == 0)
-        return handle->content_type;
-    else if (strcasecmp(name, "Cookie") == 0)
-        return handle->cookie_string;
-    else if (strcasecmp(name, "Cookie2") == 0)
-        return handle->cookie2_string;
-    else
+    if (handle->jar == NULL || name == NULL)
         return NULL;
+
+    val = apr_table_get(handle->jar, name);
+
+    if (val == NULL)
+        return NULL;
+
+    return apreq_value_to_cookie(val);
 }
 
-static apr_status_t custom_header_out(apreq_env_handle_t *env, const char *name,
-                                      char *value)
+static apreq_param_t *custom_args_get(apreq_env_handle_t *env, const char *name)
 {
-    (void)env;
-    (void)name;
-    (void)value;
+    struct custom_handle *handle = (struct custom_handle*)env;
+    const char *val;
 
-    return APR_SUCCESS;
+    if (handle->args == NULL || name == NULL)
+        return NULL;
+
+    val = apr_table_get(handle->args, name);
+
+    if (val == NULL)
+        return NULL;
+
+    return apreq_value_to_param(val);
 }
 
-static apreq_jar_t *custom_jar(apreq_env_handle_t *env, apreq_jar_t *jar)
+static apreq_param_t *custom_body_get(apreq_env_handle_t *env, const char *name)
 {
     struct custom_handle *handle = (struct custom_handle*)env;
-    apreq_jar_t *value = handle->jar;
+    const char *val;
 
-    if (jar != NULL)
-        handle->jar = jar;
+    if (handle->body == NULL || name == NULL)
+        return NULL;
 
-    return value;
+ get_body_value:
+
+    *(const char **)&val = apr_table_get(handle->body, name);
+    if (val == NULL) {
+        if (handle->body_status == APR_INCOMPLETE) {
+            custom_parse_brigade(env, READ_BYTES);
+            goto get_body_value;
+        }
+        else
+            return NULL;
+    }
+
+    return apreq_value_to_param(val);
 }
 
-static apreq_request_t *custom_request(apreq_env_handle_t *env,
-                                       apreq_request_t *req)
+
+
+static apr_status_t custom_parser_get(apreq_env_handle_t *env,
+                                      const apreq_parser_t **parser)
 {
     struct custom_handle *handle = (struct custom_handle*)env;
-    apreq_request_t *value = handle->request;
+    *parser = handle->parser;
 
-    if (req != NULL)
-        handle->request = req;
-
-    return value;
+    return APR_SUCCESS;
 }
 
-static void custom_log(const char *file, int line, int level,
-                       apr_status_t status, apreq_env_handle_t *env,
-                       const char *fmt, va_list vp)
+static apr_status_t custom_parser_set(apreq_env_handle_t *env,
+                                      apreq_parser_t *parser)
 {
-    (void)file;
-    (void)line;
-    (void)level;
-    (void)status;
     (void)env;
-    (void)fmt;
-    (void)vp;
+    (void)parser;
+    return APR_ENOTIMPL;
 }
 
-static apr_status_t custom_read(apreq_env_handle_t *env,
-                                apr_read_type_e block,
-                                apr_off_t bytes)
+static apr_status_t custom_hook_add(apreq_env_handle_t *env,
+                                    apreq_hook_t *hook)
 {
     struct custom_handle *handle = (struct custom_handle*)env;
-    apr_bucket *e;
-
-    (void)block;
-
-    if (handle->status != APR_INCOMPLETE)
-        return handle->status;
+    apreq_parser_add_hook(handle->parser, hook);
+    return APR_SUCCESS;
+}
 
-    handle->status = apr_brigade_partition(handle->in, bytes, &e);
-    switch (handle->status) {
-        apr_bucket_brigade *bb;
-        apr_off_t len;
-        apreq_request_t *req;
+static apr_status_t custom_brigade_limit_get(apreq_env_handle_t *env,
+                                             apr_size_t *bytes)
+{
+    struct custom_handle *handle = (struct custom_handle*)env;
+    *bytes = handle->parser->brigade_limit;
+    return APR_SUCCESS;
+}
 
-    case APR_SUCCESS:
-        bb = apr_brigade_split(handle->in, e);
-        req = apreq_request(env, NULL);
-        if (handle->max_body >= 0 &&
-            handle->bytes_read + bytes > handle->max_body) {
-            apreq_log(APREQ_ERROR APR_EGENERAL, env,
-                      "Bytes read (%" APR_OFF_T_FMT
-                      ") exceeds configured limit (%" APR_OFF_T_FMT ")",
-                      handle->bytes_read, handle->max_body);
-            req->body_status = APR_EGENERAL;
-            return handle->status = APR_EGENERAL;
-        }
-        handle->bytes_read += bytes;
-        handle->status = apreq_parse_request(req, handle->in);
-        apr_brigade_cleanup(handle->in);
-        APR_BRIGADE_CONCAT(handle->in, bb);
-        break;
+static apr_status_t custom_brigade_limit_set(apreq_env_handle_t *env,
+                                             apr_size_t bytes)
+{
+    (void)env;
+    (void)bytes;
+    return APR_ENOTIMPL;
+}
 
-    case APR_INCOMPLETE:
-        bb = apr_brigade_split(handle->in, e);
-        handle->status = apr_brigade_length(handle->in,1,&len);
-        if (handle->status != APR_SUCCESS)
-            return handle->status;
-        req = apreq_request(env, NULL);
-        if (handle->max_body >= 0 &&
-            handle->bytes_read + len > handle->max_body) {
-            apreq_log(APREQ_ERROR APR_EGENERAL, env,
-                      "Bytes read (%" APR_OFF_T_FMT
-                      ") exceeds configured limit (%" APR_OFF_T_FMT ")",
-                      handle->bytes_read, handle->max_body);
-            req->body_status = APR_EGENERAL;
-            return handle->status = APR_EGENERAL;
-        }
-        handle->bytes_read += len;
-        handle->status = apreq_parse_request(req, handle->in);
-        apr_brigade_cleanup(handle->in);
-        APR_BRIGADE_CONCAT(handle->in, bb);
-        break;
-    }
+static apr_status_t custom_read_limit_get(apreq_env_handle_t *env,
+                                          apr_uint64_t *bytes)
+{
+    struct custom_handle *handle = (struct custom_handle*)env;
+    *bytes = handle->read_limit;
+    return APR_SUCCESS;
+}
 
-    return handle->status;
+static apr_status_t custom_read_limit_set(apreq_env_handle_t *env,
+                                          apr_uint64_t bytes)
+{
+    (void)env;
+    (void)bytes;
+    return APR_ENOTIMPL;
 }
 
-static const char *custom_temp_dir(apreq_env_handle_t *env, const char *path)
+static apr_status_t custom_temp_dir_get(apreq_env_handle_t *env,
+                                        const char **path)
 {
     struct custom_handle *handle = (struct custom_handle*)env;
-    const char *value = handle->temp_dir;
 
-    if (path != NULL)
-        handle->temp_dir = apr_pstrdup(handle->pool, path);
+    *path = handle->parser->temp_dir;
+    return APR_SUCCESS;
+}
 
-    if (handle->temp_dir == NULL) {
-        apr_status_t status;
+static apr_status_t custom_temp_dir_set(apreq_env_handle_t *env,
+                                        const char *path)
+{
+    (void)env;
+    (void)path;
+    return APR_ENOTIMPL;
+}
 
-        status = apr_temp_dir_get(&value, handle->pool);
-        if (status != APR_SUCCESS)
-            value = NULL;
 
-        handle->temp_dir = value;
-    }
 
-    return value;
-}
 
-static apr_off_t custom_max_body(apreq_env_handle_t *env, apr_off_t bytes)
+static const char *custom_header_in(apreq_env_handle_t *env,
+                                    const char *name)
 {
     struct custom_handle *handle = (struct custom_handle*)env;
-    apr_off_t value = handle->max_body;
 
-    if (bytes >= 0)
-        handle->max_body = bytes;
-
-    return value;
+    if (strcasecmp(name, "Content-Type") == 0)
+        return handle->parser->content_type;
+    else if (strcasecmp(name, "Cookie") == 0)
+        return handle->cookie_header;
+    else if (strcasecmp(name, "Cookie2") == 0)
+        return handle->cookie2_header;
+    else
+        return NULL;
 }
 
-static apr_ssize_t custom_max_brigade(apreq_env_handle_t *env, apr_ssize_t bytes)
+static apr_status_t custom_header_out(apreq_env_handle_t *env, const char *name,
+                                      char *value)
 {
-    struct custom_handle *handle = (struct custom_handle*)env;
-    apr_off_t value = handle->max_brigade;
-
-    if (bytes >= 0)
-        handle->max_brigade = bytes;
+    (void)env;
+    (void)name;
+    (void)value;
 
-    return value;
+    return APR_ENOTIMPL;
 }
 
-static APREQ_ENV_MODULE(custom, "Custom", 20050110);
 
-APREQ_DECLARE(apreq_env_handle_t*) apreq_env_make_custom(apr_pool_t *pool,
-                                                         const char *query_string,
-                                                         const char *cookie,
-                                                         const char *cookie2,
-                                                         const char *content_type,
-                                                         apr_bucket_brigade *in) {
-    struct custom_handle *handle;
+static APREQ_MODULE(custom, 20050130);
 
-    handle = apr_pcalloc(pool, sizeof(*handle));
+APREQ_DECLARE(apreq_env_handle_t*) apreq_handle_custom(apr_pool_t *pool,
+                                                       const char *query_string,
+                                                       const char *cookie,
+                                                       const char *cookie2,
+                                                       apreq_parser_t *parser,
+                                                       apr_uint64_t read_limit,
+                                                       apr_bucket_brigade *in)
+{
+    struct custom_handle *handle;
+    handle = apr_palloc(pool, sizeof(*handle));
     handle->env.module = &custom_module;
-    handle->pool = pool;
-    handle->max_body = -1;
-    handle->max_brigade = -1;
-
-    if (query_string != NULL)
-        handle->query_string = apr_pstrdup(pool, query_string);
-    if (content_type != NULL)
-        handle->content_type = apr_pstrdup(pool, content_type);
-    if (cookie != NULL)
-        handle->cookie_string = apr_pstrdup(pool, cookie);
-    if (cookie2 != NULL)
-        handle->cookie2_string = apr_pstrdup(pool, cookie2);
-
+    handle->cookie_header = cookie;
+    handle->cookie2_header = cookie2;
+    handle->read_limit = read_limit;
+    handle->parser = parser;
     handle->in = in;
-    handle->status = handle->in == NULL ? APR_ENOTIMPL : APR_INCOMPLETE;
+
+    if (cookie != NULL) {
+        handle->jar = apr_table_make(pool, APREQ_DEFAULT_NELTS);
+        handle->jar_status = 
+            apreq_parse_cookie_header(pool, handle->args, query_string);
+    }
+    else {
+        handle->jar = NULL;
+        handle->jar_status = APREQ_ERROR_NODATA;
+    }
+
+
+    if (query_string != NULL) {
+        handle->args = apr_table_make(pool, APREQ_DEFAULT_NELTS);
+        handle->args_status = 
+            apreq_parse_query_string(pool, handle->args, query_string);
+    }
+    else {
+        handle->args = NULL;
+        handle->args_status = APREQ_ERROR_NODATA;
+    }
+
+    if (in != NULL) {
+        handle->body = apr_table_make(pool, APREQ_DEFAULT_NELTS);
+        handle->body_status = APR_INCOMPLETE;
+    }
+    else {
+        handle->body = NULL;
+        handle->body_status = APREQ_ERROR_NODATA;
+    }
 
     return &handle->env;
 }
+

Modified: httpd/apreq/branches/multi-env-unstable/src/apreq_params.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/src/apreq_params.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/src/apreq_params.c (original)
+++ httpd/apreq/branches/multi-env-unstable/src/apreq_params.c Fri Feb  4 10:27:55 2005
@@ -15,7 +15,6 @@
 */
 
 #include "apreq_params.h"
-#include "apreq_env.h"
 #include "apr_strings.h"
 #include "apr_lib.h"
 
@@ -30,204 +29,58 @@
                                                 const apr_size_t vlen)
 {
     apreq_param_t *param = apr_palloc(p, nlen + vlen + 1 + sizeof *param);
-    apreq_value_t *v = &param->v;
-    char *writable_name;
+    apreq_value_t *v;
     param->info = NULL;
-    param->bb = NULL;
+    param->upload = NULL;
 
+    *(const apreq_value_t **)&v = &param->v;
     v->size = vlen;
-    memcpy(v->data, val, vlen);
+    if (vlen)
+        memcpy(v->data, val, vlen);
     v->data[vlen] = 0;
-    writable_name = v->data + vlen + 1;
-    memcpy(writable_name, name, nlen);
-    writable_name[nlen] = 0;
-    v->name = writable_name;
+    v->name = v->data + vlen + 1;
+    if (nlen)
+        memcpy(v->name, name, nlen);
+    v->name[nlen] = 0;
 
     return param;
 }
 
 
-APREQ_DECLARE(apreq_request_t *) apreq_request(apreq_env_handle_t *env,
-                                               const char *qs)
+APREQ_DECLARE(apr_status_t) apreq_decode_param(apreq_param_t **param,
+                                               apr_pool_t *pool, 
+                                               const char *word,
+                                               const apr_size_t nlen, 
+                                               const apr_size_t vlen)
 {
-    apreq_request_t *req;
-    apr_pool_t *p;
-
-    if (qs == NULL) {
-        apreq_request_t *old_req = apreq_env_request(env,NULL);
-        if (old_req != NULL)
-            return old_req;
-
-        p = apreq_env_pool(env);
-        qs = apreq_env_query_string(env);
-
-        req = apr_palloc(p, sizeof *req);
-        req->env      = env;
-        req->args     = apr_table_make(p, APREQ_NELTS);
-        req->body     = NULL;
-        req->parser   = NULL;
-
-        /* XXX get/set race condition here wrt apreq_env_request? */
-        old_req = apreq_env_request(env, req);
-
-        if (old_req != NULL) {
-            apreq_log(APREQ_ERROR APR_EGENERAL, env, "race condition"
-                      "between consecutive calls of apreq_env_request");
-            apreq_env_request(env, old_req); /* reset old_req */
-            return old_req;
-        }
-
-    }
-    else {
-        p = apreq_env_pool(env);
-
-        req = apr_palloc(p, sizeof *req);
-        req->env      = env;
-        req->args     = apr_table_make(p, APREQ_NELTS);
-        req->body     = NULL;
-        req->parser   = NULL;
-
-    }
-
-    if (qs != NULL) {
-        req->args_status = apreq_parse_query_string(p, req->args, qs);
-        if (req->args_status != APR_SUCCESS)
-            apreq_log(APREQ_ERROR req->args_status, env, 
-                      "invalid query string: %s", qs);
-    }
-    else
-        req->args_status = APR_SUCCESS;
-
-    req->body_status = APR_EINIT;
-    return req;
-}
-
-
-APREQ_DECLARE(apreq_param_t *)apreq_param(const apreq_request_t *req, 
-                                          const char *name)
-{
-    const char *val = apr_table_get(req->args, name);
+    apr_status_t status;
+    apreq_value_t *v;
+    apreq_param_t *p;
+    apr_size_t size;
 
-    while (val == NULL) {
-        apr_status_t s = req->body_status;
-        switch (s) {
-        case APR_INCOMPLETE:
-        case APR_EINIT:
-            s = apreq_env_read(req->env, APR_BLOCK_READ, APREQ_READ_AHEAD);
+    if (nlen == 0)
+        return APR_EBADARG;
 
-        default:
-            if (req->body == NULL)
-                return NULL;
-            val = apr_table_get(req->body, name);
-            if (s != APR_INCOMPLETE && val == NULL)
-                return NULL;
+    p = apr_palloc(pool, nlen + vlen + 1 + sizeof *p);
+    p->info = NULL;
+    p->upload = NULL;
+    *(const apreq_value_t **)&v = &p->v;
+
+    if (vlen > 0) {
+        status = apreq_decode(v->data, &v->size, word + nlen + 1, vlen);
+        if (status != APR_SUCCESS) {
+            *param = NULL;
+            return status;
         }
     }
-
-    return apreq_value_to_param(apreq_strtoval(val));
-}
-
-
-APREQ_DECLARE(apr_table_t *) apreq_params(apr_pool_t *pool,
-                                          const apreq_request_t *req)
-{
-    apr_status_t s;
-
-    switch (req->body_status) {
-    case APR_INCOMPLETE:
-    case APR_EINIT:
-        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);
-}
-
-
-static int param_push(void *data, const char *key, const char *val)
-{
-    apr_array_header_t *arr = data;
-    *(apreq_param_t **)apr_array_push(arr) = 
-        apreq_value_to_param(apreq_strtoval(val));
-    return 1;   /* keep going */
-}
-
-
-APREQ_DECLARE(apr_array_header_t *) apreq_params_as_array(apr_pool_t *p,
-                                                          apreq_request_t *req,
-                                                          const char *key)
-{
-    apr_status_t s;
-    apr_array_header_t *arr = apr_array_make(p, apr_table_elts(req->args)->nelts,
-                                             sizeof(apreq_param_t *));
-
-    apr_table_do(param_push, arr, req->args, key, NULL);
-
-    switch (req->body_status) {
-    case APR_INCOMPLETE:
-    case APR_EINIT:
-        do s = apreq_env_read(req->env, APR_BLOCK_READ, APREQ_READ_AHEAD);
-        while (s == APR_INCOMPLETE);
-    }
-
-    if (req->body)
-        apr_table_do(param_push, arr, req->body, key, NULL);
-
-    return arr;
-}
-
-APREQ_DECLARE(const char *) apreq_params_as_string(apr_pool_t *p,
-                                                   apreq_request_t *req,
-                                                   const char *key,
-                                                   apreq_join_t mode)
-{
-    /* Must adjust apreq_param_t pointers to apreq_value_t. */
-#ifdef DEBUG
-    assert(sizeof(apreq_param_t **) == sizeof(apreq_value_t **));
-#endif
-    apr_array_header_t *arr = apreq_params_as_array(p, req, key);
-    apreq_param_t **elt = (apreq_param_t **)arr->elts;
-    apreq_param_t **const end = elt + arr->nelts;
-    if (arr->nelts == 0)
-        return NULL;
-
-    while (elt < end) {
-        *(apreq_value_t **)elt = &(**elt).v;
-        ++elt;
+    else {
+        v->data[0] = 0;
+        v->size    = 0;
     }
-    return apreq_join(p, ", ", arr, mode);
-}
-
-
-APREQ_DECLARE(apreq_param_t *) apreq_decode_param(apr_pool_t *pool, 
-                                                  const char *word,
-                                                  const apr_size_t nlen, 
-                                                  const apr_size_t vlen)
-{
-    apreq_param_t *param;
-    apr_ssize_t size;
-
-    if (nlen == 0)
-        return NULL;
-
-    param = apr_palloc(pool, nlen + vlen + 1 + sizeof *param);
-    param->info = NULL;
-    param->bb = NULL;
-
-    param->v.name = NULL;
-
-    size = apreq_decode(param->v.data, word + nlen + 1, vlen);
-
-    if (size < 0)
-        return NULL;
-
-    param->v.size = size;
-    param->v.name = param->v.data + size + 1;
+    v->name = v->data + v->size + 1;
+    *param = p;
 
-    if (apreq_decode(param->v.data + size + 1, word, nlen) < 0)
-        return NULL;
-
-    return param;
+    return apreq_decode(v->name, &size, word, nlen);
 }
 
 
@@ -273,14 +126,15 @@
             if (qs > start) {
                 apr_size_t vlen = 0;
                 apreq_param_t *param;
+                apr_status_t s;
                 if (nlen == 0)
                     nlen = qs - start;
                 else
                     vlen = qs - start - nlen - 1;
 
-                param = apreq_decode_param(pool, start, nlen, vlen);
-                if (param == NULL)
-                    return APR_EGENERAL;
+                s = apreq_decode_param(&param, pool, start, nlen, vlen);
+                if (s != APR_SUCCESS)
+                    return s;
 
                 apr_table_addn(t, param->v.name, param->v.data);
             }
@@ -296,65 +150,76 @@
     return APR_INCOMPLETE;
 }
 
-APREQ_DECLARE(apr_status_t) apreq_parse_request(apreq_request_t *req, 
-                                                apr_bucket_brigade *bb)
+
+
+
+static int param_push(void *data, const char *key, const char *val)
 {
-    switch (req->body_status) {
-    case APR_EINIT:
-        if (req->parser == NULL) {
-            req->parser = apreq_parser(req->env,NULL);
-            if (req->parser == NULL)
-                return APR_ENOTIMPL;
-        }
-        if (req->body == NULL)
-            req->body = apr_table_make(apreq_env_pool(req->env),APREQ_NELTS);
+    apr_array_header_t *arr = data;
+    *(apreq_param_t **)apr_array_push(arr) = 
+        apreq_value_to_param(val);
+    return 1;   /* keep going */
+}
+
+
+APREQ_DECLARE(apr_array_header_t *) apreq_params_as_array(apr_pool_t *p,
+                                                          const apr_table_t *t,
+                                                          const char *key)
+{
+    apr_array_header_t *arr;
+
+    arr = apr_array_make(p, apr_table_elts(t)->nelts,
+                         sizeof(apreq_param_t *));
 
+    apr_table_do(param_push, arr, t, key, NULL);
+    return arr;
+}
+
+APREQ_DECLARE(const char *) apreq_params_as_string(apr_pool_t *p,
+                                                   const apr_table_t *t,
+                                                   const char *key,
+                                                   apreq_join_t mode)
+{
+    apr_array_header_t *arr = apreq_params_as_array(p, t, key);
+    apreq_param_t **elt = (apreq_param_t **)arr->elts;
+    apreq_param_t **const end = elt + arr->nelts;
+    if (arr->nelts == 0)
+        return NULL;
 
-    case APR_INCOMPLETE:
-        req->body_status = APREQ_RUN_PARSER(req->parser, req->env, 
-                                            req->body, bb);
-    default:
-        return req->body_status;
+    while (elt < end) {
+        *(const apreq_value_t **)elt = &(**elt).v;
+        ++elt;
     }
+    return apreq_join(p, ", ", arr, mode);
 }
 
 
+
 static int upload_push(void *data, const char *key, const char *val)
 {
     apr_table_t *t = data;
-    apreq_param_t *p = apreq_value_to_param(apreq_strtoval(val));
-    if (p->bb)
+    apreq_param_t *p = apreq_value_to_param(val);
+
+    if (p->upload != NULL)
         apr_table_addn(t, key, val);
     return 1;   /* keep going */
 }
 
 
-APREQ_DECLARE(apr_table_t *) apreq_uploads(apr_pool_t *pool,
-                                           const apreq_request_t *req)
+APREQ_DECLARE(const apr_table_t *) apreq_uploads(const apr_table_t *body,
+                                                 apr_pool_t *pool)
 {
-    apr_table_t *t;
-    apr_status_t s;
-
-    switch (req->body_status) {
-    case APR_INCOMPLETE:
-    case APR_EINIT:
-        do s = apreq_env_read(req->env, APR_BLOCK_READ, APREQ_READ_AHEAD);
-        while (s == APR_INCOMPLETE);
-    }
-    if (req->body == NULL)
-        return NULL;
-
-    t = apr_table_make(pool, APREQ_NELTS);
-    /* XXX needs appropriate copy/merge callbacks */
-    apr_table_do(upload_push, t, req->body, NULL);
+    apr_table_t *t = apr_table_make(pool, APREQ_DEFAULT_NELTS);
+    apr_table_do(upload_push, t, body, NULL);
     return t;
 }
 
-static int upload_get(void *data, const char *key, const char *val)
+static int upload_set(void *data, const char *key, const char *val)
 {
-    apreq_param_t *p = apreq_value_to_param(apreq_strtoval(val));
-    apreq_param_t **q = data;
-    if (p->bb) {
+    const apreq_param_t **q = data;
+    apreq_param_t *p = apreq_value_to_param(val);
+
+    if (p->upload != NULL) {
         *q = p;
         return 0; /* upload found, stop */
     }
@@ -363,25 +228,12 @@
 }
 
 
-APREQ_DECLARE(apreq_param_t *) apreq_upload(const apreq_request_t *req,
-                                            const char *key)
+APREQ_DECLARE(const apreq_param_t *) apreq_upload(const apr_table_t *body,
+                                                  const char *name)
 {
-    apreq_param_t *param = NULL;
-    do {
-        apr_status_t s = req->body_status;
-        switch (s) {
-        case APR_INCOMPLETE:
-        case APR_EINIT:
-            s = apreq_env_read(req->env, APR_BLOCK_READ, APREQ_READ_AHEAD);
-
-        default:
-            if (req->body == NULL)
-                return NULL;
-            apr_table_do(upload_get, &param, req->body, key, NULL);
-            if (s != APR_INCOMPLETE)
-                return param;
-        }
-    } while (param == NULL);
-
+    const apreq_param_t *param = NULL;
+    apr_table_do(upload_set, &param, body, name, NULL);
     return param;
 }
+
+

Modified: httpd/apreq/branches/multi-env-unstable/src/apreq_params.h
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/src/apreq_params.h?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/src/apreq_params.h (original)
+++ httpd/apreq/branches/multi-env-unstable/src/apreq_params.h Fri Feb  4 10:27:55 2005
@@ -30,19 +30,29 @@
  * @ingroup libapreq2
  */
 
+
 /** Common data structure for params and file uploads */
 typedef struct apreq_param_t {
-    apr_table_t         *info; /**< header table associated with the param */
-    apr_bucket_brigade  *bb;   /**< brigade to spool upload files */
-    apreq_value_t        v;    /**< underlying name/value/status info */
+    apr_table_t         *info;   /**< header table associated with the param */
+    apr_bucket_brigade  *upload; /**< brigade used to spool upload files */
+    unsigned char        flags;  /**< charsets, taint marks, app-specific bits */
+    const apreq_value_t  v;      /**< underlying name/value/status info */
 } apreq_param_t;
 
-/* These structs are defined below */
-typedef struct apreq_hook_t apreq_hook_t;
-typedef struct apreq_parser_t apreq_parser_t;
+
+/** Upgrades args and body table values to apreq_param_t structs. */
+static APR_INLINE
+apreq_param_t *apreq_value_to_param(const char *val)
+{
+    union { const char *in; char *out; } deconst;
+
+    deconst.in = val;
+    return apreq_attr_to_type(apreq_param_t, v, 
+           apreq_attr_to_type(apreq_value_t, data, deconst.out));
+}
+
 
 /** 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)
 #define apreq_param_value(p)     ((p)->v.data)
 #define apreq_param_info(p)      ((p)->info)
@@ -55,91 +65,6 @@
                                                 const char *val, 
                                                 const apr_size_t vlen);
 
-/** Structure which manages the request data. */
-typedef struct apreq_request_t {
-    apr_table_t        *args;         /**< parsed query-string */
-    apr_table_t        *body;         /**< parsed post data */
-    apreq_parser_t     *parser;       /**< active parser for this request */
-    apreq_env_handle_t *env;          /**< request environment */
-    apr_status_t        args_status;  /**< status of query-string parse */
-    apr_status_t        body_status;  /**< status of post data parse */
-} apreq_request_t;
-
-
-/**
- * Creates an apreq_request_t object.
- * @param env The current request environment.
- * @param qs  The query string.
- * @remark "qs = NULL" has special behavior.  In this case,
- * apreq_request(env,NULL) will attempt to fetch a cached object
- * from the environment via apreq_env_request.  Failing that, it will
- * replace "qs" with the result of apreq_env_query_string(env), 
- * parse that, and store the resulting apreq_request_t object back 
- * within the environment.  This maneuver is designed to both mimimize
- * parsing work and allow the environent to place the parsed POST data in
- * req->body (otherwise the caller may need to do this manually).
- * For details on this, see the environment's documentation for
- * the apreq_env_read function.
- */
-
-APREQ_DECLARE(apreq_request_t *)apreq_request(apreq_env_handle_t *env,
-                                              const char *qs);
-
-
-/**
- * Returns the first parameter value with the desired name,
- * NULL if none found. The name is case-insensitive.
- * @param req The current apreq_request_t object.
- * @param name Nul-terminated search key.  Returns the first table value 
- * if NULL.
- * @return First matching parameter.
- * @remark Also parses the request as necessary.
- */
-APREQ_DECLARE(apreq_param_t *) apreq_param(const apreq_request_t *req, 
-                                           const char *name); 
-
-
-/**
- * Returns a table containing key-value pairs for the full request
- * (args + body).
- * @param p Allocates the returned table.
- * @param req The current apreq_request_t object.
- * @remark Also parses the request if necessary.
- */
-APREQ_DECLARE(apr_table_t *) apreq_params(apr_pool_t *p,
-                                          const apreq_request_t *req);
-
-
-
-/**
- * Returns an array of parameters (apreq_param_t *) matching the given key.
- * The key is case-insensitive.
- * @param p Allocates the returned array.
- * @param req The current apreq_request_t object.
- * @param key Null-terminated search key.  key==NULL fetches all parameters.
- * @remark Also parses the request if necessary.
- */
-APREQ_DECLARE(apr_array_header_t *) apreq_params_as_array(apr_pool_t *p,
-                                                          apreq_request_t *req,
-                                                          const char *key);
-
-/**
- * Returns a ", " -separated string containing all parameters 
- * for the requested key, NULL if none are found.  The key is case-insensitive.
- * @param p Allocates the return string.
- * @param req The current apreq_request_t object.
- * @param key Null-terminated parameter name. key==NULL fetches all values. 
- * @param mode Join type- see apreq_join().
- * @return Returned string is the data attribute of an apreq_value_t,
- *         so it is safe to use in apreq_strlen() and apreq_strtoval().
- * @remark Also parses the request if necessary.
- */
-APREQ_DECLARE(const char *) apreq_params_as_string(apr_pool_t *p,
-                                                   apreq_request_t *req,
-                                                   const char *key,
-                                                   apreq_join_t mode);
-
-
 /**
  * Url-decodes a name=value pair into a param.
  * @param pool  Pool from which the param is allocated.
@@ -150,11 +75,11 @@
  *              exactly one character ('=') which separates the pair.
  *            
  */
-
-APREQ_DECLARE(apreq_param_t *) apreq_decode_param(apr_pool_t *pool, 
-                                                  const char *word,
-                                                  const apr_size_t nlen, 
-                                                  const apr_size_t vlen);
+APREQ_DECLARE(apr_status_t) apreq_decode_param(apreq_param_t **param,
+                                               apr_pool_t *pool, 
+                                               const char *word,
+                                               const apr_size_t nlen, 
+                                               const apr_size_t vlen);
 /**
  * Url-encodes the param into a name-value pair.
  * @param pool Pool which allocates the returned string.
@@ -181,257 +106,59 @@
                                                      apr_table_t *t, 
                                                      const char *qs);
 
+
+
 /**
- * Parse a brigade as incoming POST data.
- * @param req Current request.
- * @param bb  Brigade to parse. See remarks below.
- * @return    APR_INCOMPLETE if the parse is incomplete,
- *            APR_SUCCESS if the parser is finished (saw eos),
- *            APR_ENOTIMPL if no parser is available for this request
- *                         (i.e. unrecognized Content-Type header),
- *            unrecoverable error value otherwise.
+ * Returns an array of parameters (apreq_param_t *) matching the given key.
+ * The key is case-insensitive.
+ * @param p Allocates the returned array.
+ * @param req The current apreq_request_t object.
+ * @param key Null-terminated search key.  key==NULL fetches all parameters.
+ * @remark Also parses the request if necessary.
+ */
+APREQ_DECLARE(apr_array_header_t *) apreq_params_as_array(apr_pool_t *p,
+                                                          const apr_table_t *t,
+                                                          const char *key);
+
+/**
+ * Returns a ", " -separated string containing all parameters 
+ * for the requested key, NULL if none are found.  The key is case-insensitive.
+ * @param p Allocates the return string.
+ * @param req The current apreq_request_t object.
+ * @param key Null-terminated parameter name. key==NULL fetches all values. 
+ * @param mode Join type- see apreq_join().
+ * @return Returned string is the data attribute of an apreq_value_t,
+ *         so it is safe to use in apreq_strlen() and apreq_strtoval().
+ * @remark Also parses the request if necessary.
  */
+APREQ_DECLARE(const char *) apreq_params_as_string(apr_pool_t *p,
+                                                   const apr_table_t *t,
+                                                   const char *key,
+                                                   apreq_join_t mode);
 
-APREQ_DECLARE(apr_status_t)apreq_parse_request(apreq_request_t *req, 
-                                               apr_bucket_brigade *bb);
 /**
- * Returns a table of all params in req->body with non-NULL bucket brigades.
+ * Returns a table of all params in req->body with non-NULL upload brigades.
  * @param pool Pool which allocates the table struct.
  * @param req  Current request.
  * @return Upload table.
  * @remark Will parse the request if necessary.
  */
 
-APREQ_DECLARE(apr_table_t *) apreq_uploads(apr_pool_t *pool,
-                                           const apreq_request_t *req);
+APREQ_DECLARE(const apr_table_t *)
+        apreq_uploads(const apr_table_t *body, apr_pool_t *pool);
 
 /**
  * Returns the first param in req->body which has both param->v.name 
- * matching key and param->bb != NULL.
+ * matching key and param->upload != NULL.
  * @param req The current request.
  * @param key Parameter name. key == NULL returns first upload.
  * @return Corresponding upload, NULL if none found.
  * @remark Will parse the request as necessary.
  */
 
-APREQ_DECLARE(apreq_param_t *) apreq_upload(const apreq_request_t *req,
-                                            const char *key);
-#include "apreq.h"
-
-/** Parser arguments. */
-#define APREQ_PARSER_ARGS  apreq_parser_t *parser,     \
-                           apreq_env_handle_t *env,        \
-                           apr_table_t *t,             \
-                           apr_bucket_brigade *bb
-
-/** Hook arguments */
-#define APREQ_HOOK_ARGS    apreq_hook_t *hook,         \
-                           apreq_env_handle_t *env,        \
-                           apreq_param_t *param,       \
-                           apr_bucket_brigade *bb
+APREQ_DECLARE(const apreq_param_t *)
+        apreq_upload(const apr_table_t *body, const char *name);
 
-typedef apr_status_t (*apreq_parser_function_t)(APREQ_PARSER_ARGS);
-typedef apr_status_t (*apreq_hook_function_t)(APREQ_HOOK_ARGS);
-
-/**
- * Declares a API parser.
- */
-#define APREQ_DECLARE_PARSER(f) APREQ_DECLARE_NONSTD(apr_status_t) \
-                                (f) (APREQ_PARSER_ARGS)
-
-/**
- * Declares an API hook.
- */
-#define APREQ_DECLARE_HOOK(f)   APREQ_DECLARE_NONSTD(apr_status_t) \
-                                (f) (APREQ_HOOK_ARGS)
-
-/**
- * Singly linked list of hooks.
- *
- */
-struct apreq_hook_t {
-    apreq_hook_function_t hook;
-    apreq_hook_t   *next;
-    void           *ctx;
-};
-
-/**
- * Request parser with associated enctype and hooks. 
- *
- */
-struct apreq_parser_t {
-    apreq_parser_function_t parser;
-    const char    *enctype;
-    apreq_hook_t  *hook;
-    void          *ctx;
-};
-
-
-
-
-/**
- * Parse the incoming brigade into a table.  Parsers normally
- * consume all the buckets of the brigade during parsing. However
- * parsers may leave "rejected" data in the brigade, even during a
- * successful parse, so callers may need to clean up the brigade
- * themselves (in particular, rejected buckets should not be 
- * passed back to the parser again).
- * @remark  bb == NULL is valid: the parser should return its 
- * public status: APR_INCOMPLETE, APR_SUCCESS, or an error code.
- */
-#define APREQ_RUN_PARSER(psr,env,t,bb) (psr)->parser(psr,env,t,bb)
-
-/**
- * Run the hook with the current parameter and the incoming 
- * bucket brigade.  The hook may modify the brigade if necessary.
- * Once all hooks have completed, the contents of the brigade will 
- * be added to the parameter's bb attribute.
- * @return APR_SUCCESS on success. All other values represent errors.
- */
-#define APREQ_RUN_HOOK(h,env,param,bb) (h)->hook(h,env,param,bb)
-
-/**
- * Concatenates the brigades, spooling large brigades into
- * a tempfile bucket according to the environment's max_brigade
- * setting- see apreq_env_max_brigade().
- * @param env Environment.
- * @param out Resulting brigade.
- * @param in Brigade to append.
- * @return APR_SUCCESS on success, error code otherwise.
- */
-APREQ_DECLARE(apr_status_t) apreq_brigade_concat(apreq_env_handle_t *env,
-                                                 apr_bucket_brigade *out, 
-                                                 apr_bucket_brigade *in);
-
-
-/**
- * Rfc822 Header parser. It will reject all data
- * after the first CRLF CRLF sequence (an empty line).
- * See #APREQ_RUN_PARSER for more info on rejected data.
- */
-APREQ_DECLARE_PARSER(apreq_parse_headers);
-
-/**
- * Rfc2396 application/x-www-form-urlencoded parser.
- */
-APREQ_DECLARE_PARSER(apreq_parse_urlencoded);
-
-/**
- * Rfc2388 multipart/form-data (and XForms 1.0 multipart/related)
- * parser. It will reject any buckets representing preamble and 
- * postamble text (this is normal behavior, not an error condition).
- * See #APREQ_RUN_PARSER for more info on rejected data.
- */
-APREQ_DECLARE_PARSER(apreq_parse_multipart);
-
-/**
- * Generic parser.  No table entries will be added to
- * the req->body table by this parser.  The parser creates
- * a dummy apreq_param_t to pass to any configured hooks.  If
- * no hooks are configured, the dummy param's bb slot will
- * contain a copy of the request body.  It can be retrieved
- * by casting the parser's ctx pointer to (apreq_param_t **).
- */
-APREQ_DECLARE_PARSER(apreq_parse_generic);
-
-/**
- * apr_xml_parser hook. It will parse until EOS appears.
- * The parsed document isn't available until parsing has
- * completed successfully.  The hook's ctx pointer may 
- * be cast as (apr_xml_doc **) to retrieve the 
- * parsed document.
- */
-APREQ_DECLARE_HOOK(apreq_hook_apr_xml_parser);
-
-/**
- * Construct a parser.
- *
- * @param pool Pool used to allocate the parser.
- * @param enctype Content-type that this parser can deal with.
- * @param parser The parser function.
- * @param hook Hooks to asssociate this parser with.
- * @param ctx Parser's internal scratch pad.
- * @return New parser.
- */
-APREQ_DECLARE(apreq_parser_t *)
-        apreq_make_parser(apr_pool_t *pool,
-                          const char *enctype,
-                          apreq_parser_function_t parser,
-                          apreq_hook_t *hook,
-                          void *ctx);
-
-/**
- * Construct a hook.
- *
- * @param pool used to allocate the hook.
- * @param hook The hook function.
- * @param next List of other hooks for this hook to call on.
- * @param ctx Hook's internal scratch pad.
- * @return New hook.
- */
-APREQ_DECLARE(apreq_hook_t *)
-        apreq_make_hook(apr_pool_t *pool,
-                        apreq_hook_function_t hook,
-                        apreq_hook_t *next,
-                        void *ctx);
-
-
-/**
- * Add a new hook to the end of the parser's hook list.
- *
- * @param p Parser.
- * @param h Hook to append.
- */
-APREQ_DECLARE(void) apreq_add_hook(apreq_parser_t *p, 
-                                   apreq_hook_t *h);
-
-
-/**
- * Create the default parser associated with the
- * current request's Content-Type (if possible).
- * @param env The current environment.
- * @param hook Hook(s) to add to the parser.
- * @return New parser, NULL if the Content-Type is
- * unrecognized.
- *
- * @param env The current environment.
- * @param hook Additional hooks to supply the parser with.
- * @return The parser; NULL if the environment's
- * Content-Type is unrecognized.
- */
-APREQ_DECLARE(apreq_parser_t *)apreq_parser(apreq_env_handle_t *env,
-                                            apreq_hook_t *hook);
-
-
-/**
- * Register a new parsing function with a MIME enctype.
- * Registered parsers are added to apreq_parser()'s
- * internal lookup table.
- *
- * @param enctype The MIME type.
- * @param parser  The function to use during parsing. Setting
- *                parser == NULL will remove an existing parser.
- * @remark This is not a thread-safe operation, so applications 
- * should only call this during process startup,
- * or within a request-thread mutex.
- */
-
-APREQ_DECLARE(void) apreq_register_parser(const char *enctype, 
-                                          apreq_parser_function_t parser);
-
-
-/**
- * Returns APR_EGENERAL.  Effectively disables mfd parser
- * if a file-upload field is present.
- *
- */
-APREQ_DECLARE_HOOK(apreq_hook_disable_uploads);
-
-/**
- * Calls apr_brigade_cleanup on the incoming brigade
- * after passing the brigade to any subsequent hooks.
- */
-APREQ_DECLARE_HOOK(apreq_hook_discard_brigade);
 
 #ifdef __cplusplus
 }



Mime
View raw message