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