xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/http/http_decoder.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
6 #define QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
7 
8 #include <cstdint>
9 
10 #include "absl/strings/string_view.h"
11 #include "quiche/quic/core/http/http_frames.h"
12 #include "quiche/quic/core/quic_error_codes.h"
13 #include "quiche/quic/core/quic_types.h"
14 #include "quiche/quic/platform/api/quic_export.h"
15 
16 namespace quic {
17 
18 namespace test {
19 
20 class HttpDecoderPeer;
21 
22 }  // namespace test
23 
24 class QuicDataReader;
25 
26 // A class for decoding the HTTP frames that are exchanged in an HTTP over QUIC
27 // session.
28 class QUICHE_EXPORT HttpDecoder {
29  public:
30   class QUICHE_EXPORT Visitor {
31    public:
~Visitor()32     virtual ~Visitor() {}
33 
34     // Called if an error is detected.
35     virtual void OnError(HttpDecoder* decoder) = 0;
36 
37     // All the following methods return true to continue decoding,
38     // and false to pause it.
39     // On*FrameStart() methods are called after the frame header is completely
40     // processed.  At that point it is safe to consume |header_length| bytes.
41 
42     // Called when a MAX_PUSH_ID frame has been successfully parsed.
43     virtual bool OnMaxPushIdFrame() = 0;
44 
45     // Called when a GOAWAY frame has been successfully parsed.
46     virtual bool OnGoAwayFrame(const GoAwayFrame& frame) = 0;
47 
48     // Called when a SETTINGS frame has been received.
49     virtual bool OnSettingsFrameStart(QuicByteCount header_length) = 0;
50 
51     // Called when a SETTINGS frame has been successfully parsed.
52     virtual bool OnSettingsFrame(const SettingsFrame& frame) = 0;
53 
54     // Called when a DATA frame has been received.
55     // |header_length| and |payload_length| are the length of DATA frame header
56     // and payload, respectively.
57     virtual bool OnDataFrameStart(QuicByteCount header_length,
58                                   QuicByteCount payload_length) = 0;
59     // Called when part of the payload of a DATA frame has been read.  May be
60     // called multiple times for a single frame.  |payload| is guaranteed to be
61     // non-empty.
62     virtual bool OnDataFramePayload(absl::string_view payload) = 0;
63     // Called when a DATA frame has been completely processed.
64     virtual bool OnDataFrameEnd() = 0;
65 
66     // Called when a HEADERS frame has been received.
67     // |header_length| and |payload_length| are the length of HEADERS frame
68     // header and payload, respectively.
69     virtual bool OnHeadersFrameStart(QuicByteCount header_length,
70                                      QuicByteCount payload_length) = 0;
71     // Called when part of the payload of a HEADERS frame has been read.  May be
72     // called multiple times for a single frame.  |payload| is guaranteed to be
73     // non-empty.
74     virtual bool OnHeadersFramePayload(absl::string_view payload) = 0;
75     // Called when a HEADERS frame has been completely processed.
76     virtual bool OnHeadersFrameEnd() = 0;
77 
78     // Called when a PRIORITY_UPDATE frame has been received.
79     // |header_length| contains PRIORITY_UPDATE frame length and payload length.
80     virtual bool OnPriorityUpdateFrameStart(QuicByteCount header_length) = 0;
81 
82     // Called when a PRIORITY_UPDATE frame has been successfully parsed.
83     virtual bool OnPriorityUpdateFrame(const PriorityUpdateFrame& frame) = 0;
84 
85     // Called when an ACCEPT_CH frame has been received.
86     // |header_length| contains ACCEPT_CH frame length and payload length.
87     virtual bool OnAcceptChFrameStart(QuicByteCount header_length) = 0;
88 
89     // Called when an ACCEPT_CH frame has been successfully parsed.
90     virtual bool OnAcceptChFrame(const AcceptChFrame& frame) = 0;
91 
92     // Called when a WEBTRANSPORT_STREAM frame type and the session ID varint
93     // immediately following it has been received.  Any further parsing should
94     // be done by the stream itself, and not the parser. Note that this does not
95     // return bool, because WEBTRANSPORT_STREAM always causes the parsing
96     // process to cease.
97     virtual void OnWebTransportStreamFrameType(
98         QuicByteCount header_length, WebTransportSessionId session_id) = 0;
99 
100     // Called when a METADATA frame has been received.
101     // |header_length| and |payload_length| are the length of the frame header
102     // and payload, respectively.
103     virtual bool OnMetadataFrameStart(QuicByteCount header_length,
104                                       QuicByteCount payload_length) = 0;
105 
106     // Called when part of the payload of the METADATA frame has been read.  May
107     // be called multiple times for a single frame.  |payload| is guaranteed to
108     // be non-empty.
109     virtual bool OnMetadataFramePayload(absl::string_view payload) = 0;
110 
111     // Called when the METADATA frame has been completely processed.
112     virtual bool OnMetadataFrameEnd() = 0;
113 
114     // Called when a frame of unknown type |frame_type| has been received.
115     // Frame type might be reserved, Visitor must make sure to ignore.
116     // |header_length| and |payload_length| are the length of the frame header
117     // and payload, respectively.
118     virtual bool OnUnknownFrameStart(uint64_t frame_type,
119                                      QuicByteCount header_length,
120                                      QuicByteCount payload_length) = 0;
121     // Called when part of the payload of the unknown frame has been read.  May
122     // be called multiple times for a single frame.  |payload| is guaranteed to
123     // be non-empty.
124     virtual bool OnUnknownFramePayload(absl::string_view payload) = 0;
125     // Called when the unknown frame has been completely processed.
126     virtual bool OnUnknownFrameEnd() = 0;
127   };
128 
129   // |visitor| must be non-null, and must outlive HttpDecoder.
130   explicit HttpDecoder(Visitor* visitor);
131 
132   ~HttpDecoder();
133 
134   // Processes the input and invokes the appropriate visitor methods, until a
135   // visitor method returns false or an error occurs.  Returns the number of
136   // bytes processed.  Does not process any input if called after an error.
137   // Paused processing can be resumed by calling ProcessInput() again with the
138   // unprocessed portion of data.  Must not be called after an error has
139   // occurred.
140   QuicByteCount ProcessInput(const char* data, QuicByteCount len);
141 
142   // Decode settings frame from |data|.
143   // Upon successful decoding, |frame| will be populated, and returns true.
144   // This method is not used for regular processing of incoming data.
145   static bool DecodeSettings(const char* data, QuicByteCount len,
146                              SettingsFrame* frame);
147 
148   // Returns an error code other than QUIC_NO_ERROR if and only if
149   // Visitor::OnError() has been called.
error()150   QuicErrorCode error() const { return error_; }
151 
error_detail()152   const std::string& error_detail() const { return error_detail_; }
153 
154   // Returns true if input data processed so far ends on a frame boundary.
AtFrameBoundary()155   bool AtFrameBoundary() const { return state_ == STATE_READING_FRAME_TYPE; }
156 
157   // Indicates that WEBTRANSPORT_STREAM should be parsed.
EnableWebTransportStreamParsing()158   void EnableWebTransportStreamParsing() { allow_web_transport_stream_ = true; }
159 
160   std::string DebugString() const;
161 
162  private:
163   friend test::HttpDecoderPeer;
164 
165   // Represents the current state of the parsing state machine.
166   enum HttpDecoderState {
167     STATE_READING_FRAME_LENGTH,
168     STATE_READING_FRAME_TYPE,
169 
170     // States used for buffered frame types
171     STATE_BUFFER_OR_PARSE_PAYLOAD,
172 
173     // States used for non-buffered frame types
174     STATE_READING_FRAME_PAYLOAD,
175     STATE_FINISH_PARSING,
176 
177     STATE_PARSING_NO_LONGER_POSSIBLE,
178     STATE_ERROR
179   };
180 
181   // Reads the type of a frame from |reader|. Sets error_ and error_detail_
182   // if there are any errors.  Also calls OnDataFrameStart() or
183   // OnHeadersFrameStart() for appropriate frame types. Returns whether the
184   // processing should continue.
185   bool ReadFrameType(QuicDataReader* reader);
186 
187   // Reads the length of a frame from |reader|. Sets error_ and error_detail_
188   // if there are any errors.  Returns whether processing should continue.
189   bool ReadFrameLength(QuicDataReader* reader);
190 
191   // Returns whether the current frame is of a buffered type.
192   // The payload of buffered frames is buffered by HttpDecoder, and parsed by
193   // HttpDecoder after the entire frame has been received.  (Copying to the
194   // buffer is skipped if the ProcessInput() call covers the entire payload.)
195   // Frames that are not buffered have every payload fragment synchronously
196   // passed to the Visitor without buffering.
197   bool IsFrameBuffered();
198 
199   // For buffered frame types, calls BufferOrParsePayload().  For other frame
200   // types, reads the payload of the current frame from |reader| and calls
201   // visitor methods.  Returns whether processing should continue.
202   bool ReadFramePayload(QuicDataReader* reader);
203 
204   // For buffered frame types, this method is only called if frame payload is
205   // empty, and it calls BufferOrParsePayload().  For other frame types, this
206   // method directly calls visitor methods to signal that frame had been
207   // received completely.  Returns whether processing should continue.
208   bool FinishParsing();
209 
210   // Reset internal fields to prepare for reading next frame.
211   void ResetForNextFrame();
212 
213   // Read payload of unknown frame from |reader| and call
214   // Visitor::OnUnknownFramePayload().  Returns true decoding should continue,
215   // false if it should be paused.
216   bool HandleUnknownFramePayload(QuicDataReader* reader);
217 
218   // Buffers any remaining frame payload from |*reader| into |buffer_| if
219   // necessary.  Parses the frame payload if complete.  Parses out of |*reader|
220   // without unnecessary copy if |*reader| contains entire payload.
221   // Returns whether processing should continue.
222   // Must only be called when current frame type is buffered.
223   bool BufferOrParsePayload(QuicDataReader* reader);
224 
225   // Parses the entire payload of certain kinds of frames that are parsed in a
226   // single pass.  |reader| must have at least |current_frame_length_| bytes.
227   // Returns whether processing should continue.
228   // Must only be called when current frame type is buffered.
229   bool ParseEntirePayload(QuicDataReader* reader);
230 
231   // Buffers any remaining frame length field from |reader| into
232   // |length_buffer_|.
233   void BufferFrameLength(QuicDataReader* reader);
234 
235   // Buffers any remaining frame type field from |reader| into |type_buffer_|.
236   void BufferFrameType(QuicDataReader* reader);
237 
238   // Sets |error_| and |error_detail_| accordingly.
239   void RaiseError(QuicErrorCode error, std::string error_detail);
240 
241   // Parses the payload of a SETTINGS frame from |reader| into |frame|.
242   bool ParseSettingsFrame(QuicDataReader* reader, SettingsFrame* frame);
243 
244   // Parses the payload of a PRIORITY_UPDATE frame (draft-02, type 0xf0700)
245   // from |reader| into |frame|.
246   bool ParsePriorityUpdateFrame(QuicDataReader* reader,
247                                 PriorityUpdateFrame* frame);
248 
249   // Parses the payload of an ACCEPT_CH frame from |reader| into |frame|.
250   bool ParseAcceptChFrame(QuicDataReader* reader, AcceptChFrame* frame);
251 
252   // Returns the max frame size of a given |frame_type|.
253   QuicByteCount MaxFrameLength(uint64_t frame_type);
254 
255   // Visitor to invoke when messages are parsed.
256   Visitor* const visitor_;  // Unowned.
257   // Whether WEBTRANSPORT_STREAM should be parsed.
258   bool allow_web_transport_stream_;
259   // Current state of the parsing.
260   HttpDecoderState state_;
261   // Type of the frame currently being parsed.
262   uint64_t current_frame_type_;
263   // Size of the frame's length field.
264   QuicByteCount current_length_field_length_;
265   // Remaining length that's needed for the frame's length field.
266   QuicByteCount remaining_length_field_length_;
267   // Length of the payload of the frame currently being parsed.
268   QuicByteCount current_frame_length_;
269   // Remaining payload bytes to be parsed.
270   QuicByteCount remaining_frame_length_;
271   // Length of the frame's type field.
272   QuicByteCount current_type_field_length_;
273   // Remaining length that's needed for the frame's type field.
274   QuicByteCount remaining_type_field_length_;
275   // Last error.
276   QuicErrorCode error_;
277   // The issue which caused |error_|
278   std::string error_detail_;
279   // Remaining unparsed data.
280   std::string buffer_;
281   // Remaining unparsed length field data.
282   std::array<char, sizeof(uint64_t)> length_buffer_;
283   // Remaining unparsed type field data.
284   std::array<char, sizeof(uint64_t)> type_buffer_;
285 
286   // Latched value of --quic_enable_http3_metadata_decoding.
287   const bool enable_metadata_decoding_;
288 };
289 
290 }  // namespace quic
291 
292 #endif  // QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
293