mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
*) mod_http2: synchronization with github sources.
Building in trunk and against 2.4.x is now supported via AP_HAS_RESPONSE_BUCKETS defines. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1904305 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -124,32 +124,32 @@ apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool,
|
||||
x.headers = req->headers;
|
||||
x.status = APR_SUCCESS;
|
||||
apr_table_do(set_h1_header, &x, r->headers_in, NULL);
|
||||
|
||||
|
||||
*preq = req;
|
||||
return x.status;
|
||||
}
|
||||
|
||||
apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool,
|
||||
apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool,
|
||||
const char *name, size_t nlen,
|
||||
const char *value, size_t vlen,
|
||||
size_t max_field_len, int *pwas_added)
|
||||
{
|
||||
apr_status_t status = APR_SUCCESS;
|
||||
|
||||
|
||||
*pwas_added = 0;
|
||||
if (nlen <= 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
if (name[0] == ':') {
|
||||
/* pseudo header, see ch. 8.1.2.3, always should come first */
|
||||
if (!apr_is_empty_table(req->headers)) {
|
||||
ap_log_perror(APLOG_MARK, APLOG_ERR, 0, pool,
|
||||
APLOGNO(02917)
|
||||
APLOGNO(02917)
|
||||
"h2_request: pseudo header after request start");
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
|
||||
if (H2_HEADER_METHOD_LEN == nlen
|
||||
&& !strncmp(H2_HEADER_METHOD, name, nlen)) {
|
||||
req->method = apr_pstrndup(pool, value, vlen);
|
||||
@@ -171,17 +171,17 @@ apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool,
|
||||
memset(buffer, 0, 32);
|
||||
strncpy(buffer, name, (nlen > 31)? 31 : nlen);
|
||||
ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, pool,
|
||||
APLOGNO(02954)
|
||||
APLOGNO(02954)
|
||||
"h2_request: ignoring unknown pseudo header %s",
|
||||
buffer);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* non-pseudo header, add to table */
|
||||
status = h2_req_add_header(req->headers, pool, name, nlen, value, vlen,
|
||||
status = h2_req_add_header(req->headers, pool, name, nlen, value, vlen,
|
||||
max_field_len, pwas_added);
|
||||
}
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ apr_status_t h2_request_end_headers(h2_request *req, apr_pool_t *pool, int eos,
|
||||
const char *s;
|
||||
|
||||
/* rfc7540, ch. 8.1.2.3:
|
||||
* - if we have :authority, it overrides any Host header
|
||||
* - if we have :authority, it overrides any Host header
|
||||
* - :authority MUST be omitted when converting h1->h2, so we
|
||||
* might get a stream without, but then Host needs to be there */
|
||||
if (!req->authority) {
|
||||
@@ -204,6 +204,7 @@ apr_status_t h2_request_end_headers(h2_request *req, apr_pool_t *pool, int eos,
|
||||
apr_table_setn(req->headers, "Host", req->authority);
|
||||
}
|
||||
|
||||
#if AP_HAS_RESPONSE_BUCKETS
|
||||
if (eos) {
|
||||
s = apr_table_get(req->headers, "Content-Length");
|
||||
if (!s && apr_table_get(req->headers, "Content-Type")) {
|
||||
@@ -213,6 +214,29 @@ apr_status_t h2_request_end_headers(h2_request *req, apr_pool_t *pool, int eos,
|
||||
apr_table_setn(req->headers, "Content-Length", "0");
|
||||
}
|
||||
}
|
||||
#else /* AP_HAS_RESPONSE_BUCKETS */
|
||||
s = apr_table_get(req->headers, "Content-Length");
|
||||
if (!s) {
|
||||
/* HTTP/2 does not need a Content-Length for framing, but our
|
||||
* internal request processing is used to HTTP/1.1, so we
|
||||
* need to either add a Content-Length or a Transfer-Encoding
|
||||
* if any content can be expected. */
|
||||
if (!eos) {
|
||||
/* We have not seen a content-length and have no eos,
|
||||
* simulate a chunked encoding for our HTTP/1.1 infrastructure,
|
||||
* in case we have "H2SerializeHeaders on" here
|
||||
*/
|
||||
req->chunked = 1;
|
||||
apr_table_mergen(req->headers, "Transfer-Encoding", "chunked");
|
||||
}
|
||||
else if (apr_table_get(req->headers, "Content-Type")) {
|
||||
/* If we have a content-type, but already seen eos, no more
|
||||
* data will come. Signal a zero content length explicitly.
|
||||
*/
|
||||
apr_table_setn(req->headers, "Content-Length", "0");
|
||||
}
|
||||
}
|
||||
#endif /* else AP_HAS_RESPONSE_BUCKETS */
|
||||
req->raw_bytes += raw_bytes;
|
||||
|
||||
return APR_SUCCESS;
|
||||
@@ -286,6 +310,7 @@ static request_rec *my_ap_create_request(conn_rec *c)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if AP_HAS_RESPONSE_BUCKETS
|
||||
apr_bucket *h2_request_create_bucket(const h2_request *req, request_rec *r)
|
||||
{
|
||||
conn_rec *c = r->connection;
|
||||
@@ -306,10 +331,11 @@ apr_bucket *h2_request_create_bucket(const h2_request *req, request_rec *r)
|
||||
return ap_bucket_request_create(req->method, uri, "HTTP/2.0", headers,
|
||||
r->pool, c->bucket_alloc);
|
||||
}
|
||||
#endif
|
||||
|
||||
request_rec *h2_create_request_rec(const h2_request *req, conn_rec *c)
|
||||
{
|
||||
int access_status = HTTP_OK;
|
||||
int access_status = HTTP_OK;
|
||||
|
||||
#if AP_MODULE_MAGIC_AT_LEAST(20120211, 106)
|
||||
request_rec *r = ap_create_request(c);
|
||||
@@ -430,7 +456,7 @@ request_rec *h2_create_request_rec(const h2_request *req, conn_rec *c)
|
||||
*/
|
||||
ap_add_input_filter_handle(ap_http_input_filter_handle,
|
||||
NULL, r, r->connection);
|
||||
|
||||
|
||||
if ((access_status = ap_post_read_request(r))) {
|
||||
/* Request check post hooks failed. An example of this would be a
|
||||
* request for a vhost where h2 is disabled --> 421.
|
||||
@@ -441,8 +467,8 @@ request_rec *h2_create_request_rec(const h2_request *req, conn_rec *c)
|
||||
goto die;
|
||||
}
|
||||
|
||||
AP_READ_REQUEST_SUCCESS((uintptr_t)r, (char *)r->method,
|
||||
(char *)r->uri, (char *)r->server->defn_name,
|
||||
AP_READ_REQUEST_SUCCESS((uintptr_t)r, (char *)r->method,
|
||||
(char *)r->uri, (char *)r->server->defn_name,
|
||||
r->status);
|
||||
return r;
|
||||
|
||||
@@ -475,6 +501,3 @@ die:
|
||||
AP_READ_REQUEST_FAILURE((uintptr_t)r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user