1// Copyright (c) 2011 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_HTTP_HTTP_PROXY_CLIENT_SOCKET_H_
6#define NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_H_
7#pragma once
8
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/memory/ref_counted.h"
13#include "net/base/completion_callback.h"
14#include "net/base/host_port_pair.h"
15#include "net/base/net_log.h"
16#include "net/http/http_auth_controller.h"
17#include "net/http/http_request_headers.h"
18#include "net/http/http_request_info.h"
19#include "net/http/http_response_info.h"
20#include "net/http/proxy_client_socket.h"
21
22class GURL;
23
24namespace net {
25
26class AddressList;
27class ClientSocketHandle;
28class GrowableIOBuffer;
29class HttpAuthCache;
30class HttpAuthHandleFactory;
31class HttpStream;
32class HttpStreamParser;
33class IOBuffer;
34
35class HttpProxyClientSocket : public ProxyClientSocket {
36 public:
37  // Takes ownership of |transport_socket|, which should already be connected
38  // by the time Connect() is called.  If tunnel is true then on Connect()
39  // this socket will establish an Http tunnel.
40  HttpProxyClientSocket(ClientSocketHandle* transport_socket,
41                        const GURL& request_url,
42                        const std::string& user_agent,
43                        const HostPortPair& endpoint,
44                        const HostPortPair& proxy_server,
45                        HttpAuthCache* http_auth_cache,
46                        HttpAuthHandlerFactory* http_auth_handler_factory,
47                        bool tunnel,
48                        bool using_spdy,
49                        bool is_https_proxy);
50
51  // On destruction Disconnect() is called.
52  virtual ~HttpProxyClientSocket();
53
54  // If Connect (or its callback) returns PROXY_AUTH_REQUESTED, then
55  // credentials should be added to the HttpAuthController before calling
56  // RestartWithAuth.
57  int RestartWithAuth(CompletionCallback* callback);
58
59  const scoped_refptr<HttpAuthController>& auth_controller() {
60    return auth_;
61  }
62
63  bool using_spdy() {
64    return using_spdy_;
65  }
66
67  // ProxyClientSocket methods:
68  virtual const HttpResponseInfo* GetConnectResponseInfo() const;
69  virtual HttpStream* CreateConnectResponseStream();
70
71  // ClientSocket methods:
72  virtual int Connect(CompletionCallback* callback
73#ifdef ANDROID
74                      , bool wait_for_connect
75                      , bool valid_uid
76                      , uid_t calling_uid
77#endif
78                     );
79  virtual void Disconnect();
80  virtual bool IsConnected() const;
81  virtual bool IsConnectedAndIdle() const;
82  virtual const BoundNetLog& NetLog() const;
83  virtual void SetSubresourceSpeculation();
84  virtual void SetOmniboxSpeculation();
85  virtual bool WasEverUsed() const;
86  virtual bool UsingTCPFastOpen() const;
87
88  // Socket methods:
89  virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
90  virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback);
91  virtual bool SetReceiveBufferSize(int32 size);
92  virtual bool SetSendBufferSize(int32 size);
93  virtual int GetPeerAddress(AddressList* address) const;
94  virtual int GetLocalAddress(IPEndPoint* address) const;
95
96 private:
97  enum State {
98    STATE_NONE,
99    STATE_GENERATE_AUTH_TOKEN,
100    STATE_GENERATE_AUTH_TOKEN_COMPLETE,
101    STATE_SEND_REQUEST,
102    STATE_SEND_REQUEST_COMPLETE,
103    STATE_READ_HEADERS,
104    STATE_READ_HEADERS_COMPLETE,
105    STATE_DRAIN_BODY,
106    STATE_DRAIN_BODY_COMPLETE,
107    STATE_TCP_RESTART,
108    STATE_TCP_RESTART_COMPLETE,
109    STATE_DONE,
110  };
111
112  // The size in bytes of the buffer we use to drain the response body that
113  // we want to throw away.  The response body is typically a small error
114  // page just a few hundred bytes long.
115  static const int kDrainBodyBufferSize = 1024;
116
117  int PrepareForAuthRestart();
118  int DidDrainBodyForAuthRestart(bool keep_alive);
119
120  int HandleAuthChallenge();
121
122  void LogBlockedTunnelResponse(int response_code) const;
123
124  void DoCallback(int result);
125  void OnIOComplete(int result);
126
127  int DoLoop(int last_io_result);
128  int DoGenerateAuthToken();
129  int DoGenerateAuthTokenComplete(int result);
130  int DoSendRequest();
131  int DoSendRequestComplete(int result);
132  int DoReadHeaders();
133  int DoReadHeadersComplete(int result);
134  int DoDrainBody();
135  int DoDrainBodyComplete(int result);
136  int DoTCPRestart();
137  int DoTCPRestartComplete(int result);
138
139  CompletionCallbackImpl<HttpProxyClientSocket> io_callback_;
140  State next_state_;
141
142  // Stores the callback to the layer above, called on completing Connect().
143  CompletionCallback* user_callback_;
144
145  HttpRequestInfo request_;
146  HttpResponseInfo response_;
147
148  scoped_refptr<GrowableIOBuffer> parser_buf_;
149  scoped_ptr<HttpStreamParser> http_stream_parser_;
150  scoped_refptr<IOBuffer> drain_buf_;
151
152  // Stores the underlying socket.
153  scoped_ptr<ClientSocketHandle> transport_;
154
155  // The hostname and port of the endpoint.  This is not necessarily the one
156  // specified by the URL, due to Alternate-Protocol or fixed testing ports.
157  const HostPortPair endpoint_;
158  scoped_refptr<HttpAuthController> auth_;
159  const bool tunnel_;
160  // If true, then the connection to the proxy is a SPDY connection.
161  const bool using_spdy_;
162  // If true, then SSL is used to communicate with this proxy
163  const bool is_https_proxy_;
164
165  std::string request_line_;
166  HttpRequestHeaders request_headers_;
167
168  const BoundNetLog net_log_;
169
170  DISALLOW_COPY_AND_ASSIGN(HttpProxyClientSocket);
171};
172
173}  // namespace net
174
175#endif  // NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_H_
176