/* Parse form data from a string. The input string is NOT preserved. */
static apr_hash_t *parse_form_from_string(request_rec *r, char *args)
{
apr_hash_t *form;
apr_array_header_t *values;
char *pair;
char *eq;
const char *delim = "&";
char *last;
char **ptr;
if (args == NULL) {
return NULL;
}
/* Split the input on '&' */
for (pair = apr_strtok(args, delim, &last); pair != NULL;
pair = apr_strtok(NULL, delim, &last)) {
for (eq = pair; *eq; ++eq) {
if (*eq == '+') {
*eq = ' ';
}
}
/* split into Key / Value and unescape it */
eq = strchr(pair, '=');
if (eq) {
*eq++ = '/0';
ap_unescape_url(pair);
ap_unescape_url(eq);
}
else {
eq = "";
ap_unescape_url(pair);
}
/* Store key/value pair in our form hash. Given that there
* may be many values for the same key, we store values
* in an array (which we'll have to create the first
* time we encounter the key in question).
*/
values = apr_hash_get(form, pair, APR_HASH_KEY_STRING);
if (values == NULL) {
values = apr_array_make(r->pool, 1, sizeof(const char*));
apr_hash_set(form, pair, APR_HASH_KEY_STRING, values);
}
ptr = apr_array_push(values);
*ptr = apr_pstrdup(r->pool, eq);
}
return form;
}
This scheme is based on parsing the entire input data from a single input buffer. It works well where the total size of
a form submission is reasonably small, as is generally the case with normal web forms.
static apr_hash_t *parse_form_from_string(request_rec *r, char *args)
{
apr_hash_t *form;
apr_array_header_t *values;
char *pair;
char *eq;
const char *delim = "&";
char *last;
char **ptr;
if (args == NULL) {
return NULL;
}
/* Split the input on '&' */
for (pair = apr_strtok(args, delim, &last); pair != NULL;
pair = apr_strtok(NULL, delim, &last)) {
for (eq = pair; *eq; ++eq) {
if (*eq == '+') {
*eq = ' ';
}
}
/* split into Key / Value and unescape it */
eq = strchr(pair, '=');
if (eq) {
*eq++ = '/0';
ap_unescape_url(pair);
ap_unescape_url(eq);
}
else {
eq = "";
ap_unescape_url(pair);
}
/* Store key/value pair in our form hash. Given that there
* may be many values for the same key, we store values
* in an array (which we'll have to create the first
* time we encounter the key in question).
*/
values = apr_hash_get(form, pair, APR_HASH_KEY_STRING);
if (values == NULL) {
values = apr_array_make(r->pool, 1, sizeof(const char*));
apr_hash_set(form, pair, APR_HASH_KEY_STRING, values);
}
ptr = apr_array_push(values);
*ptr = apr_pstrdup(r->pool, eq);
}
return form;
}
This scheme is based on parsing the entire input data from a single input buffer. It works well where the total size of
a form submission is reasonably small, as is generally the case with normal web forms.