diff options
author | Stefan Fritsch <sf@sfritsch.de> | 2015-12-19 09:17:42 +0100 |
---|---|---|
committer | Stefan Fritsch <sf@sfritsch.de> | 2015-12-19 09:17:42 +0100 |
commit | d5325781b38052fbdf4cc28a6c6d3052b9424b51 (patch) | |
tree | 0dd970f541f3d816f3b2217a9cd7a77f1733cbc9 /modules/http2/h2_from_h1.c | |
parent | f775596dea7222b55efc18005acf1919609c3602 (diff) | |
download | apache2-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.c | 71 |
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); +} + |