| /* |
| ** Licensed to the Apache Software Foundation (ASF) under one or more |
| ** contributor license agreements. See the NOTICE file distributed with |
| ** this work for additional information regarding copyright ownership. |
| ** The ASF licenses this file to You under the Apache License, Version 2.0 |
| ** (the "License"); you may not use this file except in compliance with |
| ** the License. You may obtain a copy of the License at |
| ** |
| ** http://www.apache.org/licenses/LICENSE-2.0 |
| ** |
| ** Unless required by applicable law or agreed to in writing, software |
| ** distributed under the License is distributed on an "AS IS" BASIS, |
| ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| ** See the License for the specific language governing permissions and |
| ** limitations under the License. |
| */ |
| |
| #ifndef APREQ_COOKIE_H |
| #define APREQ_COOKIE_H |
| |
| #include "apreq.h" |
| #include "apr_time.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * @file apreq_cookie.h |
| * @brief Cookies and Jars. |
| * @ingroup libapreq2 |
| * |
| * apreq_cookie.h describes a common server-side API for request (incoming) |
| * and response (outgoing) cookies. It aims towards compliance with the |
| * standard cookie specifications listed below. |
| * |
| * @see http://wp.netscape.com/newsref/std/cookie_spec.html |
| * @see http://www.ietf.org/rfc/rfc2109.txt |
| * @see http://www.ietf.org/rfc/rfc2964.txt |
| * @see http://www.ietf.org/rfc/rfc2965.txt |
| * |
| */ |
| |
| /** This macro is deprecated. |
| * |
| * Maximum length of a single Set-Cookie(2) header. |
| */ |
| #define APREQ_COOKIE_MAX_LENGTH 4096 |
| |
| /** @brief Cookie type, supporting both Netscape and RFC cookie specifications. |
| */ |
| |
| typedef struct apreq_cookie_t { |
| |
| char *path; /**< Restricts url path */ |
| char *domain; /**< Restricts server domain */ |
| char *port; /**< Restricts server port */ |
| char *comment; /**< RFC cookies may send a comment */ |
| char *commentURL; /**< RFC cookies may place an URL here */ |
| apr_time_t max_age; /**< total duration of cookie: -1 == session */ |
| unsigned flags; /**< charsets, taint marks, app-specific bits */ |
| const apreq_value_t v; /**< "raw" cookie value */ |
| |
| } apreq_cookie_t; |
| |
| |
| /** Upgrades a jar's table values to apreq_cookie_t structs. */ |
| static APR_INLINE |
| apreq_cookie_t *apreq_value_to_cookie(const char *val) |
| { |
| union { const char *in; char *out; } deconst; |
| |
| deconst.in = val; |
| return apreq_attr_to_type(apreq_cookie_t, v, |
| apreq_attr_to_type(apreq_value_t, data, deconst.out)); |
| } |
| |
| /**@return 1 if this is an RFC cookie, 0 if its a Netscape cookie. */ |
| static APR_INLINE |
| unsigned apreq_cookie_version(const apreq_cookie_t *c) { |
| return APREQ_FLAGS_GET(c->flags, APREQ_COOKIE_VERSION); |
| } |
| |
| /** Sets the cookie's protocol version. */ |
| static APR_INLINE |
| void apreq_cookie_version_set(apreq_cookie_t *c, unsigned v) { |
| APREQ_FLAGS_SET(c->flags, APREQ_COOKIE_VERSION, v); |
| } |
| |
| /** @return 1 if the secure flag is set, 0 otherwise. */ |
| static APR_INLINE |
| unsigned apreq_cookie_is_secure(const apreq_cookie_t *c) { |
| return APREQ_FLAGS_GET(c->flags, APREQ_COOKIE_SECURE); |
| } |
| |
| /** Sets the cookie's secure flag, meaning it only |
| * comes back over an SSL-encrypted connction. |
| */ |
| static APR_INLINE |
| void apreq_cookie_secure_on(apreq_cookie_t *c) { |
| APREQ_FLAGS_ON(c->flags, APREQ_COOKIE_SECURE); |
| } |
| |
| /** Turns off the cookie's secure flag. */ |
| static APR_INLINE |
| void apreq_cookie_secure_off(apreq_cookie_t *c) { |
| APREQ_FLAGS_OFF(c->flags, APREQ_COOKIE_SECURE); |
| } |
| |
| /** @return 1 if the HttpOnly flag is set, 0 otherwise. */ |
| static APR_INLINE |
| unsigned apreq_cookie_is_httponly(const apreq_cookie_t *c) { |
| return APREQ_FLAGS_GET(c->flags, APREQ_COOKIE_HTTPONLY); |
| } |
| |
| /** Sets the cookie's HttpOnly flag, meaning it is not |
| * accessible through client-side script in supported |
| * browsers. |
| */ |
| static APR_INLINE |
| void apreq_cookie_httponly_on(apreq_cookie_t *c) { |
| APREQ_FLAGS_ON(c->flags, APREQ_COOKIE_HTTPONLY); |
| } |
| |
| /** Turns off the cookie's HttpOnly flag. */ |
| static APR_INLINE |
| void apreq_cookie_httponly_off(apreq_cookie_t *c) { |
| APREQ_FLAGS_OFF(c->flags, APREQ_COOKIE_HTTPONLY); |
| } |
| |
| |
| /** @return 1 if the taint flag is set, 0 otherwise. */ |
| static APR_INLINE |
| unsigned apreq_cookie_is_tainted(const apreq_cookie_t *c) { |
| return APREQ_FLAGS_GET(c->flags, APREQ_TAINTED); |
| } |
| |
| /** Sets the cookie's tainted flag. */ |
| static APR_INLINE |
| void apreq_cookie_tainted_on(apreq_cookie_t *c) { |
| APREQ_FLAGS_ON(c->flags, APREQ_TAINTED); |
| } |
| |
| /** Turns off the cookie's tainted flag. */ |
| static APR_INLINE |
| void apreq_cookie_tainted_off(apreq_cookie_t *c) { |
| APREQ_FLAGS_OFF(c->flags, APREQ_TAINTED); |
| } |
| |
| /** |
| * Parse a cookie header and store the cookies in an apr_table_t. |
| * |
| * @param pool pool which allocates the cookies |
| * @param jar table where parsed cookies are stored |
| * @param header the header value |
| * |
| * @return APR_SUCCESS. |
| * @return ::APREQ_ERROR_BADSEQ if an unparseable character sequence appears. |
| * @return ::APREQ_ERROR_MISMATCH if an rfc-cookie attribute appears in a |
| * netscape cookie header. |
| * @return ::APR_ENOTIMPL if an unrecognized rfc-cookie attribute appears. |
| * @return ::APREQ_ERROR_NOTOKEN if a required token was not present. |
| * @return ::APREQ_ERROR_BADCHAR if an unexpected token was present. |
| */ |
| APREQ_DECLARE(apr_status_t) apreq_parse_cookie_header(apr_pool_t *pool, |
| apr_table_t *jar, |
| const char *header); |
| |
| /** |
| * Returns a new cookie, made from the argument list. |
| * |
| * @param pool Pool which allocates the cookie. |
| * @param name The cookie's name. |
| * @param nlen Length of name. |
| * @param value The cookie's value. |
| * @param vlen Length of value. |
| * |
| * @return the new cookie |
| */ |
| APREQ_DECLARE(apreq_cookie_t *) apreq_cookie_make(apr_pool_t *pool, |
| const char *name, |
| const apr_size_t nlen, |
| const char *value, |
| const apr_size_t vlen); |
| |
| /** |
| * Returns a string that represents the cookie as it would appear |
| * in a valid "Set-Cookie*" header. |
| * |
| * @param c cookie. |
| * @param p pool which allocates the returned string. |
| * |
| * @return header string. |
| */ |
| APREQ_DECLARE(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 cookie. |
| * @param buf storage location for the result. |
| * @param len size of buf's storage area. |
| * |
| * @return size of resulting header string. |
| */ |
| APREQ_DECLARE(int) apreq_cookie_serialize(const apreq_cookie_t *c, |
| char *buf, apr_size_t len); |
| |
| /** |
| * Set the Cookie's expiration date. |
| * |
| * @param c The cookie. |
| * @param time_str If NULL, the Cookie's expiration date is unset, |
| * making it a session cookie. This means no "expires" or "max-age" |
| * attribute will appear in the cookie's serialized form. If time_str |
| * is not NULL, the expiration date will be reset to the offset (from now) |
| * represented by time_str. The time_str should be in a format that |
| * apreq_atoi64t() can understand, namely /[+-]?\\d+\\s*[YMDhms]/. |
| * |
| * @remarks Now time_str may also be a fixed date; see apr_date_parse_rfc() |
| * for admissible formats. |
| */ |
| APREQ_DECLARE(void) apreq_cookie_expires(apreq_cookie_t *c, |
| const char *time_str); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /*APREQ_COOKIE_H*/ |
| |
| |