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 2019/03/07 09:41:15 UTC

svn commit: r1854963 - in /httpd/httpd/trunk: ./ modules/http2/

Author: icing
Date: Thu Mar  7 09:41:15 2019
New Revision: 1854963

URL: http://svn.apache.org/viewvc?rev=1854963&view=rev
Log:
  *) mod_http2: new configuration directive: ```H2Padding numbits``` to control 
     padding of HTTP/2 payload frames. 'numbits' is a number from 0-8,
     controlling the range of padding bytes added to a frame. The actual number
     added is chosen randomly per frame. This applies to HEADERS, DATA and PUSH_PROMISE
     frames equally. The default continues to be 0, e.g. no padding. [Stefan Eissing] 
  
  *) mod_http2: ripping out all the h2_req_engine internal features now that mod_proxy_http2
     has no more need for it. Optional functions are still declared but no longer implemented.
     While previous mod_proxy_http2 will work with this, it is recommeneded to run the matching
     versions of both modules. [Stefan Eissing]
  
  *) mod_proxy_http2: changed mod_proxy_http2 implementation and fixed several bugs which
     resolve PR63170. The proxy module does now a single h2 request on the (reused)
     connection and returns. [Stefan Eissing]


Removed:
    httpd/httpd/trunk/modules/http2/h2_ngn_shed.c
    httpd/httpd/trunk/modules/http2/h2_ngn_shed.h
Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/modules/http2/config2.m4
    httpd/httpd/trunk/modules/http2/h2.h
    httpd/httpd/trunk/modules/http2/h2_config.c
    httpd/httpd/trunk/modules/http2/h2_config.h
    httpd/httpd/trunk/modules/http2/h2_conn_io.c
    httpd/httpd/trunk/modules/http2/h2_mplx.c
    httpd/httpd/trunk/modules/http2/h2_mplx.h
    httpd/httpd/trunk/modules/http2/h2_proxy_session.c
    httpd/httpd/trunk/modules/http2/h2_proxy_session.h
    httpd/httpd/trunk/modules/http2/h2_request.c
    httpd/httpd/trunk/modules/http2/h2_session.c
    httpd/httpd/trunk/modules/http2/h2_session.h
    httpd/httpd/trunk/modules/http2/h2_stream.c
    httpd/httpd/trunk/modules/http2/h2_task.c
    httpd/httpd/trunk/modules/http2/h2_task.h
    httpd/httpd/trunk/modules/http2/h2_version.h
    httpd/httpd/trunk/modules/http2/mod_http2.c
    httpd/httpd/trunk/modules/http2/mod_http2.h
    httpd/httpd/trunk/modules/http2/mod_proxy_http2.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Thu Mar  7 09:41:15 2019
@@ -1,6 +1,21 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.1
 
+  *) mod_http2: new configuration directive: ```H2Padding numbits``` to control 
+     padding of HTTP/2 payload frames. 'numbits' is a number from 0-8,
+     controlling the range of padding bytes added to a frame. The actual number
+     added is chosen randomly per frame. This applies to HEADERS, DATA and PUSH_PROMISE
+     frames equally. The default continues to be 0, e.g. no padding. [Stefan Eissing] 
+  
+  *) mod_http2: ripping out all the h2_req_engine internal features now that mod_proxy_http2
+     has no more need for it. Optional functions are still declared but no longer implemented.
+     While previous mod_proxy_http2 will work with this, it is recommeneded to run the matching
+     versions of both modules. [Stefan Eissing]
+  
+  *) mod_proxy_http2: changed mod_proxy_http2 implementation and fixed several bugs which
+     resolve PR63170. The proxy module does now a single h2 request on the (reused)
+     connection and returns. [Stefan Eissing]
+  
   *) mod_http2/mod_proxy_http2: proxy_http2 checks correct master connection aborted status 
      to trigger immediate shutdown of backend connections. This is now always signalled
      by mod_http2 when the the session is being released. 

Modified: httpd/httpd/trunk/modules/http2/config2.m4
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/config2.m4?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/config2.m4 (original)
+++ httpd/httpd/trunk/modules/http2/config2.m4 Thu Mar  7 09:41:15 2019
@@ -31,7 +31,6 @@ h2_from_h1.lo dnl
 h2_h2.lo dnl
 h2_headers.lo dnl
 h2_mplx.lo dnl
-h2_ngn_shed.lo dnl
 h2_push.lo dnl
 h2_request.lo dnl
 h2_session.lo dnl

Modified: httpd/httpd/trunk/modules/http2/h2.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2.h?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2.h (original)
+++ httpd/httpd/trunk/modules/http2/h2.h Thu Mar  7 09:41:15 2019
@@ -48,12 +48,12 @@ extern const char *H2_MAGIC_TOKEN;
 #define H2_HEADER_PATH_LEN   5
 #define H2_CRLF             "\r\n"
 
-/* Max data size to write so it fits inside a TLS record */
-#define H2_DATA_CHUNK_SIZE          ((16*1024) - 100 - 9) 
-
 /* Size of the frame header itself in HTTP/2 */
 #define H2_FRAME_HDR_LEN            9
  
+/* Max data size to write so it fits inside a TLS record */
+#define H2_DATA_CHUNK_SIZE          ((16*1024) - 100 - H2_FRAME_HDR_LEN) 
+
 /* Maximum number of padding bytes in a frame, rfc7540 */
 #define H2_MAX_PADLEN               256
 /* Initial default window size, RFC 7540 ch. 6.5.2 */

Modified: httpd/httpd/trunk/modules/http2/h2_config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_config.c?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_config.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_config.c Thu Mar  7 09:41:15 2019
@@ -76,6 +76,8 @@ typedef struct h2_config {
     int copy_files;               /* if files shall be copied vs setaside on output */
     apr_array_header_t *push_list;/* list of h2_push_res configurations */
     int early_hints;              /* support status code 103 */
+    int padding_bits;
+    int padding_always;
 } h2_config;
 
 typedef struct h2_dir_config {
@@ -111,6 +113,8 @@ static h2_config defconf = {
     0,                      /* copy files across threads */
     NULL,                   /* push list */
     0,                      /* early hints, http status 103 */
+    0,                      /* padding bits */
+    1,                      /* padding always */
 };
 
 static h2_dir_config defdconf = {
@@ -153,6 +157,8 @@ void *h2_config_create_svr(apr_pool_t *p
     conf->copy_files           = DEF_VAL;
     conf->push_list            = NULL;
     conf->early_hints          = DEF_VAL;
+    conf->padding_bits         = DEF_VAL;
+    conf->padding_always       = DEF_VAL;
     return conf;
 }
 
@@ -194,6 +200,8 @@ static void *h2_config_merge(apr_pool_t
         n->push_list        = add->push_list? add->push_list : base->push_list;
     }
     n->early_hints          = H2_CONFIG_GET(add, base, early_hints);
+    n->padding_bits         = H2_CONFIG_GET(add, base, padding_bits);
+    n->padding_always       = H2_CONFIG_GET(add, base, padding_always);
     return n;
 }
 
@@ -275,6 +283,10 @@ static apr_int64_t h2_srv_config_geti64(
             return H2_CONFIG_GET(conf, &defconf, copy_files);
         case H2_CONF_EARLY_HINTS:
             return H2_CONFIG_GET(conf, &defconf, early_hints);
+        case H2_CONF_PADDING_BITS:
+            return H2_CONFIG_GET(conf, &defconf, padding_bits);
+        case H2_CONF_PADDING_ALWAYS:
+            return H2_CONFIG_GET(conf, &defconf, padding_always);
         default:
             return DEF_VAL;
     }
@@ -334,6 +346,12 @@ static void h2_srv_config_seti(h2_config
         case H2_CONF_EARLY_HINTS:
             H2_CONFIG_SET(conf, early_hints, val);
             break;
+        case H2_CONF_PADDING_BITS:
+            H2_CONFIG_SET(conf, padding_bits, val);
+            break;
+        case H2_CONF_PADDING_ALWAYS:
+            H2_CONFIG_SET(conf, padding_always, val);
+            break;
         default:
             break;
     }
@@ -873,6 +891,22 @@ static const char *h2_conf_set_early_hin
     return NULL;
 }
 
+static const char *h2_conf_set_padding(cmd_parms *cmd, void *dirconf, const char *value)
+{
+    int val;
+    
+    val = (int)apr_atoi64(value);
+    if (val < 0) {
+        return "number of bits must be >= 0";
+    }
+    if (val > 8) {
+        return "number of bits must be <= 8";
+    }
+    CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PADDING_BITS, val);
+    return NULL;
+}
+
+
 void h2_get_num_workers(server_rec *s, int *minw, int *maxw)
 {
     int threads_per_child = 0;
@@ -941,6 +975,8 @@ const command_rec h2_cmds[] = {
                    OR_FILEINFO|OR_AUTHCFG, "add a resource to be pushed in this location/on this server."),
     AP_INIT_TAKE1("H2EarlyHints", h2_conf_set_early_hints, NULL,
                   RSRC_CONF, "on to enable interim status 103 responses"),
+    AP_INIT_TAKE1("H2Padding", h2_conf_set_padding, NULL,
+                  RSRC_CONF, "set payload padding"),
     AP_END_CMD
 };
 

Modified: httpd/httpd/trunk/modules/http2/h2_config.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_config.h?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_config.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_config.h Thu Mar  7 09:41:15 2019
@@ -42,6 +42,8 @@ typedef enum {
     H2_CONF_PUSH_DIARY_SIZE,
     H2_CONF_COPY_FILES,
     H2_CONF_EARLY_HINTS,
+    H2_CONF_PADDING_BITS,
+    H2_CONF_PADDING_ALWAYS,
 } h2_config_var_t;
 
 struct apr_hash_t;

Modified: httpd/httpd/trunk/modules/http2/h2_conn_io.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_conn_io.c?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_conn_io.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_conn_io.c Thu Mar  7 09:41:15 2019
@@ -40,12 +40,17 @@
  * ~= 1300 bytes */
 #define WRITE_SIZE_INITIAL    1300
 
-/* Calculated like this: max TLS record size 16*1024
- *   - 40 (IP) - 20 (TCP) - 40 (TCP options) 
- *    - TLS overhead (60-100) 
- * which seems to create less TCP packets overall
+/* The maximum we'd like to write in one chunk is
+ * the max size of a TLS record. When pushing
+ * many frames down the h2 connection, this might
+ * align differently because of headers and other
+ * frames or simply as not sufficient data is
+ * in a response body.
+ * However keeping frames at or below this limit
+ * should make optimizations at the layer that writes
+ * to TLS easier.
  */
-#define WRITE_SIZE_MAX        (TLS_DATA_MAX - 100) 
+#define WRITE_SIZE_MAX        (TLS_DATA_MAX) 
 
 #define BUF_REMAIN            ((apr_size_t)(bmax-off))
 

Modified: httpd/httpd/trunk/modules/http2/h2_mplx.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_mplx.c?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_mplx.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_mplx.c Thu Mar  7 09:41:15 2019
@@ -40,7 +40,6 @@
 #include "h2_ctx.h"
 #include "h2_h2.h"
 #include "h2_mplx.h"
-#include "h2_ngn_shed.h"
 #include "h2_request.h"
 #include "h2_stream.h"
 #include "h2_session.h"
@@ -83,12 +82,6 @@ static void check_data_for(h2_mplx *m, h
 static void stream_output_consumed(void *ctx, 
                                    h2_bucket_beam *beam, apr_off_t length)
 {
-    h2_stream *stream = ctx;
-    h2_task *task = stream->task;
-    
-    if (length > 0 && task && task->assigned) {
-        h2_req_engine_out_consumed(task->assigned, task->c, length); 
-    }
 }
 
 static void stream_input_ev(void *ctx, h2_bucket_beam *beam)
@@ -136,7 +129,6 @@ static void stream_cleanup(h2_mplx *m, h
     }
     else if (stream->task) {
         stream->task->c->aborted = 1;
-        apr_thread_cond_broadcast(m->task_thawed);
     }
 }
 
@@ -198,12 +190,6 @@ h2_mplx *h2_mplx_create(conn_rec *c, ser
             return NULL;
         }
         
-        status = apr_thread_cond_create(&m->task_thawed, m->pool);
-        if (status != APR_SUCCESS) {
-            apr_pool_destroy(m->pool);
-            return NULL;
-        }
-    
         m->max_streams = h2_config_sgeti(s, H2_CONF_MAX_STREAMS);
         m->stream_max_mem = h2_config_sgeti(s, H2_CONF_STREAM_MAX_MEM);
 
@@ -226,10 +212,6 @@ h2_mplx *h2_mplx_create(conn_rec *c, ser
         m->limit_change_interval = apr_time_from_msec(100);
         
         m->spare_slaves = apr_array_make(m->pool, 10, sizeof(conn_rec*));
-        
-        m->ngn_shed = h2_ngn_shed_create(m->pool, m->c, m->max_streams, 
-                                         m->stream_max_mem);
-        h2_ngn_shed_set_ctx(m->ngn_shed , m);
     }
     return m;
 }
@@ -387,10 +369,10 @@ static int report_stream_iter(void *ctx,
     if (task) {
         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, /* NO APLOGNO */
                       H2_STRM_MSG(stream, "->03198: %s %s %s"
-                      "[started=%d/done=%d/frozen=%d]"), 
+                      "[started=%d/done=%d]"), 
                       task->request->method, task->request->authority, 
                       task->request->path, task->worker_started, 
-                      task->worker_done, task->frozen);
+                      task->worker_done);
     }
     else {
         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, /* NO APLOGNO */
@@ -452,9 +434,7 @@ void h2_mplx_release_and_join(h2_mplx *m
         /* until empty */
     }
     
-    /* 2. terminate ngn_shed, no more streams
-     * should be scheduled or in the active set */
-    h2_ngn_shed_abort(m->ngn_shed);
+    /* 2. no more streams should be scheduled or in the active set */
     ap_assert(h2_ihash_empty(m->streams));
     ap_assert(h2_iq_empty(m->q));
     
@@ -478,10 +458,6 @@ void h2_mplx_release_and_join(h2_mplx *m
     ap_assert(m->tasks_active == 0);
     m->join_wait = NULL;
     
-    /* 4. close the h2_req_enginge shed */
-    h2_ngn_shed_destroy(m->ngn_shed);
-    m->ngn_shed = NULL;
-    
     /* 4. With all workers done, all streams should be in spurge */
     if (!h2_ihash_empty(m->shold)) {
         ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c, APLOGNO(03516)
@@ -787,49 +763,14 @@ apr_status_t h2_mplx_pop_task(h2_mplx *m
     return rv;
 }
 
-static void task_done(h2_mplx *m, h2_task *task, h2_req_engine *ngn)
+static void task_done(h2_mplx *m, h2_task *task)
 {
     h2_stream *stream;
     
-    if (task->frozen) {
-        /* this task was handed over to an engine for processing 
-         * and the original worker has finished. That means the 
-         * engine may start processing now. */
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,
-                      "h2_mplx(%ld): task(%s) done (frozen)", m->id, task->id);
-        h2_task_thaw(task);
-        apr_thread_cond_broadcast(m->task_thawed);
-        return;
-    }
-        
     ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,
                   "h2_mplx(%ld): task(%s) done", m->id, task->id);
     out_close(m, task);
     
-    if (ngn) {
-        apr_off_t bytes = 0;
-        h2_beam_send(task->output.beam, NULL, APR_NONBLOCK_READ);
-        bytes += h2_beam_get_buffered(task->output.beam);
-        if (bytes > 0) {
-            /* we need to report consumed and current buffered output
-             * to the engine. The request will be streamed out or cancelled,
-             * no more data is coming from it and the engine should update
-             * its calculations before we destroy this information. */
-            h2_req_engine_out_consumed(ngn, task->c, bytes);
-        }
-    }
-    
-    if (task->engine) {
-        if (!m->aborted && !task->c->aborted 
-            && !h2_req_engine_is_shutdown(task->engine)) {
-            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, APLOGNO(10022)
-                          "h2_mplx(%ld): task(%s) has not-shutdown "
-                          "engine(%s)", m->id, task->id, 
-                          h2_req_engine_get_id(task->engine));
-        }
-        h2_ngn_shed_done_ngn(m->ngn_shed, task->engine);
-    }
-    
     task->worker_done = 1;
     task->done_at = apr_time_now();
     ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
@@ -906,7 +847,7 @@ void h2_mplx_task_done(h2_mplx *m, h2_ta
 {
     H2_MPLX_ENTER_ALWAYS(m);
 
-    task_done(m, task, NULL);
+    task_done(m, task);
     --m->tasks_active;
     
     if (m->join_wait) {
@@ -1100,143 +1041,6 @@ apr_status_t h2_mplx_idle(h2_mplx *m)
 }
 
 /*******************************************************************************
- * HTTP/2 request engines
- ******************************************************************************/
-
-typedef struct {
-    h2_mplx * m;
-    h2_req_engine *ngn;
-    int streams_updated;
-} ngn_update_ctx;
-
-static int ngn_update_window(void *ctx, void *val)
-{
-    ngn_update_ctx *uctx = ctx;
-    h2_stream *stream = val;
-    if (stream->task && stream->task->assigned == uctx->ngn
-        && output_consumed_signal(uctx->m, stream->task)) {
-        ++uctx->streams_updated;
-    }
-    return 1;
-}
-
-static apr_status_t ngn_out_update_windows(h2_mplx *m, h2_req_engine *ngn)
-{
-    ngn_update_ctx ctx;
-        
-    ctx.m = m;
-    ctx.ngn = ngn;
-    ctx.streams_updated = 0;
-    h2_ihash_iter(m->streams, ngn_update_window, &ctx);
-    
-    return ctx.streams_updated? APR_SUCCESS : APR_EAGAIN;
-}
-
-apr_status_t h2_mplx_req_engine_push(const char *ngn_type, 
-                                     request_rec *r,
-                                     http2_req_engine_init *einit)
-{
-    apr_status_t status;
-    h2_mplx *m;
-    h2_task *task;
-    h2_stream *stream;
-    
-    task = h2_ctx_get_task(r->connection);
-    if (!task) {
-        return APR_ECONNABORTED;
-    }
-    m = task->mplx;
-    
-    H2_MPLX_ENTER(m);
-
-    stream = h2_ihash_get(m->streams, task->stream_id);
-    if (stream) {
-        status = h2_ngn_shed_push_request(m->ngn_shed, ngn_type, r, einit);
-    }
-    else {
-        status = APR_ECONNABORTED;
-    }
-
-    H2_MPLX_LEAVE(m);
-    return status;
-}
-
-apr_status_t h2_mplx_req_engine_pull(h2_req_engine *ngn, 
-                                     apr_read_type_e block, 
-                                     int capacity, 
-                                     request_rec **pr)
-{   
-    h2_ngn_shed *shed = h2_ngn_shed_get_shed(ngn);
-    h2_mplx *m = h2_ngn_shed_get_ctx(shed);
-    apr_status_t status;
-    int want_shutdown;
-    
-    H2_MPLX_ENTER(m);
-
-    want_shutdown = (block == APR_BLOCK_READ);
-
-    /* Take this opportunity to update output consummation 
-     * for this engine */
-    ngn_out_update_windows(m, ngn);
-    
-    if (want_shutdown && !h2_iq_empty(m->q)) {
-        /* For a blocking read, check first if requests are to be
-         * had and, if not, wait a short while before doing the
-         * blocking, and if unsuccessful, terminating read.
-         */
-        status = h2_ngn_shed_pull_request(shed, ngn, capacity, 1, pr);
-        if (APR_STATUS_IS_EAGAIN(status)) {
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,
-                          "h2_mplx(%ld): start block engine pull", m->id);
-            apr_thread_cond_timedwait(m->task_thawed, m->lock, 
-                                      apr_time_from_msec(20));
-            status = h2_ngn_shed_pull_request(shed, ngn, capacity, 1, pr);
-        }
-    }
-    else {
-        status = h2_ngn_shed_pull_request(shed, ngn, capacity,
-                                          want_shutdown, pr);
-    }
-
-    H2_MPLX_LEAVE(m);
-    return status;
-}
- 
-void h2_mplx_req_engine_done(h2_req_engine *ngn, conn_rec *r_conn,
-                             apr_status_t status)
-{
-    h2_task *task = h2_ctx_get_task(r_conn);
-    
-    if (task) {
-        h2_mplx *m = task->mplx;
-        h2_stream *stream;
-        int task_hosting_engine = (task->engine != NULL); 
-
-        H2_MPLX_ENTER_ALWAYS(m);
-
-        stream = h2_ihash_get(m->streams, task->stream_id);
-        
-        ngn_out_update_windows(m, ngn);
-        h2_ngn_shed_done_task(m->ngn_shed, ngn, task);
-        
-        if (status != APR_SUCCESS && stream 
-            && h2_task_can_redo(task) 
-            && !h2_ihash_get(m->sredo, stream->id)) {
-            ap_log_cerror(APLOG_MARK, APLOG_INFO, status, m->c,
-                          "h2_mplx(%ld): task %s added to redo", m->id, task->id);
-            h2_ihash_add(m->sredo, stream);
-        }
-
-        /* cannot report that until hosted engine returns */
-        if (!task_hosting_engine) { 
-            task_done(m, task, ngn);
-        }
-
-        H2_MPLX_LEAVE(m);
-    }
-}
-
-/*******************************************************************************
  * mplx master events dispatching
  ******************************************************************************/
 

Modified: httpd/httpd/trunk/modules/http2/h2_mplx.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_mplx.h?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_mplx.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_mplx.h Thu Mar  7 09:41:15 2019
@@ -47,8 +47,6 @@ struct h2_request;
 struct apr_thread_cond_t;
 struct h2_workers;
 struct h2_iqueue;
-struct h2_ngn_shed;
-struct h2_req_engine;
 
 #include <apr_queue.h>
 
@@ -86,7 +84,6 @@ struct h2_mplx {
 
     apr_thread_mutex_t *lock;
     struct apr_thread_cond_t *added_output;
-    struct apr_thread_cond_t *task_thawed;
     struct apr_thread_cond_t *join_wait;
     
     apr_size_t stream_max_mem;
@@ -95,8 +92,6 @@ struct h2_mplx {
     apr_array_header_t *spare_slaves; /* spare slave connections */
     
     struct h2_workers *workers;
-    
-    struct h2_ngn_shed *ngn_shed;
 };
 
 
@@ -302,28 +297,4 @@ APR_RING_INSERT_TAIL((b), ap__b, h2_mplx
  */
 apr_status_t h2_mplx_idle(h2_mplx *m);
 
-/*******************************************************************************
- * h2_req_engine handling
- ******************************************************************************/
-
-typedef void h2_output_consumed(void *ctx, conn_rec *c, apr_off_t consumed);
-typedef apr_status_t h2_mplx_req_engine_init(struct h2_req_engine *engine, 
-                                             const char *id, 
-                                             const char *type,
-                                             apr_pool_t *pool, 
-                                             apr_size_t req_buffer_size,
-                                             request_rec *r,
-                                             h2_output_consumed **pconsumed,
-                                             void **pbaton);
-
-apr_status_t h2_mplx_req_engine_push(const char *ngn_type, 
-                                     request_rec *r, 
-                                     h2_mplx_req_engine_init *einit);
-apr_status_t h2_mplx_req_engine_pull(struct h2_req_engine *ngn, 
-                                     apr_read_type_e block, 
-                                     int capacity, 
-                                     request_rec **pr);
-void h2_mplx_req_engine_done(struct h2_req_engine *ngn, conn_rec *r_conn,
-                             apr_status_t status);
-
 #endif /* defined(__mod_h2__h2_mplx__) */

Modified: httpd/httpd/trunk/modules/http2/h2_proxy_session.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_proxy_session.c?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_proxy_session.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_proxy_session.c Thu Mar  7 09:41:15 2019
@@ -429,12 +429,6 @@ static int stream_response_data(nghttp2_
                                   stream_id, NGHTTP2_STREAM_CLOSED);
         return NGHTTP2_ERR_STREAM_CLOSING;
     }
-    if (stream->standalone) {
-        nghttp2_session_consume(ngh2, stream_id, len);
-        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, stream->r,
-                      "h2_proxy_session(%s): stream %d, win_update %d bytes",
-                      session->id, stream_id, (int)len);
-    }
     return 0;
 }
 
@@ -641,7 +635,7 @@ h2_proxy_session *h2_proxy_session_setup
         
         nghttp2_option_new(&option);
         nghttp2_option_set_peer_max_concurrent_streams(option, 100);
-        nghttp2_option_set_no_auto_window_update(option, 1);
+        nghttp2_option_set_no_auto_window_update(option, 0);
         
         nghttp2_session_client_new2(&session->ngh2, cbs, session, option);
         
@@ -1545,42 +1539,3 @@ typedef struct {
     int updated;
 } win_update_ctx;
 
-static int win_update_iter(void *udata, void *val)
-{
-    win_update_ctx *ctx = udata;
-    h2_proxy_stream *stream = val;
-    
-    if (stream->r && stream->r->connection == ctx->c) {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, ctx->session->c, 
-                      "h2_proxy_session(%s-%d): win_update %ld bytes",
-                      ctx->session->id, (int)stream->id, (long)ctx->bytes);
-        nghttp2_session_consume(ctx->session->ngh2, stream->id, ctx->bytes);
-        ctx->updated = 1;
-        return 0;
-    }
-    return 1;
-}
-
-
-void h2_proxy_session_update_window(h2_proxy_session *session, 
-                                    conn_rec *c, apr_off_t bytes)
-{
-    if (!h2_proxy_ihash_empty(session->streams)) {
-        win_update_ctx ctx;
-        ctx.session = session;
-        ctx.c = c;
-        ctx.bytes = bytes;
-        ctx.updated = 0;
-        h2_proxy_ihash_iter(session->streams, win_update_iter, &ctx);
-        
-        if (!ctx.updated) {
-            /* could not find the stream any more, possibly closed, update
-             * the connection window at least */
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c, 
-                          "h2_proxy_session(%s): win_update conn %ld bytes",
-                          session->id, (long)bytes);
-            nghttp2_session_consume_connection(session->ngh2, (size_t)bytes);
-        }
-    }
-}
-

Modified: httpd/httpd/trunk/modules/http2/h2_proxy_session.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_proxy_session.h?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_proxy_session.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_proxy_session.h Thu Mar  7 09:41:15 2019
@@ -120,9 +120,6 @@ void h2_proxy_session_cancel_all(h2_prox
 
 void h2_proxy_session_cleanup(h2_proxy_session *s, h2_proxy_request_done *done);
 
-void h2_proxy_session_update_window(h2_proxy_session *s, 
-                                    conn_rec *c, apr_off_t bytes);
-
 #define H2_PROXY_REQ_URL_NOTE   "h2-proxy-req-url"
 
 #endif /* h2_proxy_session_h */

Modified: httpd/httpd/trunk/modules/http2/h2_request.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_request.c?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_request.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_request.c Thu Mar  7 09:41:15 2019
@@ -282,7 +282,7 @@ request_rec *h2_request_create_rec(const
     
     /* Time to populate r with the data we have. */
     r->request_time = req->request_time;
-    r->method = apr_pstrdup(r->pool, req->method);
+    r->method = req->method;
     /* Provide quick information about the request method as soon as known */
     r->method_number = ap_method_number_of(r->method);
     if (r->method_number == M_GET && r->method[0] == 'H') {

Modified: httpd/httpd/trunk/modules/http2/h2_session.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_session.c?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_session.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_session.c Thu Mar  7 09:41:15 2019
@@ -495,9 +495,7 @@ static int on_send_data_cb(nghttp2_sessi
         return NGHTTP2_ERR_WOULDBLOCK;
     }
 
-    if (frame->data.padlen > H2_MAX_PADLEN) {
-        return NGHTTP2_ERR_PROTO;
-    }
+    ap_assert(frame->data.padlen <= (H2_MAX_PADLEN+1));
     padlen = (unsigned char)frame->data.padlen;
     
     stream = get_stream(session, stream_id);
@@ -513,8 +511,9 @@ static int on_send_data_cb(nghttp2_sessi
                   H2_STRM_MSG(stream, "send_data_cb for %ld bytes"),
                   (long)length);
                   
-    status = h2_conn_io_write(&session->io, (const char *)framehd, 9);
+    status = h2_conn_io_write(&session->io, (const char *)framehd, H2_FRAME_HDR_LEN);
     if (padlen && status == APR_SUCCESS) {
+        --padlen;
         status = h2_conn_io_write(&session->io, (const char *)&padlen, 1);
     }
     
@@ -622,6 +621,39 @@ static int on_invalid_header_cb(nghttp2_
 }
 #endif
 
+static ssize_t select_padding_cb(nghttp2_session *ngh2, 
+                                 const nghttp2_frame *frame, 
+                                 size_t max_payloadlen, void *user_data)
+{
+    h2_session *session = user_data;
+    ssize_t frame_len = frame->hd.length + H2_FRAME_HDR_LEN; /* the total length without padding */
+    ssize_t padded_len = frame_len;
+
+    /* Determine # of padding bytes to append to frame. Unless session->padding_always
+     * the number my be capped by the ui.write_size that currently applies. 
+     */
+    if (session->padding_max) {
+        int n = ap_random_pick(0, session->padding_max);
+        padded_len = H2MIN(max_payloadlen + H2_FRAME_HDR_LEN, frame_len + n); 
+    }
+
+    if (padded_len != frame_len) {
+        if (!session->padding_always && session->io.write_size 
+            && (padded_len > session->io.write_size)
+            && (frame_len <= session->io.write_size)) {
+            padded_len = session->io.write_size;
+        }
+        if (APLOGctrace2(session->c)) {
+            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c,
+                          "select padding from [%d, %d]: %d (frame length: 0x%04x, write size: %d)", 
+                          (int)frame_len, (int)max_payloadlen+H2_FRAME_HDR_LEN, 
+                          (int)(padded_len - frame_len), (int)padded_len, (int)session->io.write_size);
+        }
+        return padded_len - H2_FRAME_HDR_LEN;
+    }
+    return frame->hd.length;
+}
+
 #define NGH2_SET_CALLBACK(callbacks, name, fn)\
 nghttp2_session_callbacks_set_##name##_callback(callbacks, fn)
 
@@ -647,6 +679,7 @@ static apr_status_t init_callbacks(conn_
 #ifdef H2_NG2_INVALID_HEADER_CB
     NGH2_SET_CALLBACK(*pcb, on_invalid_header, on_invalid_header_cb);
 #endif
+    NGH2_SET_CALLBACK(*pcb, select_padding, select_padding_cb);
     return APR_SUCCESS;
 }
 
@@ -862,6 +895,11 @@ apr_status_t h2_session_create(h2_sessio
     ap_add_input_filter("H2_IN", session->cin, r, c);
     
     h2_conn_io_init(&session->io, c, s);
+    session->padding_max = h2_config_sgeti(s, H2_CONF_PADDING_BITS);
+    if (session->padding_max) {
+        session->padding_max = (0x01 << session->padding_max) - 1; 
+    }
+    session->padding_always = h2_config_sgeti(s, H2_CONF_PADDING_ALWAYS);
     session->bbtmp = apr_brigade_create(session->pool, c->bucket_alloc);
     
     status = init_callbacks(c, &callbacks);

Modified: httpd/httpd/trunk/modules/http2/h2_session.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_session.h?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_session.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_session.h Thu Mar  7 09:41:15 2019
@@ -85,6 +85,8 @@ typedef struct h2_session {
     struct h2_workers *workers;     /* for executing stream tasks */
     struct h2_filter_cin *cin;      /* connection input filter context */
     h2_conn_io io;                  /* io on httpd conn filters */
+    int padding_max;                /* max number of padding bytes */
+    int padding_always;             /* padding has precedence over I/O optimizations */
     struct nghttp2_session *ngh2;   /* the nghttp2 session (internal use) */
 
     h2_session_state state;         /* state session is in */

Modified: httpd/httpd/trunk/modules/http2/h2_stream.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_stream.c?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_stream.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_stream.c Thu Mar  7 09:41:15 2019
@@ -854,7 +854,7 @@ apr_status_t h2_stream_out_prepare(h2_st
      * is requested. But we can reduce the size in case the master
      * connection operates in smaller chunks. (TSL warmup) */
     if (stream->session->io.write_size > 0) {
-        max_chunk = stream->session->io.write_size - 9; /* header bits */ 
+        max_chunk = stream->session->io.write_size - H2_FRAME_HDR_LEN; 
     }
     requested = (*plen > 0)? H2MIN(*plen, max_chunk) : max_chunk;
     

Modified: httpd/httpd/trunk/modules/http2/h2_task.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_task.c?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_task.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_task.c Thu Mar  7 09:41:15 2019
@@ -97,7 +97,7 @@ static apr_status_t send_out(h2_task *ta
     apr_brigade_length(bb, 0, &written);
     H2_TASK_OUT_LOG(APLOG_TRACE2, task, bb, "h2_task send_out");
     h2_beam_log(task->output.beam, task->c, APLOG_TRACE2, "send_out(before)");
-    /* engines send unblocking */
+
     status = h2_beam_send(task->output.beam, bb, 
                           block? APR_BLOCK_READ : APR_NONBLOCK_READ);
     h2_beam_log(task->output.beam, task->c, APLOG_TRACE2, "send_out(after)");
@@ -133,26 +133,9 @@ static apr_status_t slave_out(h2_task *t
     apr_status_t rv = APR_SUCCESS;
     int flush = 0, blocking;
     
-    if (task->frozen) {
-        h2_util_bb_log(task->c, task->stream_id, APLOG_TRACE2,
-                       "frozen task output write, ignored", bb);
-        while (!APR_BRIGADE_EMPTY(bb)) {
-            b = APR_BRIGADE_FIRST(bb);
-            if (AP_BUCKET_IS_EOR(b)) {
-                APR_BUCKET_REMOVE(b);
-                task->eor = b;
-            }
-            else {
-                apr_bucket_delete(b);
-            }
-        }
-        return APR_SUCCESS;
-    }
-
 send:
-    /* we send block once we opened the output, so someone is there
-     * reading it *and* the task is not assigned to a h2_req_engine */
-    blocking = (!task->assigned && task->output.opened);
+    /* we send block once we opened the output, so someone is there reading it */
+    blocking = task->output.opened;
     for (b = APR_BRIGADE_FIRST(bb);
          b != APR_BRIGADE_SENTINEL(bb);
          b = APR_BUCKET_NEXT(b)) {
@@ -632,18 +615,9 @@ apr_status_t h2_task_do(h2_task *task, a
     task->c->current_thread = thread; 
     ap_run_process_connection(c);
     
-    if (task->frozen) {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
-                      "h2_task(%s): process_conn returned frozen task", 
-                      task->id);
-        /* cleanup delayed */
-        return APR_EAGAIN;
-    }
-    else {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
-                      "h2_task(%s): processing done", task->id);
-        return output_finish(task);
-    }
+    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
+                  "h2_task(%s): processing done", task->id);
+    return output_finish(task);
 }
 
 static apr_status_t h2_task_process_request(h2_task *task, conn_rec *c)
@@ -681,14 +655,8 @@ static apr_status_t h2_task_process_requ
         
         ap_process_request(r);
         
-        if (task->frozen) {
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
-                          "h2_task(%s): process_request frozen", task->id);
-        }
-        else {
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
-                          "h2_task(%s): process_request done", task->id);
-        }
+        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
+                      "h2_task(%s): process_request done", task->id);
         
         /* After the call to ap_process_request, the
          * request pool may have been deleted.  We set
@@ -740,28 +708,3 @@ static int h2_task_process_conn(conn_rec
     return DECLINED;
 }
 
-apr_status_t h2_task_freeze(h2_task *task)
-{   
-    if (!task->frozen) {
-        task->frozen = 1;
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, task->c, APLOGNO(03406) 
-                      "h2_task(%s), frozen", task->id);
-    }
-    return APR_SUCCESS;
-}
-
-apr_status_t h2_task_thaw(h2_task *task)
-{
-    if (task->frozen) {
-        task->frozen = 0;
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, task->c, APLOGNO(03407) 
-                      "h2_task(%s), thawed", task->id);
-    }
-    task->thawed = 1;
-    return APR_SUCCESS;
-}
-
-int h2_task_has_thawed(h2_task *task)
-{
-    return task->thawed;
-}

Modified: httpd/httpd/trunk/modules/http2/h2_task.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_task.h?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_task.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_task.h Thu Mar  7 09:41:15 2019
@@ -42,7 +42,6 @@ struct h2_bucket_beam;
 struct h2_conn;
 struct h2_mplx;
 struct h2_task;
-struct h2_req_engine;
 struct h2_request;
 struct h2_response_parser;
 struct h2_stream;
@@ -80,8 +79,6 @@ struct h2_task {
     struct h2_mplx *mplx;
     
     unsigned int filters_set    : 1;
-    unsigned int frozen         : 1;
-    unsigned int thawed         : 1;
     unsigned int worker_started : 1; /* h2_worker started processing */
     
     int worker_done;                 /* h2_worker finished */
@@ -90,9 +87,6 @@ struct h2_task {
     apr_time_t started_at;           /* when processing started */
     apr_time_t done_at;              /* when processing was done */
     apr_bucket *eor;
-    
-    struct h2_req_engine *engine;   /* engine hosted by this task */
-    struct h2_req_engine *assigned; /* engine that task has been assigned to */
 };
 
 h2_task *h2_task_create(conn_rec *slave, int stream_id,
@@ -122,8 +116,4 @@ apr_status_t h2_task_init(apr_pool_t *po
 extern APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_in) *h2_task_logio_add_bytes_in;
 extern APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *h2_task_logio_add_bytes_out;
 
-apr_status_t h2_task_freeze(h2_task *task);
-apr_status_t h2_task_thaw(h2_task *task);
-int h2_task_has_thawed(h2_task *task);
-
 #endif /* defined(__mod_h2__h2_task__) */

Modified: httpd/httpd/trunk/modules/http2/h2_version.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_version.h?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_version.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_version.h Thu Mar  7 09:41:15 2019
@@ -27,7 +27,7 @@
  * @macro
  * Version number of the http2 module as c string
  */
-#define MOD_HTTP2_VERSION "1.12.6-DEV"
+#define MOD_HTTP2_VERSION "1.14.1-git"
 
 /**
  * @macro
@@ -35,7 +35,7 @@
  * release. This is a 24 bit number with 8 bits for major number, 8 bits
  * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
  */
-#define MOD_HTTP2_VERSION_NUM 0x010c06
+#define MOD_HTTP2_VERSION_NUM 0x010e01
 
 
 #endif /* mod_h2_h2_version_h */

Modified: httpd/httpd/trunk/modules/http2/mod_http2.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/mod_http2.c?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/mod_http2.c (original)
+++ httpd/httpd/trunk/modules/http2/mod_http2.c Thu Mar  7 09:41:15 2019
@@ -172,27 +172,6 @@ static char *http2_var_lookup(apr_pool_t
                          conn_rec *, request_rec *, char *name);
 static int http2_is_h2(conn_rec *);
 
-static apr_status_t http2_req_engine_push(const char *ngn_type, 
-                                          request_rec *r, 
-                                          http2_req_engine_init *einit)
-{
-    return h2_mplx_req_engine_push(ngn_type, r, einit);
-}
-
-static apr_status_t http2_req_engine_pull(h2_req_engine *ngn, 
-                                          apr_read_type_e block, 
-                                          int capacity, 
-                                          request_rec **pr)
-{
-    return h2_mplx_req_engine_pull(ngn, block, (apr_uint32_t)capacity, pr);
-}
-
-static void http2_req_engine_done(h2_req_engine *ngn, conn_rec *r_conn,
-                                  apr_status_t status)
-{
-    h2_mplx_req_engine_done(ngn, r_conn, status);
-}
-
 static void http2_get_num_workers(server_rec *s, int *minw, int *maxw)
 {
     h2_get_num_workers(s, minw, maxw);
@@ -220,9 +199,6 @@ static void h2_hooks(apr_pool_t *pool)
     
     APR_REGISTER_OPTIONAL_FN(http2_is_h2);
     APR_REGISTER_OPTIONAL_FN(http2_var_lookup);
-    APR_REGISTER_OPTIONAL_FN(http2_req_engine_push);
-    APR_REGISTER_OPTIONAL_FN(http2_req_engine_pull);
-    APR_REGISTER_OPTIONAL_FN(http2_req_engine_done);
     APR_REGISTER_OPTIONAL_FN(http2_get_num_workers);
 
     ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool, "installing hooks");

Modified: httpd/httpd/trunk/modules/http2/mod_http2.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/mod_http2.h?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/mod_http2.h (original)
+++ httpd/httpd/trunk/modules/http2/mod_http2.h Thu Mar  7 09:41:15 2019
@@ -30,22 +30,20 @@ APR_DECLARE_OPTIONAL_FN(int,
 
 
 /*******************************************************************************
- * HTTP/2 request engines
+ * START HTTP/2 request engines (DEPRECATED)
  ******************************************************************************/
+
+/* The following functions were introduced for the experimental mod_proxy_http2
+ * support, but have been abandoned since.
+ * They are still declared here for backward compatibiliy, in case someone
+ * tries to build an old mod_proxy_http2 against it, but will disappear
+ * completely sometime in the future.
+ */ 
  
 struct apr_thread_cond_t;
-
 typedef struct h2_req_engine h2_req_engine;
-
 typedef void http2_output_consumed(void *ctx, conn_rec *c, apr_off_t consumed);
 
-/**
- * Initialize a h2_req_engine. The structure will be passed in but
- * only the name and master are set. The function should initialize
- * all fields.
- * @param engine the allocated, partially filled structure
- * @param r      the first request to process, or NULL
- */
 typedef apr_status_t http2_req_engine_init(h2_req_engine *engine, 
                                            const char *id, 
                                            const char *type,
@@ -55,35 +53,11 @@ typedef apr_status_t http2_req_engine_in
                                            http2_output_consumed **pconsumed,
                                            void **pbaton);
 
-/**
- * Push a request to an engine with the specified name for further processing.
- * If no such engine is available, einit is not NULL, einit is called 
- * with a new engine record and the caller is responsible for running the
- * new engine instance.
- * @param engine_type the type of the engine to add the request to
- * @param r           the request to push to an engine for processing
- * @param einit       an optional initialization callback for a new engine 
- *                    of the requested type, should no instance be available.
- *                    By passing a non-NULL callback, the caller is willing
- *                    to init and run a new engine itself.
- * @return APR_SUCCESS iff slave was successfully added to an engine
- */
 APR_DECLARE_OPTIONAL_FN(apr_status_t, 
                         http2_req_engine_push, (const char *engine_type, 
                                                 request_rec *r,
                                                 http2_req_engine_init *einit));
 
-/**
- * Get a new request for processing in this engine.
- * @param engine      the engine which is done processing the slave
- * @param block       if call should block waiting for request to come
- * @param capacity    how many parallel requests are acceptable
- * @param pr          the request that needs processing or NULL
- * @return APR_SUCCESS if new request was assigned
- *         APR_EAGAIN  if no new request is available
- *         APR_EOF          if engine may shut down, as no more request will be scheduled
- *         APR_ECONNABORTED if the engine needs to shut down immediately
- */
 APR_DECLARE_OPTIONAL_FN(apr_status_t, 
                         http2_req_engine_pull, (h2_req_engine *engine, 
                                                 apr_read_type_e block,
@@ -98,4 +72,8 @@ APR_DECLARE_OPTIONAL_FN(void,
                         http2_get_num_workers, (server_rec *s,
                                                 int *minw, int *max));
 
+/*******************************************************************************
+ * END HTTP/2 request engines (DEPRECATED)
+ ******************************************************************************/
+
 #endif

Modified: httpd/httpd/trunk/modules/http2/mod_proxy_http2.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/mod_proxy_http2.c?rev=1854963&r1=1854962&r2=1854963&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/mod_proxy_http2.c (original)
+++ httpd/httpd/trunk/modules/http2/mod_proxy_http2.c Thu Mar  7 09:41:15 2019
@@ -47,20 +47,12 @@ AP_DECLARE_MODULE(proxy_http2) = {
 
 /* Optional functions from mod_http2 */
 static int (*is_h2)(conn_rec *c);
-static apr_status_t (*req_engine_push)(const char *name, request_rec *r, 
-                                       http2_req_engine_init *einit);
-static apr_status_t (*req_engine_pull)(h2_req_engine *engine, 
-                                       apr_read_type_e block, 
-                                       int capacity, 
-                                       request_rec **pr);
-static void (*req_engine_done)(h2_req_engine *engine, conn_rec *r_conn,
-                               apr_status_t status);
-                                       
+
 typedef struct h2_proxy_ctx {
+    const char *id;
     conn_rec *master;
     conn_rec *owner;
     apr_pool_t *pool;
-    request_rec *rbase;
     server_rec *server;
     const char *proxy_func;
     char server_portstr[32];
@@ -68,19 +60,16 @@ typedef struct h2_proxy_ctx {
     proxy_worker *worker;
     proxy_server_conf *conf;
     
-    h2_req_engine *engine;
-    const char *engine_id;
-    const char *engine_type;
-    apr_pool_t *engine_pool;    
     apr_size_t req_buffer_size;
-    h2_proxy_fifo *requests;
     int capacity;
     
-    unsigned standalone : 1;
     unsigned is_ssl : 1;
     unsigned flushall : 1;
     
-    apr_status_t r_status;     /* status of our first request work */
+    request_rec *r;            /* the request processed in this ctx */
+    apr_status_t r_status;     /* status of request work */
+    int r_done;                /* request was processed, not necessarily successfully */
+    int r_may_retry;           /* request may be retried */
     h2_proxy_session *session; /* current http2 session against backend */
 } h2_proxy_ctx;
 
@@ -106,16 +95,6 @@ static int h2_proxy_post_config(apr_pool
                  MOD_HTTP2_VERSION, ngh2? ngh2->version_str : "unknown");
     
     is_h2 = APR_RETRIEVE_OPTIONAL_FN(http2_is_h2);
-    req_engine_push = APR_RETRIEVE_OPTIONAL_FN(http2_req_engine_push);
-    req_engine_pull = APR_RETRIEVE_OPTIONAL_FN(http2_req_engine_pull);
-    req_engine_done = APR_RETRIEVE_OPTIONAL_FN(http2_req_engine_done);
-    
-    /* we need all of them */
-    if (!req_engine_push || !req_engine_pull || !req_engine_done) {
-        req_engine_push = NULL;
-        req_engine_pull = NULL;
-        req_engine_done = NULL;
-    }
     
     return status;
 }
@@ -206,45 +185,6 @@ static int proxy_http2_canon(request_rec
     return OK;
 }
 
-static void out_consumed(void *baton, conn_rec *c, apr_off_t bytes)
-{
-    h2_proxy_ctx *ctx = baton;
-    
-    if (ctx->session) {
-        h2_proxy_session_update_window(ctx->session, c, bytes);
-    }
-}
-
-static apr_status_t proxy_engine_init(h2_req_engine *engine, 
-                                        const char *id, 
-                                        const char *type,
-                                        apr_pool_t *pool, 
-                                        apr_size_t req_buffer_size,
-                                        request_rec *r,
-                                        http2_output_consumed **pconsumed,
-                                        void **pctx)
-{
-    h2_proxy_ctx *ctx = ap_get_module_config(r->connection->conn_config, 
-                                             &proxy_http2_module);
-    if (!ctx) {
-        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(03368)
-                      "h2_proxy_session, engine init, no ctx found");
-        return APR_ENOTIMPL;
-    }
-    
-    ctx->pool = pool;
-    ctx->engine = engine;
-    ctx->engine_id = id;
-    ctx->engine_type = type;
-    ctx->engine_pool = pool;
-    ctx->req_buffer_size = req_buffer_size;
-    ctx->capacity = H2MIN(100, h2_proxy_fifo_capacity(ctx->requests));
-    
-    *pconsumed = out_consumed;
-    *pctx = ctx;
-    return APR_SUCCESS;
-}
-
 static apr_status_t add_request(h2_proxy_session *session, request_rec *r)
 {
     h2_proxy_ctx *ctx = session->user_data;
@@ -254,7 +194,7 @@ static apr_status_t add_request(h2_proxy
     url = apr_table_get(r->notes, H2_PROXY_REQ_URL_NOTE);
     apr_table_setn(r->notes, "proxy-source-port", apr_psprintf(r->pool, "%hu",
                    ctx->p_conn->connection->local_addr->port));
-    status = h2_proxy_session_submit(session, url, r, ctx->standalone);
+    status = h2_proxy_session_submit(session, url, r, 1);
     if (status != APR_SUCCESS) {
         ap_log_cerror(APLOG_MARK, APLOG_ERR, status, r->connection, APLOGNO(03351)
                       "pass request body failed to %pI (%s) from %s (%s)",
@@ -268,43 +208,15 @@ static apr_status_t add_request(h2_proxy
 static void request_done(h2_proxy_ctx *ctx, request_rec *r,
                          apr_status_t status, int touched)
 {   
-    const char *task_id = apr_table_get(r->connection->notes, H2_TASK_ID_NOTE);
-
-    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, r->connection, 
-                  "h2_proxy_session(%s): request done %s, touched=%d",
-                  ctx->engine_id, task_id, touched);
-    if (status != APR_SUCCESS) {
-        if (!touched) {
-            /* untouched request, need rescheduling */
-            status = h2_proxy_fifo_push(ctx->requests, r);
-            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, r->connection, 
-                          APLOGNO(03369)
-                          "h2_proxy_session(%s): rescheduled request %s",
-                          ctx->engine_id, task_id);
-            return;
-        }
-        else {
-            const char *uri;
-            uri = apr_uri_unparse(r->pool, &r->parsed_uri, 0);
-            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, r->connection, 
-                          APLOGNO(03471) "h2_proxy_session(%s): request %s -> %s "
-                          "not complete, cannot repeat", 
-                          ctx->engine_id, task_id, uri);
-        }
-    }
-    
-    if (r == ctx->rbase) {
+    if (r == ctx->r) {
+        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, r->connection, 
+                      "h2_proxy_session(%s): request done, touched=%d",
+                      ctx->id, touched);
+        ctx->r_done = 1;
+        if (touched) ctx->r_may_retry = 0;
         ctx->r_status = ((status == APR_SUCCESS)? APR_SUCCESS
                          : HTTP_SERVICE_UNAVAILABLE);
     }
-    
-    if (req_engine_done && ctx->engine) {
-        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, r->connection, 
-                      APLOGNO(03370)
-                      "h2_proxy_session(%s): finished request %s",
-                      ctx->engine_id, task_id);
-        req_engine_done(ctx->engine, r->connection, status);
-    }
 }    
 
 static void session_req_done(h2_proxy_session *session, request_rec *r,
@@ -313,43 +225,15 @@ static void session_req_done(h2_proxy_se
     request_done(session->user_data, r, status, touched);
 }
 
-static apr_status_t next_request(h2_proxy_ctx *ctx, int before_leave)
-{
-    if (h2_proxy_fifo_count(ctx->requests) > 0) {
-        return APR_SUCCESS;
-    }
-    else if (req_engine_pull && ctx->engine) {
-        apr_status_t status;
-        request_rec *r = NULL;
-        
-        status = req_engine_pull(ctx->engine, before_leave? 
-                                 APR_BLOCK_READ: APR_NONBLOCK_READ, 
-                                 ctx->capacity, &r);
-        if (status == APR_SUCCESS && r) {
-            ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, ctx->owner, 
-                          "h2_proxy_engine(%s): pulled request (%s) %s", 
-                          ctx->engine_id, 
-                          before_leave? "before leave" : "regular", 
-                          r->the_request);
-            h2_proxy_fifo_push(ctx->requests, r);
-        }
-        return APR_STATUS_IS_EAGAIN(status)? APR_SUCCESS : status;
-    }
-    return APR_EOF;
-}
-
-static apr_status_t proxy_engine_run(h2_proxy_ctx *ctx) {
+static apr_status_t ctx_run(h2_proxy_ctx *ctx) {
     apr_status_t status = OK;
     int h2_front;
-    request_rec *r;
     
     /* Step Four: Send the Request in a new HTTP/2 stream and
      * loop until we got the response or encounter errors.
      */
-    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->owner, 
-                  "eng(%s): setup session", ctx->engine_id);
     h2_front = is_h2? is_h2(ctx->owner) : 0;
-    ctx->session = h2_proxy_session_setup(ctx->engine_id, ctx->p_conn, ctx->conf,
+    ctx->session = h2_proxy_session_setup(ctx->id, ctx->p_conn, ctx->conf,
                                           h2_front, 30, 
                                           h2_proxy_log2((int)ctx->req_buffer_size), 
                                           session_req_done);
@@ -360,45 +244,20 @@ static apr_status_t proxy_engine_run(h2_
     }
     
     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->owner, APLOGNO(03373)
-                  "eng(%s): run session %s", ctx->engine_id, ctx->session->id);
+                  "eng(%s): run session %s", ctx->id, ctx->session->id);
     ctx->session->user_data = ctx;
     
-    while (1) {
-        if (ctx->master->aborted) {
-            status = APR_ECONNABORTED;
-            goto out;
-        }
-        
-        if (APR_SUCCESS == h2_proxy_fifo_try_pull(ctx->requests, (void**)&r)) {
-            add_request(ctx->session, r);
-        }
+    ctx->r_done = 0;
+    add_request(ctx->session, ctx->r);
+    
+    while (!ctx->master->aborted && !ctx->r_done) {
+    
         status = h2_proxy_session_process(ctx->session);
-        
-        if (status == APR_SUCCESS) {
-            /* ongoing processing, check if we have room to handle more streams,
-             * maybe the remote side changed their limit */
-            if (ctx->session->remote_max_concurrent > 0
-                && ctx->session->remote_max_concurrent != ctx->capacity) {
-                ctx->capacity = H2MIN((int)ctx->session->remote_max_concurrent, 
-                                      h2_proxy_fifo_capacity(ctx->requests));
-            }
-            /* try to pull more request, if our capacity allows it */
-            if (APR_ECONNABORTED == next_request(ctx, 0)) {
-                status = APR_ECONNABORTED;
-                goto out;
-            }
-            /* If we have no ongoing streams and nothing in our queue, we
-             * terminate processing and return to our caller. */
-            if ((h2_proxy_fifo_count(ctx->requests) == 0) 
-                && h2_proxy_ihash_empty(ctx->session->streams)) {
-                goto out;
-            }
-        }
-        else {
+        if (status != APR_SUCCESS) {
             /* Encountered an error during session processing */
             ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner, 
                           APLOGNO(03375) "eng(%s): end of session %s", 
-                          ctx->engine_id, ctx->session->id);
+                          ctx->id, ctx->session->id);
             /* Any open stream of that session needs to
              * a) be reopened on the new session iff safe to do so
              * b) reported as done (failed) otherwise
@@ -409,12 +268,11 @@ static apr_status_t proxy_engine_run(h2_
     }
     
 out:
-    if (APR_ECONNABORTED == status) {
+    if (ctx->master->aborted) {
         /* master connection gone */
         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner, 
-                      APLOGNO(03374) "eng(%s): master connection gone", ctx->engine_id);
-        /* give notice that we're leaving and cancel all ongoing streams. */
-        next_request(ctx, 1); 
+                      APLOGNO(03374) "eng(%s): master connection gone", ctx->id);
+        /* cancel all ongoing requests */
         h2_proxy_session_cancel_all(ctx->session);
         h2_proxy_session_process(ctx->session);
         if (!ctx->master->aborted) {
@@ -427,49 +285,6 @@ out:
     return status;
 }
 
-static apr_status_t push_request_somewhere(h2_proxy_ctx *ctx, request_rec *r)
-{
-    conn_rec *c = ctx->owner;
-    const char *engine_type, *hostname;
-    
-    hostname = (ctx->p_conn->ssl_hostname? 
-                ctx->p_conn->ssl_hostname : ctx->p_conn->hostname);
-    engine_type = apr_psprintf(ctx->pool, "proxy_http2 %s%s", hostname, 
-                               ctx->server_portstr);
-    
-    if (c->master && req_engine_push && r && is_h2 && is_h2(c)) {
-        /* If we are have req_engine capabilities, push the handling of this
-         * request (e.g. slave connection) to a proxy_http2 engine which 
-         * uses the same backend. We may be called to create an engine 
-         * ourself. */
-        if (req_engine_push(engine_type, r, proxy_engine_init) == APR_SUCCESS) {
-            if (ctx->engine == NULL) {
-                /* request has been assigned to an engine in another thread */
-                return SUSPENDED;
-            }
-        }
-    }
-    
-    if (!ctx->engine) {
-        /* No engine was available or has been initialized, handle this
-         * request just by ourself. */
-        ctx->engine_id = apr_psprintf(ctx->pool, "eng-proxy-%ld", c->id);
-        ctx->engine_type = engine_type;
-        ctx->engine_pool = ctx->pool;
-        ctx->req_buffer_size = (32*1024);
-        ctx->standalone = 1;
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, 
-                      "h2_proxy_http2(%ld): setup standalone engine for type %s", 
-                      c->id, engine_type);
-    }
-    else {
-        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, 
-                      "H2: hosting engine %s", ctx->engine_id);
-    }
-
-    return h2_proxy_fifo_push(ctx->requests, r);
-}
-
 static int proxy_http2_handler(request_rec *r, 
                                proxy_worker *worker,
                                proxy_server_conf *conf,
@@ -477,7 +292,7 @@ static int proxy_http2_handler(request_r
                                const char *proxyname,
                                apr_port_t proxyport)
 {
-    const char *proxy_func;
+    const char *proxy_func, *task_id;
     char *locurl = url, *u;
     apr_size_t slen;
     int is_ssl = 0;
@@ -509,34 +324,35 @@ static int proxy_http2_handler(request_r
         default:
             return DECLINED;
     }
+
+    task_id = apr_table_get(r->connection->notes, H2_TASK_ID_NOTE);
     
     ctx = apr_pcalloc(r->pool, sizeof(*ctx));
-    ctx->master     = r->connection->master? r->connection->master : r->connection;
-    ctx->owner      = r->connection;
-    ctx->pool       = r->pool;
-    ctx->rbase      = r;
-    ctx->server     = r->server;
+    ctx->master = r->connection->master? r->connection->master : r->connection;
+    ctx->id = task_id? task_id : apr_psprintf(r->pool, "%ld", (long)ctx->master->id);
+    ctx->owner = r->connection;
+    ctx->pool = r->pool;
+    ctx->server = r->server;
     ctx->proxy_func = proxy_func;
-    ctx->is_ssl     = is_ssl;
-    ctx->worker     = worker;
-    ctx->conf       = conf;
-    ctx->flushall   = apr_table_get(r->subprocess_env, "proxy-flushall")? 1 : 0;
-    ctx->r_status   = HTTP_SERVICE_UNAVAILABLE;
-    
-    h2_proxy_fifo_set_create(&ctx->requests, ctx->pool, 100);
+    ctx->is_ssl = is_ssl;
+    ctx->worker = worker;
+    ctx->conf = conf;
+    ctx->flushall = apr_table_get(r->subprocess_env, "proxy-flushall")? 1 : 0;
+    ctx->req_buffer_size = (32*1024);
+    ctx->r = r;
+    ctx->r_status = status = HTTP_SERVICE_UNAVAILABLE;
+    ctx->r_done = 0;
+    ctx->r_may_retry =  1;
     
     ap_set_module_config(ctx->owner->conn_config, &proxy_http2_module, ctx);
 
     /* scheme says, this is for us. */
-    apr_table_setn(ctx->rbase->notes, H2_PROXY_REQ_URL_NOTE, url);
-    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->rbase, 
+    apr_table_setn(ctx->r->notes, H2_PROXY_REQ_URL_NOTE, url);
+    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->r, 
                   "H2: serving URL %s", url);
     
 run_connect:    
-    if (ctx->master->aborted) {
-        ctx->r_status = APR_ECONNABORTED;
-        goto cleanup;
-    }
+    if (ctx->master->aborted) goto cleanup;
 
     /* Get a proxy_conn_rec from the worker, might be a new one, might
      * be one still open from another request, or it might fail if the
@@ -551,7 +367,7 @@ run_connect:
     /* Step One: Determine the URL to connect to (might be a proxy),
      * initialize the backend accordingly and determine the server 
      * port string we can expect in responses. */
-    if ((status = ap_proxy_determine_connection(ctx->pool, ctx->rbase, conf, worker, 
+    if ((status = ap_proxy_determine_connection(ctx->pool, ctx->r, conf, worker, 
                                                 ctx->p_conn, &uri, &locurl, 
                                                 proxyname, proxyport, 
                                                 ctx->server_portstr,
@@ -559,17 +375,6 @@ run_connect:
         goto cleanup;
     }
     
-    /* If we are not already hosting an engine, try to push the request 
-     * to an already existing engine or host a new engine here. */
-    if (r && !ctx->engine) {
-        ctx->r_status = push_request_somewhere(ctx, r);
-        r = NULL;
-        if (ctx->r_status == SUSPENDED) {
-            /* request was pushed to another thread, leave processing here */
-            goto cleanup;
-        }
-    }
-    
     /* Step Two: Make the Connection (or check that an already existing
      * socket is still usable). On success, we have a socket connected to
      * backend->hostname. */
@@ -578,19 +383,19 @@ run_connect:
         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->owner, APLOGNO(03352)
                       "H2: failed to make connection to backend: %s",
                       ctx->p_conn->hostname);
-        goto reconnect;
+        goto cleanup;
     }
     
     /* Step Three: Create conn_rec for the socket we have open now. */
     if (!ctx->p_conn->connection) {
-        status = ap_proxy_connection_create_ex(ctx->proxy_func,
-                                               ctx->p_conn, ctx->rbase);
+        status = ap_proxy_connection_create_ex(ctx->proxy_func, ctx->p_conn, ctx->r);
         if (status != OK) {
             ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner, APLOGNO(03353)
                           "setup new connection: is_ssl=%d %s %s %s", 
                           ctx->p_conn->is_ssl, ctx->p_conn->ssl_hostname, 
                           locurl, ctx->p_conn->hostname);
-            goto reconnect;
+            ctx->r_status = status;
+            goto cleanup;
         }
         
         if (!ctx->p_conn->data && ctx->is_ssl) {
@@ -600,7 +405,7 @@ run_connect:
             apr_table_setn(ctx->p_conn->connection->notes,
                            "proxy-request-alpn-protos", "h2");
             if (ctx->p_conn->ssl_hostname) {
-                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, ctx->owner, 
+                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->owner, 
                               "set SNI to %s for (%s)", 
                               ctx->p_conn->ssl_hostname, 
                               ctx->p_conn->hostname);
@@ -610,33 +415,11 @@ run_connect:
         }
     }
 
-run_session:
-    if (ctx->owner->aborted) {
-        ctx->r_status = APR_ECONNABORTED;
-        goto cleanup;
-    }
+    if (ctx->master->aborted) goto cleanup;
+    status = ctx_run(ctx);
 
-    status = proxy_engine_run(ctx);
-    if (status == APR_SUCCESS) {
-        /* session and connection still ok */
-        if (next_request(ctx, 1) == APR_SUCCESS) {
-            /* more requests, run again */
-            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->owner, APLOGNO(03376)
-                          "run_session, again");
-            goto run_session;
-        }
-        /* done */
-        ctx->engine = NULL;
-    }
-
-reconnect:
-    if (ctx->master->aborted) {
-        ctx->r_status = APR_ECONNABORTED;
-        goto cleanup;
-    }
-
-    if (next_request(ctx, 1) == APR_SUCCESS) {
-        /* Still more to do, tear down old conn and start over */
+    if (ctx->r_status != APR_SUCCESS && ctx->r_may_retry && !ctx->master->aborted) {
+        /* Not successfully processed, but may retry, tear down old conn and start over */
         if (ctx->p_conn) {
             ctx->p_conn->close = 1;
 #if AP_MODULE_MAGIC_AT_LEAST(20140207, 2)
@@ -646,12 +429,12 @@ reconnect:
             ctx->p_conn = NULL;
         }
         ++reconnects;
-        if (reconnects < 5 && !ctx->master->aborted) {
+        if (reconnects < 5) {
             goto run_connect;
         } 
         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctx->owner, APLOGNO(10023)
-                      "giving up after %d reconnects, %d requests todo",
-                      reconnects, h2_proxy_fifo_count(ctx->requests));
+                      "giving up after %d reconnects, request-done=%d",
+                      reconnects, ctx->r_done);
     }
     
 cleanup:
@@ -661,17 +444,12 @@ cleanup:
             ctx->p_conn->close = 1;
         }
 #if AP_MODULE_MAGIC_AT_LEAST(20140207, 2)
-        proxy_run_detach_backend(ctx->rbase, ctx->p_conn);
+        proxy_run_detach_backend(ctx->r, ctx->p_conn);
 #endif
         ap_proxy_release_connection(ctx->proxy_func, ctx->p_conn, ctx->server);
         ctx->p_conn = NULL;
     }
 
-    /* Any requests we still have need to fail */
-    while (APR_SUCCESS == h2_proxy_fifo_try_pull(ctx->requests, (void**)&r)) {
-        request_done(ctx, r, HTTP_SERVICE_UNAVAILABLE, 1);
-    }
-    
     ap_set_module_config(ctx->owner->conn_config, &proxy_http2_module, NULL);
     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner, 
                   APLOGNO(03377) "leaving handler");



Re: svn commit: r1854963 - in /httpd/httpd/trunk: ./ modules/http2/

Posted by Ruediger Pluem <rp...@apache.org>.

On 8/17/22 9:57 AM, Stefan Eissing via dev wrote:
> 
> 
>> Am 17.08.2022 um 09:26 schrieb Ruediger Pluem <rp...@apache.org>:
>>
>>
>>
>> On 3/7/19 10:41 AM, icing@apache.org wrote:
>>> Author: icing
>>> Date: Thu Mar  7 09:41:15 2019
>>> New Revision: 1854963
>>>
>>> URL: http://svn.apache.org/viewvc?rev=1854963&view=rev
>>> Log:
>>>  *) mod_http2: new configuration directive: ```H2Padding numbits``` to control 
>>>     padding of HTTP/2 payload frames. 'numbits' is a number from 0-8,
>>>     controlling the range of padding bytes added to a frame. The actual number
>>>     added is chosen randomly per frame. This applies to HEADERS, DATA and PUSH_PROMISE
>>>     frames equally. The default continues to be 0, e.g. no padding. [Stefan Eissing] 
>>>
>>>  *) mod_http2: ripping out all the h2_req_engine internal features now that mod_proxy_http2
>>>     has no more need for it. Optional functions are still declared but no longer implemented.
>>>     While previous mod_proxy_http2 will work with this, it is recommeneded to run the matching
>>>     versions of both modules. [Stefan Eissing]
>>>
>>>  *) mod_proxy_http2: changed mod_proxy_http2 implementation and fixed several bugs which
>>>     resolve PR63170. The proxy module does now a single h2 request on the (reused)
>>>     connection and returns. [Stefan Eissing]
>>>
>>>
>>> Removed:
>>>    httpd/httpd/trunk/modules/http2/h2_ngn_shed.c
>>>    httpd/httpd/trunk/modules/http2/h2_ngn_shed.h
>>> Modified:
>>>    httpd/httpd/trunk/CHANGES
>>>    httpd/httpd/trunk/modules/http2/config2.m4
>>>    httpd/httpd/trunk/modules/http2/h2.h
>>>    httpd/httpd/trunk/modules/http2/h2_config.c
>>>    httpd/httpd/trunk/modules/http2/h2_config.h
>>>    httpd/httpd/trunk/modules/http2/h2_conn_io.c
>>>    httpd/httpd/trunk/modules/http2/h2_mplx.c
>>>    httpd/httpd/trunk/modules/http2/h2_mplx.h
>>>    httpd/httpd/trunk/modules/http2/h2_proxy_session.c
>>>    httpd/httpd/trunk/modules/http2/h2_proxy_session.h
>>>    httpd/httpd/trunk/modules/http2/h2_request.c
>>>    httpd/httpd/trunk/modules/http2/h2_session.c
>>>    httpd/httpd/trunk/modules/http2/h2_session.h
>>>    httpd/httpd/trunk/modules/http2/h2_stream.c
>>>    httpd/httpd/trunk/modules/http2/h2_task.c
>>>    httpd/httpd/trunk/modules/http2/h2_task.h
>>>    httpd/httpd/trunk/modules/http2/h2_version.h
>>>    httpd/httpd/trunk/modules/http2/mod_http2.c
>>>    httpd/httpd/trunk/modules/http2/mod_http2.h
>>>    httpd/httpd/trunk/modules/http2/mod_proxy_http2.c
>>>
>>
>>> Modified: httpd/httpd/trunk/modules/http2/mod_http2.h
>>> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/mod_http2.h?rev=1854963&r1=1854962&r2=1854963&view=diff
>>> ==============================================================================
>>> --- httpd/httpd/trunk/modules/http2/mod_http2.h (original)
>>> +++ httpd/httpd/trunk/modules/http2/mod_http2.h Thu Mar  7 09:41:15 2019
>>> @@ -30,22 +30,20 @@ APR_DECLARE_OPTIONAL_FN(int,
>>>
>>>
>>> /*******************************************************************************
>>> - * HTTP/2 request engines
>>> + * START HTTP/2 request engines (DEPRECATED)
>>>  ******************************************************************************/
>>> +
>>> +/* The following functions were introduced for the experimental mod_proxy_http2
>>> + * support, but have been abandoned since.
>>> + * They are still declared here for backward compatibiliy, in case someone
>>> + * tries to build an old mod_proxy_http2 against it, but will disappear
>>> + * completely sometime in the future.
>>> + */ 
>>>
>>> struct apr_thread_cond_t;
>>> -
>>> typedef struct h2_req_engine h2_req_engine;
>>> -
>>> typedef void http2_output_consumed(void *ctx, conn_rec *c, apr_off_t consumed);
>>>
>>> -/**
>>> - * Initialize a h2_req_engine. The structure will be passed in but
>>> - * only the name and master are set. The function should initialize
>>> - * all fields.
>>> - * @param engine the allocated, partially filled structure
>>> - * @param r      the first request to process, or NULL
>>> - */
>>> typedef apr_status_t http2_req_engine_init(h2_req_engine *engine, 
>>>                                            const char *id, 
>>>                                            const char *type,
>>> @@ -55,35 +53,11 @@ typedef apr_status_t http2_req_engine_in
>>>                                            http2_output_consumed **pconsumed,
>>>                                            void **pbaton);
>>>
>>> -/**
>>> - * Push a request to an engine with the specified name for further processing.
>>> - * If no such engine is available, einit is not NULL, einit is called 
>>> - * with a new engine record and the caller is responsible for running the
>>> - * new engine instance.
>>> - * @param engine_type the type of the engine to add the request to
>>> - * @param r           the request to push to an engine for processing
>>> - * @param einit       an optional initialization callback for a new engine 
>>> - *                    of the requested type, should no instance be available.
>>> - *                    By passing a non-NULL callback, the caller is willing
>>> - *                    to init and run a new engine itself.
>>> - * @return APR_SUCCESS iff slave was successfully added to an engine
>>> - */
>>> APR_DECLARE_OPTIONAL_FN(apr_status_t, 
>>>                         http2_req_engine_push, (const char *engine_type, 
>>>                                                 request_rec *r,
>>>                                                 http2_req_engine_init *einit));
>>>
>>> -/**
>>> - * Get a new request for processing in this engine.
>>> - * @param engine      the engine which is done processing the slave
>>> - * @param block       if call should block waiting for request to come
>>> - * @param capacity    how many parallel requests are acceptable
>>> - * @param pr          the request that needs processing or NULL
>>> - * @return APR_SUCCESS if new request was assigned
>>> - *         APR_EAGAIN  if no new request is available
>>> - *         APR_EOF          if engine may shut down, as no more request will be scheduled
>>> - *         APR_ECONNABORTED if the engine needs to shut down immediately
>>> - */
>>> APR_DECLARE_OPTIONAL_FN(apr_status_t, 
>>>                         http2_req_engine_pull, (h2_req_engine *engine, 
>>>                                                 apr_read_type_e block,
>>> @@ -98,4 +72,8 @@ APR_DECLARE_OPTIONAL_FN(void,
>>>                         http2_get_num_workers, (server_rec *s,
>>>                                                 int *minw, int *max));
>>
>> Is http2_get_num_workers really deprecated? I think it should move before this block. Something like the below?
> 
> That looks reasonable. When I added the deprecation warning, I did not add how far that extends.

r1903478

Regards

Rüdiger


Re: svn commit: r1854963 - in /httpd/httpd/trunk: ./ modules/http2/

Posted by Stefan Eissing via dev <de...@httpd.apache.org>.

> Am 17.08.2022 um 09:26 schrieb Ruediger Pluem <rp...@apache.org>:
> 
> 
> 
> On 3/7/19 10:41 AM, icing@apache.org wrote:
>> Author: icing
>> Date: Thu Mar  7 09:41:15 2019
>> New Revision: 1854963
>> 
>> URL: http://svn.apache.org/viewvc?rev=1854963&view=rev
>> Log:
>>  *) mod_http2: new configuration directive: ```H2Padding numbits``` to control 
>>     padding of HTTP/2 payload frames. 'numbits' is a number from 0-8,
>>     controlling the range of padding bytes added to a frame. The actual number
>>     added is chosen randomly per frame. This applies to HEADERS, DATA and PUSH_PROMISE
>>     frames equally. The default continues to be 0, e.g. no padding. [Stefan Eissing] 
>> 
>>  *) mod_http2: ripping out all the h2_req_engine internal features now that mod_proxy_http2
>>     has no more need for it. Optional functions are still declared but no longer implemented.
>>     While previous mod_proxy_http2 will work with this, it is recommeneded to run the matching
>>     versions of both modules. [Stefan Eissing]
>> 
>>  *) mod_proxy_http2: changed mod_proxy_http2 implementation and fixed several bugs which
>>     resolve PR63170. The proxy module does now a single h2 request on the (reused)
>>     connection and returns. [Stefan Eissing]
>> 
>> 
>> Removed:
>>    httpd/httpd/trunk/modules/http2/h2_ngn_shed.c
>>    httpd/httpd/trunk/modules/http2/h2_ngn_shed.h
>> Modified:
>>    httpd/httpd/trunk/CHANGES
>>    httpd/httpd/trunk/modules/http2/config2.m4
>>    httpd/httpd/trunk/modules/http2/h2.h
>>    httpd/httpd/trunk/modules/http2/h2_config.c
>>    httpd/httpd/trunk/modules/http2/h2_config.h
>>    httpd/httpd/trunk/modules/http2/h2_conn_io.c
>>    httpd/httpd/trunk/modules/http2/h2_mplx.c
>>    httpd/httpd/trunk/modules/http2/h2_mplx.h
>>    httpd/httpd/trunk/modules/http2/h2_proxy_session.c
>>    httpd/httpd/trunk/modules/http2/h2_proxy_session.h
>>    httpd/httpd/trunk/modules/http2/h2_request.c
>>    httpd/httpd/trunk/modules/http2/h2_session.c
>>    httpd/httpd/trunk/modules/http2/h2_session.h
>>    httpd/httpd/trunk/modules/http2/h2_stream.c
>>    httpd/httpd/trunk/modules/http2/h2_task.c
>>    httpd/httpd/trunk/modules/http2/h2_task.h
>>    httpd/httpd/trunk/modules/http2/h2_version.h
>>    httpd/httpd/trunk/modules/http2/mod_http2.c
>>    httpd/httpd/trunk/modules/http2/mod_http2.h
>>    httpd/httpd/trunk/modules/http2/mod_proxy_http2.c
>> 
> 
>> Modified: httpd/httpd/trunk/modules/http2/mod_http2.h
>> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/mod_http2.h?rev=1854963&r1=1854962&r2=1854963&view=diff
>> ==============================================================================
>> --- httpd/httpd/trunk/modules/http2/mod_http2.h (original)
>> +++ httpd/httpd/trunk/modules/http2/mod_http2.h Thu Mar  7 09:41:15 2019
>> @@ -30,22 +30,20 @@ APR_DECLARE_OPTIONAL_FN(int,
>> 
>> 
>> /*******************************************************************************
>> - * HTTP/2 request engines
>> + * START HTTP/2 request engines (DEPRECATED)
>>  ******************************************************************************/
>> +
>> +/* The following functions were introduced for the experimental mod_proxy_http2
>> + * support, but have been abandoned since.
>> + * They are still declared here for backward compatibiliy, in case someone
>> + * tries to build an old mod_proxy_http2 against it, but will disappear
>> + * completely sometime in the future.
>> + */ 
>> 
>> struct apr_thread_cond_t;
>> -
>> typedef struct h2_req_engine h2_req_engine;
>> -
>> typedef void http2_output_consumed(void *ctx, conn_rec *c, apr_off_t consumed);
>> 
>> -/**
>> - * Initialize a h2_req_engine. The structure will be passed in but
>> - * only the name and master are set. The function should initialize
>> - * all fields.
>> - * @param engine the allocated, partially filled structure
>> - * @param r      the first request to process, or NULL
>> - */
>> typedef apr_status_t http2_req_engine_init(h2_req_engine *engine, 
>>                                            const char *id, 
>>                                            const char *type,
>> @@ -55,35 +53,11 @@ typedef apr_status_t http2_req_engine_in
>>                                            http2_output_consumed **pconsumed,
>>                                            void **pbaton);
>> 
>> -/**
>> - * Push a request to an engine with the specified name for further processing.
>> - * If no such engine is available, einit is not NULL, einit is called 
>> - * with a new engine record and the caller is responsible for running the
>> - * new engine instance.
>> - * @param engine_type the type of the engine to add the request to
>> - * @param r           the request to push to an engine for processing
>> - * @param einit       an optional initialization callback for a new engine 
>> - *                    of the requested type, should no instance be available.
>> - *                    By passing a non-NULL callback, the caller is willing
>> - *                    to init and run a new engine itself.
>> - * @return APR_SUCCESS iff slave was successfully added to an engine
>> - */
>> APR_DECLARE_OPTIONAL_FN(apr_status_t, 
>>                         http2_req_engine_push, (const char *engine_type, 
>>                                                 request_rec *r,
>>                                                 http2_req_engine_init *einit));
>> 
>> -/**
>> - * Get a new request for processing in this engine.
>> - * @param engine      the engine which is done processing the slave
>> - * @param block       if call should block waiting for request to come
>> - * @param capacity    how many parallel requests are acceptable
>> - * @param pr          the request that needs processing or NULL
>> - * @return APR_SUCCESS if new request was assigned
>> - *         APR_EAGAIN  if no new request is available
>> - *         APR_EOF          if engine may shut down, as no more request will be scheduled
>> - *         APR_ECONNABORTED if the engine needs to shut down immediately
>> - */
>> APR_DECLARE_OPTIONAL_FN(apr_status_t, 
>>                         http2_req_engine_pull, (h2_req_engine *engine, 
>>                                                 apr_read_type_e block,
>> @@ -98,4 +72,8 @@ APR_DECLARE_OPTIONAL_FN(void,
>>                         http2_get_num_workers, (server_rec *s,
>>                                                 int *minw, int *max));
> 
> Is http2_get_num_workers really deprecated? I think it should move before this block. Something like the below?

That looks reasonable. When I added the deprecation warning, I did not add how far that extends.

Cheers,
Stefan

> 
> Index: modules/http2/mod_http2.h
> ===================================================================
> --- modules/http2/mod_http2.h	(revision 1903169)
> +++ modules/http2/mod_http2.h	(working copy)
> @@ -28,6 +28,9 @@
> APR_DECLARE_OPTIONAL_FN(int,
>                         http2_is_h2, (conn_rec *));
> 
> +APR_DECLARE_OPTIONAL_FN(void,
> +                        http2_get_num_workers, (server_rec *s,
> +                                                int *minw, int *max));
> 
> /*******************************************************************************
>  * START HTTP/2 request engines (DEPRECATED)
> @@ -68,9 +71,6 @@
>                                                 conn_rec *rconn,
>                                                 apr_status_t status));
> 
> -APR_DECLARE_OPTIONAL_FN(void,
> -                        http2_get_num_workers, (server_rec *s,
> -                                                int *minw, int *max));
> 
> /*******************************************************************************
>  * END HTTP/2 request engines (DEPRECATED)
> 
> 
>> 
>> +/*******************************************************************************
>> + * END HTTP/2 request engines (DEPRECATED)
>> + ******************************************************************************/
>> +
>> #endif
>> 
> 
> 
> Regards
> 
> Rüdiger


Re: svn commit: r1854963 - in /httpd/httpd/trunk: ./ modules/http2/

Posted by Ruediger Pluem <rp...@apache.org>.

On 3/7/19 10:41 AM, icing@apache.org wrote:
> Author: icing
> Date: Thu Mar  7 09:41:15 2019
> New Revision: 1854963
> 
> URL: http://svn.apache.org/viewvc?rev=1854963&view=rev
> Log:
>   *) mod_http2: new configuration directive: ```H2Padding numbits``` to control 
>      padding of HTTP/2 payload frames. 'numbits' is a number from 0-8,
>      controlling the range of padding bytes added to a frame. The actual number
>      added is chosen randomly per frame. This applies to HEADERS, DATA and PUSH_PROMISE
>      frames equally. The default continues to be 0, e.g. no padding. [Stefan Eissing] 
>   
>   *) mod_http2: ripping out all the h2_req_engine internal features now that mod_proxy_http2
>      has no more need for it. Optional functions are still declared but no longer implemented.
>      While previous mod_proxy_http2 will work with this, it is recommeneded to run the matching
>      versions of both modules. [Stefan Eissing]
>   
>   *) mod_proxy_http2: changed mod_proxy_http2 implementation and fixed several bugs which
>      resolve PR63170. The proxy module does now a single h2 request on the (reused)
>      connection and returns. [Stefan Eissing]
> 
> 
> Removed:
>     httpd/httpd/trunk/modules/http2/h2_ngn_shed.c
>     httpd/httpd/trunk/modules/http2/h2_ngn_shed.h
> Modified:
>     httpd/httpd/trunk/CHANGES
>     httpd/httpd/trunk/modules/http2/config2.m4
>     httpd/httpd/trunk/modules/http2/h2.h
>     httpd/httpd/trunk/modules/http2/h2_config.c
>     httpd/httpd/trunk/modules/http2/h2_config.h
>     httpd/httpd/trunk/modules/http2/h2_conn_io.c
>     httpd/httpd/trunk/modules/http2/h2_mplx.c
>     httpd/httpd/trunk/modules/http2/h2_mplx.h
>     httpd/httpd/trunk/modules/http2/h2_proxy_session.c
>     httpd/httpd/trunk/modules/http2/h2_proxy_session.h
>     httpd/httpd/trunk/modules/http2/h2_request.c
>     httpd/httpd/trunk/modules/http2/h2_session.c
>     httpd/httpd/trunk/modules/http2/h2_session.h
>     httpd/httpd/trunk/modules/http2/h2_stream.c
>     httpd/httpd/trunk/modules/http2/h2_task.c
>     httpd/httpd/trunk/modules/http2/h2_task.h
>     httpd/httpd/trunk/modules/http2/h2_version.h
>     httpd/httpd/trunk/modules/http2/mod_http2.c
>     httpd/httpd/trunk/modules/http2/mod_http2.h
>     httpd/httpd/trunk/modules/http2/mod_proxy_http2.c
> 

> Modified: httpd/httpd/trunk/modules/http2/mod_http2.h
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/mod_http2.h?rev=1854963&r1=1854962&r2=1854963&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/http2/mod_http2.h (original)
> +++ httpd/httpd/trunk/modules/http2/mod_http2.h Thu Mar  7 09:41:15 2019
> @@ -30,22 +30,20 @@ APR_DECLARE_OPTIONAL_FN(int,
>  
>  
>  /*******************************************************************************
> - * HTTP/2 request engines
> + * START HTTP/2 request engines (DEPRECATED)
>   ******************************************************************************/
> +
> +/* The following functions were introduced for the experimental mod_proxy_http2
> + * support, but have been abandoned since.
> + * They are still declared here for backward compatibiliy, in case someone
> + * tries to build an old mod_proxy_http2 against it, but will disappear
> + * completely sometime in the future.
> + */ 
>   
>  struct apr_thread_cond_t;
> -
>  typedef struct h2_req_engine h2_req_engine;
> -
>  typedef void http2_output_consumed(void *ctx, conn_rec *c, apr_off_t consumed);
>  
> -/**
> - * Initialize a h2_req_engine. The structure will be passed in but
> - * only the name and master are set. The function should initialize
> - * all fields.
> - * @param engine the allocated, partially filled structure
> - * @param r      the first request to process, or NULL
> - */
>  typedef apr_status_t http2_req_engine_init(h2_req_engine *engine, 
>                                             const char *id, 
>                                             const char *type,
> @@ -55,35 +53,11 @@ typedef apr_status_t http2_req_engine_in
>                                             http2_output_consumed **pconsumed,
>                                             void **pbaton);
>  
> -/**
> - * Push a request to an engine with the specified name for further processing.
> - * If no such engine is available, einit is not NULL, einit is called 
> - * with a new engine record and the caller is responsible for running the
> - * new engine instance.
> - * @param engine_type the type of the engine to add the request to
> - * @param r           the request to push to an engine for processing
> - * @param einit       an optional initialization callback for a new engine 
> - *                    of the requested type, should no instance be available.
> - *                    By passing a non-NULL callback, the caller is willing
> - *                    to init and run a new engine itself.
> - * @return APR_SUCCESS iff slave was successfully added to an engine
> - */
>  APR_DECLARE_OPTIONAL_FN(apr_status_t, 
>                          http2_req_engine_push, (const char *engine_type, 
>                                                  request_rec *r,
>                                                  http2_req_engine_init *einit));
>  
> -/**
> - * Get a new request for processing in this engine.
> - * @param engine      the engine which is done processing the slave
> - * @param block       if call should block waiting for request to come
> - * @param capacity    how many parallel requests are acceptable
> - * @param pr          the request that needs processing or NULL
> - * @return APR_SUCCESS if new request was assigned
> - *         APR_EAGAIN  if no new request is available
> - *         APR_EOF          if engine may shut down, as no more request will be scheduled
> - *         APR_ECONNABORTED if the engine needs to shut down immediately
> - */
>  APR_DECLARE_OPTIONAL_FN(apr_status_t, 
>                          http2_req_engine_pull, (h2_req_engine *engine, 
>                                                  apr_read_type_e block,
> @@ -98,4 +72,8 @@ APR_DECLARE_OPTIONAL_FN(void,
>                          http2_get_num_workers, (server_rec *s,
>                                                  int *minw, int *max));

Is http2_get_num_workers really deprecated? I think it should move before this block. Something like the below?

Index: modules/http2/mod_http2.h
===================================================================
--- modules/http2/mod_http2.h	(revision 1903169)
+++ modules/http2/mod_http2.h	(working copy)
@@ -28,6 +28,9 @@
 APR_DECLARE_OPTIONAL_FN(int,
                         http2_is_h2, (conn_rec *));

+APR_DECLARE_OPTIONAL_FN(void,
+                        http2_get_num_workers, (server_rec *s,
+                                                int *minw, int *max));

 /*******************************************************************************
  * START HTTP/2 request engines (DEPRECATED)
@@ -68,9 +71,6 @@
                                                 conn_rec *rconn,
                                                 apr_status_t status));

-APR_DECLARE_OPTIONAL_FN(void,
-                        http2_get_num_workers, (server_rec *s,
-                                                int *minw, int *max));

 /*******************************************************************************
  * END HTTP/2 request engines (DEPRECATED)


>  
> +/*******************************************************************************
> + * END HTTP/2 request engines (DEPRECATED)
> + ******************************************************************************/
> +
>  #endif
> 


Regards

Rüdiger