diff options
Diffstat (limited to 'modules/http2/h2_request.c')
-rw-r--r-- | modules/http2/h2_request.c | 170 |
1 files changed, 22 insertions, 148 deletions
diff --git a/modules/http2/h2_request.c b/modules/http2/h2_request.c index 2652661e..d213e167 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,111 +42,28 @@ 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 h2_request_rwrite(h2_request *req, apr_pool_t *pool, + request_rec *r) { apr_status_t status; const char *scheme, *authority; - scheme = (r->parsed_uri.scheme? r->parsed_uri.scheme + scheme = apr_pstrdup(pool, r->parsed_uri.scheme? r->parsed_uri.scheme : ap_http_scheme(r)); - authority = r->hostname; + authority = apr_pstrdup(pool, r->hostname); if (!ap_strchr_c(authority, ':') && r->server && r->server->port) { apr_port_t defport = apr_uri_port_of_scheme(scheme); if (defport != r->server->port) { /* port info missing and port is not default for scheme: append */ - authority = apr_psprintf(r->pool, "%s:%d", authority, + authority = apr_psprintf(pool, "%s:%d", authority, (int)r->server->port); } } - 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, pool, apr_pstrdup(pool, r->method), scheme, + authority, apr_uri_unparse(pool, &r->parsed_uri, + APR_URI_UNP_OMITSITEPART), + r->headers_in); return status; } @@ -223,7 +115,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; @@ -235,7 +127,8 @@ apr_status_t h2_request_end_headers(h2_request *req, apr_pool_t *pool, const char *s; if (req->eoh) { - return APR_EINVAL; + /* already done */ + return APR_SUCCESS; } /* rfc7540, ch. 8.1.2.3: @@ -337,37 +230,18 @@ apr_status_t h2_request_add_trailer(h2_request *req, apr_pool_t *pool, return add_h1_trailer(req, pool, name, nlen, value, vlen); } -#define OPT_COPY(p, s) ((s)? apr_pstrdup(p, s) : NULL) - -void h2_request_copy(apr_pool_t *p, h2_request *dst, const h2_request *src) +h2_request *h2_request_clone(apr_pool_t *p, const h2_request *src) { - /* keep the dst id */ - dst->initiated_on = src->initiated_on; - dst->method = OPT_COPY(p, src->method); - dst->scheme = OPT_COPY(p, src->scheme); - dst->authority = OPT_COPY(p, src->authority); - dst->path = OPT_COPY(p, src->path); - dst->headers = apr_table_clone(p, src->headers); + h2_request *dst = apr_pmemdup(p, src, sizeof(*dst)); + dst->method = apr_pstrdup(p, src->method); + dst->scheme = apr_pstrdup(p, src->scheme); + dst->authority = apr_pstrdup(p, src->authority); + dst->path = apr_pstrdup(p, src->path); + dst->headers = apr_table_clone(p, src->headers); if (src->trailers) { - dst->trailers = apr_table_clone(p, src->trailers); + dst->trailers = apr_table_clone(p, src->trailers); } - else { - dst->trailers = NULL; - } - dst->content_length = src->content_length; - dst->chunked = src->chunked; - dst->eoh = src->eoh; - dst->body = src->body; - dst->serialize = src->serialize; - dst->push_policy = src->push_policy; -} - -h2_request *h2_request_clone(apr_pool_t *p, const h2_request *src) -{ - h2_request *nreq = apr_pcalloc(p, sizeof(*nreq)); - memcpy(nreq, src, sizeof(*nreq)); - h2_request_copy(p, nreq, src); - return nreq; + return dst; } request_rec *h2_request_create_rec(const h2_request *req, conn_rec *conn) @@ -436,7 +310,7 @@ request_rec *h2_request_create_rec(const h2_request *req, conn_rec *conn) } ap_parse_uri(r, req->path); - r->protocol = "HTTP/2"; + r->protocol = "HTTP/2.0"; r->proto_num = HTTP_VERSION(2, 0); r->the_request = apr_psprintf(r->pool, "%s %s %s", |