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

At the hack-athon we decided to change the way that input filters

determine how much data is returned to the previous filter.  Prior to this
change, we used a field in the conn_rec to determine how much to return.
After this change, we use an argument to ap_get_brigade.  This makes it
much more obvious how things work at all levels, so that module authors
can easily determine how much data is supposed to be returned to them.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88912 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Ryan Bloom
2001-04-22 22:19:32 +00:00
parent 97b23cb074
commit eb94b557ee
12 changed files with 41 additions and 37 deletions

View File

@@ -1,4 +1,10 @@
Changes with Apache 2.0.18-dev
*) Change how input filters decide how much data is returned to the
higher filter. We used to use a field in the conn_rec, with this
change, we use an argument to ap_get_brigade to determine how much
data is retrieved. [Ryan Bloom]
*) Fix seg fault at start-up introduced by Ryan's change to enable
modules to specify their own logging tags. mod_log_config
registers an optional function, ap_register_log_handler().

View File

@@ -697,7 +697,7 @@ struct request_rec {
apr_off_t clength;
/** bytes left to read */
long remaining;
apr_size_t remaining;
/** bytes that have been read */
long read_length;
/** how the request body should be read */
@@ -887,9 +887,6 @@ struct conn_rec {
/** A list of output filters to be used for this connection
* @defvar ap_filter_t *filters */
struct ap_filter_t *output_filters;
/** The length of the current request body
* @defvar long remain */
long remain;
};
/* Per-vhost config... */

View File

@@ -155,7 +155,8 @@ 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);
ap_input_mode_t mode, apr_size_t *readbytes);
typedef union ap_filter_func {
ap_out_filter_func out_func;
ap_in_filter_func in_func;
@@ -273,7 +274,7 @@ struct ap_filter_t {
* @param mode ::AP_MODE_BLOCKING, ::AP_MODE_NONBLOCKING, or ::AP_MODE_PEEK
*/
AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket,
ap_input_mode_t mode);
ap_input_mode_t mode, apr_size_t *readbytes);
/**
* Pass the current bucket brigade down to the next filter on the filter

View File

@@ -1005,7 +1005,7 @@ 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)
ap_input_mode_t mode, apr_size_t *readbytes)
{
apr_status_t rv;
charset_req_t *reqinfo = ap_get_module_config(f->r->request_config,
@@ -1049,11 +1049,11 @@ static int xlate_in_filter(ap_filter_t *f, apr_bucket_brigade *bb,
}
if (ctx->noop) {
return ap_get_brigade(f->next, bb, mode);
return ap_get_brigade(f->next, bb, mode, readbytes);
}
if (APR_BRIGADE_EMPTY(ctx->bb)) {
if ((rv = ap_get_brigade(f->next, bb, mode)) != APR_SUCCESS) {
if ((rv = ap_get_brigade(f->next, bb, mode, readbytes)) != APR_SUCCESS) {
return rv;
}
}

View File

@@ -749,7 +749,7 @@ 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)
ap_input_mode_t mode, apr_size_t *readbytes)
{
apr_status_t rv;
apr_bucket *b;
@@ -757,7 +757,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);
rv = ap_get_brigade(f->next, bb, mode, readbytes);
if (rv != APR_SUCCESS) {
return rv;
}

View File

@@ -420,7 +420,7 @@ struct dechunk_ctx {
static long get_chunk_size(char *);
apr_status_t ap_dechunk_filter(ap_filter_t *f, apr_bucket_brigade *bb,
ap_input_mode_t mode)
ap_input_mode_t mode, apr_size_t *readbytes)
{
apr_status_t rv;
struct dechunk_ctx *ctx = f->ctx;
@@ -475,8 +475,8 @@ apr_status_t ap_dechunk_filter(ap_filter_t *f, apr_bucket_brigade *bb,
if (ctx->state == WANT_BODY) {
/* Tell ap_http_filter() how many bytes to deliver. */
f->c->remain = ctx->chunk_size - ctx->bytes_delivered;
if ((rv = ap_get_brigade(f->next, bb, mode)) != APR_SUCCESS) {
apr_size_t readbytes = ctx->chunk_size - ctx->bytes_delivered;
if ((rv = ap_get_brigade(f->next, bb, mode, &readbytes)) != APR_SUCCESS) {
return rv;
}
/* Walk through the body, accounting for bytes, and removing an eos bucket if
@@ -503,7 +503,7 @@ typedef struct http_filter_ctx {
apr_bucket_brigade *b;
} http_ctx_t;
apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode)
apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_size_t *readbytes)
{
apr_bucket *e;
char *buff;
@@ -556,12 +556,12 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode
}
if (APR_BRIGADE_EMPTY(ctx->b)) {
if ((rv = ap_get_brigade(f->next, ctx->b, mode)) != APR_SUCCESS) {
if ((rv = ap_get_brigade(f->next, ctx->b, mode, readbytes)) != APR_SUCCESS) {
return rv;
}
}
if (f->c->remain) {
if (*readbytes) {
while (!APR_BRIGADE_EMPTY(ctx->b)) {
const char *ignore;
@@ -580,12 +580,12 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode
* a time - don't assume that one call to apr_bucket_read()
* will return the full string.
*/
if (f->c->remain < len) {
apr_bucket_split(e, f->c->remain);
f->c->remain = 0;
if (*readbytes < len) {
apr_bucket_split(e, *readbytes);
*readbytes = 0;
}
else {
f->c->remain -= len;
*readbytes -= len;
}
APR_BUCKET_REMOVE(e);
APR_BRIGADE_INSERT_TAIL(b, e);
@@ -593,7 +593,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode
}
apr_bucket_delete(e);
}
if (f->c->remain == 0) {
if (*readbytes == 0) {
apr_bucket *eos = apr_bucket_eos_create();
APR_BRIGADE_INSERT_TAIL(b, eos);
@@ -1258,7 +1258,7 @@ AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy)
return HTTP_BAD_REQUEST;
}
r->connection->remain = r->remaining = atol(lenp);
r->remaining = atol(lenp);
}
if ((r->read_body == REQUEST_NO_BODY) &&
@@ -1366,7 +1366,7 @@ AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer, int bufsiz)
do {
if (APR_BRIGADE_EMPTY(bb)) {
if (ap_get_brigade(r->input_filters, bb, AP_MODE_BLOCKING) != APR_SUCCESS) {
if (ap_get_brigade(r->input_filters, bb, AP_MODE_BLOCKING, &r->remaining) != APR_SUCCESS) {
/* if we actually fail here, we want to just return and
* stop trying to read data from the client.
*/

View File

@@ -367,6 +367,7 @@ static void check_pipeline_flush(request_rec *r)
### allow us to defer creation of the brigade to when we actually
### need to send a FLUSH. */
apr_bucket_brigade *bb = apr_brigade_create(r->pool);
apr_size_t zero = 0;
/* Flush the filter contents if:
*
@@ -375,7 +376,7 @@ static void check_pipeline_flush(request_rec *r)
*/
/* ### shouldn't this read from the connection input filters? */
if (!r->connection->keepalive ||
ap_get_brigade(r->input_filters, bb, AP_MODE_PEEK) != APR_SUCCESS) {
ap_get_brigade(r->input_filters, bb, AP_MODE_PEEK, &zero) != APR_SUCCESS) {
apr_bucket *e = apr_bucket_flush_create();
/* We just send directly to the connection based filters. At

View File

@@ -73,8 +73,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_status_t ap_dechunk_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode);
apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_size_t *readbytes);
apr_status_t ap_dechunk_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_size_t *readbytes);
char *ap_response_code_string(request_rec *r, int error_index);

View File

@@ -186,14 +186,14 @@ static apr_status_t churn_output(TLSFilterCtx *pCtx)
return APR_SUCCESS;
}
static apr_status_t churn(TLSFilterCtx *pCtx,apr_read_type_e eReadType)
static apr_status_t churn(TLSFilterCtx *pCtx,apr_read_type_e eReadType,apr_size_t *readbytes)
{
ap_input_mode_t eMode=eReadType == APR_BLOCK_READ ? AP_MODE_BLOCKING
: AP_MODE_NONBLOCKING;
apr_bucket *pbktIn;
if(APR_BRIGADE_EMPTY(pCtx->pbbInput)) {
ap_get_brigade(pCtx->pInputFilter->next,pCtx->pbbInput,eMode);
ap_get_brigade(pCtx->pInputFilter->next,pCtx->pbbInput,eMode,readbytes);
if(APR_BRIGADE_EMPTY(pCtx->pbbInput))
return APR_EOF;
}
@@ -329,7 +329,7 @@ static apr_status_t tls_out_filter(ap_filter_t *f,apr_bucket_brigade *pbbIn)
}
static apr_status_t tls_in_filter(ap_filter_t *f,apr_bucket_brigade *pbbOut,
ap_input_mode_t eMode)
ap_input_mode_t eMode, apr_size_t *readbytes)
{
TLSFilterCtx *pCtx=f->ctx;
apr_read_type_e eReadType=eMode == AP_MODE_BLOCKING ? APR_BLOCK_READ :
@@ -340,7 +340,7 @@ static apr_status_t tls_in_filter(ap_filter_t *f,apr_bucket_brigade *pbbOut,
assert(eMode != AP_MODE_PEEK);
// churn the state machine
ret=churn(pCtx,eReadType);
ret=churn(pCtx,eReadType,readbytes);
if(ret != APR_SUCCESS)
return ret;

View File

@@ -2995,7 +2995,7 @@ static int default_handler(request_rec *r)
return ap_pass_brigade(r->output_filters, bb);
}
static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode)
static int core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_size_t *readbytes)
{
apr_bucket *e;

View File

@@ -203,6 +203,7 @@ AP_CORE_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int fold)
int retval;
int total = 0;
int looking_ahead = 0;
apr_size_t zero = 0;
apr_size_t length;
conn_rec *c = r->connection;
core_request_config *req_cfg;
@@ -217,7 +218,7 @@ AP_CORE_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int fold)
while (1) {
if (APR_BRIGADE_EMPTY(b)) {
if ((retval = ap_get_brigade(c->input_filters, b, AP_MODE_BLOCKING)) != APR_SUCCESS ||
if ((retval = ap_get_brigade(c->input_filters, b, AP_MODE_BLOCKING, &zero)) != APR_SUCCESS ||
APR_BRIGADE_EMPTY(b)) {
apr_brigade_destroy(b);
return -1;
@@ -548,8 +549,6 @@ request_rec *ap_read_request(conn_rec *conn)
const char *expect;
int access_status;
AP_DEBUG_ASSERT(conn->remain == 0);
apr_pool_create(&p, conn->pool);
r = apr_pcalloc(p, sizeof(request_rec));
r->pool = p;

View File

@@ -209,10 +209,10 @@ AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f)
* brigade especially for that use.
*/
AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *next, apr_bucket_brigade *bb,
ap_input_mode_t mode)
ap_input_mode_t mode, apr_size_t *readbytes)
{
if (next) {
return next->frec->filter_func.in_func(next, bb, mode);
return next->frec->filter_func.in_func(next, bb, mode, readbytes);
}
return AP_NOBODY_READ;
}