• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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