summaryrefslogtreecommitdiff
path: root/modules/http2/h2_from_h1.c
diff options
context:
space:
mode:
authorStefan Fritsch <sf@sfritsch.de>2015-12-19 09:17:42 +0100
committerStefan Fritsch <sf@sfritsch.de>2015-12-19 09:17:42 +0100
commitd5325781b38052fbdf4cc28a6c6d3052b9424b51 (patch)
tree0dd970f541f3d816f3b2217a9cd7a77f1733cbc9 /modules/http2/h2_from_h1.c
parentf775596dea7222b55efc18005acf1919609c3602 (diff)
downloadapache2-d5325781b38052fbdf4cc28a6c6d3052b9424b51.tar.gz
Imported Upstream version 2.4.18
Diffstat (limited to 'modules/http2/h2_from_h1.c')
-rw-r--r--modules/http2/h2_from_h1.c71
1 files changed, 45 insertions, 26 deletions
diff --git a/modules/http2/h2_from_h1.c b/modules/http2/h2_from_h1.c
index be11f5c3..0b5060d4 100644
--- a/modules/http2/h2_from_h1.c
+++ b/modules/http2/h2_from_h1.c
@@ -51,19 +51,10 @@ h2_from_h1 *h2_from_h1_create(int stream_id, apr_pool_t *pool)
apr_status_t h2_from_h1_destroy(h2_from_h1 *from_h1)
{
- if (from_h1->response) {
- h2_response_destroy(from_h1->response);
- from_h1->response = NULL;
- }
from_h1->bb = NULL;
return APR_SUCCESS;
}
-h2_from_h1_state_t h2_from_h1_get_state(h2_from_h1 *from_h1)
-{
- return from_h1->state;
-}
-
static void set_state(h2_from_h1 *from_h1, h2_from_h1_state_t state)
{
if (from_h1->state != state) {
@@ -78,16 +69,9 @@ h2_response *h2_from_h1_get_response(h2_from_h1 *from_h1)
static apr_status_t make_h2_headers(h2_from_h1 *from_h1, request_rec *r)
{
- from_h1->response = h2_response_create(from_h1->stream_id,
- from_h1->status, from_h1->hlines,
- from_h1->pool);
- if (from_h1->response == NULL) {
- ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EINVAL, r->connection,
- APLOGNO(02915)
- "h2_from_h1(%d): unable to create resp_head",
- from_h1->stream_id);
- return APR_EINVAL;
- }
+ from_h1->response = h2_response_create(from_h1->stream_id, 0,
+ from_h1->http_status, from_h1->hlines,
+ from_h1->pool);
from_h1->content_length = from_h1->response->content_length;
from_h1->chunked = r->chunked;
@@ -202,8 +186,7 @@ apr_status_t h2_from_h1_read_response(h2_from_h1 *from_h1, ap_filter_t* f,
}
if (from_h1->state == H2_RESP_ST_STATUS_LINE) {
/* instead of parsing, just take it directly */
- from_h1->status = apr_psprintf(from_h1->pool,
- "%d", f->r->status);
+ from_h1->http_status = f->r->status;
from_h1->state = H2_RESP_ST_HEADERS;
}
else if (line[0] == '\0') {
@@ -375,6 +358,7 @@ static h2_response *create_response(h2_from_h1 *from_h1, request_rec *r)
if (!apr_is_empty_table(r->err_headers_out)) {
r->headers_out = apr_table_overlay(r->pool, r->err_headers_out,
r->headers_out);
+ apr_table_clear(r->err_headers_out);
}
/*
@@ -417,7 +401,7 @@ static h2_response *create_response(h2_from_h1 *from_h1, request_rec *r)
}
if (!apr_is_empty_array(r->content_languages)) {
- int i;
+ unsigned int i;
char *token;
char **languages = (char **)(r->content_languages->elts);
const char *field = apr_table_get(r->headers_out, "Content-Language");
@@ -492,8 +476,8 @@ static h2_response *create_response(h2_from_h1 *from_h1, request_rec *r)
apr_status_t h2_response_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
{
- h2_task_env *env = f->ctx;
- h2_from_h1 *from_h1 = env->output? env->output->from_h1 : NULL;
+ h2_task *task = f->ctx;
+ h2_from_h1 *from_h1 = task->output? task->output->from_h1 : NULL;
request_rec *r = f->r;
apr_bucket *b;
ap_bucket_error *eb = NULL;
@@ -503,7 +487,7 @@ apr_status_t h2_response_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
"h2_from_h1(%d): output_filter called", from_h1->stream_id);
- if (r->header_only && env->output && from_h1->response) {
+ if (r->header_only && task->output && from_h1->response) {
/* throw away any data after we have compiled the response */
apr_brigade_cleanup(bb);
return OK;
@@ -533,7 +517,7 @@ apr_status_t h2_response_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
if (eb) {
int st = eb->status;
apr_brigade_cleanup(bb);
- ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c,
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c,
"h2_from_h1(%d): err bucket status=%d",
from_h1->stream_id, st);
ap_die(st, r);
@@ -568,3 +552,38 @@ apr_status_t h2_response_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
}
return ap_pass_brigade(f->next, bb);
}
+
+apr_status_t h2_response_trailers_filter(ap_filter_t *f, apr_bucket_brigade *bb)
+{
+ h2_task *task = f->ctx;
+ h2_from_h1 *from_h1 = task->output? task->output->from_h1 : NULL;
+ request_rec *r = f->r;
+ apr_bucket *b;
+
+ if (from_h1 && from_h1->response) {
+ /* Detect the EOR bucket and forward any trailers that may have
+ * been set to our h2_response.
+ */
+ for (b = APR_BRIGADE_FIRST(bb);
+ b != APR_BRIGADE_SENTINEL(bb);
+ b = APR_BUCKET_NEXT(b))
+ {
+ if (AP_BUCKET_IS_EOR(b)) {
+ /* FIXME: need a better test case than this.
+ apr_table_setn(r->trailers_out, "X", "1"); */
+ if (r->trailers_out && !apr_is_empty_table(r->trailers_out)) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c,
+ "h2_from_h1(%d): trailers filter, saving trailers",
+ from_h1->stream_id);
+ h2_response_set_trailers(from_h1->response,
+ apr_table_clone(from_h1->pool,
+ r->trailers_out));
+ }
+ break;
+ }
+ }
+ }
+
+ return ap_pass_brigade(f->next, bb);
+}
+