blob: 1cc973ab6270e7440a463a4a9277aa3cff951399 [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
8#include <cstddef>
9
10#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"
12#include "net/third_party/quiche/src/quic/core/quic_types.h"
13#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
14#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
15
16namespace quic {
17
18class QuicDataReader;
19
bnc62446bc2019-03-14 06:11:25 -070020// Struct that stores meta data of an HTTP/3 frame.
21// |header_length| is frame header length in bytes.
22// |payload_length| is frame payload length in bytes.
QUICHE teama6ef0a62019-03-07 20:34:33 -050023struct QUIC_EXPORT_PRIVATE Http3FrameLengths {
24 Http3FrameLengths(QuicByteCount header, QuicByteCount payload)
25 : header_length(header), payload_length(payload) {}
26
27 bool operator==(const Http3FrameLengths& other) const {
28 return (header_length == other.header_length) &&
29 (payload_length == other.payload_length);
30 }
31
32 QuicByteCount header_length;
33 QuicByteCount payload_length;
34};
35
36// A class for decoding the HTTP frames that are exchanged in an HTTP over QUIC
37// session.
38class QUIC_EXPORT_PRIVATE HttpDecoder {
39 public:
40 class QUIC_EXPORT_PRIVATE Visitor {
41 public:
42 virtual ~Visitor() {}
43
44 // Called if an error is detected.
45 virtual void OnError(HttpDecoder* decoder) = 0;
46
47 // Called when a PRIORITY frame has been successfully parsed.
48 virtual void OnPriorityFrame(const PriorityFrame& frame) = 0;
49
50 // Called when a CANCEL_PUSH frame has been successfully parsed.
51 virtual void OnCancelPushFrame(const CancelPushFrame& frame) = 0;
52
53 // Called when a MAX_PUSH_ID frame has been successfully parsed.
54 virtual void OnMaxPushIdFrame(const MaxPushIdFrame& frame) = 0;
55
56 // Called when a GOAWAY frame has been successfully parsed.
57 virtual void OnGoAwayFrame(const GoAwayFrame& frame) = 0;
58
59 // Called when a SETTINGS frame has been successfully parsed.
60 virtual void OnSettingsFrame(const SettingsFrame& frame) = 0;
61
62 // Called when a DUPLICATE_PUSH frame has been successfully parsed.
63 virtual void OnDuplicatePushFrame(const DuplicatePushFrame& frame) = 0;
64
bnc62446bc2019-03-14 06:11:25 -070065 // Called when a DATA frame has been received.
66 // |frame_length| contains DATA frame length and payload length.
QUICHE teama6ef0a62019-03-07 20:34:33 -050067 virtual void OnDataFrameStart(Http3FrameLengths frame_length) = 0;
bnc70914262019-03-16 12:49:50 -070068 // Called when part of the payload of a DATA frame has been read. May be
69 // called multiple times for a single frame. |payload| is guaranteed to be
70 // non-empty.
QUICHE teama6ef0a62019-03-07 20:34:33 -050071 virtual void OnDataFramePayload(QuicStringPiece payload) = 0;
72 // Called when a DATA frame has been completely processed.
73 virtual void OnDataFrameEnd() = 0;
74
75 // Called when a HEADERS frame has been recevied.
bnc62446bc2019-03-14 06:11:25 -070076 // |frame_length| contains HEADERS frame length and payload length.
77 virtual void OnHeadersFrameStart(Http3FrameLengths frame_length) = 0;
bnc70914262019-03-16 12:49:50 -070078 // Called when part of the payload of a HEADERS frame has been read. May be
79 // called multiple times for a single frame. |payload| is guaranteed to be
80 // non-empty.
QUICHE teama6ef0a62019-03-07 20:34:33 -050081 virtual void OnHeadersFramePayload(QuicStringPiece payload) = 0;
82 // Called when a HEADERS frame has been completely processed.
83 // |frame_len| is the length of the HEADERS frame payload.
84 virtual void OnHeadersFrameEnd(QuicByteCount frame_len) = 0;
85
86 // Called when a PUSH_PROMISE frame has been recevied for |push_id|.
87 virtual void OnPushPromiseFrameStart(PushId push_id) = 0;
bnc70914262019-03-16 12:49:50 -070088 // Called when part of the payload of a PUSH_PROMISE frame has been read.
89 // May be called multiple times for a single frame. |payload| is guaranteed
90 // to be non-empty.
QUICHE teama6ef0a62019-03-07 20:34:33 -050091 virtual void OnPushPromiseFramePayload(QuicStringPiece payload) = 0;
92 // Called when a PUSH_PROMISE frame has been completely processed.
93 virtual void OnPushPromiseFrameEnd() = 0;
94
95 // TODO(rch): Consider adding methods like:
96 // OnUnknownFrame{Start,Payload,End}()
97 // to allow callers to handle unknown frames.
98 };
99
100 HttpDecoder();
101
102 ~HttpDecoder();
103
104 // Set callbacks to be called from the decoder. A visitor must be set, or
105 // else the decoder will crash. It is acceptable for the visitor to do
106 // nothing. If this is called multiple times, only the last visitor
107 // will be used. |visitor| will be owned by the caller.
108 void set_visitor(Visitor* visitor) { visitor_ = visitor; }
109
110 // Processes the input and invokes the visitor for any frames.
111 // Returns the number of bytes consumed, or 0 if there was an error, in which
112 // case error() should be consulted.
113 QuicByteCount ProcessInput(const char* data, QuicByteCount len);
114
QUICHE teama6ef0a62019-03-07 20:34:33 -0500115 QuicErrorCode error() const { return error_; }
vasilvvc48c8712019-03-11 13:38:16 -0700116 const std::string& error_detail() const { return error_detail_; }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500117
118 private:
119 // Represents the current state of the parsing state machine.
120 enum HttpDecoderState {
121 STATE_READING_FRAME_LENGTH,
122 STATE_READING_FRAME_TYPE,
123 STATE_READING_FRAME_PAYLOAD,
bnc70914262019-03-16 12:49:50 -0700124 STATE_FINISH_PARSING,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500125 STATE_ERROR
126 };
127
128 // Reads the length of a frame from |reader|. Sets error_ and error_detail_
129 // if there are any errors.
130 void ReadFrameLength(QuicDataReader* reader);
131
132 // Reads the type of a frame from |reader|. Sets error_ and error_detail_
bnc70914262019-03-16 12:49:50 -0700133 // if there are any errors. Also calls OnDataFrameStart() or
134 // OnHeadersFrameStart() for appropriate frame types.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500135 void ReadFrameType(QuicDataReader* reader);
136
137 // Reads the payload of the current frame from |reader| and processes it,
138 // possibly buffering the data or invoking the visitor.
139 void ReadFramePayload(QuicDataReader* reader);
140
bnc70914262019-03-16 12:49:50 -0700141 // Optionally parses buffered data; calls visitor method to signal that frame
142 // had been parsed completely.
143 void FinishParsing();
144
QUICHE teama6ef0a62019-03-07 20:34:33 -0500145 // Discards any remaining frame payload from |reader|.
146 void DiscardFramePayload(QuicDataReader* reader);
147
148 // Buffers any remaining frame payload from |reader| into |buffer_|.
149 void BufferFramePayload(QuicDataReader* reader);
150
151 // Buffers any remaining frame length field from |reader| into
152 // |length_buffer_|
153 void BufferFrameLength(QuicDataReader* reader);
154
155 // Sets |error_| and |error_detail_| accordingly.
vasilvvc48c8712019-03-11 13:38:16 -0700156 void RaiseError(QuicErrorCode error, std::string error_detail);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500157
158 // Parses the payload of a PRIORITY frame from |reader| into |frame|.
159 bool ParsePriorityFrame(QuicDataReader* reader, PriorityFrame* frame);
160
161 // Parses the payload of a SETTINGS frame from |reader| into |frame|.
162 bool ParseSettingsFrame(QuicDataReader* reader, SettingsFrame* frame);
163
164 // Visitor to invoke when messages are parsed.
165 Visitor* visitor_; // Unowned.
166 // Current state of the parsing.
167 HttpDecoderState state_;
168 // Type of the frame currently being parsed.
169 uint8_t current_frame_type_;
170 // Size of the frame's length field.
171 QuicByteCount current_length_field_size_;
172 // Remaining length that's needed for the frame's length field.
173 QuicByteCount remaining_length_field_length_;
174 // Length of the payload of the frame currently being parsed.
175 QuicByteCount current_frame_length_;
176 // Remaining payload bytes to be parsed.
177 QuicByteCount remaining_frame_length_;
178 // Last error.
179 QuicErrorCode error_;
180 // The issue which caused |error_|
vasilvvc48c8712019-03-11 13:38:16 -0700181 std::string error_detail_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500182 // Remaining unparsed data.
vasilvvc48c8712019-03-11 13:38:16 -0700183 std::string buffer_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500184 // Remaining unparsed length field data.
vasilvvc48c8712019-03-11 13:38:16 -0700185 std::string length_buffer_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500186};
187
188} // namespace quic
189
190#endif // QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_