Skip to main content

netlog/
h3.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;
28use serde::Serialize;
29
30use super::EventHeader;
31
32#[derive(Debug)]
33pub enum Event {
34    Http3PriorityUpdateSent(Http3PriorityUpdateSentEvent),
35    Http3HeadersSent(Http3HeadersSentEvent),
36    Http3DataSent(Http3DataSentEvent),
37    Http3HeadersReceived(Http3HeadersReceivedEvent),
38    Http3HeadersDecoded(Http3HeadersDecodedEvent),
39    Http3DataFrameReceived(Http3DataFrameReceivedEvent),
40}
41#[derive(Serialize, Deserialize, Debug, Default)]
42#[serde(rename_all = "snake_case")]
43pub enum PrioritizedElementType {
44    PushStream,
45    #[default]
46    RequestStream,
47}
48
49#[derive(Serialize, Deserialize, Debug, Default)]
50pub struct Http3PriorityUpdateSentParams {
51    pub prioritized_element_id: u64,
52    pub priority_field_value: String,
53    #[serde(rename = "type")]
54    pub ty: Option<PrioritizedElementType>,
55}
56
57#[derive(Serialize, Deserialize, Debug, Default)]
58pub struct Http3PriorityUpdateSentEvent {
59    pub params: Http3PriorityUpdateSentParams,
60}
61
62#[derive(Serialize, Deserialize, Debug, Default)]
63pub struct Http3HeadersSentParams {
64    pub stream_id: u64,
65    pub headers: Vec<String>,
66}
67
68#[derive(Serialize, Deserialize, Debug, Default)]
69pub struct Http3HeadersSentEvent {
70    pub params: Http3HeadersSentParams,
71}
72
73#[derive(Serialize, Deserialize, Debug, Default)]
74pub struct Http3DataSentParams {
75    pub payload_length: u64,
76    pub stream_id: u64,
77}
78
79#[derive(Serialize, Deserialize, Debug, Default)]
80pub struct Http3DataSentEvent {
81    pub params: Http3DataSentParams,
82}
83
84#[derive(Serialize, Deserialize, Debug, Default)]
85pub struct Http3HeadersReceivedParams {
86    pub stream_id: u64,
87    pub compressed_headers_length: u64,
88}
89
90#[derive(Serialize, Deserialize, Debug, Default)]
91pub struct Http3HeadersReceivedEvent {
92    pub params: Http3HeadersReceivedParams,
93}
94
95#[derive(Serialize, Deserialize, Debug, Default)]
96pub struct Http3HeadersDecodedParams {
97    pub stream_id: u64,
98    pub headers: Vec<String>,
99}
100
101#[derive(Serialize, Deserialize, Debug, Default)]
102pub struct Http3HeadersDecodedEvent {
103    pub params: Http3HeadersDecodedParams,
104}
105
106#[derive(Serialize, Deserialize, Debug, Default)]
107pub struct Http3DataFrameReceivedParams {
108    pub payload_length: u64,
109    pub stream_id: u64,
110}
111
112#[derive(Serialize, Deserialize, Debug, Default)]
113pub struct Http3DataFrameReceivedEvent {
114    pub params: Http3DataFrameReceivedParams,
115}
116
117/// Parses the provided `event` based on the event type provided in `event_hdr`.
118pub fn parse_event(
119    event_hdr: &EventHeader, event: &[u8],
120) -> Option<super::Event> {
121    match event_hdr.ty_string.as_str() {
122        "HTTP3_HEADERS_SENT" => {
123            let ev: Http3HeadersSentEvent =
124                serde_json::from_slice(event).unwrap();
125            return Some(super::Event::H3(Event::Http3HeadersSent(ev)));
126        },
127
128        "HTTP3_DATA_SENT" => {
129            let ev: Http3DataSentEvent = serde_json::from_slice(event).unwrap();
130            return Some(super::Event::H3(Event::Http3DataSent(ev)));
131        },
132
133        "HTTP3_HEADERS_RECEIVED" => {
134            let ev: Http3HeadersReceivedEvent =
135                serde_json::from_slice(event).unwrap();
136            return Some(super::Event::H3(Event::Http3HeadersReceived(ev)));
137        },
138
139        "HTTP3_HEADERS_DECODED" => {
140            let ev: Http3HeadersDecodedEvent =
141                serde_json::from_slice(event).unwrap();
142            return Some(super::Event::H3(Event::Http3HeadersDecoded(ev)));
143        },
144
145        "HTTP3_DATA_FRAME_RECEIVED" => {
146            let ev: Http3DataFrameReceivedEvent =
147                serde_json::from_slice(event).unwrap();
148            return Some(super::Event::H3(Event::Http3DataFrameReceived(ev)));
149        },
150
151        "HTTP3_PRIORITY_UPDATE_SENT" => {
152            let ev: Http3PriorityUpdateSentEvent =
153                serde_json::from_slice(event).unwrap();
154            return Some(super::Event::H3(Event::Http3PriorityUpdateSent(ev)));
155        },
156
157        "HTTP3_GOAWAY_SENT" | "HTTP3_GOAWAY_RECEIVED" => {
158            // TODO
159        },
160
161        // Other events observed in netlogs but not currently supported.
162        "HTTP3_LOCAL_CONTROL_STREAM_CREATED" |
163        "HTTP3_LOCAL_QPACK_DECODER_STREAM_CREATED" |
164        "HTTP3_LOCAL_QPACK_ENCODER_STREAM_CREATED" |
165        "HTTP3_PEER_QPACK_DECODER_STREAM_CREATED" |
166        "HTTP3_PEER_QPACK_ENCODER_STREAM_CREATED" |
167        "HTTP3_SETTINGS_SENT" |
168        "HTTP3_SETTINGS_RESUMED" |
169        "HTTP3_PEER_CONTROL_STREAM_CREATED" |
170        "HTTP3_SETTINGS_RECEIVED" |
171        "HTTP3_UNKNOWN_FRAME_RECEIVED" => (),
172
173        // The netlog format is continually evolving, log any unknown types
174        // in case they are interesting.
175        _ =>
176            log::trace!("skipping unknown HTTP/3 type....{}", event_hdr.ty_string),
177    }
178
179    None
180}