xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/adapter/nghttp2_adapter.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 #ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_ADAPTER_H_
2 #define QUICHE_HTTP2_ADAPTER_NGHTTP2_ADAPTER_H_
3 
4 #include <cstdint>
5 
6 #include "absl/container/flat_hash_map.h"
7 #include "absl/container/inlined_vector.h"
8 #include "quiche/http2/adapter/http2_adapter.h"
9 #include "quiche/http2/adapter/http2_protocol.h"
10 #include "quiche/http2/adapter/nghttp2_session.h"
11 #include "quiche/http2/adapter/nghttp2_util.h"
12 #include "quiche/common/platform/api/quiche_export.h"
13 
14 namespace http2 {
15 namespace adapter {
16 
17 class QUICHE_EXPORT NgHttp2Adapter : public Http2Adapter {
18  public:
19   ~NgHttp2Adapter() override;
20 
21   // Creates an adapter that functions as a client. Does not take ownership of
22   // |options|.
23   static std::unique_ptr<NgHttp2Adapter> CreateClientAdapter(
24       Http2VisitorInterface& visitor, const nghttp2_option* options = nullptr);
25 
26   // Creates an adapter that functions as a server. Does not take ownership of
27   // |options|.
28   static std::unique_ptr<NgHttp2Adapter> CreateServerAdapter(
29       Http2VisitorInterface& visitor, const nghttp2_option* options = nullptr);
30 
31   bool IsServerSession() const override;
want_read()32   bool want_read() const override { return session_->want_read(); }
want_write()33   bool want_write() const override { return session_->want_write(); }
34 
35   int64_t ProcessBytes(absl::string_view bytes) override;
36   void SubmitSettings(absl::Span<const Http2Setting> settings) override;
37   void SubmitPriorityForStream(Http2StreamId stream_id,
38                                Http2StreamId parent_stream_id, int weight,
39                                bool exclusive) override;
40 
41   // Submits a PING on the connection. Note that nghttp2 automatically submits
42   // PING acks upon receiving non-ack PINGs from the peer, so callers only use
43   // this method to originate PINGs. See nghttp2_option_set_no_auto_ping_ack().
44   void SubmitPing(Http2PingId ping_id) override;
45 
46   void SubmitShutdownNotice() override;
47   void SubmitGoAway(Http2StreamId last_accepted_stream_id,
48                     Http2ErrorCode error_code,
49                     absl::string_view opaque_data) override;
50 
51   void SubmitWindowUpdate(Http2StreamId stream_id,
52                           int window_increment) override;
53 
54   void SubmitRst(Http2StreamId stream_id, Http2ErrorCode error_code) override;
55 
56   void SubmitMetadata(Http2StreamId stream_id, size_t max_frame_size,
57                       std::unique_ptr<MetadataSource> source) override;
58 
59   int Send() override;
60 
61   int GetSendWindowSize() const override;
62   int GetStreamSendWindowSize(Http2StreamId stream_id) const override;
63 
64   int GetStreamReceiveWindowLimit(Http2StreamId stream_id) const override;
65   int GetStreamReceiveWindowSize(Http2StreamId stream_id) const override;
66   int GetReceiveWindowSize() const override;
67 
68   int GetHpackEncoderDynamicTableSize() const override;
69   int GetHpackDecoderDynamicTableSize() const override;
70 
71   Http2StreamId GetHighestReceivedStreamId() const override;
72 
73   void MarkDataConsumedForStream(Http2StreamId stream_id,
74                                  size_t num_bytes) override;
75 
76   int32_t SubmitRequest(absl::Span<const Header> headers,
77                         std::unique_ptr<DataFrameSource> data_source,
78                         void* user_data) override;
79 
80   int SubmitResponse(Http2StreamId stream_id, absl::Span<const Header> headers,
81                      std::unique_ptr<DataFrameSource> data_source) override;
82 
83   int SubmitTrailer(Http2StreamId stream_id,
84                     absl::Span<const Header> trailers) override;
85 
86   void SetStreamUserData(Http2StreamId stream_id, void* user_data) override;
87   void* GetStreamUserData(Http2StreamId stream_id) override;
88 
89   bool ResumeStream(Http2StreamId stream_id) override;
90 
91   void FrameNotSent(Http2StreamId stream_id, uint8_t frame_type) override;
92 
93   // Removes references to the `stream_id` from this adapter.
94   void RemoveStream(Http2StreamId stream_id);
95 
96   // Accessor for testing.
sources_size()97   size_t sources_size() const { return sources_.size(); }
stream_metadata_size()98   size_t stream_metadata_size() const { return stream_metadata_.size(); }
pending_metadata_count(Http2StreamId stream_id)99   size_t pending_metadata_count(Http2StreamId stream_id) const {
100     if (auto it = stream_metadata_.find(stream_id);
101         it != stream_metadata_.end()) {
102       return it->second.size();
103     }
104     return 0;
105   }
106 
107  private:
108   class NotifyingMetadataSource;
109 
110   NgHttp2Adapter(Http2VisitorInterface& visitor, Perspective perspective,
111                  const nghttp2_option* options);
112 
113   // Performs any necessary initialization of the underlying HTTP/2 session,
114   // such as preparing initial SETTINGS.
115   void Initialize();
116 
117   void RemovePendingMetadata(Http2StreamId stream_id);
118 
119   std::unique_ptr<NgHttp2Session> session_;
120   Http2VisitorInterface& visitor_;
121   const nghttp2_option* options_;
122   Perspective perspective_;
123 
124   using MetadataSourceVec =
125       absl::InlinedVector<std::unique_ptr<MetadataSource>, 2>;
126   using MetadataMap = absl::flat_hash_map<Http2StreamId, MetadataSourceVec>;
127   MetadataMap stream_metadata_;
128 
129   absl::flat_hash_map<int32_t, std::unique_ptr<DataFrameSource>> sources_;
130 };
131 
132 }  // namespace adapter
133 }  // namespace http2
134 
135 #endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_ADAPTER_H_
136