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 [EMAIL PROTECTED]
*
* 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
* <http://www.apache.org/>.
*
* 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 [EMAIL PROTECTED]
*
* 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
* <http://www.apache.org/>.
*
* 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;
}