1 // Copyright 2021 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_TEST_EMBEDDED_TEST_SERVER_HTTP2_CONNECTION_H_ 6 #define NET_TEST_EMBEDDED_TEST_SERVER_HTTP2_CONNECTION_H_ 7 8 #include <memory> 9 #include <queue> 10 #include <string> 11 12 #include "base/containers/flat_map.h" 13 #include "base/containers/flat_set.h" 14 #include "base/memory/raw_ptr.h" 15 #include "base/memory/scoped_refptr.h" 16 #include "base/memory/weak_ptr.h" 17 #include "net/base/io_buffer.h" 18 #include "net/test/embedded_test_server/embedded_test_server_connection_listener.h" 19 #include "net/test/embedded_test_server/http_connection.h" 20 #include "net/test/embedded_test_server/http_request.h" 21 #include "net/third_party/quiche/src/quiche/http2/adapter/http2_visitor_interface.h" 22 #include "net/third_party/quiche/src/quiche/http2/adapter/oghttp2_adapter.h" 23 24 namespace net::test_server { 25 26 using StreamId = http2::adapter::Http2StreamId; 27 template <class T> 28 using StreamMap = base::flat_map<StreamId, T>; 29 30 class EmbeddedTestServer; 31 32 // Outside of the text/binary (which is just a drop-in parser/decoder 33 // replacement) the main difference from Http1Connection is that multiple 34 // request/response "streams" can exist on the same connection, which means 35 // connections don't open on first request and don't close on first response 36 class Http2Connection : public HttpConnection, 37 public http2::adapter::Http2VisitorInterface { 38 public: 39 Http2Connection(std::unique_ptr<StreamSocket> socket, 40 EmbeddedTestServerConnectionListener* connection_listener, 41 EmbeddedTestServer* server_delegate); 42 ~Http2Connection() override; 43 Http2Connection(const HttpConnection&) = delete; 44 Http2Connection& operator=(const Http2Connection&) = delete; 45 46 // HttpConnection 47 void OnSocketReady() override; 48 StreamSocket* Socket() override; 49 std::unique_ptr<StreamSocket> TakeSocket() override; 50 base::WeakPtr<HttpConnection> GetWeakPtr() override; 51 52 // http2::adapter::Http2VisitorInterface 53 int64_t OnReadyToSend(std::string_view serialized) override; 54 OnHeaderResult OnHeaderForStream(StreamId stream_id, 55 std::string_view key, 56 std::string_view value) override; 57 bool OnEndHeadersForStream(StreamId stream_id) override; 58 bool OnEndStream(StreamId stream_id) override; 59 bool OnCloseStream(StreamId stream_id, 60 http2::adapter::Http2ErrorCode error_code) override; 61 DataFrameHeaderInfo OnReadyToSendDataForStream(StreamId stream_id, 62 size_t max_length) override; 63 bool SendDataFrame(StreamId stream_id, 64 absl::string_view frame_header, 65 size_t payload_bytes) override; 66 // Unused functions OnConnectionError(ConnectionError)67 void OnConnectionError(ConnectionError /*error*/) override {} 68 bool OnFrameHeader(StreamId /*stream_id*/, 69 size_t /*length*/, 70 uint8_t /*type*/, 71 uint8_t /*flags*/) override; OnSettingsStart()72 void OnSettingsStart() override {} OnSetting(http2::adapter::Http2Setting setting)73 void OnSetting(http2::adapter::Http2Setting setting) override {} OnSettingsEnd()74 void OnSettingsEnd() override {} OnSettingsAck()75 void OnSettingsAck() override {} 76 bool OnBeginHeadersForStream(StreamId stream_id) override; 77 bool OnBeginDataForStream(StreamId stream_id, size_t payload_length) override; 78 bool OnDataForStream(StreamId stream_id, std::string_view data) override; 79 bool OnDataPaddingLength(StreamId stream_id, size_t padding_length) override; OnRstStream(StreamId stream_id,http2::adapter::Http2ErrorCode error_code)80 void OnRstStream(StreamId stream_id, 81 http2::adapter::Http2ErrorCode error_code) override {} OnPriorityForStream(StreamId stream_id,StreamId parent_stream_id,int weight,bool exclusive)82 void OnPriorityForStream(StreamId stream_id, 83 StreamId parent_stream_id, 84 int weight, 85 bool exclusive) override {} OnPing(http2::adapter::Http2PingId ping_id,bool is_ack)86 void OnPing(http2::adapter::Http2PingId ping_id, bool is_ack) override {} OnPushPromiseForStream(StreamId stream_id,StreamId promised_stream_id)87 void OnPushPromiseForStream(StreamId stream_id, 88 StreamId promised_stream_id) override {} 89 bool OnGoAway(StreamId last_accepted_stream_id, 90 http2::adapter::Http2ErrorCode error_code, 91 std::string_view opaque_data) override; OnWindowUpdate(StreamId stream_id,int window_increment)92 void OnWindowUpdate(StreamId stream_id, int window_increment) override {} 93 int OnBeforeFrameSent(uint8_t frame_type, 94 StreamId stream_id, 95 size_t length, 96 uint8_t flags) override; 97 int OnFrameSent(uint8_t frame_type, 98 StreamId stream_id, 99 size_t length, 100 uint8_t flags, 101 uint32_t error_code) override; 102 bool OnInvalidFrame(StreamId stream_id, InvalidFrameError error) override; OnBeginMetadataForStream(StreamId stream_id,size_t payload_length)103 void OnBeginMetadataForStream(StreamId stream_id, 104 size_t payload_length) override {} 105 bool OnMetadataForStream(StreamId stream_id, 106 std::string_view metadata) override; 107 bool OnMetadataEndForStream(StreamId stream_id) override; OnErrorDebug(std::string_view message)108 void OnErrorDebug(std::string_view message) override {} 109 adapter()110 http2::adapter::OgHttp2Adapter* adapter() { return adapter_.get(); } 111 112 private: 113 // Corresponds to one HTTP/2 stream in a connection 114 class ResponseDelegate; 115 class DataFrameSource; 116 117 void ReadData(); 118 void OnDataRead(int rv); 119 bool HandleData(int rv); 120 void SendInternal(); 121 void OnSendInternalDone(int rv); 122 123 void SendIfNotProcessing(); 124 125 StreamMap<std::unique_ptr<HttpRequest>> request_map_; 126 StreamMap<std::unique_ptr<ResponseDelegate>> response_map_; 127 StreamMap<HttpRequest::HeaderMap> header_map_; 128 std::queue<StreamId> ready_streams_; 129 std::unique_ptr<http2::adapter::OgHttp2Adapter> adapter_; 130 std::unique_ptr<StreamSocket> socket_; 131 const raw_ptr<EmbeddedTestServerConnectionListener> connection_listener_; 132 const raw_ptr<EmbeddedTestServer> embedded_test_server_; 133 scoped_refptr<IOBufferWithSize> read_buf_; 134 // Frames can be submitted asynchronusly, so frames will be pulled one at a 135 // time by the data frame through ReadyToSend. If the buffer is not null, it 136 // is being processed and new frames should be blocked. 137 scoped_refptr<DrainableIOBuffer> write_buf_{nullptr}; 138 // Streams from a DataFrameSource that were blocked. 139 base::flat_set<StreamId> blocked_streams_; 140 // Whether the connection is in the midst of processing requests, and will 141 // send queued frames and data sources. Stops early on an I/O block or 142 // depleted flow-control window. 143 bool processing_responses_ = false; 144 145 base::WeakPtrFactory<Http2Connection> weak_factory_{this}; 146 }; 147 148 } // namespace net::test_server 149 150 #endif // NET_TEST_EMBEDDED_TEST_SERVER_HTTP2_CONNECTION_H_ 151