blob: 282cf86fca71fbf7f61f37f11d4cb0a917f0f5ad [file] [log] [blame]
/*
** 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 unparsable 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*/