mirror of
https://github.com/apache/httpd.git
synced 2025-07-29 12:37:06 +00:00
import apreq include files
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1200458 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
308
include/apreq.h
Normal file
308
include/apreq.h
Normal file
@ -0,0 +1,308 @@
|
||||
/*
|
||||
** 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_H
|
||||
#define APREQ_H
|
||||
|
||||
#ifdef APREQ_DEBUG
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#include "apr_tables.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file apreq.h
|
||||
* @brief Main header file...
|
||||
* @ingroup libapreq2
|
||||
*
|
||||
* Define the generic APREQ_ macros and common data structures.
|
||||
*/
|
||||
|
||||
#ifndef WIN32
|
||||
/**
|
||||
* The public APREQ functions are declared with APREQ_DECLARE(), so they may
|
||||
* use the most appropriate calling convention. Public APR functions with
|
||||
* variable arguments must use APR_DECLARE_NONSTD().
|
||||
*
|
||||
* @remark Both the declaration and implementations must use the same macro.
|
||||
*/
|
||||
/** APREQ_DECLARE(rettype) apeq_func(args)
|
||||
*/
|
||||
#define APREQ_DECLARE(d) APR_DECLARE(d)
|
||||
/**
|
||||
* The public APEQ functions using variable arguments are declared with
|
||||
* APEQ_DECLARE_NONSTD(), as they must follow the C language calling convention.
|
||||
* @see APEQ_DECLARE @see APEQ_DECLARE_DATA
|
||||
* @remark Both the declaration and implementations must use the same macro.
|
||||
* @example
|
||||
*/
|
||||
/** APEQ_DECLARE_NONSTD(rettype) apr_func(args, ...);
|
||||
*/
|
||||
#define APREQ_DECLARE_NONSTD(d) APR_DECLARE_NONSTD(d)
|
||||
/**
|
||||
* The public APREQ variables are declared with APREQ_DECLARE_DATA.
|
||||
* This assures the appropriate indirection is invoked at compile time.
|
||||
* @see APREQ_DECLARE @see APREQ_DECLARE_NONSTD
|
||||
* @remark Note that the declaration and implementations use different forms,
|
||||
* but both must include the macro.
|
||||
*/
|
||||
/** extern APREQ_DECLARE_DATA type apr_variable;\n
|
||||
* APREQ_DECLARE_DATA type apr_variable = value;
|
||||
*/
|
||||
#define APREQ_DECLARE_DATA
|
||||
#elif defined (APREQ_DECLARE_STATIC)
|
||||
#define APREQ_DECLARE(type) type __stdcall
|
||||
#define APREQ_DECLARE_NONSTD(type) type
|
||||
#define APREQ_DECLARE_DATA
|
||||
#elif defined (APREQ_DECLARE_EXPORT)
|
||||
#define APREQ_DECLARE(type) __declspec(dllexport) type __stdcall
|
||||
#define APREQ_DECLARE_NONSTD(type) __declspec(dllexport) type
|
||||
#define APREQ_DECLARE_DATA __declspec(dllexport)
|
||||
#else
|
||||
#define APREQ_DECLARE(type) __declspec(dllimport) type __stdcall
|
||||
#define APREQ_DECLARE_NONSTD(type) __declspec(dllimport) type
|
||||
#define APREQ_DECLARE_DATA __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Read chucks of data in 64k blocks from the request
|
||||
*/
|
||||
|
||||
#define APREQ_DEFAULT_READ_BLOCK_SIZE (64 * 1024)
|
||||
|
||||
/**
|
||||
* Maximum number of bytes mod_apreq2 will send off to libapreq2 for parsing.
|
||||
* mod_apreq2 will log this event and subsequently remove itself
|
||||
* from the filter chain.
|
||||
* @see ap_set_read_limit
|
||||
*/
|
||||
#define APREQ_DEFAULT_READ_LIMIT (64 * 1024 * 1024)
|
||||
/**
|
||||
* Maximum number of bytes mod_apreq2 will let accumulate within the
|
||||
* heap-buckets in a brigade. Excess data will be spooled to an
|
||||
* appended file bucket
|
||||
* @see ap_set_brigade_read_limit
|
||||
*/
|
||||
#define APREQ_DEFAULT_BRIGADE_LIMIT (256 * 1024)
|
||||
|
||||
/**
|
||||
* Number of elements in the initial apr_table
|
||||
* @see apr_table_make
|
||||
*/
|
||||
#define APREQ_DEFAULT_NELTS 8
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check to see if specified bit f is off in bitfield name
|
||||
*/
|
||||
#define APREQ_FLAGS_OFF(f, name) ((f) &= ~(name##_MASK << name##_BIT))
|
||||
/**
|
||||
* Check to see if specified bit f is on in bitfield name
|
||||
*/
|
||||
#define APREQ_FLAGS_ON(f, name) ((f) |= (name##_MASK << name##_BIT))
|
||||
/**
|
||||
* Get specified bit f in bitfield name
|
||||
*/
|
||||
#define APREQ_FLAGS_GET(f, name) (((f) >> name##_BIT) & name##_MASK)
|
||||
/**
|
||||
* Set specified bit f in bitfield name to value
|
||||
* Note the below BIT/Mask defines are used sans the
|
||||
* _BIT, _MASK because of the this define's \#\#_MASK, \#\#_BIT usage.
|
||||
* Each come in a pair
|
||||
*/
|
||||
#define APREQ_FLAGS_SET(f, name, value) \
|
||||
((f) = (((f) & ~(name##_MASK << name##_BIT)) \
|
||||
| ((name##_MASK & (value)) << name##_BIT)))
|
||||
|
||||
/**
|
||||
* Charset Bit
|
||||
* @see APREQ_FLAGS_OFF @see APREQ_FLAGS_ON
|
||||
* @see APREQ_FLAGS_GET @see APREQ_FLAGS_SET
|
||||
*/
|
||||
#define APREQ_CHARSET_BIT 0
|
||||
|
||||
/**
|
||||
* Charset Mask
|
||||
* @see APREQ_FLAGS_OFF @see APREQ_FLAGS_ON
|
||||
* @see APREQ_FLAGS_GET @see APREQ_FLAGS_SET
|
||||
*/
|
||||
#define APREQ_CHARSET_MASK 255
|
||||
|
||||
/**
|
||||
* Tainted Bit
|
||||
* @see APREQ_FLAGS_OFF @see APREQ_FLAGS_ON
|
||||
* @see APREQ_FLAGS_GET @see APREQ_FLAGS_SET
|
||||
*/
|
||||
#define APREQ_TAINTED_BIT 8
|
||||
/**
|
||||
* Tainted Mask
|
||||
* @see APREQ_FLAGS_OFF @see APREQ_FLAGS_ON
|
||||
* @see APREQ_FLAGS_GET @see APREQ_FLAGS_SET
|
||||
*/
|
||||
#define APREQ_TAINTED_MASK 1
|
||||
|
||||
/**
|
||||
* Cookier Version Bit
|
||||
* @see APREQ_FLAGS_OFF @see APREQ_FLAGS_ON
|
||||
* @see APREQ_FLAGS_GET @see APREQ_FLAGS_SET
|
||||
*/
|
||||
|
||||
#define APREQ_COOKIE_VERSION_BIT 11
|
||||
/**
|
||||
* Cookie Version Mask
|
||||
* @see APREQ_FLAGS_OFF @see APREQ_FLAGS_ON
|
||||
* @see APREQ_FLAGS_GET @see APREQ_FLAGS_SET
|
||||
*/
|
||||
#define APREQ_COOKIE_VERSION_MASK 3
|
||||
|
||||
/**
|
||||
* Cookie's Secure Bit
|
||||
* @see APREQ_FLAGS_OFF @see APREQ_FLAGS_ON
|
||||
* @see APREQ_FLAGS_GET @see APREQ_FLAGS_SET
|
||||
*/
|
||||
#define APREQ_COOKIE_SECURE_BIT 13
|
||||
/**
|
||||
* Cookie's Secure Mask
|
||||
* @see APREQ_FLAGS_OFF @see APREQ_FLAGS_ON
|
||||
* @see APREQ_FLAGS_GET @see APREQ_FLAGS_SET
|
||||
*/
|
||||
#define APREQ_COOKIE_SECURE_MASK 1
|
||||
|
||||
/**
|
||||
* Cookie's HttpOnly Bit
|
||||
* @see APREQ_FLAGS_OFF @see APREQ_FLAGS_ON
|
||||
* @see APREQ_FLAGS_GET @see APREQ_FLAGS_SET
|
||||
*/
|
||||
#define APREQ_COOKIE_HTTPONLY_BIT 14
|
||||
/**
|
||||
* Cookie's HttpOnly Mask
|
||||
* @see APREQ_FLAGS_OFF @see APREQ_FLAGS_ON
|
||||
* @see APREQ_FLAGS_GET @see APREQ_FLAGS_SET
|
||||
*/
|
||||
#define APREQ_COOKIE_HTTPONLY_MASK 1
|
||||
|
||||
/** Character encodings. */
|
||||
typedef enum {
|
||||
APREQ_CHARSET_ASCII =0,
|
||||
APREQ_CHARSET_LATIN1 =1, /* ISO-8859-1 */
|
||||
APREQ_CHARSET_CP1252 =2, /* Windows-1252 */
|
||||
APREQ_CHARSET_UTF8 =8
|
||||
} apreq_charset_t;
|
||||
|
||||
|
||||
/** @enum apreq_join_t Join type */
|
||||
typedef enum {
|
||||
APREQ_JOIN_AS_IS, /**< Join the strings without modification */
|
||||
APREQ_JOIN_ENCODE, /**< Url-encode the strings before joining them */
|
||||
APREQ_JOIN_DECODE, /**< Url-decode the strings before joining them */
|
||||
APREQ_JOIN_QUOTE /**< Quote the strings, backslashing existing quote marks. */
|
||||
} apreq_join_t;
|
||||
|
||||
/** @enum apreq_match_t Match type */
|
||||
typedef enum {
|
||||
APREQ_MATCH_FULL, /**< Full match only. */
|
||||
APREQ_MATCH_PARTIAL /**< Partial matches are ok. */
|
||||
} apreq_match_t;
|
||||
|
||||
/** @enum apreq_expires_t Expiration date format */
|
||||
typedef enum {
|
||||
APREQ_EXPIRES_HTTP, /**< Use date formatting consistent with RFC 2616 */
|
||||
APREQ_EXPIRES_NSCOOKIE /**< Use format consistent with Netscape's Cookie Spec */
|
||||
} apreq_expires_t;
|
||||
|
||||
|
||||
/** @brief libapreq's pre-extensible string type */
|
||||
typedef struct apreq_value_t {
|
||||
char *name; /**< value name */
|
||||
apr_size_t nlen; /**< length of name */
|
||||
apr_size_t dlen; /**< length of data */
|
||||
char data[1]; /**< value data */
|
||||
} apreq_value_t;
|
||||
|
||||
/**
|
||||
* Adds the specified apreq_value_t to the apr_table_t.
|
||||
*
|
||||
* @param v value to add
|
||||
* @param t add v to this table
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @ see apr_table_t @see apr_value_t
|
||||
*/
|
||||
|
||||
static APR_INLINE
|
||||
void apreq_value_table_add(const apreq_value_t *v, apr_table_t *t) {
|
||||
apr_table_addn(t, v->name, v->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param T type
|
||||
* @param A attribute
|
||||
* @param P
|
||||
*
|
||||
* XXX
|
||||
*/
|
||||
#define apreq_attr_to_type(T,A,P) ( (T*) ((char*)(P)-offsetof(T,A)) )
|
||||
|
||||
/**
|
||||
* Initialize libapreq2. Applications (except apache modules using
|
||||
* mod_apreq) should call this exactly once before they use any
|
||||
* libapreq2 modules. If you want to modify the list of default parsers
|
||||
* with apreq_register_parser(), please use apreq_pre_initialize()
|
||||
* and apreq_post_initialize() instead.
|
||||
*
|
||||
* @param pool a base pool persisting while libapreq2 is used
|
||||
* @remarks after you detroy the pool, you have to call this function again
|
||||
* with a new pool if you still plan to use libapreq2
|
||||
*/
|
||||
APREQ_DECLARE(apr_status_t) apreq_initialize(apr_pool_t *pool);
|
||||
|
||||
|
||||
/**
|
||||
* Pre-initialize libapreq2. Applications (except apache modules using
|
||||
* mod_apreq2) should call this exactly once before they register custom
|
||||
* parsers with libapreq2. mod_apreq2 does this automatically during the
|
||||
* post-config phase, so modules that need call apreq_register_parser should
|
||||
* create a post-config hook using APR_HOOK_MIDDLE.
|
||||
*
|
||||
* @param pool a base pool persisting while libapreq2 is used
|
||||
* @remarks after you detroyed the pool, you have to call this function again
|
||||
* with a new pool if you still plan to use libapreq2
|
||||
*/
|
||||
APREQ_DECLARE(apr_status_t) apreq_pre_initialize(apr_pool_t *pool);
|
||||
|
||||
/**
|
||||
* Post-initialize libapreq2. Applications (except apache modules using
|
||||
* mod_apreq2) should this exactly once before they use any
|
||||
* libapreq2 modules for parsing.
|
||||
*
|
||||
* @param pool the same pool that was used in apreq_pre_initialize().
|
||||
*/
|
||||
APREQ_DECLARE(apr_status_t) apreq_post_initialize(apr_pool_t *pool);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APREQ_H */
|
237
include/apreq_cookie.h
Normal file
237
include/apreq_cookie.h
Normal file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
** 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*/
|
||||
|
||||
|
97
include/apreq_error.h
Normal file
97
include/apreq_error.h
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
** 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_ERROR_H
|
||||
#define APREQ_ERROR_H
|
||||
|
||||
#include "apr_errno.h"
|
||||
#include "apreq.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* apreq's wrapper around apr_strerror();
|
||||
* recognizes APREQ_ERROR_* status codes.
|
||||
*/
|
||||
APREQ_DECLARE(char *)
|
||||
apreq_strerror(apr_status_t s, char *buf, apr_size_t bufsize);
|
||||
|
||||
/**
|
||||
* @file apreq_error.h
|
||||
* @brief Error status codes.
|
||||
* @ingroup libapreq2
|
||||
*
|
||||
* Define the APREQ_ error codes.
|
||||
*/
|
||||
|
||||
#ifndef APR_EBADARG
|
||||
/**
|
||||
* Bad Arguments return value
|
||||
* @see APR_BADARG
|
||||
*/
|
||||
#define APR_EBADARG APR_BADARG /* XXX: don't use APR_BADARG */
|
||||
#endif
|
||||
|
||||
/** Internal apreq error. */
|
||||
#define APREQ_ERROR_GENERAL APR_OS_START_USERERR
|
||||
/** Attempted to perform unsafe action with tainted data. */
|
||||
#define APREQ_ERROR_TAINTED (APREQ_ERROR_GENERAL + 1)
|
||||
/** Parsing interrupted. */
|
||||
#define APREQ_ERROR_INTERRUPT (APREQ_ERROR_GENERAL + 2)
|
||||
|
||||
/** Invalid input data. */
|
||||
#define APREQ_ERROR_BADDATA (APREQ_ERROR_GENERAL + 10)
|
||||
/** Invalid character. */
|
||||
#define APREQ_ERROR_BADCHAR (APREQ_ERROR_BADDATA + 1)
|
||||
/** Invalid byte sequence. */
|
||||
#define APREQ_ERROR_BADSEQ (APREQ_ERROR_BADDATA + 2)
|
||||
/** Invalid attribute. */
|
||||
#define APREQ_ERROR_BADATTR (APREQ_ERROR_BADDATA + 3)
|
||||
/** Invalid header. */
|
||||
#define APREQ_ERROR_BADHEADER (APREQ_ERROR_BADDATA + 4)
|
||||
/** Invalid utf8 encoding. */
|
||||
#define APREQ_ERROR_BADUTF8 (APREQ_ERROR_BADDATA + 5)
|
||||
|
||||
/** Missing input data. */
|
||||
#define APREQ_ERROR_NODATA (APREQ_ERROR_GENERAL + 20)
|
||||
/** Missing required token. */
|
||||
#define APREQ_ERROR_NOTOKEN (APREQ_ERROR_NODATA + 1)
|
||||
/** Missing attribute. */
|
||||
#define APREQ_ERROR_NOATTR (APREQ_ERROR_NODATA + 2)
|
||||
/** Missing header. */
|
||||
#define APREQ_ERROR_NOHEADER (APREQ_ERROR_NODATA + 3)
|
||||
/** Missing parser. */
|
||||
#define APREQ_ERROR_NOPARSER (APREQ_ERROR_NODATA + 4)
|
||||
|
||||
|
||||
/** Conflicting information. */
|
||||
#define APREQ_ERROR_MISMATCH (APREQ_ERROR_GENERAL + 30)
|
||||
/** Exceeds configured maximum limit. */
|
||||
#define APREQ_ERROR_OVERLIMIT (APREQ_ERROR_MISMATCH + 1)
|
||||
/** Below configured minimum limit. */
|
||||
#define APREQ_ERROR_UNDERLIMIT (APREQ_ERROR_MISMATCH + 2)
|
||||
/** Setting already configured. */
|
||||
#define APREQ_ERROR_NOTEMPTY (APREQ_ERROR_MISMATCH + 3)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APREQ_ERROR_H */
|
457
include/apreq_module.h
Normal file
457
include/apreq_module.h
Normal file
@ -0,0 +1,457 @@
|
||||
/*
|
||||
** 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_MODULE_H
|
||||
#define APREQ_MODULE_H
|
||||
|
||||
#include "apreq_cookie.h"
|
||||
#include "apreq_parser.h"
|
||||
#include "apreq_error.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file apreq_module.h
|
||||
* @brief Module API
|
||||
* @ingroup libapreq2
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* An apreq handle associated with a module. The structure
|
||||
* may have variable size, because the module may append its own data
|
||||
* structures after it.
|
||||
*/
|
||||
typedef struct apreq_handle_t {
|
||||
/** the apreq module which implements this handle */
|
||||
const struct apreq_module_t *module;
|
||||
/** the pool which defines the lifetime of the parsed data */
|
||||
apr_pool_t *pool;
|
||||
/** the allocator, which persists at least as long as the pool */
|
||||
apr_bucket_alloc_t *bucket_alloc;
|
||||
|
||||
} apreq_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Vtable describing the necessary module functions.
|
||||
*/
|
||||
|
||||
|
||||
typedef struct apreq_module_t {
|
||||
/** name of this apreq module */
|
||||
const char *name;
|
||||
/** magic number identifying the module and version */
|
||||
apr_uint32_t magic_number;
|
||||
|
||||
/** get a table with all cookies */
|
||||
apr_status_t (*jar)(apreq_handle_t *, const apr_table_t **);
|
||||
/** get a table with all query string parameters */
|
||||
apr_status_t (*args)(apreq_handle_t *, const apr_table_t **);
|
||||
/** get a table with all body parameters */
|
||||
apr_status_t (*body)(apreq_handle_t *, const apr_table_t **);
|
||||
|
||||
/** get a cookie by its name */
|
||||
apreq_cookie_t *(*jar_get)(apreq_handle_t *, const char *);
|
||||
/** get a query string parameter by its name */
|
||||
apreq_param_t *(*args_get)(apreq_handle_t *, const char *);
|
||||
/** get a body parameter by its name */
|
||||
apreq_param_t *(*body_get)(apreq_handle_t *, const char *);
|
||||
|
||||
/** gets the parser associated with the request body */
|
||||
apr_status_t (*parser_get)(apreq_handle_t *, const apreq_parser_t **);
|
||||
/** manually set a parser for the request body */
|
||||
apr_status_t (*parser_set)(apreq_handle_t *, apreq_parser_t *);
|
||||
/** add a hook function */
|
||||
apr_status_t (*hook_add)(apreq_handle_t *, apreq_hook_t *);
|
||||
|
||||
/** determine the maximum in-memory bytes a brigade may use */
|
||||
apr_status_t (*brigade_limit_get)(apreq_handle_t *, apr_size_t *);
|
||||
/** set the maximum in-memory bytes a brigade may use */
|
||||
apr_status_t (*brigade_limit_set)(apreq_handle_t *, apr_size_t);
|
||||
|
||||
/** determine the maximum amount of data that will be fed into a parser */
|
||||
apr_status_t (*read_limit_get)(apreq_handle_t *, apr_uint64_t *);
|
||||
/** set the maximum amount of data that will be fed into a parser */
|
||||
apr_status_t (*read_limit_set)(apreq_handle_t *, apr_uint64_t);
|
||||
|
||||
/** determine the directory used by the parser for temporary files */
|
||||
apr_status_t (*temp_dir_get)(apreq_handle_t *, const char **);
|
||||
/** set the directory used by the parser for temporary files */
|
||||
apr_status_t (*temp_dir_set)(apreq_handle_t *, const char *);
|
||||
|
||||
} apreq_module_t;
|
||||
|
||||
|
||||
/**
|
||||
* Defines the module-specific status codes which
|
||||
* are commonly considered to be non-fatal.
|
||||
*
|
||||
* @param s status code returned by an apreq_module_t method.
|
||||
*
|
||||
* @return 1 if s is fatal, 0 otherwise.
|
||||
*/
|
||||
static APR_INLINE
|
||||
unsigned apreq_module_status_is_error(apr_status_t s) {
|
||||
switch (s) {
|
||||
case APR_SUCCESS:
|
||||
case APR_INCOMPLETE:
|
||||
case APR_EINIT:
|
||||
case APREQ_ERROR_NODATA:
|
||||
case APREQ_ERROR_NOPARSER:
|
||||
case APREQ_ERROR_NOHEADER:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Expose the parsed "cookie" header associated to this handle.
|
||||
*
|
||||
* @param req The request handle
|
||||
* @param t The resulting table, which will either be NULL or a
|
||||
* valid table object on return.
|
||||
*
|
||||
* @return APR_SUCCESS or a module-specific error status code.
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_jar(apreq_handle_t *req, const apr_table_t **t)
|
||||
{
|
||||
return req->module->jar(req,t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose the parsed "query string" associated to this handle.
|
||||
*
|
||||
* @param req The request handle
|
||||
* @param t The resulting table, which will either be NULL or a
|
||||
* valid table object on return.
|
||||
*
|
||||
* @return APR_SUCCESS or a module-specific error status code.
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_args(apreq_handle_t *req, const apr_table_t **t)
|
||||
{
|
||||
return req->module->args(req,t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose the parsed "request body" associated to this handle.
|
||||
*
|
||||
* @param req The request handle
|
||||
* @param t The resulting table, which will either be NULL or a
|
||||
* valid table object on return.
|
||||
*
|
||||
* @return APR_SUCCESS or a module-specific error status code.
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_body(apreq_handle_t *req, const apr_table_t **t)
|
||||
{
|
||||
return req->module->body(req, t);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetch the first cookie with the given name.
|
||||
*
|
||||
* @param req The request handle
|
||||
* @param name Case-insensitive cookie name.
|
||||
*
|
||||
* @return First matching cookie, or NULL if none match.
|
||||
*/
|
||||
static APR_INLINE
|
||||
apreq_cookie_t *apreq_jar_get(apreq_handle_t *req, const char *name)
|
||||
{
|
||||
return req->module->jar_get(req, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the first query string param with the given name.
|
||||
*
|
||||
* @param req The request handle
|
||||
* @param name Case-insensitive param name.
|
||||
*
|
||||
* @return First matching param, or NULL if none match.
|
||||
*/
|
||||
static APR_INLINE
|
||||
apreq_param_t *apreq_args_get(apreq_handle_t *req, const char *name)
|
||||
{
|
||||
return req->module->args_get(req, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the first body param with the given name.
|
||||
*
|
||||
* @param req The request handle
|
||||
* @param name Case-insensitive cookie name.
|
||||
*
|
||||
* @return First matching param, or NULL if none match.
|
||||
*/
|
||||
static APR_INLINE
|
||||
apreq_param_t *apreq_body_get(apreq_handle_t *req, const char *name)
|
||||
{
|
||||
return req->module->body_get(req, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the active body parser.
|
||||
*
|
||||
* @param req The request handle
|
||||
* @param parser Points to the active parser on return.
|
||||
*
|
||||
* @return APR_SUCCESS or module-specific error.
|
||||
*
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_parser_get(apreq_handle_t *req,
|
||||
const apreq_parser_t **parser)
|
||||
{
|
||||
return req->module->parser_get(req, parser);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the body parser for this request.
|
||||
*
|
||||
* @param req The request handle
|
||||
* @param parser New parser to use.
|
||||
*
|
||||
* @return APR_SUCCESS or module-specific error.
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_parser_set(apreq_handle_t *req,
|
||||
apreq_parser_t *parser)
|
||||
{
|
||||
return req->module->parser_set(req, parser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a parser hook for this request.
|
||||
*
|
||||
* @param req The request handle
|
||||
* @param hook Hook to add.
|
||||
*
|
||||
* @return APR_SUCCESS or module-specific error.
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_hook_add(apreq_handle_t *req, apreq_hook_t *hook)
|
||||
{
|
||||
return req->module->hook_add(req, hook);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the active brigade limit.
|
||||
*
|
||||
* @param req The handle.
|
||||
* @param bytes New limit to use.
|
||||
*
|
||||
* @return APR_SUCCESS or module-specific error.
|
||||
*
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_brigade_limit_set(apreq_handle_t *req,
|
||||
apr_size_t bytes)
|
||||
{
|
||||
return req->module->brigade_limit_set(req, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active brigade limit.
|
||||
*
|
||||
* @param req The handle.
|
||||
* @param bytes Pointer to resulting (current) limit.
|
||||
*
|
||||
* @return APR_SUCCESS or a module-specific error,
|
||||
* which may leave bytes undefined.
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_brigade_limit_get(apreq_handle_t *req,
|
||||
apr_size_t *bytes)
|
||||
{
|
||||
return req->module->brigade_limit_get(req, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the active read limit.
|
||||
*
|
||||
* @param req The handle.
|
||||
* @param bytes New limit to use.
|
||||
*
|
||||
* @return APR_SUCCESS or a module-specific error.
|
||||
*
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_read_limit_set(apreq_handle_t *req,
|
||||
apr_uint64_t bytes)
|
||||
{
|
||||
return req->module->read_limit_set(req, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active read limit.
|
||||
*
|
||||
* @param req The request handle.
|
||||
* @param bytes Pointer to resulting (current) limit.
|
||||
*
|
||||
* @return APR_SUCCESS or a module-specific error,
|
||||
* which may leave bytes undefined.
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_read_limit_get(apreq_handle_t *req,
|
||||
apr_uint64_t *bytes)
|
||||
{
|
||||
return req->module->read_limit_get(req, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the active temp directory.
|
||||
*
|
||||
* @param req The handle.
|
||||
* @param path New path to use; may be NULL.
|
||||
*
|
||||
* @return APR_SUCCESS or a module-specific error .
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_temp_dir_set(apreq_handle_t *req, const char *path)
|
||||
{
|
||||
return req->module->temp_dir_set(req, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active temp directory.
|
||||
*
|
||||
* @param req The handle.
|
||||
* @param path Resulting path to temp dir.
|
||||
*
|
||||
* @return APR_SUCCESS implies path is valid, but may also be NULL.
|
||||
* Any other return value is module-specific, and may leave
|
||||
* path undefined.
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_temp_dir_get(apreq_handle_t *req, const char **path)
|
||||
{
|
||||
return req->module->temp_dir_get(req, path);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Convenience macro for defining a module by mapping
|
||||
* a function prefix to an associated apreq_module_t structure.
|
||||
*
|
||||
* @param pre Prefix to define new module. All attributes of
|
||||
* the apreq_module_t struct are defined with this as their
|
||||
* prefix. The generated struct is named by appending "_module" to
|
||||
* the prefix.
|
||||
* @param mmn Magic number (i.e. version number) of this module.
|
||||
*/
|
||||
#define APREQ_MODULE(pre, mmn) const apreq_module_t \
|
||||
pre##_module = { #pre, mmn, \
|
||||
pre##_jar, pre##_args, pre##_body, \
|
||||
pre##_jar_get, pre##_args_get, pre##_body_get, \
|
||||
pre##_parser_get, pre##_parser_set, pre##_hook_add, \
|
||||
pre##_brigade_limit_get, pre##_brigade_limit_set, \
|
||||
pre##_read_limit_get, pre##_read_limit_set, \
|
||||
pre##_temp_dir_get, pre##_temp_dir_set, \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create an apreq handle which is suitable for a CGI program. It
|
||||
* reads input from stdin and writes output to stdout.
|
||||
*
|
||||
* @param pool Pool associated to this handle.
|
||||
*
|
||||
* @return New handle; can only be NULL if the pool allocation failed.
|
||||
*
|
||||
* @remarks The handle gets cached in the pool's userdata, so subsequent
|
||||
* calls will retrieve the original cached handle.
|
||||
*/
|
||||
APREQ_DECLARE(apreq_handle_t*) apreq_handle_cgi(apr_pool_t *pool);
|
||||
|
||||
/**
|
||||
* Create a custom apreq handle which knows only some static
|
||||
* values. Useful if you want to test the parser code or if you have
|
||||
* got data from a custom source (neither Apache 2 nor CGI).
|
||||
*
|
||||
* @param pool allocates the parse data,
|
||||
* @param query_string parsed into args table
|
||||
* @param cookie value of the request "Cookie" header
|
||||
* @param parser parses the request body
|
||||
* @param read_limit maximum bytes to read from the body
|
||||
* @param in brigade containing the request body
|
||||
*
|
||||
* @return new handle; can only be NULL if the pool allocation failed.
|
||||
*/
|
||||
APREQ_DECLARE(apreq_handle_t*) apreq_handle_custom(apr_pool_t *pool,
|
||||
const char *query_string,
|
||||
const char *cookie,
|
||||
apreq_parser_t *parser,
|
||||
apr_uint64_t read_limit,
|
||||
apr_bucket_brigade *in);
|
||||
|
||||
/**
|
||||
* Find the first query string parameter or body parameter with the
|
||||
* specified name. The match is case-insensitive.
|
||||
*
|
||||
* @param req request handle.
|
||||
* @param key desired parameter name
|
||||
*
|
||||
* @return The first matching parameter (with args searched first) or NULL.
|
||||
*/
|
||||
APREQ_DECLARE(apreq_param_t *)apreq_param(apreq_handle_t *req, const char *key);
|
||||
|
||||
/**
|
||||
* Find the first cookie with the specified name.
|
||||
* The match is case-insensitive.
|
||||
*
|
||||
* @param req request handle.
|
||||
* @param name desired cookie name
|
||||
*
|
||||
* @return The first matching cookie or NULL.
|
||||
*/
|
||||
#define apreq_cookie(req, name) apreq_jar_get(req, name)
|
||||
|
||||
/**
|
||||
* Returns a table containing key-value pairs for the full request
|
||||
* (args + body).
|
||||
*
|
||||
* @param req request handle
|
||||
* @param p allocates the returned table.
|
||||
*
|
||||
* @return table representing all available params; is never NULL.
|
||||
*/
|
||||
APREQ_DECLARE(apr_table_t *) apreq_params(apreq_handle_t *req, apr_pool_t *p);
|
||||
|
||||
|
||||
/**
|
||||
* Returns a table containing all request cookies.
|
||||
*
|
||||
* @param req the apreq request handle
|
||||
* @param p Allocates the returned table.
|
||||
*/
|
||||
APREQ_DECLARE(apr_table_t *)apreq_cookies(apreq_handle_t *req, apr_pool_t *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APREQ_MODULE_H */
|
209
include/apreq_param.h
Normal file
209
include/apreq_param.h
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
** 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_PARAM_H
|
||||
#define APREQ_PARAM_H
|
||||
|
||||
#include "apreq.h"
|
||||
#include "apr_buckets.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @file apreq_param.h
|
||||
* @brief Request parsing and parameter API
|
||||
* @ingroup libapreq2
|
||||
*/
|
||||
|
||||
|
||||
/** Common data structure for params and file uploads */
|
||||
typedef struct apreq_param_t {
|
||||
apr_table_t *info; /**< header table associated with the param */
|
||||
apr_bucket_brigade *upload; /**< brigade used to spool upload files */
|
||||
unsigned flags; /**< charsets, taint marks, app-specific bits */
|
||||
const apreq_value_t v; /**< underlying name/value info */
|
||||
} apreq_param_t;
|
||||
|
||||
|
||||
/** @return 1 if the taint flag is set, 0 otherwise. */
|
||||
static APR_INLINE
|
||||
unsigned apreq_param_is_tainted(const apreq_param_t *p) {
|
||||
return APREQ_FLAGS_GET(p->flags, APREQ_TAINTED);
|
||||
}
|
||||
|
||||
/** Sets the tainted flag. */
|
||||
static APR_INLINE
|
||||
void apreq_param_tainted_on(apreq_param_t *p) {
|
||||
APREQ_FLAGS_ON(p->flags, APREQ_TAINTED);
|
||||
}
|
||||
|
||||
/** Turns off the taint flag. */
|
||||
static APR_INLINE
|
||||
void apreq_param_tainted_off(apreq_param_t *p) {
|
||||
APREQ_FLAGS_OFF(p->flags, APREQ_TAINTED);
|
||||
}
|
||||
|
||||
/** Sets the character encoding for this parameter. */
|
||||
static APR_INLINE
|
||||
apreq_charset_t apreq_param_charset_set(apreq_param_t *p, apreq_charset_t c) {
|
||||
apreq_charset_t old = (apreq_charset_t)
|
||||
APREQ_FLAGS_GET(p->flags, APREQ_CHARSET);
|
||||
APREQ_FLAGS_SET(p->flags, APREQ_CHARSET, c);
|
||||
return old;
|
||||
}
|
||||
|
||||
/** Gets the character encoding for this parameter. */
|
||||
static APR_INLINE
|
||||
apreq_charset_t apreq_param_charset_get(apreq_param_t *p) {
|
||||
return (apreq_charset_t)APREQ_FLAGS_GET(p->flags, APREQ_CHARSET);
|
||||
}
|
||||
|
||||
|
||||
/** Upgrades args and body table values to apreq_param_t structs. */
|
||||
static APR_INLINE
|
||||
apreq_param_t *apreq_value_to_param(const char *val)
|
||||
{
|
||||
union { const char *in; char *out; } deconst;
|
||||
|
||||
deconst.in = val;
|
||||
return apreq_attr_to_type(apreq_param_t, v,
|
||||
apreq_attr_to_type(apreq_value_t, data, deconst.out));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** creates a param from name/value information */
|
||||
APREQ_DECLARE(apreq_param_t *) apreq_param_make(apr_pool_t *p,
|
||||
const char *name,
|
||||
const apr_size_t nlen,
|
||||
const char *val,
|
||||
const apr_size_t vlen);
|
||||
|
||||
/**
|
||||
* Url-decodes a name=value pair into a param.
|
||||
*
|
||||
* @param param points to the decoded parameter on success
|
||||
* @param pool Pool from which the param is allocated.
|
||||
* @param word Start of the name=value pair.
|
||||
* @param nlen Length of urlencoded name.
|
||||
* @param vlen Length of urlencoded value.
|
||||
*
|
||||
* @return APR_SUCCESS on success.
|
||||
* @return ::APREQ_ERROR_BADSEQ or ::APREQ_ERROR_BADCHAR on malformed input.
|
||||
*
|
||||
* @remarks Unless vlen == 0, this function assumes there is
|
||||
* exactly one character ('=') which separates the pair.
|
||||
*
|
||||
*/
|
||||
APREQ_DECLARE(apr_status_t) apreq_param_decode(apreq_param_t **param,
|
||||
apr_pool_t *pool,
|
||||
const char *word,
|
||||
apr_size_t nlen,
|
||||
apr_size_t vlen);
|
||||
|
||||
/**
|
||||
* Url-encodes the param into a name-value pair.
|
||||
* @param pool Pool which allocates the returned string.
|
||||
* @param param Param to encode.
|
||||
* @return name-value pair representing the param.
|
||||
*/
|
||||
APREQ_DECLARE(char *) apreq_param_encode(apr_pool_t *pool,
|
||||
const apreq_param_t *param);
|
||||
|
||||
/**
|
||||
* Parse a url-encoded string into a param table.
|
||||
* @param pool pool used to allocate the param data.
|
||||
* @param t table to which the params are added.
|
||||
* @param qs Query string to url-decode.
|
||||
* @return APR_SUCCESS if successful, error otherwise.
|
||||
* @remark This function uses [&;] as the set of tokens
|
||||
* to delineate words, and will treat a word w/o '='
|
||||
* as a name-value pair with value-length = 0.
|
||||
*
|
||||
*/
|
||||
APREQ_DECLARE(apr_status_t) apreq_parse_query_string(apr_pool_t *pool,
|
||||
apr_table_t *t,
|
||||
const char *qs);
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of parameters (apreq_param_t *) matching the given key.
|
||||
* The key is case-insensitive.
|
||||
* @param p Allocates the returned array.
|
||||
* @param t the parameter table returned by apreq_args(), apreq_body()
|
||||
* or apreq_params()
|
||||
* @param key Null-terminated search key, case insensitive.
|
||||
* key==NULL fetches all parameters.
|
||||
* @return an array of apreq_param_t* (pointers)
|
||||
* @remark Also parses the request if necessary.
|
||||
*/
|
||||
APREQ_DECLARE(apr_array_header_t *) apreq_params_as_array(apr_pool_t *p,
|
||||
const apr_table_t *t,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* Returns a ", " -joined string containing all parameters
|
||||
* for the requested key, an empty string if none are found.
|
||||
* The key is case-insensitive.
|
||||
*
|
||||
* @param p Allocates the return string.
|
||||
* @param t the parameter table returned by apreq_args(), apreq_body()
|
||||
* or apreq_params()
|
||||
* @param key Null-terminated parameter name, case insensitive.
|
||||
* key==NULL fetches all values.
|
||||
* @param mode Join type- see apreq_join().
|
||||
* @return the joined string or NULL on error
|
||||
* @remark Also parses the request if necessary.
|
||||
*/
|
||||
APREQ_DECLARE(const char *) apreq_params_as_string(apr_pool_t *p,
|
||||
const apr_table_t *t,
|
||||
const char *key,
|
||||
apreq_join_t mode);
|
||||
|
||||
/**
|
||||
* Returns a table of all params in req->body with non-NULL upload brigades.
|
||||
* @param body parameter table returned by apreq_body() or apreq_params()
|
||||
* @param pool Pool which allocates the table struct.
|
||||
* @return Upload table.
|
||||
* @remark Will parse the request if necessary.
|
||||
*/
|
||||
APREQ_DECLARE(const apr_table_t *) apreq_uploads(const apr_table_t *body,
|
||||
apr_pool_t *pool);
|
||||
|
||||
/**
|
||||
* Returns the first param in req->body which has both param->v.name
|
||||
* matching key (case insensitive) and param->upload != NULL.
|
||||
* @param body parameter table returned by apreq_body() or apreq_params()
|
||||
* @param name Parameter name. key == NULL returns first upload.
|
||||
* @return Corresponding upload, NULL if none found.
|
||||
* @remark Will parse the request as necessary.
|
||||
*/
|
||||
APREQ_DECLARE(const apreq_param_t *) apreq_upload(const apr_table_t *body,
|
||||
const char *name);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APREQ_PARAM_H */
|
||||
|
||||
|
||||
|
300
include/apreq_parser.h
Normal file
300
include/apreq_parser.h
Normal file
@ -0,0 +1,300 @@
|
||||
/*
|
||||
** 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_PARSERS_H
|
||||
#define APREQ_PARSERS_H
|
||||
/* These structs are defined below */
|
||||
|
||||
#include "apreq_param.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @file apreq_parser.h
|
||||
* @brief Request body parser API
|
||||
* @ingroup libapreq2
|
||||
*/
|
||||
|
||||
/**
|
||||
* A hook is called by the parser whenever data arrives in a file
|
||||
* upload parameter of the request body. You may associate any number
|
||||
* of hooks with a parser instance with apreq_parser_add_hook().
|
||||
*/
|
||||
typedef struct apreq_hook_t apreq_hook_t;
|
||||
|
||||
/**
|
||||
* A request body parser instance.
|
||||
*/
|
||||
typedef struct apreq_parser_t apreq_parser_t;
|
||||
|
||||
/** Parser arguments. */
|
||||
#define APREQ_PARSER_ARGS apreq_parser_t *parser, \
|
||||
apr_table_t *t, \
|
||||
apr_bucket_brigade *bb
|
||||
|
||||
/** Hook arguments */
|
||||
#define APREQ_HOOK_ARGS apreq_hook_t *hook, \
|
||||
apreq_param_t *param, \
|
||||
apr_bucket_brigade *bb
|
||||
|
||||
/**
|
||||
* The callback function implementing a request body parser.
|
||||
*/
|
||||
typedef apr_status_t (*apreq_parser_function_t)(APREQ_PARSER_ARGS);
|
||||
|
||||
/**
|
||||
* The callback function of a hook. See apreq_hook_t.
|
||||
*/
|
||||
typedef apr_status_t (*apreq_hook_function_t)(APREQ_HOOK_ARGS);
|
||||
|
||||
/**
|
||||
* Declares a API parser.
|
||||
*/
|
||||
#define APREQ_DECLARE_PARSER(f) APREQ_DECLARE_NONSTD(apr_status_t) \
|
||||
(f) (APREQ_PARSER_ARGS)
|
||||
|
||||
/**
|
||||
* Declares an API hook.
|
||||
*/
|
||||
#define APREQ_DECLARE_HOOK(f) APREQ_DECLARE_NONSTD(apr_status_t) \
|
||||
(f) (APREQ_HOOK_ARGS)
|
||||
|
||||
/**
|
||||
* A hook is called by the parser whenever data arrives in a file
|
||||
* upload parameter of the request body. You may associate any number
|
||||
* of hooks with a parser instance with apreq_parser_add_hook().
|
||||
*/
|
||||
struct apreq_hook_t {
|
||||
apreq_hook_function_t hook; /**< the hook function */
|
||||
apreq_hook_t *next; /**< next item in the linked list */
|
||||
apr_pool_t *pool; /**< pool which allocated this hook */
|
||||
void *ctx; /**< a user defined pointer passed to the hook function */
|
||||
};
|
||||
|
||||
/**
|
||||
* A request body parser instance.
|
||||
*/
|
||||
struct apreq_parser_t {
|
||||
/** the function which parses chunks of body data */
|
||||
apreq_parser_function_t parser;
|
||||
/** the Content-Type request header */
|
||||
const char *content_type;
|
||||
/** a pool which outlasts the bucket_alloc. */
|
||||
apr_pool_t *pool;
|
||||
/** bucket allocator used to create bucket brigades */
|
||||
apr_bucket_alloc_t *bucket_alloc;
|
||||
/** the maximum in-memory bytes a brigade may use */
|
||||
apr_size_t brigade_limit;
|
||||
/** the directory for generating temporary files */
|
||||
const char *temp_dir;
|
||||
/** linked list of hooks */
|
||||
apreq_hook_t *hook;
|
||||
/** internal context pointer used by the parser function */
|
||||
void *ctx;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parse the incoming brigade into a table. Parsers normally
|
||||
* consume all the buckets of the brigade during parsing. However
|
||||
* parsers may leave "rejected" data in the brigade, even during a
|
||||
* successful parse, so callers may need to clean up the brigade
|
||||
* themselves (in particular, rejected buckets should not be
|
||||
* passed back to the parser again).
|
||||
* @remark bb == NULL is valid: the parser should return its
|
||||
* public status: APR_INCOMPLETE, APR_SUCCESS, or an error code.
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_parser_run(struct apreq_parser_t *psr, apr_table_t *t,
|
||||
apr_bucket_brigade *bb)
|
||||
{
|
||||
return psr->parser(psr, t, bb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the hook with the current parameter and the incoming
|
||||
* bucket brigade. The hook may modify the brigade if necessary.
|
||||
* Once all hooks have completed, the contents of the brigade will
|
||||
* be added to the parameter's bb attribute.
|
||||
* @return APR_SUCCESS on success. All other values represent errors.
|
||||
*/
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_hook_run(struct apreq_hook_t *h, apreq_param_t *param,
|
||||
apr_bucket_brigade *bb)
|
||||
{
|
||||
return h->hook(h, param, bb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* RFC 822 Header parser. It will reject all data
|
||||
* after the first CRLF CRLF sequence (an empty line).
|
||||
* See apreq_parser_run() for more info on rejected data.
|
||||
*/
|
||||
APREQ_DECLARE_PARSER(apreq_parse_headers);
|
||||
|
||||
/**
|
||||
* RFC 2396 application/x-www-form-urlencoded parser.
|
||||
*/
|
||||
APREQ_DECLARE_PARSER(apreq_parse_urlencoded);
|
||||
|
||||
/**
|
||||
* RFC 2388 multipart/form-data (and XForms 1.0 multipart/related)
|
||||
* parser. It will reject any buckets representing preamble and
|
||||
* postamble text (this is normal behavior, not an error condition).
|
||||
* See apreq_parser_run() for more info on rejected data.
|
||||
*/
|
||||
APREQ_DECLARE_PARSER(apreq_parse_multipart);
|
||||
|
||||
/**
|
||||
* Generic parser. No table entries will be added to
|
||||
* the req->body table by this parser. The parser creates
|
||||
* a dummy apreq_param_t to pass to any configured hooks. If
|
||||
* no hooks are configured, the dummy param's bb slot will
|
||||
* contain a copy of the request body. It can be retrieved
|
||||
* by casting the parser's ctx pointer to (apreq_param_t **).
|
||||
*/
|
||||
APREQ_DECLARE_PARSER(apreq_parse_generic);
|
||||
|
||||
/**
|
||||
* apr_xml_parser hook. It will parse until EOS appears.
|
||||
* The parsed document isn't available until parsing has
|
||||
* completed successfully. The hook's ctx pointer may
|
||||
* be cast as (apr_xml_doc **) to retrieve the
|
||||
* parsed document.
|
||||
*/
|
||||
APREQ_DECLARE_HOOK(apreq_hook_apr_xml_parser);
|
||||
|
||||
/**
|
||||
* Construct a parser.
|
||||
*
|
||||
* @param pool Pool used to allocate the parser.
|
||||
* @param ba bucket allocator used to create bucket brigades
|
||||
* @param content_type Content-type that this parser can deal with.
|
||||
* @param pfn The parser function.
|
||||
* @param brigade_limit the maximum in-memory bytes a brigade may use
|
||||
* @param temp_dir the directory used by the parser for temporary files
|
||||
* @param hook Hooks to associate this parser with.
|
||||
* @param ctx Parser's internal scratch pad.
|
||||
* @return New parser.
|
||||
*/
|
||||
APREQ_DECLARE(apreq_parser_t *) apreq_parser_make(apr_pool_t *pool,
|
||||
apr_bucket_alloc_t *ba,
|
||||
const char *content_type,
|
||||
apreq_parser_function_t pfn,
|
||||
apr_size_t brigade_limit,
|
||||
const char *temp_dir,
|
||||
apreq_hook_t *hook,
|
||||
void *ctx);
|
||||
|
||||
/**
|
||||
* Construct a hook.
|
||||
*
|
||||
* @param pool used to allocate the hook.
|
||||
* @param hook The hook function.
|
||||
* @param next List of other hooks for this hook to call on.
|
||||
* @param ctx Hook's internal scratch pad.
|
||||
* @return New hook.
|
||||
*/
|
||||
APREQ_DECLARE(apreq_hook_t *) apreq_hook_make(apr_pool_t *pool,
|
||||
apreq_hook_function_t hook,
|
||||
apreq_hook_t *next,
|
||||
void *ctx);
|
||||
|
||||
|
||||
/**
|
||||
* Add a new hook to the end of the parser's hook list.
|
||||
*
|
||||
* @param p Parser.
|
||||
* @param h Hook to append.
|
||||
*/
|
||||
APREQ_DECLARE(apr_status_t) apreq_parser_add_hook(apreq_parser_t *p,
|
||||
apreq_hook_t *h);
|
||||
|
||||
|
||||
/**
|
||||
* Fetch the default parser function associated with the given MIME type.
|
||||
* @param enctype The desired enctype (can also be a full "Content-Type"
|
||||
* header).
|
||||
* @return The parser function, or NULL if the enctype is unrecognized.
|
||||
*/
|
||||
APREQ_DECLARE(apreq_parser_function_t)apreq_parser(const char *enctype);
|
||||
|
||||
|
||||
/**
|
||||
* Register a new parsing function with a MIME enctype.
|
||||
* Registered parsers are added to apreq_parser()'s
|
||||
* internal lookup table.
|
||||
*
|
||||
* @param enctype The MIME type.
|
||||
* @param pfn The function to use during parsing. Setting
|
||||
* parser == NULL will remove an existing parser.
|
||||
*
|
||||
* @return APR_SUCCESS or error.
|
||||
*/
|
||||
|
||||
APREQ_DECLARE(apr_status_t) apreq_register_parser(const char *enctype,
|
||||
apreq_parser_function_t pfn);
|
||||
|
||||
|
||||
/**
|
||||
* Returns APREQ_ERROR_GENERAL. Effectively disables mfd parser
|
||||
* if a file-upload field is present.
|
||||
*
|
||||
*/
|
||||
APREQ_DECLARE_HOOK(apreq_hook_disable_uploads);
|
||||
|
||||
/**
|
||||
* Calls apr_brigade_cleanup on the incoming brigade
|
||||
* after passing the brigade to any subsequent hooks.
|
||||
*/
|
||||
APREQ_DECLARE_HOOK(apreq_hook_discard_brigade);
|
||||
|
||||
/**
|
||||
* Context struct for the apreq_hook_find_param hook.
|
||||
*/
|
||||
typedef struct apreq_hook_find_param_ctx_t {
|
||||
const char *name;
|
||||
apreq_param_t *param;
|
||||
apreq_hook_t *prev;
|
||||
} apreq_hook_find_param_ctx_t;
|
||||
|
||||
|
||||
/**
|
||||
* Special purpose utility for locating a parameter
|
||||
* during parsing. The hook's ctx shoud be initialized
|
||||
* to an apreq_hook_find_param_ctx_t *, with the name
|
||||
* attribute set to the sought parameter name, the param
|
||||
* attribute set to NULL, and the prev attribute set to
|
||||
* the address of the previous hook. The param attribute
|
||||
* will be reassigned to the first param found, and once
|
||||
* that happens this hook is immediately removed from the chain.
|
||||
*
|
||||
* @remarks When used, this should always be the first hook
|
||||
* invoked, so add it manually with ctx->prev = &parser->hook
|
||||
* instead of using apreq_parser_add_hook.
|
||||
*/
|
||||
APREQ_DECLARE_HOOK(apreq_hook_find_param);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* APREQ_PARSERS_H */
|
443
include/apreq_util.h
Normal file
443
include/apreq_util.h
Normal file
@ -0,0 +1,443 @@
|
||||
/*
|
||||
** 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_UTIL_H
|
||||
#define APREQ_UTIL_H
|
||||
|
||||
#include "apr_file_io.h"
|
||||
#include "apr_buckets.h"
|
||||
#include "apreq.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This header contains useful functions for creating new
|
||||
* parsers, hooks or modules. It includes
|
||||
*
|
||||
* - string <-> array converters
|
||||
* - substring search functions
|
||||
* - simple encoders & decoders for urlencoded strings
|
||||
* - simple time, date, & file-size converters
|
||||
* @file apreq_util.h
|
||||
* @brief Utility functions for apreq.
|
||||
* @ingroup libapreq2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Join an array of values. The result is an empty string if there are
|
||||
* no values.
|
||||
*
|
||||
* @param p Pool to allocate return value.
|
||||
* @param sep String that is inserted between the joined values.
|
||||
* @param arr Array of apreq_value_t entries.
|
||||
* @param mode Join type- see apreq_join_t.
|
||||
*
|
||||
* @return Joined string, or NULL on error
|
||||
*/
|
||||
APREQ_DECLARE(char *) apreq_join(apr_pool_t *p,
|
||||
const char *sep,
|
||||
const apr_array_header_t *arr,
|
||||
apreq_join_t mode);
|
||||
|
||||
/**
|
||||
* Returns offset of match string's location, or -1 if no match is found.
|
||||
*
|
||||
* @param hay Location of bytes to scan.
|
||||
* @param hlen Number of bytes available for scanning.
|
||||
* @param ndl Search string
|
||||
* @param nlen Length of search string.
|
||||
* @param type Match type.
|
||||
*
|
||||
* @return Offset of match string, or -1 if no match is found.
|
||||
*
|
||||
*/
|
||||
APREQ_DECLARE(apr_ssize_t) apreq_index(const char* hay, apr_size_t hlen,
|
||||
const char* ndl, apr_size_t nlen,
|
||||
const apreq_match_t type);
|
||||
|
||||
/**
|
||||
* Places a quoted copy of src into dest. Embedded quotes are escaped with a
|
||||
* backslash ('\').
|
||||
*
|
||||
* @param dest Location of quoted copy. Must be large enough to hold the copy
|
||||
* and trailing null byte.
|
||||
* @param src Original string.
|
||||
* @param slen Length of original string.
|
||||
* @param dest Destination string.
|
||||
*
|
||||
* @return length of quoted copy in dest.
|
||||
*/
|
||||
APREQ_DECLARE(apr_size_t) apreq_quote(char *dest, const char *src,
|
||||
const apr_size_t slen);
|
||||
|
||||
/**
|
||||
*
|
||||
* Same as apreq_quote() except when src begins and ends in quote marks. In
|
||||
* that case it assumes src is quoted correctly, and just copies src to dest.
|
||||
*
|
||||
* @param dest Location of quoted copy. Must be large enough to hold the copy
|
||||
* and trailing null byte.
|
||||
* @param src Original string.
|
||||
* @param slen Length of original string.
|
||||
* @param dest Destination string.
|
||||
*
|
||||
* @return length of quoted copy in dest.
|
||||
*/
|
||||
APREQ_DECLARE(apr_size_t) apreq_quote_once(char *dest, const char *src,
|
||||
const apr_size_t slen);
|
||||
|
||||
/**
|
||||
* Url-encodes a string.
|
||||
*
|
||||
* @param dest Location of url-encoded result string. Caller must ensure it
|
||||
* is large enough to hold the encoded string and trailing '\\0'.
|
||||
* @param src Original string.
|
||||
* @param slen Length of original string.
|
||||
*
|
||||
* @return length of url-encoded string in dest; does not exceed 3 * slen.
|
||||
*/
|
||||
APREQ_DECLARE(apr_size_t) apreq_encode(char *dest, const char *src,
|
||||
const apr_size_t slen);
|
||||
|
||||
/**
|
||||
* Convert a string from cp1252 to utf8. Caller must ensure it is large enough
|
||||
* to hold the encoded string and trailing '\\0'.
|
||||
*
|
||||
* @param dest Location of utf8-encoded result string. Caller must ensure it
|
||||
* is large enough to hold the encoded string and trailing '\\0'.
|
||||
* @param src Original string.
|
||||
* @param slen Length of original string.
|
||||
*
|
||||
* @return length of utf8-encoded string in dest; does not exceed 3 * slen.
|
||||
*/
|
||||
APREQ_DECLARE(apr_size_t) apreq_cp1252_to_utf8(char *dest,
|
||||
const char *src, apr_size_t slen);
|
||||
|
||||
/**
|
||||
* Heuristically determine the charset of a string.
|
||||
*
|
||||
* @param src String to scan.
|
||||
* @param slen Length of string.
|
||||
*
|
||||
* @return APREQ_CHARSET_ASCII if the string contains only 7-bit chars;
|
||||
* @return APREQ_CHARSET_UTF8 if the string is a valid utf8 byte sequence;
|
||||
* @return APREQ_CHARSET_LATIN1 if the string has no control chars;
|
||||
* @return APREQ_CHARSET_CP1252 if the string has control chars.
|
||||
*/
|
||||
APREQ_DECLARE(apreq_charset_t) apreq_charset_divine(const char *src,
|
||||
apr_size_t slen);
|
||||
|
||||
/**
|
||||
* Url-decodes a string.
|
||||
*
|
||||
* @param dest Location of url-encoded result string. Caller must ensure dest is
|
||||
* large enough to hold the encoded string and trailing null character.
|
||||
* @param dlen points to resultant length of url-decoded string in dest
|
||||
* @param src Original string.
|
||||
* @param slen Length of original string.
|
||||
*
|
||||
* @return APR_SUCCESS.
|
||||
* @return APR_INCOMPLETE if the string
|
||||
* ends in the middle of an escape sequence.
|
||||
* @return ::APREQ_ERROR_BADSEQ or ::APREQ_ERROR_BADCHAR on malformed input.
|
||||
*
|
||||
* @remarks In the non-success case, dlen will be set to include
|
||||
* the last succesfully decoded value. This function decodes
|
||||
* \%uXXXX into a utf8 (wide) character, following ECMA-262
|
||||
* (the Javascript spec) Section B.2.1.
|
||||
*/
|
||||
|
||||
APREQ_DECLARE(apr_status_t) apreq_decode(char *dest, apr_size_t *dlen,
|
||||
const char *src, apr_size_t slen);
|
||||
|
||||
/**
|
||||
* Url-decodes an iovec array.
|
||||
*
|
||||
* @param dest Location of url-encoded result string. Caller must ensure dest is
|
||||
* large enough to hold the encoded string and trailing null character.
|
||||
* @param dlen Resultant length of dest.
|
||||
* @param v Array of iovecs that represent the source string
|
||||
* @param nelts Number of iovecs in the array.
|
||||
*
|
||||
* @return APR_SUCCESS.
|
||||
* @return APR_INCOMPLETE if the iovec
|
||||
* ends in the middle of an escape sequence.
|
||||
* @return ::APREQ_ERROR_BADSEQ or ::APREQ_ERROR_BADCHAR on malformed input.
|
||||
*
|
||||
* @remarks In the non-APR_SUCCESS case, dlen will be set to include
|
||||
* the last succesfully decoded value. This function decodes
|
||||
* \%uXXXX into a utf8 (wide) character, following ECMA-262
|
||||
* (the Javascript spec) Section B.2.1.
|
||||
*/
|
||||
|
||||
APREQ_DECLARE(apr_status_t) apreq_decodev(char *dest, apr_size_t *dlen,
|
||||
struct iovec *v, int nelts);
|
||||
|
||||
/**
|
||||
* Returns an url-encoded copy of a string.
|
||||
*
|
||||
* @param p Pool used to allocate the return value.
|
||||
* @param src Original string.
|
||||
* @param slen Length of original string.
|
||||
*
|
||||
* @return The url-encoded string.
|
||||
*
|
||||
* @remarks Use this function insead of apreq_encode if its
|
||||
* caller might otherwise overflow dest.
|
||||
*/
|
||||
static APR_INLINE
|
||||
char *apreq_escape(apr_pool_t *p, const char *src, const apr_size_t slen)
|
||||
{
|
||||
char *rv;
|
||||
|
||||
if (src == NULL)
|
||||
return NULL;
|
||||
|
||||
rv = (char *)apr_palloc(p, 3 * slen + 1);
|
||||
apreq_encode(rv, src, slen);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* An \e in-situ url-decoder.
|
||||
*
|
||||
* @param str The string to decode
|
||||
*
|
||||
* @return Length of decoded string, or < 0 on error.
|
||||
*/
|
||||
static APR_INLINE apr_ssize_t apreq_unescape(char *str)
|
||||
{
|
||||
apr_size_t len;
|
||||
apr_status_t rv = apreq_decode(str, &len, str, strlen(str));
|
||||
if (rv == APR_SUCCESS)
|
||||
return (apr_ssize_t)len;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts file sizes (KMG) to bytes
|
||||
*
|
||||
* @param s file size matching m/^\\d+[KMG]b?$/i
|
||||
*
|
||||
* @return 64-bit integer representation of s.
|
||||
*
|
||||
* @todo What happens when s is malformed? Should this return
|
||||
* an unsigned value instead?
|
||||
*/
|
||||
|
||||
APREQ_DECLARE(apr_int64_t) apreq_atoi64f(const char *s);
|
||||
|
||||
/**
|
||||
* Converts time strings (YMDhms) to seconds
|
||||
*
|
||||
* @param s time string matching m/^\\+?\\d+[YMDhms]$/
|
||||
*
|
||||
* @return 64-bit integer representation of s as seconds.
|
||||
*
|
||||
* @todo What happens when s is malformed? Should this return
|
||||
* an unsigned value instead?
|
||||
*/
|
||||
|
||||
APREQ_DECLARE(apr_int64_t) apreq_atoi64t(const char *s);
|
||||
|
||||
/**
|
||||
* Writes brigade to a file.
|
||||
*
|
||||
* @param f File that gets the brigade.
|
||||
* @param wlen On a successful return, wlen holds the length of
|
||||
* the brigade, which is the amount of data written to
|
||||
* the file.
|
||||
* @param bb Bucket brigade.
|
||||
*
|
||||
* @return APR_SUCCESS.
|
||||
* @return Error status code from either an unsuccessful apr_bucket_read(),
|
||||
* or a failed apr_file_writev().
|
||||
*
|
||||
* @remarks This function leaks a bucket brigade into bb->p whenever
|
||||
* the final bucket in bb is a spool bucket.
|
||||
*/
|
||||
|
||||
APREQ_DECLARE(apr_status_t) apreq_brigade_fwrite(apr_file_t *f,
|
||||
apr_off_t *wlen,
|
||||
apr_bucket_brigade *bb);
|
||||
/**
|
||||
* Makes a temporary file.
|
||||
*
|
||||
* @param fp Points to the temporary apr_file_t on success.
|
||||
* @param pool Pool to associate with the temp file. When the
|
||||
* pool is destroyed, the temp file will be closed
|
||||
* and deleted.
|
||||
* @param path The base directory which will contain the temp file.
|
||||
* If param == NULL, the directory will be selected via
|
||||
* tempnam(). See the tempnam manpage for details.
|
||||
*
|
||||
* @return APR_SUCCESS.
|
||||
* @return Error status code from unsuccessful apr_filepath_merge(),
|
||||
* or a failed apr_file_mktemp().
|
||||
*/
|
||||
|
||||
APREQ_DECLARE(apr_status_t) apreq_file_mktemp(apr_file_t **fp,
|
||||
apr_pool_t *pool,
|
||||
const char *path);
|
||||
|
||||
/**
|
||||
* Set aside all buckets in the brigade.
|
||||
*
|
||||
* @param bb Brigade.
|
||||
* @param p Setaside buckets into this pool.
|
||||
* @return APR_SUCCESS.
|
||||
* @return Error status code from an unsuccessful apr_bucket_setaside().
|
||||
*/
|
||||
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_brigade_setaside(apr_bucket_brigade *bb, apr_pool_t *p)
|
||||
{
|
||||
apr_bucket *e;
|
||||
for (e = APR_BRIGADE_FIRST(bb); e != APR_BRIGADE_SENTINEL(bb);
|
||||
e = APR_BUCKET_NEXT(e))
|
||||
{
|
||||
apr_status_t rv = apr_bucket_setaside(e, p);
|
||||
if (rv != APR_SUCCESS)
|
||||
return rv;
|
||||
}
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy a brigade.
|
||||
*
|
||||
* @param d (destination) Copied buckets are appended to this brigade.
|
||||
* @param s (source) Brigade to copy from.
|
||||
*
|
||||
* @return APR_SUCCESS.
|
||||
* @return Error status code from an unsuccessful apr_bucket_copy().
|
||||
*
|
||||
* @remarks s == d produces Undefined Behavior.
|
||||
*/
|
||||
|
||||
static APR_INLINE
|
||||
apr_status_t apreq_brigade_copy(apr_bucket_brigade *d, apr_bucket_brigade *s) {
|
||||
apr_bucket *e;
|
||||
for (e = APR_BRIGADE_FIRST(s); e != APR_BRIGADE_SENTINEL(s);
|
||||
e = APR_BUCKET_NEXT(e))
|
||||
{
|
||||
apr_bucket *c;
|
||||
apr_status_t rv = apr_bucket_copy(e, &c);
|
||||
if (rv != APR_SUCCESS)
|
||||
return rv;
|
||||
|
||||
APR_BRIGADE_INSERT_TAIL(d, c);
|
||||
}
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the front of a brigade.
|
||||
*
|
||||
* @param d (destination) Append buckets to this brigade.
|
||||
* @param s (source) Brigade to take buckets from.
|
||||
* @param e First bucket of s after the move. All buckets
|
||||
* before e are appended to d.
|
||||
*
|
||||
* @remarks This moves all buckets when e == APR_BRIGADE_SENTINEL(s).
|
||||
*/
|
||||
|
||||
static APR_INLINE
|
||||
void apreq_brigade_move(apr_bucket_brigade *d, apr_bucket_brigade *s,
|
||||
apr_bucket *e)
|
||||
{
|
||||
apr_bucket *f;
|
||||
|
||||
if (e != APR_BRIGADE_SENTINEL(s)) {
|
||||
f = APR_RING_FIRST(&s->list);
|
||||
if (f == e) /* zero buckets to be moved */
|
||||
return;
|
||||
|
||||
/* obtain the last bucket to be moved */
|
||||
e = APR_RING_PREV(e, link);
|
||||
|
||||
APR_RING_UNSPLICE(f, e, link);
|
||||
APR_RING_SPLICE_HEAD(&d->list, f, e, apr_bucket, link);
|
||||
}
|
||||
else {
|
||||
APR_BRIGADE_CONCAT(d, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search a header string for the value of a particular named attribute.
|
||||
*
|
||||
* @param hdr Header string to scan.
|
||||
* @param name Name of attribute to search for.
|
||||
* @param nlen Length of name.
|
||||
* @param val Location of (first) matching value.
|
||||
* @param vlen Length of matching value.
|
||||
*
|
||||
* @return APR_SUCCESS.
|
||||
* @return ::APREQ_ERROR_NOATTR if the attribute is not found.
|
||||
* @return ::APREQ_ERROR_BADSEQ if an unpaired quote mark was detected.
|
||||
*/
|
||||
APREQ_DECLARE(apr_status_t) apreq_header_attribute(const char *hdr,
|
||||
const char *name,
|
||||
const apr_size_t nlen,
|
||||
const char **val,
|
||||
apr_size_t *vlen);
|
||||
|
||||
|
||||
/**
|
||||
* Concatenates the brigades, spooling large brigades into
|
||||
* a tempfile (APREQ_SPOOL) bucket.
|
||||
*
|
||||
* @param pool Pool for creating a tempfile bucket.
|
||||
* @param temp_dir Directory for tempfile creation.
|
||||
* @param brigade_limit If out's length would exceed this value,
|
||||
* the appended buckets get written to a tempfile.
|
||||
* @param out Resulting brigade.
|
||||
* @param in Brigade to append.
|
||||
*
|
||||
* @return APR_SUCCESS.
|
||||
* @return Error status code resulting from either apr_brigade_length(),
|
||||
* apreq_file_mktemp(), apreq_brigade_fwrite(), or apr_file_seek().
|
||||
*
|
||||
* @todo Flesh out these error codes, making them as explicit as possible.
|
||||
*/
|
||||
APREQ_DECLARE(apr_status_t) apreq_brigade_concat(apr_pool_t *pool,
|
||||
const char *temp_dir,
|
||||
apr_size_t brigade_limit,
|
||||
apr_bucket_brigade *out,
|
||||
apr_bucket_brigade *in);
|
||||
|
||||
/**
|
||||
* Determines the spool file used by the brigade. Returns NULL if the
|
||||
* brigade is not spooled in a file (does not use an APREQ_SPOOL
|
||||
* bucket).
|
||||
*
|
||||
* @param bb the bucket brigade
|
||||
* @return the spool file, or NULL.
|
||||
*/
|
||||
APREQ_DECLARE(apr_file_t *)apreq_brigade_spoolfile(apr_bucket_brigade *bb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APREQ_UTIL_H */
|
105
include/apreq_version.h
Normal file
105
include/apreq_version.h
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
** 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_VERSION_H
|
||||
#define APREQ_VERSION_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "apr_version.h"
|
||||
#include "apreq.h"
|
||||
|
||||
/**
|
||||
* @file apreq_version.h
|
||||
* @brief Versioning API for libapreq
|
||||
* @ingroup libapreq2
|
||||
*
|
||||
* There are several different mechanisms for accessing the version. There
|
||||
* is a string form, and a set of numbers; in addition, there are constants
|
||||
* which can be compiled into your application, and you can query the library
|
||||
* being used for its actual version.
|
||||
*
|
||||
* Note that it is possible for an application to detect that it has been
|
||||
* compiled against a different version of libapreq by use of the compile-time
|
||||
* constants and the use of the run-time query function.
|
||||
*
|
||||
* libapreq version numbering follows the guidelines specified in:
|
||||
*
|
||||
* http://apr.apache.org/versioning.html
|
||||
*/
|
||||
|
||||
/* The numeric compile-time version constants. These constants are the
|
||||
* authoritative version numbers for libapreq.
|
||||
*/
|
||||
|
||||
/** major version
|
||||
* Major API changes that could cause compatibility problems for older
|
||||
* programs such as structure size changes. No binary compatibility is
|
||||
* possible across a change in the major version.
|
||||
*/
|
||||
#define APREQ_MAJOR_VERSION 2
|
||||
|
||||
/**
|
||||
* Minor API changes that do not cause binary compatibility problems.
|
||||
* Should be reset to 0 when upgrading APREQ_MAJOR_VERSION
|
||||
*/
|
||||
#define APREQ_MINOR_VERSION 8
|
||||
|
||||
/** patch level */
|
||||
#define APREQ_PATCH_VERSION 0
|
||||
|
||||
/**
|
||||
* This symbol is defined for internal, "development" copies of libapreq.
|
||||
* This symbol will be \#undef'd for releases.
|
||||
*/
|
||||
#define APREQ_IS_DEV_VERSION
|
||||
|
||||
|
||||
/** The formatted string of libapreq's version */
|
||||
#define APREQ_VERSION_STRING \
|
||||
APR_STRINGIFY(APREQ_MAJOR_VERSION) "." \
|
||||
APR_STRINGIFY(APREQ_MINOR_VERSION) "." \
|
||||
APR_STRINGIFY(APREQ_PATCH_VERSION) \
|
||||
APREQ_IS_DEV_STRING
|
||||
|
||||
/**
|
||||
* Return libapreq's version information information in a numeric form.
|
||||
*
|
||||
* @param pvsn Pointer to a version structure for returning the version
|
||||
* information.
|
||||
*/
|
||||
APREQ_DECLARE(void) apreq_version(apr_version_t *pvsn);
|
||||
|
||||
/** Return libapreq's version information as a string. */
|
||||
APREQ_DECLARE(const char *) apreq_version_string(void);
|
||||
|
||||
|
||||
/** Internal: string form of the "is dev" flag */
|
||||
#ifdef APREQ_IS_DEV_VERSION
|
||||
#define APREQ_IS_DEV_STRING "-dev"
|
||||
#else
|
||||
#define APREQ_IS_DEV_STRING ""
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APREQ_VERSION_H */
|
Reference in New Issue
Block a user