Return-Path: Delivered-To: apmail-httpd-apreq-cvs-archive@www.apache.org Received: (qmail 58280 invoked from network); 4 Feb 2005 18:28:19 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 4 Feb 2005 18:28:19 -0000 Received: (qmail 87093 invoked by uid 500); 4 Feb 2005 18:28:11 -0000 Delivered-To: apmail-httpd-apreq-cvs-archive@httpd.apache.org Received: (qmail 87054 invoked by uid 500); 4 Feb 2005 18:28:11 -0000 Mailing-List: contact apreq-cvs-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: apreq-dev@httpd.apache.org List-Post: List-Help: List-Unsubscribe: List-Subscribe: Delivered-To: mailing list apreq-cvs@httpd.apache.org Received: (qmail 87032 invoked by uid 99); 4 Feb 2005 18:28:10 -0000 X-ASF-Spam-Status: No, hits=-9.8 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from minotaur.apache.org (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Fri, 04 Feb 2005 10:28:05 -0800 Received: (qmail 58219 invoked by uid 65534); 4 Feb 2005 18:28:04 -0000 Message-ID: <20050204182804.58217.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Mailer: svnmailer-1.0.0-dev Date: Fri, 04 Feb 2005 18:28:04 -0000 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/ To: apreq-cvs@httpd.apache.org From: joes@apache.org X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N 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=3Ddiff&r1=3D151385&r2=3D151386 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- 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 @@ */ =20 #include "apreq.h" -#include "apreq_env.h" #include "apr_time.h" #include "apr_strings.h" #include "apr_lib.h" - +#include #define MIN(a,b) ( (a) < (b) ? (a) : (b) ) #define MAX(a,b) ( (a) > (b) ? (a) : (b) ) =20 @@ -30,70 +29,22 @@ const apr_size_t vlen) { apreq_value_t *v =3D apr_palloc(p, vlen + nlen + 1 + sizeof *v); - char *writable_name; =20 if (v =3D=3D NULL) return NULL; =20 - v->size =3D vlen; memcpy(v->data, val, vlen); v->data[vlen] =3D 0; + v->size =3D vlen; =20 - v->name =3D writable_name =3D v->data + vlen + 1; - memcpy(writable_name, name, nlen); - writable_name[nlen] =3D 0; + v->name =3D v->data + vlen + 1; + memcpy(v->name, name, nlen); + v->name[nlen] =3D 0; =20 - v->flags =3D 0; return v; } =20 =20 -APREQ_DECLARE(apreq_value_t *)apreq_copy_value(apr_pool_t *p,=20 - const apreq_value_t *val) -{ - apreq_value_t *v; - if (val =3D=3D NULL) - return NULL; - - v =3D apr_palloc(p, val->size + sizeof *v); - - *v =3D *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 =3D *(apreq_value_t **)(arr->elts); - apreq_value_t *v =3D apreq_char_to_value(apreq_deconst(apreq_join(p, "= , ", arr, APREQ_JOIN_AS_IS))); - if (arr->nelts > 0) - v->name =3D a->name; - return v; -} - -APREQ_DECLARE(const char *)apreq_enctype(apreq_env_handle_t *env) -{ - char *enctype; - const char *ct =3D apreq_env_content_type(env); - - if (ct =3D=3D NULL) - return NULL; - else { - const char *semicolon =3D strchr(ct, ';'); - if (semicolon) { - enctype =3D apr_pstrdup(apreq_env_pool(env), ct); - enctype[semicolon - ct] =3D 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; } =20 -static const char c2x_table[] =3D "0123456789abcdef"; +static const char c2x_table[] =3D "0123456789abcdef"; /* XXX uppercase a-f= ? */ static APR_INLINE char x2c(const char *what) { register char digit; @@ -346,7 +297,7 @@ *slen =3D s - src; if (s + 5 < end || (s + 2 < end && s[1] !=3D 'u' && s[1] != =3D 'U')) { *d =3D 0; - return APR_EGENERAL; + return APREQ_ERROR_BADSEQ; } memcpy(d, s, end - s); d[end - s] =3D 0; @@ -358,7 +309,7 @@ *d =3D 0; *dlen =3D d - start; *slen =3D s - src; - return APR_BADCH; + return APREQ_ERROR_BADCHAR; =20 default: *d =3D *s; @@ -371,33 +322,36 @@ return APR_SUCCESS; } =20 -APREQ_DECLARE(apr_ssize_t) apreq_decode(char *d, const char *s,=20 - 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 =3D 0; const char *end =3D s + slen; - - if (s =3D=3D NULL || d =3D=3D NULL) - return -1; + apr_status_t rv; =20 if (s =3D=3D (const char *)d) { /* optimize for src =3D dest case = */ for ( ; d < end; ++d) { if (*d =3D=3D '%' || *d =3D=3D '+') break; - else if (*d =3D=3D 0) - return (const char*)d - s; + else if (*d =3D=3D 0) { + *dlen =3D (const char *)d - s; + return APREQ_ERROR_BADCHAR; + } } + len =3D (const char *)d - s; s =3D (const char *)d; + slen -=3D len; } =20 - 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] =3D 0; + *dlen =3D slen; + return APR_SUCCESS; + */ + rv =3D url_decode(d, dlen, s, &slen); + *dlen +=3D len; + return rv; } =20 =20 @@ -435,7 +389,7 @@ goto start_decodev; =20 default: - *dlen =3D len; + *dlen +=3D len; return status; } } @@ -582,9 +536,7 @@ break; =20 case APREQ_JOIN_DECODE: - len =3D 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 +=3D len; @@ -593,9 +545,7 @@ memcpy(d, sep, slen); d +=3D slen; =20 - len =3D 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 +=3D len; @@ -636,8 +586,8 @@ return rv->data; } =20 -APREQ_DECLARE(char *) apreq_escape(apr_pool_t *p,=20 - 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 =3D=3D NULL) @@ -649,9 +599,15 @@ return rv->data; } =20 +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 =3D apreq_decode(str,&len,str,strlen(str)); + if (rv =3D=3D APR_SUCCESS) + return (apr_ssize_t)len; + else + return -1; } =20 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 =3D 0; @@ -714,7 +670,7 @@ e =3D APR_BUCKET_NEXT(e))=20 { apr_size_t len; - if (n =3D=3D APREQ_NELTS) { + if (n =3D=3D APREQ_DEFAULT_NELTS) { s =3D apreq_fwritev(f, v, &n, &len); if (s !=3D APR_SUCCESS) return s; @@ -802,19 +758,6 @@ } =20 =20 -APREQ_DECLARE(apr_file_t *)apreq_brigade_spoolfile(apr_bucket_brigade *bb) -{ - apr_bucket *last =3D APR_BRIGADE_LAST(bb); - apr_bucket_file *f; - if (APR_BUCKET_IS_FILE(last)) { - f =3D 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; =20 + /*Must ensure first char isn't '=3D', so we can safely backstep. */ + while (*hdr =3D=3D '=3D') + ++hdr; + while ((key =3D strchr(hdr, '=3D')) !=3D NULL) { =20 v =3D 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 @@ } =20 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 =3D apr_bucket_type_fil= e; + * =20 + * 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 =3D=3D &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 =3D apr_bucket_type_file; + */ +static const apr_bucket_type_t spool_bucket =3D { + "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,=20 + 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 =3D APR_BRIGADE_LAST(out); + + if (APR_BUCKET_IS_EOS(last_out)) + return APR_EOF; + + s =3D apr_brigade_length(out, 0, &out_len); + if (s !=3D APR_SUCCESS) + return s; + + /* This cast, when out_len =3D -1, is intentional */ + if ((apr_uint64_t)out_len < heap_limit) { + + s =3D apr_brigade_length(in, 0, &in_len); + if (s !=3D APR_SUCCESS) + return s; + + /* This cast, when in_len =3D -1, is intentional */ + if ((apr_uint64_t)in_len < heap_limit - out_len) { + APR_BRIGADE_CONCAT(out, in); + return APR_SUCCESS; + } + } + =20 + if (!BUCKET_IS_SPOOL(last_out)) { + + s =3D apreq_file_mktemp(&file, pool, temp_dir); + if (s !=3D APR_SUCCESS) + return s; + + /* This cast, when out_len =3D -1, is intentional */ + if ((apr_uint64_t)out_len < heap_limit) + s =3D apreq_brigade_fwrite(file, &wlen, out); + + if (s !=3D APR_SUCCESS) + return s; + + last_out =3D apr_bucket_file_create(file, wlen, 0,=20 + out->p, out->bucket_alloc); + last_out->type =3D &spool_bucket; + APR_BRIGADE_INSERT_TAIL(out, last_out); + f =3D last_out->data; + } + else { + f =3D last_out->data; + /* Need to seek here, just in case our spool bucket=20 + * was read from between apreq_brigade_concat calls.=20 + */ + wlen =3D last_out->start + last_out->length; + s =3D apr_file_seek(f->fd, APR_SET, &wlen); + if (s !=3D APR_SUCCESS) + return s; + } + + last_in =3D APR_BRIGADE_LAST(in); + + if (APR_BUCKET_IS_EOS(last_in)) + APR_BUCKET_REMOVE(last_in); + + s =3D apreq_brigade_fwrite(f->fd, &wlen, in); + + if (s =3D=3D APR_SUCCESS) { + + /* We have to deal with the possibility that the new=20 + * 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 =3D 0; + e->start =3D last_out->start + FILE_BUCKET_LIMIT; + wlen -=3D FILE_BUCKET_LIMIT - last_out->length; + last_out->length =3D FILE_BUCKET_LIMIT; + last_out->type =3D &apr_bucket_type_file; + + APR_BRIGADE_INSERT_TAIL(out, e); + last_out =3D e; + } + + last_out->length +=3D 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=3Ddiff&r1=3D151385&r2=3D151386 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- 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 =20 -#define APREQ_URL_ENCTYPE "application/x-www-form-urlencoded" -#define APREQ_MFD_ENCTYPE "multipart/form-data" -#define APREQ_XML_ENCTYPE "application/xml" =20 -#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)=20 - =20 - -/** @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); =20 - -#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 =20 /** - * 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 =20 -#define apreq_char_to_value(ptr) apreq_attr_to_type(apreq_value_t, data, = ptr) =20 -/** 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 =3D (long)p; - return (void*)v; -} =20 -static APR_INLINE apreq_value_t *apreq_strtoval(const char *name) { - return (apreq_value_t*)apreq_char_to_value(apreq_deconst(name)); -} =20 -/** - * 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. - *=20 - */ +/** @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; + =20 -#define apreq_strlen(ptr) (apreq_strtoval(ptr)->size) +#define apreq_attr_to_type(T,A,P) ( (T*) ((char*)(P)-offsetof(T,A)) ) =20 /** * Construcs an apreq_value_t from the name/value info @@ -130,37 +125,6 @@ const char *val,=20 const apr_size_t vlen); =20 -/** - * 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,=20 - 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,=20 - 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 {=20 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=20 - * with apreq_stroval. + * @remark Return string can be upgraded to an apreq_value_t. */ APREQ_DECLARE(const char *) apreq_join(apr_pool_t *p,=20 const char *sep,=20 @@ -214,8 +177,8 @@ * */ APREQ_DECLARE(apr_ssize_t) apreq_index(const char* hay, apr_size_t hlen,=20 - const char* ndl, apr_size_t nlen,=20 - const apreq_match_t type); + const char* ndl, apr_size_t nlen,=20 + const apreq_match_t type); /** * Places a quoted copy of src into dest. Embedded quotes are escaped wit= h a * backslash ('\'). @@ -257,12 +220,14 @@ * Url-decodes a string. * @param dest Location of url-encoded result string. Caller must ensure d= est is * large enough to hold the encoded string and trailing null c= haracter. + * @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 d= ata) error. + * @return APR_SUCCESS, error otherwise. */ =20 -APREQ_DECLARE(apr_ssize_t) apreq_decode(char *dest, const char *src, apr_s= ize_t slen); +APREQ_DECLARE(apr_status_t) apreq_decode(char *dest, apr_size_t *dlen, + const char *src, apr_size_t slen); =20 =20 /** @@ -372,22 +337,14 @@ const char *path); =20 /** - * 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. */ =20 -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 =3D APR_BRIGADE_FIRST(bb); e !=3D APR_BRIGADE_SENTINEL(bb); e =3D 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,=20 + * the appended buckets get written to a tempfile. =20 + * @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,=20 + apr_bucket_brigade *in); =20 =20 #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=3Ddiff&r1=3D151385&r2=3D151386 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.c (original) +++ httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.c Fri Feb 4 1= 0:27:55 2005 @@ -15,7 +15,6 @@ */ =20 #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 =20 -APREQ_DECLARE(apreq_cookie_t *) apreq_cookie(const apreq_jar_t *jar,=20 - const char *name) -{ - const char *val =3D apr_table_get(jar->cookies, name); - if (val =3D=3D 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,=20 - 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) =20 +=20 APREQ_DECLARE(void) apreq_cookie_expires(apreq_cookie_t *c,=20 const char *time_str) { @@ -59,40 +45,13 @@ } } =20 -static int has_rfc_cookie(void *ctx, const char *key, const char *val) -{ - const apreq_cookie_t *c =3D apreq_value_to_cookie(apreq_char_to_value(= apreq_deconst(val))); - - return c->version =3D=3D NETSCAPE; /* 0 -> non-netscape cookie found, = stop. - 1 -> not found, keep going. */ -} - -APREQ_DECLARE(apreq_cookie_version_t) apreq_ua_cookie_version(apreq_env_ha= ndle_t *env) -{ - if (apreq_env_cookie2(env) =3D=3D NULL) { - apreq_jar_t *j =3D apreq_jar(env, NULL); - - if (j =3D=3D NULL || apreq_jar_nelts(j) =3D=3D 0)=20 - return NETSCAPE; - - else if (apr_table_do(has_rfc_cookie, NULL, j->cookies, NULL) =3D= =3D 1) - return NETSCAPE; - - else - return RFC; - } - else - return RFC; -} - - APREQ_DECLARE(apr_status_t)=20 apreq_cookie_attr(apr_pool_t *p, apreq_cookie_t *c,=20 const char *attr, apr_size_t alen, const char *val, apr_size_t vlen) { if (alen < 2) - return APR_EGENERAL; + return APR_EBADARG; =20 if ( attr[0] =3D=3D '-' || attr[0] =3D=3D '$' ) { ++attr; @@ -101,14 +60,16 @@ =20 switch (apr_tolower(*attr)) { =20 - case 'n': /* name */ - c->v.name =3D 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 =3D=3D 5 && strncasecmp(attr,"value", 5) =3D=3D 0) + return APR_ENOTIMPL; =20 - case 'v': /* version */ while (!apr_isdigit(*val)) { if (vlen =3D=3D 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 =3D apr_palloc(p, vlen + sizeof *c); - apreq_value_t *v =3D &c->v; + apreq_cookie_t *c; + apreq_value_t *v; + + c =3D apr_palloc(p, nlen + vlen + 1 + sizeof *c); + + if (c =3D=3D NULL || nlen =3D=3D 0) + return NULL; + + *(const apreq_value_t **)&v =3D &c->v; =20 v->size =3D vlen; - v->name =3D apr_pstrmemdup(p, name, nlen); + memcpy(v->data, value, vlen); v->data[vlen] =3D 0; - =20 + + v->name =3D v->data + vlen + 1; + memcpy (v->name, name, nlen); + v->name[nlen] =3D 0; + c->version =3D DEFAULT; =20 /* session cookie is the default */ @@ -200,7 +172,7 @@ key =3D strchr(hdr, '=3D'); =20 if (key =3D=3D NULL) - return APR_NOTFOUND; + return APREQ_ERROR_NOTOKEN; =20 val =3D key + 1; =20 @@ -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 @@ } =20 =20 -APREQ_DECLARE(apreq_jar_t *) apreq_jar(apreq_env_handle_t *env, - const char *hdr) -{ - apr_pool_t *p =3D apreq_env_pool(env); =20 - apreq_cookie_version_t version; - apreq_jar_t *j =3D 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;=20 - apr_size_t nlen, vlen; - - /* initialize jar */ - =20 - if (hdr =3D=3D NULL) { - /* use the environment's cookie data */ - - j =3D apreq_env_jar(env, NULL); - if ( j !=3D NULL ) - return j; - - j =3D apr_palloc(p, sizeof *j); - j->env =3D env; - j->cookies =3D apr_table_make(p, APREQ_NELTS); - j->status =3D APR_SUCCESS; - - hdr =3D apreq_env_cookie(env); - - /* XXX: potential race condition here=20 - between env_jar fetch and env_jar set. */ - - apreq_env_jar(env,j); - - if (hdr =3D=3D NULL) - return j; - } - else { - j =3D apr_palloc(p, sizeof *j); - j->env =3D env; - j->cookies =3D apr_table_make(p, APREQ_NELTS); - j->status =3D APR_SUCCESS; - } - - origin =3D hdr; - - apreq_log(APREQ_DEBUG 0, env, "parsing cookie data: %s", hdr); - - /* parse data */ + apreq_cookie_version_t version; =20 parse_cookie_header: =20 @@ -350,6 +280,8 @@ =20 for (;;) { apr_status_t status; + const char *name, *value; + apr_size_t nlen, vlen; =20 while (*hdr =3D=3D ';' || apr_isspace(*hdr)) ++hdr; @@ -357,91 +289,64 @@ switch (*hdr) { =20 case 0: - /* this is the normal exit point for apreq_jar */ + /* this is the normal exit point */ if (c !=3D NULL) { - apreq_log(APREQ_DEBUG j->status, env,=20 - "adding cookie: %s =3D> %s", c->v.name, c->v.dat= a); - apreq_add_cookie(j, c); + ADD_COOKIE(j, c); } - return j; + return APR_SUCCESS; =20 case ',': ++hdr; if (c !=3D NULL) { - apreq_log(APREQ_DEBUG j->status, env,=20 - "adding cookie: %s =3D> %s", c->v.name, c->v.dat= a); - apreq_add_cookie(j, c); + ADD_COOKIE(j, c); } goto parse_cookie_header; =20 case '$': if (c =3D=3D NULL) { - j->status =3D APR_EGENERAL; - apreq_log(APREQ_ERROR j->status, env, - "Saw RFC attribute, was expecting NAME=3DVALUE cooki= e pair: %s", - hdr); - return j; + return APREQ_ERROR_BADSEQ; } else if (version =3D=3D NETSCAPE) { - j->status =3D APR_EGENERAL; - apreq_log(APREQ_ERROR j->status, env,=20 - "Saw RFC attribute in a Netscape Cookie header: = %s",=20 - hdr); - return j; + return APREQ_ERROR_CONFLICT; } =20 ++hdr; status =3D get_pair(p, &hdr, &name, &nlen, &value, &vlen, 1); - if (status !=3D APR_SUCCESS) { - j->status =3D status; - apreq_log(APREQ_ERROR status, env, - "Bad RFC attribute: %s", - apr_pstrmemdup(p, name, hdr-name)); - return j; - } + if (status !=3D APR_SUCCESS) + return status; =20 status =3D apreq_cookie_attr(p, c, name, nlen, value, vlen); + switch (status) { case APR_ENOTIMPL: - apreq_log(APREQ_WARN status, env,=20 - "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 =3D status; - apreq_log(APREQ_ERROR status, env, - "Bad RFC attribute pair: %s", - apr_pstrmemdup(p, name, hdr-name)); - return j; + return status; } =20 break; =20 default: if (c !=3D NULL) { - apreq_log(APREQ_DEBUG j->status, env,=20 - "adding cookie: %s =3D> %s", c->v.name, c->v.dat= a); - apreq_add_cookie(j, c); + ADD_COOKIE(j, c); } =20 status =3D get_pair(p, &hdr, &name, &nlen, &value, &vlen, 0); =20 - if (status =3D=3D APR_SUCCESS) { - c =3D apreq_make_cookie(p, name, nlen, value, vlen); - c->version =3D version; - } - else { - if (status =3D=3D APR_EGENERAL) - j->status =3D APR_EGENERAL; - return j; - } + if (status !=3D APR_SUCCESS) + return status; + + c =3D apreq_make_cookie(p, name, nlen, value, vlen); + c->version =3D version; } } =20 /* NOT REACHED */ - return j; + return APR_EGENERAL; } =20 =20 @@ -543,38 +448,3 @@ return s; } =20 -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 =3D 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,=20 - "serialized cookie length exceeds limit %d",=20 - 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 !=3D NETSCAPE ) { - int len =3D 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,=20 - "serialized cookie length exceeds limit %d",=20 - 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=3Ddiff&r1=3D151385&r2=3D151386 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.h (original) +++ httpd/apreq/branches/multi-env-unstable/src/apreq_cookie.h Fri Feb 4 1= 0:27:55 2005 @@ -40,13 +40,6 @@ * */ =20 -/** @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; - =20 /** * 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 =3D=3D = 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 */ =20 } apreq_cookie_t; =20 +/** 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 =3D val; + return apreq_attr_to_type(apreq_cookie_t, v,=20 + apreq_attr_to_type(apreq_value_t, data, deconst.out)); +} =20 -#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) =20 -#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,=20 - const apreq_cookie_t *c); =20 -#define apreq_add_cookie(j,c) apreq_jar_add(j,c) - -/** - * Parse the incoming "Cookie:" headers into a cookie jar. - *=20 - * @param env The current environment. - * @param hdr String to parse as a HTTP-merged "Cookie" header. - * @remark "data =3D 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); =20 /** * Returns a new cookie, made from the argument list. @@ -206,33 +170,6 @@ */ APREQ_DECLARE(void) apreq_cookie_expires(apreq_cookie_t *c,=20 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,=20 - * APREQ_COOKIE_VERSION_NETSCAPE otherwise. - */ -APREQ_DECLARE(apreq_cookie_version_t) apreq_ua_cookie_version(apreq_env_ha= ndle_t *env); =20 #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=3Ddiff&r1=3D151385&r2=3D151386 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- 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:2= 7:55 2005 @@ -14,7 +14,6 @@ ** limitations under the License. */ =20 -#include "apreq.h" #include "apreq_env.h" #include "apr_strings.h" #include "apr_lib.h" @@ -22,84 +21,92 @@ #include "apr_file_io.h" =20 =20 -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); -} =20 -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 =3D apreq_value_to_cookie(val); =20 -APREQ_DECLARE(apr_bucket_alloc_t *) apreq_env_bucket_alloc(apreq_env_handl= e_t *env) -{ - return env->module->bucket_alloc(env); -} + /* 0 -> non-netscape cookie found, stop. + 1 -> not found, keep going. */ =20 -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 =3D=3D APREQ_COOKIE_VERSION_NETSCAPE; } =20 -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); -} =20 -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") =3D=3D NULL) { + const apr_table_t *j; =20 -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) !=3D APR_SUCCESS + || apr_table_do(has_rfc_cookie, NULL, j, NULL) =3D=3D 1) + return APREQ_COOKIE_VERSION_NETSCAPE; =20 -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; } =20 -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 =3D apreq_cookie_serialize(c, s, APREQ_COOKIE_MAX_LENGTH); + + if (len >=3D APREQ_COOKIE_MAX_LENGTH) + return APREQ_ERROR_OVERLIMIT; + + return apreq_header_out(env, "Set-Cookie", s); } =20 -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 !=3D NULL) - /* ensure path is a valid pointer during the entire request */ - path =3D apr_pstrdup(apreq_env_pool(env),path); + char s[APREQ_COOKIE_MAX_LENGTH]; + int len =3D apreq_cookie_serialize(c, s, APREQ_COOKIE_MAX_LENGTH); + + if (c->version =3D=3D APREQ_COOKIE_VERSION_NETSCAPE) + return APREQ_ERROR_CONFLICT; + + if (len >=3D APREQ_COOKIE_MAX_LENGTH) + return APREQ_ERROR_OVERLIMIT; =20 - return env->module->temp_dir(env,path); + return apreq_header_out(env, "Set-Cookie2", s); } =20 -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,=20 + const char *name) { - return env->module->max_body(env,bytes); + apreq_param_t *param =3D apreq_args_get(env, name); + if (param =3D=3D NULL) + return apreq_body_get(env, name); + else + return param; } =20 -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) =3D=3D APR_SUCCESS) + if (apreq_body(env, &body) =3D=3D APR_SUCCESS) + return apr_table_overlay(pool, args, body); + else + return apr_table_copy(pool, args); + else + if (apreq_body(env, &body) =3D=3D APR_SUCCESS) + return apr_table_copy(pool, body); + else + return NULL; + } + =20 /** @} */ 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=3Ddiff&r1=3D151385&r2=3D151386 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- 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:2= 7:55 2005 @@ -19,117 +19,181 @@ =20 #include "apreq_params.h" #include "apreq_cookie.h" -#include +#include "apreq_parsers.h" =20 -#ifdef HAVE_SYSLOG -#include - -#ifndef LOG_PRIMASK -#define LOG_PRIMASK 7 -#endif +#ifdef __cplusplus + extern "C" { +#endif=20 =20 +/** + * 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; =20 -#define APREQ_LOG_EMERG LOG_EMERG /* system is unusable */ -#define APREQ_LOG_ALERT LOG_ALERT /* action must be taken immediat= ely */ -#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 condit= ion */ -#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=20 + * in a given environment. Normally it is set once, with an apreq_env_modu= le()=20 + * call during process initialization, and should remain fixed thereafter. + * @brief Vtable describing the necessary environment functions. + */ =20 -#define APREQ_LOG_LEVELMASK LOG_PRIMASK /* mask off the level value */ =20 -#else +typedef struct apreq_env_module_t { + const char *name; + apr_uint32_t magic_number; =20 -#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 *); =20 -#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); =20 -#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); =20 -#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 *); =20 -#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 *); =20 -#ifdef __cplusplus - extern "C" { -#endif=20 +} apreq_env_module_t; =20 -/** - * @file apreq_env.h - * @brief Logging and environment (module) declarations. - * @ingroup libapreq2 - */ =20 -/** - * 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. - */ =20 -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); +} =20 -/** - * Pool associated with the environment. - * @param env The current environment - * @return The associated pool. - */ =20 -APREQ_DECLARE(apr_pool_t *) apreq_env_pool(apreq_env_handle_t *env); =20 -/** - * Bucket allocator associated with the environment. - * @param env The current environment - * @return The associated bucket allocator. - */ =20 -APREQ_DECLARE(apr_bucket_alloc_t *) apreq_env_bucket_alloc(apreq_env_handl= e_t *env); =20 -/** - * 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 =3D=3D 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); =20 /** - * 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 =3D=3D 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); =20 -/** - * 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= ); =20 /** * 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); =20 =20 /** - * 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= ") =20 =20 /** - * 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 =3D { #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 } =20 /** - * 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); =20 /** - * 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,=20 - const char *name, - char *val); +APREQ_DECLARE(apreq_env_handle_t*) apreq_handle_custom(apr_pool_t *pool, + const char *query_s= tring, + const char *cookie, + const char *cookie2, + apreq_parser_t *par= ser, + apr_uint64_t read_l= imit, + apr_bucket_brigade = *in); =20 /** - * 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); =20 /** - * 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); =20 /** - * 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 usi= ng - * path=3D=3DNULL fetches the current directory without resetting it to NU= LL. + * @return APREQ_COOKIE_VERSION_RFC if rfc2965 is supported,=20 + * 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,=20 + const char *name); =20 -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) =20 /** - * 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 =3D=3D -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); =20 -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); =20 /** - * Get/set the current max_brigade setting. This is the maximum - * amount of heap-allocated buckets libapreq2 will use for its brigades. =20 - * If additional buckets are necessary, they will be created from a tempor= ary file. - * @param env The current environment. - * @param bytes The new max_brigade setting. - * @return The previous max_brigade setting. Note: a call using - * bytes =3D=3D -1 fetches the current max_brigade setting without modifyi= ng 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); =20 -/** - * This must be fully defined for libapreq2 to operate properly=20 - * in a given environment. Normally it is set once, with an apreq_env_modu= le()=20 - * 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 =3D apreq_jar(req, &dummy); + args_status =3D apreq_args(req, &dummy); + body_status =3D apreq_body(req, &dummy); + + /* XXX: punt to APR_EGENERAL; need to improve this + * for valid requests where certain data/headers are=20 + * unavailable. + */ + if (jar_status || args_status || body_status) + return APR_EGENERAL; =20 -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; +} =20 -/** - * 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##_mo= dule =3D { \ - 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 } =20 -/** - * 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); =20 -/** - * 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 *cooki= e, - const char *cooki= e2, - const char *conte= nt_type, - apr_bucket_brigad= e *in); =20 #ifdef __cplusplus }