Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
int h2_h2_pre_conn(conn_rec* c, void *arg)
{
    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                  "h2_h2, pre_connection, start");
    h2_ctx *ctx = h2_ctx_get(c, 0);
    if (!ctx) {
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                      "h2_h2, pre_connection, no ctx");
        /* We have not seen this one yet, are we active? */
        h2_config *cfg = h2_config_get(c);
        if (!h2_config_geti(cfg, H2_CONF_ENABLED)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                          "h2_h2, pre_connection, h2 not enabled");
            return DECLINED;
        }
        
        /* Are we using TLS on this connection? */
        if (!h2_h2_is_tls(c)) {
            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                          "h2_h2, pre_connection, no TLS");
            return DECLINED;
        }
        
        /* Does mod_ssl offer ALPN/NPN support? */
        if (opt_ssl_register_alpn == NULL && opt_ssl_register_npn == NULL) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
                          "h2_h2, pre_connection, no ALPN/NPN support in mod_ssl");
            return DECLINED;
        }
        
        ctx = h2_ctx_get(c, 1);
        if (opt_ssl_register_alpn) {
            opt_ssl_register_alpn(c, h2_h2_alpn_propose, h2_h2_alpn_negotiated);
        }
        if (opt_ssl_register_npn) {
            opt_ssl_register_npn(c, h2_h2_npn_advertise, h2_h2_npn_negotiated);
        }

        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                      "h2_h2, pre_connection, ALPN callback registered");
        
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                      "h2_h2, pre_connection, end");
    }
    else if (h2_ctx_is_task(c)) {
        /* A connection that represents a http2 stream from another connection.
         */
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                      "h2_h2, pre_connection, found stream task");
        h2_task *task = h2_ctx_get_task(ctx);
        return h2_task_pre_conn(task, c);
    }
    
    return DECLINED;
}
Ejemplo n.º 4
0
static int h2_task_pre_conn(conn_rec* c, void *arg)
{
    
    h2_ctx *ctx = h2_ctx_get(c);
    
    (void)arg;
    if (h2_ctx_is_task(ctx)) {
        h2_task *task = h2_ctx_get_task(ctx);
        
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                      "h2_h2, pre_connection, found stream task");
        
        /* Add our own, network level in- and output filters.
         */
        ap_add_input_filter("H2_TO_H1", task, NULL, c);
        ap_add_output_filter("H1_TO_H2", task, NULL, c);
    }
    return OK;
}
Ejemplo n.º 5
0
static int h2_h2_late_fixups(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);
        if (task) {
            /* check if we copy vs. setaside files in this location */
            task->output.copy_files = h2_config_geti(h2_config_rget(r), 
                                                     H2_CONF_COPY_FILES);
            if (task->output.copy_files) {
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, task->c,
                              "h2_slave_out(%s): copy_files on", task->id);
                h2_beam_on_file_beam(task->output.beam, h2_beam_no_files, NULL);
            }
            check_push(r, "late_fixup");
        }
    }
    return DECLINED;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
Archivo: h2_h2.c Proyecto: 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;
}
Ejemplo n.º 8
0
int h2_filter_h2_status_handler(request_rec *r)
{
    h2_ctx *ctx = h2_ctx_rget(r);
    h2_task *task;
    
    if (strcmp(r->handler, "http2-status")) {
        return DECLINED;
    }
    if (r->method_number != M_GET) {
        return DECLINED;
    }

    task = ctx? h2_ctx_get_task(ctx) : NULL;
    if (task) {
        /* We need to handle the actual output on the main thread, as
         * we need to access h2_session information. */
        apr_table_setn(r->notes, H2_RESP_SOS_NOTE, H2_SOS_H2_STATUS);
        apr_table_setn(r->headers_out, "Content-Type", "application/json");
        r->status = 200;
        return DONE;
    }
    return DECLINED;
}
Ejemplo n.º 9
0
static int h2_task_pre_conn(conn_rec* c, void *arg)
{
    (void)arg;
    
    h2_ctx *ctx = h2_ctx_get(c);
    if (h2_ctx_is_task(ctx)) {
        h2_task_env *env = h2_ctx_get_task(ctx);
        
        /* This connection is a pseudo-connection used for a h2_task.
         * Since we read/write directly from it ourselves, we need
         * to disable a possible ssl connection filter.
         */
        h2_tls_disable(c);
        
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
                      "h2_h2, pre_connection, found stream task");
        
        /* Add our own, network level in- and output filters.
         */
        ap_add_input_filter("H2_TO_H1", env, NULL, c);
        ap_add_output_filter("H1_TO_H2", env, NULL, c);
    }
    return OK;
}