blob: 426a86ebb901eca5a90b9ed1e945e04ed41f82e9 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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
renjietang857362b2019-08-09 09:52:35 -07008#include <cstdint>
9
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include "net/third_party/quiche/src/quic/core/http/http_frames.h"
11#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
renjietang857362b2019-08-09 09:52:35 -070012#include "net/third_party/quiche/src/quic/core/quic_types.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050013#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
dmcardleba2fb7e2019-12-13 07:44:34 -080014#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050015
16namespace quic {
17
bnc62c32b42019-06-24 16:06:41 -070018namespace test {
19
20class HttpDecoderPeer;
21
22} // namespace test
23
QUICHE teama6ef0a62019-03-07 20:34:33 -050024class QuicDataReader;
25
QUICHE teama6ef0a62019-03-07 20:34:33 -050026// A class for decoding the HTTP frames that are exchanged in an HTTP over QUIC
27// session.
28class QUIC_EXPORT_PRIVATE HttpDecoder {
29 public:
30 class QUIC_EXPORT_PRIVATE Visitor {
31 public:
32 virtual ~Visitor() {}
33
34 // Called if an error is detected.
35 virtual void OnError(HttpDecoder* decoder) = 0;
36
bncb9d07d92019-06-25 17:43:49 -070037 // All the following methods return true to continue decoding,
38 // and false to pause it.
bnce5f9c032019-07-25 11:30:40 -070039 // On*FrameStart() methods are called after the frame header is completely
bncf0db6542019-09-23 11:18:28 -070040 // processed. At that point it is safe to consume |header_length| bytes.
bncb9d07d92019-06-25 17:43:49 -070041
QUICHE teama6ef0a62019-03-07 20:34:33 -050042 // Called when a CANCEL_PUSH frame has been successfully parsed.
renjietang546a6282019-06-03 10:21:21 -070043 virtual bool OnCancelPushFrame(const CancelPushFrame& frame) = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050044
45 // Called when a MAX_PUSH_ID frame has been successfully parsed.
renjietang546a6282019-06-03 10:21:21 -070046 virtual bool OnMaxPushIdFrame(const MaxPushIdFrame& frame) = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050047
48 // Called when a GOAWAY frame has been successfully parsed.
renjietang546a6282019-06-03 10:21:21 -070049 virtual bool OnGoAwayFrame(const GoAwayFrame& frame) = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050050
renjietangf41bf642019-04-02 11:45:34 -070051 // Called when a SETTINGS frame has been received.
bnca2b13be2019-07-31 12:04:20 -070052 virtual bool OnSettingsFrameStart(QuicByteCount header_length) = 0;
renjietangf41bf642019-04-02 11:45:34 -070053
QUICHE teama6ef0a62019-03-07 20:34:33 -050054 // Called when a SETTINGS frame has been successfully parsed.
renjietang546a6282019-06-03 10:21:21 -070055 virtual bool OnSettingsFrame(const SettingsFrame& frame) = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050056
57 // Called when a DUPLICATE_PUSH frame has been successfully parsed.
renjietang546a6282019-06-03 10:21:21 -070058 virtual bool OnDuplicatePushFrame(const DuplicatePushFrame& frame) = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050059
bnc62446bc2019-03-14 06:11:25 -070060 // Called when a DATA frame has been received.
bncf0db6542019-09-23 11:18:28 -070061 // |header_length| contains DATA frame length and payload length.
bnca2b13be2019-07-31 12:04:20 -070062 virtual bool OnDataFrameStart(QuicByteCount header_length) = 0;
bnc70914262019-03-16 12:49:50 -070063 // Called when part of the payload of a DATA frame has been read. May be
64 // called multiple times for a single frame. |payload| is guaranteed to be
65 // non-empty.
dmcardleba2fb7e2019-12-13 07:44:34 -080066 virtual bool OnDataFramePayload(quiche::QuicheStringPiece payload) = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050067 // Called when a DATA frame has been completely processed.
renjietang546a6282019-06-03 10:21:21 -070068 virtual bool OnDataFrameEnd() = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050069
bnce433f532019-04-16 13:05:27 -070070 // Called when a HEADERS frame has been received.
bncf0db6542019-09-23 11:18:28 -070071 // |header_length| contains HEADERS frame length and payload length.
bnca2b13be2019-07-31 12:04:20 -070072 virtual bool OnHeadersFrameStart(QuicByteCount header_length) = 0;
bnc70914262019-03-16 12:49:50 -070073 // Called when part of the payload of a HEADERS frame has been read. May be
74 // called multiple times for a single frame. |payload| is guaranteed to be
75 // non-empty.
dmcardleba2fb7e2019-12-13 07:44:34 -080076 virtual bool OnHeadersFramePayload(quiche::QuicheStringPiece payload) = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050077 // Called when a HEADERS frame has been completely processed.
78 // |frame_len| is the length of the HEADERS frame payload.
renjietang546a6282019-06-03 10:21:21 -070079 virtual bool OnHeadersFrameEnd() = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050080
bncf0db6542019-09-23 11:18:28 -070081 // Called when a PUSH_PROMISE frame has been received.
82 virtual bool OnPushPromiseFrameStart(QuicByteCount header_length) = 0;
83 // Called when the Push ID field of a PUSH_PROMISE frame has been parsed.
84 // Called exactly once for a valid PUSH_PROMISE frame.
85 virtual bool OnPushPromiseFramePushId(PushId push_id,
86 QuicByteCount push_id_length) = 0;
87 // Called when part of the header block of a PUSH_PROMISE frame has been
88 // read. May be called multiple times for a single frame. |payload| is
89 // guaranteed to be non-empty.
dmcardleba2fb7e2019-12-13 07:44:34 -080090 virtual bool OnPushPromiseFramePayload(
91 quiche::QuicheStringPiece payload) = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050092 // Called when a PUSH_PROMISE frame has been completely processed.
renjietang546a6282019-06-03 10:21:21 -070093 virtual bool OnPushPromiseFrameEnd() = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050094
bnc51e89622020-01-10 10:40:32 -080095 // Called when a PRIORITY_UPDATE frame has been received.
96 // |header_length| contains PRIORITY_UPDATE frame length and payload length.
97 virtual bool OnPriorityUpdateFrameStart(QuicByteCount header_length) = 0;
98
99 // Called when a PRIORITY_UPDATE frame has been successfully parsed.
100 virtual bool OnPriorityUpdateFrame(const PriorityUpdateFrame& frame) = 0;
101
bncbf3dbe52019-07-17 05:17:41 -0700102 // Called when a frame of unknown type |frame_type| has been received.
103 // Frame type might be reserved, Visitor must make sure to ignore.
bncf0db6542019-09-23 11:18:28 -0700104 // |header_length| contains frame length and payload length.
bncbf3dbe52019-07-17 05:17:41 -0700105 virtual bool OnUnknownFrameStart(uint64_t frame_type,
bnca2b13be2019-07-31 12:04:20 -0700106 QuicByteCount header_length) = 0;
bncbf3dbe52019-07-17 05:17:41 -0700107 // 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.
dmcardleba2fb7e2019-12-13 07:44:34 -0800110 virtual bool OnUnknownFramePayload(quiche::QuicheStringPiece payload) = 0;
bncbf3dbe52019-07-17 05:17:41 -0700111 // Called when the unknown frame has been completely processed.
112 virtual bool OnUnknownFrameEnd() = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500113 };
114
bnca9bb4692019-07-09 17:29:48 -0700115 // |visitor| must be non-null, and must outlive HttpDecoder.
116 explicit HttpDecoder(Visitor* visitor);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500117
118 ~HttpDecoder();
119
bncb9d07d92019-06-25 17:43:49 -0700120 // 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
bnc620095a2019-06-26 05:31:05 -0700124 // unprocessed portion of data. Must not be called after an error has
125 // occurred.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500126 QuicByteCount ProcessInput(const char* data, QuicByteCount len);
127
bnc620095a2019-06-26 05:31:05 -0700128 // Returns an error code other than QUIC_NO_ERROR if and only if
129 // Visitor::OnError() has been called.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500130 QuicErrorCode error() const { return error_; }
bnc620095a2019-06-26 05:31:05 -0700131
vasilvvc48c8712019-03-11 13:38:16 -0700132 const std::string& error_detail() const { return error_detail_; }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500133
134 private:
bnc62c32b42019-06-24 16:06:41 -0700135 friend test::HttpDecoderPeer;
136
QUICHE teama6ef0a62019-03-07 20:34:33 -0500137 // Represents the current state of the parsing state machine.
138 enum HttpDecoderState {
139 STATE_READING_FRAME_LENGTH,
140 STATE_READING_FRAME_TYPE,
141 STATE_READING_FRAME_PAYLOAD,
bnc70914262019-03-16 12:49:50 -0700142 STATE_FINISH_PARSING,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500143 STATE_ERROR
144 };
145
QUICHE teama6ef0a62019-03-07 20:34:33 -0500146 // Reads the type of a frame from |reader|. Sets error_ and error_detail_
bnc70914262019-03-16 12:49:50 -0700147 // if there are any errors. Also calls OnDataFrameStart() or
148 // OnHeadersFrameStart() for appropriate frame types.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500149 void ReadFrameType(QuicDataReader* reader);
150
renjietangfcd91c02019-04-22 10:40:35 -0700151 // Reads the length of a frame from |reader|. Sets error_ and error_detail_
bncb9d07d92019-06-25 17:43:49 -0700152 // if there are any errors. Returns whether processing should continue.
153 bool ReadFrameLength(QuicDataReader* reader);
renjietangfcd91c02019-04-22 10:40:35 -0700154
QUICHE teama6ef0a62019-03-07 20:34:33 -0500155 // Reads the payload of the current frame from |reader| and processes it,
bncb9d07d92019-06-25 17:43:49 -0700156 // possibly buffering the data or invoking the visitor. Returns whether
157 // processing should continue.
158 bool ReadFramePayload(QuicDataReader* reader);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500159
bnc70914262019-03-16 12:49:50 -0700160 // Optionally parses buffered data; calls visitor method to signal that frame
bncb9d07d92019-06-25 17:43:49 -0700161 // had been parsed completely. Returns whether processing should continue.
162 bool FinishParsing();
bnc70914262019-03-16 12:49:50 -0700163
QUICHE teama6ef0a62019-03-07 20:34:33 -0500164 // Discards any remaining frame payload from |reader|.
165 void DiscardFramePayload(QuicDataReader* reader);
166
167 // Buffers any remaining frame payload from |reader| into |buffer_|.
168 void BufferFramePayload(QuicDataReader* reader);
169
170 // Buffers any remaining frame length field from |reader| into
renjietang2d475cf2019-04-18 17:03:37 -0700171 // |length_buffer_|.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500172 void BufferFrameLength(QuicDataReader* reader);
173
renjietang2d475cf2019-04-18 17:03:37 -0700174 // Buffers any remaining frame type field from |reader| into |type_buffer_|.
175 void BufferFrameType(QuicDataReader* reader);
176
renjietang857362b2019-08-09 09:52:35 -0700177 // Buffers at most |remaining_push_id_length_| from |reader| to
178 // |push_id_buffer_|.
179 void BufferPushId(QuicDataReader* reader);
180
QUICHE teama6ef0a62019-03-07 20:34:33 -0500181 // Sets |error_| and |error_detail_| accordingly.
vasilvvc48c8712019-03-11 13:38:16 -0700182 void RaiseError(QuicErrorCode error, std::string error_detail);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500183
QUICHE teama6ef0a62019-03-07 20:34:33 -0500184 // Parses the payload of a SETTINGS frame from |reader| into |frame|.
185 bool ParseSettingsFrame(QuicDataReader* reader, SettingsFrame* frame);
186
bnc51e89622020-01-10 10:40:32 -0800187 // Parses the payload of a PRIORITY_UPDATE frame from |reader| into |frame|.
188 bool ParsePriorityUpdateFrame(QuicDataReader* reader,
189 PriorityUpdateFrame* frame);
190
renjietang4ab9d9f2019-04-10 14:30:26 -0700191 // Returns the max frame size of a given |frame_type|.
bnc95fb6b62019-07-21 11:20:47 -0700192 QuicByteCount MaxFrameLength(uint64_t frame_type);
renjietang4ab9d9f2019-04-10 14:30:26 -0700193
QUICHE teama6ef0a62019-03-07 20:34:33 -0500194 // Visitor to invoke when messages are parsed.
bnca9bb4692019-07-09 17:29:48 -0700195 Visitor* const visitor_; // Unowned.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500196 // Current state of the parsing.
197 HttpDecoderState state_;
198 // Type of the frame currently being parsed.
renjietang2d475cf2019-04-18 17:03:37 -0700199 uint64_t current_frame_type_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500200 // Size of the frame's length field.
renjietangbb98cbc2019-04-23 13:13:56 -0700201 QuicByteCount current_length_field_length_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500202 // Remaining length that's needed for the frame's length field.
203 QuicByteCount remaining_length_field_length_;
204 // Length of the payload of the frame currently being parsed.
205 QuicByteCount current_frame_length_;
206 // Remaining payload bytes to be parsed.
207 QuicByteCount remaining_frame_length_;
renjietang2d475cf2019-04-18 17:03:37 -0700208 // Length of the frame's type field.
209 QuicByteCount current_type_field_length_;
210 // Remaining length that's needed for the frame's type field.
211 QuicByteCount remaining_type_field_length_;
renjietang857362b2019-08-09 09:52:35 -0700212 // Length of PUSH_PROMISE frame's push id.
213 QuicByteCount current_push_id_length_;
214 // Remaining length that's needed for PUSH_PROMISE frame's push id field.
215 QuicByteCount remaining_push_id_length_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500216 // Last error.
217 QuicErrorCode error_;
218 // The issue which caused |error_|
vasilvvc48c8712019-03-11 13:38:16 -0700219 std::string error_detail_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500220 // Remaining unparsed data.
vasilvvc48c8712019-03-11 13:38:16 -0700221 std::string buffer_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500222 // Remaining unparsed length field data.
renjietangbb98cbc2019-04-23 13:13:56 -0700223 std::array<char, sizeof(uint64_t)> length_buffer_;
renjietang2d475cf2019-04-18 17:03:37 -0700224 // Remaining unparsed type field data.
225 std::array<char, sizeof(uint64_t)> type_buffer_;
renjietang857362b2019-08-09 09:52:35 -0700226 // Remaining unparsed push id data.
227 std::array<char, sizeof(uint64_t)> push_id_buffer_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500228};
229
230} // namespace quic
231
232#endif // QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_