http_network_transaction.h revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2010 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_NETWORK_TRANSACTION_H_
6#define NET_HTTP_HTTP_NETWORK_TRANSACTION_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/ref_counted.h"
12#include "base/scoped_ptr.h"
13#include "base/time.h"
14#include "net/base/address_list.h"
15#include "net/base/io_buffer.h"
16#include "net/base/load_flags.h"
17#include "net/base/load_states.h"
18#include "net/base/net_log.h"
19#include "net/base/ssl_config_service.h"
20#include "net/http/http_alternate_protocols.h"
21#include "net/http/http_auth.h"
22#include "net/http/http_auth_controller.h"
23#include "net/http/http_auth_handler.h"
24#include "net/http/http_response_info.h"
25#include "net/http/http_transaction.h"
26#include "net/proxy/proxy_service.h"
27#include "net/socket/client_socket_pool.h"
28#include "testing/gtest/include/gtest/gtest_prod.h"
29
30namespace net {
31
32class ClientSocketFactory;
33class ClientSocketHandle;
34class HttpNetworkSession;
35class HttpRequestHeaders;
36class HttpStream;
37class SpdyHttpStream;
38
39class HttpNetworkTransaction : public HttpTransaction {
40 public:
41  explicit HttpNetworkTransaction(HttpNetworkSession* session);
42
43  virtual ~HttpNetworkTransaction();
44
45  static void SetHostMappingRules(const std::string& rules);
46
47  // Controls whether or not we use the Alternate-Protocol header.
48  static void SetUseAlternateProtocols(bool value);
49
50  // Sets the next protocol negotiation value used during the SSL handshake.
51  static void SetNextProtos(const std::string& next_protos);
52
53  // Sets the HttpNetworkTransaction into a mode where it can ignore
54  // certificate errors.  This is for testing.
55  static void IgnoreCertificateErrors(bool enabled);
56
57  // HttpTransaction methods:
58  virtual int Start(const HttpRequestInfo* request_info,
59                    CompletionCallback* callback,
60                    const BoundNetLog& net_log);
61  virtual int RestartIgnoringLastError(CompletionCallback* callback);
62  virtual int RestartWithCertificate(X509Certificate* client_cert,
63                                     CompletionCallback* callback);
64  virtual int RestartWithAuth(const std::wstring& username,
65                              const std::wstring& password,
66                              CompletionCallback* callback);
67  virtual bool IsReadyToRestartForAuth() {
68    return pending_auth_target_ != HttpAuth::AUTH_NONE &&
69        HaveAuth(pending_auth_target_);
70  }
71
72  virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
73  virtual void StopCaching() {}
74  virtual const HttpResponseInfo* GetResponseInfo() const;
75  virtual LoadState GetLoadState() const;
76  virtual uint64 GetUploadProgress() const;
77
78 private:
79  FRIEND_TEST(HttpNetworkTransactionTest, ResetStateForRestart);
80
81  enum State {
82    STATE_RESOLVE_PROXY,
83    STATE_RESOLVE_PROXY_COMPLETE,
84    STATE_INIT_CONNECTION,
85    STATE_INIT_CONNECTION_COMPLETE,
86    STATE_GENERATE_PROXY_AUTH_TOKEN,
87    STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE,
88    STATE_GENERATE_SERVER_AUTH_TOKEN,
89    STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE,
90    STATE_SEND_REQUEST,
91    STATE_SEND_REQUEST_COMPLETE,
92    STATE_READ_HEADERS,
93    STATE_READ_HEADERS_COMPLETE,
94    STATE_READ_BODY,
95    STATE_READ_BODY_COMPLETE,
96    STATE_DRAIN_BODY_FOR_AUTH_RESTART,
97    STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE,
98    STATE_SPDY_GET_STREAM,
99    STATE_SPDY_GET_STREAM_COMPLETE,
100    STATE_SPDY_SEND_REQUEST,
101    STATE_SPDY_SEND_REQUEST_COMPLETE,
102    STATE_SPDY_READ_HEADERS,
103    STATE_SPDY_READ_HEADERS_COMPLETE,
104    STATE_SPDY_READ_BODY,
105    STATE_SPDY_READ_BODY_COMPLETE,
106    STATE_NONE
107  };
108
109  enum AlternateProtocolMode {
110    kUnspecified,  // Unspecified, check HttpAlternateProtocols
111    kUsingAlternateProtocol,  // Using an alternate protocol
112    kDoNotUseAlternateProtocol,  // Failed to connect once, do not try again.
113  };
114
115  void DoCallback(int result);
116  void OnIOComplete(int result);
117
118  // Runs the state transition loop.
119  int DoLoop(int result);
120
121  // Each of these methods corresponds to a State value.  Those with an input
122  // argument receive the result from the previous state.  If a method returns
123  // ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
124  // next state method as the result arg.
125  int DoResolveProxy();
126  int DoResolveProxyComplete(int result);
127  int DoInitConnection();
128  int DoInitConnectionComplete(int result);
129  int DoGenerateProxyAuthToken();
130  int DoGenerateProxyAuthTokenComplete(int result);
131  int DoGenerateServerAuthToken();
132  int DoGenerateServerAuthTokenComplete(int result);
133  int DoSendRequest();
134  int DoSendRequestComplete(int result);
135  int DoReadHeaders();
136  int DoReadHeadersComplete(int result);
137  int DoReadBody();
138  int DoReadBodyComplete(int result);
139  int DoDrainBodyForAuthRestart();
140  int DoDrainBodyForAuthRestartComplete(int result);
141  int DoSpdyGetStream();
142  int DoSpdyGetStreamComplete(int result);
143  int DoSpdySendRequest();
144  int DoSpdySendRequestComplete(int result);
145  int DoSpdyReadHeaders();
146  int DoSpdyReadHeadersComplete(int result);
147  int DoSpdyReadBody();
148  int DoSpdyReadBodyComplete(int result);
149
150  // Record histograms of latency until Connect() completes.
151  static void LogHttpConnectedMetrics(const ClientSocketHandle& handle);
152
153  // Record histogram of time until first byte of header is received.
154  void LogTransactionConnectedMetrics();
155
156  // Record histogram of latency (durations until last byte received).
157  void LogTransactionMetrics() const;
158
159  // Writes a log message to help debugging in the field when we block a proxy
160  // response to a CONNECT request.
161  void LogBlockedTunnelResponse(int response_code) const;
162
163  static void LogIOErrorMetrics(const ClientSocketHandle& handle);
164
165  // Called to handle a certificate error.  Returns OK if the error should be
166  // ignored.  Otherwise, stores the certificate in response_.ssl_info and
167  // returns the same error code.
168  int HandleCertificateError(int error);
169
170  // Called to handle a client certificate request.
171  int HandleCertificateRequest(int error);
172
173  // Called to possibly recover from an SSL handshake error.  Sets next_state_
174  // and returns OK if recovering from the error.  Otherwise, the same error
175  // code is returned.
176  int HandleSSLHandshakeError(int error);
177
178  // Called to possibly recover from the given error.  Sets next_state_ and
179  // returns OK if recovering from the error.  Otherwise, the same error code
180  // is returned.
181  int HandleIOError(int error);
182
183  // Gets the response headers from the HttpStream.
184  HttpResponseHeaders* GetResponseHeaders() const;
185
186  // Called when we reached EOF or got an error.  Returns true if we should
187  // resend the request.  |error| is OK when we reached EOF.
188  bool ShouldResendRequest(int error) const;
189
190  // Resets the connection and the request headers for resend.  Called when
191  // ShouldResendRequest() is true.
192  void ResetConnectionAndRequestForResend();
193
194  // Called when we encounter a network error that could be resolved by trying
195  // a new proxy configuration.  If there is another proxy configuration to try
196  // then this method sets next_state_ appropriately and returns either OK or
197  // ERR_IO_PENDING depending on whether or not the new proxy configuration is
198  // available synchronously or asynchronously.  Otherwise, the given error
199  // code is simply returned.
200  int ReconsiderProxyAfterError(int error);
201
202  // Decides the policy when the connection is closed before the end of headers
203  // has been read. This only applies to reading responses, and not writing
204  // requests.
205  int HandleConnectionClosedBeforeEndOfHeaders();
206
207  // Sets up the state machine to restart the transaction with auth.
208  void PrepareForAuthRestart(HttpAuth::Target target);
209
210  // Called when we don't need to drain the response body or have drained it.
211  // Resets |connection_| unless |keep_alive| is true, then calls
212  // ResetStateForRestart.  Sets |next_state_| appropriately.
213  void DidDrainBodyForAuthRestart(bool keep_alive);
214
215  // Resets the members of the transaction so it can be restarted.
216  void ResetStateForRestart();
217
218  // Returns true if we should try to add a Proxy-Authorization header
219  bool ShouldApplyProxyAuth() const;
220
221  // Returns true if we should try to add an Authorization header.
222  bool ShouldApplyServerAuth() const;
223
224  // Handles HTTP status code 401 or 407.
225  // HandleAuthChallenge() returns a network error code, or OK on success.
226  // May update |pending_auth_target_| or |response_.auth_challenge|.
227  int HandleAuthChallenge();
228
229  bool HaveAuth(HttpAuth::Target target) const {
230    return auth_controllers_[target].get() &&
231         auth_controllers_[target]->HaveAuth();
232  }
233
234  // Get the {scheme, host, path, port} for the authentication target
235  GURL AuthURL(HttpAuth::Target target) const;
236
237  void MarkBrokenAlternateProtocolAndFallback();
238
239  // Debug helper.
240  static std::string DescribeState(State state);
241
242  static bool g_ignore_certificate_errors;
243
244  scoped_refptr<HttpAuthController>
245      auth_controllers_[HttpAuth::AUTH_NUM_TARGETS];
246
247  // Whether this transaction is waiting for proxy auth, server auth, or is
248  // not waiting for any auth at all. |pending_auth_target_| is read and
249  // cleared by RestartWithAuth().
250  HttpAuth::Target pending_auth_target_;
251
252  CompletionCallbackImpl<HttpNetworkTransaction> io_callback_;
253  CompletionCallback* user_callback_;
254
255  scoped_refptr<HttpNetworkSession> session_;
256
257  BoundNetLog net_log_;
258  const HttpRequestInfo* request_;
259  HttpResponseInfo response_;
260
261  ProxyService::PacRequest* pac_request_;
262  ProxyInfo proxy_info_;
263
264  scoped_ptr<ClientSocketHandle> connection_;
265  scoped_ptr<HttpStream> http_stream_;
266  scoped_ptr<SpdyHttpStream> spdy_http_stream_;
267  bool reused_socket_;
268
269  // True if we've validated the headers that the stream parser has returned.
270  bool headers_valid_;
271
272  // True if we've logged the time of the first response byte.  Used to
273  // prevent logging across authentication activity where we see multiple
274  // responses.
275  bool logged_response_time_;
276
277  bool using_ssl_;     // True if handling a HTTPS request
278
279  // True if this network transaction is using SPDY instead of HTTP.
280  bool using_spdy_;
281
282  // The certificate error while using SPDY over SSL for insecure URLs.
283  int spdy_certificate_error_;
284
285  AlternateProtocolMode alternate_protocol_mode_;
286
287  // Only valid if |alternate_protocol_mode_| == kUsingAlternateProtocol.
288  HttpAlternateProtocols::Protocol alternate_protocol_;
289
290  SSLConfig ssl_config_;
291
292  std::string request_headers_;
293
294  // The size in bytes of the buffer we use to drain the response body that
295  // we want to throw away.  The response body is typically a small error
296  // page just a few hundred bytes long.
297  enum { kDrainBodyBufferSize = 1024 };
298
299  // User buffer and length passed to the Read method.
300  scoped_refptr<IOBuffer> read_buf_;
301  int read_buf_len_;
302
303  // The time the Start method was called.
304  base::Time start_time_;
305
306  // The next state in the state machine.
307  State next_state_;
308
309  // The hostname and port of the endpoint.  This is not necessarily the one
310  // specified by the URL, due to Alternate-Protocol or fixed testing ports.
311  HostPortPair endpoint_;
312
313  // True when the tunnel is in the process of being established - we can't
314  // read from the socket until the tunnel is done.
315  bool establishing_tunnel_;
316
317  DISALLOW_COPY_AND_ASSIGN(HttpNetworkTransaction);
318};
319
320}  // namespace net
321
322#endif  // NET_HTTP_HTTP_NETWORK_TRANSACTION_H_
323