Blame modules/http2/h2_task.h

Packit 90a5c9
/* Licensed to the Apache Software Foundation (ASF) under one or more
Packit 90a5c9
 * contributor license agreements.  See the NOTICE file distributed with
Packit 90a5c9
 * this work for additional information regarding copyright ownership.
Packit 90a5c9
 * The ASF licenses this file to You under the Apache License, Version 2.0
Packit 90a5c9
 * (the "License"); you may not use this file except in compliance with
Packit 90a5c9
 * the License.  You may obtain a copy of the License at
Packit 90a5c9
 *
Packit 90a5c9
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 90a5c9
 *
Packit 90a5c9
 * Unless required by applicable law or agreed to in writing, software
Packit 90a5c9
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 90a5c9
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 90a5c9
 * See the License for the specific language governing permissions and
Packit 90a5c9
 * limitations under the License.
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
#ifndef __mod_h2__h2_task__
Packit 90a5c9
#define __mod_h2__h2_task__
Packit 90a5c9
Packit 90a5c9
#include <http_core.h>
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * A h2_task fakes a HTTP/1.1 request from the data in a HTTP/2 stream 
Packit 90a5c9
 * (HEADER+CONT.+DATA) the module recieves.
Packit 90a5c9
 *
Packit 90a5c9
 * In order to answer a HTTP/2 stream, we want all Apache httpd infrastructure
Packit 90a5c9
 * to be involved as usual, as if this stream can as a separate HTTP/1.1
Packit 90a5c9
 * request. The basic trickery to do so was derived from google's mod_spdy
Packit 90a5c9
 * source. Basically, we fake a new conn_rec object, even with its own
Packit 90a5c9
 * socket and give it to ap_process_connection().
Packit 90a5c9
 *
Packit 90a5c9
 * Since h2_task instances are executed in separate threads, we may have
Packit 90a5c9
 * different lifetimes than our h2_stream or h2_session instances. Basically,
Packit 90a5c9
 * we would like to be as standalone as possible.
Packit 90a5c9
 *
Packit 90a5c9
 * Finally, to keep certain connection level filters, such as ourselves and
Packit 90a5c9
 * especially mod_ssl ones, from messing with our data, we need a filter
Packit 90a5c9
 * of our own to disble those.
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
struct h2_bucket_beam;
Packit 90a5c9
struct h2_conn;
Packit 90a5c9
struct h2_mplx;
Packit 90a5c9
struct h2_task;
Packit 90a5c9
struct h2_req_engine;
Packit 90a5c9
struct h2_request;
Packit 90a5c9
struct h2_response_parser;
Packit 90a5c9
struct h2_stream;
Packit 90a5c9
struct h2_worker;
Packit 90a5c9
Packit 90a5c9
typedef struct h2_task h2_task;
Packit 90a5c9
Packit 90a5c9
struct h2_task {
Packit 90a5c9
    const char *id;
Packit 90a5c9
    int stream_id;
Packit 90a5c9
    conn_rec *c;
Packit 90a5c9
    apr_pool_t *pool;
Packit 90a5c9
    
Packit 90a5c9
    const struct h2_request *request;
Packit 90a5c9
    apr_interval_time_t timeout;
Packit 90a5c9
    int rst_error;                   /* h2 related stream abort error */
Packit 90a5c9
    
Packit 90a5c9
    struct {
Packit 90a5c9
        struct h2_bucket_beam *beam;
Packit 90a5c9
        unsigned int eos : 1;
Packit 90a5c9
        apr_bucket_brigade *bb;
Packit 90a5c9
        apr_bucket_brigade *bbchunk;
Packit 90a5c9
        apr_off_t chunked_total;
Packit 90a5c9
    } input;
Packit 90a5c9
    struct {
Packit 90a5c9
        struct h2_bucket_beam *beam;
Packit 90a5c9
        unsigned int opened : 1;
Packit 90a5c9
        unsigned int sent_response : 1;
Packit 90a5c9
        unsigned int copy_files : 1;
Packit 90a5c9
        struct h2_response_parser *rparser;
Packit 90a5c9
        apr_bucket_brigade *bb;
Packit 90a5c9
        apr_size_t max_buffer;
Packit 90a5c9
    } output;
Packit 90a5c9
    
Packit 90a5c9
    struct h2_mplx *mplx;
Packit 90a5c9
    
Packit 90a5c9
    unsigned int filters_set    : 1;
Packit 90a5c9
    unsigned int frozen         : 1;
Packit 90a5c9
    unsigned int thawed         : 1;
Packit 90a5c9
    unsigned int worker_started : 1; /* h2_worker started processing */
Packit 90a5c9
    unsigned int worker_done    : 1; /* h2_worker finished */
Packit 90a5c9
    
Packit 90a5c9
    apr_time_t started_at;           /* when processing started */
Packit 90a5c9
    apr_time_t done_at;              /* when processing was done */
Packit 90a5c9
    apr_bucket *eor;
Packit 90a5c9
    
Packit 90a5c9
    struct h2_req_engine *engine;   /* engine hosted by this task */
Packit 90a5c9
    struct h2_req_engine *assigned; /* engine that task has been assigned to */
Packit 90a5c9
};
Packit 90a5c9
Packit 90a5c9
h2_task *h2_task_create(conn_rec *slave, int stream_id,
Packit 90a5c9
                        const h2_request *req, struct h2_mplx *m, 
Packit 90a5c9
                        struct h2_bucket_beam *input, 
Packit 90a5c9
                        apr_interval_time_t timeout,
Packit 90a5c9
                        apr_size_t output_max_mem);
Packit 90a5c9
Packit 90a5c9
void h2_task_destroy(h2_task *task);
Packit 90a5c9
Packit 90a5c9
apr_status_t h2_task_do(h2_task *task, apr_thread_t *thread, int worker_id);
Packit 90a5c9
Packit 90a5c9
void h2_task_redo(h2_task *task);
Packit 90a5c9
int h2_task_can_redo(h2_task *task);
Packit 90a5c9
Packit 90a5c9
/**
Packit 90a5c9
 * Reset the task with the given error code, resets all input/output.
Packit 90a5c9
 */
Packit 90a5c9
void h2_task_rst(h2_task *task, int error);
Packit 90a5c9
Packit 90a5c9
void h2_task_register_hooks(void);
Packit 90a5c9
/*
Packit 90a5c9
 * One time, post config intialization.
Packit 90a5c9
 */
Packit 90a5c9
apr_status_t h2_task_init(apr_pool_t *pool, server_rec *s);
Packit 90a5c9
Packit 90a5c9
extern APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_in) *h2_task_logio_add_bytes_in;
Packit 90a5c9
extern APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *h2_task_logio_add_bytes_out;
Packit 90a5c9
Packit 90a5c9
apr_status_t h2_task_freeze(h2_task *task);
Packit 90a5c9
apr_status_t h2_task_thaw(h2_task *task);
Packit 90a5c9
int h2_task_has_thawed(h2_task *task);
Packit 90a5c9
Packit 90a5c9
#endif /* defined(__mod_h2__h2_task__) */