static int h2_h2_post_read_req(request_rec *r) { h2_ctx *ctx = h2_ctx_rget(r); struct h2_task *task = h2_ctx_get_task(ctx); if (task) { /* FIXME: sometimes, this hook gets called twice for a single request. * This should not be, right? */ /* h2_task connection for a stream, not for h2c */ ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "adding h1_to_h2_resp output filter"); if (task->serialize_headers) { ap_remove_output_filter_byhandle(r->output_filters, "H1_TO_H2_RESP"); ap_add_output_filter("H1_TO_H2_RESP", task, r, r->connection); } else { /* replace the core http filter that formats response headers * in HTTP/1 with our own that collects status and headers */ ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER"); ap_remove_output_filter_byhandle(r->output_filters, "H2_RESPONSE"); ap_add_output_filter("H2_RESPONSE", task, r, r->connection); } ap_add_output_filter("H2_TRAILERS", task, r, r->connection); } return DECLINED; }
static int h2_h2_post_read_req(request_rec *r) { /* slave connection? */ if (r->connection->master) { h2_ctx *ctx = h2_ctx_rget(r); struct h2_task *task = h2_ctx_get_task(ctx); /* This hook will get called twice on internal redirects. Take care * that we manipulate filters only once. */ if (task && !task->filters_set) { ap_filter_t *f; ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "h2_task(%s): adding request filters", task->id); /* setup the correct filters to process the request for h2 */ ap_add_input_filter("H2_REQUEST", task, r, r->connection); /* replace the core http filter that formats response headers * in HTTP/1 with our own that collects status and headers */ ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER"); ap_add_output_filter("H2_RESPONSE", task, r, r->connection); for (f = r->input_filters; f; f = f->next) { if (!strcmp("H2_SLAVE_IN", f->frec->name)) { f->r = r; break; } } ap_add_output_filter("H2_TRAILERS_OUT", task, r, r->connection); task->filters_set = 1; } } return DECLINED; }
static int h2_protocol_switch(conn_rec *c, request_rec *r, server_rec *s, const char *protocol) { int found = 0; const char **protos = h2_h2_is_tls(c)? h2_tls_protos : h2_clear_protos; const char **p = protos; (void)s; while (*p) { if (!strcmp(*p, protocol)) { found = 1; break; } p++; } if (found) { h2_ctx *ctx = h2_ctx_get(c, 1); ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "switching protocol to '%s'", protocol); h2_ctx_protocol_set(ctx, protocol); h2_ctx_server_set(ctx, s); if (r != NULL) { apr_status_t status; /* Switching in the middle of a request means that * we have to send out the response to this one in h2 * format. So we need to take over the connection * right away. */ ap_remove_input_filter_byhandle(r->input_filters, "http_in"); ap_remove_input_filter_byhandle(r->input_filters, "reqtimeout"); ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER"); /* Ok, start an h2_conn on this one. */ h2_ctx_server_set(ctx, r->server); status = h2_conn_setup(ctx, r->connection, r); if (status != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(03088) "session setup"); return status; } h2_conn_run(ctx, c); return DONE; } return DONE; } return DECLINED; }
int h2_h2_post_read_req(request_rec *r) { h2_ctx *ctx = h2_ctx_rget(r, 0); struct h2_task *task = ctx? h2_ctx_get_task(ctx) : NULL; if (task) { /* h2_task connection for a stream, not for h2c */ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "adding h1_to_h2_resp output filter"); if (0) { ap_add_output_filter("H1_TO_H2_RESP", task, r, r->connection); } else { /* replace the core http filter that formats response headers * in HTTP/1 with our own that collects status and headers */ ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER"); ap_add_output_filter("H2_RESPONSE", task, r, r->connection); } } return DECLINED; }
static int h2_h2_post_read_req(request_rec *r) { /* slave connection? */ if (r->connection->master) { h2_ctx *ctx = h2_ctx_rget(r); struct h2_task *task = h2_ctx_get_task(ctx); /* This hook will get called twice on internal redirects. Take care * that we manipulate filters only once. */ if (task && !task->filters_set) { ap_filter_t *f; /* setup the correct output filters to process the response * on the proper mod_http2 way. */ ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "adding task output filter"); if (task->ser_headers) { ap_add_output_filter("H1_TO_H2_RESP", task, r, r->connection); } else { /* replace the core http filter that formats response headers * in HTTP/1 with our own that collects status and headers */ ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER"); ap_add_output_filter("H2_RESPONSE", task, r, r->connection); } /* trailers processing. Incoming trailers are added to this * request via our h2 input filter, outgoing trailers * in a special h2 out filter. */ for (f = r->input_filters; f; f = f->next) { if (!strcmp("H2_TO_H1", f->frec->name)) { f->r = r; break; } } ap_add_output_filter("H2_TRAILERS", task, r, r->connection); task->filters_set = 1; } } return DECLINED; }