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