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