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/06/14 11:59:33 UTC
svn commit: r1861337 - in /httpd/httpd/trunk: CHANGES
modules/http2/h2_proxy_session.c modules/http2/h2_proxy_util.c
modules/http2/h2_proxy_util.h
Author: icing
Date: Fri Jun 14 11:59:33 2019
New Revision: 1861337
URL: http://svn.apache.org/viewvc?rev=1861337&view=rev
Log:
*) mod_proxy_http2: adding support for handling trailers in both directions. PR 63502.
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/modules/http2/h2_proxy_session.c
httpd/httpd/trunk/modules/http2/h2_proxy_util.c
httpd/httpd/trunk/modules/http2/h2_proxy_util.h
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1861337&r1=1861336&r2=1861337&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Fri Jun 14 11:59:33 2019
@@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes with Apache 2.5.1
+ *) mod_proxy_http2: adding support for handling trailers in both directions. PR 63502.
+ [Stefan Eissing]
+
*) mod_proxy/ssl: Proxy SSL client certificate configuration and other proxy
SSL configurations broken inside <Proxy> context. PR 63430.
[Ruediger Pluem, Yann Ylavic]
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=1861337&r1=1861336&r2=1861337&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_proxy_session.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_proxy_session.c Fri Jun 14 11:59:33 2019
@@ -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,
@@ -547,9 +554,14 @@ static ssize_t stream_request_data(nghtt
stream->data_sent += readlen;
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(03468)
+ "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;
Modified: httpd/httpd/trunk/modules/http2/h2_proxy_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_proxy_util.c?rev=1861337&r1=1861336&r2=1861337&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_proxy_util.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_proxy_util.c Fri Jun 14 11:59:33 2019
@@ -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;
}
Modified: httpd/httpd/trunk/modules/http2/h2_proxy_util.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_proxy_util.h?rev=1861337&r1=1861336&r2=1861337&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_proxy_util.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_proxy_util.h Fri Jun 14 11:59:33 2019
@@ -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
******************************************************************************/