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 // Unused functions OnConnectionError(ConnectionError)62 void OnConnectionError(ConnectionError /*error*/) override {} 63 bool OnFrameHeader(StreamId /*stream_id*/, 64 size_t /*length*/, 65 uint8_t /*type*/, 66 uint8_t /*flags*/) override; OnSettingsStart()67 void OnSettingsStart() override {} OnSetting(http2::adapter::Http2Setting setting)68 void OnSetting(http2::adapter::Http2Setting setting) override {} OnSettingsEnd()69 void OnSettingsEnd() override {} OnSettingsAck()70 void OnSettingsAck() override {} 71 bool OnBeginHeadersForStream(StreamId stream_id) override; 72 bool OnBeginDataForStream(StreamId stream_id, size_t payload_length) override; 73 bool OnDataForStream(StreamId stream_id, std::string_view data) override; 74 bool OnDataPaddingLength(StreamId stream_id, size_t padding_length) override; OnRstStream(StreamId stream_id,http2::adapter::Http2ErrorCode error_code)75 void OnRstStream(StreamId stream_id, 76 http2::adapter::Http2ErrorCode error_code) override {} OnPriorityForStream(StreamId stream_id,StreamId parent_stream_id,int weight,bool exclusive)77 void OnPriorityForStream(StreamId stream_id, 78 StreamId parent_stream_id, 79 int weight, 80 bool exclusive) override {} OnPing(http2::adapter::Http2PingId ping_id,bool is_ack)81 void OnPing(http2::adapter::Http2PingId ping_id, bool is_ack) override {} OnPushPromiseForStream(StreamId stream_id,StreamId promised_stream_id)82 void OnPushPromiseForStream(StreamId stream_id, 83 StreamId promised_stream_id) override {} 84 bool OnGoAway(StreamId last_accepted_stream_id, 85 http2::adapter::Http2ErrorCode error_code, 86 std::string_view opaque_data) override; OnWindowUpdate(StreamId stream_id,int window_increment)87 void OnWindowUpdate(StreamId stream_id, int window_increment) override {} 88 int OnBeforeFrameSent(uint8_t frame_type, 89 StreamId stream_id, 90 size_t length, 91 uint8_t flags) override; 92 int OnFrameSent(uint8_t frame_type, 93 StreamId stream_id, 94 size_t length, 95 uint8_t flags, 96 uint32_t error_code) override; 97 bool OnInvalidFrame(StreamId stream_id, InvalidFrameError error) override; OnBeginMetadataForStream(StreamId stream_id,size_t payload_length)98 void OnBeginMetadataForStream(StreamId stream_id, 99 size_t payload_length) override {} 100 bool OnMetadataForStream(StreamId stream_id, 101 std::string_view metadata) override; 102 bool OnMetadataEndForStream(StreamId stream_id) override; OnErrorDebug(std::string_view message)103 void OnErrorDebug(std::string_view message) override {} 104 adapter()105 http2::adapter::OgHttp2Adapter* adapter() { return adapter_.get(); } 106 107 private: 108 // Corresponds to one HTTP/2 stream in a connection 109 class ResponseDelegate; 110 class DataFrameSource; 111 112 void ReadData(); 113 void OnDataRead(int rv); 114 bool HandleData(int rv); 115 void SendInternal(); 116 void OnSendInternalDone(int rv); 117 118 void SendIfNotProcessing(); 119 120 StreamMap<std::unique_ptr<HttpRequest>> request_map_; 121 StreamMap<std::unique_ptr<ResponseDelegate>> response_map_; 122 StreamMap<HttpRequest::HeaderMap> header_map_; 123 std::queue<StreamId> ready_streams_; 124 std::unique_ptr<http2::adapter::OgHttp2Adapter> adapter_; 125 std::unique_ptr<StreamSocket> socket_; 126 const raw_ptr<EmbeddedTestServerConnectionListener> connection_listener_; 127 const raw_ptr<EmbeddedTestServer> embedded_test_server_; 128 scoped_refptr<IOBufferWithSize> read_buf_; 129 // Frames can be submitted asynchronusly, so frames will be pulled one at a 130 // time by the data frame through ReadyToSend. If the buffer is not null, it 131 // is being processed and new frames should be blocked. 132 scoped_refptr<DrainableIOBuffer> write_buf_{nullptr}; 133 // Streams from a DataFrameSource that were blocked. 134 base::flat_set<StreamId> blocked_streams_; 135 // Whether the connection is in the midst of processing requests, and will 136 // send queued frames and data sources. Stops early on an I/O block or 137 // depleted flow-control window. 138 bool processing_responses_ = false; 139 140 base::WeakPtrFactory<Http2Connection> weak_factory_{this}; 141 }; 142 143 } // namespace net::test_server 144 145 #endif // NET_TEST_EMBEDDED_TEST_SERVER_HTTP2_CONNECTION_H_ 146