Skip to main content

netlog/
h2.rs

1// Copyright (C) 2025, Cloudflare, Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8//     * Redistributions of source code must retain the above copyright notice,
9//       this list of conditions and the following disclaimer.
10//
11//     * Redistributions in binary form must reproduce the above copyright
12//       notice, this list of conditions and the following disclaimer in the
13//       documentation and/or other materials provided with the distribution.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
19// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27use 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
87// Example: "[id:1 (SETTINGS_HEADER_TABLE_SIZE) value:65536]"
88pub 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
99// Example: "3 (SETTINGS_MAX_CONCURRENT_STREAMS)"
100pub 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, /* TODO: this is really an 8-bit integer but the number
121                      * range is 1-256 so u8 fails */
122    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            // TODO: ignoring unknown settings but could capture them
370            _ => (),
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
418/// Parses the provided `event` based on the event type provided in `event_hdr`.
419pub 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        // TODO
577        "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        // Other events observed in netlogs but not currently supported.
594        "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        // The netlog format is continually evolving, log any unknown types in
605        // case they are interesting.
606        _ =>
607            log::trace!("skipping unknown HTTP/2 type....{}", event_hdr.ty_string),
608    }
609
610    None
611}