/*
**  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*/


