1 // Copyright (c) 2017 The Chromium Authors. All rights reserved.
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_QUIC_QUIC_PROXY_CLIENT_SOCKET_H_
6 #define NET_QUIC_QUIC_PROXY_CLIENT_SOCKET_H_
7 
8 #include <cstdio>
9 #include <memory>
10 #include <string>
11 
12 #include "net/base/completion_once_callback.h"
13 #include "net/base/proxy_server.h"
14 #include "net/http/proxy_client_socket.h"
15 #include "net/quic/quic_chromium_client_session.h"
16 #include "net/quic/quic_chromium_client_stream.h"
17 #include "net/spdy/spdy_read_queue.h"
18 #include "net/traffic_annotation/network_traffic_annotation.h"
19 
20 namespace net {
21 
22 class HttpAuthController;
23 class ProxyDelegate;
24 
25 // QuicProxyClientSocket provides a socket interface to an underlying
26 // QuicChromiumClientStream. Bytes written to/read from a QuicProxyClientSocket
27 // are sent/received via STREAM frames in the underlying QUIC stream.
28 class NET_EXPORT_PRIVATE QuicProxyClientSocket : public ProxyClientSocket {
29  public:
30   // Create a socket on top of the |stream| by sending a HEADERS CONNECT
31   // frame for |endpoint|.  After the response HEADERS frame is received, any
32   // data read/written to the socket will be transferred in STREAM frames.
33   QuicProxyClientSocket(
34       std::unique_ptr<QuicChromiumClientStream::Handle> stream,
35       std::unique_ptr<QuicChromiumClientSession::Handle> session,
36       const ProxyServer& proxy_server,
37       const std::string& user_agent,
38       const HostPortPair& endpoint,
39       const NetLogWithSource& net_log,
40       HttpAuthController* auth_controller,
41       ProxyDelegate* proxy_delegate);
42 
43   // On destruction Disconnect() is called.
44   ~QuicProxyClientSocket() override;
45 
46   // ProxyClientSocket methods:
47   const HttpResponseInfo* GetConnectResponseInfo() const override;
48   const scoped_refptr<HttpAuthController>& GetAuthController() const override;
49   int RestartWithAuth(CompletionOnceCallback callback) override;
50   bool IsUsingSpdy() const override;
51   NextProto GetProxyNegotiatedProtocol() const override;
52   void SetStreamPriority(RequestPriority priority) override;
53 
54   // StreamSocket implementation.
55   int Connect(CompletionOnceCallback callback) override;
56   void Disconnect() override;
57   bool IsConnected() const override;
58   bool IsConnectedAndIdle() const override;
59   const NetLogWithSource& NetLog() const override;
60   bool WasEverUsed() const override;
61   bool WasAlpnNegotiated() const override;
62   NextProto GetNegotiatedProtocol() const override;
63   bool GetSSLInfo(SSLInfo* ssl_info) override;
64   void GetConnectionAttempts(ConnectionAttempts* out) const override;
ClearConnectionAttempts()65   void ClearConnectionAttempts() override {}
AddConnectionAttempts(const ConnectionAttempts & attempts)66   void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
67   int64_t GetTotalReceivedBytes() const override;
68   void ApplySocketTag(const SocketTag& tag) override;
69 
70   // Socket implementation.
71   int Read(IOBuffer* buf,
72            int buf_len,
73            CompletionOnceCallback callback) override;
74   int Write(IOBuffer* buf,
75             int buf_len,
76             CompletionOnceCallback callback,
77             const NetworkTrafficAnnotationTag& traffic_annotation) override;
78   int SetReceiveBufferSize(int32_t size) override;
79   int SetSendBufferSize(int32_t size) override;
80   int GetPeerAddress(IPEndPoint* address) const override;
81   int GetLocalAddress(IPEndPoint* address) const override;
82 
83  private:
84   enum State {
85     STATE_DISCONNECTED,
86     STATE_GENERATE_AUTH_TOKEN,
87     STATE_GENERATE_AUTH_TOKEN_COMPLETE,
88     STATE_SEND_REQUEST,
89     STATE_SEND_REQUEST_COMPLETE,
90     STATE_READ_REPLY,
91     STATE_READ_REPLY_COMPLETE,
92     STATE_CONNECT_COMPLETE
93   };
94 
95   void OnIOComplete(int result);  // Callback used during connecting
96   void OnReadComplete(int rv);
97   void OnWriteComplete(int rv);
98 
99   // Callback for stream_->ReadInitialHeaders()
100   void OnReadResponseHeadersComplete(int result);
101   int ProcessResponseHeaders(const spdy::Http2HeaderBlock& headers);
102 
103   int DoLoop(int last_io_result);
104   int DoGenerateAuthToken();
105   int DoGenerateAuthTokenComplete(int result);
106   int DoSendRequest();
107   int DoSendRequestComplete(int result);
108   int DoReadReply();
109   int DoReadReplyComplete(int result);
110 
111   State next_state_;
112 
113   // Handle to the QUIC Stream that this sits on top of.
114   std::unique_ptr<QuicChromiumClientStream::Handle> stream_;
115 
116   // Handle to the session that |stream_| belongs to.
117   std::unique_ptr<QuicChromiumClientSession::Handle> session_;
118 
119   // Stores the callback for Connect().
120   CompletionOnceCallback connect_callback_;
121   // Stores the callback for Read().
122   CompletionOnceCallback read_callback_;
123   // Stores the read buffer pointer for Read().
124   IOBuffer* read_buf_;
125   // Stores the callback for Write().
126   CompletionOnceCallback write_callback_;
127   // Stores the write buffer length for Write().
128   int write_buf_len_;
129 
130   // CONNECT request and response.
131   HttpRequestInfo request_;
132   HttpResponseInfo response_;
133 
134   spdy::Http2HeaderBlock response_header_block_;
135 
136   // The hostname and port of the endpoint.  This is not necessarily the one
137   // specified by the URL, due to Alternate-Protocol or fixed testing ports.
138   const HostPortPair endpoint_;
139   scoped_refptr<HttpAuthController> auth_;
140 
141   const ProxyServer proxy_server_;
142 
143   // This delegate must outlive this proxy client socket.
144   ProxyDelegate* const proxy_delegate_;
145 
146   std::string user_agent_;
147 
148   const NetLogWithSource net_log_;
149 
150   // The default weak pointer factory.
151   base::WeakPtrFactory<QuicProxyClientSocket> weak_factory_{this};
152 
153   DISALLOW_COPY_AND_ASSIGN(QuicProxyClientSocket);
154 };
155 
156 }  // namespace net
157 
158 #endif  // NET_QUIC_QUIC_PROXY_CLIENT_SOCKET_H_
159