Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
File: h2_h2.c Project: Karm/mod_h2
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;
}