/src/trafficserver/include/proxy/http2/HTTP2.h
Line | Count | Source |
1 | | /** @file |
2 | | * |
3 | | * Fundamental HTTP/2 protocol definitions and parsers. |
4 | | * |
5 | | * @section license License |
6 | | * |
7 | | * Licensed to the Apache Software Foundation (ASF) under one |
8 | | * or more contributor license agreements. See the NOTICE file |
9 | | * distributed with this work for additional information |
10 | | * regarding copyright ownership. The ASF licenses this file |
11 | | * to you under the Apache License, Version 2.0 (the |
12 | | * "License"); you may not use this file except in compliance |
13 | | * with the License. You may obtain a copy of the License at |
14 | | * |
15 | | * http://www.apache.org/licenses/LICENSE-2.0 |
16 | | * |
17 | | * Unless required by applicable law or agreed to in writing, software |
18 | | * distributed under the License is distributed on an "AS IS" BASIS, |
19 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
20 | | * See the License for the specific language governing permissions and |
21 | | * limitations under the License. |
22 | | */ |
23 | | |
24 | | #pragma once |
25 | | |
26 | | #include "tscore/ink_defs.h" |
27 | | #include "tscore/ink_memory.h" |
28 | | #include "proxy/http2/HPACK.h" |
29 | | #include "proxy/hdrs/MIME.h" |
30 | | #include "records/RecDefs.h" |
31 | | |
32 | | #include "tsutil/Metrics.h" |
33 | | |
34 | | using ts::Metrics; |
35 | | |
36 | | class HTTPHdr; |
37 | | |
38 | | // [RFC 9113] 5.1.1 Stream identifiers. |
39 | | using Http2StreamId = uint32_t; |
40 | | |
41 | | constexpr Http2StreamId HTTP2_CONNECTION_CONTROL_STREAM = 0; |
42 | | constexpr uint8_t HTTP2_FRAME_NO_FLAG = 0; |
43 | | |
44 | | // [RFC 7540] 6.9.2. Initial Flow Control Window Size |
45 | | // the flow control window can be come negative so we need to track it with a signed type. |
46 | | using Http2WindowSize = int32_t; |
47 | | |
48 | | extern const char *const HTTP2_CONNECTION_PREFACE; |
49 | | const size_t HTTP2_CONNECTION_PREFACE_LEN = 24; |
50 | | |
51 | | const size_t HTTP2_FRAME_HEADER_LEN = 9; |
52 | | const size_t HTTP2_DATA_PADLEN_LEN = 1; |
53 | | const size_t HTTP2_HEADERS_PADLEN_LEN = 1; |
54 | | const size_t HTTP2_PRIORITY_LEN = 5; |
55 | | const size_t HTTP2_RST_STREAM_LEN = 4; |
56 | | const size_t HTTP2_PING_LEN = 8; |
57 | | const size_t HTTP2_GOAWAY_LEN = 8; |
58 | | const size_t HTTP2_WINDOW_UPDATE_LEN = 4; |
59 | | const size_t HTTP2_SETTINGS_PARAMETER_LEN = 6; |
60 | | |
61 | | // SETTINGS initial values. NOTE: These should not be modified |
62 | | // unless the protocol changes! Do not change this thinking you |
63 | | // are changing server defaults. that is done via RecordsConfig.cc |
64 | | const uint32_t HTTP2_ENABLE_PUSH = 1; |
65 | | const uint32_t HTTP2_MAX_CONCURRENT_STREAMS = UINT_MAX; |
66 | | const uint32_t HTTP2_INITIAL_WINDOW_SIZE = 65535; |
67 | | const uint32_t HTTP2_MAX_FRAME_SIZE = 16384; |
68 | | const uint32_t HTTP2_HEADER_TABLE_SIZE = 4096; |
69 | | const uint32_t HTTP2_MAX_HEADER_LIST_SIZE = UINT_MAX; |
70 | | const uint32_t HTTP2_MAX_BUFFER_USAGE = 524288; |
71 | | |
72 | | // [RFC 7540] 5.3.5 Default Priorities |
73 | | // The RFC says weight value is 1 to 256, but the value in TS is between 0 to 255 |
74 | | // to use uint8_t. So the default weight is 16 minus 1. |
75 | | const uint32_t HTTP2_PRIORITY_DEFAULT_STREAM_DEPENDENCY = 0; |
76 | | const uint8_t HTTP2_PRIORITY_DEFAULT_WEIGHT = 15; |
77 | | |
78 | | // Statistics |
79 | | struct Http2StatsBlock { |
80 | | Metrics::Gauge::AtomicType *current_client_session_count; |
81 | | Metrics::Gauge::AtomicType *current_server_session_count; |
82 | | Metrics::Gauge::AtomicType *current_active_client_connection_count; |
83 | | Metrics::Gauge::AtomicType *current_active_server_connection_count; |
84 | | Metrics::Gauge::AtomicType *current_client_stream_count; |
85 | | Metrics::Gauge::AtomicType *current_server_stream_count; |
86 | | Metrics::Counter::AtomicType *total_client_stream_count; |
87 | | Metrics::Counter::AtomicType *total_server_stream_count; |
88 | | Metrics::Counter::AtomicType *total_transactions_time; |
89 | | Metrics::Counter::AtomicType *total_client_connection_count; |
90 | | Metrics::Counter::AtomicType *total_server_connection_count; |
91 | | Metrics::Counter::AtomicType *stream_errors_count; |
92 | | Metrics::Counter::AtomicType *connection_errors_count; |
93 | | Metrics::Counter::AtomicType *session_die_default; |
94 | | Metrics::Counter::AtomicType *session_die_other; |
95 | | Metrics::Counter::AtomicType *session_die_active; |
96 | | Metrics::Counter::AtomicType *session_die_inactive; |
97 | | Metrics::Counter::AtomicType *session_die_eos; |
98 | | Metrics::Counter::AtomicType *session_die_error; |
99 | | Metrics::Counter::AtomicType *session_die_high_error_rate; |
100 | | Metrics::Counter::AtomicType *max_settings_per_frame_exceeded; |
101 | | Metrics::Counter::AtomicType *max_settings_per_minute_exceeded; |
102 | | Metrics::Counter::AtomicType *max_settings_frames_per_minute_exceeded; |
103 | | Metrics::Counter::AtomicType *max_ping_frames_per_minute_exceeded; |
104 | | Metrics::Counter::AtomicType *max_priority_frames_per_minute_exceeded; |
105 | | Metrics::Counter::AtomicType *max_rst_stream_frames_per_minute_exceeded; |
106 | | Metrics::Counter::AtomicType *max_continuation_frames_per_minute_exceeded; |
107 | | Metrics::Counter::AtomicType *max_empty_frames_per_minute_exceeded; |
108 | | Metrics::Counter::AtomicType *insufficient_avg_window_update; |
109 | | Metrics::Counter::AtomicType *max_concurrent_streams_exceeded_in; |
110 | | Metrics::Counter::AtomicType *max_concurrent_streams_exceeded_out; |
111 | | Metrics::Counter::AtomicType *max_active_streams_exceeded_in; |
112 | | Metrics::Counter::AtomicType *data_frames_in; |
113 | | Metrics::Counter::AtomicType *headers_frames_in; |
114 | | Metrics::Counter::AtomicType *priority_frames_in; |
115 | | Metrics::Counter::AtomicType *rst_stream_frames_in; |
116 | | Metrics::Counter::AtomicType *settings_frames_in; |
117 | | Metrics::Counter::AtomicType *push_promise_frames_in; |
118 | | Metrics::Counter::AtomicType *ping_frames_in; |
119 | | Metrics::Counter::AtomicType *goaway_frames_in; |
120 | | Metrics::Counter::AtomicType *window_update_frames_in; |
121 | | Metrics::Counter::AtomicType *continuation_frames_in; |
122 | | Metrics::Counter::AtomicType *unknown_frames_in; |
123 | | }; |
124 | | |
125 | | extern Http2StatsBlock http2_rsb; |
126 | | |
127 | | // [RFC 7540] 6.9.1. The Flow Control Window |
128 | | static const Http2WindowSize HTTP2_MAX_WINDOW_SIZE = 0x7FFFFFFF; |
129 | | |
130 | | // [RFC 7540] 5.4. Error Handling |
131 | | enum class Http2ErrorClass { |
132 | | HTTP2_ERROR_CLASS_NONE, |
133 | | HTTP2_ERROR_CLASS_CONNECTION, |
134 | | HTTP2_ERROR_CLASS_STREAM, |
135 | | }; |
136 | | |
137 | | // [RFC 7540] 7. Error Codes |
138 | | enum class Http2ErrorCode { |
139 | | HTTP2_ERROR_NO_ERROR = 0, |
140 | | HTTP2_ERROR_PROTOCOL_ERROR = 1, |
141 | | HTTP2_ERROR_INTERNAL_ERROR = 2, |
142 | | HTTP2_ERROR_FLOW_CONTROL_ERROR = 3, |
143 | | HTTP2_ERROR_SETTINGS_TIMEOUT = 4, |
144 | | HTTP2_ERROR_STREAM_CLOSED = 5, |
145 | | HTTP2_ERROR_FRAME_SIZE_ERROR = 6, |
146 | | HTTP2_ERROR_REFUSED_STREAM = 7, |
147 | | HTTP2_ERROR_CANCEL = 8, |
148 | | HTTP2_ERROR_COMPRESSION_ERROR = 9, |
149 | | HTTP2_ERROR_CONNECT_ERROR = 10, |
150 | | HTTP2_ERROR_ENHANCE_YOUR_CALM = 11, |
151 | | HTTP2_ERROR_INADEQUATE_SECURITY = 12, |
152 | | HTTP2_ERROR_HTTP_1_1_REQUIRED = 13, |
153 | | |
154 | | HTTP2_ERROR_MAX, |
155 | | }; |
156 | | |
157 | | // [RFC 7540] 5.1. Stream States |
158 | | enum class Http2StreamState { |
159 | | HTTP2_STREAM_STATE_IDLE, |
160 | | HTTP2_STREAM_STATE_RESERVED_LOCAL, |
161 | | HTTP2_STREAM_STATE_RESERVED_REMOTE, |
162 | | HTTP2_STREAM_STATE_OPEN, |
163 | | HTTP2_STREAM_STATE_HALF_CLOSED_LOCAL, |
164 | | HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE, |
165 | | HTTP2_STREAM_STATE_CLOSED |
166 | | }; |
167 | | |
168 | | enum Http2FrameType { |
169 | | HTTP2_FRAME_TYPE_DATA = 0, |
170 | | HTTP2_FRAME_TYPE_HEADERS = 1, |
171 | | HTTP2_FRAME_TYPE_PRIORITY = 2, |
172 | | HTTP2_FRAME_TYPE_RST_STREAM = 3, |
173 | | HTTP2_FRAME_TYPE_SETTINGS = 4, |
174 | | HTTP2_FRAME_TYPE_PUSH_PROMISE = 5, |
175 | | HTTP2_FRAME_TYPE_PING = 6, |
176 | | HTTP2_FRAME_TYPE_GOAWAY = 7, |
177 | | HTTP2_FRAME_TYPE_WINDOW_UPDATE = 8, |
178 | | HTTP2_FRAME_TYPE_CONTINUATION = 9, |
179 | | |
180 | | HTTP2_FRAME_TYPE_MAX, |
181 | | }; |
182 | | |
183 | | extern Metrics::Counter::AtomicType *http2_frame_metrics_in[HTTP2_FRAME_TYPE_MAX + 1]; |
184 | | |
185 | | // [RFC 7540] 6.1. Data |
186 | | enum Http2FrameFlagsData { |
187 | | HTTP2_FLAGS_DATA_END_STREAM = 0x01, |
188 | | HTTP2_FLAGS_DATA_PADDED = 0x08, |
189 | | |
190 | | HTTP2_FLAGS_DATA_MASK = 0x09, |
191 | | }; |
192 | | |
193 | | // [RFC 7540] 6.2. Headers |
194 | | enum Http2FrameFlagsHeaders { |
195 | | HTTP2_FLAGS_HEADERS_END_STREAM = 0x01, |
196 | | HTTP2_FLAGS_HEADERS_END_HEADERS = 0x04, |
197 | | HTTP2_FLAGS_HEADERS_PADDED = 0x08, |
198 | | HTTP2_FLAGS_HEADERS_PRIORITY = 0x20, |
199 | | |
200 | | HTTP2_FLAGS_HEADERS_MASK = 0x2D, |
201 | | }; |
202 | | |
203 | | // [RFC 7540] 6.3. Priority |
204 | | enum Http2FrameFlagsPriority { |
205 | | HTTP2_FLAGS_PRIORITY_MASK = 0x00, |
206 | | }; |
207 | | |
208 | | // [RFC 7540] 6.4. Rst Stream |
209 | | enum Http2FrameFlagsRstStream { |
210 | | HTTP2_FLAGS_RST_STREAM_MASK = 0x00, |
211 | | }; |
212 | | |
213 | | // [RFC 7540] 6.5. Settings |
214 | | enum Http2FrameFlagsSettings { |
215 | | HTTP2_FLAGS_SETTINGS_ACK = 0x01, |
216 | | |
217 | | HTTP2_FLAGS_SETTINGS_MASK = 0x01 |
218 | | }; |
219 | | |
220 | | // [RFC 7540] 6.6. Push Promise |
221 | | enum Http2FrameFlagsPushPromise { |
222 | | HTTP2_FLAGS_PUSH_PROMISE_END_HEADERS = 0x04, |
223 | | HTTP2_FLAGS_PUSH_PROMISE_PADDED = 0x08, |
224 | | |
225 | | HTTP2_FLAGS_PUSH_PROMISE_MASK = 0x0C, |
226 | | }; |
227 | | |
228 | | // [RFC 7540] 6.7. Ping |
229 | | enum Http2FrameFlagsPing { |
230 | | HTTP2_FLAGS_PING_ACK = 0x01, |
231 | | |
232 | | HTTP2_FLAGS_PING_MASK = 0x01 |
233 | | }; |
234 | | |
235 | | // [RFC 7540] 6.8. Goaway |
236 | | enum Http2FrameFlagsGoaway { |
237 | | HTTP2_FLAGS_GOAWAY_MASK = 0x00, |
238 | | }; |
239 | | |
240 | | // [RFC 7540] 6.9. Window Update |
241 | | enum Http2FrameFlagsWindowUpdate { |
242 | | HTTP2_FLAGS_WINDOW_UPDATE_MASK = 0x00, |
243 | | }; |
244 | | |
245 | | // [RFC 7540] 6.10. Continuation |
246 | | enum Http2FrameFlagsContinuation { |
247 | | HTTP2_FLAGS_CONTINUATION_END_HEADERS = 0x04, |
248 | | |
249 | | HTTP2_FLAGS_CONTINUATION_MASK = 0x04, |
250 | | }; |
251 | | |
252 | | // [RFC 7540] 6.5.2. Defined SETTINGS Parameters |
253 | | enum Http2SettingsIdentifier { |
254 | | HTTP2_SETTINGS_HEADER_TABLE_SIZE = 1, |
255 | | HTTP2_SETTINGS_ENABLE_PUSH = 2, |
256 | | HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 3, |
257 | | HTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 4, |
258 | | HTTP2_SETTINGS_MAX_FRAME_SIZE = 5, |
259 | | HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 6, |
260 | | HTTP2_SETTINGS_MAX, // Really just the max of the "densely numbered" core id's |
261 | | }; |
262 | | |
263 | | // [RFC 7540] 4.1. Frame Format |
264 | | struct Http2FrameHeader { |
265 | | uint32_t length; |
266 | | uint8_t type; |
267 | | uint8_t flags; |
268 | | Http2StreamId streamid; |
269 | | }; |
270 | | |
271 | | // [RFC 7540] 5.4. Error Handling |
272 | | struct Http2Error { |
273 | | Http2Error(const Http2ErrorClass error_class = Http2ErrorClass::HTTP2_ERROR_CLASS_NONE, |
274 | | const Http2ErrorCode error_code = Http2ErrorCode::HTTP2_ERROR_NO_ERROR, const char *err_msg = "") |
275 | 0 | { |
276 | 0 | cls = error_class; |
277 | 0 | code = error_code; |
278 | 0 | msg = err_msg; |
279 | 0 | }; |
280 | | |
281 | | Http2ErrorClass cls; |
282 | | Http2ErrorCode code; |
283 | | const char *msg; |
284 | | }; |
285 | | |
286 | | // [RFC 7540] 6.5.1. SETTINGS Format |
287 | | struct Http2SettingsParameter { |
288 | | uint16_t id; |
289 | | uint32_t value; |
290 | | }; |
291 | | |
292 | | // [RFC 7540] 6.3 PRIORITY Format |
293 | | struct Http2Priority { |
294 | 0 | Http2Priority() : weight(HTTP2_PRIORITY_DEFAULT_WEIGHT), stream_dependency(HTTP2_PRIORITY_DEFAULT_STREAM_DEPENDENCY) {} |
295 | | |
296 | | bool exclusive_flag = false; |
297 | | uint8_t weight; |
298 | | uint32_t stream_dependency; |
299 | | }; |
300 | | |
301 | | // [RFC 7540] 6.2 HEADERS Format |
302 | | struct Http2HeadersParameter { |
303 | 0 | Http2HeadersParameter() {} |
304 | | uint8_t pad_length = 0; |
305 | | Http2Priority priority; |
306 | | }; |
307 | | |
308 | | // [RFC 7540] 6.8 GOAWAY Format |
309 | | struct Http2Goaway { |
310 | 0 | Http2Goaway() {} |
311 | | Http2StreamId last_streamid = 0; |
312 | | Http2ErrorCode error_code = Http2ErrorCode::HTTP2_ERROR_NO_ERROR; |
313 | | |
314 | | // NOTE: we don't (de)serialize the variable length debug data at this layer |
315 | | // because there's |
316 | | // really nothing we can do with it without some out of band agreement. Trying |
317 | | // to deal with it |
318 | | // just complicates memory management. |
319 | | }; |
320 | | |
321 | | // [RFC 7540] 6.4 RST_STREAM Format |
322 | | struct Http2RstStream { |
323 | | uint32_t error_code; |
324 | | }; |
325 | | |
326 | | // [RFC 7540] 6.6 PUSH_PROMISE Format |
327 | | struct Http2PushPromise { |
328 | | uint8_t pad_length = 0; |
329 | | Http2StreamId promised_streamid = 0; |
330 | | }; |
331 | | |
332 | | static inline bool |
333 | | http2_is_client_streamid(Http2StreamId streamid) |
334 | 0 | { |
335 | 0 | return (streamid & 0x1u) == 0x1u; |
336 | 0 | } Unexecuted instantiation: fuzz_hpack.cc:http2_is_client_streamid(unsigned int) Unexecuted instantiation: HTTP2.cc:http2_is_client_streamid(unsigned int) Unexecuted instantiation: Http2Frame.cc:http2_is_client_streamid(unsigned int) |
337 | | |
338 | | static inline bool |
339 | | http2_is_server_streamid(Http2StreamId streamid) |
340 | 0 | { |
341 | 0 | return (streamid & 0x1u) == 0x0u && streamid != 0x0u; |
342 | 0 | } Unexecuted instantiation: fuzz_hpack.cc:http2_is_server_streamid(unsigned int) Unexecuted instantiation: HTTP2.cc:http2_is_server_streamid(unsigned int) Unexecuted instantiation: Http2Frame.cc:http2_is_server_streamid(unsigned int) |
343 | | |
344 | | bool http2_parse_frame_header(IOVec, Http2FrameHeader &); |
345 | | |
346 | | bool http2_write_frame_header(const Http2FrameHeader &, IOVec); |
347 | | |
348 | | bool http2_write_rst_stream(uint32_t, IOVec); |
349 | | |
350 | | bool http2_write_settings(const Http2SettingsParameter &, const IOVec &); |
351 | | |
352 | | bool http2_write_ping(const uint8_t *, IOVec); |
353 | | |
354 | | bool http2_write_goaway(const Http2Goaway &, IOVec); |
355 | | |
356 | | bool http2_write_window_update(const uint32_t new_size, const IOVec &); |
357 | | |
358 | | bool http2_write_push_promise(const Http2PushPromise &push_promise, const uint8_t *src, size_t length, const IOVec &iov); |
359 | | |
360 | | bool http2_frame_header_is_valid(const Http2FrameHeader &, unsigned); |
361 | | |
362 | | bool http2_settings_parameter_is_valid(const Http2SettingsParameter &); |
363 | | |
364 | | bool http2_parse_headers_parameter(IOVec, Http2HeadersParameter &); |
365 | | |
366 | | bool http2_parse_priority_parameter(IOVec, Http2Priority &); |
367 | | |
368 | | bool http2_parse_rst_stream(IOVec, Http2RstStream &); |
369 | | |
370 | | bool http2_parse_settings_parameter(IOVec, Http2SettingsParameter &); |
371 | | |
372 | | bool http2_parse_goaway(IOVec, Http2Goaway &); |
373 | | |
374 | | bool http2_parse_window_update(IOVec, uint32_t &); |
375 | | |
376 | | // Returns true if appending `payload_length` more bytes to an |
377 | | // existing CONTINUATION header-block accumulator of `current_length` would |
378 | | // overflow a uint32_t. Used by Http2ConnectionState::rcv_continuation_frame() |
379 | | // to reject crafted CONTINUATION chains whose total payload would wrap the |
380 | | // 32-bit accumulator and pair an undersized ats_realloc() with a memcpy at |
381 | | // the pre-wrap offset. |
382 | | static inline bool |
383 | | http2_continuation_length_would_overflow(uint32_t current_length, uint32_t payload_length) |
384 | 0 | { |
385 | 0 | return current_length > UINT32_MAX - payload_length; |
386 | 0 | } Unexecuted instantiation: fuzz_hpack.cc:http2_continuation_length_would_overflow(unsigned int, unsigned int) Unexecuted instantiation: HTTP2.cc:http2_continuation_length_would_overflow(unsigned int, unsigned int) Unexecuted instantiation: Http2Frame.cc:http2_continuation_length_would_overflow(unsigned int, unsigned int) |
387 | | |
388 | | Http2ErrorCode http2_decode_header_blocks(HTTPHdr *, const uint8_t *, const uint32_t, uint32_t *, HpackHandle &, bool, uint32_t, |
389 | | uint32_t, bool is_outbound = false); |
390 | | |
391 | | Http2ErrorCode http2_encode_header_blocks(HTTPHdr *, uint8_t *, uint32_t, uint32_t *, HpackHandle &, int32_t); |
392 | | |
393 | | ParseResult http2_convert_header_from_2_to_1_1(HTTPHdr *); |
394 | | ParseResult http2_convert_header_from_1_1_to_2(HTTPHdr *); |
395 | | void http2_init(); |
396 | | |
397 | | /** Each of these values correspond to the flow control policy described in or |
398 | | * records.yaml documentation for proxy.config.http2.flow_control.policy_in. |
399 | | */ |
400 | | enum class Http2FlowControlPolicy { |
401 | | STATIC_SESSION_AND_STATIC_STREAM, |
402 | | LARGE_SESSION_AND_STATIC_STREAM, |
403 | | LARGE_SESSION_AND_DYNAMIC_STREAM, |
404 | | }; |
405 | | |
406 | | // Not sure where else to put this, but figure this is as good of a start as |
407 | | // anything else. |
408 | | // Right now, only the static init() is available, which sets up some basic |
409 | | // librecords |
410 | | // dependencies. |
411 | | class Http2 |
412 | | { |
413 | | public: |
414 | | static uint32_t max_concurrent_streams_in; |
415 | | static uint32_t min_concurrent_streams_in; |
416 | | static uint32_t max_active_streams_in; |
417 | | static uint32_t max_active_streams_policy_in; |
418 | | static bool throttling; |
419 | | static uint32_t stream_priority_enabled; |
420 | | static uint32_t initial_window_size_in; |
421 | | static Http2FlowControlPolicy flow_control_policy_in; |
422 | | static uint32_t max_frame_size; |
423 | | static uint32_t header_table_size; |
424 | | static uint32_t max_header_list_size; |
425 | | static uint32_t accept_no_activity_timeout; |
426 | | static uint32_t no_activity_timeout_in; |
427 | | static uint32_t active_timeout_in; |
428 | | static uint32_t incomplete_header_timeout_in; |
429 | | static uint32_t push_diary_size; |
430 | | static uint32_t zombie_timeout_in; |
431 | | |
432 | | static uint32_t max_concurrent_streams_out; |
433 | | static uint32_t min_concurrent_streams_out; |
434 | | static uint32_t max_active_streams_out; |
435 | | static uint32_t no_activity_timeout_out; |
436 | | static uint32_t initial_window_size_out; |
437 | | static Http2FlowControlPolicy flow_control_policy_out; |
438 | | |
439 | | static float stream_error_rate_threshold; |
440 | | static uint32_t stream_error_sampling_threshold; |
441 | | static int32_t max_settings_per_frame; |
442 | | static int32_t max_settings_per_minute; |
443 | | static int32_t max_settings_frames_per_minute; |
444 | | static int32_t max_ping_frames_per_minute; |
445 | | static int32_t max_priority_frames_per_minute; |
446 | | static int32_t max_rst_stream_frames_per_minute; |
447 | | static int32_t max_continuation_frames_per_minute; |
448 | | static int32_t max_empty_frames_per_minute; |
449 | | static float min_avg_window_update; |
450 | | static uint32_t con_slow_log_threshold; |
451 | | static uint32_t stream_slow_log_threshold; |
452 | | static uint32_t header_table_size_limit; |
453 | | static uint32_t write_buffer_block_size; |
454 | | static int64_t write_buffer_block_size_index; |
455 | | static float write_size_threshold; |
456 | | static uint32_t write_time_threshold; |
457 | | static uint32_t buffer_water_mark; |
458 | | |
459 | | static void init(); |
460 | | }; |