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