xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/adapter/http2_visitor_interface.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 #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 
11 namespace http2 {
12 namespace 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).
49 class QUICHE_EXPORT 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     // The peer sent a GOAWAY with an invalid last-stream-ID field.
84     kInvalidGoAwayLastStreamId,
85     // The peer sent an invalid SETTINGS value.
86     kInvalidSetting,
87   };
88   virtual void OnConnectionError(ConnectionError error) = 0;
89 
90   // Called when the header for a frame is received. Returns false if a fatal
91   // error has occurred.
OnFrameHeader(Http2StreamId,size_t,uint8_t,uint8_t)92   virtual bool OnFrameHeader(Http2StreamId /*stream_id*/, size_t /*length*/,
93                              uint8_t /*type*/, uint8_t /*flags*/) {
94     return true;
95   }
96 
97   // Called when a non-ack SETTINGS frame is received.
98   virtual void OnSettingsStart() = 0;
99 
100   // Called for each SETTINGS id-value pair.
101   virtual void OnSetting(Http2Setting setting) = 0;
102 
103   // Called at the end of a non-ack SETTINGS frame.
104   virtual void OnSettingsEnd() = 0;
105 
106   // Called when a SETTINGS ack frame is received.
107   virtual void OnSettingsAck() = 0;
108 
109   // Called when the connection receives the header block for a HEADERS frame on
110   // a stream but has not yet parsed individual headers. Returns false if a
111   // fatal error has occurred.
112   virtual bool OnBeginHeadersForStream(Http2StreamId stream_id) = 0;
113 
114   // Called when the connection receives the header |key| and |value| for a
115   // stream. The HTTP/2 pseudo-headers defined in RFC 7540 Sections 8.1.2.3 and
116   // 8.1.2.4 are also conveyed in this callback. This method is called after
117   // OnBeginHeadersForStream(). May return HEADER_RST_STREAM to indicate the
118   // header block should be rejected. This will cause the library to queue a
119   // RST_STREAM frame, which will have a default error code of INTERNAL_ERROR.
120   // The visitor implementation may choose to queue a RST_STREAM with a
121   // different error code instead, which should be done before returning
122   // HEADER_RST_STREAM. Returning HEADER_CONNECTION_ERROR will lead to a
123   // non-recoverable error on the connection.
124   enum OnHeaderResult {
125     // The header was accepted.
126     HEADER_OK,
127     // The application considers the header a connection error.
128     HEADER_CONNECTION_ERROR,
129     // The application rejects the header and requests the stream be reset.
130     HEADER_RST_STREAM,
131     // The header field is invalid and will be reset with error code
132     // PROTOCOL_ERROR.
133     HEADER_FIELD_INVALID,
134     // The headers are a violation of HTTP messaging semantics and will be reset
135     // with error code PROTOCOL_ERROR.
136     HEADER_HTTP_MESSAGING,
137     // The headers caused a compression context error.
138     HEADER_COMPRESSION_ERROR,
139   };
140   virtual OnHeaderResult OnHeaderForStream(Http2StreamId stream_id,
141                                            absl::string_view key,
142                                            absl::string_view value) = 0;
143 
144   // Called when the connection has received the complete header block for a
145   // logical HEADERS frame on a stream (which may contain CONTINUATION frames,
146   // transparent to the user). Returns false if a fatal error has occurred.
147   virtual bool OnEndHeadersForStream(Http2StreamId stream_id) = 0;
148 
149   // Called when the connection receives the beginning of a DATA frame. The data
150   // payload will be provided via subsequent calls to OnDataForStream(). Returns
151   // false if a fatal error has occurred.
152   virtual bool OnBeginDataForStream(Http2StreamId stream_id,
153                                     size_t payload_length) = 0;
154 
155   // Called when the optional padding length field is parsed as part of a DATA
156   // frame payload. `padding_length` represents the total amount of padding for
157   // this frame, including the length byte itself. Returns false if a fatal
158   // error has occurred.
159   virtual bool OnDataPaddingLength(Http2StreamId stream_id,
160                                    size_t padding_length) = 0;
161 
162   // Called when the connection receives some |data| (as part of a DATA frame
163   // payload) for a stream. Returns false if a fatal error has occurred.
164   virtual bool OnDataForStream(Http2StreamId stream_id,
165                                absl::string_view data) = 0;
166 
167   // Called when the peer sends the END_STREAM flag on a stream, indicating that
168   // the peer will not send additional headers or data for that stream.
169   virtual bool OnEndStream(Http2StreamId stream_id) = 0;
170 
171   // Called when the connection receives a RST_STREAM for a stream. This call
172   // will be followed by either OnCloseStream().
173   virtual void OnRstStream(Http2StreamId stream_id,
174                            Http2ErrorCode error_code) = 0;
175 
176   // Called when a stream is closed. Returns false if a fatal error has
177   // occurred.
178   virtual bool OnCloseStream(Http2StreamId stream_id,
179                              Http2ErrorCode error_code) = 0;
180 
181   // Called when the connection receives a PRIORITY frame.
182   virtual void OnPriorityForStream(Http2StreamId stream_id,
183                                    Http2StreamId parent_stream_id, int weight,
184                                    bool exclusive) = 0;
185 
186   // Called when the connection receives a PING frame.
187   virtual void OnPing(Http2PingId ping_id, bool is_ack) = 0;
188 
189   // Called when the connection receives a PUSH_PROMISE frame. The server push
190   // request headers follow in calls to OnHeaderForStream() with |stream_id|.
191   virtual void OnPushPromiseForStream(Http2StreamId stream_id,
192                                       Http2StreamId promised_stream_id) = 0;
193 
194   // Called when the connection receives a GOAWAY frame. Returns false if a
195   // fatal error has occurred.
196   virtual bool OnGoAway(Http2StreamId last_accepted_stream_id,
197                         Http2ErrorCode error_code,
198                         absl::string_view opaque_data) = 0;
199 
200   // Called when the connection receives a WINDOW_UPDATE frame. For
201   // connection-level window updates, the |stream_id| will be 0.
202   virtual void OnWindowUpdate(Http2StreamId stream_id,
203                               int window_increment) = 0;
204 
205   // Called immediately before a frame of the given type is sent. Should return
206   // 0 on success.
207   virtual int OnBeforeFrameSent(uint8_t frame_type, Http2StreamId stream_id,
208                                 size_t length, uint8_t flags) = 0;
209 
210   // Called immediately after a frame of the given type is sent. Should return 0
211   // on success. |error_code| is only populated for RST_STREAM and GOAWAY frame
212   // types.
213   virtual int OnFrameSent(uint8_t frame_type, Http2StreamId stream_id,
214                           size_t length, uint8_t flags,
215                           uint32_t error_code) = 0;
216 
217   // Called when the connection receives an invalid frame. A return value of
218   // false will result in the connection entering an error state, with no
219   // further frame processing possible.
220   enum class InvalidFrameError {
221     // The frame contains a general protocol error.
222     kProtocol,
223     // The frame would have caused a new (invalid) stream to be opened.
224     kRefusedStream,
225     // The frame contains an invalid header field.
226     kHttpHeader,
227     // The frame contains a violation in HTTP messaging rules.
228     kHttpMessaging,
229     // The frame causes a flow control error.
230     kFlowControl,
231     // The frame is on an already closed stream or has an invalid stream ID.
232     kStreamClosed,
233   };
234   virtual bool OnInvalidFrame(Http2StreamId stream_id,
235                               InvalidFrameError error) = 0;
236 
237   // Called when the connection receives the beginning of a METADATA frame
238   // (which may itself be the middle of a logical metadata block). The metadata
239   // payload will be provided via subsequent calls to OnMetadataForStream().
240   // TODO(birenroy): Consider removing this unnecessary method.
241   virtual void OnBeginMetadataForStream(Http2StreamId stream_id,
242                                         size_t payload_length) = 0;
243 
244   // Called when the connection receives |metadata| as part of a METADATA frame
245   // payload for a stream. Returns false if a fatal error has occurred.
246   virtual bool OnMetadataForStream(Http2StreamId stream_id,
247                                    absl::string_view metadata) = 0;
248 
249   // Called when the connection has finished receiving a logical metadata block
250   // for a stream. Note that there may be multiple metadata blocks for a stream.
251   // Returns false if there was an error unpacking the metadata payload.
252   virtual bool OnMetadataEndForStream(Http2StreamId stream_id) = 0;
253 
254   // Invoked with an error message from the application.
255   virtual void OnErrorDebug(absl::string_view message) = 0;
256 
257  protected:
258   Http2VisitorInterface() = default;
259 };
260 
261 }  // namespace adapter
262 }  // namespace http2
263 
264 #endif  // QUICHE_HTTP2_ADAPTER_HTTP2_VISITOR_INTERFACE_H_
265