diff options
author | Jim Jagielski <jim@apache.org> | 2011-02-18 19:40:31 +0100 |
---|---|---|
committer | Jim Jagielski <jim@apache.org> | 2011-02-18 19:40:31 +0100 |
commit | ec88a92d838dd25a456fb844a2a8395bc32381fd (patch) | |
tree | 69572669a5fc537b3ec1460a9718048279b9b1eb /modules | |
parent | No longer depend on how fork() works when laying out segments... (diff) | |
download | apache2-ec88a92d838dd25a456fb844a2a8395bc32381fd.tar.xz apache2-ec88a92d838dd25a456fb844a2a8395bc32381fd.zip |
Expose "new" ap_parse_form_data() function instead of requiring
mod_request for any module that may want to parse form data...
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1072099 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r-- | modules/aaa/mod_auth_form.c | 10 | ||||
-rw-r--r-- | modules/filters/mod_request.c | 216 |
2 files changed, 3 insertions, 223 deletions
diff --git a/modules/aaa/mod_auth_form.c b/modules/aaa/mod_auth_form.c index 05ac6c26cb..41e1f2fe36 100644 --- a/modules/aaa/mod_auth_form.c +++ b/modules/aaa/mod_auth_form.c @@ -46,9 +46,6 @@ static void (*ap_session_get_fn) (request_rec * r, session_rec * z, const char *key, const char **value) = NULL; static void (*ap_session_set_fn) (request_rec * r, session_rec * z, const char *key, const char *value) = NULL; -static int (*ap_parse_request_form_fn) (request_rec * r, ap_filter_t *f, - apr_array_header_t ** ptr, - apr_size_t num, apr_size_t size) = NULL; static void (*ap_request_insert_filter_fn) (request_rec * r) = NULL; static void (*ap_request_remove_filter_fn) (request_rec * r) = NULL; @@ -187,11 +184,10 @@ static const char *add_authn_provider(cmd_parms * cmd, void *config, } } - if (!ap_parse_request_form_fn || !ap_request_insert_filter_fn || !ap_request_remove_filter_fn) { - ap_parse_request_form_fn = APR_RETRIEVE_OPTIONAL_FN(ap_parse_request_form); + if (!ap_request_insert_filter_fn || !ap_request_remove_filter_fn) { ap_request_insert_filter_fn = APR_RETRIEVE_OPTIONAL_FN(ap_request_insert_filter); ap_request_remove_filter_fn = APR_RETRIEVE_OPTIONAL_FN(ap_request_remove_filter); - if (!ap_parse_request_form_fn || !ap_request_insert_filter_fn || !ap_request_remove_filter_fn) { + if (!ap_request_insert_filter_fn || !ap_request_remove_filter_fn) { return "You must load mod_request to enable the mod_auth_form " "functions"; } @@ -607,7 +603,7 @@ static int get_form_auth(request_rec * r, return OK; } - res = ap_parse_request_form_fn(r, NULL, &pairs, -1, conf->form_size); + res = ap_parse_form_data(r, NULL, &pairs, -1, conf->form_size); if (res != OK) { return res; } diff --git a/modules/filters/mod_request.c b/modules/filters/mod_request.c index 3693db8d25..cebe539a19 100644 --- a/modules/filters/mod_request.c +++ b/modules/filters/mod_request.c @@ -267,221 +267,6 @@ static apr_status_t kept_body_filter(ap_filter_t *f, apr_bucket_brigade *b, } -/* form parsing stuff */ -typedef enum { - FORM_NORMAL, - FORM_AMP, - FORM_NAME, - FORM_VALUE, - FORM_PERCENTA, - FORM_PERCENTB, - FORM_ABORT -} ap_form_type_t; - -/** - * Read the body and parse any form found, which must be of the - * type application/x-www-form-urlencoded. - * - * Name/value pairs are returned in an array, with the names as - * strings with a maximum length of HUGE_STRING_LEN, and the - * values as bucket brigades. This allows values to be arbitrarily - * large. - * - * All url-encoding is removed from both the names and the values - * on the fly. The names are interpreted as strings, while the - * values are interpreted as blocks of binary data, that may - * contain the 0 character. - * - * In order to ensure that resource limits are not exceeded, a - * maximum size must be provided. If the sum of the lengths of - * the names and the values exceed this size, this function - * will return HTTP_REQUEST_ENTITY_TOO_LARGE. - * - * An optional number of parameters can be provided, if the number - * of parameters provided exceeds this amount, this function will - * return HTTP_REQUEST_ENTITY_TOO_LARGE. If this value is negative, - * no limit is imposed, and the number of parameters is in turn - * constrained by the size parameter above. - * - * This function honours any kept_body configuration, and the - * original raw request body will be saved to the kept_body brigade - * if so configured, just as ap_discard_request_body does. - * - * NOTE: File upload is not yet supported, but can be without change - * to the function call. - */ -static int ap_parse_request_form(request_rec * r, ap_filter_t * f, - apr_array_header_t ** ptr, - apr_size_t num, apr_size_t usize) -{ - apr_bucket_brigade *bb = NULL; - int seen_eos = 0; - char buffer[HUGE_STRING_LEN + 1]; - const char *ct; - apr_size_t offset = 0; - apr_ssize_t size; - ap_form_type_t state = FORM_NAME, percent = FORM_NORMAL; - ap_form_pair_t *pair = NULL; - apr_array_header_t *pairs = apr_array_make(r->pool, 4, sizeof(ap_form_pair_t)); - - char hi = 0; - char low = 0; - - *ptr = pairs; - - /* sanity check - we only support forms for now */ - ct = apr_table_get(r->headers_in, "Content-Type"); - if (!ct || strcmp("application/x-www-form-urlencoded", ct)) { - return ap_discard_request_body(r); - } - - if (usize > APR_SIZE_MAX >> 1) - size = APR_SIZE_MAX >> 1; - else - size = usize; - - if (!f) { - f = r->input_filters; - } - - bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); - do { - apr_bucket *bucket = NULL, *last = NULL; - - int rv = ap_get_brigade(f, bb, AP_MODE_READBYTES, - APR_BLOCK_READ, HUGE_STRING_LEN); - if (rv != APR_SUCCESS) { - apr_brigade_destroy(bb); - return (rv == AP_FILTER_ERROR) ? rv : HTTP_BAD_REQUEST; - } - - for (bucket = APR_BRIGADE_FIRST(bb); - bucket != APR_BRIGADE_SENTINEL(bb); - last = bucket, bucket = APR_BUCKET_NEXT(bucket)) { - const char *data; - apr_size_t len, slide; - - if (last) { - apr_bucket_delete(last); - } - if (APR_BUCKET_IS_EOS(bucket)) { - seen_eos = 1; - break; - } - if (bucket->length == 0) { - continue; - } - - rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); - if (rv != APR_SUCCESS) { - apr_brigade_destroy(bb); - return HTTP_BAD_REQUEST; - } - - slide = len; - while (state != FORM_ABORT && slide-- > 0 && size >= 0 && num != 0) { - char c = *data++; - if ('+' == c) { - c = ' '; - } - else if ('&' == c) { - state = FORM_AMP; - } - if ('%' == c) { - percent = FORM_PERCENTA; - continue; - } - if (FORM_PERCENTA == percent) { - if (c >= 'a') { - hi = c - 'a' + 10; - } - else if (c >= 'A') { - hi = c - 'A' + 10; - } - else if (c >= '0') { - hi = c - '0'; - } - hi = hi << 4; - percent = FORM_PERCENTB; - continue; - } - if (FORM_PERCENTB == percent) { - if (c >= 'a') { - low = c - 'a' + 10; - } - else if (c >= 'A') { - low = c - 'A' + 10; - } - else if (c >= '0') { - low = c - '0'; - } - c = low | hi; - percent = FORM_NORMAL; - } - switch (state) { - case FORM_AMP: - if (pair) { - const char *tmp = apr_pmemdup(r->pool, buffer, offset); - apr_bucket *b = apr_bucket_pool_create(tmp, offset, r->pool, r->connection->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(pair->value, b); - } - state = FORM_NAME; - pair = NULL; - offset = 0; - num--; - break; - case FORM_NAME: - if (offset < HUGE_STRING_LEN) { - if ('=' == c) { - buffer[offset] = 0; - offset = 0; - pair = (ap_form_pair_t *) apr_array_push(pairs); - pair->name = apr_pstrdup(r->pool, buffer); - pair->value = apr_brigade_create(r->pool, r->connection->bucket_alloc); - state = FORM_VALUE; - } - else { - buffer[offset++] = c; - size--; - } - } - else { - state = FORM_ABORT; - } - break; - case FORM_VALUE: - if (offset >= HUGE_STRING_LEN) { - const char *tmp = apr_pmemdup(r->pool, buffer, offset); - apr_bucket *b = apr_bucket_pool_create(tmp, offset, r->pool, r->connection->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(pair->value, b); - offset = 0; - } - buffer[offset++] = c; - size--; - break; - default: - break; - } - } - - } - - apr_brigade_cleanup(bb); - } while (!seen_eos); - - if (FORM_ABORT == state || size < 0 || num == 0) { - return HTTP_REQUEST_ENTITY_TOO_LARGE; - } - else if (FORM_VALUE == state && pair && offset > 0) { - const char *tmp = apr_pmemdup(r->pool, buffer, offset); - apr_bucket *b = apr_bucket_pool_create(tmp, offset, r->pool, r->connection->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(pair->value, b); - } - - return OK; - -} - /** * Check whether this filter is not already present. */ @@ -596,7 +381,6 @@ static void register_hooks(apr_pool_t *p) ap_register_input_filter(KEPT_BODY_FILTER, kept_body_filter, kept_body_filter_init, AP_FTYPE_RESOURCE); ap_hook_insert_filter(ap_request_insert_filter, NULL, NULL, APR_HOOK_LAST); - APR_REGISTER_OPTIONAL_FN(ap_parse_request_form); APR_REGISTER_OPTIONAL_FN(ap_request_insert_filter); APR_REGISTER_OPTIONAL_FN(ap_request_remove_filter); } |