• 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 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 frame of unknown type |frame_type| has been received.
101     // Frame type might be reserved, Visitor must make sure to ignore.
102     // |header_length| and |payload_length| are the length of the frame header
103     // and payload, respectively.
104     virtual bool OnUnknownFrameStart(uint64_t frame_type,
105                                      QuicByteCount header_length,
106                                      QuicByteCount payload_length) = 0;
107     // Called when part of the payload of the unknown frame has been read.  May
108     // be called multiple times for a single frame.  |payload| is guaranteed to
109     // be non-empty.
110     virtual bool OnUnknownFramePayload(absl::string_view payload) = 0;
111     // Called when the unknown frame has been completely processed.
112     virtual bool OnUnknownFrameEnd() = 0;
113   };
114 
115   // |visitor| must be non-null, and must outlive HttpDecoder.
116   explicit HttpDecoder(Visitor* visitor);
117 
118   ~HttpDecoder();
119 
120   // Processes the input and invokes the appropriate visitor methods, until a
121   // visitor method returns false or an error occurs.  Returns the number of
122   // bytes processed.  Does not process any input if called after an error.
123   // Paused processing can be resumed by calling ProcessInput() again with the
124   // unprocessed portion of data.  Must not be called after an error has
125   // occurred.
126   QuicByteCount ProcessInput(const char* data, QuicByteCount len);
127 
128   // Decode settings frame from |data|.
129   // Upon successful decoding, |frame| will be populated, and returns true.
130   // This method is not used for regular processing of incoming data.
131   static bool DecodeSettings(const char* data, QuicByteCount len,
132                              SettingsFrame* frame);
133 
134   // Returns an error code other than QUIC_NO_ERROR if and only if
135   // Visitor::OnError() has been called.
error()136   QuicErrorCode error() const { return error_; }
137 
error_detail()138   const std::string& error_detail() const { return error_detail_; }
139 
140   // Returns true if input data processed so far ends on a frame boundary.
AtFrameBoundary()141   bool AtFrameBoundary() const { return state_ == STATE_READING_FRAME_TYPE; }
142 
143   // Indicates that WEBTRANSPORT_STREAM should be parsed.
EnableWebTransportStreamParsing()144   void EnableWebTransportStreamParsing() { allow_web_transport_stream_ = true; }
145 
146   std::string DebugString() const;
147 
148  private:
149   friend test::HttpDecoderPeer;
150 
151   // Represents the current state of the parsing state machine.
152   enum HttpDecoderState {
153     STATE_READING_FRAME_LENGTH,
154     STATE_READING_FRAME_TYPE,
155 
156     // States used for buffered frame types
157     STATE_BUFFER_OR_PARSE_PAYLOAD,
158 
159     // States used for non-buffered frame types
160     STATE_READING_FRAME_PAYLOAD,
161     STATE_FINISH_PARSING,
162 
163     STATE_PARSING_NO_LONGER_POSSIBLE,
164     STATE_ERROR
165   };
166 
167   // Reads the type of a frame from |reader|. Sets error_ and error_detail_
168   // if there are any errors.  Also calls OnDataFrameStart() or
169   // OnHeadersFrameStart() for appropriate frame types. Returns whether the
170   // processing should continue.
171   bool ReadFrameType(QuicDataReader* reader);
172 
173   // Reads the length of a frame from |reader|. Sets error_ and error_detail_
174   // if there are any errors.  Returns whether processing should continue.
175   bool ReadFrameLength(QuicDataReader* reader);
176 
177   // Returns whether the current frame is of a buffered type.
178   // The payload of buffered frames is buffered by HttpDecoder, and parsed by
179   // HttpDecoder after the entire frame has been received.  (Copying to the
180   // buffer is skipped if the ProcessInput() call covers the entire payload.)
181   // Frames that are not buffered have every payload fragment synchronously
182   // passed to the Visitor without buffering.
183   bool IsFrameBuffered();
184 
185   // For buffered frame types, calls BufferOrParsePayload().  For other frame
186   // types, reads the payload of the current frame from |reader| and calls
187   // visitor methods.  Returns whether processing should continue.
188   bool ReadFramePayload(QuicDataReader* reader);
189 
190   // For buffered frame types, this method is only called if frame payload is
191   // empty, and it calls BufferOrParsePayload().  For other frame types, this
192   // method directly calls visitor methods to signal that frame had been
193   // received completely.  Returns whether processing should continue.
194   bool FinishParsing();
195 
196   // Reset internal fields to prepare for reading next frame.
197   void ResetForNextFrame();
198 
199   // Read payload of unknown frame from |reader| and call
200   // Visitor::OnUnknownFramePayload().  Returns true decoding should continue,
201   // false if it should be paused.
202   bool HandleUnknownFramePayload(QuicDataReader* reader);
203 
204   // Buffers any remaining frame payload from |*reader| into |buffer_| if
205   // necessary.  Parses the frame payload if complete.  Parses out of |*reader|
206   // without unnecessary copy if |*reader| contains entire payload.
207   // Returns whether processing should continue.
208   // Must only be called when current frame type is buffered.
209   bool BufferOrParsePayload(QuicDataReader* reader);
210 
211   // Parses the entire payload of certain kinds of frames that are parsed in a
212   // single pass.  |reader| must have at least |current_frame_length_| bytes.
213   // Returns whether processing should continue.
214   // Must only be called when current frame type is buffered.
215   bool ParseEntirePayload(QuicDataReader* reader);
216 
217   // Buffers any remaining frame length field from |reader| into
218   // |length_buffer_|.
219   void BufferFrameLength(QuicDataReader* reader);
220 
221   // Buffers any remaining frame type field from |reader| into |type_buffer_|.
222   void BufferFrameType(QuicDataReader* reader);
223 
224   // Sets |error_| and |error_detail_| accordingly.
225   void RaiseError(QuicErrorCode error, std::string error_detail);
226 
227   // Parses the payload of a SETTINGS frame from |reader| into |frame|.
228   bool ParseSettingsFrame(QuicDataReader* reader, SettingsFrame* frame);
229 
230   // Parses the payload of a PRIORITY_UPDATE frame (draft-02, type 0xf0700)
231   // from |reader| into |frame|.
232   bool ParsePriorityUpdateFrame(QuicDataReader* reader,
233                                 PriorityUpdateFrame* frame);
234 
235   // Parses the payload of an ACCEPT_CH frame from |reader| into |frame|.
236   bool ParseAcceptChFrame(QuicDataReader* reader, AcceptChFrame* frame);
237 
238   // Returns the max frame size of a given |frame_type|.
239   QuicByteCount MaxFrameLength(uint64_t frame_type);
240 
241   // Visitor to invoke when messages are parsed.
242   Visitor* const visitor_;  // Unowned.
243   // Whether WEBTRANSPORT_STREAM should be parsed.
244   bool allow_web_transport_stream_;
245   // Current state of the parsing.
246   HttpDecoderState state_;
247   // Type of the frame currently being parsed.
248   uint64_t current_frame_type_;
249   // Size of the frame's length field.
250   QuicByteCount current_length_field_length_;
251   // Remaining length that's needed for the frame's length field.
252   QuicByteCount remaining_length_field_length_;
253   // Length of the payload of the frame currently being parsed.
254   QuicByteCount current_frame_length_;
255   // Remaining payload bytes to be parsed.
256   QuicByteCount remaining_frame_length_;
257   // Length of the frame's type field.
258   QuicByteCount current_type_field_length_;
259   // Remaining length that's needed for the frame's type field.
260   QuicByteCount remaining_type_field_length_;
261   // Last error.
262   QuicErrorCode error_;
263   // The issue which caused |error_|
264   std::string error_detail_;
265   // Remaining unparsed data.
266   std::string buffer_;
267   // Remaining unparsed length field data.
268   std::array<char, sizeof(uint64_t)> length_buffer_;
269   // Remaining unparsed type field data.
270   std::array<char, sizeof(uint64_t)> type_buffer_;
271 };
272 
273 }  // namespace quic
274 
275 #endif  // QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
276