1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

Input filtering prototype change: Socket blocking type should be

separate from the input filter mode type.

We also no longer look at readbytes to determine the method of
filter operation.  This makes the use of filters more obvious and
allows a wider range of options for input filters modes.

To start with, the new input filter modes are:

AP_MODE_READBYTES (no more than *readbytes returned)
AP_MODE_GETLINE (old *readbytes == 0 case)
AP_MODE_EATCRLF (old AP_MODE_PEEK)
AP_MODE_SPECULATIVE (will be used in a future ap_getline rewrite)
AP_MODE_EXHAUSTIVE (old *readbytes == -1 case)
AP_MODE_INIT (special case for NNTP over SSL)

The block parameter is an apr_read_type_e: APR_BLOCK_READ, APR_NONBLOCK_READ

This also allows cleanup of mod_ssl's handling in the getline case.

Reviewed by:	Ryan Bloom (concept), Greg Stein (concept)


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@92928 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Justin Erenkrantz
2002-01-19 07:45:18 +00:00
parent 316ae68ba8
commit 7d32242a14
19 changed files with 118 additions and 78 deletions

View File

@@ -1,5 +1,8 @@
Changes with Apache 2.0.31-dev
*) Split out blocking from the mode in the input filters.
[Justin Erenkrantz]
*) Fix a segfault in mod_include. [Justin Erenkrantz, Jeff Trawick]
*) Cause Win32 to capture all child-worker process errors in

View File

@@ -92,6 +92,7 @@
* 20020111 (2.0.31-dev) bump for ETag fields added at end of cor_dir_config
* 20020114 (2.0.31-dev) mod_dav changed how it asks its provider to fulfill
* a GET request
* 20020118 (2.0.31-dev) Input filtering split of blocking and mode
*/
#define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */

View File

@@ -84,22 +84,26 @@ extern "C" {
/**
* input filtering modes
* @see apr_read_type_e in apr_buckets.h -- this is a superset of it
*/
typedef enum {
/** The filter shouldn't return until data is received or EOF is hit
* or an error occurs. */
AP_MODE_BLOCKING = APR_BLOCK_READ,
/** The filter should process any available data/status as normal,
* but will not wait for additional data. */
AP_MODE_NONBLOCKING = APR_NONBLOCK_READ,
/** The filter should return ::APR_SUCCESS if data is available or
* ::APR_EOF otherwise. The filter must not return any buckets of
* data. Data returned on a subsequent call, when mode is
* ::AP_MODE_BLOCKING or ::AP_MODE_NONBLOCKING. */
AP_MODE_PEEK,
/*
* the filter should initialize the connection if needed,
/** The filter should return at most *readbytes data. */
AP_MODE_READBYTES,
/** The filter should return at most one line of CRLF data.
* (If a potential line is too long or no CRLF is found, the
* filter may return partial data).
*/
AP_MODE_GETLINE,
/** The filter should implicitly eat any CRLF pairs that it sees. */
AP_MODE_EATCRLF,
/** The filter read should be treated as speculative and any returned
* data should be stored for later retrieval in another mode. */
AP_MODE_SPECULATIVE,
/** The filter read should be exhaustive and read until it can not
* read any more.
* Use this mode with extreme caution.
*/
AP_MODE_EXHAUSTIVE,
/** The filter should initialize the connection if needed,
* NNTP or FTP over SSL for example.
*/
AP_MODE_INIT
@@ -161,7 +165,7 @@ typedef struct ap_filter_t ap_filter_t;
*/
typedef apr_status_t (*ap_out_filter_func)(ap_filter_t *f, apr_bucket_brigade *b);
typedef apr_status_t (*ap_in_filter_func)(ap_filter_t *f, apr_bucket_brigade *b,
ap_input_mode_t mode, apr_off_t *readbytes);
ap_input_mode_t mode, apr_read_type_e block, apr_off_t *readbytes);
typedef union ap_filter_func {
ap_out_filter_func out_func;
@@ -277,12 +281,16 @@ struct ap_filter_t {
* filter doesn't read from the network, then ::AP_NOBODY_READ is returned.
* @param filter The next filter in the chain
* @param bucket The current bucket brigade
* @param mode ::AP_MODE_BLOCKING, ::AP_MODE_NONBLOCKING, or ::AP_MODE_PEEK
* @param readbytes How many bytes to read from the next filter. 0 means that
* a single line should be read.
* @param mode The way in which the data should be read
* @param block How the operations should be performed
* ::APR_BLOCK_READ, ::APR_NONBLOCK_READ
* @param readbytes How many bytes to read from the next filter.
*/
AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket,
ap_input_mode_t mode, apr_off_t *readbytes);
AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *filter,
apr_bucket_brigade *bucket,
ap_input_mode_t mode,
apr_read_type_e block,
apr_off_t *readbytes);
/**
* Pass the current bucket brigade down to the next filter on the filter

View File

@@ -106,8 +106,8 @@ static int process_echo_connection(conn_rec *c)
for ( ; ; ) {
/* Get a single line of input from the client */
if ((rv = ap_get_brigade(c->input_filters, bb,
AP_MODE_BLOCKING, &zero) != APR_SUCCESS ||
if ((rv = ap_get_brigade(c->input_filters, bb, AP_MODE_GETLINE,
APR_BLOCK_READ, &zero) != APR_SUCCESS ||
APR_BRIGADE_EMPTY(bb))) {
apr_brigade_destroy(bb);
break;

View File

@@ -101,6 +101,7 @@ static void CaseFilterInInsertFilter(request_rec *r)
static apr_status_t CaseFilterInFilter(ap_filter_t *f,
apr_bucket_brigade *pbbOut,
ap_input_mode_t eMode,
apr_read_type_e eBlock,
apr_off_t *nBytes)
{
request_rec *r = f->r;
@@ -113,9 +114,9 @@ static apr_status_t CaseFilterInFilter(ap_filter_t *f,
}
if (APR_BRIGADE_EMPTY(pCtx->pbbTmp)) {
ret = ap_get_brigade(f->next, pCtx->pbbTmp, eMode, nBytes);
ret = ap_get_brigade(f->next, pCtx->pbbTmp, eMode, eBlock, nBytes);
if (eMode == AP_MODE_PEEK || ret != APR_SUCCESS)
if (eMode == AP_MODE_EATCRLF || ret != APR_SUCCESS)
return ret;
}
@@ -140,7 +141,7 @@ static apr_status_t CaseFilterInFilter(ap_filter_t *f,
break;
}
ret=apr_bucket_read(pbktIn, &data, &len, eMode);
ret=apr_bucket_read(pbktIn, &data, &len, eBlock);
if(ret != APR_SUCCESS)
return ret;

View File

@@ -990,7 +990,8 @@ static void transfer_brigade(apr_bucket_brigade *in, apr_bucket_brigade *out)
}
static int xlate_in_filter(ap_filter_t *f, apr_bucket_brigade *bb,
ap_input_mode_t mode, apr_off_t *readbytes)
ap_input_mode_t mode, apr_read_type_e block,
apr_off_t *readbytes)
{
apr_status_t rv;
charset_req_t *reqinfo = ap_get_module_config(f->r->request_config,
@@ -1034,11 +1035,12 @@ static int xlate_in_filter(ap_filter_t *f, apr_bucket_brigade *bb,
}
if (ctx->noop) {
return ap_get_brigade(f->next, bb, mode, readbytes);
return ap_get_brigade(f->next, bb, mode, block, readbytes);
}
if (APR_BRIGADE_EMPTY(ctx->bb)) {
if ((rv = ap_get_brigade(f->next, bb, mode, readbytes)) != APR_SUCCESS) {
if ((rv = ap_get_brigade(f->next, bb, mode, block,
readbytes)) != APR_SUCCESS) {
return rv;
}
}

View File

@@ -749,7 +749,8 @@ static apr_status_t ef_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
#if 0
static int ef_input_filter(ap_filter_t *f, apr_bucket_brigade *bb,
ap_input_mode_t mode, apr_off_t *readbytes)
ap_input_mode_t mode, apr_read_type_e block,
apr_off_t *readbytes)
{
apr_status_t rv;
apr_bucket *b;
@@ -757,7 +758,7 @@ static int ef_input_filter(ap_filter_t *f, apr_bucket_brigade *bb,
apr_ssize_t len;
char *zero;
rv = ap_get_brigade(f->next, bb, mode, readbytes);
rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
if (rv != APR_SUCCESS) {
return rv;
}

View File

@@ -533,15 +533,16 @@ typedef struct http_filter_ctx {
* are successfully parsed.
*/
apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
ap_input_mode_t mode, apr_off_t *readbytes)
ap_input_mode_t mode, apr_read_type_e block,
apr_off_t *readbytes)
{
apr_bucket *e;
http_ctx_t *ctx = f->ctx;
apr_status_t rv;
/* just get out of the way of this thing. */
if (mode == AP_MODE_PEEK) {
return ap_get_brigade(f->next, b, mode, readbytes);
if (mode == AP_MODE_EATCRLF) {
return ap_get_brigade(f->next, b, mode, block, readbytes);
}
if (!ctx) {
@@ -648,7 +649,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
AP_DEBUG_ASSERT(*readbytes > 0); /* shouldn't be in getline mode */
}
rv = ap_get_brigade(f->next, b, mode, readbytes);
rv = ap_get_brigade(f->next, b, mode, block, readbytes);
if (rv != APR_SUCCESS) {
return rv;
@@ -1479,8 +1480,8 @@ AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer,
/* read until we get a non-empty brigade */
while (APR_BRIGADE_EMPTY(bb)) {
apr_off_t len_read = bufsiz;
if (ap_get_brigade(r->input_filters, bb, AP_MODE_BLOCKING,
&len_read) != APR_SUCCESS) {
if (ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
APR_BLOCK_READ, &len_read) != APR_SUCCESS) {
/* if we actually fail here, we want to just return and
* stop trying to read data from the client.
*/

View File

@@ -249,7 +249,8 @@ static void check_pipeline_flush(request_rec *r)
/* ### shouldn't this read from the connection input filters? */
/* ### is zero correct? that means "read one line" */
if (!r->connection->keepalive ||
ap_get_brigade(r->input_filters, bb, AP_MODE_PEEK, &zero) != APR_SUCCESS) {
ap_get_brigade(r->input_filters, bb, AP_MODE_EATCRLF,
APR_NONBLOCK_READ, &zero) != APR_SUCCESS) {
apr_bucket *e = apr_bucket_flush_create();
/* We just send directly to the connection based filters. At

View File

@@ -74,7 +74,8 @@ extern "C" {
* These (input) filters are internal to the mod_core operation.
*/
apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
ap_input_mode_t mode, apr_off_t *readbytes);
ap_input_mode_t mode, apr_read_type_e block,
apr_off_t *readbytes);
char *ap_response_code_string(request_rec *r, int error_index);

View File

@@ -1586,7 +1586,8 @@ int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf,
"proxy: FTP: start body send");
/* read the body, pass it to the output filters */
while (ap_get_brigade(remote->input_filters, bb, AP_MODE_BLOCKING, &readbytes) == APR_SUCCESS) {
while (ap_get_brigade(remote->input_filters, bb, AP_MODE_READBYTES,
APR_BLOCK_READ, &readbytes) == APR_SUCCESS) {
if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
ap_pass_brigade(r->output_filters, bb);
break;

View File

@@ -845,7 +845,8 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
readbytes = AP_IOBUFSIZE;
while (ap_get_brigade(rp->input_filters,
bb,
AP_MODE_BLOCKING,
AP_MODE_READBYTES,
APR_BLOCK_READ,
&readbytes) == APR_SUCCESS) {
#if DEBUGGING
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,

View File

@@ -1017,7 +1017,8 @@ PROXY_DECLARE(apr_status_t) ap_proxy_string_read(conn_rec *c, apr_bucket_brigade
apr_off_t zero = 0;
/* get brigade from network one line at a time */
if (APR_SUCCESS != (rv = ap_get_brigade(c->input_filters, bb,
AP_MODE_BLOCKING,
AP_MODE_GETLINE,
APR_BLOCK_READ,
&zero /* readline */))) {
return rv;
}

View File

@@ -297,7 +297,7 @@ typedef struct {
ap_filter_t *f;
apr_status_t rc;
ap_input_mode_t mode;
int getline;
apr_read_type_e block;
apr_bucket_brigade *bb;
apr_bucket *bucket;
char_buffer_t cbuf;
@@ -368,7 +368,7 @@ static int bio_bucket_in_read(BIO *bio, char *in, int inl)
/* first use data already read from socket if any */
if ((len = char_buffer_read(&inbio->cbuf, in, inl))) {
if ((len <= inl) || inbio->getline) {
if ((len <= inl) || inbio->mode == AP_MODE_GETLINE) {
return len;
}
}
@@ -386,8 +386,11 @@ static int bio_bucket_in_read(BIO *bio, char *in, int inl)
}
if (APR_BRIGADE_EMPTY(inbio->bb)) {
/* We will always call with READBYTES even if the user wants
* GETLINE.
*/
inbio->rc = ap_get_brigade(inbio->f->next, inbio->bb,
inbio->mode, &readbytes);
AP_MODE_READBYTES, inbio->block, &readbytes);
if ((inbio->rc != APR_SUCCESS) || APR_BRIGADE_EMPTY(inbio->bb))
{
@@ -398,7 +401,7 @@ static int bio_bucket_in_read(BIO *bio, char *in, int inl)
inbio->bucket = APR_BRIGADE_FIRST(inbio->bb);
inbio->rc = apr_bucket_read(inbio->bucket,
&buf, &buf_len, inbio->mode);
&buf, &buf_len, inbio->block);
if (inbio->rc != APR_SUCCESS) {
apr_bucket_delete(inbio->bucket);
@@ -433,7 +436,7 @@ static int bio_bucket_in_read(BIO *bio, char *in, int inl)
}
}
if (inbio->getline) {
if (inbio->mode == AP_MODE_GETLINE) {
/* only read from the socket once in getline mode.
* since callers buffer size is likely much larger than
* the request headers. caller can always come back for more
@@ -643,7 +646,7 @@ static apr_status_t ssl_io_input_read(ssl_io_input_ctx_t *ctx,
if ((bytes = char_buffer_read(&ctx->cbuf, buf, wanted))) {
*len = bytes;
if ((*len >= wanted) || ctx->inbio.getline) {
if ((*len >= wanted) || ctx->inbio.mode == AP_MODE_GETLINE) {
return APR_SUCCESS;
}
}
@@ -664,9 +667,7 @@ static apr_status_t ssl_io_input_getline(ssl_io_input_ctx_t *ctx,
const char *pos;
apr_status_t status;
ctx->inbio.getline = 1;
status = ssl_io_input_read(ctx, buf, len);
ctx->inbio.getline = 0;
if (status != APR_SUCCESS) {
return status;
@@ -725,6 +726,7 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f,
static apr_status_t ssl_io_filter_Input(ap_filter_t *f,
apr_bucket_brigade *bb,
ap_input_mode_t mode,
apr_read_type_e block,
apr_off_t *readbytes)
{
apr_status_t status;
@@ -735,11 +737,12 @@ static apr_status_t ssl_io_filter_Input(ap_filter_t *f,
int is_init = (mode == AP_MODE_INIT);
/* XXX: we don't currently support peek or readbytes == -1 */
if (mode == AP_MODE_PEEK || *readbytes == -1) {
if (mode == AP_MODE_EATCRLF || *readbytes == -1) {
return APR_ENOTIMPL;
}
ctx->inbio.mode = is_init ? AP_MODE_BLOCKING : mode;
ctx->inbio.mode = mode;
ctx->inbio.block = block;
/* XXX: we could actually move ssl_hook_process_connection to an
* ap_hook_process_connection but would still need to call it for
@@ -759,17 +762,20 @@ static apr_status_t ssl_io_filter_Input(ap_filter_t *f,
return APR_SUCCESS;
}
if (bytes > 0) {
if (ctx->inbio.mode == AP_MODE_READBYTES) {
/* Protected from truncation, bytes < MAX_SIZE_T */
if (bytes < len) {
len = (apr_size_t)bytes;
}
ctx->inbio.getline = 0;
status = ssl_io_input_read(ctx, ctx->buffer, &len);
}
else {
else if (ctx->inbio.mode == AP_MODE_GETLINE) {
status = ssl_io_input_getline(ctx, ctx->buffer, &len);
}
else {
/* We have no idea what you are talking about, so return an error. */
return APR_ENOTIMPL;
}
if (status != APR_SUCCESS) {
return ssl_io_filter_error(f, bb, status);
@@ -804,7 +810,6 @@ static void ssl_io_input_add_filter(SSLFilterRec *frec, conn_rec *c,
ctx->inbio.f = frec->pInputFilter;
ctx->inbio.bb = apr_brigade_create(c->pool);
ctx->inbio.bucket = NULL;
ctx->inbio.getline = 0;
ctx->inbio.cbuf.length = 0;
ctx->cbuf.length = 0;

View File

@@ -2973,7 +2973,9 @@ static int default_handler(request_rec *r)
return ap_pass_brigade(r->output_filters, bb);
}
static int net_time_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_off_t *readbytes)
static int net_time_filter(ap_filter_t *f, apr_bucket_brigade *b,
ap_input_mode_t mode, apr_read_type_e block,
apr_off_t *readbytes)
{
int keptalive = f->c->keepalive == 1;
apr_socket_t *csd = ap_get_module_config(f->c->conn_config, &core_module);
@@ -2984,7 +2986,7 @@ static int net_time_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_
*first_line = 1;
}
if (mode != AP_MODE_INIT && mode != AP_MODE_PEEK) {
if (mode != AP_MODE_INIT && mode != AP_MODE_EATCRLF) {
if (*first_line) {
apr_setsocketopt(csd, APR_SO_TIMEOUT,
(int)(keptalive
@@ -2999,10 +3001,12 @@ static int net_time_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_
}
}
}
return ap_get_brigade(f->next, b, mode, readbytes);
return ap_get_brigade(f->next, b, mode, block, readbytes);
}
static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_off_t *readbytes)
static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
ap_input_mode_t mode, apr_read_type_e block,
apr_off_t *readbytes)
{
apr_bucket *e;
apr_status_t rv;
@@ -3046,7 +3050,7 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mod
/* ### AP_MODE_PEEK is a horrific name for this mode because we also
* eat any CRLFs that we see. That's not the obvious intention of
* this mode. Determine whether anyone actually uses this or not. */
if (mode == AP_MODE_PEEK) {
if (mode == AP_MODE_EATCRLF) {
apr_bucket *e;
const char *c;
@@ -3096,7 +3100,7 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mod
* This is just an all-around bad idea. We may be better off by
* just closing the socket. Determine whether anyone uses this.
*/
if (*readbytes == -1) {
if (mode == AP_MODE_EXHAUSTIVE) {
apr_bucket *e;
apr_off_t total;
@@ -3110,8 +3114,8 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mod
APR_BRIGADE_INSERT_TAIL(b, e);
return APR_SUCCESS;
}
/* readbytes == 0 is "read a single line". otherwise, read a block. */
if (*readbytes) {
/* read up to the amount they specified. */
if (mode == AP_MODE_READBYTES) {
apr_off_t total;
apr_bucket *e;
apr_bucket_brigade *newbb;
@@ -3119,7 +3123,7 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mod
AP_DEBUG_ASSERT(*readbytes > 0);
e = APR_BRIGADE_FIRST(ctx->b);
rv = apr_bucket_read(e, &str, &len, mode);
rv = apr_bucket_read(e, &str, &len, block);
if (APR_STATUS_IS_EAGAIN(rv)) {
*readbytes = 0;
@@ -3153,7 +3157,7 @@ static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mod
const char *pos;
e = APR_BRIGADE_FIRST(ctx->b);
rv = apr_bucket_read(e, &str, &len, mode);
rv = apr_bucket_read(e, &str, &len, block);
/* We should treat EAGAIN here the same as we do for EOF (brigade is
* empty). We do this by returning whatever we have read. This may

View File

@@ -1550,8 +1550,8 @@ static int pass_request(request_rec *r)
/* ### this "read one line" doesn't seem right... shouldn't we be
### reading large chunks of data or something?
*/
while (ap_get_brigade(r->input_filters, bb, AP_MODE_NONBLOCKING,
&zero /* read one line */) == APR_SUCCESS) {
while (ap_get_brigade(r->input_filters, bb, AP_MODE_GETLINE,
APR_NONBLOCK_READ, &zero) == APR_SUCCESS) {
apr_bucket *e;
APR_BRIGADE_FOREACH(e, bb) {
const char *str;
@@ -1656,7 +1656,9 @@ static int perchild_post_read(request_rec *r)
}
static apr_status_t perchild_buffer(ap_filter_t *f, apr_bucket_brigade *b,
ap_input_mode_t mode, apr_off_t *readbytes)
ap_input_mode_t mode,
apr_read_type_e block,
apr_off_t *readbytes)
{
apr_bucket *e;
apr_status_t rv;
@@ -1664,7 +1666,8 @@ static apr_status_t perchild_buffer(ap_filter_t *f, apr_bucket_brigade *b,
const char *str;
apr_size_t len;
if ((rv = ap_get_brigade(f->next, b, mode, readbytes)) != APR_SUCCESS) {
if ((rv = ap_get_brigade(f->next, b, mode, block,
readbytes)) != APR_SUCCESS) {
return rv;
}

View File

@@ -1550,8 +1550,8 @@ static int pass_request(request_rec *r)
/* ### this "read one line" doesn't seem right... shouldn't we be
### reading large chunks of data or something?
*/
while (ap_get_brigade(r->input_filters, bb, AP_MODE_NONBLOCKING,
&zero /* read one line */) == APR_SUCCESS) {
while (ap_get_brigade(r->input_filters, bb, AP_MODE_GETLINE,
APR_NONBLOCK_READ, &zero) == APR_SUCCESS) {
apr_bucket *e;
APR_BRIGADE_FOREACH(e, bb) {
const char *str;
@@ -1656,7 +1656,9 @@ static int perchild_post_read(request_rec *r)
}
static apr_status_t perchild_buffer(ap_filter_t *f, apr_bucket_brigade *b,
ap_input_mode_t mode, apr_off_t *readbytes)
ap_input_mode_t mode,
apr_read_type_e block,
apr_off_t *readbytes)
{
apr_bucket *e;
apr_status_t rv;
@@ -1664,7 +1666,8 @@ static apr_status_t perchild_buffer(ap_filter_t *f, apr_bucket_brigade *b,
const char *str;
apr_size_t len;
if ((rv = ap_get_brigade(f->next, b, mode, readbytes)) != APR_SUCCESS) {
if ((rv = ap_get_brigade(f->next, b, mode, block,
readbytes)) != APR_SUCCESS) {
return rv;
}

View File

@@ -223,8 +223,9 @@ AP_DECLARE(int) ap_rgetline(char **s, int n, request_rec *r, int fold)
if (APR_BRIGADE_EMPTY(b)) {
apr_off_t zero = 0;
if ((retval = ap_get_brigade(r->input_filters, b,
AP_MODE_BLOCKING,
&zero /* readline */)) != APR_SUCCESS ||
AP_MODE_GETLINE,
APR_BLOCK_READ,
&zero)) != APR_SUCCESS ||
APR_BRIGADE_EMPTY(b)) {
apr_brigade_destroy(b);
return -1;

View File

@@ -356,10 +356,12 @@ AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f)
AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *next,
apr_bucket_brigade *bb,
ap_input_mode_t mode,
apr_read_type_e block,
apr_off_t *readbytes)
{
if (next) {
return next->frec->filter_func.in_func(next, bb, mode, readbytes);
return next->frec->filter_func.in_func(next, bb, mode, block,
readbytes);
}
return AP_NOBODY_READ;
}