mirror of
https://github.com/apache/httpd.git
synced 2025-07-20 16:46:32 +00: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
305 lines
8.4 KiB
C
305 lines
8.4 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 "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;
|
|
}
|
|
|