/*
** 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
**
**
** 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 "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include "util_filter.h"
#include "apr_tables.h"
#include "apr_buckets.h"
#include "http_request.h"
#include "apr_strings.h"
#include "apreq_module_apache2.h"
#include "apreq_private_apache2.h"
#include "apreq_error.h"
#include "apreq_util.h"
{
/* d == OR_ALL */
return dc;
}
{
? a->brigade_limit : b->brigade_limit;
? b->read_limit : a->read_limit;
return c;
}
const char *arg)
{
return err;
return NULL;
}
const char *arg)
{
return err;
return NULL;
}
const char *arg)
{
return err;
return NULL;
}
{
"Default location of temporary directory"),
"Maximum amount of data that will be fed into a parser."),
"Maximum in-memory bytes a brigade may use."),
{ NULL }
};
{
request_rec *r = f->r;
const char *cl_header;
if (r->method_number == M_GET) {
/* Don't parse GET (this protects against subrequest body parsing). */
return;
}
char *dummy;
"Invalid Content-Length header (%s)", cl_header);
return;
}
"Content-Length header (%s) exceeds configured "
return;
}
}
NULL);
}
else {
return;
}
}
else {
return;
}
}
else {
}
}
/*
* Situations to contend with:
*
* 1) Often the filter will be added by the content handler itself,
* so the apreq_filter_init hook will not be run.
* 2) If an auth handler uses apreq, the apreq_filter will ensure
* it's part of the protocol filters. apreq_filter_init does NOT need
* to notify the protocol filter that it must not continue parsing,
* the apreq filter can perform this check itself. apreq_filter_init
* just needs to ensure cfg->f does not point at it.
* 3) If req->proto_input_filters and req->input_filters are apreq
* filters, and req->input_filters->next == req->proto_input_filters,
* it is safe for apreq_filter to "steal" the proto filter's context
* and subsequently drop it from the chain.
*/
/* Examines the input_filter chain and moves the apreq filter(s) around
* before the filter chain is stacked by ap_get_brigade.
*/
{
request_rec *r = f->r;
(struct apache2_handle *)apreq_handle_apache2(r);
/* Don't parse GET (this protects against subrequest body parsing). */
if (f->r->method_number == M_GET)
return APR_SUCCESS;
if (f == r->input_filters) {
handle->f = f;
}
"removing intermediate apreq filter");
if (handle->f == f)
handle->f = r->input_filters;
}
else {
"relocating intermediate apreq filter");
handle->f = f;
}
return APR_SUCCESS;
}
/* else this is a protocol filter which may still be active.
* if it is, we must deregister it now.
*/
if (handle->f == f) {
"disabling stale protocol filter");
}
return APR_SUCCESS;
}
{
request_rec *r = f->r;
return ctx->body_status;
if (rv != APR_SUCCESS) {
"ap_get_brigade failed during prefetch");
}
"apreq_brigade_concat failed; TempDir problem?");
}
/* Adding "f" to the protocol filter chain ensures the
* spooled data is preserved across internal redirects.
*/
if (f != r->proto_input_filters) {
{
if (f == in) {
r->proto_input_filters = f;
break;
}
}
}
"Bytes read (%" APR_UINT64_T_FMT
return ctx->body_status;
}
return ctx->body_status;
}
{
request_rec *r = f->r;
switch (mode) {
case AP_MODE_READBYTES:
/* only the modes above are supported */
break;
case AP_MODE_EXHAUSTIVE: /* not worth supporting at this level */
case AP_MODE_GETLINE: /* chunked trailers are b0rked in ap_http_filter */
default:
return APR_ENOTIMPL;
}
apr_bucket *e;
return rv;
if (APR_BUCKET_IS_EOS(e))
e = APR_BUCKET_NEXT(e);
return APR_SUCCESS;
}
if (ctx->filter_error)
return ctx->filter_error;
return rv;
}
if (rv != APR_SUCCESS)
return rv;
"Bytes read (%" APR_UINT64_T_FMT
") exceeds configured max_body limit (%"
APR_UINT64_T_FMT ")",
}
else {
}
return APR_SUCCESS;
}
{
status = apreq_pre_initialize(p);
if (status != APR_SUCCESS) {
"Failed to pre-initialize libapreq2");
return HTTP_INTERNAL_SERVER_ERROR;
}
return OK;
}
{
status = apreq_post_initialize(p);
if (status != APR_SUCCESS) {
"Failed to post-initialize libapreq2");
return HTTP_INTERNAL_SERVER_ERROR;
}
return OK;
}
{
/* APR_HOOK_FIRST because we want other modules to be able to
* register parsers in their post_config hook via APR_HOOK_MIDDLE.
*/
/* APR_HOOK_LAST because we need to lock the default_parsers hash
* (to prevent further modifications) before the server forks.
*/
}
/** @} */
NULL,
NULL,
};
{
request_rec *r;
struct dir_config *d;
r = f->r;
if (f == r->input_filters
&& r->proto_input_filters == f->next
&& f->r->method_number != M_GET)
{
switch (ctx->body_status) {
case APREQ_ERROR_INTERRUPT:
/* fall thru */
case APR_SUCCESS:
if (d != NULL) {
}
}
"stealing filter context");
r->proto_input_filters = f;
return;
default:
"cannot steal context: bad filter status");
}
}
if (d == NULL) {
} else {
? APREQ_DEFAULT_READ_LIMIT : d->read_limit;
}
}