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