1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef __mod_h2__h2__
18 #define __mod_h2__h2__
19 
20 #include <apr_version.h>
21 
22 struct h2_session;
23 struct h2_stream;
24 
25 /*
26  * When apr pollsets can poll file descriptors (e.g. pipes),
27  * we use it for polling stream input/output.
28  */
29 #ifdef H2_NO_POLL_STREAMS
30 #define H2_POLL_STREAMS           0
31 #else
32 #define H2_POLL_STREAMS           (APR_FILES_AS_SOCKETS && APR_VERSION_AT_LEAST(1,6,0))
33 #endif
34 
35 /**
36  * The magic PRIamble of RFC 7540 that is always sent when starting
37  * a h2 communication.
38  */
39 extern const char *H2_MAGIC_TOKEN;
40 
41 #define H2_ERR_NO_ERROR             (0x00)
42 #define H2_ERR_PROTOCOL_ERROR       (0x01)
43 #define H2_ERR_INTERNAL_ERROR       (0x02)
44 #define H2_ERR_FLOW_CONTROL_ERROR   (0x03)
45 #define H2_ERR_SETTINGS_TIMEOUT     (0x04)
46 #define H2_ERR_STREAM_CLOSED        (0x05)
47 #define H2_ERR_FRAME_SIZE_ERROR     (0x06)
48 #define H2_ERR_REFUSED_STREAM       (0x07)
49 #define H2_ERR_CANCEL               (0x08)
50 #define H2_ERR_COMPRESSION_ERROR    (0x09)
51 #define H2_ERR_CONNECT_ERROR        (0x0a)
52 #define H2_ERR_ENHANCE_YOUR_CALM    (0x0b)
53 #define H2_ERR_INADEQUATE_SECURITY  (0x0c)
54 #define H2_ERR_HTTP_1_1_REQUIRED    (0x0d)
55 
56 #define H2_HEADER_METHOD     ":method"
57 #define H2_HEADER_METHOD_LEN 7
58 #define H2_HEADER_SCHEME     ":scheme"
59 #define H2_HEADER_SCHEME_LEN 7
60 #define H2_HEADER_AUTH       ":authority"
61 #define H2_HEADER_AUTH_LEN   10
62 #define H2_HEADER_PATH       ":path"
63 #define H2_HEADER_PATH_LEN   5
64 #define H2_CRLF             "\r\n"
65 
66 /* Size of the frame header itself in HTTP/2 */
67 #define H2_FRAME_HDR_LEN            9
68 
69 /* Max data size to write so it fits inside a TLS record */
70 #define H2_DATA_CHUNK_SIZE          ((16*1024) - 100 - H2_FRAME_HDR_LEN)
71 
72 /* Maximum number of padding bytes in a frame, rfc7540 */
73 #define H2_MAX_PADLEN               256
74 /* Initial default window size, RFC 7540 ch. 6.5.2 */
75 #define H2_INITIAL_WINDOW_SIZE      ((64*1024)-1)
76 
77 #define H2_STREAM_CLIENT_INITIATED(id)      (id&0x01)
78 
79 #define H2_ALEN(a)          (sizeof(a)/sizeof((a)[0]))
80 
81 #define H2MAX(x,y) ((x) > (y) ? (x) : (y))
82 #define H2MIN(x,y) ((x) < (y) ? (x) : (y))
83 
84 typedef enum {
85     H2_DEPENDANT_AFTER,
86     H2_DEPENDANT_INTERLEAVED,
87     H2_DEPENDANT_BEFORE,
88 } h2_dependency;
89 
90 typedef struct h2_priority {
91     h2_dependency dependency;
92     int           weight;
93 } h2_priority;
94 
95 typedef enum {
96     H2_PUSH_NONE,
97     H2_PUSH_DEFAULT,
98     H2_PUSH_HEAD,
99     H2_PUSH_FAST_LOAD,
100 } h2_push_policy;
101 
102 typedef enum {
103     H2_SESSION_ST_INIT,             /* send initial SETTINGS, etc. */
104     H2_SESSION_ST_DONE,             /* finished, connection close */
105     H2_SESSION_ST_IDLE,             /* nothing to write, expecting data inc */
106     H2_SESSION_ST_BUSY,             /* read/write without stop */
107     H2_SESSION_ST_WAIT,             /* waiting for c1 incoming + c2s output */
108     H2_SESSION_ST_CLEANUP,          /* pool is being cleaned up */
109 } h2_session_state;
110 
111 typedef struct h2_session_props {
112     int accepted_max;      /* the highest remote stream id was/will be handled */
113     int completed_max;     /* the highest remote stream completed */
114     int emitted_count;     /* the number of local streams sent */
115     int emitted_max;       /* the highest local stream id sent */
116     int error;             /* the last session error encountered */
117     const char *error_msg; /* the short message given on the error */
118     unsigned int accepting : 1;     /* if the session is accepting new streams */
119     unsigned int shutdown : 1;      /* if the final GOAWAY has been sent */
120 } h2_session_props;
121 
122 typedef enum h2_stream_state_t {
123     H2_SS_IDLE,
124     H2_SS_RSVD_R,
125     H2_SS_RSVD_L,
126     H2_SS_OPEN,
127     H2_SS_CLOSED_R,
128     H2_SS_CLOSED_L,
129     H2_SS_CLOSED,
130     H2_SS_CLEANUP,
131     H2_SS_MAX
132 } h2_stream_state_t;
133 
134 typedef enum {
135     H2_SEV_CLOSED_L,
136     H2_SEV_CLOSED_R,
137     H2_SEV_CANCELLED,
138     H2_SEV_EOS_SENT,
139     H2_SEV_IN_ERROR,
140     H2_SEV_IN_DATA_PENDING,
141     H2_SEV_OUT_C1_BLOCK,
142 } h2_stream_event_t;
143 
144 
145 /* h2_request is the transformer of HTTP2 streams into HTTP/1.1 internal
146  * format that will be fed to various httpd input filters to finally
147  * become a request_rec to be handled by soemone.
148  */
149 typedef struct h2_request h2_request;
150 struct h2_request {
151     const char *method; /* pseudo header values, see ch. 8.1.2.3 */
152     const char *scheme;
153     const char *authority;
154     const char *path;
155     apr_table_t *headers;
156 
157     apr_time_t request_time;
158     unsigned int chunked : 1;   /* iff request body needs to be forwarded as chunked */
159     apr_off_t raw_bytes;        /* RAW network bytes that generated this request - if known. */
160     int http_status;            /* Store a possible HTTP status code that gets
161                                  * defined before creating the dummy HTTP/1.1
162                                  * request e.g. due to an error already
163                                  * detected.
164                                  */
165 };
166 
167 /*
168  * A possible HTTP status code is not defined yet. See the http_status field
169  * in struct h2_request above for further explanation.
170  */
171 #define H2_HTTP_STATUS_UNSET (0)
172 
173 typedef struct h2_headers h2_headers;
174 struct h2_headers {
175     int         status;
176     apr_table_t *headers;
177     apr_table_t *notes;
178     apr_off_t   raw_bytes;      /* RAW network bytes that generated this request - if known. */
179 };
180 
181 typedef apr_status_t h2_io_data_cb(void *ctx, const char *data, apr_off_t len);
182 
183 typedef int h2_stream_pri_cmp_fn(int stream_id1, int stream_id2, void *session);
184 typedef struct h2_stream *h2_stream_get_fn(struct h2_session *session, int stream_id);
185 
186 /* Note key to attach stream id to conn_rec/request_rec instances */
187 #define H2_HDR_CONFORMANCE      "http2-hdr-conformance"
188 #define H2_HDR_CONFORMANCE_UNSAFE      "unsafe"
189 #define H2_PUSH_MODE_NOTE       "http2-push-mode"
190 
191 #endif /* defined(__mod_h2__h2__) */
192