1use serde::Deserialize;
28
29use super::EventHeader;
30use super::SourceDependency;
31
32use regex::Regex;
33use std::convert::TryFrom;
34
35#[derive(Debug)]
36pub enum Event {
37 Http2Session(Http2SessionEvent),
38 Http2SessionInitialized(Http2SessionInitializedEvent),
39 Http2SessionSendSettings(Http2SessionSendSettingsEvent),
40 Http2SessionRecvSetting(Http2SessionRecvSettingEvent),
41 Http2SessionSendHeaders(Http2SessionSendHeadersEvent),
42 Http2SessionSendData(Http2SessionSendDataEvent),
43 Http2SessionRecvHeaders(Http2SessionRecvHeadersEvent),
44 Http2SessionRecvData(Http2SessionRecvDataEvent),
45 Http2SessionUpdateRecvWindow(Http2SessionUpdateRecvWindowEvent),
46 Http2SessionUpdateSendWindow(Http2SessionUpdateSendWindowEvent),
47 Http2SessionUpdateStreamsSendWindowSize(
48 Http2SessionUpdateStreamsSendWindowSizeEvent,
49 ),
50 Http2SessionSendWindowUpdate(Http2SessionSendWindowUpdateEvent),
51 Http2SessionRecvWindowUpdate(Http2SessionRecvWindowUpdateEvent),
52 Http2StreamUpdateSendWindow(Http2StreamUpdateSendWindowEvent),
53 Http2StreamUpdateRecvWindow(Http2StreamUpdateRecvWindowEvent),
54 Http2StreamStalledByStreamSendWindow(
55 Http2StreamStalledByStreamSendWindowEvent,
56 ),
57 Http2SessionPing(Http2SessionPingEvent),
58 Http2SessionSendRstStream(Http2SessionSendRstStreamEvent),
59 Http2SessionRecvRstStream(Http2SessionRecvRstStreamEvent),
60 Http2SessionRecvGoaway(Http2SessionRecvGoawayEvent),
61 Http2SessionClose(Http2SessionCloseEvent),
62 Http2SessionStalledMaxStreams(Htt2SessionStalledMaxStreamsEvent),
63}
64
65#[derive(Deserialize, Debug, Default)]
66pub struct Http2SessionParams {
67 pub host: String,
68 pub proxy: String,
69}
70
71#[derive(Deserialize, Debug, Default)]
72pub struct Http2SessionEvent {
73 pub params: Http2SessionParams,
74}
75
76#[derive(Deserialize, Debug, Default)]
77pub struct Http2SessionInitializedParams {
78 pub protocol: String,
79 pub source_dependency: SourceDependency,
80}
81
82#[derive(Deserialize, Debug, Default)]
83pub struct Http2SessionInitializedEvent {
84 pub params: Http2SessionInitializedParams,
85}
86
87pub const H2_SEND_SETTINGS_PATTERN: &str = r"^\[id:(\d+) \(\w+\) value:(\d+)\]";
89#[derive(Deserialize, Debug, Default)]
90pub struct Http2SessionSendSettingsParams {
91 pub settings: Vec<String>,
92}
93
94#[derive(Deserialize, Debug, Default)]
95pub struct Http2SessionSendSettingsEvent {
96 pub params: Http2SessionSendSettingsParams,
97}
98
99pub const H2_RECV_SETTING_PATTERN: &str = r"^(\d+) \(\w+\)";
101#[derive(Deserialize, Debug, Default)]
102pub struct Http2SessionRecvSettingParams {
103 pub id: String,
104 pub value: u32,
105}
106
107#[derive(Deserialize, Debug, Default)]
108pub struct Http2SessionRecvSettingEvent {
109 pub params: Http2SessionRecvSettingParams,
110}
111
112#[derive(Deserialize, Debug, Default)]
113pub struct Http2SessionSendHeadersParams {
114 pub stream_id: u32,
115 pub headers: Vec<String>,
116 pub fin: bool,
117
118 pub has_priority: bool,
119 pub exclusive: bool,
120 pub weight: u16, pub parent_stream_id: u32,
123
124 pub source_dependency: SourceDependency,
125}
126
127#[derive(Deserialize, Debug, Default)]
128pub struct Http2SessionSendHeadersEvent {
129 pub params: Http2SessionSendHeadersParams,
130}
131
132#[derive(Deserialize, Debug, Default)]
133pub struct Http2SessionSendDataParams {
134 pub stream_id: u32,
135 pub size: u32,
136 pub fin: bool,
137}
138
139#[derive(Deserialize, Debug, Default)]
140pub struct Http2SessionSendDataEvent {
141 pub params: Http2SessionSendDataParams,
142}
143
144#[derive(Deserialize, Debug, Default)]
145pub struct Http2SessionRecvHeadersParams {
146 pub stream_id: u32,
147 pub headers: Vec<String>,
148 pub fin: bool,
149}
150
151#[derive(Deserialize, Debug, Default)]
152pub struct Http2SessionRecvHeadersEvent {
153 pub params: Http2SessionRecvHeadersParams,
154}
155
156#[derive(Deserialize, Debug, Default)]
157pub struct Http2SessionRecvDataParams {
158 pub stream_id: u32,
159 pub size: u32,
160 pub fin: bool,
161}
162
163#[derive(Deserialize, Debug, Default)]
164pub struct Http2SessionRecvDataEvent {
165 pub params: Http2SessionSendDataParams,
166}
167
168#[derive(Deserialize, Debug, Default)]
169pub struct Http2SessionUpdateRecvWindowParams {
170 pub delta: i32,
171 pub window_size: u32,
172}
173
174#[derive(Deserialize, Debug, Default)]
175pub struct Http2SessionUpdateRecvWindowEvent {
176 pub params: Http2SessionUpdateRecvWindowParams,
177}
178
179#[derive(Deserialize, Debug, Default)]
180pub struct Http2SessionUpdateSendWindowParams {
181 pub delta: i32,
182 pub window_size: u32,
183}
184
185#[derive(Deserialize, Debug, Default)]
186pub struct Http2SessionUpdateSendWindowEvent {
187 pub params: Http2SessionUpdateSendWindowParams,
188}
189
190#[derive(Deserialize, Debug, Default)]
191pub struct Http2SessionUpdateStreamsSendWindowSizeParams {
192 pub delta_window_size: u32,
193}
194
195#[derive(Deserialize, Debug, Default)]
196pub struct Http2SessionUpdateStreamsSendWindowSizeEvent {
197 pub params: Http2SessionUpdateStreamsSendWindowSizeParams,
198}
199
200#[derive(Deserialize, Debug, Default)]
201pub struct Http2SessionSendWindowUpdateParams {
202 pub delta: i32,
203 pub stream_id: u32,
204}
205
206#[derive(Deserialize, Debug, Default)]
207pub struct Http2SessionSendWindowUpdateEvent {
208 pub params: Http2SessionSendWindowUpdateParams,
209}
210
211#[derive(Deserialize, Debug, Default)]
212pub struct Http2SessionRecvWindowUpdateParams {
213 pub delta: i32,
214 pub stream_id: u32,
215}
216
217#[derive(Deserialize, Debug, Default)]
218pub struct Http2SessionRecvWindowUpdateEvent {
219 pub params: Http2SessionRecvWindowUpdateParams,
220}
221
222#[derive(Deserialize, Debug, Default)]
223pub struct Http2StreamUpdateSendWindowParams {
224 pub delta: i32,
225 pub stream_id: u32,
226}
227
228#[derive(Deserialize, Debug, Default)]
229pub struct Http2StreamUpdateSendWindowEvent {
230 pub params: Http2StreamUpdateSendWindowParams,
231}
232
233#[derive(Deserialize, Debug, Default)]
234pub struct Http2StreamUpdateRecvWindowParams {
235 pub delta: i32,
236 pub stream_id: u32,
237 pub window_size: u32,
238}
239
240#[derive(Deserialize, Debug, Default)]
241pub struct Http2StreamUpdateRecvWindowEvent {
242 pub params: Http2StreamUpdateRecvWindowParams,
243}
244
245#[derive(Deserialize, Debug, Default)]
246pub struct Http2StreamStalledByStreamSendWindowParams {
247 pub stream_id: u32,
248}
249
250#[derive(Deserialize, Debug, Default)]
251pub struct Http2StreamStalledByStreamSendWindowEvent {
252 pub params: Http2StreamStalledByStreamSendWindowParams,
253}
254
255#[derive(Deserialize, Debug, Default)]
256pub struct Http2SessionPingParams {
257 pub is_ack: bool,
258 #[serde(rename = "type")]
259 pub ty: String,
260 pub unique_id: u64,
261}
262
263#[derive(Deserialize, Debug, Default)]
264pub struct Http2SessionPingEvent {
265 pub params: Http2SessionPingParams,
266}
267
268#[derive(Deserialize, Debug, Default)]
269pub struct Http2SessionSendRstStreamParams {
270 pub stream_id: u32,
271 pub description: String,
272 pub error_code: String,
273}
274
275#[derive(Deserialize, Debug, Default)]
276pub struct Http2SessionSendRstStreamEvent {
277 pub params: Http2SessionSendRstStreamParams,
278}
279
280#[derive(Deserialize, Debug, Default)]
281pub struct Http2SessionRecvRstStreamParams {
282 pub stream_id: u32,
283 pub error_code: String,
284}
285
286#[derive(Deserialize, Debug, Default)]
287pub struct Http2SessionRecvRstStreamEvent {
288 pub params: Http2SessionRecvRstStreamParams,
289}
290
291#[derive(Deserialize, Debug, Default)]
292pub struct Http2SessionRecvGoawayParams {
293 pub active_streams: u32,
294 pub debug_data: String,
295 pub error_code: String,
296}
297
298#[derive(Deserialize, Debug, Default)]
299pub struct Http2SessionRecvGoawayEvent {
300 pub params: Http2SessionRecvGoawayParams,
301}
302
303#[derive(Deserialize, Debug, Default)]
304pub struct Http2SessionCloseParams {
305 pub description: String,
306 pub net_error: i64,
307}
308
309#[derive(Deserialize, Debug, Default)]
310pub struct Http2SessionCloseEvent {
311 pub params: Http2SessionCloseParams,
312}
313
314#[derive(Deserialize, Debug, Default)]
315pub struct Htt2SessionStalledMaxStreamsParams {
316 pub max_concurrent_streams: u32,
317 pub num_active_streams: u32,
318 pub num_created_streams: u32,
319}
320
321#[derive(Deserialize, Debug, Default)]
322pub struct Htt2SessionStalledMaxStreamsEvent {
323 pub params: Htt2SessionStalledMaxStreamsParams,
324}
325
326const H2_HEADER_TABLE_SIZE: u16 = 0x01;
327const H2_ENABLE_PUSH: u16 = 0x02;
328const H2_MAX_CONCURRENT_STREAMS: u16 = 0x03;
329const H2_INITIAL_WINDOW_SIZE: u16 = 0x04;
330const H2_MAX_FRAME_SIZE: u16 = 0x05;
331const H2_MAX_HEADER_LIST_SIZE: u16 = 0x06;
332const H2_ENABLE_CONNECT_PROTOCOL: u16 = 0x08;
333const H2_NO_RFC7540_PRIORITIES: u16 = 0x09;
334const H2_TLS_RENEG_PERMITTED: u16 = 0x10;
335const H2_ENABLE_METADATA: u16 = 0x4d44;
336
337pub const H2_DEFAULT_WINDOW_SIZE: u32 = 65535;
338
339#[derive(Debug, Default)]
340pub struct Http2Settings {
341 pub header_table_size: Option<u32>,
342 pub enable_push: Option<u32>,
343 pub max_concurrent_streams: Option<u32>,
344 pub initial_window_size: Option<u32>,
345 pub max_frame_size: Option<u32>,
346 pub max_header_list_size: Option<u32>,
347 pub enable_connect_protocol: Option<u32>,
348 pub no_rfc7540_priorities: Option<u32>,
349 pub tls_reneg_permitted: Option<u32>,
350 pub enable_metadata: Option<u32>,
351}
352
353impl Http2Settings {
354 pub fn set_from_wire(&mut self, id: u16, value: u32) {
355 match id {
356 H2_HEADER_TABLE_SIZE => self.header_table_size = Some(value),
357 H2_ENABLE_PUSH => self.enable_push = Some(value),
358 H2_MAX_CONCURRENT_STREAMS =>
359 self.max_concurrent_streams = Some(value),
360 H2_INITIAL_WINDOW_SIZE => self.initial_window_size = Some(value),
361 H2_MAX_FRAME_SIZE => self.max_frame_size = Some(value),
362 H2_MAX_HEADER_LIST_SIZE => self.max_header_list_size = Some(value),
363 H2_ENABLE_CONNECT_PROTOCOL =>
364 self.enable_connect_protocol = Some(value),
365 H2_NO_RFC7540_PRIORITIES => self.no_rfc7540_priorities = Some(value),
366 H2_TLS_RENEG_PERMITTED => self.tls_reneg_permitted = Some(value),
367 H2_ENABLE_METADATA => self.enable_metadata = Some(value),
368
369 _ => (),
371 }
372 }
373}
374
375impl TryFrom<&[String]> for Http2Settings {
376 type Error = String;
377
378 fn try_from(settings: &[String]) -> Result<Self, Self::Error> {
379 let re = Regex::new(H2_SEND_SETTINGS_PATTERN).unwrap();
380 let mut parsed = Self::default();
381
382 for setting in settings {
383 match re.captures(setting) {
384 Some(caps) => match (caps.get(1), caps.get(2)) {
385 (Some(id), Some(value)) => {
386 match (
387 id.as_str().parse::<u16>(),
388 value.as_str().parse::<u32>(),
389 ) {
390 (Ok(id), Ok(v)) => {
391 parsed.set_from_wire(id, v);
392 },
393
394 _ =>
395 return Err(format!(
396 "error: parsing H2 setting {}",
397 setting
398 )),
399 }
400 },
401
402 _ =>
403 return Err(format!(
404 "error: parsing H2 setting {}",
405 setting
406 )),
407 },
408
409 None =>
410 return Err(format!("error: parsing H2 setting {}", setting)),
411 }
412 }
413
414 Ok(parsed)
415 }
416}
417
418pub fn parse_event(
420 event_hdr: &EventHeader, event: &[u8],
421) -> Option<super::Event> {
422 match event_hdr.ty_string.as_str() {
423 "HTTP2_SESSION" =>
424 if event_hdr.phase_string == "PHASE_BEGIN" {
425 let ev: Http2SessionEvent =
426 serde_json::from_slice(event).unwrap();
427 return Some(super::Event::H2(Event::Http2Session(ev)));
428 },
429
430 "HTTP2_SESSION_INITIALIZED" => {
431 let ev: Http2SessionInitializedEvent =
432 serde_json::from_slice(event).unwrap();
433 return Some(super::Event::H2(Event::Http2SessionInitialized(ev)));
434 },
435
436 "HTTP2_SESSION_SEND_SETTINGS" => {
437 let ev: Http2SessionSendSettingsEvent =
438 serde_json::from_slice(event).unwrap();
439 return Some(super::Event::H2(Event::Http2SessionSendSettings(ev)));
440 },
441
442 "HTTP2_SESSION_RECV_SETTING" => {
443 let ev: Http2SessionRecvSettingEvent =
444 serde_json::from_slice(event).unwrap();
445 return Some(super::Event::H2(Event::Http2SessionRecvSetting(ev)));
446 },
447
448 "HTTP2_SESSION_UPDATE_RECV_WINDOW" => {
449 let ev: Http2SessionUpdateRecvWindowEvent =
450 serde_json::from_slice(event).unwrap();
451 return Some(super::Event::H2(Event::Http2SessionUpdateRecvWindow(
452 ev,
453 )));
454 },
455
456 "HTTP2_SESSION_UPDATE_SEND_WINDOW" => {
457 let ev: Http2SessionUpdateSendWindowEvent =
458 serde_json::from_slice(event).unwrap();
459 return Some(super::Event::H2(Event::Http2SessionUpdateSendWindow(
460 ev,
461 )));
462 },
463
464 "HTTP2_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE" => {
465 let ev: Http2SessionUpdateStreamsSendWindowSizeEvent =
466 serde_json::from_slice(event).unwrap();
467 return Some(super::Event::H2(
468 Event::Http2SessionUpdateStreamsSendWindowSize(ev),
469 ));
470 },
471
472 "HTTP2_SESSION_SEND_WINDOW_UPDATE" => {
473 let ev: Http2SessionSendWindowUpdateEvent =
474 serde_json::from_slice(event).unwrap();
475
476 return Some(super::Event::H2(Event::Http2SessionSendWindowUpdate(
477 ev,
478 )));
479 },
480
481 "HTTP2_SESSION_RECV_WINDOW_UPDATE" => {
482 let ev: Http2SessionRecvWindowUpdateEvent =
483 serde_json::from_slice(event).unwrap();
484 return Some(super::Event::H2(Event::Http2SessionRecvWindowUpdate(
485 ev,
486 )));
487 },
488
489 "HTTP2_STREAM_UPDATE_SEND_WINDOW" => {
490 let ev: Http2StreamUpdateSendWindowEvent =
491 serde_json::from_slice(event).unwrap();
492 return Some(super::Event::H2(Event::Http2StreamUpdateSendWindow(
493 ev,
494 )));
495 },
496
497 "HTTP2_STREAM_UPDATE_RECV_WINDOW" => {
498 let ev: Http2StreamUpdateRecvWindowEvent =
499 serde_json::from_slice(event).unwrap();
500 return Some(super::Event::H2(Event::Http2StreamUpdateRecvWindow(
501 ev,
502 )));
503 },
504
505 "HTTP2_SESSION_STREAM_STALLED_BY_STREAM_SEND_WINDOW" => {
506 let ev: Http2StreamStalledByStreamSendWindowEvent =
507 serde_json::from_slice(event).unwrap();
508 return Some(super::Event::H2(
509 Event::Http2StreamStalledByStreamSendWindow(ev),
510 ));
511 },
512
513 "HTTP2_SESSION_SEND_HEADERS" => {
514 let ev: Http2SessionSendHeadersEvent =
515 serde_json::from_slice(event).unwrap();
516 return Some(super::Event::H2(Event::Http2SessionSendHeaders(ev)));
517 },
518
519 "HTTP2_SESSION_SEND_DATA" => {
520 let ev: Http2SessionSendDataEvent =
521 serde_json::from_slice(event).unwrap();
522 return Some(super::Event::H2(Event::Http2SessionSendData(ev)));
523 },
524
525 "HTTP2_SESSION_RECV_HEADERS" => {
526 let ev: Http2SessionRecvHeadersEvent =
527 serde_json::from_slice(event).unwrap();
528 return Some(super::Event::H2(Event::Http2SessionRecvHeaders(ev)));
529 },
530
531 "HTTP2_SESSION_RECV_DATA" => {
532 let ev: Http2SessionRecvDataEvent =
533 serde_json::from_slice(event).unwrap();
534 return Some(super::Event::H2(Event::Http2SessionRecvData(ev)));
535 },
536
537 "HTTP2_SESSION_PING" => {
538 let ev: Http2SessionPingEvent =
539 serde_json::from_slice(event).unwrap();
540 return Some(super::Event::H2(Event::Http2SessionPing(ev)));
541 },
542
543 "HTTP2_SESSION_SEND_RST_STREAM" => {
544 let ev: Http2SessionSendRstStreamEvent =
545 serde_json::from_slice(event).unwrap();
546 return Some(super::Event::H2(Event::Http2SessionSendRstStream(ev)));
547 },
548
549 "HTTP2_SESSION_RECV_RST_STREAM" => {
550 let ev: Http2SessionRecvRstStreamEvent =
551 serde_json::from_slice(event).unwrap();
552 return Some(super::Event::H2(Event::Http2SessionRecvRstStream(ev)));
553 },
554
555 "HTTP2_SESSION_RECV_GOAWAY" => {
556 let ev: Http2SessionRecvGoawayEvent =
557 serde_json::from_slice(event).unwrap();
558 return Some(super::Event::H2(Event::Http2SessionRecvGoaway(ev)));
559 },
560
561 "HTTP2_SESSION_CLOSE" => {
562 let ev: Http2SessionCloseEvent =
563 serde_json::from_slice(event).unwrap();
564
565 return Some(super::Event::H2(Event::Http2SessionClose(ev)));
566 },
567
568 "HTTP2_SESSION_STALLED_MAX_STREAMS" => {
569 let ev: Htt2SessionStalledMaxStreamsEvent =
570 serde_json::from_slice(event).unwrap();
571 return Some(super::Event::H2(Event::Http2SessionStalledMaxStreams(
572 ev,
573 )));
574 },
575
576 "HTTP2_PROXY_CLIENT_SESSION" |
578 "HTTP2_SESSION_INITIAL_WINDOW_SIZE_OUT_OF_RANGE" |
579 "HTTP2_SESSION_RECV_INVALID_HEADER" |
580 "HTTP2_SESSION_RECV_PUSH_PROMISE" |
581 "HTTP2_SESSION_SEND_GREASED_FRAME" |
582 "HTTP2_SESSION_STREAM_STALLED_BY_SESSION_SEND_WINDOW" |
583 "HTTP2_STREAM" |
584 "HTTP2_STREAM_ADOPTED_PUSH_STREAM" |
585 "HTTP2_STREAM_ERROR" |
586 "HTTP2_STREAM_FLOW_CONTROL_UNSTALLED" |
587 "HTTP2_STREAM_SEND_PRIORITY" => log::trace!(
588 "todo: {} => {}\n",
589 event_hdr.ty_string,
590 String::from_utf8_lossy(event)
591 ),
592
593 "HTTP2_SESSION_POOL_CREATED_NEW_SESSION" |
595 "HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION" |
596 "HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL" |
597 "HTTP2_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET" |
598 "HTTP2_SESSION_POOL_REMOVE_SESSION" |
599 "HTTP2_SESSION_RECV_ACCEPT_CH" |
600 "HTTP2_SESSION_RECV_SETTINGS" |
601 "HTTP2_SESSION_SEND_SETTINGS_ACK" |
602 "HTTP2_SESSION_RECV_SETTINGS_ACK" => (),
603
604 _ =>
607 log::trace!("skipping unknown HTTP/2 type....{}", event_hdr.ty_string),
608 }
609
610 None
611}