mirror of
https://github.com/apache/httpd.git
synced 2025-04-18 22:24:07 +03:00
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
273 lines
7.5 KiB
C
273 lines
7.5 KiB
C
/*
|
|
** 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;
|
|
}
|