2 ** Licensed to the Apache Software Foundation (ASF) under one or more
3 ** contributor license agreements. See the NOTICE file distributed with
4 ** this work for additional information regarding copyright ownership.
5 ** The ASF licenses this file to You under the Apache License, Version 2.0
6 ** (the "License"); you may not use this file except in compliance with
7 ** the License. You may obtain a copy of the License at
9 ** http://www.apache.org/licenses/LICENSE-2.0
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
18 #include "apreq_param.h"
19 #include "apreq_error.h"
20 #include "apreq_util.h"
21 #include "apr_strings.h"
24 #define MAX_LEN (1024 * 1024)
25 #define MAX_BRIGADE_LEN (1024 * 256)
26 #define MAX_READ_AHEAD (1024 * 64)
29 APREQ_DECLARE(apreq_param_t *) apreq_param_make(apr_pool_t *p,
31 const apr_size_t nlen,
33 const apr_size_t vlen)
38 param = apr_palloc(p, nlen + vlen + 1 + sizeof *param);
47 *(const apreq_value_t **)&v = ¶m->v;
49 if (vlen && val != NULL)
50 memcpy(v->data, val, vlen);
54 v->name = v->data + vlen + 1;
55 if (nlen && name != NULL)
56 memcpy(v->name, name, nlen);
63 APREQ_DECLARE(apr_status_t) apreq_param_decode(apreq_param_t **param,
72 apreq_charset_t charset;
79 p = apr_palloc(pool, nlen + vlen + 1 + sizeof *p);
83 *(const apreq_value_t **)&v = &p->v;
86 status = apreq_decode(v->data, &v->dlen, word + nlen + 1, vlen);
87 if (status != APR_SUCCESS) {
91 charset = apreq_charset_divine(v->data, v->dlen);
96 charset = APREQ_CHARSET_ASCII;
98 v->name = v->data + vlen + 1;
100 status = apreq_decode(v->name, &v->nlen, word, nlen);
101 if (status != APR_SUCCESS) {
106 switch (apreq_charset_divine(v->name, v->nlen)) {
107 case APREQ_CHARSET_UTF8:
108 if (charset == APREQ_CHARSET_ASCII)
109 charset = APREQ_CHARSET_UTF8;
110 case APREQ_CHARSET_ASCII:
113 case APREQ_CHARSET_LATIN1:
114 if (charset != APREQ_CHARSET_CP1252)
115 charset = APREQ_CHARSET_LATIN1;
117 case APREQ_CHARSET_CP1252:
118 charset = APREQ_CHARSET_CP1252;
121 apreq_param_charset_set(p, charset);
128 APREQ_DECLARE(char *) apreq_param_encode(apr_pool_t *pool,
129 const apreq_param_t *param)
133 data = apr_palloc(pool, 3 * (param->v.nlen + param->v.dlen) + 2);
134 dlen = apreq_encode(data, param->v.name, param->v.nlen);
136 dlen += apreq_encode(data + dlen, param->v.data, param->v.dlen);
141 APREQ_DECLARE(apr_status_t) apreq_parse_query_string(apr_pool_t *pool,
145 const char *start = qs;
162 apreq_param_t *param;
167 vlen = qs - start - nlen - 1;
169 s = apreq_param_decode(¶m, pool, start, nlen, vlen);
170 if (s != APR_SUCCESS)
173 apreq_param_tainted_on(param);
174 apreq_value_table_add(¶m->v, t);
185 return APR_INCOMPLETE;
191 static int param_push(void *data, const char *key, const char *val)
193 apr_array_header_t *arr = data;
194 *(apreq_param_t **)apr_array_push(arr) =
195 apreq_value_to_param(val);
196 return 1; /* keep going */
200 APREQ_DECLARE(apr_array_header_t *) apreq_params_as_array(apr_pool_t *p,
201 const apr_table_t *t,
204 apr_array_header_t *arr;
206 arr = apr_array_make(p, apr_table_elts(t)->nelts,
207 sizeof(apreq_param_t *));
209 apr_table_do(param_push, arr, t, key, NULL);
213 APREQ_DECLARE(const char *) apreq_params_as_string(apr_pool_t *p,
214 const apr_table_t *t,
218 apr_array_header_t *arr = apreq_params_as_array(p, t, key);
219 apreq_param_t **elt = (apreq_param_t **)arr->elts;
220 apreq_param_t **const end = elt + arr->nelts;
222 return apr_pstrdup(p, "");
225 *(const apreq_value_t **)elt = &(**elt).v;
228 return apreq_join(p, ", ", arr, mode);
233 static int upload_push(void *data, const char *key, const char *val)
235 apr_table_t *t = data;
236 apreq_param_t *p = apreq_value_to_param(val);
238 if (p->upload != NULL)
239 apreq_value_table_add(&p->v, t);
240 return 1; /* keep going */
244 APREQ_DECLARE(const apr_table_t *) apreq_uploads(const apr_table_t *body,
247 apr_table_t *t = apr_table_make(pool, APREQ_DEFAULT_NELTS);
248 apr_table_do(upload_push, t, body, NULL);
252 static int upload_set(void *data, const char *key, const char *val)
254 const apreq_param_t **q = data;
255 apreq_param_t *p = apreq_value_to_param(val);
257 if (p->upload != NULL) {
259 return 0; /* upload found, stop */
262 return 1; /* keep searching */
266 APREQ_DECLARE(const apreq_param_t *) apreq_upload(const apr_table_t *body,
269 apreq_param_t *param = NULL;
270 apr_table_do(upload_set, ¶m, body, name, NULL);