From: Ryan Bloom Date: Sun, 6 May 2001 23:27:14 +0000 (+0000) Subject: Back out the recent change to ap_get_brigade, to make it use indirection X-Git-Tag: 2.0.18~73 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1c98aabbf13be673d386684d13e066139eed3c68;p=thirdparty%2Fapache%2Fhttpd.git Back out the recent change to ap_get_brigade, to make it use indirection again. The problem is that the amount of data read from the network, is not necessarily the amount of data returned from the filters. It is possible for input filters to add bytes to the data read from the network. To fix the original bug, I just removed the line from ap_get_client_block that decremented r->remaining, we allow the http_filter to do that for us. I have also removed an incorrect comment. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@89041 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/util_filter.h b/include/util_filter.h index 2ee93fa8ee4..17e5c0acadf 100644 --- a/include/util_filter.h +++ b/include/util_filter.h @@ -155,7 +155,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_size_t readbytes); + ap_input_mode_t mode, apr_size_t *readbytes); typedef union ap_filter_func { ap_out_filter_func out_func; @@ -276,7 +276,7 @@ struct ap_filter_t { * a single line should be read. */ AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket, - ap_input_mode_t mode, apr_size_t readbytes); + ap_input_mode_t mode, apr_size_t *readbytes); /** * Pass the current bucket brigade down to the next filter on the filter diff --git a/modules/experimental/mod_case_filter_in.c b/modules/experimental/mod_case_filter_in.c index e4ab97feab4..94ecae6dd0d 100644 --- a/modules/experimental/mod_case_filter_in.c +++ b/modules/experimental/mod_case_filter_in.c @@ -47,7 +47,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_size_t nBytes) + ap_input_mode_t eMode,apr_size_t *nBytes) { CaseFilterInContext *pCtx=f->ctx; apr_status_t ret; diff --git a/modules/experimental/mod_charset_lite.c b/modules/experimental/mod_charset_lite.c index 190ec1b4d34..79830eed08d 100644 --- a/modules/experimental/mod_charset_lite.c +++ b/modules/experimental/mod_charset_lite.c @@ -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, apr_size_t readbytes) + 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, diff --git a/modules/experimental/mod_ext_filter.c b/modules/experimental/mod_ext_filter.c index 7f9d87b62c3..46b4b1e5273 100644 --- a/modules/experimental/mod_ext_filter.c +++ b/modules/experimental/mod_ext_filter.c @@ -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, apr_size_t readbytes) + ap_input_mode_t mode, apr_size_t *readbytes) { apr_status_t rv; apr_bucket *b; diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index f092dbdbaf8..95ace2ed162 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -424,7 +424,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, apr_size_t readbytes) + ap_input_mode_t mode, apr_size_t *readbytes) { apr_status_t rv; struct dechunk_ctx *ctx = f->ctx; @@ -484,7 +484,7 @@ apr_status_t ap_dechunk_filter(ap_filter_t *f, apr_bucket_brigade *bb, apr_size_t chunk_bytes = ctx->chunk_size - ctx->bytes_delivered; if ((rv = ap_get_brigade(f->next, bb, mode, - chunk_bytes)) != APR_SUCCESS) { + &chunk_bytes)) != APR_SUCCESS) { return rv; } @@ -518,7 +518,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_size_t readbytes) +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; @@ -577,7 +577,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode } /* readbytes == 0 is "read a single line". otherwise, read a block. */ - if (readbytes) { + if (*readbytes) { /* ### the code below, which moves bytes from one brigade to the ### other is probably bogus. presuming the next filter down was @@ -604,12 +604,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 (readbytes < len) { - apr_bucket_split(e, readbytes); - readbytes = 0; + if (*readbytes < len) { + apr_bucket_split(e, *readbytes); + *readbytes = 0; } else { - readbytes -= len; + *readbytes -= len; } APR_BUCKET_REMOVE(e); APR_BRIGADE_INSERT_TAIL(b, e); @@ -628,7 +628,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode ### chunks to determine where the end of the request is, so we ### shouldn't be monkeying with EOS buckets. */ - if (readbytes == 0) { + if (*readbytes == 0) { apr_bucket *eos = apr_bucket_eos_create(); APR_BRIGADE_INSERT_TAIL(b, eos); @@ -1403,7 +1403,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, - r->remaining) != APR_SUCCESS) { + &r->remaining) != APR_SUCCESS) { /* if we actually fail here, we want to just return and * stop trying to read data from the client. */ @@ -1449,7 +1449,6 @@ AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer, int bufsiz) * these */ r->read_length += len_read; /* XXX yank me? */ - r->remaining -= len_read; /* XXX yank me? */ old = b; b = APR_BUCKET_NEXT(b); apr_bucket_delete(old); diff --git a/modules/http/http_request.c b/modules/http/http_request.c index d79f4c79878..a2a03827e4a 100644 --- a/modules/http/http_request.c +++ b/modules/http/http_request.c @@ -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); + int zero = 0; /* Flush the filter contents if: * @@ -376,7 +377,7 @@ 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, 0) != 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 diff --git a/modules/http/mod_core.h b/modules/http/mod_core.h index 2f149797bff..f01f6a0f1fa 100644 --- a/modules/http/mod_core.h +++ b/modules/http/mod_core.h @@ -74,9 +74,9 @@ 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_size_t readbytes); + 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); + ap_input_mode_t mode, apr_size_t *readbytes); char *ap_response_code_string(request_rec *r, int error_index); diff --git a/modules/mappers/mod_alias.c b/modules/mappers/mod_alias.c index a5752e3c1ec..5217ff373af 100644 --- a/modules/mappers/mod_alias.c +++ b/modules/mappers/mod_alias.c @@ -335,7 +335,16 @@ static char *try_alias_list(request_rec *r, apr_array_header_t *aliases, int doe found = ap_pregsub(r->pool, p->real, r->uri, p->regexp->re_nsub + 1, regm); if (found && doesc) { - found = ap_escape_uri(r->pool, found); + uri_components uri; + ap_parse_uri_components(r->pool, found, &uri); + found = ap_escape_uri(r->pool, uri.path); + if (uri.query) { + found = apr_pstrcat(r->pool, found, "?", uri.query, NULL); + } + else if (uri.fragment) { + found = apr_pstrcat(r->pool, found, "#", uri.fragment, NULL); + + } } } else { diff --git a/modules/tls/mod_tls.c b/modules/tls/mod_tls.c index 3f3130694b2..de7f8ece2ca 100644 --- a/modules/tls/mod_tls.c +++ b/modules/tls/mod_tls.c @@ -186,7 +186,7 @@ static apr_status_t churn_output(TLSFilterCtx *pCtx) return APR_SUCCESS; } -static apr_status_t churn(TLSFilterCtx *pCtx,apr_read_type_e eReadType,apr_size_t readbytes) +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; @@ -333,7 +333,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, apr_size_t readbytes) + 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 : diff --git a/server/core.c b/server/core.c index b230fc974e6..18661e1b93b 100644 --- a/server/core.c +++ b/server/core.c @@ -2995,18 +2995,10 @@ 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, apr_size_t readbytes) +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; - /* ### we should obey readbytes. the policy is to not insert more than - ### READBYTES into the brigade. the caller knows the amount that is - ### proper for the protocol. reading more than that could cause - ### problems. - ### (of course, we can read them from the socket, we just should not - ### return them until asked) - */ - if (!f->ctx) { /* If we haven't passed up the socket yet... */ f->ctx = (void *)1; e = apr_bucket_socket_create(f->c->client_socket); diff --git a/server/mpm/experimental/perchild/perchild.c b/server/mpm/experimental/perchild/perchild.c index 4bad0ccdfd4..a27ba5ecce4 100644 --- a/server/mpm/experimental/perchild/perchild.c +++ b/server/mpm/experimental/perchild/perchild.c @@ -1362,6 +1362,7 @@ static int pass_request(request_rec *r) &mpm_perchild_module); char *foo; apr_size_t len; + int zero = 0; apr_pool_userdata_get((void **)&foo, "PERCHILD_BUFFER", r->connection->pool); len = strlen(foo); @@ -1401,7 +1402,7 @@ static int pass_request(request_rec *r) ### reading large chunks of data or something? */ while (ap_get_brigade(r->input_filters, bb, AP_MODE_NONBLOCKING, - 0 /* read one line */) == APR_SUCCESS) { + &zero /* read one line */) == APR_SUCCESS) { apr_bucket *e; APR_BRIGADE_FOREACH(e, bb) { const char *str; @@ -1495,7 +1496,7 @@ static int perchild_post_read(request_rec *r) return OK; } -static apr_status_t perchild_buffer(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_size_t readbytes) +static apr_status_t perchild_buffer(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_size_t *readbytes) { apr_bucket *e; apr_status_t rv; diff --git a/server/mpm/perchild/perchild.c b/server/mpm/perchild/perchild.c index 4bad0ccdfd4..a27ba5ecce4 100644 --- a/server/mpm/perchild/perchild.c +++ b/server/mpm/perchild/perchild.c @@ -1362,6 +1362,7 @@ static int pass_request(request_rec *r) &mpm_perchild_module); char *foo; apr_size_t len; + int zero = 0; apr_pool_userdata_get((void **)&foo, "PERCHILD_BUFFER", r->connection->pool); len = strlen(foo); @@ -1401,7 +1402,7 @@ static int pass_request(request_rec *r) ### reading large chunks of data or something? */ while (ap_get_brigade(r->input_filters, bb, AP_MODE_NONBLOCKING, - 0 /* read one line */) == APR_SUCCESS) { + &zero /* read one line */) == APR_SUCCESS) { apr_bucket *e; APR_BRIGADE_FOREACH(e, bb) { const char *str; @@ -1495,7 +1496,7 @@ static int perchild_post_read(request_rec *r) return OK; } -static apr_status_t perchild_buffer(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_size_t readbytes) +static apr_status_t perchild_buffer(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_size_t *readbytes) { apr_bucket *e; apr_status_t rv; diff --git a/server/protocol.c b/server/protocol.c index 0d816b835e7..bd9d268c69f 100644 --- a/server/protocol.c +++ b/server/protocol.c @@ -217,9 +217,10 @@ AP_CORE_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int fold) while (1) { if (APR_BRIGADE_EMPTY(b)) { + int zero = 0; if ((retval = ap_get_brigade(c->input_filters, b, AP_MODE_BLOCKING, - 0 /* readline */)) != APR_SUCCESS || + &zero /* readline */)) != APR_SUCCESS || APR_BRIGADE_EMPTY(b)) { apr_brigade_destroy(b); return -1; diff --git a/server/util_filter.c b/server/util_filter.c index eaa3ad3f71e..ef9a55262f8 100644 --- a/server/util_filter.c +++ b/server/util_filter.c @@ -211,7 +211,7 @@ 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_size_t readbytes) + apr_size_t *readbytes) { if (next) { return next->frec->filter_func.in_func(next, bb, mode, readbytes);