diff options
author | Stefan Eissing <icing@apache.org> | 2022-04-04 11:08:58 +0000 |
---|---|---|
committer | Stefan Eissing <icing@apache.org> | 2022-04-04 11:08:58 +0000 |
commit | dc18031936ae3c7b98ea1305ce24dc537aecb596 (patch) | |
tree | 9efeeface0c982ac9b59f98424c16a7385381713 /modules/http | |
parent | cc232ba4549b1c47b5e4c944e6040e11563bafad (diff) | |
download | httpd-dc18031936ae3c7b98ea1305ce24dc537aecb596.tar.gz |
*) mod_http: genereate HEADERS buckets for trailers
mod_proxy: forward trailers on chunked request encoding
test: add http/1.x test cases in pytest
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1899552 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/http')
-rw-r--r-- | modules/http/http_filters.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index 9bcf2297d0..0a9ff425ea 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -1312,6 +1312,15 @@ AP_DECLARE_NONSTD(int) ap_send_http_trace(request_rec *r) return DONE; } +static apr_bucket *create_trailers_bucket(request_rec *r, apr_bucket_alloc_t *bucket_alloc) +{ + if (r->trailers_out && !apr_is_empty_table(r->trailers_out)) { + ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "sending trailers"); + return ap_bucket_headers_create(r->trailers_out, r->pool, bucket_alloc); + } + return NULL; +} + typedef struct header_filter_ctx { int headers_sent; } header_filter_ctx; @@ -1323,7 +1332,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, conn_rec *c = r->connection; int header_only = (r->header_only || AP_STATUS_IS_HEADER_ONLY(r->status)); const char *protocol = NULL; - apr_bucket *e; + apr_bucket *e, *eos = NULL; apr_bucket_brigade *b2; header_struct h; header_filter_ctx *ctx = f->ctx; @@ -1364,6 +1373,10 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, eb = e->data; continue; } + if (APR_BUCKET_IS_EOS(e)) { + if (!eos) eos = e; + continue; + } /* * If we see an EOC bucket it is a signal that we should get out * of the way doing nothing. @@ -1416,6 +1429,22 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, goto out; } + if (eos) { + /* on having seen EOS and added possible trailers, we + * can remove this filter. + */ + e = create_trailers_bucket(r, b->bucket_alloc); + if (e) { + APR_BUCKET_INSERT_BEFORE(eos, e); + } + ap_remove_output_filter(f); + } + + if (ctx->headers_sent) { + /* we did already the stuff below, just pass on */ + return ap_pass_brigade(f->next, b); + } + /* * Now that we are ready to send a response, we need to combine the two * header field tables into a single table. If we don't do this, our @@ -1545,11 +1574,6 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, ap_add_output_filter("CHUNK", NULL, r, r->connection); } - /* Don't remove this filter until after we have added the CHUNK filter. - * Otherwise, f->next won't be the CHUNK filter and thus the first - * brigade won't be chunked properly. - */ - ap_remove_output_filter(f); rv = ap_pass_brigade(f->next, b); out: if (recursive_error) { |