]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
incoming trailers passed directly to request_rec, work independant of chunked encoding
authorStefan Eissing <icing@apache.org>
Mon, 14 Dec 2015 10:33:11 +0000 (10:33 +0000)
committerStefan Eissing <icing@apache.org>
Mon, 14 Dec 2015 10:33:11 +0000 (10:33 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1719876 13f79535-47bb-0310-9956-ffa450edef68

modules/http2/h2_h2.c
modules/http2/h2_io.c
modules/http2/h2_io.h
modules/http2/h2_mplx.c
modules/http2/h2_mplx.h
modules/http2/h2_task_input.c

index dee6f1e14937f9efc966365f089b2dc137dadbe1..20fbe30d1ed252750d9c1977886fae5dc190b433 100644 (file)
@@ -651,6 +651,8 @@ static int h2_h2_post_read_req(request_rec *r)
          * that we manipulate filters only once. */
         /* our slave connection? */
         if (task && !task->filters_set) {
+            ap_filter_t *f;
+            
             /* setup the correct output filters to process the response
              * on the proper mod_http2 way. */
             ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "adding task output filter");
@@ -663,6 +665,16 @@ static int h2_h2_post_read_req(request_rec *r)
                 ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER");
                 ap_add_output_filter("H2_RESPONSE", task, r, r->connection);
             }
+            
+            /* trailers processing. Incoming trailers are added to this
+             * request via our h2 input filter, outgoing trailers
+             * in a special h2 out filter. */
+            for (f = r->input_filters; f; f = f->next) {
+                if (!strcmp("H2_TO_H1", f->frec->name)) {
+                    f->r = r;
+                    break;
+                }
+            }
             ap_add_output_filter("H2_TRAILERS", task, r, r->connection);
             task->filters_set = 1;
         }
index 9e968286565acfab01c4ba949b4069fe12f35549..d3880797ed961a068cf0744b025d5e0366a58c64 100644 (file)
@@ -105,15 +105,23 @@ static int add_trailer(void *ctx, const char *key, const char *value)
     return (status == APR_SUCCESS);
 }
 
-static apr_status_t append_eos(h2_io *io, apr_bucket_brigade *bb)
+static apr_status_t append_eos(h2_io *io, apr_bucket_brigade *bb, 
+                               apr_table_t *trailers)
 {
     apr_status_t status = APR_SUCCESS;
+    apr_table_t *t = io->request->trailers;
+
+    if (trailers && t && !apr_is_empty_table(trailers)) {
+        /* trailers passed in, transfer directly. */
+        apr_table_overlap(trailers, t, APR_OVERLAP_TABLES_SET);
+        t = NULL;
+    }
     
     if (io->request->chunked) {
-        apr_table_t *trailers = io->request->trailers;
-        if (trailers && !apr_is_empty_table(trailers)) {
+        if (t && !apr_is_empty_table(t)) {
+            /* no trailers passed in, transfer via chunked */
             status = apr_brigade_puts(bb, NULL, NULL, "0\r\n");
-            apr_table_do(add_trailer, bb, trailers, NULL);
+            apr_table_do(add_trailer, bb, t, NULL);
             status = apr_brigade_puts(bb, NULL, NULL, "\r\n");
         }
         else {
@@ -125,7 +133,7 @@ static apr_status_t append_eos(h2_io *io, apr_bucket_brigade *bb)
 }
 
 apr_status_t h2_io_in_read(h2_io *io, apr_bucket_brigade *bb, 
-                           apr_size_t maxlen)
+                           apr_size_t maxlen, apr_table_t *trailers)
 {
     apr_off_t start_len = 0;
     apr_status_t status;
@@ -137,7 +145,7 @@ apr_status_t h2_io_in_read(h2_io *io, apr_bucket_brigade *bb,
     if (!io->bbin || APR_BRIGADE_EMPTY(io->bbin)) {
         if (io->eos_in) {
             if (!io->eos_in_written) {
-                status = append_eos(io, bb);
+                status = append_eos(io, bb, trailers);
                 io->eos_in_written = 1;
                 return status;
             }
index 6dd447421197c7075546cb4a97881547a9024cc3..c2ecbb912213ba6cb2b2263a0476177586fffaf3 100644 (file)
@@ -96,7 +96,7 @@ int h2_io_out_has_data(h2_io *io);
  * is currently available, APR_EOF if end of input has been reached.
  */
 apr_status_t h2_io_in_read(h2_io *io, apr_bucket_brigade *bb, 
-                           apr_size_t maxlen);
+                           apr_size_t maxlen, apr_table_t *trailers);
 
 /**
  * Appends given bucket to the input.
index 4c3d16dce97b449e28202d56f67db016324f8c23..9f50b8cb8bdfc0b7bc95b4faf73d3700b6fb9776 100644 (file)
@@ -339,7 +339,8 @@ void h2_mplx_task_done(h2_mplx *m, int stream_id)
 }
 
 apr_status_t h2_mplx_in_read(h2_mplx *m, apr_read_type_e block,
-                             int stream_id, apr_bucket_brigade *bb,
+                             int stream_id, apr_bucket_brigade *bb, 
+                             apr_table_t *trailers,
                              struct apr_thread_cond_t *iowait)
 {
     apr_status_t status; 
@@ -353,7 +354,7 @@ apr_status_t h2_mplx_in_read(h2_mplx *m, apr_read_type_e block,
         if (io && !io->orphaned) {
             io->input_arrived = iowait;
             H2_MPLX_IO_IN(APLOG_TRACE2, m, io, "h2_mplx_in_read_pre");
-            status = h2_io_in_read(io, bb, -1);
+            status = h2_io_in_read(io, bb, -1, trailers);
             while (APR_STATUS_IS_EAGAIN(status) 
                    && !is_aborted(m, &status)
                    && block == APR_BLOCK_READ) {
@@ -361,7 +362,7 @@ apr_status_t h2_mplx_in_read(h2_mplx *m, apr_read_type_e block,
                               "h2_mplx(%ld-%d): wait on in data (BLOCK_READ)", 
                               m->id, stream_id);
                 apr_thread_cond_wait(io->input_arrived, m->lock);
-                status = h2_io_in_read(io, bb, -1);
+                status = h2_io_in_read(io, bb, -1, trailers);
             }
             H2_MPLX_IO_IN(APLOG_TRACE2, m, io, "h2_mplx_in_read_post");
             io->input_arrived = NULL;
index f2805be373a1fb5866e3f88e97a146ac246a703e..4c577d0f768e26d80adee7246e024230c627d935 100644 (file)
@@ -206,6 +206,7 @@ void h2_mplx_set_consumed_cb(h2_mplx *m, h2_mplx_consumed_cb *cb, void *ctx);
  */
 apr_status_t h2_mplx_in_read(h2_mplx *m, apr_read_type_e block,
                              int stream_id, apr_bucket_brigade *bb,
+                             apr_table_t *trailers, 
                              struct apr_thread_cond_t *iowait);
 
 /**
index 863480c85896c8f9135a19b0861bb127e6d76728..921d03394e7bcda20c2bdc489d095681301f5093 100644 (file)
@@ -135,6 +135,7 @@ apr_status_t h2_task_input_read(h2_task_input *input,
          never calling us again. */
         status = h2_mplx_in_read(input->task->mplx, APR_BLOCK_READ,
                                  input->task->stream_id, input->bb, 
+                                 f->r? f->r->trailers_in : NULL, 
                                  input->task->io);
         ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, f->c,
                       "h2_task_input(%s): mplx in read returned",