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