joes 2003/01/21 07:22:23
Modified: src apreq_cookie.h apreq_cookie.c
Log:
Clean up cookie API docs.
Revision Changes Path
1.2 +49 -24 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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- apreq_cookie.h 21 Jan 2003 02:36:28 -0000 1.1
+++ apreq_cookie.h 21 Jan 2003 15:22:23 -0000 1.2
@@ -17,26 +17,28 @@
apreq_cookie_version_t version;
- char *path;
- char *domain;
- char *port;
- unsigned secure;
+ char *path;
+ char *domain;
+ char *port;
+ unsigned secure;
- char *comment;
- char *commentURL;
+ char *comment;
+ char *commentURL;
- union {
- long max_age;
+ union {
+ long max_age;
const char *expires;
} time;
- void *ctx;
+ void *ctx;
+
+ apreq_value_t v; /* "raw" value (extended struct) */
- apreq_value_t v; /* "raw" value (extended struct) */
} apreq_cookie_t;
-#define apreq_value_to_cookie(ptr) apreq_attr_to_type(apreq_cookie_t, v, ptr)
+#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)
@@ -44,6 +46,7 @@
* Returns the number of cookies in the jar.
*
* @param jar The cookie jar.
+ * @remark Shouldn't this be called apreq_jar_nelts?
*/
int apreq_jar_items(apreq_jar_t *jar);
@@ -52,8 +55,8 @@
/**
* Fetches a cookie from the jar
*
- * @param jar The cookie jar.
- * @param i The index of the desired cookie.
+ * @param jar The cookie jar.
+ * @param name The name of the desired cookie.
*/
apreq_cookie_t *apreq_jar_get(apreq_jar_t *jar, char *name);
@@ -73,22 +76,31 @@
/**
* Parse the incoming "Cookie:" headers into a cookie jar.
*
- * @param r The current request_rec.
- * @param data Optional header string to use in place of r->headers_in.
- * @remark The current source assumes the client will fold all cookies
- * into a single "Cookie:" header. This may assumption may be removed
- * in a future release.
+ * @param ctx The current context.
+ * @param data String to parse as a HTTP-merged "Cookie" header.
+ * @remark "data = NULL" has special semantics. In this case,
+ * apreq_jar_parse will attempt to fetch a cached jar from the
+ * environment ctx via apreq_env_jar. Failing that, it replace
+ * data with the result of apreq_env_cookie(ctx), parse that,
+ * and store the resulting jar back within the environment.
+ * This Orcish maneuver is designed to mimimize parsing work,
+ * since generating the cookie jar is fairly expensive.
+ *
*/
+
apreq_jar_t *apreq_jar_parse(void *ctx, const char *data);
/**
* Returns a new cookie, made from the argument list.
- * Valid argument strings, passed in "attr","value" pairs, are:
- * name, value, version, expires/max-len, domain, port, path,
- * comment, commentURL, secure.
+ * The cookie is allocated from the ctx pool.
*
- * @param r The current request.
+ * @param ctx The current context.
+ * @param v The cookie version, currently one of ::NETSCAPE or ::RFC.
+ * @param name The cookie's name.
+ * @param nlen Length of name.
+ * @param value The cookie's value.
+ * @param vlen Length of value.
*/
apreq_cookie_t *apreq_cookie_make(void *ctx, const apreq_cookie_version_t v,
const char *name, const apr_ssize_t nlen,
@@ -99,13 +111,26 @@
char *attr, char *val);
/**
- * Returns a string (allocated from the cookie's pool) that
- * represents the cookie as it would appear in a valid "Set-Cookie*" header.
+ * Returns a string that represents the cookie as it would appear
+ * in a valid "Set-Cookie*" header.
*
* @param c The cookie.
+ * @param p The pool.
*/
APREQ_DECLARE(const char*) apreq_cookie_as_string(const apreq_cookie_t *c,
apr_pool_t *p);
+
+/**
+ * Same functionality as apreq_cookie_as_string. Stores the string
+ * representation in buf, using up to len bytes in buf as storage.
+ * The return value has the same semantics as that of apr_snprintf,
+ * including the special behavior for a "len = 0" argument.
+ *
+ * @param c The cookie.
+ * @param buf Storage location for the result.
+ * @param len Size of buf's storage area.
+ */
+
APREQ_DECLARE(int) apreq_cookie_serialize(const apreq_cookie_t *c,
char *buf, apr_size_t len);
1.2 +42 -31 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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- apreq_cookie.c 21 Jan 2003 02:36:28 -0000 1.1
+++ apreq_cookie.c 21 Jan 2003 15:22:23 -0000 1.2
@@ -189,7 +189,7 @@
*n = d;
while( *d != '=' && !apr_isspace(*d) )
- if (*d++ == 0) /*error: no '=' sign */
+ if (*d++ == 0) /*error: no '=' sign detected */
return APR_EGENERAL;
*nlen = d - *n;
@@ -209,27 +209,30 @@
goto pair_result;
case '\\':
- if (d[1])
- ++d;
- break;
+ if (*++d)
+ break;
+ else
+ return APR_EGENERAL; /* shouldn't end on a sour note */
case '"':
in_quotes = ! in_quotes;
+
}
}
pair_result:
- *data = d;
*vlen = d - *v;
- /* shouldn't still be in_quotes */
+ if (in_quotes)
+ return APR_EGENERAL;
- return in_quotes ? APR_EGENERAL : APR_SUCCESS;
+ *data = d;
+ return APR_SUCCESS;
}
APREQ_DECLARE(apreq_jar_t *) apreq_jar_parse(void *ctx,
- const char *d)
+ const char *data)
{
apr_pool_t *p = apreq_env_pool(ctx);
@@ -237,20 +240,20 @@
apreq_jar_t *j = NULL;
apreq_cookie_t *c;
+ const char *origin;
const char *name, *value;
apr_ssize_t nlen, vlen;
-
/* initialize jar */
- if (d == NULL) {
+ if (data == NULL) {
/* use the environment's cookie data */
/* fetch ctx->jar (cached jar) */
- if ( apreq_env_jar(ctx, &j) == APR_SUCCESS && j != NULL)
+ if ( apreq_env_jar(ctx, &j) == APR_SUCCESS && j != NULL )
return j;
- d = apreq_env_cookie(ctx);
+ data = apreq_env_cookie(ctx);
j = apreq_table_make(apreq_env_pool(ctx), APREQ_DEFAULT_NELTS);
/* XXX: potential race condition here
@@ -258,63 +261,71 @@
apreq_env_jar(ctx,&j); /* set (cache) ctx->jar */
- if (d == NULL)
+ if (data == NULL)
return j;
}
else {
j = apreq_table_make(p, APREQ_DEFAULT_NELTS);
}
+ origin = data;
+
#ifdef DEBUG
- apreq_log(APREQ_DEBUG(ctx), "parsing cookie data: %s",d);
+ apreq_debug(ctx, "parsing cookie data: %s", data);
#endif
/* parse d */
- parse_header:
+ parse_cookie_header:
c = NULL;
version = NETSCAPE;
- while (apr_isspace(*d))
- ++d;
+ while (apr_isspace(*data))
+ ++data;
/* XXX cheat: assume "$..." => "$Version" => RFC Cookie header */
- if (*d == '$') {
+ if (*data == '$') {
version = RFC;
- while (*d && !apr_isspace(*d))
- ++d;
+ while (*data && !apr_isspace(*data))
+ ++data;
}
for (;;) {
- while (*d == ';' || apr_isspace(*d))
- ++d;
+ while (*data == ';' || apr_isspace(*data))
+ ++data;
- switch (*d) {
+ switch (*data) {
case 0:
return j;
case ',':
- ++d;
- goto parse_header;
+ ++data;
+ goto parse_cookie_header;
case '$':
if ( c == NULL || version == NETSCAPE ||
- get_pair(&d, &name, &nlen, &value, &vlen) != APR_SUCCESS )
- return j; /* XXX: log error? */
-
+ get_pair(&data, &name, &nlen, &value, &vlen) !=
+ APR_SUCCESS )
+ {
+ apreq_warn(ctx, "b0rked Cookie segment: %s", data);
+ return j;
+ }
apreq_cookie_attr(c, apr_pstrmemdup(p, name, nlen),
apr_pstrmemdup(p, value, vlen));
break;
default:
- if ( get_pair(&d, &name, &nlen, &value, &vlen) != APR_SUCCESS )
+ if ( get_pair(&data, &name, &nlen, &value, &vlen)
+ != APR_SUCCESS )
+ {
+ apreq_warn(ctx, "Bad Cookie segment: %s", data);
return j; /* XXX: log error? */
-
+ }
c = apreq_cookie_make(ctx, version, name, nlen, value, vlen);
apreq_jar_add(j, c);
@@ -375,7 +386,7 @@
* just for certainty though.
*/
- strcpy(f, c->time.max_age >= 0 ? "; max_age=%ld" : "%.0s");
+ strcpy(f, c->time.max_age >= 0 ? "; max-age=%ld" : "%.0s");
f += strlen(f);