1 #ifndef QUICHE_HTTP2_ADAPTER_CALLBACK_VISITOR_H_ 2 #define QUICHE_HTTP2_ADAPTER_CALLBACK_VISITOR_H_ 3 4 #include <cstdint> 5 #include <memory> 6 #include <utility> 7 #include <vector> 8 9 #include "absl/container/flat_hash_map.h" 10 #include "quiche/http2/adapter/http2_visitor_interface.h" 11 #include "quiche/http2/adapter/nghttp2.h" 12 #include "quiche/http2/adapter/nghttp2_util.h" 13 #include "quiche/common/platform/api/quiche_export.h" 14 #include "quiche/common/quiche_callbacks.h" 15 16 namespace http2 { 17 namespace adapter { 18 19 // This visitor implementation accepts a set of nghttp2 callbacks and a "user 20 // data" pointer, and invokes the callbacks according to HTTP/2 events received. 21 class QUICHE_EXPORT CallbackVisitor : public Http2VisitorInterface { 22 public: 23 // Called when the visitor receives a close event for `stream_id`. 24 using StreamCloseListener = 25 quiche::MultiUseCallback<void(Http2StreamId stream_id)>; 26 27 explicit CallbackVisitor(Perspective perspective, 28 const nghttp2_session_callbacks& callbacks, 29 void* user_data); 30 31 int64_t OnReadyToSend(absl::string_view serialized) override; 32 void OnConnectionError(ConnectionError error) override; 33 bool OnFrameHeader(Http2StreamId stream_id, size_t length, uint8_t type, 34 uint8_t flags) override; 35 void OnSettingsStart() override; 36 void OnSetting(Http2Setting setting) override; 37 void OnSettingsEnd() override; 38 void OnSettingsAck() override; 39 bool OnBeginHeadersForStream(Http2StreamId stream_id) override; 40 OnHeaderResult OnHeaderForStream(Http2StreamId stream_id, 41 absl::string_view name, 42 absl::string_view value) override; 43 bool OnEndHeadersForStream(Http2StreamId stream_id) override; 44 bool OnDataPaddingLength(Http2StreamId stream_id, 45 size_t padding_length) override; 46 bool OnBeginDataForStream(Http2StreamId stream_id, 47 size_t payload_length) override; 48 bool OnDataForStream(Http2StreamId stream_id, 49 absl::string_view data) override; 50 bool OnEndStream(Http2StreamId stream_id) override; 51 void OnRstStream(Http2StreamId stream_id, Http2ErrorCode error_code) override; 52 bool OnCloseStream(Http2StreamId stream_id, 53 Http2ErrorCode error_code) override; 54 void OnPriorityForStream(Http2StreamId stream_id, 55 Http2StreamId parent_stream_id, int weight, 56 bool exclusive) override; 57 void OnPing(Http2PingId ping_id, bool is_ack) override; 58 void OnPushPromiseForStream(Http2StreamId stream_id, 59 Http2StreamId promised_stream_id) override; 60 bool OnGoAway(Http2StreamId last_accepted_stream_id, 61 Http2ErrorCode error_code, 62 absl::string_view opaque_data) override; 63 void OnWindowUpdate(Http2StreamId stream_id, int window_increment) override; 64 int OnBeforeFrameSent(uint8_t frame_type, Http2StreamId stream_id, 65 size_t length, uint8_t flags) override; 66 int OnFrameSent(uint8_t frame_type, Http2StreamId stream_id, size_t length, 67 uint8_t flags, uint32_t error_code) override; 68 bool OnInvalidFrame(Http2StreamId stream_id, 69 InvalidFrameError error) override; 70 void OnBeginMetadataForStream(Http2StreamId stream_id, 71 size_t payload_length) override; 72 bool OnMetadataForStream(Http2StreamId stream_id, 73 absl::string_view metadata) override; 74 bool OnMetadataEndForStream(Http2StreamId stream_id) override; 75 void OnErrorDebug(absl::string_view message) override; 76 stream_map_size()77 size_t stream_map_size() const { return stream_map_.size(); } 78 set_stream_close_listener(StreamCloseListener stream_close_listener)79 void set_stream_close_listener(StreamCloseListener stream_close_listener) { 80 stream_close_listener_ = std::move(stream_close_listener); 81 } 82 83 private: 84 struct QUICHE_EXPORT StreamInfo { 85 bool before_sent_headers = false; 86 bool sent_headers = false; 87 bool received_headers = false; 88 }; 89 90 using StreamInfoMap = absl::flat_hash_map<Http2StreamId, StreamInfo>; 91 92 void PopulateFrame(nghttp2_frame& frame, uint8_t frame_type, 93 Http2StreamId stream_id, size_t length, uint8_t flags, 94 uint32_t error_code, bool sent_headers); 95 96 // Creates the StreamInfoMap entry if it doesn't exist. 97 StreamInfoMap::iterator GetStreamInfo(Http2StreamId stream_id); 98 99 StreamInfoMap stream_map_; 100 101 StreamCloseListener stream_close_listener_; 102 103 Perspective perspective_; 104 nghttp2_session_callbacks_unique_ptr callbacks_; 105 void* user_data_; 106 107 nghttp2_frame current_frame_; 108 std::vector<nghttp2_settings_entry> settings_; 109 size_t remaining_data_ = 0; 110 // Any new stream must have an ID greater than the watermark. 111 Http2StreamId stream_id_watermark_ = 0; 112 }; 113 114 } // namespace adapter 115 } // namespace http2 116 117 #endif // QUICHE_HTTP2_ADAPTER_CALLBACK_VISITOR_H_ 118