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