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 [2/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.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/src/apreq.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/src/apreq.c (original)
+++ httpd/apreq/branches/multi-env-unstable/src/apreq.c Fri Feb  4 10:27:55 2005
@@ -15,11 +15,10 @@
 */
 
 #include "apreq.h"
-#include "apreq_env.h"
 #include "apr_time.h"
 #include "apr_strings.h"
 #include "apr_lib.h"
-
+#include <assert.h>
 #define MIN(a,b) ( (a) < (b) ? (a) : (b) )
 #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
 
@@ -30,70 +29,22 @@
                                                const apr_size_t vlen)
 {
     apreq_value_t *v = apr_palloc(p, vlen + nlen + 1 + sizeof *v);
-    char *writable_name;
 
     if (v == NULL)
         return NULL;
 
-    v->size = vlen;
     memcpy(v->data, val, vlen);
     v->data[vlen] = 0;
+    v->size = vlen;
 
-    v->name = writable_name = v->data + vlen + 1;
-    memcpy(writable_name, name, nlen);
-    writable_name[nlen] = 0;
+    v->name = v->data + vlen + 1;
+    memcpy(v->name, name, nlen);
+    v->name[nlen] = 0;
 
-    v->flags = 0;
     return v;
 }
 
 
-APREQ_DECLARE(apreq_value_t *)apreq_copy_value(apr_pool_t *p, 
-                                               const apreq_value_t *val)
-{
-    apreq_value_t *v;
-    if (val == NULL)
-        return NULL;
-
-    v = apr_palloc(p, val->size + sizeof *v);
-
-    *v = *val;
-
-    if ( v->size > 0 )
-        memcpy(v->data, val->data, v->size);
-
-    return v;
-}
-
-apreq_value_t * apreq_merge_values(apr_pool_t *p,
-                                   const apr_array_header_t *arr)
-{
-    apreq_value_t *a = *(apreq_value_t **)(arr->elts);
-    apreq_value_t *v = apreq_char_to_value(apreq_deconst(apreq_join(p, ", ", arr, APREQ_JOIN_AS_IS)));
-    if (arr->nelts > 0)
-        v->name = a->name;
-    return v;
-}
-
-APREQ_DECLARE(const char *)apreq_enctype(apreq_env_handle_t *env)
-{
-    char *enctype;
-    const char *ct = apreq_env_content_type(env);
-
-    if (ct == NULL)
-        return NULL;
-    else {
-        const char *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,
                                           const apreq_expires_t type)
 {
@@ -233,7 +184,7 @@
     return hay ? hay - begin : -1;
 }
 
-static const char c2x_table[] = "0123456789abcdef";
+static const char c2x_table[] = "0123456789abcdef"; /* XXX uppercase a-f ? */
 static APR_INLINE char x2c(const char *what)
 {
     register char digit;
@@ -346,7 +297,7 @@
                 *slen = s - src;
                 if (s + 5 < end || (s + 2 < end && s[1] != 'u' && s[1] != 'U')) {
                     *d = 0;
-                    return APR_EGENERAL;
+                    return APREQ_ERROR_BADSEQ;
                 }
                 memcpy(d, s, end - s);
                 d[end - s] = 0;
@@ -358,7 +309,7 @@
             *d = 0;
             *dlen = d - start;
             *slen = s - src;
-            return APR_BADCH;
+            return APREQ_ERROR_BADCHAR;
 
         default:
             *d = *s;
@@ -371,33 +322,36 @@
     return APR_SUCCESS;
 }
 
-APREQ_DECLARE(apr_ssize_t) apreq_decode(char *d, const char *s, 
-                                        apr_size_t slen)
+APREQ_DECLARE(apr_status_t) apreq_decode(char *d, apr_size_t *dlen,
+                                         const char *s, apr_size_t slen)
 {
-    apr_size_t dlen;
+    apr_size_t len = 0;
     const char *end = s + slen;
-
-    if (s == NULL || d == NULL)
-        return -1;
+    apr_status_t rv;
 
     if (s == (const char *)d) {     /* optimize for src = dest case */
         for ( ; d < end; ++d) {
             if (*d == '%' || *d == '+')
                 break;
-            else if (*d == 0)
-                return (const char*)d - s;
+            else if (*d == 0) {
+                *dlen = (const char *)d - s;
+                return APREQ_ERROR_BADCHAR;
+            }
         }
+        len = (const char *)d - s;
         s = (const char *)d;
+        slen -= len;
     }
 
-    switch (url_decode(d, &dlen, s, &slen)) {
-    case APR_SUCCESS:
-        return dlen;
-    case APR_INCOMPLETE:
-        return -2;
-    default:
-        return -1;
-    }
+    /*XXX fooo
+    memcpy(d,s,slen);
+    d[slen] = 0;
+    *dlen = slen;
+    return APR_SUCCESS;
+    */
+    rv = url_decode(d, dlen, s, &slen);
+    *dlen += len;
+    return rv;
 }
 
 
@@ -435,7 +389,7 @@
             goto start_decodev;
 
         default:
-            *dlen = len;
+            *dlen += len;
             return status;
         }
     }
@@ -582,9 +536,7 @@
         break;
 
     case APREQ_JOIN_DECODE:
-        len = apreq_decode(d, a[0]->data, a[0]->size);
-
-        if (len < 0)
+        if (apreq_decode(d, &len, a[0]->data, a[0]->size))
             return NULL;
         else
             d += len;
@@ -593,9 +545,7 @@
             memcpy(d, sep, slen);
             d += slen;
 
-            len = apreq_decode(d, a[j]->data, a[j]->size);
-
-            if (len < 0)
+            if (apreq_decode(d, &len, a[j]->data, a[j]->size))
                 return NULL;
             else
                 d += len;
@@ -636,8 +586,8 @@
     return rv->data;
 }
 
-APREQ_DECLARE(char *) apreq_escape(apr_pool_t *p, 
-                                   const char *src, const apr_size_t slen)
+APREQ_DECLARE(char *) apreq_escape(apr_pool_t *p,
+                                         const char *src, const apr_size_t slen)
 {
     apreq_value_t *rv;
     if (src == NULL)
@@ -649,9 +599,15 @@
     return rv->data;
 }
 
+APR_INLINE
 APREQ_DECLARE(apr_ssize_t) apreq_unescape(char *str)
 {
-    return apreq_decode(str,str,strlen(str));
+    apr_size_t len;
+    apr_status_t rv = apreq_decode(str,&len,str,strlen(str));
+    if (rv == APR_SUCCESS)
+        return (apr_ssize_t)len;
+    else
+        return -1;
 }
 
 APR_INLINE
@@ -704,7 +660,7 @@
                                                  apr_off_t *wlen,
                                                  apr_bucket_brigade *bb)
 {
-    struct iovec v[APREQ_NELTS];
+    struct iovec v[APREQ_DEFAULT_NELTS];
     apr_status_t s;
     apr_bucket *e;
     int n = 0;
@@ -714,7 +670,7 @@
          e = APR_BUCKET_NEXT(e)) 
     {
         apr_size_t len;
-        if (n == APREQ_NELTS) {
+        if (n == APREQ_DEFAULT_NELTS) {
             s = apreq_fwritev(f, v, &n, &len);
             if (s != APR_SUCCESS)
                 return s;
@@ -802,19 +758,6 @@
 }
 
 
-APREQ_DECLARE(apr_file_t *)apreq_brigade_spoolfile(apr_bucket_brigade *bb)
-{
-    apr_bucket *last = APR_BRIGADE_LAST(bb);
-    apr_bucket_file *f;
-    if (APR_BUCKET_IS_FILE(last)) {
-        f = last->data;
-        return f->fd;
-    }
-    else
-        return NULL;
-}
-
-
 APREQ_DECLARE(apr_status_t)
     apreq_header_attribute(const char *hdr,
                            const char *name, const apr_size_t nlen,
@@ -822,6 +765,10 @@
 {
     const char *key, *v;
 
+    /*Must ensure first char isn't '=', so we can safely backstep. */
+    while (*hdr == '=')
+        ++hdr;
+
     while ((key = strchr(hdr, '=')) != NULL) {
 
         v = key + 1;
@@ -849,8 +796,8 @@
                     break;
                 }
             }
-            /* bad attr: no terminating quote found */
-            return APR_EGENERAL;
+            /* bad token: no terminating quote found */
+            return APREQ_ERROR_BADTOKEN;
         }
         else {
             /* value is not wrapped in quotes */
@@ -892,4 +839,156 @@
     }
 
     return APR_NOTFOUND;
+}
+
+/* XXX: find a way to remove these spool_bucket_* functions.
+ * The only reason joes uses them here, is because this assignment
+ *
+ *     static const apr_bucket_type_t spool_bucket = apr_bucket_type_file;
+ *   
+ * is (I think) illegal in C89, even though the RHS is declared constant.
+ * Not sure its ok in C99 either.
+ */
+
+#define BUCKET_IS_SPOOL(e) ((e)->type == &spool_bucket)
+#define FILE_BUCKET_LIMIT      ((apr_size_t)-1 - 1)
+
+static
+void spool_bucket_destroy(void *data)
+{
+    apr_bucket_type_file.destroy(data);
+}
+
+static
+apr_status_t spool_bucket_read(apr_bucket *e, const char **str,
+                                   apr_size_t *len, apr_read_type_e block)
+{
+    return apr_bucket_type_file.read(e, str, len, block);
+}
+
+static
+apr_status_t spool_bucket_setaside(apr_bucket *data, apr_pool_t *reqpool)
+{
+    return apr_bucket_type_file.setaside(data, reqpool);
+}
+
+/* XXX: all we really need to do here is make a local copy of
+ * apr_bucket_type_file; i.e.
+ *
+ *    static const apr_bucket_type_t spool_bucket = apr_bucket_type_file;
+ */
+static const apr_bucket_type_t spool_bucket = {
+    "APREQ_SPOOL_BUCKET", 5, APR_BUCKET_DATA,
+    spool_bucket_destroy,
+    spool_bucket_read,
+    spool_bucket_setaside,
+    apr_bucket_shared_split,
+    apr_bucket_shared_copy
+};
+
+APREQ_DECLARE(apr_status_t) apreq_brigade_concat(apr_pool_t *pool,
+                                                 const char *temp_dir,
+                                                 apr_size_t heap_limit,
+                                                 apr_bucket_brigade *out, 
+                                                 apr_bucket_brigade *in)
+{
+    apr_status_t s;
+    apr_bucket_file *f;
+    apr_off_t wlen;
+    apr_file_t *file;
+    apr_off_t in_len, out_len;
+    apr_bucket *last_in, *last_out;
+
+    last_out = APR_BRIGADE_LAST(out);
+
+    if (APR_BUCKET_IS_EOS(last_out))
+        return APR_EOF;
+
+    s = apr_brigade_length(out, 0, &out_len);
+    if (s != APR_SUCCESS)
+        return s;
+
+    /* This cast, when out_len = -1, is intentional */
+    if ((apr_uint64_t)out_len < heap_limit) {
+
+        s = apr_brigade_length(in, 0, &in_len);
+        if (s != APR_SUCCESS)
+            return s;
+
+        /* This cast, when in_len = -1, is intentional */
+        if ((apr_uint64_t)in_len < heap_limit - out_len) {
+            APR_BRIGADE_CONCAT(out, in);
+            return APR_SUCCESS;
+        }
+    }
+    
+    if (!BUCKET_IS_SPOOL(last_out)) {
+
+        s = apreq_file_mktemp(&file, pool, temp_dir);
+        if (s != APR_SUCCESS)
+            return s;
+
+        /* This cast, when out_len = -1, is intentional */
+        if ((apr_uint64_t)out_len < heap_limit)
+            s = apreq_brigade_fwrite(file, &wlen, out);
+
+        if (s != APR_SUCCESS)
+            return s;
+
+        last_out = apr_bucket_file_create(file, wlen, 0, 
+                                          out->p, out->bucket_alloc);
+        last_out->type = &spool_bucket;
+        APR_BRIGADE_INSERT_TAIL(out, last_out);
+        f = last_out->data;
+    }
+    else {
+        f = last_out->data;
+        /* Need to seek here, just in case our spool bucket 
+         * was read from between apreq_brigade_concat calls. 
+         */
+        wlen = last_out->start + last_out->length;
+        s = apr_file_seek(f->fd, APR_SET, &wlen);
+        if (s != APR_SUCCESS)
+            return s;
+    }
+
+    last_in = APR_BRIGADE_LAST(in);
+
+    if (APR_BUCKET_IS_EOS(last_in))
+        APR_BUCKET_REMOVE(last_in);
+
+    s = apreq_brigade_fwrite(f->fd, &wlen, in);
+
+    if (s == APR_SUCCESS) {
+
+        /* We have to deal with the possibility that the new 
+         * data may be too large to be represented by a single
+         * temp_file bucket.
+         */
+
+        while ((apr_uint64_t)wlen > FILE_BUCKET_LIMIT - last_out->length) {
+            apr_bucket *e;
+
+            apr_bucket_copy(last_out, &e);
+            e->length = 0;
+            e->start = last_out->start + FILE_BUCKET_LIMIT;
+            wlen -= FILE_BUCKET_LIMIT - last_out->length;
+            last_out->length = FILE_BUCKET_LIMIT;
+            last_out->type = &apr_bucket_type_file;
+
+            APR_BRIGADE_INSERT_TAIL(out, e);
+            last_out = e;
+        }
+
+        last_out->length += wlen;
+
+        if (APR_BUCKET_IS_EOS(last_in))
+            APR_BRIGADE_INSERT_TAIL(out, last_in);
+
+    }
+    else if (APR_BUCKET_IS_EOS(last_in))
+        APR_BRIGADE_INSERT_TAIL(in, last_in);
+
+    apr_brigade_cleanup(in);
+    return s;
 }

Modified: httpd/apreq/branches/multi-env-unstable/src/apreq.h
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/src/apreq.h?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/src/apreq.h (original)
+++ httpd/apreq/branches/multi-env-unstable/src/apreq.h Fri Feb  4 10:27:55 2005
@@ -49,67 +49,62 @@
 #define APREQ_DECLARE_DATA              __declspec(dllexport)
 #endif
 
-#define APREQ_URL_ENCTYPE               "application/x-www-form-urlencoded"
-#define APREQ_MFD_ENCTYPE               "multipart/form-data"
-#define APREQ_XML_ENCTYPE               "application/xml"
 
-#define APREQ_NELTS                     8
-#define APREQ_READ_AHEAD                (64 * 1024)
 /**
+ * Commong Defaults.
  * Maximum amount of heap space a brigade may use before switching to file
  * buckets
 */
-#define APREQ_MAX_BRIGADE_LEN           (256 * 1024) 
-                     
-
-/** @brief libapreq's pre-extensible string type */
-typedef struct apreq_value_t {
-    const char    *name;    /**< value's name */
-    apr_size_t     size;    /**< Size of data.*/
-    unsigned char  flags;   /**< reserved (for future charset support) */
-    char           data[1]; /**< Actual data bytes.*/
-} apreq_value_t;
-
-typedef apreq_value_t *(apreq_value_merge_t)(apr_pool_t *p,
-                                             const apr_array_header_t *a);
-typedef apreq_value_t *(apreq_value_copy_t)(apr_pool_t *p,
-                                            const apreq_value_t *v);
 
-
-#define apreq_attr_to_type(T,A,P) ( (T*) ((char*)(P)-offsetof(T,A)) )
+#define APREQ_DEFAULT_READ_BLOCK_SIZE   (64  * 1024)
+#define APREQ_DEFAULT_READ_LIMIT        (64 * 1024 * 1024)
+#define APREQ_DEFAULT_BRIGADE_LIMIT     (256 * 1024)
+#define APREQ_DEFAULT_NELTS              8
 
 /**
- * Converts (char *) to (apreq_value_t *).  The char * is assumed
- * to point at the data attribute of an apreq_value_t struct.
+ * Beginning work on error-codes ...
+ *
  *
- * @param ptr   points at the data field of an apreq_value_t struct.
  */
+#ifndef APR_EBADARG
+#define APR_EBADARG                APR_BADARG   /* apr's unfixed booboo */
+#endif
+
+/* 0's: generic error status codes */
+#define APREQ_ERROR_GENERAL        APR_OS_START_USERERR
+#define APREQ_ERROR_INTERRUPT      APREQ_ERROR_GENERAL + 1
+
+/* 10's: malformed input */
+#define APREQ_ERROR_NODATA         APREQ_ERROR_GENERAL + 10
+#define APREQ_ERROR_BADSEQ         APREQ_ERROR_GENERAL + 11
+#define APREQ_ERROR_BADCHAR        APREQ_ERROR_GENERAL + 12
+#define APREQ_ERROR_BADTOKEN       APREQ_ERROR_GENERAL + 13
+#define APREQ_ERROR_NOTOKEN        APREQ_ERROR_GENERAL + 14
+#define APREQ_ERROR_BADATTR        APREQ_ERROR_GENERAL + 15
+#define APREQ_ERROR_BADHEADER      APREQ_ERROR_GENERAL + 16
+#define APREQ_ERROR_NOHEADER       APREQ_ERROR_GENERAL + 17
+
+/* 20's: misconfiguration */
+#define APREQ_ERROR_CONFLICT       APREQ_ERROR_GENERAL + 20
+#define APREQ_ERROR_NOPARSER       APREQ_ERROR_GENERAL + 21
+
+
+/* 30's: limit violations */
+#define APREQ_ERROR_OVERLIMIT      APREQ_ERROR_GENERAL + 30
+#define APREQ_ERROR_UNDERLIMIT     APREQ_ERROR_GENERAL + 31
 
-#define apreq_char_to_value(ptr)  apreq_attr_to_type(apreq_value_t, data, ptr)
 
-/** convert a const pointer into a non-const. WARNING: this is
-    dangerous. Use only if you really know what you're doing. Only for
-    Dirty Hacks (TM) */
-static APR_INLINE void *apreq_deconst(const void *p) {
-    /* go around the gcc warning */
-    /* FIXME: does this work on all platforms? */
-    long v = (long)p;
-    return (void*)v;
-}
 
-static APR_INLINE apreq_value_t *apreq_strtoval(const char *name) {
-    return (apreq_value_t*)apreq_char_to_value(apreq_deconst(name));
-}
 
-/**
- * Computes the length of the string, but unlike strlen(),
- * it permits embedded null characters.
- *
- * @param ptr  points at the data field of an apreq_value_t struct.
- * 
- */
+/** @brief libapreq's pre-extensible string type */
+typedef struct apreq_value_t {
+    char             *name;    /**< value name */
+    apr_size_t        size;    /**< value length (in bytes) */
+    char              data[1]; /**< value data  */
+} apreq_value_t;
+
 
-#define apreq_strlen(ptr) (apreq_strtoval(ptr)->size)
+#define apreq_attr_to_type(T,A,P) ( (T*) ((char*)(P)-offsetof(T,A)) )
 
 /**
  * Construcs an apreq_value_t from the name/value info
@@ -130,37 +125,6 @@
                                                 const char *val, 
                                                 const apr_size_t vlen);
 
-/**
- * Makes a pool-allocated copy of the value.
- * @param p  Pool.
- * @param val Original value to copy.
- */
-APREQ_DECLARE(apreq_value_t *) apreq_copy_value(apr_pool_t *p, 
-                                                const apreq_value_t *val);
-
-/**
- * Merges an array of values into one.
- * @param p   Pool from which the new value is generated.
- * @param arr Array of apr_value_t *.
- */
-apreq_value_t * apreq_merge_values(apr_pool_t *p, 
-                                   const apr_array_header_t *arr);
-
-/**
- * An apreq environment, associated with an env module. The structure
- * may have variable size, because the module may append its own data
- * structures after it.
- */
-typedef struct apreq_env_handle_t {
-    const struct apreq_env_module_t *module;
-} apreq_env_handle_t;
-
-/**
- * Fetches the enctype from the environment.
- * @param env Environment.
- */
-APREQ_DECLARE(const char *)apreq_enctype(apreq_env_handle_t *env);
-
 /** @enum apreq_join_t Join type */
 typedef enum { 
     APREQ_JOIN_AS_IS,      /**< Join the strings without modification */
@@ -175,8 +139,7 @@
  * @param sep  String that is inserted between the joined values.
  * @param arr  Array of values.
  * @param mode Join type- see apreq_join_t.
- * @remark     Return string can be upgraded to an apreq_value_t 
- *             with apreq_stroval.
+ * @remark     Return string can be upgraded to an apreq_value_t.
  */
 APREQ_DECLARE(const char *) apreq_join(apr_pool_t *p, 
                                        const char *sep, 
@@ -214,8 +177,8 @@
  *
  */
 APREQ_DECLARE(apr_ssize_t) apreq_index(const char* hay, apr_size_t hlen, 
-                        const char* ndl, apr_size_t nlen, 
-                        const apreq_match_t type);
+                                       const char* ndl, apr_size_t nlen, 
+                                       const apreq_match_t type);
 /**
  * Places a quoted copy of src into dest.  Embedded quotes are escaped with a
  * backslash ('\').
@@ -257,12 +220,14 @@
  * Url-decodes a string.
  * @param dest Location of url-encoded result string. Caller must ensure dest is
  *             large enough to hold the encoded string and trailing null character.
+ * @param dlen points to resultant length of url-decoded string in dest
  * @param src  Original string.
  * @param slen Length of original string.
- * @return Length of url-decoded string in dest, or < 0 on decoding (bad data) error.
+ * @return APR_SUCCESS, error otherwise.
  */
 
-APREQ_DECLARE(apr_ssize_t) apreq_decode(char *dest, const char *src, apr_size_t slen);
+APREQ_DECLARE(apr_status_t) apreq_decode(char *dest, apr_size_t *dlen,
+                                         const char *src, apr_size_t slen);
 
 
 /**
@@ -372,22 +337,14 @@
                                               const char *path);
 
 /**
- * Gets the spoolfile associated to a brigade, if any.
- * @param bb Brigade, usually associated to a file upload (apreq_param_t).
- * @return If the last bucket in the brigade is a file bucket,
- *         this function will return its associated file.  Otherwise,
- *         this function returns NULL.
- */
-
-APREQ_DECLARE(apr_file_t *) apreq_brigade_spoolfile(apr_bucket_brigade *bb);
-
-/**
  * Set aside all buckets in the brigade.
  * @param bb Brigade.
  * @param p  Setaside buckets into this pool.
  */
 
-static APR_INLINE void APREQ_BRIGADE_SETASIDE(apr_bucket_brigade *bb, apr_pool_t *p) {
+static APR_INLINE void
+APREQ_BRIGADE_SETASIDE(apr_bucket_brigade *bb, apr_pool_t *p)
+{
     apr_bucket *e;
     for (e = APR_BRIGADE_FIRST(bb); e != APR_BRIGADE_SENTINEL(bb);
          e = APR_BUCKET_NEXT(e))
@@ -429,6 +386,25 @@
          apreq_header_attribute(const char *hdr,
                                 const char *name, const apr_size_t nlen,
                                 const char **val, apr_size_t *vlen);
+
+
+/**
+ * Concatenates the brigades, spooling large brigades into
+ * a tempfile bucket according to the environment's max_brigade
+ * setting- see apreq_env_max_brigade().
+ * @param pool           Pool for creating a tempfile bucket.
+ * @param temp_dir       Directory for tempfile creation.
+ * @param brigade_limit  If out's length would exceed this value, 
+ *                       the appended buckets get written to a tempfile.  
+ * @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(apr_pool_t *pool,
+                                                 const char *temp_dir,
+                                                 apr_size_t brigade_limit,
+                                                 apr_bucket_brigade *out, 
+                                                 apr_bucket_brigade *in);
 
 
 #ifdef __cplusplus

Modified: httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.c (original)
+++ httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.c Fri Feb  4 10:27:55 2005
@@ -15,7 +15,6 @@
 */
 
 #include "apreq_cookie.h"
-#include "apreq_env.h"
 #include "apr_strings.h"
 #include "apr_lib.h"
 #include "apr_date.h"
@@ -24,22 +23,9 @@
 #define NETSCAPE APREQ_COOKIE_VERSION_NETSCAPE
 #define DEFAULT  APREQ_COOKIE_VERSION_DEFAULT
 
-APREQ_DECLARE(apreq_cookie_t *) apreq_cookie(const apreq_jar_t *jar, 
-                                             const char *name)
-{
-    const char *val = apr_table_get(jar->cookies, name);
-    if (val == NULL)
-        return NULL;
-    return apreq_value_to_cookie(apreq_char_to_value(apreq_deconst(val)));
-}
-
-APREQ_DECLARE(void) apreq_jar_add(apreq_jar_t *jar, 
-                                  const apreq_cookie_t *c)
-{
-    apr_table_addn(jar->cookies,
-                   c->v.name,c->v.data);
-}
+#define ADD_COOKIE(j,c) apr_table_addn(j, c->v.name, c->v.data)
 
+ 
 APREQ_DECLARE(void) apreq_cookie_expires(apreq_cookie_t *c, 
                                          const char *time_str)
 {
@@ -59,40 +45,13 @@
     }
 }
 
-static int has_rfc_cookie(void *ctx, const char *key, const char *val)
-{
-    const apreq_cookie_t *c = apreq_value_to_cookie(apreq_char_to_value(apreq_deconst(val)));
-
-    return c->version == NETSCAPE; /* 0 -> non-netscape cookie found, stop.
-                                      1 -> not found, keep going. */
-}
-
-APREQ_DECLARE(apreq_cookie_version_t) apreq_ua_cookie_version(apreq_env_handle_t *env)
-{
-    if (apreq_env_cookie2(env) == NULL) {
-        apreq_jar_t *j = apreq_jar(env, NULL);
-
-        if (j == NULL || apreq_jar_nelts(j) == 0) 
-            return NETSCAPE;
-
-        else if (apr_table_do(has_rfc_cookie, NULL, j->cookies, NULL) == 1)
-            return NETSCAPE;
-
-        else
-            return RFC;
-    }
-    else
-        return RFC;
-}
-
-
 APREQ_DECLARE(apr_status_t) 
     apreq_cookie_attr(apr_pool_t *p, apreq_cookie_t *c, 
                       const char *attr, apr_size_t alen,
                       const char *val, apr_size_t vlen)
 {
     if (alen < 2)
-        return APR_EGENERAL;
+        return APR_EBADARG;
 
     if ( attr[0] ==  '-' || attr[0] == '$' ) {
         ++attr;
@@ -101,14 +60,16 @@
 
     switch (apr_tolower(*attr)) {
 
-    case 'n': /* name */
-        c->v.name = apr_pstrmemdup(p,val,vlen);
-        return APR_SUCCESS;
+    case 'n': /* name is not an attr */
+        return APR_ENOTIMPL;
+
+    case 'v': /* version; value is not an attr */
+        if (alen == 5 && strncasecmp(attr,"value", 5) == 0)
+            return APR_ENOTIMPL;
 
-    case 'v': /* version */
         while (!apr_isdigit(*val)) {
             if (vlen == 0)
-                return APR_EGENERAL;
+                return APREQ_ERROR_BADSEQ;
             ++val;
             --vlen;
         }
@@ -161,14 +122,25 @@
                                   const char *name, const apr_size_t nlen,
                                   const char *value, const apr_size_t vlen)
 {
-    apreq_cookie_t *c = apr_palloc(p, vlen + sizeof *c);
-    apreq_value_t *v = &c->v;
+    apreq_cookie_t *c;
+    apreq_value_t *v;
+
+    c = apr_palloc(p, nlen + vlen + 1 + sizeof *c);
+
+    if (c == NULL || nlen == 0)
+        return NULL;
+
+    *(const apreq_value_t **)&v = &c->v;
 
     v->size = vlen;
-    v->name = apr_pstrmemdup(p, name, nlen);
+
     memcpy(v->data, value, vlen);
     v->data[vlen] = 0;
-    
+
+    v->name = v->data + vlen + 1;
+    memcpy (v->name, name, nlen);
+    v->name[nlen] = 0;
+
     c->version = DEFAULT;
 
     /* session cookie is the default */
@@ -200,7 +172,7 @@
     key = strchr(hdr, '=');
 
     if (key == NULL)
-        return APR_NOTFOUND;
+        return APREQ_ERROR_NOTOKEN;
 
     val = key + 1;
 
@@ -254,7 +226,7 @@
             }
         }
         /* bad attr: no terminating quote found */
-        return APR_EGENERAL;
+        return APREQ_ERROR_BADCHAR;
     }
     else {
         /* value is not wrapped in quotes */
@@ -282,55 +254,13 @@
 }
 
 
-APREQ_DECLARE(apreq_jar_t *) apreq_jar(apreq_env_handle_t *env,
-                                       const char *hdr)
-{
-    apr_pool_t *p = apreq_env_pool(env);
 
-    apreq_cookie_version_t version;
-    apreq_jar_t *j = NULL;
+APREQ_DECLARE(apr_status_t)apreq_parse_cookie_header(apr_pool_t *p,
+                                                     apr_table_t *j,
+                                                     const char *hdr)
+{
     apreq_cookie_t *c;
-
-    const char *origin;
-    const char *name, *value; 
-    apr_size_t nlen, vlen;
-
-    /* initialize jar */
-    
-    if (hdr == NULL) {
-        /* use the environment's cookie data */
-
-        j = apreq_env_jar(env, NULL);
-        if ( j != NULL )
-            return j;
-
-        j = apr_palloc(p, sizeof *j);
-        j->env = env;
-        j->cookies = apr_table_make(p, APREQ_NELTS);
-        j->status = APR_SUCCESS;
-
-        hdr = apreq_env_cookie(env);
-
-        /* XXX: potential race condition here 
-           between env_jar fetch and env_jar set.  */
-
-        apreq_env_jar(env,j);
-
-        if (hdr == NULL)
-            return j;
-    }
-    else {
-        j = apr_palloc(p, sizeof *j);
-        j->env = env;
-        j->cookies = apr_table_make(p, APREQ_NELTS);
-        j->status = APR_SUCCESS;
-    }
-
-    origin = hdr;
-
-    apreq_log(APREQ_DEBUG 0, env, "parsing cookie data: %s", hdr);
-
-    /* parse data */
+    apreq_cookie_version_t version;
 
  parse_cookie_header:
 
@@ -350,6 +280,8 @@
 
     for (;;) {
         apr_status_t status;
+        const char *name, *value;
+        apr_size_t nlen, vlen;
 
         while (*hdr == ';' || apr_isspace(*hdr))
             ++hdr;
@@ -357,91 +289,64 @@
         switch (*hdr) {
 
         case 0:
-            /* this is the normal exit point for apreq_jar */
+            /* this is the normal exit point */
             if (c != NULL) {
-                apreq_log(APREQ_DEBUG j->status, env, 
-                          "adding cookie: %s => %s", c->v.name, c->v.data);
-                apreq_add_cookie(j, c);
+                ADD_COOKIE(j, c);
             }
-            return j;
+            return APR_SUCCESS;
 
         case ',':
             ++hdr;
             if (c != NULL) {
-                apreq_log(APREQ_DEBUG j->status, env, 
-                          "adding cookie: %s => %s", c->v.name, c->v.data);
-                apreq_add_cookie(j, c);
+                ADD_COOKIE(j, c);
             }
             goto parse_cookie_header;
 
         case '$':
             if (c == NULL) {
-                j->status = APR_EGENERAL;
-                apreq_log(APREQ_ERROR j->status, env,
-                      "Saw RFC attribute, was expecting NAME=VALUE cookie pair: %s",
-                          hdr);
-                return j;
+                return APREQ_ERROR_BADSEQ;
             }
             else if (version == NETSCAPE) {
-                j->status = APR_EGENERAL;
-                apreq_log(APREQ_ERROR j->status, env, 
-                          "Saw RFC attribute in a Netscape Cookie header: %s", 
-                          hdr);
-                return j;
+                return APREQ_ERROR_CONFLICT;
             }
 
             ++hdr;
             status = get_pair(p, &hdr, &name, &nlen, &value, &vlen, 1);
-            if (status != APR_SUCCESS) {
-                j->status = status;
-                apreq_log(APREQ_ERROR status, env,
-                              "Bad RFC attribute: %s",
-                           apr_pstrmemdup(p, name, hdr-name));
-                return j;
-            }
+            if (status != APR_SUCCESS)
+                return status;
 
             status = apreq_cookie_attr(p, c, name, nlen, value, vlen);
+
             switch (status) {
             case APR_ENOTIMPL:
-                apreq_log(APREQ_WARN status, env, 
-                          "Skipping unrecognized RFC attribute pair: %s",
-                           apr_pstrmemdup(p, name, hdr-name));
-                /* fall through */
+                /* XXX: skip unrecognized attr?  Not really correct,
+                   but for now, just fall through */
+
             case APR_SUCCESS:
                 break;
             default:
-                j->status = status;
-                apreq_log(APREQ_ERROR status, env,
-                          "Bad RFC attribute pair: %s",
-                           apr_pstrmemdup(p, name, hdr-name));
-                return j;
+                return status;
             }
 
             break;
 
         default:
             if (c != NULL) {
-                apreq_log(APREQ_DEBUG j->status, env, 
-                          "adding cookie: %s => %s", c->v.name, c->v.data);
-                apreq_add_cookie(j, c);
+                ADD_COOKIE(j, c);
             }
 
             status = get_pair(p, &hdr, &name, &nlen, &value, &vlen, 0);
 
-            if (status == APR_SUCCESS) {
-                c = apreq_make_cookie(p, name, nlen, value, vlen);
-                c->version = version;
-            }
-            else {
-                if (status == APR_EGENERAL)
-                    j->status = APR_EGENERAL;
-                return j;
-            }
+            if (status != APR_SUCCESS)
+                return status;
+
+            c = apreq_make_cookie(p, name, nlen, value, vlen);
+            c->version = version;
         }
     }
 
     /* NOT REACHED */
-    return j;
+    return APR_EGENERAL;
 }
 
 
@@ -543,38 +448,3 @@
     return s;
 }
 
-APREQ_DECLARE(apr_status_t) apreq_cookie_bake(const apreq_cookie_t *c,
-                                              apreq_env_handle_t *env)
-{
-    char s[APREQ_COOKIE_MAX_LENGTH];
-    int len = apreq_cookie_serialize(c, s, APREQ_COOKIE_MAX_LENGTH);
-    if (len < APREQ_COOKIE_MAX_LENGTH)
-        return apreq_env_set_cookie(env, s);
-
-    apreq_log(APREQ_ERROR APR_INCOMPLETE, env, 
-              "serialized cookie length exceeds limit %d", 
-              APREQ_COOKIE_MAX_LENGTH - 1);
-    return APR_INCOMPLETE;
-}
-
-APREQ_DECLARE(apr_status_t) apreq_cookie_bake2(const apreq_cookie_t *c,
-                                               apreq_env_handle_t *env)
-{
-    char s[APREQ_COOKIE_MAX_LENGTH];
-    if ( c->version != NETSCAPE ) {
-        int len = apreq_cookie_serialize(c, s, APREQ_COOKIE_MAX_LENGTH);
-        if (len < APREQ_COOKIE_MAX_LENGTH)
-            return apreq_env_set_cookie2(env, s);
-
-        apreq_log(APREQ_ERROR APR_INCOMPLETE, env, 
-                  "serialized cookie length exceeds limit %d", 
-                  APREQ_COOKIE_MAX_LENGTH - 1);
-
-        return APR_INCOMPLETE;
-    }
-    apreq_log(APREQ_ERROR APR_EGENERAL, env,
-              "Cannot bake2 a Netscape cookie: %s", s);
-
-
-    return APR_EGENERAL;
-}

Modified: httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.h
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.h?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.h (original)
+++ httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.h Fri Feb  4 10:27:55 2005
@@ -40,13 +40,6 @@
  *
  */
 
-/** @brief This is the container class for libapreq cookies. */
-typedef struct apreq_jar_t {
-    apr_table_t   *cookies;   /**< cookie table */
-    apreq_env_handle_t *env;  /**< env handle */
-    apr_status_t  status;     /**< status of "Cookie" header parse */
-} apreq_jar_t;
-
 
 /**
  * Cookie Version.  libapreq does not distinguish between
@@ -81,58 +74,29 @@
     char           *comment;     /**< RFC cookies may send a comment */
     char           *commentURL;  /**< RFC cookies may place an URL here */
     apr_time_t      max_age;     /**< total duration of cookie: -1 == session */
-    apreq_value_t   v;           /**< "raw" cookie value */
+    unsigned char   flags;       /**< charsets, taint marks, app-specific bits */
+    const apreq_value_t   v;     /**< "raw" cookie value */
 
 } apreq_cookie_t;
 
+/** Upgrades cookie jar table values to apreq_cookie_t structs. */
+static APR_INLINE
+apreq_cookie_t *apreq_value_to_cookie(const char *val)
+{
+    union { const char *in; char *out; } deconst;
+
+    deconst.in = val;
+    return apreq_attr_to_type(apreq_cookie_t, v, 
+           apreq_attr_to_type(apreq_value_t, data, deconst.out));
+}
 
-#define apreq_value_to_cookie(ptr) apreq_attr_to_type(apreq_cookie_t, \
-                                                      v, ptr)
 #define apreq_cookie_name(c)  ((c)->v.name)
 #define apreq_cookie_value(c) ((c)->v.data)
 
-#define apreq_jar_items(j) apr_table_elts(j->cookies)->nelts
-#define apreq_jar_nelts(j) apr_table_elts(j->cookies)->nelts
-
-/**
- * Fetches a cookie from the jar
- *
- * @param jar   The cookie jar.
- * @param name  The name of the desired cookie.
- */
-
-APREQ_DECLARE(apreq_cookie_t *)apreq_cookie(const apreq_jar_t *jar,
-                                            const char *name);
-
-/**
- * Adds a cookie by pushing it to the bottom of the jar.
- *
- * @param jar The cookie jar.
- * @param c The cookie to add.
- */
-
-APREQ_DECLARE(void) apreq_jar_add(apreq_jar_t *jar, 
-                                     const apreq_cookie_t *c);
 
-#define apreq_add_cookie(j,c) apreq_jar_add(j,c)
-
-/**
- * Parse the incoming "Cookie:" headers into a cookie jar.
- * 
- * @param env The current environment.
- * @param hdr  String to parse as a HTTP-merged "Cookie" header.
- * @remark "data = NULL" has special behavior.  In this case,
- * apreq_jar(env,NULL) will attempt to fetch a cached object from the
- * environment via apreq_env_jar.  Failing that, it will replace
- * "hdr" with the result of apreq_env_cookie(env), parse that,
- * and store the resulting object back within the environment.
- * This maneuver is designed to mimimize parsing work,
- * since generating the cookie jar is relatively expensive.
- *
- */
-
-
-APREQ_DECLARE(apreq_jar_t *) apreq_jar(apreq_env_handle_t *env, const char *hdr);
+APREQ_DECLARE(apr_status_t)apreq_parse_cookie_header(apr_pool_t *pool,
+                                                     apr_table_t *jar,
+                                                     const char *header);
 
 /**
  * Returns a new cookie, made from the argument list.
@@ -206,33 +170,6 @@
  */
 APREQ_DECLARE(void) apreq_cookie_expires(apreq_cookie_t *c, 
                                          const char *time_str);
-
-/**
- * Add the cookie to the outgoing "Set-Cookie" headers.
- *
- * @param c The cookie.
- * @param env Environment.
- */
-APREQ_DECLARE(apr_status_t) apreq_cookie_bake(const apreq_cookie_t *c,
-                                              apreq_env_handle_t *env);
-
-/**
- * Add the cookie to the outgoing "Set-Cookie2" headers.
- *
- * @param c The cookie.
- * @param env Environment.
- */
-APREQ_DECLARE(apr_status_t) apreq_cookie_bake2(const apreq_cookie_t *c,
-                                               apreq_env_handle_t *env);
-
-/**
- * Looks for the presence of a "Cookie2" header to determine whether
- * or not the current User-Agent supports rfc2965.
- * @param env The current environment.
- * @return APREQ_COOKIE_VERSION_RFC if rfc2965 is supported, 
- *         APREQ_COOKIE_VERSION_NETSCAPE otherwise.
- */
-APREQ_DECLARE(apreq_cookie_version_t) apreq_ua_cookie_version(apreq_env_handle_t *env);
 
 #ifdef __cplusplus
  }

Modified: httpd/apreq/branches/multi-env-unstable/src/apreq_env.c
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/src/apreq_env.c?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/src/apreq_env.c (original)
+++ httpd/apreq/branches/multi-env-unstable/src/apreq_env.c Fri Feb  4 10:27:55 2005
@@ -14,7 +14,6 @@
 **  limitations under the License.
 */
 
-#include "apreq.h"
 #include "apreq_env.h"
 #include "apr_strings.h"
 #include "apr_lib.h"
@@ -22,84 +21,92 @@
 #include "apr_file_io.h"
 
 
-APREQ_DECLARE_NONSTD(void) apreq_log(const char *file, int line,
-                                     int level, apr_status_t status,
-                                     apreq_env_handle_t *env,
-                                     const char *fmt, ...)
-{
-    va_list vp;
-    va_start(vp, fmt);
-    env->module->log(file,line,level,status,env,fmt,vp);
-    va_end(vp);
-}
 
-APREQ_DECLARE(apr_pool_t *) apreq_env_pool(apreq_env_handle_t *env)
+static int has_rfc_cookie(void *ctx, const char *key, const char *val)
 {
-    return env->module->pool(env);
-}
+    const apreq_cookie_t *c = apreq_value_to_cookie(val);
 
-APREQ_DECLARE(apr_bucket_alloc_t *) apreq_env_bucket_alloc(apreq_env_handle_t *env)
-{
-    return env->module->bucket_alloc(env);
-}
+    /* 0 -> non-netscape cookie found, stop.
+       1 -> not found, keep going. */
 
-APREQ_DECLARE(apreq_jar_t *) apreq_env_jar(apreq_env_handle_t *env,
-                                           apreq_jar_t *jar)
-{
-    return env->module->jar(env,jar);
+    return c->version == APREQ_COOKIE_VERSION_NETSCAPE;
 }
 
-APREQ_DECLARE(apreq_request_t *) apreq_env_request(apreq_env_handle_t *env,
-                                                   apreq_request_t *req)
+APREQ_DECLARE(apreq_cookie_version_t)
+    apreq_ua_cookie_version(apreq_env_handle_t *env)
 {
-    return env->module->request(env,req);
-}
 
-APREQ_DECLARE(const char *) apreq_env_query_string(apreq_env_handle_t *env)
-{
-    return env->module->query_string(env);
-}
+    if (apreq_header_in(env, "Cookie2") == NULL) {
+        const apr_table_t *j;
 
-APREQ_DECLARE(const char *) apreq_env_header_in(apreq_env_handle_t *env,
-                                                const char *name)
-{
-    return env->module->header_in(env, name);
-}
+        if (apreq_jar(env, &j) != APR_SUCCESS
+            || apr_table_do(has_rfc_cookie, NULL, j, NULL) == 1)
+            return APREQ_COOKIE_VERSION_NETSCAPE;
 
-APREQ_DECLARE(apr_status_t)apreq_env_header_out(apreq_env_handle_t *env,
-                                                const char *name,
-                                                char *val)
-{
-    return env->module->header_out(env,name,val);
+        else
+            return APREQ_COOKIE_VERSION_RFC;
+    }
+    else
+        return APREQ_COOKIE_VERSION_RFC;
 }
 
-APREQ_DECLARE(apr_status_t) apreq_env_read(apreq_env_handle_t *env,
-                                           apr_read_type_e block,
-                                           apr_off_t bytes)
+
+APREQ_DECLARE(apr_status_t) apreq_cookie_bake(const apreq_cookie_t *c,
+                                              apreq_env_handle_t *env)
 {
-    return env->module->read(env,block,bytes);
+    char s[APREQ_COOKIE_MAX_LENGTH];
+    int len = apreq_cookie_serialize(c, s, APREQ_COOKIE_MAX_LENGTH);
+
+    if (len >= APREQ_COOKIE_MAX_LENGTH)
+        return APREQ_ERROR_OVERLIMIT;
+
+    return apreq_header_out(env, "Set-Cookie", s);
 }
 
-APREQ_DECLARE(const char *) apreq_env_temp_dir(apreq_env_handle_t *env,
-                                               const char *path)
+APREQ_DECLARE(apr_status_t) apreq_cookie_bake2(const apreq_cookie_t *c,
+                                               apreq_env_handle_t *env)
 {
-    if (path != NULL)
-        /* ensure path is a valid pointer during the entire request */
-        path = apr_pstrdup(apreq_env_pool(env),path);
+    char s[APREQ_COOKIE_MAX_LENGTH];
+    int len = apreq_cookie_serialize(c, s, APREQ_COOKIE_MAX_LENGTH);
+
+    if (c->version == APREQ_COOKIE_VERSION_NETSCAPE)
+        return APREQ_ERROR_CONFLICT;
+
+    if (len >= APREQ_COOKIE_MAX_LENGTH)
+        return APREQ_ERROR_OVERLIMIT;
 
-    return env->module->temp_dir(env,path);
+    return apreq_header_out(env, "Set-Cookie2", s);
 }
 
-APREQ_DECLARE(apr_off_t) apreq_env_max_body(apreq_env_handle_t *env,
-                                            apr_off_t bytes)
+
+APREQ_DECLARE(apreq_param_t *)apreq_param(apreq_env_handle_t *env, 
+                                          const char *name)
 {
-    return env->module->max_body(env,bytes);
+    apreq_param_t *param = apreq_args_get(env, name);
+    if (param == NULL)
+        return apreq_body_get(env, name);
+    else
+        return param;
 }
 
-APREQ_DECLARE(apr_ssize_t) apreq_env_max_brigade(apreq_env_handle_t *env,
-                                                 apr_ssize_t bytes)
+
+APREQ_DECLARE(apr_table_t *)apreq_params(apr_pool_t *pool,
+                                         apreq_env_handle_t *env)
 {
-    return env->module->max_brigade(env,bytes);
+    const apr_table_t *args, *body;
+
+    if (apreq_args(env, &args) == APR_SUCCESS)
+        if (apreq_body(env, &body) == APR_SUCCESS)
+            return apr_table_overlay(pool, args, body);
+        else
+            return apr_table_copy(pool, args);
+    else
+        if (apreq_body(env, &body) == APR_SUCCESS)
+            return apr_table_copy(pool, body);
+        else
+            return NULL;
+
 }
+
 
 /** @} */

Modified: httpd/apreq/branches/multi-env-unstable/src/apreq_env.h
URL: http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/src/apreq_env.h?view=diff&r1=151385&r2=151386
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/src/apreq_env.h (original)
+++ httpd/apreq/branches/multi-env-unstable/src/apreq_env.h Fri Feb  4 10:27:55 2005
@@ -19,117 +19,181 @@
 
 #include "apreq_params.h"
 #include "apreq_cookie.h"
-#include <stdarg.h>
+#include "apreq_parsers.h"
 
-#ifdef HAVE_SYSLOG
-#include <syslog.h>
-
-#ifndef LOG_PRIMASK
-#define LOG_PRIMASK 7
-#endif
+#ifdef  __cplusplus
+ extern "C" {
+#endif 
 
+/**
+ * An apreq environment, associated with an env module. The structure
+ * may have variable size, because the module may append its own data
+ * structures after it.
+ */
+typedef struct apreq_env_handle_t {
+    const struct apreq_env_module_t *module;
+} apreq_env_handle_t;
 
-#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 */
-#define APREQ_LOG_ERR       LOG_ERR       /* error conditions */
-#define APREQ_LOG_WARNING   LOG_WARNING   /* warning conditions */
-#define APREQ_LOG_NOTICE    LOG_NOTICE    /* normal but significant condition */
-#define APREQ_LOG_INFO      LOG_INFO      /* informational */
-#define APREQ_LOG_DEBUG     LOG_DEBUG     /* debug-level messages */
+/**
+ * This must be fully defined for libapreq2 to operate properly 
+ * in a given environment. Normally it is set once, with an apreq_env_module() 
+ * call during process initialization, and should remain fixed thereafter.
+ * @brief Vtable describing the necessary environment functions.
+ */
 
-#define APREQ_LOG_LEVELMASK LOG_PRIMASK   /* mask off the level value */
 
-#else
+typedef struct apreq_env_module_t {
+    const char *name;
+    apr_uint32_t magic_number;
 
-#define	APREQ_LOG_EMERG	    0	/* system is unusable */
-#define	APREQ_LOG_ALERT	    1	/* action must be taken immediately */
-#define	APREQ_LOG_CRIT	    2	/* critical conditions */
-#define	APREQ_LOG_ERR	    3	/* error conditions */
-#define	APREQ_LOG_WARNING   4	/* warning conditions */
-#define	APREQ_LOG_NOTICE    5	/* normal but significant condition */
-#define	APREQ_LOG_INFO	    6	/* informational */
-#define	APREQ_LOG_DEBUG	    7   /* debug-level messages */
+    apr_status_t (*jar)(apreq_env_handle_t *, const apr_table_t **);
+    apr_status_t (*args)(apreq_env_handle_t *, const apr_table_t **);
+    apr_status_t (*body)(apreq_env_handle_t *, const apr_table_t **);
+
+    apreq_cookie_t *(*jar_get)(apreq_env_handle_t *, const char *);
+    apreq_param_t *(*args_get)(apreq_env_handle_t *, const char *);
+    apreq_param_t *(*body_get)(apreq_env_handle_t *, const char *);
+
+    apr_status_t (*parser_get)(apreq_env_handle_t *, const apreq_parser_t **);
+    apr_status_t (*parser_set)(apreq_env_handle_t *, apreq_parser_t *);
+    apr_status_t (*hook_add)(apreq_env_handle_t *, apreq_hook_t *);
 
-#define	APREQ_LOG_LEVELMASK	7	/* mask off the level value */
+    apr_status_t (*brigade_limit_get)(apreq_env_handle_t *, apr_size_t *);
+    apr_status_t (*brigade_limit_set)(apreq_env_handle_t *, apr_size_t);
 
-#endif
+    apr_status_t (*read_limit_get)(apreq_env_handle_t *, apr_uint64_t *);
+    apr_status_t (*read_limit_set)(apreq_env_handle_t *, apr_uint64_t);
 
-#define APREQ_LOG_MARK	__FILE__ , __LINE__
+    apr_status_t (*temp_dir_get)(apreq_env_handle_t *, const char **);
+    apr_status_t (*temp_dir_set)(apreq_env_handle_t *, const char *);
 
-#define APREQ_DEBUG  APREQ_LOG_MARK, APREQ_LOG_DEBUG,
-#define APREQ_WARN   APREQ_LOG_MARK, APREQ_LOG_WARNING,
-#define APREQ_ERROR  APREQ_LOG_MARK, APREQ_LOG_ERR,
+    const char *(*header_in)(apreq_env_handle_t *,const char *);
+    apr_status_t (*header_out)(apreq_env_handle_t *, const char *,char *);
 
-#ifdef  __cplusplus
- extern "C" {
-#endif 
+} apreq_env_module_t;
 
-/**
- * @file apreq_env.h
- * @brief Logging and environment (module) declarations.
- * @ingroup libapreq2
- */
 
-/**
- * Analog of Apache's ap_log_rerror().
- * @param file Filename to list in the log message.
- * @param line Line number from the file.
- * @param level Log level.
- * @param status Status code.
- * @param env Current environment.
- * @param fmt Format string for the log message.
- */
 
-APREQ_DECLARE_NONSTD(void) apreq_log(const char *file, int line,
-                                     int level, apr_status_t status,
-                                     apreq_env_handle_t *env,
-                                     const char *fmt, ...);
+static APR_INLINE
+apr_status_t apreq_jar(apreq_env_handle_t *env, const apr_table_t **t)
+{
+    return env->module->jar(env,t);
+}
+
+static APR_INLINE
+apr_status_t apreq_args(apreq_env_handle_t *env, const apr_table_t **t)
+{
+    return env->module->args(env,t);
+}
+
+static APR_INLINE
+apr_status_t apreq_body(apreq_env_handle_t *env, const apr_table_t **t)
+{
+    return env->module->body(env,t);
+}
+
+static APR_INLINE
+apreq_cookie_t *apreq_jar_get(apreq_env_handle_t *env, const char *name)
+{
+    return env->module->jar_get(env, name);
+}
+
+static APR_INLINE
+apreq_param_t *apreq_args_get(apreq_env_handle_t *env, const char *name)
+{
+    return env->module->args_get(env, name);
+}
+
+static APR_INLINE
+apreq_param_t *apreq_body_get(apreq_env_handle_t *env, const char *name)
+{
+    return env->module->body_get(env, name);
+}
+
+static APR_INLINE
+apr_status_t apreq_parser_get(apreq_env_handle_t *env,
+                              const apreq_parser_t **parser)
+{
+    return env->module->parser_get(env, parser);
+}
+
+static APR_INLINE
+apr_status_t apreq_parser_set(apreq_env_handle_t *env,
+                              apreq_parser_t *parser)
+{
+    return env->module->parser_set(env, parser);
+}
+
+static APR_INLINE
+apr_status_t apreq_hook_add(apreq_env_handle_t *env, apreq_hook_t *hook)
+{
+    return env->module->hook_add(env, hook);
+}
+
+static APR_INLINE
+const char *apreq_header_in(apreq_env_handle_t *env, const char *name)
+{
+    return env->module->header_in(env, name);
+}
+
+static APR_INLINE
+apr_status_t apreq_header_out(apreq_env_handle_t *env,
+                              const char *name, char *val)
+{
+    return env->module->header_out(env, name, val);
+}
+
+static APR_INLINE
+apr_status_t apreq_brigade_limit_set(apreq_env_handle_t *env,
+                                     apr_size_t bytes)
+{
+    return env->module->brigade_limit_set(env, bytes);
+}
+
+static APR_INLINE
+apr_status_t apreq_brigade_limit_get(apreq_env_handle_t *env,
+                                     apr_size_t *bytes)
+{
+    return env->module->brigade_limit_get(env, bytes);
+}
+
+static APR_INLINE
+apr_status_t apreq_read_limit_set(apreq_env_handle_t *env,
+                                  apr_uint64_t bytes)
+{
+    return env->module->read_limit_set(env, bytes);
+}
+
+static APR_INLINE
+apr_status_t apreq_read_limit_get(apreq_env_handle_t *env,
+                                  apr_uint64_t *bytes)
+{
+    return env->module->read_limit_get(env, bytes);
+}
+
+static APR_INLINE
+apr_status_t apreq_temp_dir_set(apreq_env_handle_t *env, const char *path)
+{
+    return env->module->temp_dir_set(env, path);
+}
+
+static APR_INLINE
+apr_status_t apreq_temp_dir_get(apreq_env_handle_t *env, const char **path)
+{
+    return env->module->temp_dir_get(env, path);
+}
 
-/**
- * Pool associated with the environment.
- * @param env The current environment
- * @return The associated pool.
- */
 
-APREQ_DECLARE(apr_pool_t *) apreq_env_pool(apreq_env_handle_t *env);
 
-/**
- * Bucket allocator associated with the environment.
- * @param env The current environment
- * @return The associated bucket allocator.
- */
 
-APREQ_DECLARE(apr_bucket_alloc_t *) apreq_env_bucket_alloc(apreq_env_handle_t *env);
 
-/**
- * Get/set the jar currently associated to the environment.
- * @param env The current environment.
- * @param jar New Jar to associate.
- * @return The previous jar associated to the environment.
- * jar == NULL gets the current jar, which will remain associated
- * after the call.
- */
-APREQ_DECLARE(apreq_jar_t *) apreq_env_jar(apreq_env_handle_t *env,
-                                           apreq_jar_t *jar);
 
 /**
- * Get/set the request currently associated to the environment.
- * @param env The current environment.
- * @param req New request to associate.
- * @return The previous request associated to the environment.
- * req == NULL gets the current request, which will remain associated
- * after the call.
+ * @file apreq_env.h
+ * @brief Logging and environment (module) declarations.
+ * @ingroup libapreq2
  */
-APREQ_DECLARE(apreq_request_t *) apreq_env_request(apreq_env_handle_t *env,
-                                                   apreq_request_t *req);
 
-/**
- * Fetch the query string.
- * @param env The current environment.
- * @return The query string.
- */
-APREQ_DECLARE(const char *) apreq_env_query_string(apreq_env_handle_t *env);
 
 /**
  * Fetch the header value (joined by ", " if there are multiple headers)
@@ -138,171 +202,139 @@
  * @param name The header name.
  * @return The value of the header, NULL if not found.
  */
-APREQ_DECLARE(const char *) apreq_env_header_in(apreq_env_handle_t *env,
-                                                const char *name);
 
 
 /**
- * Fetch the environment's "Content-Type" header.
+ * Add a header field to the environment's outgoing response headers
  * @param env The current environment.
- * @return The value of the Content-Type header, NULL if not found.
+ * @param name The name of the outgoing header.
+ * @param val Value of the outgoing header.
+ * @return APR_SUCCESS on success, error code otherwise.
  */
-#define apreq_env_content_type(env) apreq_env_header_in(env, "Content-Type")
 
 
 /**
- * Fetch the environment's "Cookie" header.
- * @param env The current environment.
- * @return The value of the "Cookie" header, NULL if not found.
+ * Convenience macro for defining an environment module by mapping
+ * a function prefix to an associated environment structure.
+ * @param pre Prefix to define new environment.  All attributes of
+ * the apreq_env_module_t struct are defined with this as their prefix. The
+ * generated struct is named by appending "_module" to the prefix.
+ * @param name Name of this environment.
+ * @param mmn Magic number (i.e. version number) of this environment.
  */
-#define apreq_env_cookie(env) apreq_env_header_in(env, "Cookie")
+#define APREQ_MODULE(pre, mmn) const apreq_env_module_t \
+  pre##_module = { #pre, mmn,                           \
+  pre##_jar,        pre##_args,       pre##_body,       \
+  pre##_jar_get,    pre##_args_get,   pre##_body_get,   \
+  pre##_parser_get, pre##_parser_set, pre##_hook_add,   \
+  pre##_brigade_limit_get, pre##_brigade_limit_set,     \
+  pre##_read_limit_get,    pre##_read_limit_set,        \
+  pre##_temp_dir_get,      pre##_temp_dir_set,          \
+  pre##_header_in,         pre##_header_out }
 
 /**
- * Fetch the environment's "Cookie2" header.
- * @param env The current environment.
- * @return The value of the "Cookie2" header, NULL if not found.
+ * Create an apreq handle which is suitable for a CGI program. It
+ * reads input from stdin and writes output to stdout.
  */
-#define apreq_env_cookie2(env) apreq_env_header_in(env, "Cookie2")
+APREQ_DECLARE(apreq_env_handle_t*) apreq_handle_cgi(apr_pool_t *pool);
 
 /**
- * Add a header field to the environment's outgoing response headers
- * @param env The current environment.
- * @param name The name of the outgoing header.
- * @param val Value of the outgoing header.
- * @return APR_SUCCESS on success, error code otherwise.
+ * Create a custom apreq handle which knows only some static
+ * values. Useful if you want to test the parser code or if you have
+ * got data from a custom source (neither Apache 2 nor CGI).
+ * @param pool the APR pool
+ * @param query_string the query string
+ * @param cookie value of the request "Cookie" header
+ * @param cookie2 value of the request "Cookie2" header
+ * @param content_type content type of the request body
+ * @param in a bucket brigade containing the request body
  */
-APREQ_DECLARE(apr_status_t)apreq_env_header_out(apreq_env_handle_t *env, 
-                                                const char *name,
-                                                char *val);
+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);
 
 /**
- * Add a "Set-Cookie" header to the outgoing response headers.
- * @param e The current environment.
- * @param s The cookie string.
- * @return APR_SUCCESS on success, error code otherwise.
+ * Add the cookie to the outgoing "Set-Cookie" headers.
+ *
+ * @param c The cookie.
+ * @param env Environment.
  */
-#define apreq_env_set_cookie(e,s) apreq_env_header_out(e,"Set-Cookie",s)
+APREQ_DECLARE(apr_status_t) apreq_cookie_bake(const apreq_cookie_t *c,
+                                              apreq_env_handle_t *env);
 
 /**
- * Add a "Set-Cookie2" header to the outgoing response headers.
- * @param e The current environment.
- * @param s The cookie string.
- * @return APR_SUCCESS on success, error code otherwise.
+ * Add the cookie to the outgoing "Set-Cookie2" headers.
+ *
+ * @param c The cookie.
+ * @param env Environment.
  */
-#define apreq_env_set_cookie2(e,s) apreq_env_header_out(e,"Set-Cookie2",s)
-
-/**
- * Read data from the environment and into the current active parser.
- * @param env The current environment.
- * @param block Read type (APR_READ_BLOCK or APR_READ_NONBLOCK).
- * @param bytes Maximum number of bytes to read.
- * @return APR_INCOMPLETE if there's more data to read,
- *         APR_SUCCESS if everything was read & parsed successfully,
- *         error code otherwise.
- */
-APREQ_DECLARE(apr_status_t) apreq_env_read(apreq_env_handle_t *env,
-                                           apr_read_type_e block,
-                                           apr_off_t bytes);
+APREQ_DECLARE(apr_status_t) apreq_cookie_bake2(const apreq_cookie_t *c,
+                                               apreq_env_handle_t *env);
 
 /**
- * Get/set the current temporary directory.
+ * Looks for the presence of a "Cookie2" header to determine whether
+ * or not the current User-Agent supports rfc2965.
  * @param env The current environment.
- * @param path The full pathname of the new directory.
- * @return The path of the previous temporary directory.  Note: a call using
- * path==NULL fetches the current directory without resetting it to NULL.
+ * @return APREQ_COOKIE_VERSION_RFC if rfc2965 is supported, 
+ *         APREQ_COOKIE_VERSION_NETSCAPE otherwise.
  */
+APREQ_DECLARE(apreq_cookie_version_t)
+    apreq_ua_cookie_version(apreq_env_handle_t *env);
+
+
+APREQ_DECLARE(apreq_param_t *)apreq_param(apreq_env_handle_t *env, 
+                                          const char *name);
 
-APREQ_DECLARE(const char *) apreq_env_temp_dir(apreq_env_handle_t *env,
-                                               const char *path);
+#define apreq_cookie(env, name) apreq_jar_get(env, name)
 
 /**
- * Get/set the current max_body setting.  This is the maximum
- * amount of bytes that will be read into the environment's parser.
- * @param env The current environment.
- * @param bytes The new max_body setting.
- * @return The previous max_body setting.  Note: a call using
- * bytes == -1 fetches the current max_body setting without modifying it.
- *
+ * 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,
+                                          apreq_env_handle_t *env);
 
-APREQ_DECLARE(apr_off_t) apreq_env_max_body(apreq_env_handle_t *env,
-                                            apr_off_t bytes);
+
+APREQ_DECLARE(apr_table_t *)apreq_cookies(apr_pool_t *p,
+                                          apreq_env_handle_t *env);
 
 /**
- * Get/set the current max_brigade setting.  This is the maximum
- * amount of heap-allocated buckets libapreq2 will use for its brigades.  
- * If additional buckets are necessary, they will be created from a temporary file.
- * @param env The current environment.
- * @param bytes The new max_brigade setting.
- * @return The previous max_brigade setting.  Note: a call using
- * bytes == -1 fetches the current max_brigade setting without modifying it.
+ * Force a complete parse.
+ * @param req Current request handle.
+ * @return APR_SUCCESS on an error-free parse of the request data.
+ *         Any other status code indicates a problem somewhere.
  *
  */
-APREQ_DECLARE(apr_ssize_t) apreq_env_max_brigade(apreq_env_handle_t *env,
-                                                 apr_ssize_t bytes);
 
-/**
- * This must be fully defined for libapreq2 to operate properly 
- * in a given environment. Normally it is set once, with an apreq_env_module() 
- * call during process initialization, and should remain fixed thereafter.
- * @brief Vtable describing the necessary environment functions.
- */
+static APR_INLINE
+apr_status_t apreq_parse_request(apreq_env_handle_t *req)
+{
+    const apr_table_t *dummy;
+    apr_status_t jar_status, args_status, body_status;
+
+    jar_status = apreq_jar(req, &dummy);
+    args_status = apreq_args(req, &dummy);
+    body_status = apreq_body(req, &dummy);
+
+    /* XXX: punt to APR_EGENERAL; need to improve this
+     * for valid requests where certain data/headers are 
+     * unavailable.
+     */
+    if (jar_status || args_status || body_status)
+        return APR_EGENERAL;
 
-typedef struct apreq_env_module_t {
-    const char *name;
-    apr_uint32_t magic_number;
-    void (*log)(const char *,int,int,apr_status_t,apreq_env_handle_t *,
-                const char *,va_list);
-    apr_pool_t *(*pool)(apreq_env_handle_t *);
-    apr_bucket_alloc_t *(*bucket_alloc)(apreq_env_handle_t *);
-    apreq_jar_t *(*jar)(apreq_env_handle_t *,apreq_jar_t *);
-    apreq_request_t *(*request)(apreq_env_handle_t *,apreq_request_t *);
-    const char *(*query_string)(apreq_env_handle_t *);
-    const char *(*header_in)(apreq_env_handle_t *,const char *);
-    apr_status_t (*header_out)(apreq_env_handle_t *, const char *,char *);
-    apr_status_t (*read)(apreq_env_handle_t *,apr_read_type_e,apr_off_t);
-    const char *(*temp_dir)(apreq_env_handle_t *, const char *);
-    apr_off_t (*max_body)(apreq_env_handle_t *,apr_off_t);
-    apr_ssize_t (*max_brigade)(apreq_env_handle_t *, apr_ssize_t);
-} apreq_env_module_t;
+    return APR_SUCCESS;
+}
 
-/**
- * Convenience macro for defining an environment module by mapping
- * a function prefix to an associated environment structure.
- * @param pre Prefix to define new environment.  All attributes of
- * the apreq_env_module_t struct are defined with this as their prefix. The
- * generated struct is named by appending "_module" to the prefix.
- * @param name Name of this environment.
- * @param mmn Magic number (i.e. version number) of this environment.
- */
-#define APREQ_ENV_MODULE(pre, name, mmn) const apreq_env_module_t pre##_module = { \
-  name, mmn, pre##_log, pre##_pool, pre##_bucket_alloc, pre##_jar,          \
-  pre##_request, pre##_query_string, pre##_header_in, pre##_header_out,     \
-  pre##_read, pre##_temp_dir, pre##_max_body, pre##_max_brigade }
 
-/**
- * Create an apreq handle which is suitable for a CGI program. It
- * reads input from stdin and writes output to stdout.
- */
-APREQ_DECLARE(apreq_env_handle_t*) apreq_env_make_cgi(apr_pool_t *pool);
 
-/**
- * Create a custom apreq handle which knows only some static
- * values. Useful if you want to test the parser code or if you have
- * got data from a custom source (neither Apache 2 nor CGI).
- * @param pool the APR pool
- * @param query_string the query string
- * @param cookie value of the request "Cookie" header
- * @param cookie2 value of the request "Cookie2" header
- * @param content_type content type of the request body
- * @param in a bucket brigade containing the request body
- */
-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);
 
 #ifdef __cplusplus
  }



Mime
View raw message