You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2016/09/07 06:44:17 UTC

svn commit: r1759547 - in /httpd/httpd/trunk/modules/http2: NWGNUmod_http2 h2.h h2_mplx.c h2_push.c h2_request.c h2_request.h h2_response.c h2_session.c h2_stream.c h2_stream.h h2_task.c h2_util.c h2_util.h

Author: icing
Date: Wed Sep  7 06:44:16 2016
New Revision: 1759547

URL: http://svn.apache.org/viewvc?rev=1759547&view=rev
Log:
mod_http2: more const goodiness and checks on h2 request creation, less NULL checking while processing

Modified:
    httpd/httpd/trunk/modules/http2/NWGNUmod_http2
    httpd/httpd/trunk/modules/http2/h2.h
    httpd/httpd/trunk/modules/http2/h2_mplx.c
    httpd/httpd/trunk/modules/http2/h2_push.c
    httpd/httpd/trunk/modules/http2/h2_request.c
    httpd/httpd/trunk/modules/http2/h2_request.h
    httpd/httpd/trunk/modules/http2/h2_response.c
    httpd/httpd/trunk/modules/http2/h2_session.c
    httpd/httpd/trunk/modules/http2/h2_stream.c
    httpd/httpd/trunk/modules/http2/h2_stream.h
    httpd/httpd/trunk/modules/http2/h2_task.c
    httpd/httpd/trunk/modules/http2/h2_util.c
    httpd/httpd/trunk/modules/http2/h2_util.h

Modified: httpd/httpd/trunk/modules/http2/NWGNUmod_http2
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/NWGNUmod_http2?rev=1759547&r1=1759546&r2=1759547&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/NWGNUmod_http2 (original)
+++ httpd/httpd/trunk/modules/http2/NWGNUmod_http2 Wed Sep  7 06:44:16 2016
@@ -370,7 +370,6 @@ $(OBJDIR)/mod_http2.imp : NWGNUmod_http2
 	@echo $(DL) h2_headers_add_h1,$(DL) >> $@
 	@echo $(DL) h2_req_create,$(DL) >> $@
 	@echo $(DL) h2_req_createn,$(DL) >> $@
-	@echo $(DL) h2_req_make,$(DL) >> $@
 	@echo $(DL) h2_util_camel_case_header,$(DL) >> $@
 	@echo $(DL) h2_util_frame_print,$(DL) >> $@
 	@echo $(DL) h2_util_ngheader_make_req,$(DL) >> $@

Modified: httpd/httpd/trunk/modules/http2/h2.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2.h?rev=1759547&r1=1759546&r2=1759547&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2.h (original)
+++ httpd/httpd/trunk/modules/http2/h2.h Wed Sep  7 06:44:16 2016
@@ -130,7 +130,6 @@ struct h2_request {
     apr_off_t content_length;
     
     unsigned int chunked : 1; /* iff requst body needs to be forwarded as chunked */
-    unsigned int eoh     : 1; /* iff end-of-headers has been seen and request is complete */
     unsigned int body    : 1; /* iff this request has a body */
     unsigned int serialize : 1; /* iff this request is written in HTTP/1.1 serialization */
     unsigned int push_policy; /* which push policy to use for this request */

Modified: httpd/httpd/trunk/modules/http2/h2_mplx.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_mplx.c?rev=1759547&r1=1759546&r2=1759547&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_mplx.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_mplx.c Wed Sep  7 06:44:16 2016
@@ -512,7 +512,7 @@ static int task_print(void *ctx, void *v
     h2_mplx *m = ctx;
     h2_task *task = val;
 
-    if (task && task->request) {
+    if (task) {
         h2_stream *stream = h2_ihash_get(m->streams, task->stream_id);
 
         ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c, /* NO APLOGNO */

Modified: httpd/httpd/trunk/modules/http2/h2_push.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_push.c?rev=1759547&r1=1759546&r2=1759547&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_push.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_push.c Wed Sep  7 06:44:16 2016
@@ -346,9 +346,9 @@ static int add_push(link_ctx *ctx)
                 }
                 headers = apr_table_make(ctx->pool, 5);
                 apr_table_do(set_push_header, headers, ctx->req->headers, NULL);
-                req = h2_req_createn(0, ctx->pool, method, ctx->req->scheme,
-                                     ctx->req->authority, path, headers,
-                                     ctx->req->serialize);
+                req = h2_req_create(0, ctx->pool, method, ctx->req->scheme,
+                                    ctx->req->authority, path, headers,
+                                    ctx->req->serialize);
                 /* atm, we do not push on pushes */
                 h2_request_end_headers(req, ctx->pool, 1, 0);
                 push->req = req;

Modified: httpd/httpd/trunk/modules/http2/h2_request.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_request.c?rev=1759547&r1=1759546&r2=1759547&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_request.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_request.c Wed Sep  7 06:44:16 2016
@@ -30,6 +30,7 @@
 #include <scoreboard.h>
 
 #include "h2_private.h"
+#include "h2_config.h"
 #include "h2_push.h"
 #include "h2_request.h"
 #include "h2_util.h"
@@ -42,15 +43,39 @@ static apr_status_t inspect_clen(h2_requ
     return (s == end)? APR_EINVAL : APR_SUCCESS;
 }
 
-apr_status_t h2_request_rwrite(h2_request *req, apr_pool_t *pool, 
-                               request_rec *r)
+typedef struct {
+    apr_table_t *headers;
+    apr_pool_t *pool;
+} h1_ctx;
+
+static int set_h1_header(void *ctx, const char *key, const char *value)
+{
+    h1_ctx *x = ctx;
+    size_t klen = strlen(key);
+    if (!h2_req_ignore_header(key, klen)) {
+        h2_headers_add_h1(x->headers, x->pool, key, klen, value, strlen(value));
+    }
+    return 1;
+}
+
+apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool, 
+                                int stream_id, int initiated_on,
+                                request_rec *r)
 {
-    apr_status_t status;
-    const char *scheme, *authority;
+    h2_request *req;
+    const char *scheme, *authority, *path;
+    h1_ctx x;
     
+    *preq = NULL;
     scheme = apr_pstrdup(pool, r->parsed_uri.scheme? r->parsed_uri.scheme
               : ap_http_scheme(r));
-    authority = (r->hostname ? apr_pstrdup(pool, r->hostname) : "");
+    authority = apr_pstrdup(pool, r->hostname);
+    path = apr_uri_unparse(pool, &r->parsed_uri, APR_URI_UNP_OMITSITEPART);
+    
+    if (!r->method || !scheme || !r->hostname || !path) {
+        return APR_EINVAL;
+    }
+
     if (!ap_strchr_c(authority, ':') && r->server && r->server->port) {
         apr_port_t defport = apr_uri_port_of_scheme(scheme);
         if (defport != r->server->port) {
@@ -60,11 +85,25 @@ apr_status_t h2_request_rwrite(h2_reques
         }
     }
     
-    status = h2_req_make(req, pool, apr_pstrdup(pool, r->method), scheme, 
-                         authority, apr_uri_unparse(pool, &r->parsed_uri, 
-                                                    APR_URI_UNP_OMITSITEPART),
-                         r->headers_in);
-    return status;
+    req = apr_pcalloc(pool, sizeof(*req));
+    req->id = stream_id;
+    req->initiated_on = initiated_on;
+    req->method    = apr_pstrdup(pool, r->method);
+    req->scheme    = scheme;
+    req->authority = authority;
+    req->path      = path;
+    req->headers   = apr_table_make(pool, 10);
+    if (r->server) {
+        req->serialize = h2_config_geti(h2_config_sget(r->server), 
+                                        H2_CONF_SER_HEADERS);
+    }
+
+    x.pool = pool;
+    x.headers = req->headers;
+    apr_table_do(set_h1_header, &x, r->headers_in, NULL);
+    
+    *preq = req;
+    return APR_SUCCESS;
 }
 
 apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool, 
@@ -126,11 +165,6 @@ apr_status_t h2_request_end_headers(h2_r
 {
     const char *s;
     
-    if (req->eoh) {
-        /* already done */
-        return APR_SUCCESS;
-    }
-
     /* rfc7540, ch. 8.1.2.3:
      * - if we have :authority, it overrides any Host header 
      * - :authority MUST be ommited when converting h1->h2, so we
@@ -155,11 +189,13 @@ apr_status_t h2_request_end_headers(h2_r
                           req->id, s);
             return APR_EINVAL;
         }
+        req->body = 1;
     }
     else {
         /* no content-length given */
         req->content_length = -1;
-        if (!eos) {
+        req->body = !eos;
+        if (req->body) {
             /* We have not seen a content-length and have no eos,
              * simulate a chunked encoding for our HTTP/1.1 infrastructure,
              * in case we have "H2SerializeHeaders on" here
@@ -175,7 +211,6 @@ apr_status_t h2_request_end_headers(h2_r
         }
     }
 
-    req->eoh = 1;
     h2_push_policy_determine(req, pool, push);
     
     /* In the presence of trailers, force behaviour of chunked encoding */

Modified: httpd/httpd/trunk/modules/http2/h2_request.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_request.h?rev=1759547&r1=1759546&r2=1759547&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_request.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_request.h Wed Sep  7 06:44:16 2016
@@ -18,8 +18,9 @@
 
 #include "h2.h"
 
-apr_status_t h2_request_rwrite(h2_request *req, apr_pool_t *pool, 
-                               request_rec *r);
+apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool, 
+                                int stream_id, int initiated_on,
+                                request_rec *r);
 
 apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool,
                                    const char *name, size_t nlen,

Modified: httpd/httpd/trunk/modules/http2/h2_response.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_response.c?rev=1759547&r1=1759546&r2=1759547&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_response.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_response.c Wed Sep  7 06:44:16 2016
@@ -174,7 +174,7 @@ h2_response *h2_response_die(int stream_
     int status = (type >= 200 && type < 600)? type : 500;
     
     date = apr_palloc(pool, APR_RFC822_DATE_LEN);
-    ap_recent_rfc822_date(date, req->request_time);
+    ap_recent_rfc822_date(date, req? req->request_time : apr_time_now());
     apr_table_setn(headers, "Date", date);
     apr_table_setn(headers, "Server", ap_get_server_banner());
     

Modified: httpd/httpd/trunk/modules/http2/h2_session.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_session.c?rev=1759547&r1=1759546&r2=1759547&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_session.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_session.c Wed Sep  7 06:44:16 2016
@@ -143,10 +143,14 @@ h2_stream *h2_session_open_stream(h2_ses
     apr_pool_tag(stream_pool, "h2_stream");
     
     stream = h2_stream_open(stream_id, stream_pool, session, 
-                            initiated_on, req);
+                            initiated_on);
     nghttp2_session_set_stream_user_data(session->ngh2, stream_id, stream);
     h2_ihash_add(session->streams, stream);
     
+    if (req) {
+        h2_stream_set_request(stream, req);
+    }
+    
     if (H2_STREAM_CLIENT_INITIATED(stream_id)) {
         if (stream_id > session->remote.emitted_max) {
             ++session->remote.emitted_count;
@@ -500,7 +504,7 @@ static int on_frame_recv_cb(nghttp2_sess
                           session->id, (int)frame->hd.stream_id,
                           (int)frame->rst_stream.error_code);
             stream = get_stream(session, frame->hd.stream_id);
-            if (stream && stream->request && stream->request->initiated_on) {
+            if (stream && stream->initiated_on) {
                 ++session->pushes_reset;
             }
             else {
@@ -1078,7 +1082,7 @@ static apr_status_t h2_session_start(h2_
             return status;
         }
         
-        status = h2_stream_set_request(stream, session->r);
+        status = h2_stream_set_request_rec(stream, session->r);
         if (status != APR_SUCCESS) {
             return status;
         }
@@ -1508,8 +1512,7 @@ static apr_status_t on_stream_response(v
          *    as the client, having this resource in its cache, might
          *    also have the pushed ones as well.
          */
-        if (stream->request 
-            && !stream->request->initiated_on
+        if (!stream->initiated_on
             && h2_response_is_final(response)
             && H2_HTTP_2XX(response->http_status)
             && h2_session_push_enabled(session)) {
@@ -1529,7 +1532,7 @@ static apr_status_t on_stream_response(v
         stream->submitted = h2_response_is_final(response);
         session->have_written = 1;
         
-        if (stream->request && stream->request->initiated_on) {
+        if (stream->initiated_on) {
             ++session->pushes_submitted;
         }
         else {

Modified: httpd/httpd/trunk/modules/http2/h2_stream.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_stream.c?rev=1759547&r1=1759546&r2=1759547&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_stream.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_stream.c Wed Sep  7 06:44:16 2016
@@ -175,30 +175,18 @@ static apr_status_t stream_pool_cleanup(
 }
 
 h2_stream *h2_stream_open(int id, apr_pool_t *pool, h2_session *session,
-                          int initiated_on, const h2_request *creq)
+                          int initiated_on)
 {
-    h2_request *req;
     h2_stream *stream = apr_pcalloc(pool, sizeof(h2_stream));
     
-    stream->id        = id;
-    stream->created   = apr_time_now();
-    stream->state     = H2_STREAM_ST_IDLE;
-    stream->pool      = pool;
-    stream->session   = session;
-    set_state(stream, H2_STREAM_ST_OPEN);
-    
-    if (creq) {
-        /* take it into out pool and assure correct id's */
-        req = h2_request_clone(pool, creq);
-        req->id = id;
-        req->initiated_on = initiated_on;
-    }
-    else {
-        req = h2_req_create(id, pool, 
-                h2_config_geti(session->config, H2_CONF_SER_HEADERS));
-    }
-    stream->request = req; 
+    stream->id           = id;
+    stream->initiated_on = initiated_on;
+    stream->created      = apr_time_now();
+    stream->state        = H2_STREAM_ST_IDLE;
+    stream->pool         = pool;
+    stream->session      = session;
     
+    set_state(stream, H2_STREAM_ST_OPEN);
     apr_pool_cleanup_register(pool, stream, stream_pool_cleanup, 
                               apr_pool_cleanup_null);
     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03082)
@@ -276,31 +264,40 @@ struct h2_response *h2_stream_get_unsent
     return unsent;
 }
 
-apr_status_t h2_stream_set_request(h2_stream *stream, request_rec *r)
+apr_status_t h2_stream_set_request_rec(h2_stream *stream, request_rec *r)
 {
+    h2_request *req;
     apr_status_t status;
-    AP_DEBUG_ASSERT(stream);
+
+    ap_assert(stream->request == NULL);
+    ap_assert(stream->rtmp == NULL);
     if (stream->rst_error) {
         return APR_ECONNRESET;
     }
-    set_state(stream, H2_STREAM_ST_OPEN);
-    status = h2_request_rwrite(stream->request, stream->pool, r);
-    stream->request->serialize = h2_config_geti(h2_config_sget(r->server), 
-                                                H2_CONF_SER_HEADERS);
+    status = h2_request_rcreate(&req, stream->pool, stream->id,
+                                stream->initiated_on, r);
     ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(03058)
-                  "h2_request(%d): rwrite %s host=%s://%s%s",
-                  stream->request->id, stream->request->method, 
-                  stream->request->scheme, stream->request->authority, 
-                  stream->request->path);
-
+                  "h2_request(%d): set_request_rec %s host=%s://%s%s",
+                  stream->id, req->method, req->scheme, req->authority, 
+                  req->path);
+    stream->rtmp = req;
     return status;
 }
 
+apr_status_t h2_stream_set_request(h2_stream *stream, const h2_request *r)
+{
+    ap_assert(stream->request == NULL);
+    ap_assert(stream->rtmp == NULL);
+    stream->rtmp = h2_request_clone(stream->pool, r);
+    return APR_SUCCESS;
+}
+
 apr_status_t h2_stream_add_header(h2_stream *stream,
                                   const char *name, size_t nlen,
                                   const char *value, size_t vlen)
 {
     AP_DEBUG_ASSERT(stream);
+    
     if (!stream->response) {
         if (name[0] == ':') {
             if ((vlen) > stream->session->s->limit_req_line) {
@@ -336,14 +333,20 @@ apr_status_t h2_stream_add_header(h2_str
     }
     
     if (h2_stream_is_scheduled(stream)) {
-        return h2_request_add_trailer(stream->request, stream->pool,
+        /* FIXME: this is not clean. we modify a struct that is being processed
+         * by another thread potentially. */
+        return h2_request_add_trailer((h2_request*)stream->request, stream->pool,
                                       name, nlen, value, vlen);
     }
     else {
-        if (!input_open(stream)) {
+        if (!stream->rtmp) {
+            stream->rtmp = h2_req_create(stream->id, stream->pool, 
+                                         NULL, NULL, NULL, NULL, NULL, 0);
+        }
+        if (stream->state != H2_STREAM_ST_OPEN) {
             return APR_ECONNRESET;
         }
-        return h2_request_add_header(stream->request, stream->pool,
+        return h2_request_add_header(stream->rtmp, stream->pool,
                                      name, nlen, value, vlen);
     }
 }
@@ -351,52 +354,59 @@ apr_status_t h2_stream_add_header(h2_str
 apr_status_t h2_stream_schedule(h2_stream *stream, int eos, int push_enabled, 
                                 h2_stream_pri_cmp *cmp, void *ctx)
 {
-    apr_status_t status;
+    apr_status_t status = APR_EINVAL;
     AP_DEBUG_ASSERT(stream);
     AP_DEBUG_ASSERT(stream->session);
     AP_DEBUG_ASSERT(stream->session->mplx);
     
-    if (!output_open(stream)) {
-        return APR_ECONNRESET;
-    }
-    if (stream->scheduled) {
-        return APR_EINVAL;
-    }
-    if (eos) {
-        close_input(stream);
-    }
-    
-    if (stream->response) {
-        /* already have a resonse, probably a HTTP error code */
-        return h2_mplx_process(stream->session->mplx, stream, cmp, ctx);
-    }
-    
-    /* Seeing the end-of-headers, we have everything we need to 
-     * start processing it.
-     */
-    status = h2_request_end_headers(stream->request, stream->pool, 
-                                    eos, push_enabled);
-    if (status == APR_SUCCESS) {
-        stream->request->body = !eos;
-        stream->scheduled = 1;
-        stream->input_remaining = stream->request->content_length;
+    if (!stream->scheduled) {
+        if (eos) {
+            close_input(stream);
+        }
         
-        status = h2_mplx_process(stream->session->mplx, stream, cmp, ctx);
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->session->c,
-                      "h2_stream(%ld-%d): scheduled %s %s://%s%s",
-                      stream->session->id, stream->id,
-                      stream->request->method, stream->request->scheme,
-                      stream->request->authority, stream->request->path);
-    }
-    else {
-        h2_stream_rst(stream, H2_ERR_INTERNAL_ERROR);
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, stream->session->c,
-                      "h2_stream(%ld-%d): RST=2 (internal err) %s %s://%s%s",
-                      stream->session->id, stream->id,
-                      stream->request->method, stream->request->scheme,
-                      stream->request->authority, stream->request->path);
+        if (stream->response) {
+            /* already have a resonse, probably a HTTP error code */
+            return h2_mplx_process(stream->session->mplx, stream, cmp, ctx);
+        }
+        else if (!stream->request && stream->rtmp) {
+            /* This is the common case: a h2_request was being assembled, now
+             * it gets finalized and checked for completness */
+            status = h2_request_end_headers(stream->rtmp, stream->pool, 
+                                            eos, push_enabled);
+            if (status == APR_SUCCESS) {
+                stream->rtmp->id = stream->id;
+                stream->rtmp->initiated_on = stream->initiated_on;
+                stream->rtmp->serialize = h2_config_geti(stream->session->config,
+                                                         H2_CONF_SER_HEADERS); 
+
+                stream->request = stream->rtmp;
+                stream->rtmp = NULL;
+                stream->scheduled = 1;
+                stream->input_remaining = stream->request->content_length;
+                
+                status = h2_mplx_process(stream->session->mplx, stream, cmp, ctx);
+                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->session->c,
+                              "h2_stream(%ld-%d): scheduled %s %s://%s%s "
+                              "clen=%ld, body=%d, chunked=%d",
+                              stream->session->id, stream->id,
+                              stream->request->method, stream->request->scheme,
+                              stream->request->authority, stream->request->path,
+                              (long)stream->request->content_length,
+                              stream->request->body, stream->request->chunked);
+                return status;
+            }
+        }
+        else {
+            status = APR_ECONNRESET;
+        }
     }
     
+    h2_stream_rst(stream, H2_ERR_INTERNAL_ERROR);
+    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, stream->session->c,
+                  "h2_stream(%ld-%d): RST=2 (internal err) %s %s://%s%s",
+                  stream->session->id, stream->id,
+                  stream->request->method, stream->request->scheme,
+                  stream->request->authority, stream->request->path);
     return status;
 }
 
@@ -435,11 +445,11 @@ apr_status_t h2_stream_write_data(h2_str
     if (!stream->input) {
         return APR_EOF;
     }
-    if (input_closed(stream) || !stream->request->eoh) {
+    if (input_closed(stream) || !stream->request) {
         ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
                       "h2_stream(%ld-%d): writing denied, closed=%d, eoh=%d", 
                       stream->session->id, stream->id, input_closed(stream),
-                      stream->request->eoh);
+                      stream->request != NULL);
         return APR_EINVAL;
     }
 
@@ -583,8 +593,12 @@ apr_status_t h2_stream_set_error(h2_stre
     if (stream->submitted) {
         return APR_EINVAL;
     }
-    response = h2_response_die(stream->id, http_status, stream->request, 
-                               stream->pool);
+    if (stream->rtmp) {
+        stream->request = stream->rtmp;
+        stream->rtmp = NULL;
+    }
+    response = h2_response_die(stream->id, http_status, 
+                               stream->request, stream->pool);
     return h2_stream_add_response(stream, response, NULL);
 }
 
@@ -714,7 +728,7 @@ apr_table_t *h2_stream_get_trailers(h2_s
 
 const h2_priority *h2_stream_get_priority(h2_stream *stream)
 {
-    if (stream->response && stream->request && stream->request->initiated_on) {
+    if (stream->response && stream->initiated_on) {
         const char *ctype = apr_table_get(stream->response->headers, "content-type");
         if (ctype) {
             /* FIXME: Not good enough, config needs to come from request->server */

Modified: httpd/httpd/trunk/modules/http2/h2_stream.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_stream.h?rev=1759547&r1=1759546&r2=1759547&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_stream.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_stream.h Wed Sep  7 06:44:16 2016
@@ -43,12 +43,14 @@ typedef struct h2_stream h2_stream;
 
 struct h2_stream {
     int id;                     /* http2 stream id */
+    int initiated_on;           /* initiating stream id (PUSH) or 0 */
     apr_time_t created;         /* when stream was created */
     h2_stream_state_t state;    /* http/2 state of this stream */
     struct h2_session *session; /* the session this stream belongs to */
     
     apr_pool_t *pool;           /* the memory pool for this stream */
-    struct h2_request *request; /* the request made in this stream */
+    const struct h2_request *request; /* the request made in this stream */
+    struct h2_request *rtmp;    /* request being assembled */
     struct h2_bucket_beam *input;
     int request_headers_added;  /* number of request headers added */
     
@@ -83,7 +85,7 @@ struct h2_stream {
  * @return the newly opened stream
  */
 h2_stream *h2_stream_open(int id, apr_pool_t *pool, struct h2_session *session,
-                          int initiated_on, const struct h2_request *req);
+                          int initiated_on);
 
 /**
  * Cleanup any resources still held by the stream, called by last bucket.
@@ -111,6 +113,13 @@ void h2_stream_cleanup(h2_stream *stream
  */
 apr_pool_t *h2_stream_detach_pool(h2_stream *stream);
 
+/**
+ * Initialize stream->request with the given h2_request.
+ * 
+ * @param stream stream to write request to
+ * @param r the request with all the meta data
+ */
+apr_status_t h2_stream_set_request(h2_stream *stream, const h2_request *r);
 
 /**
  * Initialize stream->request with the given request_rec.
@@ -118,7 +127,7 @@ apr_pool_t *h2_stream_detach_pool(h2_str
  * @param stream stream to write request to
  * @param r the request with all the meta data
  */
-apr_status_t h2_stream_set_request(h2_stream *stream, request_rec *r);
+apr_status_t h2_stream_set_request_rec(h2_stream *stream, request_rec *r);
 
 /*
  * Add a HTTP/2 header (including pseudo headers) or trailer 

Modified: httpd/httpd/trunk/modules/http2/h2_task.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_task.c?rev=1759547&r1=1759546&r2=1759547&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_task.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_task.c Wed Sep  7 06:44:16 2016
@@ -89,7 +89,7 @@ static apr_status_t input_handle_eos(h2_
 {
     apr_status_t status = APR_SUCCESS;
     apr_bucket_brigade *bb = task->input.bb;
-    apr_table_t *t = task->request? task->request->trailers : NULL;
+    apr_table_t *t = task->request->trailers;
 
     if (task->input.chunked) {
         apr_bucket_brigade *tmp = apr_brigade_split_ex(bb, b, NULL);
@@ -116,7 +116,7 @@ static apr_status_t input_append_eos(h2_
 {
     apr_status_t status = APR_SUCCESS;
     apr_bucket_brigade *bb = task->input.bb;
-    apr_table_t *t = task->request? task->request->trailers : NULL;
+    apr_table_t *t = task->request->trailers;
 
     if (task->input.chunked) {
         if (t && !apr_is_empty_table(t)) {
@@ -153,7 +153,7 @@ static apr_status_t input_read(h2_task *
         return ap_get_brigade(f->c->input_filters, bb, mode, block, readbytes);
     }
     
-    if (f->c->aborted || !task->request) {
+    if (f->c->aborted) {
         return APR_ECONNABORTED;
     }
     
@@ -578,8 +578,7 @@ apr_status_t h2_task_add_response(h2_tas
 
 int h2_task_can_redo(h2_task *task) {
     if (task->response_sent
-        || (task->input.beam && h2_beam_was_received(task->input.beam)) 
-        || !task->request) {
+        || (task->input.beam && h2_beam_was_received(task->input.beam))) {
         /* cannot repeat that. */
         return 0;
     }
@@ -683,6 +682,10 @@ h2_task *h2_task_create(conn_rec *c, con
     apr_pool_t *pool;
     h2_task *task;
     
+    ap_assert(mplx);
+    ap_assert(c);
+    ap_assert(req);
+
     apr_pool_create(&pool, c->pool);
     task = apr_pcalloc(pool, sizeof(h2_task));
     if (task == NULL) {
@@ -691,7 +694,6 @@ h2_task *h2_task_create(conn_rec *c, con
                       c->id, req->id);
         return NULL;
     }
-    
     task->id          = apr_psprintf(pool, "%ld-%d", c->id, req->id);
     task->stream_id   = req->id;
     task->c           = c;

Modified: httpd/httpd/trunk/modules/http2/h2_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_util.c?rev=1759547&r1=1759546&r2=1759547&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_util.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_util.c Wed Sep  7 06:44:16 2016
@@ -1276,9 +1276,9 @@ apr_status_t h2_headers_add_h1(apr_table
  * h2 request handling
  ******************************************************************************/
 
-h2_request *h2_req_createn(int id, apr_pool_t *pool, const char *method, 
-                           const char *scheme, const char *authority, 
-                           const char *path, apr_table_t *header, int serialize)
+h2_request *h2_req_create(int id, apr_pool_t *pool, const char *method, 
+                          const char *scheme, const char *authority, 
+                          const char *path, apr_table_t *header, int serialize)
 {
     h2_request *req = apr_pcalloc(pool, sizeof(h2_request));
     
@@ -1294,49 +1294,6 @@ h2_request *h2_req_createn(int id, apr_p
     return req;
 }
 
-h2_request *h2_req_create(int id, apr_pool_t *pool, int serialize)
-{
-    return h2_req_createn(id, pool, NULL, NULL, NULL, NULL, NULL, serialize);
-}
-
-typedef struct {
-    apr_table_t *headers;
-    apr_pool_t *pool;
-} h1_ctx;
-
-static int set_h1_header(void *ctx, const char *key, const char *value)
-{
-    h1_ctx *x = ctx;
-    size_t klen = strlen(key);
-    if (!h2_req_ignore_header(key, klen)) {
-        h2_headers_add_h1(x->headers, x->pool, key, klen, value, strlen(value));
-    }
-    return 1;
-}
-
-apr_status_t h2_req_make(h2_request *req, apr_pool_t *pool,
-                         const char *method, const char *scheme, 
-                         const char *authority, const char *path, 
-                         apr_table_t *headers)
-{
-    h1_ctx x;
-
-    req->method    = method;
-    req->scheme    = scheme;
-    req->authority = authority;
-    req->path      = path;
-
-    AP_DEBUG_ASSERT(req->scheme);
-    AP_DEBUG_ASSERT(req->authority);
-    AP_DEBUG_ASSERT(req->path);
-    AP_DEBUG_ASSERT(req->method);
-
-    x.pool = pool;
-    x.headers = req->headers;
-    apr_table_do(set_h1_header, &x, headers, NULL);
-    return APR_SUCCESS;
-}
-
 /*******************************************************************************
  * frame logging
  ******************************************************************************/

Modified: httpd/httpd/trunk/modules/http2/h2_util.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_util.h?rev=1759547&r1=1759546&r2=1759547&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_util.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_util.h Wed Sep  7 06:44:16 2016
@@ -261,16 +261,10 @@ apr_status_t h2_headers_add_h1(apr_table
  * h2_request helpers
  ******************************************************************************/
 
-struct h2_request *h2_req_createn(int id, apr_pool_t *pool, const char *method, 
-                                  const char *scheme, const char *authority, 
-                                  const char *path, apr_table_t *header,
-                                  int serialize);
-struct h2_request *h2_req_create(int id, apr_pool_t *pool, int serialize);
-
-apr_status_t h2_req_make(struct h2_request *req, apr_pool_t *pool,
-                         const char *method, const char *scheme, 
-                         const char *authority, const char *path, 
-                         apr_table_t *headers);
+struct h2_request *h2_req_create(int id, apr_pool_t *pool, const char *method, 
+                                 const char *scheme, const char *authority, 
+                                 const char *path, apr_table_t *header,
+                                 int serialize);
 
 /*******************************************************************************
  * apr brigade helpers