blob: 012d91a53801b61c51288e6ffc2c1df5b302eb7d [file] [log] [blame]
Bence Békybac04052022-04-07 15:44:29 -04001#ifndef QUICHE_HTTP2_ADAPTER_HTTP2_VISITOR_INTERFACE_H_
2#define QUICHE_HTTP2_ADAPTER_HTTP2_VISITOR_INTERFACE_H_
3
4#include <cstdint>
5#include <vector>
6
7#include "absl/strings/string_view.h"
8#include "quiche/http2/adapter/http2_protocol.h"
9#include "quiche/common/platform/api/quiche_export.h"
10
11namespace http2 {
12namespace adapter {
13
14// Http2VisitorInterface contains callbacks for receiving HTTP/2-level events. A
15// processor like NghttpAdapter parses HTTP/2 frames and invokes the callbacks
16// on an instance of this interface. Prefer a void return type for these
17// callbacks, instead setting output parameters as needed.
18//
19// Example sequences of calls/events:
20// GET:
21// - OnBeginHeadersForStream()
22// - OnHeaderForStream()
23// - OnEndHeadersForStream()
24// - OnEndStream()
25//
26// POST:
27// - OnBeginHeadersForStream()
28// - OnHeaderForStream()
29// - OnEndHeadersForStream()
30// - OnBeginDataForStream()
31// - OnDataForStream()
32// - OnEndStream()
33//
34// Request canceled mid-stream, e.g, with error code CANCEL:
35// - OnBeginHeadersForStream()
36// - OnHeaderForStream()
37// - OnEndHeadersForStream()
38// - OnRstStream()
39// - OnCloseStream()
40//
41// Request closed mid-stream, e.g., with error code NO_ERROR:
42// - OnBeginHeadersForStream()
43// - OnHeaderForStream()
44// - OnEndHeadersForStream()
45// - OnRstStream()
46// - OnCloseStream()
47//
48// More details are at RFC 7540 (go/http2spec).
49class QUICHE_EXPORT_PRIVATE Http2VisitorInterface {
50 public:
51 Http2VisitorInterface(const Http2VisitorInterface&) = delete;
52 Http2VisitorInterface& operator=(const Http2VisitorInterface&) = delete;
53 virtual ~Http2VisitorInterface() = default;
54
55 enum : int64_t {
56 kSendBlocked = 0,
57 kSendError = -1,
58 };
59 // Called when there are serialized frames to send. Should return how many
60 // bytes were actually sent. May return kSendBlocked or kSendError.
61 virtual int64_t OnReadyToSend(absl::string_view serialized) = 0;
62
63 // Called when a connection-level error has occurred.
64 enum class ConnectionError {
65 // The peer sent an invalid connection preface.
66 kInvalidConnectionPreface,
67 // The visitor encountered an error sending bytes to the peer.
68 kSendError,
69 // There was an error reading and framing bytes from the peer.
70 kParseError,
71 // The visitor considered a received header to be a connection error.
72 kHeaderError,
73 // The peer attempted to open a stream with an invalid stream ID.
74 kInvalidNewStreamId,
75 // The peer sent a frame that is invalid on an idle stream (before HEADERS).
76 kWrongFrameSequence,
77 // The peer sent an invalid PUSH_PROMISE frame.
78 kInvalidPushPromise,
79 // The peer exceeded the max concurrent streams limit.
80 kExceededMaxConcurrentStreams,
81 // The peer caused a flow control error.
82 kFlowControlError,
83 };
84 virtual void OnConnectionError(ConnectionError error) = 0;
85
86 // Called when the header for a frame is received. Returns false if a fatal
87 // error has occurred.
88 virtual bool OnFrameHeader(Http2StreamId /*stream_id*/, size_t /*length*/,
89 uint8_t /*type*/, uint8_t /*flags*/) {
90 return true;
91 }
92
93 // Called when a non-ack SETTINGS frame is received.
94 virtual void OnSettingsStart() = 0;
95
96 // Called for each SETTINGS id-value pair.
97 virtual void OnSetting(Http2Setting setting) = 0;
98
99 // Called at the end of a non-ack SETTINGS frame.
100 virtual void OnSettingsEnd() = 0;
101
102 // Called when a SETTINGS ack frame is received.
103 virtual void OnSettingsAck() = 0;
104
105 // Called when the connection receives the header block for a HEADERS frame on
106 // a stream but has not yet parsed individual headers. Returns false if a
107 // fatal error has occurred.
108 virtual bool OnBeginHeadersForStream(Http2StreamId stream_id) = 0;
109
110 // Called when the connection receives the header |key| and |value| for a
111 // stream. The HTTP/2 pseudo-headers defined in RFC 7540 Sections 8.1.2.3 and
112 // 8.1.2.4 are also conveyed in this callback. This method is called after
113 // OnBeginHeadersForStream(). May return HEADER_RST_STREAM to indicate the
114 // header block should be rejected. This will cause the library to queue a
115 // RST_STREAM frame, which will have a default error code of INTERNAL_ERROR.
116 // The visitor implementation may choose to queue a RST_STREAM with a
117 // different error code instead, which should be done before returning
118 // HEADER_RST_STREAM. Returning HEADER_CONNECTION_ERROR will lead to a
119 // non-recoverable error on the connection.
120 enum OnHeaderResult {
121 // The header was accepted.
122 HEADER_OK,
123 // The application considers the header a connection error.
124 HEADER_CONNECTION_ERROR,
125 // The application rejects the header and requests the stream be reset.
126 HEADER_RST_STREAM,
127 // The header field is invalid and will be reset with error code
128 // PROTOCOL_ERROR.
129 HEADER_FIELD_INVALID,
130 // The headers are a violation of HTTP messaging semantics and will be reset
131 // with error code PROTOCOL_ERROR.
132 HEADER_HTTP_MESSAGING,
133 // The headers caused a compression context error.
134 HEADER_COMPRESSION_ERROR,
135 };
136 virtual OnHeaderResult OnHeaderForStream(Http2StreamId stream_id,
137 absl::string_view key,
138 absl::string_view value) = 0;
139
140 // Called when the connection has received the complete header block for a
141 // logical HEADERS frame on a stream (which may contain CONTINUATION frames,
142 // transparent to the user). Returns false if a fatal error has occurred.
143 virtual bool OnEndHeadersForStream(Http2StreamId stream_id) = 0;
144
145 // Called when the connection receives the beginning of a DATA frame. The data
146 // payload will be provided via subsequent calls to OnDataForStream(). Returns
147 // false if a fatal error has occurred.
148 virtual bool OnBeginDataForStream(Http2StreamId stream_id,
149 size_t payload_length) = 0;
150
151 // Called when the optional padding length field is parsed as part of a DATA
152 // frame payload. `padding_length` represents the total amount of padding for
153 // this frame, including the length byte itself. Returns false if a fatal
154 // error has occurred.
155 virtual bool OnDataPaddingLength(Http2StreamId stream_id,
156 size_t padding_length) = 0;
157
158 // Called when the connection receives some |data| (as part of a DATA frame
159 // payload) for a stream. Returns false if a fatal error has occurred.
160 virtual bool OnDataForStream(Http2StreamId stream_id,
161 absl::string_view data) = 0;
162
163 // Called when the peer sends the END_STREAM flag on a stream, indicating that
164 // the peer will not send additional headers or data for that stream.
165 virtual void OnEndStream(Http2StreamId stream_id) = 0;
166
167 // Called when the connection receives a RST_STREAM for a stream. This call
168 // will be followed by either OnCloseStream().
169 virtual void OnRstStream(Http2StreamId stream_id,
170 Http2ErrorCode error_code) = 0;
171
172 // Called when a stream is closed. Returns false if a fatal error has
173 // occurred.
174 virtual bool OnCloseStream(Http2StreamId stream_id,
175 Http2ErrorCode error_code) = 0;
176
177 // Called when the connection receives a PRIORITY frame.
178 virtual void OnPriorityForStream(Http2StreamId stream_id,
179 Http2StreamId parent_stream_id, int weight,
180 bool exclusive) = 0;
181
182 // Called when the connection receives a PING frame.
183 virtual void OnPing(Http2PingId ping_id, bool is_ack) = 0;
184
185 // Called when the connection receives a PUSH_PROMISE frame. The server push
186 // request headers follow in calls to OnHeaderForStream() with |stream_id|.
187 virtual void OnPushPromiseForStream(Http2StreamId stream_id,
188 Http2StreamId promised_stream_id) = 0;
189
190 // Called when the connection receives a GOAWAY frame. Returns false if a
191 // fatal error has occurred.
192 virtual bool OnGoAway(Http2StreamId last_accepted_stream_id,
193 Http2ErrorCode error_code,
194 absl::string_view opaque_data) = 0;
195
196 // Called when the connection receives a WINDOW_UPDATE frame. For
197 // connection-level window updates, the |stream_id| will be 0.
198 virtual void OnWindowUpdate(Http2StreamId stream_id,
199 int window_increment) = 0;
200
201 // Called immediately before a frame of the given type is sent. Should return
202 // 0 on success.
203 virtual int OnBeforeFrameSent(uint8_t frame_type, Http2StreamId stream_id,
204 size_t length, uint8_t flags) = 0;
205
206 // Called immediately after a frame of the given type is sent. Should return 0
207 // on success. |error_code| is only populated for RST_STREAM and GOAWAY frame
208 // types.
209 virtual int OnFrameSent(uint8_t frame_type, Http2StreamId stream_id,
210 size_t length, uint8_t flags,
211 uint32_t error_code) = 0;
212
213 // Called when the connection receives an invalid frame. A return value of
214 // false will result in the connection entering an error state, with no
215 // further frame processing possible.
216 enum class InvalidFrameError {
217 // The frame contains a general protocol error.
218 kProtocol,
219 // The frame would have caused a new (invalid) stream to be opened.
220 kRefusedStream,
221 // The frame contains an invalid header field.
222 kHttpHeader,
223 // The frame contains a violation in HTTP messaging rules.
224 kHttpMessaging,
225 // The frame causes a flow control error.
226 kFlowControl,
227 // The frame is on an already closed stream or has an invalid stream ID.
228 kStreamClosed,
229 };
230 virtual bool OnInvalidFrame(Http2StreamId stream_id,
231 InvalidFrameError error) = 0;
232
233 // Called when the connection receives the beginning of a METADATA frame
234 // (which may itself be the middle of a logical metadata block). The metadata
235 // payload will be provided via subsequent calls to OnMetadataForStream().
236 // TODO(birenroy): Consider removing this unnecessary method.
237 virtual void OnBeginMetadataForStream(Http2StreamId stream_id,
238 size_t payload_length) = 0;
239
240 // Called when the connection receives |metadata| as part of a METADATA frame
241 // payload for a stream. Returns false if a fatal error has occurred.
242 virtual bool OnMetadataForStream(Http2StreamId stream_id,
243 absl::string_view metadata) = 0;
244
245 // Called when the connection has finished receiving a logical metadata block
246 // for a stream. Note that there may be multiple metadata blocks for a stream.
247 // Returns false if there was an error unpacking the metadata payload.
248 virtual bool OnMetadataEndForStream(Http2StreamId stream_id) = 0;
249
250 // Invoked with an error message from the application.
251 virtual void OnErrorDebug(absl::string_view message) = 0;
252
253 protected:
254 Http2VisitorInterface() = default;
255};
256
257} // namespace adapter
258} // namespace http2
259
260#endif // QUICHE_HTTP2_ADAPTER_HTTP2_VISITOR_INTERFACE_H_