Return-Path: Delivered-To: apmail-httpd-apreq-cvs-archive@httpd.apache.org Received: (qmail 30138 invoked by uid 500); 24 Jan 2003 04:29: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 30115 invoked by uid 500); 24 Jan 2003 04:29:11 -0000 Delivered-To: apmail-httpd-apreq-2-cvs@apache.org Date: 24 Jan 2003 04:29:10 -0000 Message-ID: <20030124042910.24477.qmail@icarus.apache.org> From: joes@apache.org To: httpd-apreq-2-cvs@apache.org Subject: cvs commit: httpd-apreq-2/src apreq_params.h apreq_params.c apreq_cookie.h apreq_cookie.c apreq_env.h apreq_tables.c apreq_tables.h apreq.h Makefile.am X-Spam-Rating: 208.185.179.12.available.above.net 1.6.2 0/1000/N joes 2003/01/23 20:29:09 Modified: src apreq_cookie.h apreq_cookie.c apreq_env.h apreq_tables.c apreq_tables.h apreq.h Makefile.am Added: src apreq_params.h apreq_params.c Log: Import apreq_params skeleton, along with some state management tweaks. Parsers are coming next. Revision Changes Path 1.4 +15 -2 httpd-apreq-2/src/apreq_cookie.h Index: apreq_cookie.h =================================================================== RCS file: /home/cvs/httpd-apreq-2/src/apreq_cookie.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- apreq_cookie.h 23 Jan 2003 07:00:41 -0000 1.3 +++ apreq_cookie.h 24 Jan 2003 04:29:09 -0000 1.4 @@ -43,6 +43,15 @@ #define apreq_cookie_name(c) ((c)->v.name) #define apreq_cookie_value(c) ((c)->v.data) + +/** + * returns the current context jar. + * + * + */ +APREQ_DECLARE(apreq_jar_t *) apreq_jar(void *ctx); +#define apreq_jar(r) apreq_jar_parse(r,NULL) + /** * Returns the number of cookies in the jar. * @@ -52,6 +61,7 @@ int apreq_jar_items(apreq_jar_t *jar); #define apreq_jar_items(j) apreq_table_nelts(j) +#define apreq_jar_nelts(j) apreq_table_nelts(j) /** * Fetches a cookie from the jar @@ -158,7 +168,7 @@ * * @param c The cookie. */ -apr_status_t apreq_cookie_bake(apreq_cookie_t *c); +APREQ_DECLARE(apr_status_t) apreq_cookie_bake(apreq_cookie_t *c); /* XXX: how about baking whole cookie jars, too ??? */ @@ -167,7 +177,10 @@ * * @param c The cookie. */ -apr_status_t apreq_cookie_bake2(apreq_cookie_t *c); +APREQ_DECLARE(apr_status_t) apreq_cookie_bake2(apreq_cookie_t *c); + +APREQ_DECLARE(apreq_cookie_version_t) apreq_cookie_ua_version(void *ctx); + #ifdef __cplusplus } 1.5 +31 -0 httpd-apreq-2/src/apreq_cookie.c Index: apreq_cookie.c =================================================================== RCS file: /home/cvs/httpd-apreq-2/src/apreq_cookie.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- apreq_cookie.c 23 Jan 2003 07:00:41 -0000 1.4 +++ apreq_cookie.c 24 Jan 2003 04:29:09 -0000 1.5 @@ -87,6 +87,33 @@ c->time.max_age = apreq_atol(time_str); } +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(val)); + + return c->version == NETSCAPE; /* 0 -> found, stop. + 1 -> not found, keep going. */ +} + +APREQ_DECLARE(apreq_cookie_version_t) apreq_cookie_ua_version(void *ctx) +{ + if (apreq_env_cookie2(ctx) == NULL) { + apreq_jar_t *j = apreq_jar_parse(ctx, NULL); + + if (j == NULL || apreq_jar_nelts(j) == 0) + return APREQ_COOKIE_VERSION; + + else if (apreq_table_do(has_rfc_cookie, NULL, j) == 1) + return NETSCAPE; + + else + return RFC; + } + else + return RFC; +} + APREQ_DECLARE(apr_status_t) apreq_cookie_attr(apreq_cookie_t *c, char *attr, char *val) { @@ -374,6 +401,10 @@ return j; } +APREQ_DECLARE(apreq_jar_t *) (apreq_jar)(void *ctx) +{ + return apreq_jar(ctx); +} APREQ_DECLARE(int) apreq_cookie_serialize(const apreq_cookie_t *c, char *buf, apr_size_t len) 1.4 +17 -7 httpd-apreq-2/src/apreq_env.h Index: apreq_env.h =================================================================== RCS file: /home/cvs/httpd-apreq-2/src/apreq_env.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- apreq_env.h 23 Jan 2003 07:00:41 -0000 1.3 +++ apreq_env.h 24 Jan 2003 04:29:09 -0000 1.4 @@ -5,25 +5,31 @@ extern "C" { #endif +#include "apreq.h" /* ctx ~ request_rec */ struct apreq_request_env { - int foo; - apr_status_t (*init)(void *ctx, void *cfg); - void *(*make)(void *ctx); - apr_status_t (*parse)(void *ctx); + void *(*request)(void *ctx); + + apr_status_t (*setup)(void *ctx, + void *parser, + void *cfg); + + apr_status_t (*parse)(void *req); }; struct apreq_cookie_env { - const char *(*in)(void *ctx); - const char *(*in2)(void *ctx); - void *(*jar)(void *ctx, void *j); + + const char *(*in)(void *ctx); + const char *(*in2)(void *ctx); + apr_status_t (*out)(void *ctx, const char *c); apr_status_t (*out2)(void *ctx, const char *c); }; extern const struct apreq_env { + const char *name; struct apreq_request_env r; struct apreq_cookie_env c; @@ -38,6 +44,10 @@ APREQ_DECLARE(void) apreq_log(const char *file, int line, int level, apr_status_t status, void *ctx, const char *fmt, ...); + +APREQ_DECLARE(void *) apreq_env_request(void *ctx, void *r); +APREQ_DECLARE(char *) apreq_env_args(void *ctx); +APREQ_DECLARE(apr_status_t) apreq_env_parse(void *req); APREQ_DECLARE(void *) apreq_env_jar(void *ctx, void *j); APREQ_DECLARE(const char *) apreq_env_cookie(void *ctx); 1.6 +27 -12 httpd-apreq-2/src/apreq_tables.c Index: apreq_tables.c =================================================================== RCS file: /home/cvs/httpd-apreq-2/src/apreq_tables.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- apreq_tables.c 23 Jan 2003 07:00:41 -0000 1.5 +++ apreq_tables.c 24 Jan 2003 04:29:09 -0000 1.6 @@ -980,24 +980,39 @@ /********************* table_add* *********************/ -APREQ_DECLARE(void) apreq_table_add(apreq_table_t *t, - const apreq_value_t *val) +APREQ_DECLARE(apr_status_t) apreq_table_add(apreq_table_t *t, + const apreq_value_t *val) { - const char *key = val->name; - apreq_table_entry_t *elt = table_push(t); - int *root = &t->root[TABLE_HASH(key)]; - apreq_table_entry_t *o = (apreq_table_entry_t *)t->a.elts; + if (val == NULL || val->name == NULL) + return APR_EGENERAL; -#ifdef POOL_DEBUG + switch (val->status) { + case APR_SUCCESS: + case APR_EINPROGRESS: { + const char *key = val->name; + apreq_table_entry_t *elt = table_push(t); + int *root = &t->root[TABLE_HASH(key)]; + apreq_table_entry_t *o = (apreq_table_entry_t *)t->a.elts; + +#ifdef POOL_DEBUG + { /* XXX */ - } + } #endif + elt->key = val->name; + elt->val = val; + elt->tree[NEXT] = -1; + insert(t->cmp, o, root, *root, elt,TREE_PUSH); + return APR_SUCCESS; + } + + default: + return val->status; + } - elt->key = val->name; - elt->val = val; - elt->tree[NEXT] = -1; - insert(t->cmp, o, root, *root, elt,TREE_PUSH); + /* NOT REACHED */ + return APR_SUCCESS; } 1.5 +2 -1 httpd-apreq-2/src/apreq_tables.h Index: apreq_tables.h =================================================================== RCS file: /home/cvs/httpd-apreq-2/src/apreq_tables.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- apreq_tables.h 23 Jan 2003 07:00:41 -0000 1.4 +++ apreq_tables.h 24 Jan 2003 04:29:09 -0000 1.5 @@ -284,7 +284,8 @@ * @param val The value to add. * @remark This function does not make copies. */ -APREQ_DECLARE(void) apreq_table_add(apreq_table_t *t, const apreq_value_t *v); +APREQ_DECLARE(apr_status_t) apreq_table_add(apreq_table_t *t, + const apreq_value_t *v); /** * Merge two tables into one new table 1.5 +9 -0 httpd-apreq-2/src/apreq.h Index: apreq.h =================================================================== RCS file: /home/cvs/httpd-apreq-2/src/apreq.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- apreq.h 23 Jan 2003 07:00:41 -0000 1.4 +++ apreq.h 24 Jan 2003 04:29:09 -0000 1.5 @@ -87,8 +87,17 @@ apr_size_t apreq_escape(char *dest, const char *src, const apr_size_t slen); apr_ssize_t apreq_unescape(char *dest, const char *src, apr_size_t slen); +/** + * Returns an RFC-822 formatted time string. Similar to ap_gm_timestr_822. + * + * @param req The current apreq_request_t object. + * @param ts YMDhms time units (from now) until expiry. + * Understands "now". + */ + /* returns date string, (time_str is offset from "now") formatted * either as an NSCOOKIE or HTTP date */ + char *apreq_expires(apr_pool_t *p, const char *time_str, const int type); /* file sizes (KMG) to bytes */ 1.3 +1 -1 httpd-apreq-2/src/Makefile.am Index: Makefile.am =================================================================== RCS file: /home/cvs/httpd-apreq-2/src/Makefile.am,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Makefile.am 23 Jan 2003 07:00:41 -0000 1.2 +++ Makefile.am 24 Jan 2003 04:29:09 -0000 1.3 @@ -2,6 +2,6 @@ pkginclude_HEADERS = apreq.h apreq_cookie.h apreq_request.h \ apreq_tables.h apreq_env.h libapreq_la_SOURCES = apreq.c apreq_tables.c apreq_cookie.c \ - apreq_param.c apreq_parsers.c + apreq_params.c apreq_parsers.c libapreq_la_LDFLAGS = -version-info 2:0 INCLUDES = @APREQ_INCLUDES@ 1.1 httpd-apreq-2/src/apreq_params.h Index: apreq_params.h =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * * Portions of this software are based upon public domain software * originally written at the National Center for Supercomputing Applications, * University of Illinois, Urbana-Champaign. */ #ifndef APREQ_PARAM_H #define APREQ_PARAM_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include "apreq_tables.h" #include "apr_buckets.h" /*************************************************** * API: apreq_params.c * */ typedef struct apreq_param_t { enum { ASCII, UTF_8, UTF_16, IS0_LATIN_1 } charset; char *language; apreq_table_t *info; apr_bucket_brigade *bb; apreq_value_t v; } apreq_param_t; /* XXX this might be better as an ADT */ typedef struct apreq_request_t { apreq_table_t *args; /* query_string params */ apreq_table_t *body; void *ctx; apr_status_t status; } apreq_request_t; /** * Creates an apreq_request_t object. * @param ctx The current request context. */ APREQ_DECLARE(apreq_request_t *)apreq_request(void *ctx); APREQ_DECLARE(apr_status_t)apreq_parse(apreq_request_t *req); /** * Returns the first parameter value for the requested key, * NULL if none found. The key is case-insensitive. * @param req The current apreq_request_t object. * @param key Nul-terminated search key. Returns the first table value * if NULL. * @remark Also parses the request as necessary. */ APREQ_DECLARE(const char *) apreq_param(apreq_request_t *req, const char *key); APREQ_DECLARE(const char *) apreq_arg(const apreq_request_t *req, const char *key); #define apreq_arg(r,k) apreq_table_get((req)->arg, k) APREQ_DECLARE(const apreq_table_t *) apreq_args(const apreq_request_t *req); #define apreq_args(req) (const apreq_table_t *)((req)->args) APREQ_DECLARE(const apreq_table_t *) apreq_body(const apreq_request_t *req); /* Danger Will Robinson! */ #define apreq_body(req) (const apreq_table_t *)((req)->body) /** * Returns all parameters for the requested key, * NULL if none found. The key is case-insensitive. * @param req The current apreq_request_t object. * @param key Nul-terminated search key. Returns the first table value * if NULL. * @remark Also parses the request as necessary. */ APREQ_DECLARE(apr_array_header_t *) apreq_params( const apreq_request_t *req, apr_pool_t *p, const char *key); /** * Returns a ", " -separated string containing all parameters * for the requested key, NULL if none found. The key is case-insensitive. * @param req The current apreq_request_t object. * @param key Nul-terminated search key. Returns the first table value * if NULL. * @remark Also parses the request as necessary. */ #define apreq_params_as_string(req,key,pool, mode) \ apreq_join(pool, ", ", apreq_params(req,pool,key), mode) /** * Returns an array of param keys; the array elements are unique. * @param req The current apreq_request_t object. * @remark Also parses the request as necessary. */ APREQ_DECLARE(apr_array_header_t *) apreq_keys(apreq_request_t *req); APREQ_DECLARE(apr_status_t) apreq_param_split(apreq_table_t *t, apr_pool_t *pool, const char *data, apr_size_t dlen); APREQ_DECLARE(apreq_param_t *) apreq_param_decode(apr_pool_t *pool, const char *word, const apr_size_t nlen, const apr_size_t vlen); #ifdef __cplusplus } #endif #endif /* APREQ_PARAM_H */ 1.1 httpd-apreq-2/src/apreq_params.c Index: apreq_params.c =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * * Portions of this software are based upon public domain software * originally written at the National Center for Supercomputing Applications, * University of Illinois, Urbana-Champaign. */ #include "apreq_params.h" #include "apreq_env.h" #define p2v(param) ( (param) ? &(param)->v : NULL ) APREQ_DECLARE(apreq_request_t *) apreq_request(void *ctx) { apreq_request_t *req, *old_req = apreq_env_request(ctx, NULL); char *query_string; apr_pool_t *p; if (old_req != NULL) return old_req; p = apreq_env_pool(ctx); req = apr_palloc(p, sizeof *req); req->status = APR_EINIT; req->ctx = ctx; req->args = apreq_table_make(p, APREQ_DEFAULT_NELTS); req->body = NULL; /* XXX get/set race condition here wrt apreq_env_request. * apreq_env_request probably needs a write lock ??? */ old_req = apreq_env_request(ctx, req); if (old_req != NULL) return old_req; #ifdef DEBUG apreq.debug(ctx, 0, "making new request"); #endif /* XXX need to install copy/merge callbacks for apreq_param_t */ query_string = apreq_env_args(ctx); req->status = (query_string == NULL) ? APR_SUCCESS : apreq_param_split(req->args, p, query_string, strlen(query_string)); return req; } apr_status_t apreq_parse(apreq_request_t *req) { if (req->body == NULL) if (req->status == APR_SUCCESS) return apreq_env_parse(req); else return req->status; else if (req->status == APR_EAGAIN) return apreq_env_parse(req); else return req->status; } const char *apreq_param(apreq_request_t *req, const char *key) { const char *param = apreq_table_get(req->args, key); return param ? param : apreq_table_get(req->body, key); } apr_array_header_t *apreq_params(const apreq_request_t *req, apr_pool_t *pool, const char *key) { apr_array_header_t *arr = apreq_table_values(req->args, pool, key); apr_array_cat(arr, apreq_table_values(req->body, pool, key)); return arr; } apr_status_t apreq_param_split(apreq_table_t *t, apr_pool_t *pool, const char *data, apr_size_t dlen) { const char *start = data, *end = data + dlen; apr_size_t nlen = 0; apr_status_t status = APR_SUCCESS; for (; data < end; ++data) { switch (*data) { case '=': if (nlen == 0) { nlen = data - start; break; } else return APR_BADARG; case '&': case ';': case 0: if (nlen == 0) { return APR_BADARG; } else { const apr_size_t vlen = data - start - nlen - 1; status = apreq_table_add(t, p2v( apreq_param_decode( pool, start, nlen, vlen ))); if (status != APR_SUCCESS) return status; } nlen = 0; start = data + 1; if (start < end) status = APR_INCOMPLETE; } } return status; } APREQ_DECLARE(apreq_param_t *) apreq_param_decode(apr_pool_t *pool, const char *word, const apr_size_t nlen, const apr_size_t vlen) { apreq_param_t *param; apr_ssize_t size; if (nlen == 0 || vlen == 0 || word[nlen] != '=') return NULL; param = apr_palloc(pool, nlen + vlen + 1 + sizeof *param); param->charset = ASCII; /* XXX: UTF_8 */ param->language = NULL; param->info = NULL; param->bb = NULL; param->v.status = APR_SUCCESS; param->v.name = NULL; size = apreq_unescape(param->v.data, word + nlen + 1, vlen); if (size < 0) { param->v.size = 0; param->v.status = APR_BADARG; return param; } param->v.size = size; param->v.name = param->v.data + size + 1; if (apreq_unescape(param->v.data + size + 1, word, nlen) < 0) param->v.status = APR_BADCH; return param; }