]> granicus.if.org Git - apache/blob - modules/http2/h2_task.h
a0875574ecc545f3037e11ee3594591b0e5976bc
[apache] / modules / http2 / h2_task.h
1 /* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #ifndef __mod_h2__h2_task__
17 #define __mod_h2__h2_task__
18
19 #include <http_core.h>
20
21 /**
22  * A h2_task fakes a HTTP/1.1 request from the data in a HTTP/2 stream 
23  * (HEADER+CONT.+DATA) the module recieves.
24  *
25  * In order to answer a HTTP/2 stream, we want all Apache httpd infrastructure
26  * to be involved as usual, as if this stream can as a separate HTTP/1.1
27  * request. The basic trickery to do so was derived from google's mod_spdy
28  * source. Basically, we fake a new conn_rec object, even with its own
29  * socket and give it to ap_process_connection().
30  *
31  * Since h2_task instances are executed in separate threads, we may have
32  * different lifetimes than our h2_stream or h2_session instances. Basically,
33  * we would like to be as standalone as possible.
34  *
35  * Finally, to keep certain connection level filters, such as ourselves and
36  * especially mod_ssl ones, from messing with our data, we need a filter
37  * of our own to disble those.
38  */
39
40 struct h2_bucket_beam;
41 struct h2_conn;
42 struct h2_mplx;
43 struct h2_task;
44 struct h2_req_engine;
45 struct h2_request;
46 struct h2_response_parser;
47 struct h2_stream;
48 struct h2_worker;
49
50 typedef struct h2_task h2_task;
51
52 struct h2_task {
53     const char *id;
54     int stream_id;
55     conn_rec *c;
56     apr_pool_t *pool;
57     
58     const struct h2_request *request;
59     apr_interval_time_t timeout;
60     int rst_error;                   /* h2 related stream abort error */
61     
62     struct {
63         struct h2_bucket_beam *beam;
64         unsigned int eos : 1;
65         apr_bucket_brigade *bb;
66         apr_bucket_brigade *bbchunk;
67         apr_off_t chunked_total;
68     } input;
69     struct {
70         struct h2_bucket_beam *beam;
71         unsigned int opened : 1;
72         unsigned int sent_response : 1;
73         unsigned int copy_files : 1;
74         struct h2_response_parser *rparser;
75         apr_bucket_brigade *bb;
76         apr_size_t max_buffer;
77     } output;
78     
79     struct h2_mplx *mplx;
80     
81     unsigned int filters_set    : 1;
82     unsigned int frozen         : 1;
83     unsigned int thawed         : 1;
84     unsigned int worker_started : 1; /* h2_worker started processing */
85     unsigned int worker_done    : 1; /* h2_worker finished */
86     
87     apr_time_t started_at;           /* when processing started */
88     apr_time_t done_at;              /* when processing was done */
89     apr_bucket *eor;
90     
91     struct h2_req_engine *engine;   /* engine hosted by this task */
92     struct h2_req_engine *assigned; /* engine that task has been assigned to */
93 };
94
95 h2_task *h2_task_create(conn_rec *slave, int stream_id,
96                         const h2_request *req, struct h2_mplx *m, 
97                         struct h2_bucket_beam *input, 
98                         apr_interval_time_t timeout,
99                         apr_size_t output_max_mem);
100
101 void h2_task_destroy(h2_task *task);
102
103 apr_status_t h2_task_do(h2_task *task, apr_thread_t *thread, int worker_id);
104
105 void h2_task_redo(h2_task *task);
106 int h2_task_can_redo(h2_task *task);
107
108 /**
109  * Reset the task with the given error code, resets all input/output.
110  */
111 void h2_task_rst(h2_task *task, int error);
112
113 void h2_task_register_hooks(void);
114 /*
115  * One time, post config intialization.
116  */
117 apr_status_t h2_task_init(apr_pool_t *pool, server_rec *s);
118
119 extern APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_in) *h2_task_logio_add_bytes_in;
120 extern APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *h2_task_logio_add_bytes_out;
121
122 apr_status_t h2_task_freeze(h2_task *task);
123 apr_status_t h2_task_thaw(h2_task *task);
124 int h2_task_has_thawed(h2_task *task);
125
126 #endif /* defined(__mod_h2__h2_task__) */