diff options
author | Philip M. Gollucci <pgollucci@apache.org> | 2011-11-13 01:20:32 +0100 |
---|---|---|
committer | Philip M. Gollucci <pgollucci@apache.org> | 2011-11-13 01:20:32 +0100 |
commit | 4472a86146a20a356383475792bae37870c7862a (patch) | |
tree | 629b76803ce960183dc145c9f23c9e0c816309d7 /srclib | |
parent | Server directive display (-L): Include directives of DSOs. (diff) | |
download | apache2-4472a86146a20a356383475792bae37870c7862a.tar.xz apache2-4472a86146a20a356383475792bae37870c7862a.zip |
As discussed at AC NA 2011
o relocate srclib/libapreq/library/*.c -> server/apreq_${f}.c
o relocate srclib/libapreq/include/*.h -> include/*.h
o remove apreq_version.[hc] related stuff since its nolonger its own lib
o connect modules/apreq to the build under 'most' default comment out in httpd.conf
o update make_exports.awk to handle APREQ marcos
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1201372 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'srclib')
-rw-r--r-- | srclib/libapreq/include/apreq.h | 308 | ||||
-rw-r--r-- | srclib/libapreq/include/apreq_cookie.h | 237 | ||||
-rw-r--r-- | srclib/libapreq/include/apreq_error.h | 97 | ||||
-rw-r--r-- | srclib/libapreq/include/apreq_module.h | 457 | ||||
-rw-r--r-- | srclib/libapreq/include/apreq_param.h | 209 | ||||
-rw-r--r-- | srclib/libapreq/include/apreq_parser.h | 300 | ||||
-rw-r--r-- | srclib/libapreq/include/apreq_util.h | 443 | ||||
-rw-r--r-- | srclib/libapreq/include/apreq_version.h | 105 | ||||
-rw-r--r-- | srclib/libapreq/library/cookie.c | 537 | ||||
-rw-r--r-- | srclib/libapreq/library/error.c | 105 | ||||
-rw-r--r-- | srclib/libapreq/library/module.c | 65 | ||||
-rw-r--r-- | srclib/libapreq/library/module_cgi.c | 1013 | ||||
-rw-r--r-- | srclib/libapreq/library/module_custom.c | 304 | ||||
-rw-r--r-- | srclib/libapreq/library/param.c | 272 | ||||
-rw-r--r-- | srclib/libapreq/library/parser.c | 356 | ||||
-rw-r--r-- | srclib/libapreq/library/parser_header.c | 365 | ||||
-rw-r--r-- | srclib/libapreq/library/parser_multipart.c | 661 | ||||
-rw-r--r-- | srclib/libapreq/library/parser_urlencoded.c | 275 | ||||
-rw-r--r-- | srclib/libapreq/library/util.c | 1168 | ||||
-rw-r--r-- | srclib/libapreq/library/version.c | 36 |
20 files changed, 0 insertions, 7313 deletions
diff --git a/srclib/libapreq/include/apreq.h b/srclib/libapreq/include/apreq.h deleted file mode 100644 index 2d1ba5eba0..0000000000 --- a/srclib/libapreq/include/apreq.h +++ /dev/null @@ -1,308 +0,0 @@ -/* -** 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 */ diff --git a/srclib/libapreq/include/apreq_cookie.h b/srclib/libapreq/include/apreq_cookie.h deleted file mode 100644 index ee887a181d..0000000000 --- a/srclib/libapreq/include/apreq_cookie.h +++ /dev/null @@ -1,237 +0,0 @@ -/* -** 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*/ - - diff --git a/srclib/libapreq/include/apreq_error.h b/srclib/libapreq/include/apreq_error.h deleted file mode 100644 index b2de1fd2be..0000000000 --- a/srclib/libapreq/include/apreq_error.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -** 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 */ diff --git a/srclib/libapreq/include/apreq_module.h b/srclib/libapreq/include/apreq_module.h deleted file mode 100644 index 5f964348fa..0000000000 --- a/srclib/libapreq/include/apreq_module.h +++ /dev/null @@ -1,457 +0,0 @@ -/* -** 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 */ diff --git a/srclib/libapreq/include/apreq_param.h b/srclib/libapreq/include/apreq_param.h deleted file mode 100644 index 832cfc2f38..0000000000 --- a/srclib/libapreq/include/apreq_param.h +++ /dev/null @@ -1,209 +0,0 @@ -/* -** 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 */ - - - diff --git a/srclib/libapreq/include/apreq_parser.h b/srclib/libapreq/include/apreq_parser.h deleted file mode 100644 index 1c9c36ce23..0000000000 --- a/srclib/libapreq/include/apreq_parser.h +++ /dev/null @@ -1,300 +0,0 @@ -/* -** 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 */ diff --git a/srclib/libapreq/include/apreq_util.h b/srclib/libapreq/include/apreq_util.h deleted file mode 100644 index feb2d396ce..0000000000 --- a/srclib/libapreq/include/apreq_util.h +++ /dev/null @@ -1,443 +0,0 @@ -/* -** 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 */ diff --git a/srclib/libapreq/include/apreq_version.h b/srclib/libapreq/include/apreq_version.h deleted file mode 100644 index 8f5b8d2796..0000000000 --- a/srclib/libapreq/include/apreq_version.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -** 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 */ diff --git a/srclib/libapreq/library/cookie.c b/srclib/libapreq/library/cookie.c deleted file mode 100644 index 417df9e715..0000000000 --- a/srclib/libapreq/library/cookie.c +++ /dev/null @@ -1,537 +0,0 @@ -/* -** 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. -*/ - -#include "apreq_cookie.h" -#include "apreq_error.h" -#include "apreq_util.h" -#include "apr_strings.h" -#include "apr_lib.h" -#include "apr_date.h" - - -#define RFC 1 -#define NETSCAPE 0 - -#define ADD_COOKIE(j,c) apreq_value_table_add(&c->v, j) - -APREQ_DECLARE(void) apreq_cookie_expires(apreq_cookie_t *c, - const char *time_str) -{ - if (time_str == NULL) { - c->max_age = -1; - return; - } - - if (!strcasecmp(time_str, "now")) - c->max_age = 0; - else { - c->max_age = apr_date_parse_rfc(time_str); - if (c->max_age == APR_DATE_BAD) - c->max_age = apr_time_from_sec(apreq_atoi64t(time_str)); - else - c->max_age -= apr_time_now(); - } -} - -static apr_status_t apreq_cookie_attr(apr_pool_t *p, - apreq_cookie_t *c, - const char *attr, - apr_size_t alen, - const char *val, - apr_size_t vlen) -{ - if (alen < 2) - return APR_EBADARG; - - if ( attr[0] == '-' || attr[0] == '$' ) { - ++attr; - --alen; - } - - switch (apr_tolower(*attr)) { - - case 'n': /* name is not an attr */ - return APR_ENOTIMPL; - - case 'v': /* version; value is not an attr */ - if (alen == 5 && strncasecmp(attr,"value", 5) == 0) - return APR_ENOTIMPL; - - while (!apr_isdigit(*val)) { - if (vlen == 0) - return APREQ_ERROR_BADSEQ; - ++val; - --vlen; - } - apreq_cookie_version_set(c, *val - '0'); - return APR_SUCCESS; - - case 'e': case 'm': /* expires, max-age */ - apreq_cookie_expires(c, val); - return APR_SUCCESS; - - case 'd': - c->domain = apr_pstrmemdup(p,val,vlen); - return APR_SUCCESS; - - case 'p': - if (alen != 4) - break; - if (!strncasecmp("port", attr, 4)) { - c->port = apr_pstrmemdup(p,val,vlen); - return APR_SUCCESS; - } - else if (!strncasecmp("path", attr, 4)) { - c->path = apr_pstrmemdup(p,val,vlen); - return APR_SUCCESS; - } - break; - - case 'c': - if (!strncasecmp("commentURL", attr, 10)) { - c->commentURL = apr_pstrmemdup(p,val,vlen); - return APR_SUCCESS; - } - else if (!strncasecmp("comment", attr, 7)) { - c->comment = apr_pstrmemdup(p,val,vlen); - return APR_SUCCESS; - } - break; - - case 's': - if (vlen > 0 && *val != '0' && strncasecmp("off",val,vlen)) - apreq_cookie_secure_on(c); - else - apreq_cookie_secure_off(c); - return APR_SUCCESS; - - case 'h': /* httponly */ - if (vlen > 0 && *val != '0' && strncasecmp("off",val,vlen)) - apreq_cookie_httponly_on(c); - else - apreq_cookie_httponly_off(c); - return APR_SUCCESS; - - }; - - return APR_ENOTIMPL; -} - -APREQ_DECLARE(apreq_cookie_t *) apreq_cookie_make(apr_pool_t *p, - const char *name, - const apr_size_t nlen, - const char *value, - const apr_size_t vlen) -{ - apreq_cookie_t *c; - apreq_value_t *v; - - c = apr_palloc(p, nlen + vlen + 1 + sizeof *c); - - if (c == NULL) - return NULL; - - *(const apreq_value_t **)&v = &c->v; - - if (vlen > 0 && value != NULL) - memcpy(v->data, value, vlen); - v->data[vlen] = 0; - v->dlen = vlen; - v->name = v->data + vlen + 1; - if (nlen && name != NULL) - memcpy(v->name, name, nlen); - v->name[nlen] = 0; - v->nlen = nlen; - - c->path = NULL; - c->domain = NULL; - c->port = NULL; - c->comment = NULL; - c->commentURL = NULL; - c->max_age = -1; /* session cookie is the default */ - c->flags = 0; - - - return c; -} - -static APR_INLINE -apr_status_t get_pair(apr_pool_t *p, const char **data, - const char **n, apr_size_t *nlen, - const char **v, apr_size_t *vlen, unsigned unquote) -{ - const char *hdr, *key, *val; - int nlen_set = 0; - hdr = *data; - - while (apr_isspace(*hdr) || *hdr == '=') - ++hdr; - - key = hdr; - *n = hdr; - - scan_name: - - switch (*hdr) { - - case 0: - case ';': - case ',': - if (!nlen_set) - *nlen = hdr - key; - *v = hdr; - *vlen = 0; - *data = hdr; - return *nlen ? APREQ_ERROR_NOTOKEN : APREQ_ERROR_BADCHAR; - - case '=': - if (!nlen_set) { - *nlen = hdr - key; - nlen_set = 1; - } - break; - - case ' ': - case '\t': - case '\r': - case '\n': - if (!nlen_set) { - *nlen = hdr - key; - nlen_set = 1; - } - /* fall thru */ - - default: - ++hdr; - goto scan_name; - } - - val = hdr + 1; - - while (apr_isspace(*val)) - ++val; - - if (*val == '"') { - unsigned saw_backslash = 0; - for (*v = (unquote) ? ++val : val++; *val; ++val) { - switch (*val) { - case '"': - *data = val + 1; - - if (!unquote) { - *vlen = (val - *v) + 1; - } - else if (!saw_backslash) { - *vlen = val - *v; - } - else { - char *dest = apr_palloc(p, val - *v), *d = dest; - const char *s = *v; - while (s < val) { - if (*s == '\\') - ++s; - *d++ = *s++; - } - - *vlen = d - dest; - *v = dest; - } - - return APR_SUCCESS; - case '\\': - saw_backslash = 1; - if (val[1] != 0) - ++val; - default: - break; - } - } - /* bad sequence: no terminating quote found */ - *data = val; - return APREQ_ERROR_BADSEQ; - } - else { - /* value is not wrapped in quotes */ - for (*v = val; *val; ++val) { - switch (*val) { - case ';': - case ',': - case ' ': - case '\t': - case '\r': - case '\n': - *data = val; - *vlen = val - *v; - return APR_SUCCESS; - default: - break; - } - } - } - - *data = val; - *vlen = val - *v; - - return APR_SUCCESS; -} - - - -APREQ_DECLARE(apr_status_t)apreq_parse_cookie_header(apr_pool_t *p, - apr_table_t *j, - const char *hdr) -{ - apreq_cookie_t *c; - unsigned version; - apr_status_t rv = APR_SUCCESS; - - parse_cookie_header: - - c = NULL; - version = NETSCAPE; - - while (apr_isspace(*hdr)) - ++hdr; - - - if (*hdr == '$' && strncasecmp(hdr, "$Version", 8) == 0) { - /* XXX cheat: assume "$Version" => RFC Cookie header */ - version = RFC; - skip_version_string: - switch (*hdr++) { - case 0: - return rv; - case ',': - goto parse_cookie_header; - case ';': - break; - default: - goto skip_version_string; - } - } - - for (;;) { - apr_status_t status; - const char *name, *value; - apr_size_t nlen, vlen; - - while (*hdr == ';' || apr_isspace(*hdr)) - ++hdr; - - switch (*hdr) { - - case 0: - /* this is the normal exit point */ - if (c != NULL) { - ADD_COOKIE(j, c); - } - return rv; - - case ',': - ++hdr; - if (c != NULL) { - ADD_COOKIE(j, c); - } - goto parse_cookie_header; - - case '$': - ++hdr; - if (c == NULL) { - rv = APREQ_ERROR_BADCHAR; - goto parse_cookie_error; - } - else if (version == NETSCAPE) { - rv = APREQ_ERROR_MISMATCH; - } - - status = get_pair(p, &hdr, &name, &nlen, &value, &vlen, 1); - if (status != APR_SUCCESS) { - rv = status; - goto parse_cookie_error; - } - - status = apreq_cookie_attr(p, c, name, nlen, value, vlen); - - switch (status) { - - case APR_ENOTIMPL: - rv = APREQ_ERROR_BADATTR; - /* fall thru */ - - case APR_SUCCESS: - break; - - default: - rv = status; - goto parse_cookie_error; - } - - break; - - default: - if (c != NULL) { - ADD_COOKIE(j, c); - } - - status = get_pair(p, &hdr, &name, &nlen, &value, &vlen, 0); - - if (status != APR_SUCCESS) { - c = NULL; - rv = status; - goto parse_cookie_error; - } - - c = apreq_cookie_make(p, name, nlen, value, vlen); - apreq_cookie_tainted_on(c); - if (version != NETSCAPE) - apreq_cookie_version_set(c, version); - } - } - - parse_cookie_error: - - switch (*hdr) { - - case 0: - return rv; - - case ',': - case ';': - if (c != NULL) - ADD_COOKIE(j, c); - ++hdr; - goto parse_cookie_header; - - default: - ++hdr; - goto parse_cookie_error; - } - - /* not reached */ - return rv; -} - - -APREQ_DECLARE(int) apreq_cookie_serialize(const apreq_cookie_t *c, - char *buf, apr_size_t len) -{ - /* The format string must be large enough to accomodate all - * of the cookie attributes. The current attributes sum to - * ~90 characters (w/ 6-8 padding chars per attr), so anything - * over 100 should be fine. - */ - - unsigned version = apreq_cookie_version(c); - char format[128] = "%s=%s"; - char *f = format + strlen(format); - - /* XXX protocol enforcement (for debugging, anyway) ??? */ - - if (c->v.name == NULL) - return -1; - -#define NULL2EMPTY(attr) (attr ? attr : "") - - - if (version == NETSCAPE) { - char expires[APR_RFC822_DATE_LEN] = {0}; - -#define ADD_NS_ATTR(name) do { \ - if (c->name != NULL) \ - strcpy(f, "; " #name "=%s"); \ - else \ - strcpy(f, "%0.s"); \ - f += strlen(f); \ -} while (0) - - ADD_NS_ATTR(path); - ADD_NS_ATTR(domain); - - if (c->max_age != -1) { - strcpy(f, "; expires=%s"); - apr_rfc822_date(expires, c->max_age + apr_time_now()); - expires[7] = '-'; - expires[11] = '-'; - } - else - strcpy(f, ""); - - f += strlen(f); - - if (apreq_cookie_is_secure(c)) - strcpy(f, "; secure"); - - f += strlen(f); - - if (apreq_cookie_is_httponly(c)) - strcpy(f, "; HttpOnly"); - - return apr_snprintf(buf, len, format, c->v.name, c->v.data, - NULL2EMPTY(c->path), NULL2EMPTY(c->domain), expires); - } - - /* c->version == RFC */ - - strcpy(f,"; Version=%u"); - f += strlen(f); - -/* ensure RFC attributes are always quoted */ -#define ADD_RFC_ATTR(name) do { \ - if (c->name != NULL) \ - if (*c->name == '"') \ - strcpy(f, "; " #name "=%s"); \ - else \ - strcpy(f, "; " #name "=\"%s\""); \ - else \ - strcpy(f, "%0.s"); \ - f += strlen (f); \ -} while (0) - - ADD_RFC_ATTR(path); - ADD_RFC_ATTR(domain); - ADD_RFC_ATTR(port); - ADD_RFC_ATTR(comment); - ADD_RFC_ATTR(commentURL); - - strcpy(f, c->max_age != -1 ? "; max-age=%" APR_TIME_T_FMT : ""); - - f += strlen(f); - - if (apreq_cookie_is_secure(c)) - strcpy(f, "; secure"); - - f += strlen(f); - - if (apreq_cookie_is_httponly(c)) - strcpy(f, "; HttpOnly"); - - return apr_snprintf(buf, len, format, c->v.name, c->v.data, version, - NULL2EMPTY(c->path), NULL2EMPTY(c->domain), - NULL2EMPTY(c->port), NULL2EMPTY(c->comment), - NULL2EMPTY(c->commentURL), apr_time_sec(c->max_age)); -} - - -APREQ_DECLARE(char*) apreq_cookie_as_string(const apreq_cookie_t *c, - apr_pool_t *p) -{ - int n = apreq_cookie_serialize(c, NULL, 0); - char *s = apr_palloc(p, n + 1); - apreq_cookie_serialize(c, s, n + 1); - return s; -} - diff --git a/srclib/libapreq/library/error.c b/srclib/libapreq/library/error.c deleted file mode 100644 index 92a270bbe9..0000000000 --- a/srclib/libapreq/library/error.c +++ /dev/null @@ -1,105 +0,0 @@ -/* 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. - */ - -#include "apreq_error.h" -#include "apr_strings.h" - -/* - * stuffbuffer - like apr_cpystrn() but returns the address of the - * dest buffer instead of the address of the terminating '\0' - */ -static char *stuffbuffer(char *buf, apr_size_t bufsize, const char *s) -{ - apr_cpystrn(buf,s,bufsize); - return buf; -} - -static const char *apreq_error_string(apr_status_t statcode) -{ - switch (statcode) { - - -/* 0's: generic error status codes */ - - case APREQ_ERROR_GENERAL: - return "Internal apreq error"; - - case APREQ_ERROR_TAINTED: - return "Attempt to perform unsafe action with tainted data"; - - -/* 10's: malformed input */ - - case APREQ_ERROR_BADDATA: - return "Malformed input data"; - - case APREQ_ERROR_BADCHAR: - return "Invalid character"; - - case APREQ_ERROR_BADSEQ: - return "Invalid byte sequence"; - - case APREQ_ERROR_BADATTR: - return "Unrecognized attribute"; - - case APREQ_ERROR_BADHEADER: - return "Malformed header string"; - - -/* 20's: missing input */ - - case APREQ_ERROR_NODATA: - return "Missing input data"; - - case APREQ_ERROR_NOTOKEN: - return "Expected token not present"; - - case APREQ_ERROR_NOATTR: - return "Missing attribute"; - - case APREQ_ERROR_NOHEADER: - return "Missing header"; - - case APREQ_ERROR_NOPARSER: - return "Missing parser"; - - -/* 30's: configuration conflicts */ - - case APREQ_ERROR_MISMATCH: - return "Conflicting information"; - - case APREQ_ERROR_OVERLIMIT: - return "Exceeds configured maximum limit"; - - case APREQ_ERROR_NOTEMPTY: - return "Setting already configured"; - - - default: - return "Error string not yet specified by apreq"; - } -} - - -APREQ_DECLARE(char *) apreq_strerror(apr_status_t statcode, char *buf, - apr_size_t bufsize) -{ - if (statcode < APR_OS_START_USERERR || statcode >= APR_OS_START_EAIERR) - return apr_strerror(statcode, buf, bufsize); - return stuffbuffer(buf, bufsize, apreq_error_string(statcode)); -} - diff --git a/srclib/libapreq/library/module.c b/srclib/libapreq/library/module.c deleted file mode 100644 index 9ba5a765ed..0000000000 --- a/srclib/libapreq/library/module.c +++ /dev/null @@ -1,65 +0,0 @@ -/* -** 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. -*/ - -#include "apreq_module.h" -#include "apreq_error.h" -#include "apr_strings.h" -#include "apr_lib.h" -#include "apr_file_io.h" - -APREQ_DECLARE(apreq_param_t *)apreq_param(apreq_handle_t *req, const char *key) -{ - apreq_param_t *param = apreq_args_get(req, key); - if (param == NULL) - return apreq_body_get(req, key); - else - return param; -} - -APREQ_DECLARE(apr_table_t *)apreq_params(apreq_handle_t *req, apr_pool_t *p) -{ - const apr_table_t *args, *body; - apreq_args(req, &args); - apreq_body(req, &body); - - if (args != NULL) - if (body != NULL) - return apr_table_overlay(p, args, body); - else - return apr_table_copy(p, args); - else - if (body != NULL) - return apr_table_copy(p, body); - else - return NULL; - -} - -APREQ_DECLARE(apr_table_t *)apreq_cookies(apreq_handle_t *req, apr_pool_t *p) -{ - const apr_table_t *jar; - apreq_jar(req, &jar); - - if (jar != NULL) - return apr_table_copy(p, jar); - else - return NULL; - -} - - -/** @} */ diff --git a/srclib/libapreq/library/module_cgi.c b/srclib/libapreq/library/module_cgi.c deleted file mode 100644 index 14fb39ba39..0000000000 --- a/srclib/libapreq/library/module_cgi.c +++ /dev/null @@ -1,1013 +0,0 @@ -/* -** 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. -*/ -#include <assert.h> - -#define APR_WANT_STRFUNC -#include "apr_want.h" -#include "apreq_module.h" -#include "apreq_error.h" -#include "apr_strings.h" -#include "apr_lib.h" -#include "apr_env.h" -#include "apreq_util.h" - -#define USER_DATA_KEY "apreq" - -/* Parroting APLOG_* ... */ - -#define CGILOG_EMERG 0 /* system is unusable */ -#define CGILOG_ALERT 1 /* action must be taken immediately */ -#define CGILOG_CRIT 2 /* critical conditions */ -#define CGILOG_ERR 3 /* error conditions */ -#define CGILOG_WARNING 4 /* warning conditions */ -#define CGILOG_NOTICE 5 /* normal but significant condition */ -#define CGILOG_INFO 6 /* informational */ -#define CGILOG_DEBUG 7 /* debug-level messages */ - -#define CGILOG_LEVELMASK 7 -#define CGILOG_MARK __FILE__, __LINE__ - -/** Interactive patch: - * TODO Don't use 65K buffer - * TODO Handle empty/non-existant parameters - * TODO Allow body elements to be files - * TODO When running body/get/cookies all at once, include previous cached - * values (and don't start at 0 in count) - * TODO What happens if user does apreq_param, but needs POST value - we'll - * never catch it now, as args param will match... - */ - -struct cgi_handle { - struct apreq_handle_t handle; - - apr_table_t *jar, *args, *body; - apr_status_t jar_status, - args_status, - body_status; - - apreq_parser_t *parser; - apreq_hook_t *hook_queue; - apreq_hook_t *find_param; - - const char *temp_dir; - apr_size_t brigade_limit; - apr_uint64_t read_limit; - apr_uint64_t bytes_read; - - apr_bucket_brigade *in; - apr_bucket_brigade *tmpbb; - - int interactive_mode; - const char *promptstr; - apr_file_t *sout, *sin; -}; - -#define CRLF "\015\012" -static const char *nullstr = 0; -#define DEFAULT_PROMPT "([$t] )$n(\\($l\\))([$d]): " -#define MAX_PROMPT_NESTING_LEVELS 8 -#define MAX_BUFFER_SIZE 65536 - -typedef struct { - const char *t_name; - int t_val; -} TRANS; - -static const TRANS priorities[] = { - {"emerg", CGILOG_EMERG}, - {"alert", CGILOG_ALERT}, - {"crit", CGILOG_CRIT}, - {"error", CGILOG_ERR}, - {"warn", CGILOG_WARNING}, - {"notice", CGILOG_NOTICE}, - {"info", CGILOG_INFO}, - {"debug", CGILOG_DEBUG}, - {NULL, -1}, -}; - -static char* chomp(char* str) { - apr_size_t p = strlen(str); - while (--p >= 0) { - switch ((char)(str[p])) { - case '\015': - case '\012':str[p]='\000'; - break; - default:return str; - } - } - return str; -} - -/** TODO: Support wide-characters */ -/* prompt takes a apreq_handle and 2 strings - name and type - and prompts a - user for input via stdin/stdout. used in interactive mode. - - name must be defined. type can be null. - - we take the promptstring defined in the handle and interpolate variables as - follows: - - $n - name of the variable we're asking for (param 2 to prompt()) - $t - type of the variable we're asking for - like cookie, get, post, etc - (param 3 to prompt()) - parentheses - if a variable is surrounded by parentheses, and interpolates - as null, then nothing else in the parentheses will be displayed - Useful if you want a string to only show up if a given variable - is available - - These are planned for forward-compatibility, but the underlying features - need some love... I left these in here just as feature reminders, rather - than completely removing them from the code - at least they provide sanity - testing of the default prompt & parentheses - issac - - $l - label for the param - the end-user-developer can provide a textual - description of the param (name) being requested (currently unused in - lib) - $d - default value for the param (currently unused in lib) - -*/ -static char *prompt(apreq_handle_t *handle, const char *name, - const char *type) { - struct cgi_handle *req = (struct cgi_handle *)handle; - const char *defval = nullstr; - const char *label = NULL; - const char *cprompt; - char buf[MAX_PROMPT_NESTING_LEVELS][MAX_BUFFER_SIZE]; - /* Array of current arg for given p-level */ - char *start, curarg[MAX_PROMPT_NESTING_LEVELS] = ""; - /* Parenthesis level (for argument/text grouping) */ - int plevel; - - cprompt = req->promptstr - 1; - *buf[0] = plevel = 0; - start = buf[0]; - - while (*(++cprompt) != 0) { - switch (*cprompt) { - case '$': /* interpolate argument; curarg[plevel] => 1 */ - cprompt++; - switch (*cprompt) { - case 't': - if (type != NULL) { - strcpy(start, type); - start += strlen(type); - curarg[plevel] = 1; - } else { - curarg[plevel] = curarg[plevel] | 0; - } - break; - case 'n': - /* Name can't be null :-) [If it can, we should - * immediately return NULL] */ - strcpy(start, name); - start += strlen(name); - curarg[plevel] = 1; - break; - case 'l': - if (label != NULL) { - strcpy(start, label); - start += strlen(label); - curarg[plevel] = 1; - } else { - curarg[plevel] = curarg[plevel] | 0; - } - break; - case 'd': - /* TODO: Once null defaults are available, - * remove if and use nullstr if defval == NULL */ - if (defval != NULL) { - strcpy(start, defval); - start += strlen(defval); - curarg[plevel] = 1; - } else { - curarg[plevel] = curarg[plevel] | 0; - } - break; - default: - /* Handle this? */ - break; - } - break; - - case '(': - if (plevel <= MAX_PROMPT_NESTING_LEVELS) { - plevel++; - curarg[plevel] = *buf[plevel] = 0; - start = buf[plevel]; - } - /* else? */ - break; - - case ')': - if (plevel > 0) { - *start = 0; /* Null terminate current string */ - - /* Move pointer to end of string */ - plevel--; - start = buf[plevel] + strlen(buf[plevel]); - - /* If old curarg was set, concat buffer with level down */ - if (curarg[plevel + 1]) { - strcpy(start, buf[plevel + 1]); - start += strlen(buf[plevel + 1]); - } - - break; - } - case '\\': /* Check next character for escape sequence - * (just ignore it for now) */ - (void)*cprompt++; - /* Fallthrough */ - - default: - *start++ = *cprompt; - } - } - - *start = 0; /* Null terminate the string */ - - apr_file_printf(req->sout, "%s", buf[0]); - apr_file_gets(buf[0], MAX_BUFFER_SIZE, req->sin); - chomp(buf[0]); - if (strcmp(buf[0], "")) { -/* if (strcmp(buf[0], nullstr)) */ - return apr_pstrdup(handle->pool, buf[0]); -/* return NULL; */ - } - - if (defval != nullstr) - return apr_pstrdup(handle->pool, defval); - - return NULL; -} - -static const char *cgi_header_in(apreq_handle_t *handle, - const char *name) -{ - apr_pool_t *p = handle->pool; - char *key = apr_pstrcat(p, "HTTP_", name, NULL); - char *k, *value = NULL; - for (k = key; *k; ++k) { - if (*k == '-') - *k = '_'; - else - *k = apr_toupper(*k); - } - - if (!strcmp(key, "HTTP_CONTENT_TYPE") - || !strcmp(key, "HTTP_CONTENT_LENGTH")) - { - key += 5; /* strlen("HTTP_") */ - } - - apr_env_get(&value, key, p); - - return value; -} - - - - -static void cgi_log_error(const char *file, int line, int level, - apr_status_t status, apreq_handle_t *handle, - const char *fmt, ...) -{ - apr_pool_t *p = handle->pool; - char buf[256]; - char *log_level_string, *ra; - const char *remote_addr; - unsigned log_level = CGILOG_WARNING; - char date[APR_CTIME_LEN]; - va_list vp; -#ifndef WIN32 - apr_file_t *err; -#endif - - va_start(vp, fmt); - - if (apr_env_get(&log_level_string, "LOG_LEVEL", p) == APR_SUCCESS) - log_level = (log_level_string[0] - '0'); - - level &= CGILOG_LEVELMASK; - - if (level < (int)log_level) { - - if (apr_env_get(&ra, "REMOTE_ADDR", p) == APR_SUCCESS) - remote_addr = ra; - else - remote_addr = "address unavailable"; - - apr_ctime(date, apr_time_now()); - -#ifndef WIN32 - - apr_file_open_stderr(&err, p); - apr_file_printf(err, "[%s] [%s] [%s] %s(%d): %s: %s\n", - date, priorities[level].t_name, remote_addr, file, line, - apr_strerror(status,buf,255),apr_pvsprintf(p,fmt,vp)); - apr_file_flush(err); - -#else - fprintf(stderr, "[%s] [%s] [%s] %s(%d): %s: %s\n", - date, priorities[level].t_name, remote_addr, file, line, - apr_strerror(status,buf,255),apr_pvsprintf(p,fmt,vp)); -#endif - } - - va_end(vp); - -} - - -APR_INLINE -static const char *cgi_query_string(apreq_handle_t *handle) -{ - char *value = NULL, qs[] = "QUERY_STRING"; - apr_env_get(&value, qs, handle->pool); - return value; -} - - -static void init_body(apreq_handle_t *handle) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - const char *cl_header = cgi_header_in(handle, "Content-Length"); - apr_bucket_alloc_t *ba = handle->bucket_alloc; - apr_pool_t *pool = handle->pool; - apr_file_t *file; - apr_bucket *eos, *pipe; - - if (cl_header != NULL) { - char *dummy; - apr_int64_t content_length = apr_strtoi64(cl_header, &dummy, 0); - - if (dummy == NULL || *dummy != 0) { - req->body_status = APREQ_ERROR_BADHEADER; - cgi_log_error(CGILOG_MARK, CGILOG_ERR, req->body_status, handle, - "Invalid Content-Length header (%s)", cl_header); - return; - } - else if ((apr_uint64_t)content_length > req->read_limit) { - req->body_status = APREQ_ERROR_OVERLIMIT; - cgi_log_error(CGILOG_MARK, CGILOG_ERR, req->body_status, handle, - "Content-Length header (%s) exceeds configured " - "max_body limit (%" APR_UINT64_T_FMT ")", - cl_header, req->read_limit); - return; - } - } - - if (req->parser == NULL) { - const char *ct_header = cgi_header_in(handle, "Content-Type"); - - if (ct_header != NULL) { - apreq_parser_function_t pf = apreq_parser(ct_header); - - if (pf != NULL) { - req->parser = apreq_parser_make(pool, - ba, - ct_header, - pf, - req->brigade_limit, - req->temp_dir, - req->hook_queue, - NULL); - } - else { - req->body_status = APREQ_ERROR_NOPARSER; - return; - } - } - else { - req->body_status = APREQ_ERROR_NOHEADER; - return; - } - } - else { - if (req->parser->brigade_limit > req->brigade_limit) - req->parser->brigade_limit = req->brigade_limit; - if (req->temp_dir != NULL) - req->parser->temp_dir = req->temp_dir; - if (req->hook_queue != NULL) - apreq_parser_add_hook(req->parser, req->hook_queue); - } - - req->hook_queue = NULL; - req->in = apr_brigade_create(pool, ba); - req->tmpbb = apr_brigade_create(pool, ba); - - apr_file_open_stdin(&file, pool); // error status? - pipe = apr_bucket_pipe_create(file, ba); - eos = apr_bucket_eos_create(ba); - APR_BRIGADE_INSERT_HEAD(req->in, pipe); - APR_BRIGADE_INSERT_TAIL(req->in, eos); - - req->body_status = APR_INCOMPLETE; - -} - -static apr_status_t cgi_read(apreq_handle_t *handle, - apr_off_t bytes) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - apr_bucket *e; - apr_status_t s; - - if (req->body_status == APR_EINIT) - init_body(handle); - - if (req->body_status != APR_INCOMPLETE) - return req->body_status; - - - switch (s = apr_brigade_partition(req->in, bytes, &e)) { - apr_off_t len; - - case APR_SUCCESS: - - apreq_brigade_move(req->tmpbb, req->in, e); - req->bytes_read += bytes; - - if (req->bytes_read > req->read_limit) { - req->body_status = APREQ_ERROR_OVERLIMIT; - cgi_log_error(CGILOG_MARK, CGILOG_ERR, req->body_status, - handle, "Bytes read (%" APR_UINT64_T_FMT - ") exceeds configured limit (%" APR_UINT64_T_FMT ")", - req->bytes_read, req->read_limit); - break; - } - - req->body_status = - apreq_parser_run(req->parser, req->body, req->tmpbb); - apr_brigade_cleanup(req->tmpbb); - break; - - - case APR_INCOMPLETE: - - apreq_brigade_move(req->tmpbb, req->in, e); - s = apr_brigade_length(req->tmpbb, 1, &len); - - if (s != APR_SUCCESS) { - req->body_status = s; - break; - } - req->bytes_read += len; - - if (req->bytes_read > req->read_limit) { - req->body_status = APREQ_ERROR_OVERLIMIT; - cgi_log_error(CGILOG_MARK, CGILOG_ERR, req->body_status, handle, - "Bytes read (%" APR_UINT64_T_FMT - ") exceeds configured limit (%" APR_UINT64_T_FMT ")", - req->bytes_read, req->read_limit); - - break; - } - - req->body_status = - apreq_parser_run(req->parser, req->body, req->tmpbb); - apr_brigade_cleanup(req->tmpbb); - break; - - default: - req->body_status = s; - } - - return req->body_status; -} - - - -static apr_status_t cgi_jar(apreq_handle_t *handle, - const apr_table_t **t) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - - if (req->interactive_mode && req->jar_status != APR_SUCCESS) { - char buf[65536]; - const char *name, *val; - apreq_cookie_t *p; - int i = 1; - apr_file_printf(req->sout, "[CGI] Requested all cookies\n"); - while (1) { - apr_file_printf(req->sout, "[CGI] Please enter a name for cookie %d (or just hit ENTER to end): ", - i++); - apr_file_gets(buf, 65536, req->sin); - chomp(buf); - if (!strcmp(buf, "")) { - break; - } - name = apr_pstrdup(handle->pool, buf); - val = prompt(handle, name, "cookie"); - if (val == NULL) - val = ""; - p = apreq_cookie_make(handle->pool, name, strlen(name), val, strlen(val)); - apreq_cookie_tainted_on(p); - apreq_value_table_add(&p->v, req->jar); - val = p->v.data; - } - req->jar_status = APR_SUCCESS; - } /** Fallthrough */ - - if (req->jar_status == APR_EINIT) { - const char *cookies = cgi_header_in(handle, "Cookie"); - if (cookies != NULL) { - req->jar_status = - apreq_parse_cookie_header(handle->pool, req->jar, cookies); - } - else - req->jar_status = APREQ_ERROR_NODATA; - } - - *t = req->jar; - return req->jar_status; -} - -static apr_status_t cgi_args(apreq_handle_t *handle, - const apr_table_t **t) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - - if (req->interactive_mode && req->args_status != APR_SUCCESS) { - char buf[65536]; - const char *name, *val; - apreq_param_t *p; - int i = 1; - apr_file_printf(req->sout, "[CGI] Requested all argument parameters\n"); - while (1) { - apr_file_printf(req->sout, "[CGI] Please enter a name for parameter %d (or just hit ENTER to end): ", - i++); - apr_file_gets(buf, 65536, req->sin); - chomp(buf); - if (!strcmp(buf, "")) { - break; - } - name = apr_pstrdup(handle->pool, buf); - val = prompt(handle, name, "parameter"); - if (val == NULL) - val = ""; - p = apreq_param_make(handle->pool, name, strlen(name), val, strlen(val)); - apreq_param_tainted_on(p); - apreq_value_table_add(&p->v, req->args); - val = p->v.data; - } - req->args_status = APR_SUCCESS; - } /** Fallthrough */ - - if (req->args_status == APR_EINIT) { - const char *qs = cgi_query_string(handle); - if (qs != NULL) { - req->args_status = - apreq_parse_query_string(handle->pool, req->args, qs); - } - else - req->args_status = APREQ_ERROR_NODATA; - } - - *t = req->args; - return req->args_status; -} - - - - -static apreq_cookie_t *cgi_jar_get(apreq_handle_t *handle, - const char *name) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - const apr_table_t *t; - const char *val = NULL; - - if (req->jar_status == APR_EINIT && !req->interactive_mode) - cgi_jar(handle, &t); - else - t = req->jar; - - val = apr_table_get(t, name); - if (val == NULL) { - if (!req->interactive_mode) { - return NULL; - } else { - apreq_cookie_t *p; - val = prompt(handle, name, "cookie"); - if (val == NULL) - return NULL; - p = apreq_cookie_make(handle->pool, name, strlen(name), val, strlen(val)); - apreq_cookie_tainted_on(p); - apreq_value_table_add(&p->v, req->jar); - val = p->v.data; - } - } - - - return apreq_value_to_cookie(val); -} - -static apreq_param_t *cgi_args_get(apreq_handle_t *handle, - const char *name) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - const apr_table_t *t; - const char *val = NULL; - - if (req->args_status == APR_EINIT && !req->interactive_mode) - cgi_args(handle, &t); - else - t = req->args; - - val = apr_table_get(t, name); - if (val == NULL) { - if (!req->interactive_mode) { - return NULL; - } else { - apreq_param_t *p; - val = prompt(handle, name, "parameter"); - if (val == NULL) - return NULL; - p = apreq_param_make(handle->pool, name, strlen(name), val, strlen(val)); - apreq_param_tainted_on(p); - apreq_value_table_add(&p->v, req->args); - val = p->v.data; - } - } - - - return apreq_value_to_param(val); -} - - - -static apr_status_t cgi_body(apreq_handle_t *handle, - const apr_table_t **t) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - - if (req->interactive_mode && req->body_status != APR_SUCCESS) { - const char *name, *val; - apreq_param_t *p; - int i = 1; - apr_file_printf(req->sout, "[CGI] Requested all body parameters\n"); - while (1) { - char buf[65536]; - apr_file_printf(req->sout, "[CGI] Please enter a name for parameter %d (or just hit ENTER to end): ", - i++); - apr_file_gets(buf, 65536, req->sin); - chomp(buf); - if (!strcmp(buf, "")) { - break; - } - name = apr_pstrdup(handle->pool, buf); - val = prompt(handle, name, "parameter"); - if (val == NULL) - val = ""; - p = apreq_param_make(handle->pool, name, strlen(name), val, strlen(val)); - apreq_param_tainted_on(p); - apreq_value_table_add(&p->v, req->body); - val = p->v.data; - } - req->body_status = APR_SUCCESS; - } /** Fallthrough */ - - switch (req->body_status) { - - case APR_EINIT: - init_body(handle); - if (req->body_status != APR_INCOMPLETE) - break; - - case APR_INCOMPLETE: - while (cgi_read(handle, APREQ_DEFAULT_READ_BLOCK_SIZE) - == APR_INCOMPLETE) - ; /*loop*/ - } - - *t = req->body; - return req->body_status; -} - -static apreq_param_t *cgi_body_get(apreq_handle_t *handle, - const char *name) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - const char *val = NULL; - apreq_hook_t *h; - apreq_hook_find_param_ctx_t *hook_ctx; - - if (req->interactive_mode) { - val = apr_table_get(req->body, name); - if (val == NULL) { - return NULL; - } else { - apreq_param_t *p; - val = prompt(handle, name, "parameter"); - if (val == NULL) - return NULL; - p = apreq_param_make(handle->pool, name, strlen(name), val, strlen(val)); - apreq_param_tainted_on(p); - apreq_value_table_add(&p->v, req->body); - val = p->v.data; - return apreq_value_to_param(val); - } - } - - - switch (req->body_status) { - - case APR_SUCCESS: - - val = apr_table_get(req->body, name); - if (val != NULL) - return apreq_value_to_param(val); - return NULL; - - - case APR_EINIT: - - init_body(handle); - if (req->body_status != APR_INCOMPLETE) - return NULL; - cgi_read(handle, APREQ_DEFAULT_READ_BLOCK_SIZE); - - - case APR_INCOMPLETE: - - val = apr_table_get(req->body, name); - if (val != NULL) - return apreq_value_to_param(val); - - /* Not seen yet, so we need to scan for - param while prefetching the body */ - - hook_ctx = apr_palloc(handle->pool, sizeof *hook_ctx); - - if (req->find_param == NULL) - req->find_param = apreq_hook_make(handle->pool, - apreq_hook_find_param, - NULL, NULL); - h = req->find_param; - h->next = req->parser->hook; - req->parser->hook = h; - h->ctx = hook_ctx; - hook_ctx->name = name; - hook_ctx->param = NULL; - hook_ctx->prev = req->parser->hook; - - do { - cgi_read(handle, APREQ_DEFAULT_READ_BLOCK_SIZE); - if (hook_ctx->param != NULL) - return hook_ctx->param; - } while (req->body_status == APR_INCOMPLETE); - - req->parser->hook = h->next; - return NULL; - - - default: - - if (req->body == NULL) - return NULL; - - val = apr_table_get(req->body, name); - if (val != NULL) - return apreq_value_to_param(val); - return NULL; - } - - /* not reached */ - return NULL; -} - -static apr_status_t cgi_parser_get(apreq_handle_t *handle, - const apreq_parser_t **parser) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - - *parser = req->parser; - return APR_SUCCESS; -} - -static apr_status_t cgi_parser_set(apreq_handle_t *handle, - apreq_parser_t *parser) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - - if (req->parser == NULL) { - - if (req->hook_queue != NULL) { - apr_status_t s = apreq_parser_add_hook(parser, req->hook_queue); - if (s != APR_SUCCESS) - return s; - } - if (req->temp_dir != NULL) { - parser->temp_dir = req->temp_dir; - } - if (req->brigade_limit < parser->brigade_limit) { - parser->brigade_limit = req->brigade_limit; - } - - req->hook_queue = NULL; - req->parser = parser; - return APR_SUCCESS; - } - else - return APREQ_ERROR_MISMATCH; -} - - -static apr_status_t cgi_hook_add(apreq_handle_t *handle, - apreq_hook_t *hook) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - - if (req->parser != NULL) { - return apreq_parser_add_hook(req->parser, hook); - } - else if (req->hook_queue != NULL) { - apreq_hook_t *h = req->hook_queue; - while (h->next != NULL) - h = h->next; - h->next = hook; - } - else { - req->hook_queue = hook; - } - return APR_SUCCESS; - -} - -static apr_status_t cgi_brigade_limit_set(apreq_handle_t *handle, - apr_size_t bytes) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - apr_size_t *limit = (req->parser == NULL) - ? &req->brigade_limit - : &req->parser->brigade_limit; - - if (*limit > bytes) { - *limit = bytes; - return APR_SUCCESS; - } - - return APREQ_ERROR_MISMATCH; -} - -static apr_status_t cgi_brigade_limit_get(apreq_handle_t *handle, - apr_size_t *bytes) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - *bytes = (req->parser == NULL) - ? req->brigade_limit - : req->parser->brigade_limit; - - return APR_SUCCESS; -} - -static apr_status_t cgi_read_limit_set(apreq_handle_t *handle, - apr_uint64_t bytes) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - - if (req->read_limit > bytes && req->bytes_read < bytes) { - req->read_limit = bytes; - return APR_SUCCESS; - } - - return APREQ_ERROR_MISMATCH; -} - - -static apr_status_t cgi_read_limit_get(apreq_handle_t *handle, - apr_uint64_t *bytes) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - *bytes = req->read_limit; - return APR_SUCCESS; -} - - -static apr_status_t cgi_temp_dir_set(apreq_handle_t *handle, - const char *path) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - const char **temp_dir = (req->parser == NULL) - ? &req->temp_dir - : &req->parser->temp_dir; - - - if (*temp_dir == NULL && req->bytes_read == 0) { - if (path != NULL) - *temp_dir = apr_pstrdup(handle->pool, path); - return APR_SUCCESS; - } - - return APREQ_ERROR_MISMATCH; -} - - -static apr_status_t cgi_temp_dir_get(apreq_handle_t *handle, - const char **path) -{ - struct cgi_handle *req = (struct cgi_handle *)handle; - *path = (req->parser == NULL) - ? req->temp_dir - : req->parser->temp_dir; - return APR_SUCCESS; -} - - - -#ifdef APR_POOL_DEBUG -static apr_status_t ba_cleanup(void *data) -{ - apr_bucket_alloc_t *ba = data; - apr_bucket_alloc_destroy(ba); - return APR_SUCCESS; -} -#endif - -/** Determine if we're interactive mode or not. Order is - QUERY_STRING ? NO : Interactive - - I think we should just rely on GATEWAY_INTERFACE to set - non-interactive mode, and be interactive if it's not there - - Behaviour change should really be: - Always check query_string before prompting user, - but rewrite body/cookies to get if interactive - - Definately more work needed here... -*/ -static int is_interactive_mode(apr_pool_t *pool) { - char *value = NULL, qs[] = "GATEWAY_INTERFACE"; - apr_status_t rv; - - rv = apr_env_get(&value, qs, pool); - if (rv != APR_SUCCESS) - if (rv == APR_ENOENT) - return 1; - - /** handle else? (!SUCCESS && !ENOENT) */ - return 0; -} - -static APREQ_MODULE(cgi, 20090110); - -APREQ_DECLARE(apreq_handle_t *)apreq_handle_cgi(apr_pool_t *pool) -{ - apr_bucket_alloc_t *ba; - struct cgi_handle *req; - void *data; - - apr_pool_userdata_get(&data, USER_DATA_KEY, pool); - - if (data != NULL) - return data; - - req = apr_pcalloc(pool, sizeof *req); - ba = apr_bucket_alloc_create(pool); - - /* check pool's userdata first. */ - - req->handle.module = &cgi_module; - req->handle.pool = pool; - req->handle.bucket_alloc = ba; - req->read_limit = (apr_uint64_t) -1; - req->brigade_limit = APREQ_DEFAULT_BRIGADE_LIMIT; - - req->args = apr_table_make(pool, APREQ_DEFAULT_NELTS); - req->body = apr_table_make(pool, APREQ_DEFAULT_NELTS); - req->jar = apr_table_make(pool, APREQ_DEFAULT_NELTS); - - req->args_status = - req->jar_status = - req->body_status = APR_EINIT; - - if (is_interactive_mode(pool)) { - req->interactive_mode = 1; - apr_file_open_stdout(&(req->sout), pool); - apr_file_open_stdin(&(req->sin), pool); - req->promptstr=apr_pstrdup(pool, DEFAULT_PROMPT); - } - - apr_pool_userdata_setn(&req->handle, USER_DATA_KEY, NULL, pool); - -#ifdef APR_POOL_DEBUG - apr_pool_cleanup_register(pool, ba, ba_cleanup, ba_cleanup); -#endif - - return &req->handle; -} diff --git a/srclib/libapreq/library/module_custom.c b/srclib/libapreq/library/module_custom.c deleted file mode 100644 index e1e6f58bfe..0000000000 --- a/srclib/libapreq/library/module_custom.c +++ /dev/null @@ -1,304 +0,0 @@ -/* -** 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. -*/ - -#include "apr_strings.h" -#include "apreq_module.h" -#include "apreq_error.h" -#include "apreq_util.h" - -#define READ_BYTES (64 * 1024) - -struct custom_handle { - struct apreq_handle_t handle; - - apr_table_t *jar, *args, *body; - apr_status_t jar_status, - args_status, - body_status; - - apreq_parser_t *parser; - - apr_uint64_t read_limit; - apr_uint64_t bytes_read; - apr_bucket_brigade *in; - apr_bucket_brigade *tmpbb; -}; - - -static apr_status_t custom_parse_brigade(apreq_handle_t *handle, apr_uint64_t bytes) -{ - struct custom_handle *req = (struct custom_handle *)handle; - apr_status_t s; - apr_bucket *e; - - if (req->body_status != APR_INCOMPLETE) - return req->body_status; - - switch (s = apr_brigade_partition(req->in, bytes, &e)) { - apr_off_t len; - - case APR_SUCCESS: - apreq_brigade_move(req->tmpbb, req->in, e); - req->bytes_read += bytes; - - if (req->bytes_read > req->read_limit) { - req->body_status = APREQ_ERROR_OVERLIMIT; - break; - } - - req->body_status = - apreq_parser_run(req->parser, req->body, req->tmpbb); - - apr_brigade_cleanup(req->tmpbb); - break; - - case APR_INCOMPLETE: - apreq_brigade_move(req->tmpbb, req->in, e); - s = apr_brigade_length(req->tmpbb, 1, &len); - if (s != APR_SUCCESS) { - req->body_status = s; - break; - } - req->bytes_read += len; - - if (req->bytes_read > req->read_limit) { - req->body_status = APREQ_ERROR_OVERLIMIT; - break; - } - req->body_status = - apreq_parser_run(req->parser, req->body, req->tmpbb); - - apr_brigade_cleanup(req->tmpbb); - break; - - default: - req->body_status = s; - } - - return req->body_status; -} - - - -static apr_status_t custom_jar(apreq_handle_t *handle, const apr_table_t **t) -{ - struct custom_handle *req = (struct custom_handle *)handle; - *t = req->jar; - return req->jar_status; -} - -static apr_status_t custom_args(apreq_handle_t *handle, const apr_table_t **t) -{ - struct custom_handle *req = (struct custom_handle*)handle; - *t = req->args; - return req->args_status; -} - -static apr_status_t custom_body(apreq_handle_t *handle, const apr_table_t **t) -{ - struct custom_handle *req = (struct custom_handle*)handle; - while (req->body_status == APR_INCOMPLETE) - custom_parse_brigade(handle, READ_BYTES); - *t = req->body; - return req->body_status; -} - - - -static apreq_cookie_t *custom_jar_get(apreq_handle_t *handle, const char *name) -{ - struct custom_handle *req = (struct custom_handle*)handle; - const char *val; - - if (req->jar == NULL || name == NULL) - return NULL; - - val = apr_table_get(req->jar, name); - - if (val == NULL) - return NULL; - - return apreq_value_to_cookie(val); -} - -static apreq_param_t *custom_args_get(apreq_handle_t *handle, const char *name) -{ - struct custom_handle *req = (struct custom_handle*)handle; - const char *val; - - if (req->args == NULL || name == NULL) - return NULL; - - val = apr_table_get(req->args, name); - - if (val == NULL) - return NULL; - - return apreq_value_to_param(val); -} - -static apreq_param_t *custom_body_get(apreq_handle_t *handle, const char *name) -{ - struct custom_handle *req = (struct custom_handle*)handle; - const char *val; - - if (req->body == NULL || name == NULL) - return NULL; - - while (1) { - *(const char **)&val = apr_table_get(req->body, name); - if (val != NULL) - break; - - if (req->body_status == APR_INCOMPLETE) - custom_parse_brigade(handle, READ_BYTES); - else - return NULL; - } - - return apreq_value_to_param(val); -} - - - -static apr_status_t custom_parser_get(apreq_handle_t *handle, - const apreq_parser_t **parser) -{ - struct custom_handle *req = (struct custom_handle*)handle; - *parser = req->parser; - - return APR_SUCCESS; -} - -static apr_status_t custom_parser_set(apreq_handle_t *handle, - apreq_parser_t *parser) -{ - (void)handle; - (void)parser; - return APR_ENOTIMPL; -} - -static apr_status_t custom_hook_add(apreq_handle_t *handle, - apreq_hook_t *hook) -{ - struct custom_handle *req = (struct custom_handle*)handle; - apreq_parser_add_hook(req->parser, hook); - return APR_SUCCESS; -} - -static apr_status_t custom_brigade_limit_get(apreq_handle_t *handle, - apr_size_t *bytes) -{ - struct custom_handle *req = (struct custom_handle*)handle; - *bytes = req->parser->brigade_limit; - return APR_SUCCESS; -} - -static apr_status_t custom_brigade_limit_set(apreq_handle_t *handle, - apr_size_t bytes) -{ - (void)handle; - (void)bytes; - return APR_ENOTIMPL; -} - -static apr_status_t custom_read_limit_get(apreq_handle_t *handle, - apr_uint64_t *bytes) -{ - struct custom_handle *req = (struct custom_handle*)handle; - *bytes = req->read_limit; - return APR_SUCCESS; -} - -static apr_status_t custom_read_limit_set(apreq_handle_t *handle, - apr_uint64_t bytes) -{ - (void)handle; - (void)bytes; - return APR_ENOTIMPL; -} - -static apr_status_t custom_temp_dir_get(apreq_handle_t *handle, - const char **path) -{ - struct custom_handle *req = (struct custom_handle*)handle; - - *path = req->parser->temp_dir; - return APR_SUCCESS; -} - -static apr_status_t custom_temp_dir_set(apreq_handle_t *handle, - const char *path) -{ - (void)handle; - (void)path; - return APR_ENOTIMPL; -} - - -static APREQ_MODULE(custom, 20070428); - -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) -{ - struct custom_handle *req; - req = apr_palloc(pool, sizeof(*req)); - req->handle.module = &custom_module; - req->handle.pool = pool; - req->handle.bucket_alloc = in->bucket_alloc; - req->read_limit = read_limit; - req->bytes_read = 0; - req->parser = parser; - req->in = apr_brigade_create(pool, in->bucket_alloc); - req->tmpbb = apr_brigade_create(pool, in->bucket_alloc); - req->body = apr_table_make(pool, APREQ_DEFAULT_NELTS); - req->body_status = APR_INCOMPLETE; - APR_BRIGADE_CONCAT(req->in, in); - - if (cookie != NULL) { - req->jar = apr_table_make(pool, APREQ_DEFAULT_NELTS); - req->jar_status = - apreq_parse_cookie_header(pool, req->jar, cookie); - } - else { - req->jar = NULL; - req->jar_status = APREQ_ERROR_NODATA; - } - - - if (query_string != NULL) { - req->args = apr_table_make(pool, APREQ_DEFAULT_NELTS); - req->args_status = - apreq_parse_query_string(pool, req->args, query_string); - } - else { - req->args = NULL; - req->args_status = APREQ_ERROR_NODATA; - } - - if (!APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(req->in))) { - apr_bucket *eos = apr_bucket_eos_create(in->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(req->in, eos); - } - - return &req->handle; -} - diff --git a/srclib/libapreq/library/param.c b/srclib/libapreq/library/param.c deleted file mode 100644 index 83e185b595..0000000000 --- a/srclib/libapreq/library/param.c +++ /dev/null @@ -1,272 +0,0 @@ -/* -** 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. -*/ - -#include "apreq_param.h" -#include "apreq_error.h" -#include "apreq_util.h" -#include "apr_strings.h" -#include "apr_lib.h" - -#define MAX_LEN (1024 * 1024) -#define MAX_BRIGADE_LEN (1024 * 256) -#define MAX_READ_AHEAD (1024 * 64) - - -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) -{ - apreq_param_t *param; - apreq_value_t *v; - - param = apr_palloc(p, nlen + vlen + 1 + sizeof *param); - - if (param == NULL) - return NULL; - - param->info = NULL; - param->upload = NULL; - param->flags = 0; - - *(const apreq_value_t **)&v = ¶m->v; - - if (vlen && val != NULL) - memcpy(v->data, val, vlen); - v->data[vlen] = 0; - v->dlen = vlen; - - v->name = v->data + vlen + 1; - if (nlen && name != NULL) - memcpy(v->name, name, nlen); - v->name[nlen] = 0; - v->nlen = nlen; - - return param; -} - -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) -{ - apr_status_t status; - apreq_value_t *v; - apreq_param_t *p; - apreq_charset_t charset; - - if (nlen == 0) { - *param = NULL; - return APR_EBADARG; - } - - p = apr_palloc(pool, nlen + vlen + 1 + sizeof *p); - p->info = NULL; - p->upload = NULL; - p->flags = 0; - *(const apreq_value_t **)&v = &p->v; - - if (vlen > 0) { - status = apreq_decode(v->data, &v->dlen, word + nlen + 1, vlen); - if (status != APR_SUCCESS) { - *param = NULL; - return status; - } - charset = apreq_charset_divine(v->data, v->dlen); - } - else { - v->data[0] = 0; - v->dlen = 0; - charset = APREQ_CHARSET_ASCII; - } - v->name = v->data + vlen + 1; - - status = apreq_decode(v->name, &v->nlen, word, nlen); - if (status != APR_SUCCESS) { - *param = NULL; - return status; - } - - switch (apreq_charset_divine(v->name, v->nlen)) { - case APREQ_CHARSET_UTF8: - if (charset == APREQ_CHARSET_ASCII) - charset = APREQ_CHARSET_UTF8; - case APREQ_CHARSET_ASCII: - break; - - case APREQ_CHARSET_LATIN1: - if (charset != APREQ_CHARSET_CP1252) - charset = APREQ_CHARSET_LATIN1; - break; - case APREQ_CHARSET_CP1252: - charset = APREQ_CHARSET_CP1252; - } - - apreq_param_charset_set(p, charset); - *param = p; - - return APR_SUCCESS; -} - - -APREQ_DECLARE(char *) apreq_param_encode(apr_pool_t *pool, - const apreq_param_t *param) -{ - apr_size_t dlen; - char *data; - data = apr_palloc(pool, 3 * (param->v.nlen + param->v.dlen) + 2); - dlen = apreq_encode(data, param->v.name, param->v.nlen); - data[dlen++] = '='; - dlen += apreq_encode(data + dlen, param->v.data, param->v.dlen); - - return data; -} - -APREQ_DECLARE(apr_status_t) apreq_parse_query_string(apr_pool_t *pool, - apr_table_t *t, - const char *qs) -{ - const char *start = qs; - apr_size_t nlen = 0; - - for (;;++qs) { - switch (*qs) { - - case '=': - if (nlen == 0) { - nlen = qs - start; - } - break; - - case '&': - case ';': - case 0: - if (qs > start) { - apr_size_t vlen = 0; - apreq_param_t *param; - apr_status_t s; - if (nlen == 0) - nlen = qs - start; - else - vlen = qs - start - nlen - 1; - - s = apreq_param_decode(¶m, pool, start, nlen, vlen); - if (s != APR_SUCCESS) - return s; - - apreq_param_tainted_on(param); - apreq_value_table_add(¶m->v, t); - } - - if (*qs == 0) - return APR_SUCCESS; - - nlen = 0; - start = qs + 1; - } - } - /* not reached */ - return APR_INCOMPLETE; -} - - - - -static int param_push(void *data, const char *key, const char *val) -{ - apr_array_header_t *arr = data; - *(apreq_param_t **)apr_array_push(arr) = - apreq_value_to_param(val); - return 1; /* keep going */ -} - - -APREQ_DECLARE(apr_array_header_t *) apreq_params_as_array(apr_pool_t *p, - const apr_table_t *t, - const char *key) -{ - apr_array_header_t *arr; - - arr = apr_array_make(p, apr_table_elts(t)->nelts, - sizeof(apreq_param_t *)); - - apr_table_do(param_push, arr, t, key, NULL); - return arr; -} - -APREQ_DECLARE(const char *) apreq_params_as_string(apr_pool_t *p, - const apr_table_t *t, - const char *key, - apreq_join_t mode) -{ - apr_array_header_t *arr = apreq_params_as_array(p, t, key); - apreq_param_t **elt = (apreq_param_t **)arr->elts; - apreq_param_t **const end = elt + arr->nelts; - if (arr->nelts == 0) - return apr_pstrdup(p, ""); - - while (elt < end) { - *(const apreq_value_t **)elt = &(**elt).v; - ++elt; - } - return apreq_join(p, ", ", arr, mode); -} - - - -static int upload_push(void *data, const char *key, const char *val) -{ - apr_table_t *t = data; - apreq_param_t *p = apreq_value_to_param(val); - - if (p->upload != NULL) - apreq_value_table_add(&p->v, t); - return 1; /* keep going */ -} - - -APREQ_DECLARE(const apr_table_t *) apreq_uploads(const apr_table_t *body, - apr_pool_t *pool) -{ - apr_table_t *t = apr_table_make(pool, APREQ_DEFAULT_NELTS); - apr_table_do(upload_push, t, body, NULL); - return t; -} - -static int upload_set(void *data, const char *key, const char *val) -{ - const apreq_param_t **q = data; - apreq_param_t *p = apreq_value_to_param(val); - - if (p->upload != NULL) { - *q = p; - return 0; /* upload found, stop */ - } - else - return 1; /* keep searching */ -} - - -APREQ_DECLARE(const apreq_param_t *) apreq_upload(const apr_table_t *body, - const char *name) -{ - apreq_param_t *param = NULL; - apr_table_do(upload_set, ¶m, body, name, NULL); - return param; -} diff --git a/srclib/libapreq/library/parser.c b/srclib/libapreq/library/parser.c deleted file mode 100644 index 69c0c4f035..0000000000 --- a/srclib/libapreq/library/parser.c +++ /dev/null @@ -1,356 +0,0 @@ -/* -** 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. -*/ - -#include "apreq_error.h" -#include "apreq_parser.h" -#include "apreq_util.h" -#include "apr_strings.h" -#include "apr_xml.h" -#include "apr_hash.h" - -#define PARSER_STATUS_CHECK(PREFIX) do { \ - if (ctx->status == PREFIX##_ERROR) \ - return APREQ_ERROR_GENERAL; \ - else if (ctx->status == PREFIX##_COMPLETE) \ - return APR_SUCCESS; \ - else if (bb == NULL) \ - return APR_INCOMPLETE; \ -} while (0); - -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) -{ - apreq_parser_t *p = apr_palloc(pool, sizeof *p); - p->content_type = content_type; - p->parser = pfn; - p->hook = hook; - p->pool = pool; - p->bucket_alloc = ba; - p->brigade_limit = brigade_limit; - p->temp_dir = temp_dir; - p->ctx = ctx; - return p; -} - -APREQ_DECLARE(apreq_hook_t *) apreq_hook_make(apr_pool_t *pool, - apreq_hook_function_t hook, - apreq_hook_t *next, - void *ctx) -{ - apreq_hook_t *h = apr_palloc(pool, sizeof *h); - h->hook = hook; - h->next = next; - h->pool = pool; - h->ctx = ctx; - return h; -} - - -/*XXX this may need to check the parser's state before modifying the hook list */ -APREQ_DECLARE(apr_status_t) apreq_parser_add_hook(apreq_parser_t *p, - apreq_hook_t *h) -{ - apreq_hook_t *last = h; - - while (last->next) - last = last->next; - - last->next = p->hook; - p->hook = h; - - return APR_SUCCESS; -} - -static int default_parsers_lock = 0; -static apr_hash_t *default_parsers = NULL; -static apr_pool_t *default_parser_pool = NULL; - -static apr_status_t apreq_parsers_cleanup(void *data) -{ - default_parsers_lock = 0; - default_parsers = NULL; - default_parser_pool = NULL; - - return APR_SUCCESS; -} - -APREQ_DECLARE(apr_status_t) apreq_pre_initialize(apr_pool_t *pool) -{ - apr_status_t status; - - if (default_parser_pool != NULL) - return APR_SUCCESS; - - if (default_parsers_lock) - return APREQ_ERROR_GENERAL; - - status = apr_pool_create(&default_parser_pool, pool); - if (status != APR_SUCCESS) - return status; - - apr_pool_cleanup_register(default_parser_pool, NULL, - apreq_parsers_cleanup, - apr_pool_cleanup_null); - - default_parsers = apr_hash_make(default_parser_pool); - - apreq_register_parser("application/x-www-form-urlencoded", - apreq_parse_urlencoded); - apreq_register_parser("multipart/form-data", apreq_parse_multipart); - apreq_register_parser("multipart/related", apreq_parse_multipart); - - return APR_SUCCESS; -} - -APREQ_DECLARE(apr_status_t) apreq_post_initialize(apr_pool_t *pool) -{ - (void)pool; - - if (default_parser_pool == NULL) - return APREQ_ERROR_GENERAL; - - default_parsers_lock = 1; - return APR_SUCCESS; -} - -APREQ_DECLARE(apr_status_t) apreq_initialize(apr_pool_t *pool) -{ - apr_status_t s = apreq_pre_initialize(pool); - - if (s != APR_SUCCESS) - return s; - - return apreq_post_initialize(pool); -} - - -APREQ_DECLARE(apr_status_t) apreq_register_parser(const char *enctype, - apreq_parser_function_t pfn) -{ - apreq_parser_function_t *f = NULL; - - if (default_parsers == NULL) - return APR_EINIT; - - if (enctype == NULL) - return APR_EINVAL; - - if (default_parsers_lock) - return APREQ_ERROR_GENERAL; - - if (pfn != NULL) { - f = apr_palloc(default_parser_pool, sizeof *f); - *f = pfn; - } - apr_hash_set(default_parsers, apr_pstrdup(default_parser_pool, enctype), - APR_HASH_KEY_STRING, f); - - return APR_SUCCESS; -} - -APREQ_DECLARE(apreq_parser_function_t)apreq_parser(const char *enctype) -{ - apreq_parser_function_t *f; - apr_size_t tlen = 0; - - if (enctype == NULL || default_parsers_lock == 0) - return NULL; - - while(enctype[tlen] && enctype[tlen] != ';') - ++tlen; - - f = apr_hash_get(default_parsers, enctype, tlen); - - if (f != NULL) - return *f; - else - return NULL; -} - -APREQ_DECLARE_HOOK(apreq_hook_disable_uploads) -{ - return (bb == NULL) ? APR_SUCCESS : APREQ_ERROR_GENERAL; -} - -APREQ_DECLARE_HOOK(apreq_hook_discard_brigade) -{ - apr_status_t s = APR_SUCCESS; - if (hook->next) - s = apreq_hook_run(hook->next, param, bb); - if (bb != NULL) - apr_brigade_cleanup(bb); - return s; -} - - -/* generic parser */ - -struct gen_ctx { - apreq_param_t *param; - enum { - GEN_INCOMPLETE, - GEN_COMPLETE, - GEN_ERROR - } status; -}; - -APREQ_DECLARE_PARSER(apreq_parse_generic) -{ - struct gen_ctx *ctx = parser->ctx; - apr_pool_t *pool = parser->pool; - apr_status_t s = APR_SUCCESS; - apr_bucket *e = APR_BRIGADE_LAST(bb); - unsigned saw_eos = 0; - - if (ctx == NULL) { - parser->ctx = ctx = apr_palloc(pool, sizeof *ctx); - ctx->status = GEN_INCOMPLETE; - ctx->param = apreq_param_make(pool, - "_dummy_", strlen("_dummy_"), "", 0); - ctx->param->upload = apr_brigade_create(pool, parser->bucket_alloc); - ctx->param->info = apr_table_make(pool, APREQ_DEFAULT_NELTS); - } - - - PARSER_STATUS_CHECK(GEN); - - while (e != APR_BRIGADE_SENTINEL(bb)) { - if (APR_BUCKET_IS_EOS(e)) { - saw_eos = 1; - break; - } - e = APR_BUCKET_PREV(e); - } - - if (parser->hook != NULL) { - s = apreq_hook_run(parser->hook, ctx->param, bb); - if (s != APR_SUCCESS) { - ctx->status = GEN_ERROR; - return s; - } - } - - apreq_brigade_setaside(bb, pool); - s = apreq_brigade_concat(pool, parser->temp_dir, parser->brigade_limit, - ctx->param->upload, bb); - - if (s != APR_SUCCESS) { - ctx->status = GEN_ERROR; - return s; - } - - if (saw_eos) { - ctx->status = GEN_COMPLETE; - return APR_SUCCESS; - } - else - return APR_INCOMPLETE; -} - - -struct xml_ctx { - apr_xml_doc *doc; - apr_xml_parser *xml_parser; - enum { - XML_INCOMPLETE, - XML_COMPLETE, - XML_ERROR - } status; -}; - - -APREQ_DECLARE_HOOK(apreq_hook_apr_xml_parser) -{ - apr_pool_t *pool = hook->pool; - struct xml_ctx *ctx = hook->ctx; - apr_status_t s = APR_SUCCESS; - apr_bucket *e; - - if (ctx == NULL) { - hook->ctx = ctx = apr_palloc(pool, sizeof *ctx); - ctx->doc = NULL; - ctx->xml_parser = apr_xml_parser_create(pool); - ctx->status = XML_INCOMPLETE; - } - - PARSER_STATUS_CHECK(XML); - - for (e = APR_BRIGADE_FIRST(bb); e != APR_BRIGADE_SENTINEL(bb); - e = APR_BUCKET_NEXT(e)) - { - const char *data; - apr_size_t dlen; - - if (APR_BUCKET_IS_EOS(e)) { - s = apr_xml_parser_done(ctx->xml_parser, &ctx->doc); - if (s == APR_SUCCESS) { - ctx->status = XML_COMPLETE; - if (hook->next) - s = apreq_hook_run(hook->next, param, bb); - } - else { - ctx->status = XML_ERROR; - } - return s; - } - else if (APR_BUCKET_IS_METADATA(e)) { - continue; - } - - s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ); - - if (s != APR_SUCCESS) { - ctx->status = XML_ERROR; - return s; - } - - s = apr_xml_parser_feed(ctx->xml_parser, data, dlen); - - if (s != APR_SUCCESS) { - ctx->status = XML_ERROR; - return s; - } - - } - - if (hook->next) - return apreq_hook_run(hook->next, param, bb); - - return APR_SUCCESS; -} - - -APREQ_DECLARE_HOOK(apreq_hook_find_param) -{ - apreq_hook_find_param_ctx_t *ctx = hook->ctx; - int is_final = (bb == NULL) || APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb)); - apr_status_t s = (hook->next == NULL) - ? APR_SUCCESS : apreq_hook_run(hook->next, param, bb); - - if (is_final && s == APR_SUCCESS - && strcasecmp(ctx->name, param->v.name) == 0) { - ctx->param = param; - ctx->prev->next = hook->next; - } - return s; -} diff --git a/srclib/libapreq/library/parser_header.c b/srclib/libapreq/library/parser_header.c deleted file mode 100644 index ae2e030062..0000000000 --- a/srclib/libapreq/library/parser_header.c +++ /dev/null @@ -1,365 +0,0 @@ -/* -** 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. -*/ -#include <assert.h> -#include "apreq_parser.h" -#include "apreq_error.h" -#include "apreq_util.h" - -#define PARSER_STATUS_CHECK(PREFIX) do { \ - if (ctx->status == PREFIX##_ERROR) \ - return APREQ_ERROR_GENERAL; \ - else if (ctx->status == PREFIX##_COMPLETE) \ - return APR_SUCCESS; \ - else if (bb == NULL) \ - return APR_INCOMPLETE; \ -} while (0); - - -struct hdr_ctx { - apr_bucket_brigade *bb; - apr_size_t nlen; - apr_size_t glen; - apr_size_t vlen; - enum { - HDR_NAME, - HDR_GAP, - HDR_VALUE, - HDR_NEWLINE, - HDR_CONTINUE, - HDR_COMPLETE, - HDR_ERROR - } status; -}; - -/********************* header parsing utils ********************/ - - -static apr_status_t split_header_line(apreq_param_t **p, - apr_pool_t *pool, - apr_bucket_brigade *bb, - apr_size_t nlen, - apr_size_t glen, - apr_size_t vlen) -{ - apreq_param_t *param; - apreq_value_t *v; - apr_bucket *e, *f; - apr_status_t s; - struct iovec vec[APREQ_DEFAULT_NELTS], *iov, *end; - apr_array_header_t arr; - char *dest; - const char *data; - apr_size_t dlen; - - if (nlen == 0) - return APR_EBADARG; - - param = apreq_param_make(pool, NULL, nlen, NULL, vlen - 1); /*drop (CR)LF */ - *(const apreq_value_t **)&v = ¶m->v; - - arr.pool = pool; - arr.elt_size = sizeof(struct iovec); - arr.nelts = 0; - arr.nalloc = APREQ_DEFAULT_NELTS; - arr.elts = (char *)vec; - - e = APR_BRIGADE_FIRST(bb); - - /* store name in a temporary iovec array */ - - while (nlen > 0) { - apr_size_t len; - end = apr_array_push(&arr); - s = apr_bucket_read(e, (const char **)&end->iov_base, - &len, APR_BLOCK_READ); - if (s != APR_SUCCESS) - return s; - - assert(nlen >= len); - end->iov_len = len; - nlen -= len; - - e = APR_BUCKET_NEXT(e); - } - - /* skip gap */ - - while (glen > 0) { - s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ); - if (s != APR_SUCCESS) - return s; - - assert(glen >= dlen); - glen -= dlen; - e = APR_BUCKET_NEXT(e); - } - - /* copy value */ - assert(vlen > 0); - dest = v->data; - while (vlen > 0) { - - s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ); - if (s != APR_SUCCESS) - return s; - - memcpy(dest, data, dlen); - dest += dlen; - assert(vlen >= dlen); - vlen -= dlen; - e = APR_BUCKET_NEXT(e); - } - - assert(dest[-1] == '\n'); - - if (dest[-2] == '\r') - --dest; - - dest[-1] = 0; - v->dlen = (dest - v->data) - 1; - - /* write name */ - v->name = dest; - iov = (struct iovec *)arr.elts; - - while (iov <= end) { - memcpy(dest, iov->iov_base, iov->iov_len); - dest += iov->iov_len; - ++iov; - } - *dest = 0; - nlen = dest - v->name; - - while ((f = APR_BRIGADE_FIRST(bb)) != e) - apr_bucket_delete(f); - - apreq_param_tainted_on(param); - *p = param; - return APR_SUCCESS; - -} - - -APREQ_DECLARE_PARSER(apreq_parse_headers) -{ - apr_pool_t *pool = parser->pool; - apr_bucket *e; - struct hdr_ctx *ctx; - - if (parser->ctx == NULL) { - ctx = apr_pcalloc(pool, sizeof *ctx); - ctx->bb = apr_brigade_create(pool, parser->bucket_alloc); - parser->ctx = ctx; - ctx->status = HDR_NAME; - } - else - ctx = parser->ctx; - - PARSER_STATUS_CHECK(HDR); - e = APR_BRIGADE_LAST(ctx->bb); - APR_BRIGADE_CONCAT(ctx->bb, bb); - - parse_hdr_brigade: - - - /* parse the brigade for CRLF_CRLF-terminated header block, - * each time starting from the front of the brigade. - */ - - for (e = APR_BUCKET_NEXT(e); - e != APR_BRIGADE_SENTINEL(ctx->bb); - e = APR_BUCKET_NEXT(e)) - { - apr_size_t off = 0, dlen; - const char *data; - apr_status_t s; - apreq_param_t *param = NULL; /* silences gcc-4.0 warning */ - - if (APR_BUCKET_IS_EOS(e)) { - ctx->status = HDR_COMPLETE; - APR_BRIGADE_CONCAT(bb, ctx->bb); - return APR_SUCCESS; - } - s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ); - - if ( s != APR_SUCCESS ) { - ctx->status = HDR_ERROR; - return s; - } - if (dlen == 0) - continue; - - parse_hdr_bucket: - - /* gap nlen = 13 - * vvv glen = 3 - * Sample-Header: grape vlen = 5 - * ^^^^^^^^^^^^^ ^^^^^ - * name value - */ - - switch (ctx->status) { - - case HDR_NAME: - - while (off < dlen) { - switch (data[off++]) { - - case '\n': - if (off < dlen) - apr_bucket_split(e, off); - e = APR_BUCKET_NEXT(e); - - do { - apr_bucket *f = APR_BRIGADE_FIRST(ctx->bb); - apr_bucket_delete(f); - } while (e != APR_BRIGADE_FIRST(ctx->bb)); - APR_BRIGADE_CONCAT(bb, ctx->bb); - ctx->status = HDR_COMPLETE; - return APR_SUCCESS; - - case ':': - if (off > 1) { - apr_bucket_split(e, off - 1); - dlen -= off - 1; - data += off - 1; - off = 1; - e = APR_BUCKET_NEXT(e); - } - ++ctx->glen; - ctx->status = HDR_GAP; - goto parse_hdr_bucket; - - default: - ++ctx->nlen; - } - - } - - break; - - - case HDR_GAP: - - while (off < dlen) { - switch (data[off++]) { - case ' ': - case '\t': - ++ctx->glen; - break; - - case '\n': - ctx->status = HDR_NEWLINE; - goto parse_hdr_bucket; - - default: - ctx->status = HDR_VALUE; - if (off > 1) { - apr_bucket_split(e, off - 1); - dlen -= off - 1; - data += off - 1; - off = 1; - e = APR_BUCKET_NEXT(e); - } - ++ctx->vlen; - goto parse_hdr_bucket; - } - } - break; - - - case HDR_VALUE: - - while (off < dlen) { - ++ctx->vlen; - if (data[off++] == '\n') { - ctx->status = HDR_NEWLINE; - goto parse_hdr_bucket; - } - } - break; - - - case HDR_NEWLINE: - - if (off == dlen) - break; - else { - switch (data[off]) { - - case ' ': - case '\t': - ctx->status = HDR_CONTINUE; - ++off; - ++ctx->vlen; - break; - - default: - /* can parse brigade now */ - if (off > 0) - apr_bucket_split(e, off); - s = split_header_line(¶m, pool, ctx->bb, ctx->nlen, ctx->glen, ctx->vlen); - if (parser->hook != NULL && s == APR_SUCCESS) - s = apreq_hook_run(parser->hook, param, NULL); - - if (s != APR_SUCCESS) { - ctx->status = HDR_ERROR; - return s; - } - - apreq_value_table_add(¶m->v, t); - e = APR_BRIGADE_SENTINEL(ctx->bb); - ctx->status = HDR_NAME; - ctx->nlen = 0; - ctx->vlen = 0; - ctx->glen = 0; - - goto parse_hdr_brigade; - } - - /* cases ' ', '\t' fall through to HDR_CONTINUE */ - } - - - case HDR_CONTINUE: - - while (off < dlen) { - switch (data[off++]) { - case ' ': - case '\t': - ++ctx->vlen; - break; - - case '\n': - ctx->status = HDR_NEWLINE; - goto parse_hdr_bucket; - - default: - ctx->status = HDR_VALUE; - ++ctx->vlen; - goto parse_hdr_bucket; - } - } - break; - - default: - ; /* not reached */ - } - } - apreq_brigade_setaside(ctx->bb,pool); - return APR_INCOMPLETE; -} diff --git a/srclib/libapreq/library/parser_multipart.c b/srclib/libapreq/library/parser_multipart.c deleted file mode 100644 index 60b5bad9de..0000000000 --- a/srclib/libapreq/library/parser_multipart.c +++ /dev/null @@ -1,661 +0,0 @@ -/* -** 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. -*/ - -#include "apreq_parser.h" -#include "apreq_error.h" -#include "apreq_util.h" -#include "apr_strings.h" -#include "apr_strmatch.h" - -#ifndef CRLF -#define CRLF "\015\012" -#endif - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - -#define PARSER_STATUS_CHECK(PREFIX) do { \ - if (ctx->status == PREFIX##_ERROR) \ - return APREQ_ERROR_GENERAL; \ - else if (ctx->status == PREFIX##_COMPLETE) \ - return APR_SUCCESS; \ - else if (bb == NULL) \ - return APR_INCOMPLETE; \ -} while (0); - -/* maximum recursion level in the mfd parser */ -#define MAX_LEVEL 8 - -struct mfd_ctx { - apr_table_t *info; - apr_bucket_brigade *in; - apr_bucket_brigade *bb; - apreq_parser_t *hdr_parser; - apreq_parser_t *next_parser; - const apr_strmatch_pattern *pattern; - char *bdry; - enum { - MFD_INIT, - MFD_NEXTLINE, - MFD_HEADER, - MFD_POST_HEADER, - MFD_PARAM, - MFD_UPLOAD, - MFD_MIXED, - MFD_COMPLETE, - MFD_ERROR - } status; - apr_bucket *eos; - const char *param_name; - apreq_param_t *upload; - unsigned level; -}; - - -/********************* multipart/form-data *********************/ - -APR_INLINE -static apr_status_t brigade_start_string(apr_bucket_brigade *bb, - const char *start_string) -{ - apr_bucket *e; - apr_size_t slen = strlen(start_string); - - for (e = APR_BRIGADE_FIRST(bb); e != APR_BRIGADE_SENTINEL(bb); - e = APR_BUCKET_NEXT(e)) - { - const char *buf; - apr_status_t s, bytes_to_check; - apr_size_t blen; - - if (slen == 0) - return APR_SUCCESS; - - if (APR_BUCKET_IS_EOS(e)) - return APR_EOF; - - s = apr_bucket_read(e, &buf, &blen, APR_BLOCK_READ); - - if (s != APR_SUCCESS) - return s; - - if (blen == 0) - continue; - - bytes_to_check = MIN(slen,blen); - - if (strncmp(buf,start_string,bytes_to_check) != 0) - return APREQ_ERROR_GENERAL; - - slen -= bytes_to_check; - start_string += bytes_to_check; - } - - /* slen > 0, so brigade isn't large enough yet */ - return APR_INCOMPLETE; -} - - -static apr_status_t split_on_bdry(apr_bucket_brigade *out, - apr_bucket_brigade *in, - const apr_strmatch_pattern *pattern, - const char *bdry) -{ - apr_bucket *e = APR_BRIGADE_FIRST(in); - apr_size_t blen = strlen(bdry), off = 0; - - while ( e != APR_BRIGADE_SENTINEL(in) ) { - apr_ssize_t idx; - apr_size_t len; - const char *buf; - apr_status_t s; - - if (APR_BUCKET_IS_EOS(e)) - return APR_EOF; - - s = apr_bucket_read(e, &buf, &len, APR_BLOCK_READ); - if (s != APR_SUCCESS) - return s; - - if (len == 0) { - apr_bucket *f = e; - e = APR_BUCKET_NEXT(e); - apr_bucket_delete(f); - continue; - } - - look_for_boundary_up_front: - if (strncmp(bdry + off, buf, MIN(len, blen - off)) == 0) { - if ( len >= blen - off ) { - /* complete match */ - if (len > blen - off) - apr_bucket_split(e, blen - off); - e = APR_BUCKET_NEXT(e); - - do { - apr_bucket *f = APR_BRIGADE_FIRST(in); - apr_bucket_delete(f); - } while (APR_BRIGADE_FIRST(in) != e); - - return APR_SUCCESS; - } - /* partial match */ - off += len; - e = APR_BUCKET_NEXT(e); - continue; - } - else if (off > 0) { - /* prior (partial) strncmp failed, - * so we can move previous buckets across - * and retest buf against the full bdry. - */ - - /* give hints to GCC by making the brigade volatile, otherwise the - * loop below will end up being endless. See: - * https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=193740 - */ - apr_bucket_brigade * volatile in_v = in; - - do { - apr_bucket *f = APR_BRIGADE_FIRST(in_v); - APR_BUCKET_REMOVE(f); - APR_BRIGADE_INSERT_TAIL(out, f); - } while (e != APR_BRIGADE_FIRST(in_v)); - off = 0; - goto look_for_boundary_up_front; - } - - if (pattern != NULL && len >= blen) { - const char *match = apr_strmatch(pattern, buf, len); - if (match != NULL) - idx = match - buf; - else { - idx = apreq_index(buf + len-blen, blen, bdry, blen, - APREQ_MATCH_PARTIAL); - if (idx >= 0) - idx += len-blen; - } - } - else - idx = apreq_index(buf, len, bdry, blen, APREQ_MATCH_PARTIAL); - - /* Theoretically idx should never be 0 here, because we - * already tested the front of the brigade for a potential match. - * However, it doesn't hurt to allow for the possibility, - * since this will just start the whole loop over again. - */ - if (idx >= 0) - apr_bucket_split(e, idx); - - APR_BUCKET_REMOVE(e); - APR_BRIGADE_INSERT_TAIL(out, e); - e = APR_BRIGADE_FIRST(in); - } - - return APR_INCOMPLETE; -} - - -static -struct mfd_ctx * create_multipart_context(const char *content_type, - apr_pool_t *pool, - apr_bucket_alloc_t *ba, - apr_size_t brigade_limit, - const char *temp_dir, - unsigned level) - -{ - apr_status_t s; - apr_size_t blen; - struct mfd_ctx *ctx = apr_palloc(pool, sizeof *ctx); - char *ct = apr_pstrdup(pool, content_type); - - ct = strchr(ct, ';'); - if (ct == NULL) - return NULL; /* missing semicolon */ - - *ct++ = 0; - s = apreq_header_attribute(ct, "boundary", 8, - (const char **)&ctx->bdry, &blen); - - if (s != APR_SUCCESS) - return NULL; /* missing boundary */ - - ctx->bdry[blen] = 0; - - *--ctx->bdry = '-'; - *--ctx->bdry = '-'; - *--ctx->bdry = '\n'; - *--ctx->bdry = '\r'; - - ctx->status = MFD_INIT; - ctx->pattern = apr_strmatch_precompile(pool, ctx->bdry, 1); - ctx->hdr_parser = apreq_parser_make(pool, ba, "", - apreq_parse_headers, - brigade_limit, - temp_dir, NULL, NULL); - ctx->info = NULL; - ctx->bb = apr_brigade_create(pool, ba); - ctx->in = apr_brigade_create(pool, ba); - ctx->eos = apr_bucket_eos_create(ba); - ctx->next_parser = NULL; - ctx->param_name = NULL; - ctx->upload = NULL; - ctx->level = level; - - return ctx; -} - -APREQ_DECLARE_PARSER(apreq_parse_multipart) -{ - apr_pool_t *pool = parser->pool; - apr_bucket_alloc_t *ba = parser->bucket_alloc; - struct mfd_ctx *ctx = parser->ctx; - apr_status_t s; - - if (ctx == NULL) { - ctx = create_multipart_context(parser->content_type, - pool, ba, - parser->brigade_limit, - parser->temp_dir, 1); - if (ctx == NULL) - return APREQ_ERROR_GENERAL; - - - parser->ctx = ctx; - } - - PARSER_STATUS_CHECK(MFD); - APR_BRIGADE_CONCAT(ctx->in, bb); - - mfd_parse_brigade: - - switch (ctx->status) { - - case MFD_INIT: - { - s = split_on_bdry(ctx->bb, ctx->in, NULL, ctx->bdry + 2); - if (s != APR_SUCCESS) { - apreq_brigade_setaside(ctx->in, pool); - apreq_brigade_setaside(ctx->bb, pool); - return s; - } - ctx->status = MFD_NEXTLINE; - /* Be polite and return any preamble text to the caller. */ - APR_BRIGADE_CONCAT(bb, ctx->bb); - } - - /* fall through */ - - case MFD_NEXTLINE: - { - s = split_on_bdry(ctx->bb, ctx->in, NULL, CRLF); - if (s == APR_EOF) { - ctx->status = MFD_COMPLETE; - return APR_SUCCESS; - } - if (s != APR_SUCCESS) { - apreq_brigade_setaside(ctx->in, pool); - apreq_brigade_setaside(ctx->bb, pool); - return s; - } - if (!APR_BRIGADE_EMPTY(ctx->bb)) { - char *line; - apr_size_t len; - apr_brigade_pflatten(ctx->bb, &line, &len, pool); - - if (len >= 2 && strncmp(line, "--", 2) == 0) { - APR_BRIGADE_CONCAT(bb, ctx->in); - ctx->status = MFD_COMPLETE; - return APR_SUCCESS; - } - apr_brigade_cleanup(ctx->bb); - } - - ctx->status = MFD_HEADER; - ctx->info = NULL; - } - /* fall through */ - - case MFD_HEADER: - { - if (ctx->info == NULL) { - ctx->info = apr_table_make(pool, APREQ_DEFAULT_NELTS); - /* flush out header parser internal structs for reuse */ - ctx->hdr_parser->ctx = NULL; - } - s = apreq_parser_run(ctx->hdr_parser, ctx->info, ctx->in); - switch (s) { - case APR_SUCCESS: - ctx->status = MFD_POST_HEADER; - break; - case APR_INCOMPLETE: - apreq_brigade_setaside(ctx->in, pool); - return APR_INCOMPLETE; - default: - ctx->status = MFD_ERROR; - return s; - } - } - /* fall through */ - - case MFD_POST_HEADER: - { - /* Must handle special case of missing CRLF (mainly - * coming from empty file uploads). See RFC2065 S5.1.1: - * - * body-part = MIME-part-header [CRLF *OCTET] - * - * So the CRLF we already matched in MFD_HEADER may have been - * part of the boundary string! Both Konqueror (v??) and - * Mozilla-0.97 are known to emit such blocks. - * - * Here we first check for this condition with - * brigade_start_string, and prefix the brigade with - * an additional CRLF bucket if necessary. - */ - - const char *cd, *ct, *name, *filename; - apr_size_t nlen, flen; - apr_bucket *e; - - switch (brigade_start_string(ctx->in, ctx->bdry + 2)) { - - case APR_INCOMPLETE: - apreq_brigade_setaside(ctx->in, pool); - return APR_INCOMPLETE; - - case APR_SUCCESS: - /* part has no body- return CRLF to front */ - e = apr_bucket_immortal_create(CRLF, 2, - ctx->bb->bucket_alloc); - APR_BRIGADE_INSERT_HEAD(ctx->in, e); - break; - - default: - ; /* has body, ok */ - } - - cd = apr_table_get(ctx->info, "Content-Disposition"); - - /* First check to see if must descend into a new multipart - * block. If we do, create a new parser and pass control - * to it. - */ - - ct = apr_table_get(ctx->info, "Content-Type"); - - if (ct != NULL && strncmp(ct, "multipart/", 10) == 0) { - struct mfd_ctx *next_ctx; - - if (ctx->level >= MAX_LEVEL) { - ctx->status = MFD_ERROR; - goto mfd_parse_brigade; - } - - next_ctx = create_multipart_context(ct, pool, ba, - parser->brigade_limit, - parser->temp_dir, - ctx->level + 1); - - next_ctx->param_name = ""; - - if (cd != NULL) { - s = apreq_header_attribute(cd, "name", 4, - &name, &nlen); - if (s == APR_SUCCESS) { - next_ctx->param_name - = apr_pstrmemdup(pool, name, nlen); - } - else { - const char *cid = apr_table_get(ctx->info, - "Content-ID"); - if (cid != NULL) - next_ctx->param_name = apr_pstrdup(pool, cid); - } - - } - - ctx->next_parser = apreq_parser_make(pool, ba, ct, - apreq_parse_multipart, - parser->brigade_limit, - parser->temp_dir, - parser->hook, - next_ctx); - ctx->status = MFD_MIXED; - goto mfd_parse_brigade; - - } - - /* Look for a normal form-data part. */ - - if (cd != NULL && strncmp(cd, "form-data", 9) == 0) { - s = apreq_header_attribute(cd, "name", 4, &name, &nlen); - if (s != APR_SUCCESS) { - ctx->status = MFD_ERROR; - goto mfd_parse_brigade; - } - - s = apreq_header_attribute(cd, "filename", - 8, &filename, &flen); - if (s == APR_SUCCESS) { - apreq_param_t *param; - - param = apreq_param_make(pool, name, nlen, - filename, flen); - apreq_param_tainted_on(param); - param->info = ctx->info; - param->upload - = apr_brigade_create(pool, ctx->bb->bucket_alloc); - ctx->upload = param; - ctx->status = MFD_UPLOAD; - goto mfd_parse_brigade; - } - else { - ctx->param_name = apr_pstrmemdup(pool, name, nlen); - ctx->status = MFD_PARAM; - /* fall thru */ - } - } - - /* else check for a file part in a multipart section */ - else if (cd != NULL && strncmp(cd, "file", 4) == 0) { - apreq_param_t *param; - - s = apreq_header_attribute(cd, "filename", - 8, &filename, &flen); - if (s != APR_SUCCESS || ctx->param_name == NULL) { - ctx->status = MFD_ERROR; - goto mfd_parse_brigade; - } - name = ctx->param_name; - nlen = strlen(name); - param = apreq_param_make(pool, name, nlen, - filename, flen); - apreq_param_tainted_on(param); - param->info = ctx->info; - param->upload = apr_brigade_create(pool, - ctx->bb->bucket_alloc); - ctx->upload = param; - ctx->status = MFD_UPLOAD; - goto mfd_parse_brigade; - } - - /* otherwise look for Content-ID in multipart/mixed case */ - else { - const char *cid = apr_table_get(ctx->info, "Content-ID"); - apreq_param_t *param; - - if (cid != NULL) { - name = cid; - nlen = strlen(name); - } - else { - name = ""; - nlen = 0; - } - - filename = ""; - flen = 0; - param = apreq_param_make(pool, name, nlen, - filename, flen); - apreq_param_tainted_on(param); - param->info = ctx->info; - param->upload = apr_brigade_create(pool, - ctx->bb->bucket_alloc); - ctx->upload = param; - ctx->status = MFD_UPLOAD; - goto mfd_parse_brigade; - } - } - /* fall through */ - - case MFD_PARAM: - { - apreq_param_t *param; - apreq_value_t *v; - apr_size_t len; - apr_off_t off; - - s = split_on_bdry(ctx->bb, ctx->in, ctx->pattern, ctx->bdry); - - switch (s) { - - case APR_INCOMPLETE: - apreq_brigade_setaside(ctx->in, pool); - apreq_brigade_setaside(ctx->bb, pool); - return s; - - case APR_SUCCESS: - s = apr_brigade_length(ctx->bb, 1, &off); - if (s != APR_SUCCESS) { - ctx->status = MFD_ERROR; - return s; - } - len = off; - param = apreq_param_make(pool, ctx->param_name, - strlen(ctx->param_name), - NULL, len); - apreq_param_tainted_on(param); - param->info = ctx->info; - - *(const apreq_value_t **)&v = ¶m->v; - apr_brigade_flatten(ctx->bb, v->data, &len); - v->data[len] = 0; - - if (parser->hook != NULL) { - s = apreq_hook_run(parser->hook, param, NULL); - if (s != APR_SUCCESS) { - ctx->status = MFD_ERROR; - return s; - } - } - - apreq_param_charset_set(param, - apreq_charset_divine(v->data, len)); - apreq_value_table_add(v, t); - ctx->status = MFD_NEXTLINE; - ctx->param_name = NULL; - apr_brigade_cleanup(ctx->bb); - goto mfd_parse_brigade; - - default: - ctx->status = MFD_ERROR; - return s; - } - - - } - break; /* not reached */ - - case MFD_UPLOAD: - { - apreq_param_t *param = ctx->upload; - - s = split_on_bdry(ctx->bb, ctx->in, ctx->pattern, ctx->bdry); - switch (s) { - - case APR_INCOMPLETE: - if (parser->hook != NULL) { - s = apreq_hook_run(parser->hook, param, ctx->bb); - if (s != APR_SUCCESS) { - ctx->status = MFD_ERROR; - return s; - } - } - apreq_brigade_setaside(ctx->bb, pool); - apreq_brigade_setaside(ctx->in, pool); - s = apreq_brigade_concat(pool, parser->temp_dir, - parser->brigade_limit, - param->upload, ctx->bb); - return (s == APR_SUCCESS) ? APR_INCOMPLETE : s; - - case APR_SUCCESS: - if (parser->hook != NULL) { - APR_BRIGADE_INSERT_TAIL(ctx->bb, ctx->eos); - s = apreq_hook_run(parser->hook, param, ctx->bb); - APR_BUCKET_REMOVE(ctx->eos); - if (s != APR_SUCCESS) { - ctx->status = MFD_ERROR; - return s; - } - } - apreq_value_table_add(¶m->v, t); - apreq_brigade_setaside(ctx->bb, pool); - s = apreq_brigade_concat(pool, parser->temp_dir, - parser->brigade_limit, - param->upload, ctx->bb); - - if (s != APR_SUCCESS) - return s; - - ctx->status = MFD_NEXTLINE; - goto mfd_parse_brigade; - - default: - ctx->status = MFD_ERROR; - return s; - } - - } - break; /* not reached */ - - - case MFD_MIXED: - { - s = apreq_parser_run(ctx->next_parser, t, ctx->in); - switch (s) { - case APR_SUCCESS: - ctx->status = MFD_INIT; - ctx->param_name = NULL; - goto mfd_parse_brigade; - case APR_INCOMPLETE: - APR_BRIGADE_CONCAT(bb, ctx->in); - return APR_INCOMPLETE; - default: - ctx->status = MFD_ERROR; - return s; - } - - } - break; /* not reached */ - - default: - return APREQ_ERROR_GENERAL; - } - - return APR_INCOMPLETE; -} diff --git a/srclib/libapreq/library/parser_urlencoded.c b/srclib/libapreq/library/parser_urlencoded.c deleted file mode 100644 index e90d0dd382..0000000000 --- a/srclib/libapreq/library/parser_urlencoded.c +++ /dev/null @@ -1,275 +0,0 @@ -/* -** 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. -*/ - -#include "apreq_parser.h" -#include "apreq_util.h" -#include "apreq_error.h" - - -#define PARSER_STATUS_CHECK(PREFIX) do { \ - if (ctx->status == PREFIX##_ERROR) \ - return APREQ_ERROR_GENERAL; \ - else if (ctx->status == PREFIX##_COMPLETE) \ - return APR_SUCCESS; \ - else if (bb == NULL) \ - return APR_INCOMPLETE; \ -} while (0); - - - -struct url_ctx { - apr_bucket_brigade *bb; - apr_size_t nlen; - apr_size_t vlen; - enum { - URL_NAME, - URL_VALUE, - URL_COMPLETE, - URL_ERROR - } status; -}; - - -/******************** application/x-www-form-urlencoded ********************/ - -static apr_status_t split_urlword(apreq_param_t **p, apr_pool_t *pool, - apr_bucket_brigade *bb, - apr_size_t nlen, - apr_size_t vlen) -{ - apreq_param_t *param; - apreq_value_t *v; - apr_bucket *e, *f; - apr_status_t s; - struct iovec vec[APREQ_DEFAULT_NELTS]; - apr_array_header_t arr; - apr_size_t mark; - apreq_charset_t charset; - - if (nlen == 0) - return APR_EBADARG; - - param = apreq_param_make(pool, NULL, nlen, NULL, vlen); - *(const apreq_value_t **)&v = ¶m->v; - - arr.pool = pool; - arr.elt_size = sizeof(struct iovec); - arr.nelts = 0; - arr.nalloc = APREQ_DEFAULT_NELTS; - arr.elts = (char *)vec; - - ++nlen, ++vlen; - e = APR_BRIGADE_FIRST(bb); - - while (!APR_BUCKET_IS_EOS(e)) { - struct iovec *iov = apr_array_push(&arr); - apr_size_t len; - s = apr_bucket_read(e, (const char **)&iov->iov_base, - &len, APR_BLOCK_READ); - if (s != APR_SUCCESS) - return s; - - iov->iov_len = len; - nlen -= len; - - e = APR_BUCKET_NEXT(e); - - if (nlen == 0) { - iov->iov_len--; - break; - } - } - - mark = arr.nelts; - - while (!APR_BUCKET_IS_EOS(e)) { - struct iovec *iov = apr_array_push(&arr); - apr_size_t len; - s = apr_bucket_read(e, (const char **)&iov->iov_base, - &len, APR_BLOCK_READ); - if (s != APR_SUCCESS) - return s; - - iov->iov_len = len; - vlen -= len; - - e = APR_BUCKET_NEXT(e); - - if (vlen == 0) { - iov->iov_len--; - break; - } - - } - - s = apreq_decodev(v->data, &vlen, - (struct iovec *)arr.elts + mark, arr.nelts - mark); - if (s != APR_SUCCESS) - return s; - - charset = apreq_charset_divine(v->data, vlen); - - v->name = v->data + vlen + 1; - v->dlen = vlen; - - s = apreq_decodev(v->name, &nlen, (struct iovec *)arr.elts, mark); - if (s != APR_SUCCESS) - return s; - - switch (apreq_charset_divine(v->name, nlen)) { - case APREQ_CHARSET_UTF8: - if (charset == APREQ_CHARSET_ASCII) - charset = APREQ_CHARSET_UTF8; - case APREQ_CHARSET_ASCII: - break; - - case APREQ_CHARSET_LATIN1: - if (charset != APREQ_CHARSET_CP1252) - charset = APREQ_CHARSET_LATIN1; - break; - case APREQ_CHARSET_CP1252: - charset = APREQ_CHARSET_CP1252; - } - - v->nlen = nlen; - - while ((f = APR_BRIGADE_FIRST(bb)) != e) - apr_bucket_delete(f); - - apreq_param_tainted_on(param); - apreq_param_charset_set(param, charset); - *p = param; - return APR_SUCCESS; -} - -APREQ_DECLARE_PARSER(apreq_parse_urlencoded) -{ - apr_pool_t *pool = parser->pool; - apr_bucket *e; - struct url_ctx *ctx; - - if (parser->ctx == NULL) { - ctx = apr_pcalloc(pool, sizeof *ctx); - ctx->bb = apr_brigade_create(pool, parser->bucket_alloc); - parser->ctx = ctx; - ctx->status = URL_NAME; - } - else - ctx = parser->ctx; - - PARSER_STATUS_CHECK(URL); - e = APR_BRIGADE_LAST(ctx->bb); - APR_BRIGADE_CONCAT(ctx->bb, bb); - - parse_url_brigade: - - for (e = APR_BUCKET_NEXT(e); - e != APR_BRIGADE_SENTINEL(ctx->bb); - e = APR_BUCKET_NEXT(e)) - { - apreq_param_t *param; - apr_size_t off = 0, dlen; - const char *data; - apr_status_t s; - - if (APR_BUCKET_IS_EOS(e)) { - if (ctx->status == URL_NAME) { - s = APR_SUCCESS; - } - else { - s = split_urlword(¶m, pool, ctx->bb, ctx->nlen, ctx->vlen); - if (parser->hook != NULL && s == APR_SUCCESS) - s = apreq_hook_run(parser->hook, param, NULL); - - if (s == APR_SUCCESS) { - apreq_value_table_add(¶m->v, t); - ctx->status = URL_COMPLETE; - } - else { - ctx->status = URL_ERROR; - } - } - - APR_BRIGADE_CONCAT(bb, ctx->bb); - return s; - } - - s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ); - if ( s != APR_SUCCESS ) { - ctx->status = URL_ERROR; - return s; - } - - parse_url_bucket: - - switch (ctx->status) { - - case URL_NAME: - while (off < dlen) { - switch (data[off++]) { - case '=': - apr_bucket_split(e, off); - dlen -= off; - data += off; - off = 0; - e = APR_BUCKET_NEXT(e); - ctx->status = URL_VALUE; - goto parse_url_bucket; - default: - ++ctx->nlen; - } - } - break; - - case URL_VALUE: - while (off < dlen) { - - switch (data[off++]) { - case '&': - case ';': - apr_bucket_split(e, off); - s = split_urlword(¶m, pool, ctx->bb, - ctx->nlen, ctx->vlen); - if (parser->hook != NULL && s == APR_SUCCESS) - s = apreq_hook_run(parser->hook, param, NULL); - - if (s != APR_SUCCESS) { - ctx->status = URL_ERROR; - return s; - } - - apreq_value_table_add(¶m->v, t); - ctx->status = URL_NAME; - ctx->nlen = 0; - ctx->vlen = 0; - e = APR_BRIGADE_SENTINEL(ctx->bb); - goto parse_url_brigade; - - default: - ++ctx->vlen; - } - } - break; - default: - ; /* not reached */ - } - } - apreq_brigade_setaside(ctx->bb, pool); - return APR_INCOMPLETE; -} - - diff --git a/srclib/libapreq/library/util.c b/srclib/libapreq/library/util.c deleted file mode 100644 index 6d33fa94fb..0000000000 --- a/srclib/libapreq/library/util.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* -** 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. -*/ - -#include "apreq_util.h" -#include "apreq_error.h" -#include "apr_time.h" -#include "apr_strings.h" -#include "apr_lib.h" -#include <assert.h> - -#undef MAX -#undef MIN -#define MIN(a,b) ( (a) < (b) ? (a) : (b) ) -#define MAX(a,b) ( (a) > (b) ? (a) : (b) ) - -/* used for specifying file sizes */ - -APREQ_DECLARE(apr_int64_t) apreq_atoi64f(const char *s) -{ - apr_int64_t n = 0; - char *p; - if (s == NULL) - return 0; - - n = apr_strtoi64(s, &p, 0); - - if (p == NULL) - return n; - while (apr_isspace(*p)) - ++p; - - switch (*p) { - case 'G': /* fall thru */ - case 'g': return n * 1024*1024*1024; - case 'M': /* fall thru */ - case 'm': return n * 1024*1024; - case 'K': /* fall thru */ - case 'k': return n * 1024; - } - - return n; -} - - -/* converts date offsets (e.g. "+3M") to seconds */ - -APREQ_DECLARE(apr_int64_t) apreq_atoi64t(const char *s) -{ - apr_int64_t n = 0; - char *p; - if (s == NULL) - return 0; - n = apr_strtoi64(s, &p, 0); /* XXX: what about overflow? */ - - if (p == NULL) - return n; - while (apr_isspace(*p)) - ++p; - - switch (*p) { - case 'Y': /* fall thru */ - case 'y': return n * 60*60*24*365; - case 'M': return n * 60*60*24*30; - case 'D': /* fall thru */ - case 'd': return n * 60*60*24; - case 'H': /* fall thru */ - case 'h': return n * 60*60; - case 'm': return n * 60; - case 's': /* fall thru */ - default: - return n; - } - /* should never get here */ - return -1; -} - - -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) -{ - apr_size_t len = hlen; - const char *end = hay + hlen; - const char *begin = hay; - - while ( (hay = memchr(hay, ndl[0], len)) ) { - len = end - hay; - - /* done if matches up to capacity of buffer */ - if ( memcmp(hay, ndl, MIN(nlen, len)) == 0 ) { - if (type == APREQ_MATCH_FULL && len < nlen) - hay = NULL; /* insufficient room for match */ - break; - } - --len; - ++hay; - } - - return hay ? hay - begin : -1; -} - - -static const char c2x_table[] = "0123456789ABCDEF"; -static APR_INLINE unsigned char hex2_to_char(const char *what) -{ - register unsigned char digit; - -#if !APR_CHARSET_EBCDIC - digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0')); - digit *= 16; - digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0')); -#else /*APR_CHARSET_EBCDIC*/ - char xstr[5]; - xstr[0]='0'; - xstr[1]='x'; - xstr[2]=what[0]; - xstr[3]=what[1]; - xstr[4]='\0'; - digit = apr_xlate_conv_byte(ap_hdrs_from_ascii, 0xFF & strtol(xstr, NULL, 16)); -#endif /*APR_CHARSET_EBCDIC*/ - return (digit); -} - - -/* Unicode notes: "bmp" refers to the 16-bit - * Unicode Basic Multilingual Plane. Here we're - * restricting our unicode internals to 16-bit - * codepoints, to keep the code as simple as possible. - * This should be sufficient for apreq itself, since - * we really only need to validate RFC3986-encoded utf8. - */ - -/* Converts Windows cp1252 to Unicode. */ - -static APR_INLINE -apr_uint16_t cp1252_to_bmp(unsigned char c) -{ - /* We only need to deal with iso-8859-1 control chars - * in the 0x80 - 0x9F range. - */ - if ((c & 0xE0) != 0x80) - return c; - - switch (c) { - case 0x80: return 0x20AC; - case 0x82: return 0x201A; - case 0x83: return 0x192; - case 0x84: return 0x201E; - case 0x85: return 0x2026; - case 0x86: return 0x2020; - case 0x87: return 0x2021; - case 0x88: return 0x2C6; - case 0x89: return 0x2030; - case 0x8A: return 0x160; - case 0x8B: return 0x2039; - case 0x8C: return 0x152; - case 0x8E: return 0x17D; - case 0x91: return 0x2018; - case 0x92: return 0x2019; - case 0x93: return 0x201C; - case 0x94: return 0x201D; - case 0x95: return 0x2022; - case 0x96: return 0x2013; - case 0x97: return 0x2014; - case 0x98: return 0x2DC; - case 0x99: return 0x2122; - case 0x9A: return 0x161; - case 0x9B: return 0x203A; - case 0x9C: return 0x153; - case 0x9E: return 0x17E; - case 0x9F: return 0x178; - } - return c; -} - -/* converts cp1252 to utf8 */ -APREQ_DECLARE(apr_size_t) apreq_cp1252_to_utf8(char *dest, - const char *src, apr_size_t slen) -{ - const unsigned char *s = (unsigned const char *)src; - const unsigned char *end = s + slen; - unsigned char *d = (unsigned char *)dest; - apr_uint16_t c; - - while (s < end) { - c = cp1252_to_bmp(*s++); - - if (c < 0x80) { - *d++ = c; - } - else if (c < 0x800) { - *d++ = 0xC0 | (c >> 6); - *d++ = 0x80 | (c & 0x3F); - } - else { - *d++ = 0xE0 | (c >> 12); - *d++ = 0x80 | ((c >> 6) & 0x3F); - *d++ = 0x80 | (c & 0x3F); - } - } - *d = 0; - return d - (unsigned char *)dest; -} - - -/** - * Valid utf8 bit patterns: (true utf8 must satisfy a minimality condition) - * - * 0aaaaaaa - * 110bbbba 10aaaaaa minimality mask: 0x1E - * 1110cccc 10cbbbba 10aaaaaa 0x0F || 0x20 - * 11110ddd 10ddcccc 10cbbbba 10aaaaaa 0x07 || 0x30 - * 111110ee 10eeeddd 10ddcccc 10cbbbba 10aaaaaa 0x03 || 0x38 - * 1111110f 10ffffee 10eeeddd 10ddcccc 10cbbbba 10aaaaaa 0x01 || 0x3C - * - * Charset divination heuristics: - * 1) presume ascii; if not, then - * 2) presume utf8; if not, then - * 3) presume latin1; unless there are control chars, in which case - * 4) punt to cp1252. - * - * Note: in downgrading from 2 to 3, we need to be careful - * about earlier control characters presumed to be valid utf8. - */ - -APREQ_DECLARE(apreq_charset_t) apreq_charset_divine(const char *src, - apr_size_t slen) - -{ - apreq_charset_t rv = APREQ_CHARSET_ASCII; - register unsigned char trail = 0, saw_cntrl = 0, mask = 0; - register const unsigned char *s = (const unsigned char *)src; - const unsigned char *end = s + slen; - - for (; s < end; ++s) { - if (trail) { - if ((*s & 0xC0) == 0x80 && (mask == 0 || (mask & *s))) { - mask = 0; - --trail; - - if ((*s & 0xE0) == 0x80) { - saw_cntrl = 1; - } - } - else { - trail = 0; - if (saw_cntrl) - return APREQ_CHARSET_CP1252; - rv = APREQ_CHARSET_LATIN1; - } - } - else if (*s < 0x80) { - /* do nothing */ - } - else if (*s < 0xA0) { - return APREQ_CHARSET_CP1252; - } - else if (*s < 0xC0) { - if (saw_cntrl) - return APREQ_CHARSET_CP1252; - rv = APREQ_CHARSET_LATIN1; - } - else if (rv == APREQ_CHARSET_LATIN1) { - /* do nothing */ - } - - /* utf8 cases */ - - else if (*s < 0xE0) { - if (*s & 0x1E) { - rv = APREQ_CHARSET_UTF8; - trail = 1; - mask = 0; - } - else if (saw_cntrl) - return APREQ_CHARSET_CP1252; - else - rv = APREQ_CHARSET_LATIN1; - } - else if (*s < 0xF0) { - mask = (*s & 0x0F) ? 0 : 0x20; - rv = APREQ_CHARSET_UTF8; - trail = 2; - } - else if (*s < 0xF8) { - mask = (*s & 0x07) ? 0 : 0x30; - rv = APREQ_CHARSET_UTF8; - trail = 3; - } - else if (*s < 0xFC) { - mask = (*s & 0x03) ? 0 : 0x38; - rv = APREQ_CHARSET_UTF8; - trail = 4; - } - else if (*s < 0xFE) { - mask = (*s & 0x01) ? 0 : 0x3C; - rv = APREQ_CHARSET_UTF8; - trail = 5; - } - else { - rv = APREQ_CHARSET_UTF8; - } - } - - return trail ? saw_cntrl ? - APREQ_CHARSET_CP1252 : APREQ_CHARSET_LATIN1 : rv; -} - - -static APR_INLINE apr_uint16_t hex4_to_bmp(const char *what) { - register apr_uint16_t digit = 0; - -#if !APR_CHARSET_EBCDIC - digit = (what[0] >= 'A' ? ((what[0] & 0xDF)-'A') + 10 : (what[0]-'0')); - digit *= 16; - digit += (what[1] >= 'A' ? ((what[1] & 0xDF)-'A') + 10 : (what[1]-'0')); - digit *= 16; - digit += (what[2] >= 'A' ? ((what[2] & 0xDF)-'A') + 10 : (what[2]-'0')); - digit *= 16; - digit += (what[3] >= 'A' ? ((what[3] & 0xDF)-'A') + 10 : (what[3]-'0')); - -#else /*APR_CHARSET_EBCDIC*/ - char xstr[7]; - xstr[0]='0'; - xstr[1]='x'; - xstr[2]=what[0]; - xstr[3]=what[1]; - xstr[4]=what[2]; - xstr[5]=what[3]; - xstr[6]='\0'; - digit = apr_xlate_conv_byte(ap_hdrs_from_ascii, 0xFFFF & strtol(xstr, NULL, 16)); -#endif /*APR_CHARSET_EBCDIC*/ - return (digit); -} - - -static apr_status_t url_decode(char *dest, apr_size_t *dlen, - const char *src, apr_size_t *slen) -{ - register const char *s = src; - unsigned char *start = (unsigned char *)dest; - register unsigned char *d = (unsigned char *)dest; - const char *end = src + *slen; - - for (; s < end; ++d, ++s) { - switch (*s) { - - case '+': - *d = ' '; - break; - - case '%': - if (s + 2 < end && apr_isxdigit(s[1]) && apr_isxdigit(s[2])) - { - *d = hex2_to_char(s + 1); - s += 2; - } - else if (s + 5 < end && (s[1] == 'u' || s[1] == 'U') && - apr_isxdigit(s[2]) && apr_isxdigit(s[3]) && - apr_isxdigit(s[4]) && apr_isxdigit(s[5])) - { - apr_uint16_t c = hex4_to_bmp(s+2); - - if (c < 0x80) { - *d = c; - } - else if (c < 0x800) { - *d++ = 0xC0 | (c >> 6); - *d = 0x80 | (c & 0x3F); - } - else { - *d++ = 0xE0 | (c >> 12); - *d++ = 0x80 | ((c >> 6) & 0x3F); - *d = 0x80 | (c & 0x3F); - } - s += 5; - } - else { - *dlen = d - start; - *slen = s - src; - if (s + 5 < end - || (s + 2 < end && !apr_isxdigit(s[2])) - || (s + 1 < end && !apr_isxdigit(s[1]) - && s[1] != 'u' && s[1] != 'U')) - { - *d = 0; - return APREQ_ERROR_BADSEQ; - } - - memmove(d, s, end - s); - d[end - s] = 0; - return APR_INCOMPLETE; - } - break; - - default: - if (*s > 0) { - *d = *s; - } - else { - *d = 0; - *dlen = d - start; - *slen = s - src; - return APREQ_ERROR_BADCHAR; - } - } - } - - *d = 0; - *dlen = d - start; - *slen = s - src; - return APR_SUCCESS; -} - - -APREQ_DECLARE(apr_status_t) apreq_decode(char *d, apr_size_t *dlen, - const char *s, apr_size_t slen) -{ - apr_size_t len = 0; - const char *end = s + slen; - - if (s == (const char *)d) { /* optimize for src = dest case */ - for ( ; d < end; ++d) { - if (*d == '%' || *d == '+') - break; - else if (*d == 0) { - *dlen = (const char *)d - s; - return APREQ_ERROR_BADCHAR; - } - } - len = (const char *)d - s; - s = (const char *)d; - slen -= len; - } - - return url_decode(d, dlen, s, &slen); -} - -APREQ_DECLARE(apr_status_t) apreq_decodev(char *d, apr_size_t *dlen, - struct iovec *v, int nelts) -{ - apr_status_t status = APR_SUCCESS; - int n = 0; - - *dlen = 0; - - while (n < nelts) { - apr_size_t slen, len; - - slen = v[n].iov_len; - switch (status = url_decode(d, &len, v[n].iov_base, &slen)) { - - case APR_SUCCESS: - d += len; - *dlen += len; - ++n; - continue; - - case APR_INCOMPLETE: - d += len; - *dlen += len; - slen = v[n].iov_len - slen; - - if (++n == nelts) { - return status; - } - memcpy(d + slen, v[n].iov_base, v[n].iov_len); - v[n].iov_len += slen; - v[n].iov_base = d; - continue; - - default: - *dlen += len; - return status; - } - } - - return status; -} - - -APREQ_DECLARE(apr_size_t) apreq_encode(char *dest, const char *src, - const apr_size_t slen) -{ - char *d = dest; - const unsigned char *s = (const unsigned char *)src; - unsigned char c; - - for ( ; s < (const unsigned char *)src + slen; ++s) { - c = *s; - if ( c < 0x80 && (apr_isalnum(c) - || c == '-' || c == '.' - || c == '_' || c == '~') ) - *d++ = c; - - else if ( c == ' ' ) - *d++ = '+'; - - else { -#if APR_CHARSET_EBCDIC - c = apr_xlate_conv_byte(ap_hdrs_to_ascii, (unsigned char)c); -#endif - *d++ = '%'; - *d++ = c2x_table[c >> 4]; - *d++ = c2x_table[c & 0xf]; - } - } - *d = 0; - - return d - dest; -} - -static int is_quoted(const char *p, const apr_size_t len) { - if (len > 1 && p[0] == '"' && p[len-1] == '"') { - apr_size_t i; - int backslash = 0; - - for (i = 1; i < len - 1; i++) { - if (p[i] == '\\') - backslash = !backslash; - else if (p[i] == 0 || (p[i] == '"' && !backslash)) - return 0; - else - backslash = 0; - } - - return !backslash; - } - - return 0; -} - -APREQ_DECLARE(apr_size_t) apreq_quote_once(char *dest, const char *src, - const apr_size_t slen) -{ - if (is_quoted(src, slen)) { - /* looks like src is already quoted */ - memcpy(dest, src, slen); - dest[slen] = 0; - return slen; - } - else - return apreq_quote(dest, src, slen); -} - -APREQ_DECLARE(apr_size_t) apreq_quote(char *dest, const char *src, - const apr_size_t slen) -{ - char *d = dest; - const char *s = src; - const char *const last = src + slen - 1; - - if (slen == 0) { - *d = 0; - return 0; - } - - *d++ = '"'; - - while (s <= last) { - switch (*s) { - case 0: - *d++ = '\\'; - *d++ = '0'; - s++; - break; - - case '\\': - case '"': - *d++ = '\\'; - - default: - *d++ = *s++; - } - } - - *d++ = '"'; - *d = 0; - - return d - dest; -} - -APREQ_DECLARE(char *) apreq_join(apr_pool_t *p, - const char *sep, - const apr_array_header_t *arr, - apreq_join_t mode) -{ - apr_size_t len, slen; - char *rv; - const apreq_value_t **a = (const apreq_value_t **)arr->elts; - char *d; - const int n = arr->nelts; - int j; - - slen = sep ? strlen(sep) : 0; - - if (n == 0) - return apr_pstrdup(p, ""); - - for (j=0, len=0; j < n; ++j) - len += a[j]->dlen + slen + 1; - - /* Allocated the required space */ - - switch (mode) { - case APREQ_JOIN_ENCODE: - len += 2 * len; - break; - case APREQ_JOIN_QUOTE: - len = 2 * (len + n); - break; - case APREQ_JOIN_AS_IS: - case APREQ_JOIN_DECODE: - /* nothing special required, just here to keep noisy compilers happy */ - break; - } - - rv = apr_palloc(p, len); - - /* Pass two --- copy the argument strings into the result space */ - - d = rv; - - switch (mode) { - - case APREQ_JOIN_ENCODE: - d += apreq_encode(d, a[0]->data, a[0]->dlen); - - for (j = 1; j < n; ++j) { - memcpy(d, sep, slen); - d += slen; - d += apreq_encode(d, a[j]->data, a[j]->dlen); - } - break; - - case APREQ_JOIN_DECODE: - if (apreq_decode(d, &len, a[0]->data, a[0]->dlen)) - return NULL; - else - d += len; - - for (j = 1; j < n; ++j) { - memcpy(d, sep, slen); - d += slen; - - if (apreq_decode(d, &len, a[j]->data, a[j]->dlen)) - return NULL; - else - d += len; - } - break; - - - case APREQ_JOIN_QUOTE: - d += apreq_quote_once(d, a[0]->data, a[0]->dlen); - - for (j = 1; j < n; ++j) { - memcpy(d, sep, slen); - d += slen; - d += apreq_quote_once(d, a[j]->data, a[j]->dlen); - } - break; - - - case APREQ_JOIN_AS_IS: - memcpy(d,a[0]->data, a[0]->dlen); - d += a[0]->dlen; - - for (j = 1; j < n ; ++j) { - memcpy(d, sep, slen); - d += slen; - memcpy(d, a[j]->data, a[j]->dlen); - d += a[j]->dlen; - } - break; - } - - *d = 0; - return rv; -} - -/* - * This is intentionally not apr_file_writev() - * note, this is iterative and not recursive - */ -APR_INLINE -static apr_status_t apreq_fwritev(apr_file_t *f, struct iovec *v, - int *nelts, apr_size_t *bytes_written) -{ - apr_size_t len; - int n; - apr_status_t s; - - *bytes_written = 0; - - while (1) { - /* try to write */ - s = apr_file_writev(f, v, *nelts, &len); - - *bytes_written += len; - - if (s != APR_SUCCESS) - return s; - - /* see how far we've come */ - n = 0; - -#ifdef SOLARIS2 -# ifdef __GNUC__ - /* - * iovec.iov_len is a long here - * which causes a comparison between - * signed(long) and unsigned(apr_size_t) - * - */ - while (n < *nelts && len >= (apr_size_t)v[n].iov_len) -# else - /* - * Sun C however defines this as size_t which is unsigned - * - */ - while (n < *nelts && len >= v[n].iov_len) -# endif /* !__GNUC__ */ -#else - /* - * Hopefully everything else does this - * (this was the default for years) - */ - while (n < *nelts && len >= v[n].iov_len) -#endif - len -= v[n++].iov_len; - - if (n == *nelts) { - /* nothing left to write, report success */ - *nelts = 0; - return APR_SUCCESS; - } - - /* incomplete write: must shift v */ - v[n].iov_len -= len; - v[n].iov_base = (char *)(v[n].iov_base) + len; - - if (n > 0) { - /* we're satisfied for now if we can remove one iovec from - the "v" array */ - (*nelts) -= n; - memmove(v, v + n, sizeof(*v) * *nelts); - - return APR_SUCCESS; - } - - /* we're still in the first iovec - check for endless loop, - and then try again */ - if (len == 0) - return APREQ_ERROR_GENERAL; - } -} - - - - -struct cleanup_data { - const char *fname; - apr_pool_t *pool; -}; - -static apr_status_t apreq_file_cleanup(void *d) -{ - struct cleanup_data *data = d; - return apr_file_remove(data->fname, data->pool); -} - -/* - * The reason we need the above cleanup is because on Windows, APR_DELONCLOSE - * forces applications to open the file with FILE_SHARED_DELETE - * set, which is, unfortunately, a property that is preserved - * across NTFS "hard" links. This breaks apps that link() the temp - * file to a permanent location, and subsequently expect to open it - * before the original tempfile is closed+deleted. In fact, even - * Apache::Upload does this, so it is a common enough event that the - * apreq_file_cleanup workaround is necessary. - */ - -APREQ_DECLARE(apr_status_t) apreq_file_mktemp(apr_file_t **fp, - apr_pool_t *pool, - const char *path) -{ - apr_status_t rc; - char *tmpl; - struct cleanup_data *data; - apr_int32_t flag; - - if (path == NULL) { - rc = apr_temp_dir_get(&path, pool); - if (rc != APR_SUCCESS) - return rc; - } - rc = apr_filepath_merge(&tmpl, path, "apreqXXXXXX", - APR_FILEPATH_NOTRELATIVE, pool); - - if (rc != APR_SUCCESS) - return rc; - - data = apr_palloc(pool, sizeof *data); - /* cleanups are LIFO, so this one will run just after - the cleanup set by mktemp */ - apr_pool_cleanup_register(pool, data, - apreq_file_cleanup, apreq_file_cleanup); - - /* NO APR_DELONCLOSE! see comment above */ - flag = APR_CREATE | APR_READ | APR_WRITE | APR_EXCL | APR_BINARY; - - rc = apr_file_mktemp(fp, tmpl, flag, pool); - - if (rc == APR_SUCCESS) { - apr_file_name_get(&data->fname, *fp); - data->pool = pool; - } - else { - apr_pool_cleanup_kill(pool, data, apreq_file_cleanup); - } - - return rc; -} - - -/* - * is_2616_token() is the verbatim definition from section 2.2 - * in the rfc itself. We try to optimize it around the - * expectation that the argument is not a token, which - * should be the typical usage. - */ - -static APR_INLINE -unsigned is_2616_token(const char c) { - switch (c) { - case ' ': case ';': case ',': case '"': case '\t': - /* The chars we are expecting are listed above; - the chars below are just for completeness. */ - case '?': case '=': case '@': case ':': case '\\': case '/': - case '(': case ')': - case '<': case '>': - case '{': case '}': - case '[': case ']': - return 0; - default: - if (apr_iscntrl(c)) - return 0; - } - return 1; -} - -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) -{ - const char *key, *v; - - /* Must ensure first char isn't '=', so we can safely backstep. */ - while (*hdr == '=') - ++hdr; - - while ((key = strchr(hdr, '=')) != NULL) { - - v = key + 1; - --key; - - while (apr_isspace(*key) && key > hdr + nlen) - --key; - - key -= nlen - 1; - - while (apr_isspace(*v)) - ++v; - - if (*v == '"') { - ++v; - *val = v; - - look_for_end_quote: - switch (*v) { - case '"': - break; - case 0: - return APREQ_ERROR_BADSEQ; - case '\\': - if (v[1] != 0) - ++v; - default: - ++v; - goto look_for_end_quote; - } - } - else { - *val = v; - - look_for_terminator: - switch (*v) { - case 0: - case ' ': - case ';': - case ',': - case '\t': - case '\r': - case '\n': - break; - default: - ++v; - goto look_for_terminator; - } - } - - if (key >= hdr && strncasecmp(key, name, nlen) == 0) { - *vlen = v - *val; - if (key == hdr || ! is_2616_token(key[-1])) - return APR_SUCCESS; - } - hdr = v; - } - - return APREQ_ERROR_NOATTR; -} - - - -#define BUCKET_IS_SPOOL(e) ((e)->type == &spool_bucket_type) -#define FILE_BUCKET_LIMIT ((apr_size_t)-1 - 1) - -static -void spool_bucket_destroy(void *data) -{ - apr_bucket_type_file.destroy(data); -} - -static -apr_status_t spool_bucket_read(apr_bucket *e, const char **str, - apr_size_t *len, apr_read_type_e block) -{ - return apr_bucket_type_file.read(e, str, len, block); -} - -static -apr_status_t spool_bucket_setaside(apr_bucket *data, apr_pool_t *reqpool) -{ - return apr_bucket_type_file.setaside(data, reqpool); -} - -static -apr_status_t spool_bucket_split(apr_bucket *a, apr_size_t point) -{ - apr_status_t rv = apr_bucket_shared_split(a, point); - a->type = &apr_bucket_type_file; - return rv; -} - -static -apr_status_t spool_bucket_copy(apr_bucket *e, apr_bucket **c) -{ - apr_status_t rv = apr_bucket_shared_copy(e, c); - (*c)->type = &apr_bucket_type_file; - return rv; -} - -static const apr_bucket_type_t spool_bucket_type = { - "APREQ_SPOOL", 5, APR_BUCKET_DATA, - spool_bucket_destroy, - spool_bucket_read, - spool_bucket_setaside, - spool_bucket_split, - spool_bucket_copy, -}; - -APREQ_DECLARE(apr_file_t *)apreq_brigade_spoolfile(apr_bucket_brigade *bb) -{ - apr_bucket *last; - - last = APR_BRIGADE_LAST(bb); - if (BUCKET_IS_SPOOL(last)) - return ((apr_bucket_file *)last->data)->fd; - - return NULL; -} - -APREQ_DECLARE(apr_status_t) apreq_brigade_concat(apr_pool_t *pool, - const char *temp_dir, - apr_size_t heap_limit, - apr_bucket_brigade *out, - apr_bucket_brigade *in) -{ - apr_status_t s; - apr_bucket_file *f; - apr_off_t wlen; - apr_file_t *file; - apr_off_t in_len, out_len; - apr_bucket *last_in, *last_out; - - last_out = APR_BRIGADE_LAST(out); - - if (APR_BUCKET_IS_EOS(last_out)) - return APR_EOF; - - s = apr_brigade_length(out, 0, &out_len); - if (s != APR_SUCCESS) - return s; - - /* This cast, when out_len = -1, is intentional */ - if ((apr_uint64_t)out_len < heap_limit) { - - s = apr_brigade_length(in, 0, &in_len); - if (s != APR_SUCCESS) - return s; - - /* This cast, when in_len = -1, is intentional */ - if ((apr_uint64_t)in_len < heap_limit - (apr_uint64_t)out_len) { - APR_BRIGADE_CONCAT(out, in); - return APR_SUCCESS; - } - } - - if (!BUCKET_IS_SPOOL(last_out)) { - - s = apreq_file_mktemp(&file, pool, temp_dir); - if (s != APR_SUCCESS) - return s; - - s = apreq_brigade_fwrite(file, &wlen, out); - - if (s != APR_SUCCESS) - return s; - - last_out = apr_bucket_file_create(file, wlen, 0, - out->p, out->bucket_alloc); - last_out->type = &spool_bucket_type; - APR_BRIGADE_INSERT_TAIL(out, last_out); - f = last_out->data; - } - else { - f = last_out->data; - /* Need to seek here, just in case our spool bucket - * was read from between apreq_brigade_concat calls. - */ - wlen = last_out->start + last_out->length; - s = apr_file_seek(f->fd, APR_SET, &wlen); - if (s != APR_SUCCESS) - return s; - } - - if (in == out) - return APR_SUCCESS; - - last_in = APR_BRIGADE_LAST(in); - - if (APR_BUCKET_IS_EOS(last_in)) - APR_BUCKET_REMOVE(last_in); - - s = apreq_brigade_fwrite(f->fd, &wlen, in); - - if (s == APR_SUCCESS) { - - /* We have to deal with the possibility that the new - * data may be too large to be represented by a single - * temp_file bucket. - */ - - while ((apr_uint64_t)wlen > FILE_BUCKET_LIMIT - last_out->length) { - apr_bucket *e; - - apr_bucket_copy(last_out, &e); - e->length = 0; - e->start = last_out->start + FILE_BUCKET_LIMIT; - wlen -= FILE_BUCKET_LIMIT - last_out->length; - last_out->length = FILE_BUCKET_LIMIT; - - /* Copying makes the bucket types exactly the - * opposite of what we need here. - */ - last_out->type = &apr_bucket_type_file; - e->type = &spool_bucket_type; - - APR_BRIGADE_INSERT_TAIL(out, e); - last_out = e; - } - - last_out->length += wlen; - - if (APR_BUCKET_IS_EOS(last_in)) - APR_BRIGADE_INSERT_TAIL(out, last_in); - - } - else if (APR_BUCKET_IS_EOS(last_in)) - APR_BRIGADE_INSERT_TAIL(in, last_in); - - apr_brigade_cleanup(in); - return s; -} - -APREQ_DECLARE(apr_status_t) apreq_brigade_fwrite(apr_file_t *f, - apr_off_t *wlen, - apr_bucket_brigade *bb) -{ - struct iovec v[APREQ_DEFAULT_NELTS]; - apr_status_t s; - apr_bucket *e, *first; - int n = 0; - apr_bucket_brigade *tmp = bb; - *wlen = 0; - - if (BUCKET_IS_SPOOL(APR_BRIGADE_LAST(bb))) { - tmp = apr_brigade_create(bb->p, bb->bucket_alloc); - - s = apreq_brigade_copy(tmp, bb); - if (s != APR_SUCCESS) - return s; - } - - for (e = APR_BRIGADE_FIRST(tmp); e != APR_BRIGADE_SENTINEL(tmp); - e = APR_BUCKET_NEXT(e)) - { - apr_size_t len; - if (n == APREQ_DEFAULT_NELTS) { - s = apreq_fwritev(f, v, &n, &len); - if (s != APR_SUCCESS) - return s; - - if (tmp != bb) { - while ((first = APR_BRIGADE_FIRST(tmp)) != e) - apr_bucket_delete(first); - } - - *wlen += len; - } - s = apr_bucket_read(e, (const char **)&(v[n].iov_base), - &len, APR_BLOCK_READ); - if (s != APR_SUCCESS) - return s; - - v[n++].iov_len = len; - } - - while (n > 0) { - apr_size_t len; - s = apreq_fwritev(f, v, &n, &len); - if (s != APR_SUCCESS) - return s; - *wlen += len; - - if (tmp != bb) { - while ((first = APR_BRIGADE_FIRST(tmp)) != e) - apr_bucket_delete(first); - } - } - return APR_SUCCESS; -} diff --git a/srclib/libapreq/library/version.c b/srclib/libapreq/library/version.c deleted file mode 100644 index 5cfd767c12..0000000000 --- a/srclib/libapreq/library/version.c +++ /dev/null @@ -1,36 +0,0 @@ -/* -** 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. -*/ - -#include "apreq_version.h" -#include "apr_general.h" /* for APR_STRINGIFY */ - -APREQ_DECLARE(void) apreq_version(apr_version_t *pvsn) -{ - pvsn->major = APREQ_MAJOR_VERSION; - pvsn->minor = APREQ_MINOR_VERSION; - pvsn->patch = APREQ_PATCH_VERSION; -#ifdef APREQ_IS_DEV_VERSION - pvsn->is_dev = 1; -#else - pvsn->is_dev = 0; -#endif -} - -APREQ_DECLARE(const char *) apreq_version_string(void) -{ - return APREQ_VERSION_STRING; -} |