1 // Copyright 2012 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_SPDY_SPDY_PROXY_CLIENT_SOCKET_H_ 6 #define NET_SPDY_SPDY_PROXY_CLIENT_SOCKET_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <memory> 12 #include <string> 13 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/completion_once_callback.h" 18 #include "net/base/host_port_pair.h" 19 #include "net/base/net_export.h" 20 #include "net/base/proxy_chain.h" 21 #include "net/http/http_auth_controller.h" 22 #include "net/http/http_request_headers.h" 23 #include "net/http/http_request_info.h" 24 #include "net/http/http_response_info.h" 25 #include "net/http/proxy_client_socket.h" 26 #include "net/log/net_log_source.h" 27 #include "net/log/net_log_with_source.h" 28 #include "net/spdy/spdy_http_stream.h" 29 #include "net/spdy/spdy_read_queue.h" 30 #include "net/spdy/spdy_session.h" 31 #include "net/spdy/spdy_stream.h" 32 #include "net/third_party/quiche/src/quiche/common/http/http_header_block.h" 33 #include "net/third_party/quiche/src/quiche/http2/core/spdy_protocol.h" 34 #include "net/traffic_annotation/network_traffic_annotation.h" 35 36 namespace net { 37 38 class IOBuffer; 39 class ProxyDelegate; 40 class SpdyStream; 41 42 // Tunnels a stream socket over an HTTP/2 connection. 43 class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket, 44 public SpdyStream::Delegate { 45 public: 46 // Create a socket on top of the |spdy_stream| by sending a HEADERS CONNECT 47 // frame for |endpoint|. After the response HEADERS frame is received, any 48 // data read/written to the socket will be transferred in data frames. This 49 // object will set itself as |spdy_stream|'s delegate. 50 SpdyProxyClientSocket(const base::WeakPtr<SpdyStream>& spdy_stream, 51 const ProxyChain& proxy_chain, 52 size_t proxy_chain_index, 53 const std::string& user_agent, 54 const HostPortPair& endpoint, 55 const NetLogWithSource& source_net_log, 56 scoped_refptr<HttpAuthController> auth_controller, 57 ProxyDelegate* proxy_delegate); 58 59 SpdyProxyClientSocket(const SpdyProxyClientSocket&) = delete; 60 SpdyProxyClientSocket& operator=(const SpdyProxyClientSocket&) = delete; 61 62 // On destruction Disconnect() is called. 63 ~SpdyProxyClientSocket() override; 64 65 // ProxyClientSocket methods: 66 const HttpResponseInfo* GetConnectResponseInfo() const override; 67 const scoped_refptr<HttpAuthController>& GetAuthController() const override; 68 int RestartWithAuth(CompletionOnceCallback callback) override; 69 void SetStreamPriority(RequestPriority priority) override; 70 71 // StreamSocket implementation. 72 int Connect(CompletionOnceCallback callback) override; 73 void Disconnect() override; 74 bool IsConnected() const override; 75 bool IsConnectedAndIdle() const override; 76 const NetLogWithSource& NetLog() const override; 77 bool WasEverUsed() const override; 78 NextProto GetNegotiatedProtocol() const override; 79 bool GetSSLInfo(SSLInfo* ssl_info) override; 80 int64_t GetTotalReceivedBytes() const override; 81 void ApplySocketTag(const SocketTag& tag) override; 82 83 // Socket implementation. 84 int Read(IOBuffer* buf, 85 int buf_len, 86 CompletionOnceCallback callback) override; 87 int ReadIfReady(IOBuffer* buf, 88 int buf_len, 89 CompletionOnceCallback callback) override; 90 int CancelReadIfReady() override; 91 int Write(IOBuffer* buf, 92 int buf_len, 93 CompletionOnceCallback callback, 94 const NetworkTrafficAnnotationTag& traffic_annotation) override; 95 int SetReceiveBufferSize(int32_t size) override; 96 int SetSendBufferSize(int32_t size) override; 97 int GetPeerAddress(IPEndPoint* address) const override; 98 int GetLocalAddress(IPEndPoint* address) const override; 99 100 // SpdyStream::Delegate implementation. 101 void OnHeadersSent() override; 102 void OnEarlyHintsReceived(const quiche::HttpHeaderBlock& headers) override; 103 void OnHeadersReceived( 104 const quiche::HttpHeaderBlock& response_headers) override; 105 void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override; 106 void OnDataSent() override; 107 void OnTrailers(const quiche::HttpHeaderBlock& trailers) override; 108 void OnClose(int status) override; 109 bool CanGreaseFrameType() const override; 110 NetLogSource source_dependency() const override; 111 112 private: 113 enum State { 114 STATE_DISCONNECTED, 115 STATE_GENERATE_AUTH_TOKEN, 116 STATE_GENERATE_AUTH_TOKEN_COMPLETE, 117 STATE_SEND_REQUEST, 118 STATE_SEND_REQUEST_COMPLETE, 119 STATE_READ_REPLY_COMPLETE, 120 STATE_OPEN, 121 STATE_CLOSED 122 }; 123 124 // Calls `write_callback_(result)`. Used to run a callback posted to the 125 // message loop. 126 void RunWriteCallback(int result); 127 128 void OnIOComplete(int result); 129 130 int DoLoop(int last_io_result); 131 int DoGenerateAuthToken(); 132 int DoGenerateAuthTokenComplete(int result); 133 int DoSendRequest(); 134 int DoSendRequestComplete(int result); 135 int DoReadReplyComplete(int result); 136 137 // Populates |user_buffer_| with as much read data as possible 138 // and returns the number of bytes read. 139 size_t PopulateUserReadBuffer(char* out, size_t len); 140 141 // Called when the peer sent END_STREAM. 142 void MaybeSendEndStream(); 143 144 State next_state_ = STATE_DISCONNECTED; 145 146 // Pointer to the SPDY Stream that this sits on top of. 147 base::WeakPtr<SpdyStream> spdy_stream_; 148 149 // Stores the callback to the layer above, called on completing Read() or 150 // Connect(). 151 CompletionOnceCallback read_callback_; 152 // Stores the callback to the layer above, called on completing Write(). 153 CompletionOnceCallback write_callback_; 154 155 // CONNECT request and response. 156 HttpRequestInfo request_; 157 HttpResponseInfo response_; 158 159 // The hostname and port of the endpoint. This is not necessarily the one 160 // specified by the URL, due to Alternate-Protocol or fixed testing ports. 161 const HostPortPair endpoint_; 162 scoped_refptr<HttpAuthController> auth_; 163 164 const ProxyChain proxy_chain_; 165 const size_t proxy_chain_index_; 166 167 // This delegate must outlive this proxy client socket. 168 const raw_ptr<ProxyDelegate> proxy_delegate_; 169 170 std::string user_agent_; 171 172 // We buffer the response body as it arrives asynchronously from the stream. 173 SpdyReadQueue read_buffer_queue_; 174 175 // User provided buffer for the Read() response. 176 scoped_refptr<IOBuffer> user_buffer_; 177 size_t user_buffer_len_ = 0; 178 179 // User specified number of bytes to be written. 180 int write_buffer_len_ = 0; 181 182 // True if the transport socket has ever sent data. 183 bool was_ever_used_ = false; 184 185 const NetLogWithSource net_log_; 186 const NetLogSource source_dependency_; 187 188 // State for handling END_STREAM. When the peer sends a DATA frame with 189 // END_STREAM, it should be treated as being equivalent to the TCP FIN bit. 190 // We should send a DATA frame with END_STREAM after receiving END_STREAM 191 // as the spec requires. 192 enum class EndStreamState { 193 kNone, 194 kEndStreamReceived, 195 kEndStreamSent, 196 }; 197 EndStreamState end_stream_state_ = EndStreamState::kNone; 198 199 base::WeakPtrFactory<SpdyProxyClientSocket> weak_factory_{this}; 200 }; 201 202 } // namespace net 203 204 #endif // NET_SPDY_SPDY_PROXY_CLIENT_SOCKET_H_ 205