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