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