File apache2-mod_http2-1.15.4.patch of Package apache2.27541
diff -upr httpd-2.4.33/modules/http2/h2_config.c httpd-2.4.41/modules/http2/h2_config.c
--- httpd-2.4.33/modules/http2/h2_config.c 2019-08-22 09:53:22.105935133 +0200
+++ httpd-2.4.41/modules/http2/h2_config.c 2019-03-13 16:00:57.000000000 +0100
@@ -62,16 +62,16 @@ typedef struct h2_config {
int stream_max_mem_size; /* max # bytes held in memory/stream */
apr_array_header_t *alt_svcs; /* h2_alt_svc specs for this server */
int alt_svc_max_age; /* seconds clients can rely on alt-svc info*/
- int serialize_headers; /* Use serialized HTTP/1.1 headers for
+ int serialize_headers; /* Use serialized HTTP/1.1 headers for
processing, better compatibility */
int h2_direct; /* if mod_h2 is active directly */
- int modern_tls_only; /* Accept only modern TLS in HTTP/2 connections */
+ int modern_tls_only; /* Accept only modern TLS in HTTP/2 connections */
int h2_upgrade; /* Allow HTTP/1 upgrade to h2/h2c */
apr_int64_t tls_warmup_size; /* Amount of TLS data to send before going full write size */
int tls_cooldown_secs; /* Seconds of idle time before going back to small TLS records */
int h2_push; /* if HTTP/2 server push is enabled */
struct apr_hash_t *priorities;/* map of content-type to h2_priority records */
-
+
int push_diary_size; /* # of entries in push diary */
int copy_files; /* if files shall be copied vs setaside on output */
apr_array_header_t *push_list;/* list of h2_push_res configurations */
@@ -215,7 +215,7 @@ void *h2_config_create_dir(apr_pool_t *p
h2_dir_config *conf = (h2_dir_config *)apr_pcalloc(pool, sizeof(h2_dir_config));
const char *s = x? x : "unknown";
char *name = apr_pstrcat(pool, "dir[", s, "]", NULL);
-
+
conf->name = name;
conf->alt_svc_max_age = DEF_VAL;
conf->h2_upgrade = DEF_VAL;
@@ -379,7 +379,7 @@ static h2_config *h2_config_sget(server_
static const h2_dir_config *h2_config_rget(request_rec *r)
{
- h2_dir_config *cfg = (h2_dir_config *)ap_get_module_config(r->per_dir_config,
+ h2_dir_config *cfg = (h2_dir_config *)ap_get_module_config(r->per_dir_config,
&http2_module);
ap_assert(cfg);
return cfg;
@@ -451,7 +451,7 @@ static void h2_config_seti64(h2_dir_conf
static const h2_config *h2_config_get(conn_rec *c)
{
h2_ctx *ctx = h2_ctx_get(c, 0);
-
+
if (ctx) {
if (ctx->config) {
return ctx->config;
@@ -461,7 +461,7 @@ static const h2_config *h2_config_get(co
return ctx->config;
}
}
-
+
return h2_config_sget(c->base_server);
}
@@ -510,11 +510,11 @@ apr_array_header_t *h2_config_push_list(
{
const h2_config *sconf;
const h2_dir_config *conf = h2_config_rget(r);
-
+
if (conf && conf->push_list) {
return conf->push_list;
}
- sconf = h2_config_sget(r->server);
+ sconf = h2_config_sget(r->server);
return sconf? sconf->push_list : NULL;
}
@@ -522,11 +522,11 @@ apr_array_header_t *h2_config_alt_svcs(r
{
const h2_config *sconf;
const h2_dir_config *conf = h2_config_rget(r);
-
+
if (conf && conf->alt_svcs) {
return conf->alt_svcs;
}
- sconf = h2_config_sget(r->server);
+ sconf = h2_config_sget(r->server);
return sconf? sconf->alt_svcs : NULL;
}
@@ -881,10 +881,10 @@ static const char *h2_conf_set_early_hin
if (!strcasecmp(value, "On")) val = 1;
else if (!strcasecmp(value, "Off")) val = 0;
else return "value must be On or Off";
-
+
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_EARLY_HINTS, val);
if (cmd->path) {
- ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, cmd->pool,
+ ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, cmd->pool,
"H2EarlyHints = %d on path %s", val, cmd->path);
}
return NULL;
@@ -893,7 +893,7 @@ static const char *h2_conf_set_early_hin
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";
@@ -911,7 +911,7 @@ void h2_get_num_workers(server_rec *s, i
int threads_per_child = 0;
*minw = h2_config_sgeti(s, H2_CONF_MIN_WORKERS);
- *maxw = h2_config_sgeti(s, H2_CONF_MAX_WORKERS);
+ *maxw = h2_config_sgeti(s, H2_CONF_MAX_WORKERS);
ap_mpm_query(AP_MPMQ_MAX_THREADS, &threads_per_child);
if (*minw <= 0) {
diff -upr httpd-2.4.33/modules/http2/h2_config.h httpd-2.4.41/modules/http2/h2_config.h
--- httpd-2.4.33/modules/http2/h2_config.h 2019-08-22 09:53:22.105935133 +0200
+++ httpd-2.4.41/modules/http2/h2_config.h 2019-03-13 16:00:57.000000000 +0100
@@ -66,21 +66,21 @@ extern const command_rec h2_cmds[];
int h2_config_geti(request_rec *r, server_rec *s, h2_config_var_t var);
apr_int64_t h2_config_geti64(request_rec *r, server_rec *s, h2_config_var_t var);
-/**
+/**
* Get the configured value for variable <var> at the given connection.
*/
int h2_config_cgeti(conn_rec *c, h2_config_var_t var);
apr_int64_t h2_config_cgeti64(conn_rec *c, h2_config_var_t var);
-/**
+/**
* Get the configured value for variable <var> at the given server.
*/
int h2_config_sgeti(server_rec *s, h2_config_var_t var);
apr_int64_t h2_config_sgeti64(server_rec *s, h2_config_var_t var);
-/**
+/**
* Get the configured value for variable <var> at the given request,
- * if configured for the request location.
+ * if configured for the request location.
* Fallback to request server config otherwise.
*/
int h2_config_rgeti(request_rec *r, h2_config_var_t var);
diff -upr httpd-2.4.33/modules/http2/h2_conn.c httpd-2.4.41/modules/http2/h2_conn.c
--- httpd-2.4.33/modules/http2/h2_conn.c 2019-08-22 09:53:22.193935648 +0200
+++ httpd-2.4.41/modules/http2/h2_conn.c 2019-08-01 10:18:03.000000000 +0200
@@ -188,7 +188,7 @@ apr_status_t h2_conn_setup(conn_rec *c,
ctx = h2_ctx_get(c, 1);
h2_ctx_session_set(ctx, session);
}
-
+
return status;
}
@@ -341,7 +341,7 @@ conn_rec *h2_slave_create(conn_rec *mast
ap_set_module_config(c->conn_config, mpm, cfg);
}
- ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
"h2_slave(%s): created", c->log_id);
return c;
}
diff -upr httpd-2.4.33/modules/http2/h2_conn_io.c httpd-2.4.41/modules/http2/h2_conn_io.c
--- httpd-2.4.33/modules/http2/h2_conn_io.c 2019-08-22 09:53:22.105935133 +0200
+++ httpd-2.4.41/modules/http2/h2_conn_io.c 2019-03-13 16:00:57.000000000 +0100
@@ -50,7 +50,7 @@
* should make optimizations at the layer that writes
* to TLS easier.
*/
-#define WRITE_SIZE_MAX (TLS_DATA_MAX)
+#define WRITE_SIZE_MAX (TLS_DATA_MAX)
static void h2_conn_io_bb_log(conn_rec *c, int stream_id, int level,
@@ -141,7 +141,7 @@ apr_status_t h2_conn_io_init(h2_conn_io
* see https://issues.apache.org/jira/browse/TS-2503
*/
io->warmup_size = h2_config_sgeti64(s, H2_CONF_TLS_WARMUP_SIZE);
- io->cooldown_usecs = (h2_config_sgeti(s, H2_CONF_TLS_COOLDOWN_SECS)
+ io->cooldown_usecs = (h2_config_sgeti(s, H2_CONF_TLS_COOLDOWN_SECS)
* APR_USEC_PER_SEC);
io->write_size = (io->cooldown_usecs > 0?
WRITE_SIZE_INITIAL : WRITE_SIZE_MAX);
diff -upr httpd-2.4.33/modules/http2/h2_filter.c httpd-2.4.41/modules/http2/h2_filter.c
--- httpd-2.4.33/modules/http2/h2_filter.c 2019-08-22 09:53:22.193935648 +0200
+++ httpd-2.4.41/modules/http2/h2_filter.c 2019-08-01 10:18:03.000000000 +0200
@@ -436,7 +436,7 @@ static apr_status_t h2_status_insert(h2_
h2_stream *stream = h2_mplx_stream_get(m, task->stream_id);
h2_session *s;
conn_rec *c;
-
+
apr_bucket_brigade *bb;
apr_bucket *e;
int32_t connFlowIn, connFlowOut;
@@ -450,7 +450,7 @@ static apr_status_t h2_status_insert(h2_
bb = apr_brigade_create(stream->pool, c->bucket_alloc);
- connFlowIn = nghttp2_session_get_effective_local_window_size(s->ngh2);
+ connFlowIn = nghttp2_session_get_effective_local_window_size(s->ngh2);
connFlowOut = nghttp2_session_get_remote_window_size(s->ngh2);
bbout(bb, "{\n");
diff -upr httpd-2.4.33/modules/http2/h2.h httpd-2.4.41/modules/http2/h2.h
--- httpd-2.4.33/modules/http2/h2.h 2019-08-22 09:53:22.109935157 +0200
+++ httpd-2.4.41/modules/http2/h2.h 2019-03-13 16:00:57.000000000 +0100
@@ -52,7 +52,7 @@ extern const char *H2_MAGIC_TOKEN;
#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)
+#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
diff -upr httpd-2.4.33/modules/http2/h2_h2.c httpd-2.4.41/modules/http2/h2_h2.c
--- httpd-2.4.33/modules/http2/h2_h2.c 2019-08-22 09:53:22.109935157 +0200
+++ httpd-2.4.41/modules/http2/h2_h2.c 2019-03-13 16:00:57.000000000 +0100
@@ -463,7 +463,7 @@ int h2_h2_is_tls(conn_rec *c)
return opt_ssl_is_https && opt_ssl_is_https(c);
}
-int h2_is_acceptable_connection(conn_rec *c, request_rec *r, int require_all)
+int h2_is_acceptable_connection(conn_rec *c, request_rec *r, int require_all)
{
int is_tls = h2_h2_is_tls(c);
@@ -584,7 +584,7 @@ int h2_h2_process_conn(conn_rec* c)
ctx = h2_ctx_get(c, 0);
s = ctx? ctx->server : c->base_server;
-
+
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn");
if (ctx && ctx->task) {
/* our stream pseudo connection */
@@ -645,7 +645,7 @@ int h2_h2_process_conn(conn_rec* c)
if (ctx) {
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "process_conn");
-
+
if (!h2_ctx_get_session(c)) {
status = h2_conn_setup(c, NULL, s);
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, c, "conn_setup");
@@ -688,7 +688,7 @@ static void check_push(request_rec *r, c
if (!r->expecting_100 && push_list && push_list->nelts > 0) {
int i, old_status;
const char *old_line;
-
+
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
"%s, early announcing %d resources for push",
tag, push_list->nelts);
diff -upr httpd-2.4.33/modules/http2/h2_mplx.c httpd-2.4.41/modules/http2/h2_mplx.c
--- httpd-2.4.33/modules/http2/h2_mplx.c 2019-08-22 09:53:22.193935648 +0200
+++ httpd-2.4.41/modules/http2/h2_mplx.c 2019-08-01 10:18:03.000000000 +0200
@@ -147,7 +147,7 @@ static void stream_cleanup(h2_mplx *m, h
* their HTTP/1 cousins, the separate allocator seems to work better
* than protecting a shared h2_session one with an own lock.
*/
-h2_mplx *h2_mplx_create(conn_rec *c, server_rec *s, apr_pool_t *parent,
+h2_mplx *h2_mplx_create(conn_rec *c, server_rec *s, apr_pool_t *parent,
h2_workers *workers)
{
apr_status_t status = APR_SUCCESS;
@@ -373,7 +373,7 @@ 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]"),
+ "[started=%d/done=%d]"),
task->request->method, task->request->authority,
task->request->path, task->worker_started,
task->worker_done);
@@ -797,7 +797,7 @@ static void task_done(h2_mplx *m, h2_tas
h2_task_redo(task);
h2_iq_add(m->q, stream->id, NULL, NULL);
ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, m->c,
- H2_STRM_MSG(stream, "redo, added to q"));
+ H2_STRM_MSG(stream, "redo, added to q"));
}
else {
/* stream not cleaned up, stay around */
@@ -862,7 +862,6 @@ static int timed_out_busy_iter(void *dat
{
stream_iter_ctx *ctx = data;
h2_stream *stream = val;
-
if (h2_task_has_started(stream->task) && !stream->task->worker_done
&& (ctx->now - stream->task->started_at) > stream->task->timeout) {
/* timed out stream occupying a worker, found */
@@ -946,7 +945,7 @@ static apr_status_t unschedule_slow_task
* that are repeatable. If none found, fail the connection.
*/
while (APR_EAGAIN == (rv = assess_task_to_throttle(&task, m))) {
- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
"h2_mplx(%s): unschedule, resetting task for redo later",
task->id);
task->redo = 1;
diff -upr httpd-2.4.33/modules/http2/h2_mplx.h httpd-2.4.41/modules/http2/h2_mplx.h
--- httpd-2.4.33/modules/http2/h2_mplx.h 2019-08-22 09:53:22.193935648 +0200
+++ httpd-2.4.41/modules/http2/h2_mplx.h 2019-08-01 10:18:03.000000000 +0200
@@ -105,7 +105,7 @@ apr_status_t h2_mplx_child_init(apr_pool
* Create the multiplexer for the given HTTP2 session.
* Implicitly has reference count 1.
*/
-h2_mplx *h2_mplx_create(conn_rec *c, server_rec *s, apr_pool_t *master,
+h2_mplx *h2_mplx_create(conn_rec *c, server_rec *s, apr_pool_t *master,
struct h2_workers *workers);
/**
Only in httpd-2.4.33/modules/http2/: h2_ngn_shed.c
Only in httpd-2.4.33/modules/http2/: h2_ngn_shed.h
diff -upr httpd-2.4.33/modules/http2/h2_proxy_session.c httpd-2.4.41/modules/http2/h2_proxy_session.c
--- httpd-2.4.33/modules/http2/h2_proxy_session.c 2019-08-22 09:53:22.193935648 +0200
+++ httpd-2.4.41/modules/http2/h2_proxy_session.c 2019-08-01 10:18:03.000000000 +0200
@@ -45,6 +45,7 @@ typedef struct h2_proxy_stream {
unsigned int suspended : 1;
unsigned int waiting_on_100 : 1;
unsigned int waiting_on_ping : 1;
+ unsigned int headers_ended : 1;
uint32_t error_code;
apr_bucket_brigade *input;
@@ -61,6 +62,7 @@ static void dispatch_event(h2_proxy_sess
static void ping_arrived(h2_proxy_session *session);
static apr_status_t check_suspended(h2_proxy_session *session);
static void stream_resume(h2_proxy_stream *stream);
+static apr_status_t submit_trailers(h2_proxy_stream *stream);
static apr_status_t proxy_session_pre_close(void *theconn)
@@ -241,7 +243,8 @@ static int add_header(void *table, const
return 1;
}
-static void process_proxy_header(h2_proxy_stream *stream, const char *n, const char *v)
+static void process_proxy_header(apr_table_t *headers, h2_proxy_stream *stream,
+ const char *n, const char *v)
{
static const struct {
const char *name;
@@ -262,20 +265,18 @@ static void process_proxy_header(h2_prox
if (!dconf->preserve_host) {
for (i = 0; transform_hdrs[i].name; ++i) {
if (!ap_cstr_casecmp(transform_hdrs[i].name, n)) {
- apr_table_add(r->headers_out, n,
- (*transform_hdrs[i].func)(r, dconf, v));
+ apr_table_add(headers, n, (*transform_hdrs[i].func)(r, dconf, v));
return;
}
}
if (!ap_cstr_casecmp("Link", n)) {
dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
- apr_table_add(r->headers_out, n,
- h2_proxy_link_reverse_map(r, dconf,
- stream->real_server_uri, stream->p_server_uri, v));
+ apr_table_add(headers, n, h2_proxy_link_reverse_map(r, dconf,
+ stream->real_server_uri, stream->p_server_uri, v));
return;
}
}
- apr_table_add(r->headers_out, n, v);
+ apr_table_add(headers, n, v);
}
static apr_status_t h2_proxy_stream_add_header_out(h2_proxy_stream *stream,
@@ -299,8 +300,13 @@ static apr_status_t h2_proxy_stream_add_
return APR_SUCCESS;
}
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->session->c,
+ "h2_proxy_stream(%s-%d): on_header %s: %s",
+ stream->session->id, stream->id, n, v);
if (!h2_proxy_res_ignore_header(n, nlen)) {
char *hname, *hvalue;
+ apr_table_t *headers = (stream->headers_ended?
+ stream->r->trailers_out : stream->r->headers_out);
hname = apr_pstrndup(stream->pool, n, nlen);
h2_proxy_util_camel_case_header(hname, nlen);
@@ -309,7 +315,7 @@ static apr_status_t h2_proxy_stream_add_
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->session->c,
"h2_proxy_stream(%s-%d): got header %s: %s",
stream->session->id, stream->id, hname, hvalue);
- process_proxy_header(stream, hname, hvalue);
+ process_proxy_header(headers, stream, hname, hvalue);
}
return APR_SUCCESS;
}
@@ -374,6 +380,7 @@ static void h2_proxy_stream_end_headers_
server_name, portstr)
);
}
+ if (r->status >= 200) stream->headers_ended = 1;
if (APLOGrtrace2(stream->r)) {
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, stream->r,
@@ -487,8 +494,8 @@ static ssize_t stream_request_data(nghtt
stream = nghttp2_session_get_stream_user_data(ngh2, stream_id);
if (!stream) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(03361)
- "h2_proxy_stream(%s): data_read, stream %d not found",
- stream->session->id, stream_id);
+ "h2_proxy_stream(NULL): data_read, stream %d not found",
+ stream_id);
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
@@ -545,11 +552,16 @@ static ssize_t stream_request_data(nghtt
}
stream->data_sent += readlen;
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, stream->r, APLOGNO(10179)
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, stream->r, APLOGNO(03468)
"h2_proxy_stream(%d): request DATA %ld, %ld"
- " total, flags=%d",
- stream->id, (long)readlen, (long)stream->data_sent,
+ " total, flags=%d", stream->id, (long)readlen, (long)stream->data_sent,
(int)*data_flags);
+ if ((*data_flags & NGHTTP2_DATA_FLAG_EOF) && !apr_is_empty_table(stream->r->trailers_in)) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, stream->r, APLOGNO(10179)
+ "h2_proxy_stream(%d): submit trailers", stream->id);
+ *data_flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM;
+ submit_trailers(stream);
+ }
return readlen;
}
else if (APR_STATUS_IS_EAGAIN(status)) {
@@ -736,6 +748,8 @@ static apr_status_t open_stream(h2_proxy
stream->real_server_uri = apr_psprintf(stream->pool, "%s://%s", scheme, authority);
stream->p_server_uri = apr_psprintf(stream->pool, "%s://%s", puri.scheme, authority);
path = apr_uri_unparse(stream->pool, &puri, APR_URI_UNP_OMITSITEPART);
+
+
h2_proxy_req_make(stream->req, stream->pool, r->method, scheme,
authority, path, r->headers_in);
@@ -822,6 +836,16 @@ static apr_status_t submit_stream(h2_pro
return APR_EGENERAL;
}
+static apr_status_t submit_trailers(h2_proxy_stream *stream)
+{
+ h2_proxy_ngheader *hd;
+ int rv;
+
+ hd = h2_proxy_util_nghd_make(stream->pool, stream->r->trailers_in);
+ rv = nghttp2_submit_trailer(stream->session->ngh2, stream->id, hd->nv, hd->nvlen);
+ return rv == 0? APR_SUCCESS: APR_EGENERAL;
+}
+
static apr_status_t feed_brigade(h2_proxy_session *session, apr_bucket_brigade *bb)
{
apr_status_t status = APR_SUCCESS;
@@ -1419,7 +1443,7 @@ run_loop:
ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, session->c,
APLOGNO(03365)
"h2_proxy_session(%s): WAIT read, timeout=%fms",
- session->id, (float)session->wait_timeout/1000.0);
+ session->id, session->wait_timeout/1000.0);
if (status == APR_SUCCESS) {
have_read = 1;
dispatch_event(session, H2_PROXYS_EV_DATA_READ, 0, NULL);
diff -upr httpd-2.4.33/modules/http2/h2_proxy_util.c httpd-2.4.41/modules/http2/h2_proxy_util.c
--- httpd-2.4.33/modules/http2/h2_proxy_util.c 2019-08-22 09:53:22.045934783 +0200
+++ httpd-2.4.41/modules/http2/h2_proxy_util.c 2019-07-02 13:11:08.000000000 +0200
@@ -452,6 +452,22 @@ h2_proxy_ngheader *h2_proxy_util_nghd_ma
return ngh;
}
+h2_proxy_ngheader *h2_proxy_util_nghd_make(apr_pool_t *p, apr_table_t *headers)
+{
+
+ h2_proxy_ngheader *ngh;
+ size_t n;
+
+ n = 0;
+ apr_table_do(count_header, &n, headers, NULL);
+
+ ngh = apr_pcalloc(p, sizeof(h2_proxy_ngheader));
+ ngh->nv = apr_pcalloc(p, n * sizeof(nghttp2_nv));
+ apr_table_do(add_table_header, ngh, headers, NULL);
+
+ return ngh;
+}
+
/*******************************************************************************
* header HTTP/1 <-> HTTP/2 conversions
******************************************************************************/
@@ -609,6 +625,7 @@ apr_status_t h2_proxy_req_make(h2_proxy_
apr_table_t *headers)
{
h1_ctx x;
+ const char *val;
req->method = method;
req->scheme = scheme;
@@ -623,6 +640,11 @@ apr_status_t h2_proxy_req_make(h2_proxy_
x.pool = pool;
x.headers = req->headers;
apr_table_do(set_h1_header, &x, headers, NULL);
+ if ((val = apr_table_get(headers, "TE")) && ap_find_token(pool, val, "trailers")) {
+ /* client accepts trailers, forward this information */
+ apr_table_addn(req->headers, "TE", "trailers");
+ }
+ apr_table_setn(req->headers, "te", "trailers");
return APR_SUCCESS;
}
@@ -915,12 +937,12 @@ static size_t subst_str(link_ctx *ctx, i
nlen = (int)strlen(ns);
delta = nlen - olen;
plen = ctx->slen + delta + 1;
- p = apr_pcalloc(ctx->pool, plen);
+ p = apr_palloc(ctx->pool, plen);
memcpy(p, ctx->s, start);
memcpy(p + start, ns, nlen);
strcpy(p + start + nlen, ctx->s + end);
ctx->s = p;
- ctx->slen = (int)strlen(p);
+ ctx->slen = plen - 1; /* (int)strlen(p) */
if (ctx->i >= end) {
ctx->i += delta;
}
diff -upr httpd-2.4.33/modules/http2/h2_proxy_util.h httpd-2.4.41/modules/http2/h2_proxy_util.h
--- httpd-2.4.33/modules/http2/h2_proxy_util.h 2018-02-10 16:46:12.000000000 +0100
+++ httpd-2.4.41/modules/http2/h2_proxy_util.h 2019-06-14 14:11:43.000000000 +0200
@@ -168,6 +168,8 @@ typedef struct h2_proxy_ngheader {
h2_proxy_ngheader *h2_proxy_util_nghd_make_req(apr_pool_t *p,
const struct h2_proxy_request *req);
+h2_proxy_ngheader *h2_proxy_util_nghd_make(apr_pool_t *p, apr_table_t *headers);
+
/*******************************************************************************
* h2_proxy_request helpers
******************************************************************************/
diff -upr httpd-2.4.33/modules/http2/h2_request.c httpd-2.4.41/modules/http2/h2_request.c
--- httpd-2.4.33/modules/http2/h2_request.c 2019-08-22 09:53:22.109935157 +0200
+++ httpd-2.4.41/modules/http2/h2_request.c 2019-03-13 16:00:57.000000000 +0100
@@ -266,7 +266,7 @@ static request_rec *my_ap_create_request
request_rec *h2_request_create_rec(const h2_request *req, conn_rec *c)
{
- int access_status = HTTP_OK;
+ int access_status = HTTP_OK;
const char *rpath;
const char *s;
diff -upr httpd-2.4.33/modules/http2/h2_session.c httpd-2.4.41/modules/http2/h2_session.c
--- httpd-2.4.33/modules/http2/h2_session.c 2019-08-22 09:53:22.197935671 +0200
+++ httpd-2.4.41/modules/http2/h2_session.c 2019-08-01 10:18:03.000000000 +0200
@@ -626,8 +626,8 @@ static int on_invalid_header_cb(nghttp2_
}
#endif
-static ssize_t select_padding_cb(nghttp2_session *ngh2,
- const nghttp2_frame *frame,
+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;
@@ -635,23 +635,23 @@ static ssize_t select_padding_cb(nghttp2
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.
+ * 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);
+ 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
+ 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,
+ "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;
@@ -902,7 +902,7 @@ apr_status_t h2_session_create(h2_sessio
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_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);
@@ -959,7 +959,7 @@ apr_status_t h2_session_create(h2_sessio
}
apr_pool_pre_cleanup_register(pool, c, session_pool_cleanup);
-
+
return APR_SUCCESS;
}
diff -upr httpd-2.4.33/modules/http2/h2_session.h httpd-2.4.41/modules/http2/h2_session.h
--- httpd-2.4.33/modules/http2/h2_session.h 2019-08-22 09:53:22.109935157 +0200
+++ httpd-2.4.41/modules/http2/h2_session.h 2019-03-13 16:00:57.000000000 +0100
@@ -149,7 +149,7 @@ const char *h2_session_state_str(h2_sess
* @return the created session
*/
apr_status_t h2_session_create(h2_session **psession,
- conn_rec *c, request_rec *r, server_rec *,
+ conn_rec *c, request_rec *r, server_rec *,
struct h2_workers *workers);
void h2_session_event(h2_session *session, h2_session_event_t ev,
diff -upr httpd-2.4.33/modules/http2/h2_stream.c httpd-2.4.41/modules/http2/h2_stream.c
--- httpd-2.4.33/modules/http2/h2_stream.c 2019-08-22 09:53:22.197935671 +0200
+++ httpd-2.4.41/modules/http2/h2_stream.c 2019-08-08 23:23:29.000000000 +0200
@@ -783,7 +783,7 @@ apr_status_t h2_stream_end_headers(h2_st
apr_table_do(table_check_val_len, &ctx, stream->request->headers, NULL);
if (ctx.failed_key) {
ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, stream->session->c,
- H2_STRM_LOG(APLOGNO(), stream,"Request header exceeds "
+ H2_STRM_LOG(APLOGNO(10190), stream,"Request header exceeds "
"LimitRequestFieldSize: %.*s"),
(int)H2MIN(strlen(ctx.failed_key), 80), ctx.failed_key);
set_error_response(stream, HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE);
@@ -894,7 +894,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 - H2_FRAME_HDR_LEN;
+ max_chunk = stream->session->io.write_size - H2_FRAME_HDR_LEN;
}
requested = (*plen > 0)? H2MIN(*plen, max_chunk) : max_chunk;
diff -upr httpd-2.4.33/modules/http2/h2_switch.c httpd-2.4.41/modules/http2/h2_switch.c
--- httpd-2.4.33/modules/http2/h2_switch.c 2019-08-22 09:53:22.113935179 +0200
+++ httpd-2.4.41/modules/http2/h2_switch.c 2019-03-13 16:00:57.000000000 +0100
@@ -164,7 +164,7 @@ static int h2_protocol_switch(conn_rec *
/* Ok, start an h2_conn on this one. */
status = h2_conn_setup(c, r, s);
-
+
if (status != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(03088)
"session setup");
diff -upr httpd-2.4.33/modules/http2/h2_task.h httpd-2.4.41/modules/http2/h2_task.h
--- httpd-2.4.33/modules/http2/h2_task.h 2019-08-22 09:53:22.197935671 +0200
+++ httpd-2.4.41/modules/http2/h2_task.h 2019-08-01 10:18:03.000000000 +0200
@@ -81,7 +81,7 @@ struct h2_task {
unsigned int filters_set : 1;
unsigned int worker_started : 1; /* h2_worker started processing */
unsigned int redo : 1; /* was throttled, should be restarted later */
-
+
int worker_done; /* h2_worker finished */
int done_done; /* task_done has been handled */
diff -upr httpd-2.4.33/modules/http2/mod_http2.c httpd-2.4.41/modules/http2/mod_http2.c
--- httpd-2.4.33/modules/http2/mod_http2.c 2019-08-22 09:53:22.113935179 +0200
+++ httpd-2.4.41/modules/http2/mod_http2.c 2019-03-13 16:00:57.000000000 +0100
@@ -337,7 +337,7 @@ static char *http2_var_lookup(apr_pool_t
for (i = 0; i < H2_ALEN(H2_VARS); ++i) {
h2_var_def *vdef = &H2_VARS[i];
if (!strcmp(vdef->name, name)) {
- h2_ctx *ctx = (r? h2_ctx_get(c, 0) :
+ h2_ctx *ctx = (r? h2_ctx_get(c, 0) :
h2_ctx_get(c->master? c->master : c, 0));
return (char *)vdef->lookup(p, s, c, r, ctx);
}
diff -upr httpd-2.4.33/modules/http2/mod_http2.h httpd-2.4.41/modules/http2/mod_http2.h
--- httpd-2.4.33/modules/http2/mod_http2.h 2019-08-22 09:53:22.113935179 +0200
+++ httpd-2.4.41/modules/http2/mod_http2.h 2019-03-13 16:00:57.000000000 +0100
@@ -38,7 +38,7 @@ APR_DECLARE_OPTIONAL_FN(int,
* 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;
diff -upr httpd-2.4.33/modules/http2/mod_proxy_http2.c httpd-2.4.41/modules/http2/mod_proxy_http2.c
--- httpd-2.4.33/modules/http2/mod_proxy_http2.c 2019-08-22 09:53:22.113935179 +0200
+++ httpd-2.4.41/modules/http2/mod_proxy_http2.c 2019-05-28 01:19:12.000000000 +0200
@@ -64,7 +64,6 @@ typedef struct h2_proxy_ctx {
int capacity;
unsigned is_ssl : 1;
- unsigned flushall : 1;
request_rec *r; /* the request processed in this ctx */
apr_status_t r_status; /* status of request work */
@@ -209,7 +208,7 @@ static void request_done(h2_proxy_ctx *c
apr_status_t status, int touched)
{
if (r == ctx->r) {
- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, r->connection,
+ 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;
@@ -249,9 +248,9 @@ static apr_status_t ctx_run(h2_proxy_ctx
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) {
/* Encountered an error during session processing */
@@ -270,7 +269,7 @@ static apr_status_t ctx_run(h2_proxy_ctx
out:
if (ctx->master->aborted) {
/* master connection gone */
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner,
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner,
APLOGNO(03374) "eng(%s): master connection gone", ctx->id);
/* cancel all ongoing requests */
h2_proxy_session_cancel_all(ctx->session);
@@ -337,7 +336,6 @@ static int proxy_http2_handler(request_r
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;
@@ -348,7 +346,7 @@ static int proxy_http2_handler(request_r
/* scheme says, this is for us. */
apr_table_setn(ctx->r->notes, H2_PROXY_REQ_URL_NOTE, url);
- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->r,
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, ctx->r,
"H2: serving URL %s", url);
run_connect:
@@ -367,7 +365,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->r, conf, worker,
+ if ((status = ap_proxy_determine_connection(ctx->pool, ctx->r, conf, worker,
ctx->p_conn, &uri, &locurl,
proxyname, proxyport,
ctx->server_portstr,
@@ -387,32 +385,22 @@ run_connect:
}
/* 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->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);
- ctx->r_status = status;
- goto cleanup;
- }
-
- if (!ctx->p_conn->data && ctx->is_ssl) {
- /* New SSL connection: set a note on the connection about what
- * protocol we want.
- */
- 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, 0, ctx->owner,
- "set SNI to %s for (%s)",
- ctx->p_conn->ssl_hostname,
- ctx->p_conn->hostname);
- apr_table_setn(ctx->p_conn->connection->notes,
- "proxy-request-hostname", ctx->p_conn->ssl_hostname);
- }
- }
+ 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);
+ ctx->r_status = status;
+ goto cleanup;
+ }
+
+ if (!ctx->p_conn->data && ctx->is_ssl) {
+ /* New SSL connection: set a note on the connection about what
+ * protocol we want.
+ */
+ apr_table_setn(ctx->p_conn->connection->notes,
+ "proxy-request-alpn-protos", "h2");
}
if (ctx->master->aborted) goto cleanup;