xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/adapter/callback_visitor.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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