diff options
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | CMakeLists.txt | 3 | ||||
-rw-r--r-- | modules/http2/NWGNUmod_http2 | 6 | ||||
-rw-r--r-- | modules/http2/config2.m4 | 1 | ||||
-rw-r--r-- | modules/http2/h2_ctx.c | 1 | ||||
-rw-r--r-- | modules/http2/h2_private.h | 6 | ||||
-rw-r--r-- | modules/http2/h2_proxy_session.c | 9 | ||||
-rw-r--r-- | modules/http2/h2_push.c | 6 | ||||
-rw-r--r-- | modules/http2/h2_request.c | 119 | ||||
-rw-r--r-- | modules/http2/h2_request.h | 12 | ||||
-rw-r--r-- | modules/http2/h2_stream.c | 26 | ||||
-rw-r--r-- | modules/http2/h2_util.c | 117 | ||||
-rw-r--r-- | modules/http2/h2_util.h | 31 | ||||
-rw-r--r-- | modules/http2/mod_proxy_http2.c | 2 |
14 files changed, 178 insertions, 165 deletions
@@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_http2/mod_proxy_http2: h2_request.c is no longer shared between these + modules. This simplifies building on platforms such as Windows, as module + reference used in logging is now clear. + *) mod_proxy, mod_ssl: Handle SSLProxy* directives in <Proxy> sections, allowing per backend TLS configuration. [Yann Ylavic] diff --git a/CMakeLists.txt b/CMakeLists.txt index df19df4c97..d717635767 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -453,8 +453,7 @@ SET(mod_proxy_http2_requires NGHTTP2_FOUND) SET(mod_proxy_http2_extra_defines ssize_t=long) SET(mod_proxy_http2_extra_libs ${NGHTTP2_LIBRARIES}) SET(mod_proxy_http2_extra_sources - modules/http2/h2_proxy_session.c modules/http2/h2_request.c - modules/http2/h2_util.c + modules/http2/h2_proxy_session.c modules/http2/h2_util.c ) SET(mod_proxy_http2_extra_libs mod_proxy) SET(mod_ratelimit_extra_defines AP_RL_DECLARE_EXPORT) diff --git a/modules/http2/NWGNUmod_http2 b/modules/http2/NWGNUmod_http2 index 7301a21b24..e9c48a4009 100644 --- a/modules/http2/NWGNUmod_http2 +++ b/modules/http2/NWGNUmod_http2 @@ -367,8 +367,10 @@ $(OBJDIR)/mod_http2.imp : NWGNUmod_http2 @echo $(DL) h2_iq_remove,$(DL) >> $@ @echo $(DL) h2_log2,$(DL) >> $@ @echo $(DL) h2_proxy_res_ignore_header,$(DL) >> $@ - @echo $(DL) h2_request_create,$(DL) >> $@ - @echo $(DL) h2_request_make,$(DL) >> $@ + @echo $(DL) h2_headers_add_h1,$(DL) >> $@ + @echo $(DL) h2_req_create,$(DL) >> $@ + @echo $(DL) h2_req_createn,$(DL) >> $@ + @echo $(DL) h2_req_make,$(DL) >> $@ @echo $(DL) h2_util_camel_case_header,$(DL) >> $@ @echo $(DL) h2_util_frame_print,$(DL) >> $@ @echo $(DL) h2_util_ngheader_make_req,$(DL) >> $@ diff --git a/modules/http2/config2.m4 b/modules/http2/config2.m4 index ac01e2a20f..3c2fc59bbb 100644 --- a/modules/http2/config2.m4 +++ b/modules/http2/config2.m4 @@ -206,7 +206,6 @@ dnl # list of module object files proxy_http2_objs="dnl mod_proxy_http2.lo dnl h2_proxy_session.lo dnl -h2_request.lo dnl h2_util.lo dnl " diff --git a/modules/http2/h2_ctx.c b/modules/http2/h2_ctx.c index 8b786b94d9..4b596a3d78 100644 --- a/modules/http2/h2_ctx.c +++ b/modules/http2/h2_ctx.c @@ -23,7 +23,6 @@ #include "h2_session.h" #include "h2_task.h" #include "h2_ctx.h" -#include "h2_private.h" static h2_ctx *h2_ctx_create(const conn_rec *c) { diff --git a/modules/http2/h2_private.h b/modules/http2/h2_private.h index b68613692d..39d70512b8 100644 --- a/modules/http2/h2_private.h +++ b/modules/http2/h2_private.h @@ -20,8 +20,12 @@ #include <nghttp2/nghttp2.h> +#ifdef IS_MOD_PROXY_HTTP2 +extern module AP_MODULE_DECLARE_DATA proxy_http2_module; +APLOG_USE_MODULE(proxy_http2); +#else extern module AP_MODULE_DECLARE_DATA http2_module; - APLOG_USE_MODULE(http2); +#endif #endif diff --git a/modules/http2/h2_proxy_session.c b/modules/http2/h2_proxy_session.c index d627e9a8f1..28332456c2 100644 --- a/modules/http2/h2_proxy_session.c +++ b/modules/http2/h2_proxy_session.c @@ -23,7 +23,6 @@ #include "mod_http2.h" #include "h2.h" -#include "h2_request.h" #include "h2_util.h" #include "h2_proxy_session.h" @@ -553,9 +552,11 @@ static apr_status_t session_start(h2_proxy_session *session) apr_socket_t *s; s = ap_get_conn_socket(session->c); +#if (!defined(WIN32) && !defined(NETWARE)) || defined(DOXYGEN) if (s) { ap_sock_disable_nagle(s); } +#endif settings[0].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH; settings[0].value = 0; @@ -592,7 +593,7 @@ static apr_status_t open_stream(h2_proxy_session *session, const char *url, stream->input = apr_brigade_create(stream->pool, session->c->bucket_alloc); stream->output = apr_brigade_create(stream->pool, session->c->bucket_alloc); - stream->req = h2_request_create(1, stream->pool, 0); + stream->req = h2_req_create(1, stream->pool, 0); apr_uri_parse(stream->pool, url, &puri); scheme = (strcmp(puri.scheme, "h2")? "http" : "https"); @@ -603,8 +604,8 @@ static apr_status_t open_stream(h2_proxy_session *session, const char *url, authority = apr_psprintf(stream->pool, "%s:%d", authority, puri.port); } path = apr_uri_unparse(stream->pool, &puri, APR_URI_UNP_OMITSITEPART); - h2_request_make(stream->req, stream->pool, r->method, scheme, - authority, path, r->headers_in); + h2_req_make(stream->req, stream->pool, r->method, scheme, + authority, path, r->headers_in); /* Tuck away all already existing cookies */ stream->saves = apr_table_make(r->pool, 2); diff --git a/modules/http2/h2_push.c b/modules/http2/h2_push.c index 748e32abbf..977fab58a3 100644 --- a/modules/http2/h2_push.c +++ b/modules/http2/h2_push.c @@ -346,9 +346,9 @@ static int add_push(link_ctx *ctx) } headers = apr_table_make(ctx->pool, 5); apr_table_do(set_push_header, headers, ctx->req->headers, NULL); - req = h2_request_createn(0, ctx->pool, method, ctx->req->scheme, - ctx->req->authority, path, headers, - ctx->req->serialize); + req = h2_req_createn(0, ctx->pool, method, ctx->req->scheme, + ctx->req->authority, path, headers, + ctx->req->serialize); /* atm, we do not push on pushes */ h2_request_end_headers(req, ctx->pool, 1, 0); push->req = req; diff --git a/modules/http2/h2_request.c b/modules/http2/h2_request.c index 0253bede40..ca8a9bf7b9 100644 --- a/modules/http2/h2_request.c +++ b/modules/http2/h2_request.c @@ -35,31 +35,6 @@ #include "h2_util.h" -h2_request *h2_request_create(int id, apr_pool_t *pool, int serialize) -{ - return h2_request_createn(id, pool, NULL, NULL, NULL, NULL, NULL, - serialize); -} - -h2_request *h2_request_createn(int id, apr_pool_t *pool, - const char *method, const char *scheme, - const char *authority, const char *path, - apr_table_t *header, int serialize) -{ - h2_request *req = apr_pcalloc(pool, sizeof(h2_request)); - - req->id = id; - req->method = method; - req->scheme = scheme; - req->authority = authority; - req->path = path; - req->headers = header? header : apr_table_make(pool, 10); - req->request_time = apr_time_now(); - req->serialize = serialize; - - return req; -} - static apr_status_t inspect_clen(h2_request *req, const char *s) { char *end; @@ -67,87 +42,6 @@ static apr_status_t inspect_clen(h2_request *req, const char *s) return (s == end)? APR_EINVAL : APR_SUCCESS; } -static apr_status_t add_h1_header(h2_request *req, apr_pool_t *pool, - const char *name, size_t nlen, - const char *value, size_t vlen) -{ - char *hname, *hvalue; - - if (h2_req_ignore_header(name, nlen)) { - return APR_SUCCESS; - } - else if (H2_HD_MATCH_LIT("cookie", name, nlen)) { - const char *existing = apr_table_get(req->headers, "cookie"); - if (existing) { - char *nval; - - /* Cookie header come separately in HTTP/2, but need - * to be merged by "; " (instead of default ", ") - */ - hvalue = apr_pstrndup(pool, value, vlen); - nval = apr_psprintf(pool, "%s; %s", existing, hvalue); - apr_table_setn(req->headers, "Cookie", nval); - return APR_SUCCESS; - } - } - else if (H2_HD_MATCH_LIT("host", name, nlen)) { - if (apr_table_get(req->headers, "Host")) { - return APR_SUCCESS; /* ignore duplicate */ - } - } - - hname = apr_pstrndup(pool, name, nlen); - hvalue = apr_pstrndup(pool, value, vlen); - h2_util_camel_case_header(hname, nlen); - apr_table_mergen(req->headers, hname, hvalue); - - return APR_SUCCESS; -} - -typedef struct { - h2_request *req; - apr_pool_t *pool; -} h1_ctx; - -static int set_h1_header(void *ctx, const char *key, const char *value) -{ - h1_ctx *x = ctx; - size_t klen = strlen(key); - if (!h2_req_ignore_header(key, klen)) { - add_h1_header(x->req, x->pool, key, klen, value, strlen(value)); - } - return 1; -} - -static apr_status_t add_all_h1_header(h2_request *req, apr_pool_t *pool, - apr_table_t *header) -{ - h1_ctx x; - x.req = req; - x.pool = pool; - apr_table_do(set_h1_header, &x, header, NULL); - return APR_SUCCESS; -} - - -apr_status_t h2_request_make(h2_request *req, apr_pool_t *pool, - const char *method, const char *scheme, - const char *authority, const char *path, - apr_table_t *headers) -{ - req->method = method; - req->scheme = scheme; - req->authority = authority; - req->path = path; - - AP_DEBUG_ASSERT(req->scheme); - AP_DEBUG_ASSERT(req->authority); - AP_DEBUG_ASSERT(req->path); - AP_DEBUG_ASSERT(req->method); - - return add_all_h1_header(req, pool, headers); -} - apr_status_t h2_request_rwrite(h2_request *req, request_rec *r) { apr_status_t status; @@ -165,13 +59,10 @@ apr_status_t h2_request_rwrite(h2_request *req, request_rec *r) } } - status = h2_request_make(req, r->pool, r->method, scheme, authority, - apr_uri_unparse(r->pool, &r->parsed_uri, - APR_URI_UNP_OMITSITEPART), - r->headers_in); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(03058) - "h2_request(%d): rwrite %s host=%s://%s%s", - req->id, req->method, req->scheme, req->authority, req->path); + status = h2_req_make(req, r->pool, r->method, scheme, authority, + apr_uri_unparse(r->pool, &r->parsed_uri, + APR_URI_UNP_OMITSITEPART), + r->headers_in); return status; } @@ -223,7 +114,7 @@ apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool, } else { /* non-pseudo header, append to work bucket of stream */ - status = add_h1_header(req, pool, name, nlen, value, vlen); + status = h2_headers_add_h1(req->headers, pool, name, nlen, value, vlen); } return status; diff --git a/modules/http2/h2_request.h b/modules/http2/h2_request.h index 4288dfec2c..168d3796a9 100644 --- a/modules/http2/h2_request.h +++ b/modules/http2/h2_request.h @@ -18,18 +18,6 @@ #include "h2.h" -h2_request *h2_request_create(int id, apr_pool_t *pool, int serialize); - -h2_request *h2_request_createn(int id, apr_pool_t *pool, - const char *method, const char *scheme, - const char *authority, const char *path, - apr_table_t *headers, int serialize); - -apr_status_t h2_request_make(h2_request *req, apr_pool_t *pool, - const char *method, const char *scheme, - const char *authority, const char *path, - apr_table_t *headers); - apr_status_t h2_request_rwrite(h2_request *req, request_rec *r); apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool, diff --git a/modules/http2/h2_stream.c b/modules/http2/h2_stream.c index c8635aeec3..8853e6cad4 100644 --- a/modules/http2/h2_stream.c +++ b/modules/http2/h2_stream.c @@ -53,12 +53,19 @@ static int state_transition[][7] = { /*CL*/{ 1, 1, 0, 0, 1, 1, 1 }, }; -#define H2_STREAM_OUT_LOG(lvl,s,msg) \ - do { \ - if (APLOG_C_IS_LEVEL((s)->session->c,lvl)) \ - h2_util_bb_log((s)->session->c,(s)->session->id,lvl,msg,(s)->buffer); \ - } while(0) - +static void H2_STREAM_OUT_LOG(int lvl, h2_stream *s, char *tag) +{ + if (APLOG_C_IS_LEVEL(s->session->c, lvl)) { + conn_rec *c = s->session->c; + char buffer[4 * 1024]; + const char *line = "(null)"; + apr_size_t len, bmax = sizeof(buffer)/sizeof(buffer[0]); + + len = h2_util_bb_print(buffer, bmax, tag, "", s->buffer); + ap_log_cerror(APLOG_MARK, lvl, 0, c, "bb_dump(%ld-%d): %s", + c->id, s->id, len? buffer : line); + } +} static int set_state(h2_stream *stream, h2_stream_state_t state) { @@ -162,7 +169,7 @@ h2_stream *h2_stream_open(int id, apr_pool_t *pool, h2_session *session, req->initiated_on = initiated_on; } else { - req = h2_request_create(id, pool, + req = h2_req_create(id, pool, h2_config_geti(session->config, H2_CONF_SER_HEADERS)); } stream->request = req; @@ -232,6 +239,11 @@ apr_status_t h2_stream_set_request(h2_stream *stream, request_rec *r) status = h2_request_rwrite(stream->request, r); stream->request->serialize = h2_config_geti(h2_config_rget(r), H2_CONF_SER_HEADERS); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(03058) + "h2_request(%d): rwrite %s host=%s://%s%s", + stream->request->id, stream->request->method, + stream->request->scheme, stream->request->authority, + stream->request->path); return status; } diff --git a/modules/http2/h2_util.c b/modules/http2/h2_util.c index 648305247a..206bf4bd2b 100644 --- a/modules/http2/h2_util.c +++ b/modules/http2/h2_util.c @@ -23,8 +23,7 @@ #include <nghttp2/nghttp2.h> -#include "h2_private.h" -#include "h2_request.h" +#include "h2.h" #include "h2_util.h" /* h2_log2(n) iff n is a power of 2 */ @@ -1036,19 +1035,6 @@ apr_size_t h2_util_bb_print(char *buffer, apr_size_t bmax, return off; } -void h2_util_bb_log(conn_rec *c, int stream_id, int level, - const char *tag, apr_bucket_brigade *bb) -{ - char buffer[4 * 1024]; - const char *line = "(null)"; - apr_size_t len, bmax = sizeof(buffer)/sizeof(buffer[0]); - - len = h2_util_bb_print(buffer, bmax, tag, "", bb); - /* Intentional no APLOGNO */ - ap_log_cerror(APLOG_MARK, level, 0, c, "bb_dump(%ld-%d): %s", - c->id, stream_id, len? buffer : line); -} - apr_status_t h2_append_brigade(apr_bucket_brigade *to, apr_bucket_brigade *from, apr_off_t *plen, @@ -1313,6 +1299,107 @@ int h2_proxy_res_ignore_header(const char *name, size_t len) || ignore_header(H2_LIT_ARGS(IgnoredProxyRespHds), name, len)); } +apr_status_t h2_headers_add_h1(apr_table_t *headers, apr_pool_t *pool, + const char *name, size_t nlen, + const char *value, size_t vlen) +{ + char *hname, *hvalue; + + if (h2_req_ignore_header(name, nlen)) { + return APR_SUCCESS; + } + else if (H2_HD_MATCH_LIT("cookie", name, nlen)) { + const char *existing = apr_table_get(headers, "cookie"); + if (existing) { + char *nval; + + /* Cookie header come separately in HTTP/2, but need + * to be merged by "; " (instead of default ", ") + */ + hvalue = apr_pstrndup(pool, value, vlen); + nval = apr_psprintf(pool, "%s; %s", existing, hvalue); + apr_table_setn(headers, "Cookie", nval); + return APR_SUCCESS; + } + } + else if (H2_HD_MATCH_LIT("host", name, nlen)) { + if (apr_table_get(headers, "Host")) { + return APR_SUCCESS; /* ignore duplicate */ + } + } + + hname = apr_pstrndup(pool, name, nlen); + hvalue = apr_pstrndup(pool, value, vlen); + h2_util_camel_case_header(hname, nlen); + apr_table_mergen(headers, hname, hvalue); + + return APR_SUCCESS; +} + +/******************************************************************************* + * h2 request handling + ******************************************************************************/ + +h2_request *h2_req_createn(int id, apr_pool_t *pool, const char *method, + const char *scheme, const char *authority, + const char *path, apr_table_t *header, int serialize) +{ + h2_request *req = apr_pcalloc(pool, sizeof(h2_request)); + + req->id = id; + req->method = method; + req->scheme = scheme; + req->authority = authority; + req->path = path; + req->headers = header? header : apr_table_make(pool, 10); + req->request_time = apr_time_now(); + req->serialize = serialize; + + return req; +} + +h2_request *h2_req_create(int id, apr_pool_t *pool, int serialize) +{ + return h2_req_createn(id, pool, NULL, NULL, NULL, NULL, NULL, serialize); +} + +typedef struct { + apr_table_t *headers; + apr_pool_t *pool; +} h1_ctx; + +static int set_h1_header(void *ctx, const char *key, const char *value) +{ + h1_ctx *x = ctx; + size_t klen = strlen(key); + if (!h2_req_ignore_header(key, klen)) { + h2_headers_add_h1(x->headers, x->pool, key, klen, value, strlen(value)); + } + return 1; +} + +apr_status_t h2_req_make(h2_request *req, apr_pool_t *pool, + const char *method, const char *scheme, + const char *authority, const char *path, + apr_table_t *headers) +{ + h1_ctx x; + + req->method = method; + req->scheme = scheme; + req->authority = authority; + req->path = path; + + AP_DEBUG_ASSERT(req->scheme); + AP_DEBUG_ASSERT(req->authority); + AP_DEBUG_ASSERT(req->path); + AP_DEBUG_ASSERT(req->method); + + x.pool = pool; + x.headers = req->headers; + apr_table_do(set_h1_header, &x, headers, NULL); + return APR_SUCCESS; +} /******************************************************************************* * frame logging diff --git a/modules/http2/h2_util.h b/modules/http2/h2_util.h index 8e7e2795f1..56614766c3 100644 --- a/modules/http2/h2_util.h +++ b/modules/http2/h2_util.h @@ -276,6 +276,25 @@ h2_ngheader *h2_util_ngheader_make_res(apr_pool_t *p, h2_ngheader *h2_util_ngheader_make_req(apr_pool_t *p, const struct h2_request *req); +apr_status_t h2_headers_add_h1(apr_table_t *headers, apr_pool_t *pool, + const char *name, size_t nlen, + const char *value, size_t vlen); + +/******************************************************************************* + * h2_request helpers + ******************************************************************************/ + +struct h2_request *h2_req_createn(int id, apr_pool_t *pool, const char *method, + const char *scheme, const char *authority, + const char *path, apr_table_t *header, + int serialize); +struct h2_request *h2_req_create(int id, apr_pool_t *pool, int serialize); + +apr_status_t h2_req_make(struct h2_request *req, apr_pool_t *pool, + const char *method, const char *scheme, + const char *authority, const char *path, + apr_table_t *headers); + /******************************************************************************* * apr brigade helpers ******************************************************************************/ @@ -357,8 +376,16 @@ apr_size_t h2_util_bb_print(char *buffer, apr_size_t bmax, * @param tag a short message text about the context * @param bb the brigade to log */ -void h2_util_bb_log(conn_rec *c, int stream_id, int level, - const char *tag, apr_bucket_brigade *bb); +#define h2_util_bb_log(c, i, level, tag, bb) \ +do { \ + char buffer[4 * 1024]; \ + const char *line = "(null)"; \ + apr_size_t len, bmax = sizeof(buffer)/sizeof(buffer[0]); \ + len = h2_util_bb_print(buffer, bmax, (tag), "", (bb)); \ + ap_log_cerror(APLOG_MARK, level, 0, (c), "bb_dump(%ld-%d): %s", \ + (c)->id, (int)(i), (len? buffer : line)); \ +} while(0) + /** * Transfer buckets from one brigade to another with a limit on the diff --git a/modules/http2/mod_proxy_http2.c b/modules/http2/mod_proxy_http2.c index 421692d174..13bb85724b 100644 --- a/modules/http2/mod_proxy_http2.c +++ b/modules/http2/mod_proxy_http2.c @@ -21,7 +21,7 @@ #include "mod_proxy_http2.h" -#include "h2_request.h" +#include "h2.h" #include "h2_util.h" #include "h2_version.h" #include "h2_proxy_session.h" |