From: Joe Orton Date: Thu, 2 Dec 2004 13:25:12 +0000 (+0000) Subject: * modules/http/mod_core.h: Prototype ap_http_chunk_filter. X-Git-Tag: 2.1.2~26 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=671710004dbfb9793554faf4fa8247f021d66814;p=apache * modules/http/mod_core.h: Prototype ap_http_chunk_filter. * modules/http/chunk_filter.c (ap_http_chunk_filter): Rename from chunk_filter. * modules/http/http_core.c (chunk_filter): Remove the original copy. (register_hooks): Register ap_http_chunk_filter. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@109497 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/http/chunk_filter.c b/modules/http/chunk_filter.c index d28c755aee..7426a1aa6b 100644 --- a/modules/http/chunk_filter.c +++ b/modules/http/chunk_filter.c @@ -38,7 +38,7 @@ #include "mod_core.h" -static apr_status_t chunk_filter(ap_filter_t *f, apr_bucket_brigade *b) +apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b) { #define ASCII_CRLF "\015\012" #define ASCII_ZERO "\060" diff --git a/modules/http/http_core.c b/modules/http/http_core.c index 89a7c92ad7..07a3e13ae1 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -94,137 +94,6 @@ static const command_rec http_cmds[] = { { NULL } }; -/* - * HTTP/1.1 chunked transfer encoding filter. - */ -static apr_status_t chunk_filter(ap_filter_t *f, apr_bucket_brigade *b) -{ -#define ASCII_CRLF "\015\012" -#define ASCII_ZERO "\060" - conn_rec *c = f->r->connection; - apr_bucket_brigade *more; - apr_bucket *e; - apr_status_t rv; - - for (more = NULL; b; b = more, more = NULL) { - apr_off_t bytes = 0; - apr_bucket *eos = NULL; - apr_bucket *flush = NULL; - /* XXX: chunk_hdr must remain at this scope since it is used in a - * transient bucket. - */ - char chunk_hdr[20]; /* enough space for the snprintf below */ - - - for (e = APR_BRIGADE_FIRST(b); - e != APR_BRIGADE_SENTINEL(b); - e = APR_BUCKET_NEXT(e)) - { - if (APR_BUCKET_IS_EOS(e)) { - /* there shouldn't be anything after the eos */ - eos = e; - break; - } - if (APR_BUCKET_IS_FLUSH(e)) { - flush = e; - } - else if (e->length == (apr_size_t)-1) { - /* unknown amount of data (e.g. a pipe) */ - const char *data; - apr_size_t len; - - rv = apr_bucket_read(e, &data, &len, APR_BLOCK_READ); - if (rv != APR_SUCCESS) { - return rv; - } - if (len > 0) { - /* - * There may be a new next bucket representing the - * rest of the data stream on which a read() may - * block so we pass down what we have so far. - */ - bytes += len; - more = apr_brigade_split(b, APR_BUCKET_NEXT(e)); - break; - } - else { - /* If there was nothing in this bucket then we can - * safely move on to the next one without pausing - * to pass down what we have counted up so far. - */ - continue; - } - } - else { - bytes += e->length; - } - } - - /* - * XXX: if there aren't very many bytes at this point it may - * be a good idea to set them aside and return for more, - * unless we haven't finished counting this brigade yet. - */ - /* if there are content bytes, then wrap them in a chunk */ - if (bytes > 0) { - apr_size_t hdr_len; - /* - * Insert the chunk header, specifying the number of bytes in - * the chunk. - */ - hdr_len = apr_snprintf(chunk_hdr, sizeof(chunk_hdr), - "%" APR_UINT64_T_HEX_FMT CRLF, (apr_uint64_t)bytes); - ap_xlate_proto_to_ascii(chunk_hdr, hdr_len); - e = apr_bucket_transient_create(chunk_hdr, hdr_len, - c->bucket_alloc); - APR_BRIGADE_INSERT_HEAD(b, e); - - /* - * Insert the end-of-chunk CRLF before an EOS or - * FLUSH bucket, or appended to the brigade - */ - e = apr_bucket_immortal_create(ASCII_CRLF, 2, c->bucket_alloc); - if (eos != NULL) { - APR_BUCKET_INSERT_BEFORE(eos, e); - } - else if (flush != NULL) { - APR_BUCKET_INSERT_BEFORE(flush, e); - } - else { - APR_BRIGADE_INSERT_TAIL(b, e); - } - } - - /* RFC 2616, Section 3.6.1 - * - * If there is an EOS bucket, then prefix it with: - * 1) the last-chunk marker ("0" CRLF) - * 2) the trailer - * 3) the end-of-chunked body CRLF - * - * If there is no EOS bucket, then do nothing. - * - * XXX: it would be nice to combine this with the end-of-chunk - * marker above, but this is a bit more straight-forward for - * now. - */ - if (eos != NULL) { - /* XXX: (2) trailers ... does not yet exist */ - e = apr_bucket_immortal_create(ASCII_ZERO ASCII_CRLF - /* */ - ASCII_CRLF, 5, c->bucket_alloc); - APR_BUCKET_INSERT_BEFORE(eos, e); - } - - /* pass the brigade to the next filter. */ - rv = ap_pass_brigade(f->next, b); - if (rv != APR_SUCCESS || eos != NULL) { - return rv; - } - } - return APR_SUCCESS; -} - static const char *http_method(const request_rec *r) { return "http"; } @@ -360,7 +229,7 @@ static void register_hooks(apr_pool_t *p) ap_register_output_filter("HTTP_HEADER", ap_http_header_filter, NULL, AP_FTYPE_PROTOCOL); ap_chunk_filter_handle = - ap_register_output_filter("CHUNK", chunk_filter, + ap_register_output_filter("CHUNK", ap_http_chunk_filter, NULL, AP_FTYPE_TRANSCODE); ap_byterange_filter_handle = ap_register_output_filter("BYTERANGE", ap_byterange_filter, diff --git a/modules/http/mod_core.h b/modules/http/mod_core.h index 790c36e76c..fa1a124752 100644 --- a/modules/http/mod_core.h +++ b/modules/http/mod_core.h @@ -44,6 +44,9 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes); +/* HTTP/1.1 chunked transfer encoding filter. */ +apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b); + char *ap_response_code_string(request_rec *r, int error_index); /**