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_server.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 ProxyServer& proxy_server, 51 const std::string& user_agent, 52 const HostPortPair& endpoint, 53 const NetLogWithSource& source_net_log, 54 scoped_refptr<HttpAuthController> auth_controller, 55 ProxyDelegate* proxy_delegate); 56 57 SpdyProxyClientSocket(const SpdyProxyClientSocket&) = delete; 58 SpdyProxyClientSocket& operator=(const SpdyProxyClientSocket&) = delete; 59 60 // On destruction Disconnect() is called. 61 ~SpdyProxyClientSocket() override; 62 63 // ProxyClientSocket methods: 64 const HttpResponseInfo* GetConnectResponseInfo() const override; 65 const scoped_refptr<HttpAuthController>& GetAuthController() const override; 66 int RestartWithAuth(CompletionOnceCallback callback) override; 67 void SetStreamPriority(RequestPriority priority) override; 68 69 // StreamSocket implementation. 70 int Connect(CompletionOnceCallback callback) override; 71 void Disconnect() override; 72 bool IsConnected() const override; 73 bool IsConnectedAndIdle() const override; 74 const NetLogWithSource& NetLog() const override; 75 bool WasEverUsed() const override; 76 bool WasAlpnNegotiated() 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, 104 const spdy::Http2HeaderBlock* pushed_request_headers) override; 105 void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override; 106 void OnDataSent() override; 107 void OnTrailers(const spdy::Http2HeaderBlock& 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 ProxyServer proxy_server_; 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