1// Copyright (c) 2012 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/gtest_prod_util.h"
12#include "base/memory/ref_counted.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/time/time.h"
15#include "net/base/net_log.h"
16#include "net/base/request_priority.h"
17#include "net/http/http_auth.h"
18#include "net/http/http_request_headers.h"
19#include "net/http/http_response_info.h"
20#include "net/http/http_stream_factory.h"
21#include "net/http/http_transaction.h"
22#include "net/proxy/proxy_service.h"
23#include "net/ssl/ssl_config_service.h"
24#include "net/websockets/websocket_handshake_stream_base.h"
25
26namespace net {
27
28class ClientSocketHandle;
29class HttpAuthController;
30class HttpNetworkSession;
31class HttpStreamBase;
32class HttpStreamRequest;
33class IOBuffer;
34class ProxyInfo;
35class SpdySession;
36struct HttpRequestInfo;
37
38class NET_EXPORT_PRIVATE HttpNetworkTransaction
39    : public HttpTransaction,
40      public HttpStreamRequest::Delegate {
41 public:
42  HttpNetworkTransaction(RequestPriority priority,
43                         HttpNetworkSession* session);
44
45  virtual ~HttpNetworkTransaction();
46
47  // HttpTransaction methods:
48  virtual int Start(const HttpRequestInfo* request_info,
49                    const CompletionCallback& callback,
50                    const BoundNetLog& net_log) OVERRIDE;
51  virtual int RestartIgnoringLastError(
52      const CompletionCallback& callback) OVERRIDE;
53  virtual int RestartWithCertificate(
54      X509Certificate* client_cert,
55      const CompletionCallback& callback) OVERRIDE;
56  virtual int RestartWithAuth(const AuthCredentials& credentials,
57                              const CompletionCallback& callback) OVERRIDE;
58  virtual bool IsReadyToRestartForAuth() OVERRIDE;
59
60  virtual int Read(IOBuffer* buf,
61                   int buf_len,
62                   const CompletionCallback& callback) OVERRIDE;
63  virtual void StopCaching() OVERRIDE;
64  virtual bool GetFullRequestHeaders(
65      HttpRequestHeaders* headers) const OVERRIDE;
66  virtual int64 GetTotalReceivedBytes() const OVERRIDE;
67  virtual void DoneReading() OVERRIDE;
68  virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE;
69  virtual LoadState GetLoadState() const OVERRIDE;
70  virtual UploadProgress GetUploadProgress() const OVERRIDE;
71  virtual void SetQuicServerInfo(QuicServerInfo* quic_server_info) OVERRIDE;
72  virtual bool GetLoadTimingInfo(
73      LoadTimingInfo* load_timing_info) const OVERRIDE;
74  virtual void SetPriority(RequestPriority priority) OVERRIDE;
75  virtual void SetWebSocketHandshakeStreamCreateHelper(
76      WebSocketHandshakeStreamBase::CreateHelper* create_helper) OVERRIDE;
77  virtual void SetBeforeNetworkStartCallback(
78      const BeforeNetworkStartCallback& callback) OVERRIDE;
79  virtual void SetBeforeProxyHeadersSentCallback(
80      const BeforeProxyHeadersSentCallback& callback) OVERRIDE;
81  virtual int ResumeNetworkStart() OVERRIDE;
82
83  // HttpStreamRequest::Delegate methods:
84  virtual void OnStreamReady(const SSLConfig& used_ssl_config,
85                             const ProxyInfo& used_proxy_info,
86                             HttpStreamBase* stream) OVERRIDE;
87  virtual void OnWebSocketHandshakeStreamReady(
88      const SSLConfig& used_ssl_config,
89      const ProxyInfo& used_proxy_info,
90      WebSocketHandshakeStreamBase* stream) OVERRIDE;
91  virtual void OnStreamFailed(int status,
92                              const SSLConfig& used_ssl_config) OVERRIDE;
93  virtual void OnCertificateError(int status,
94                                  const SSLConfig& used_ssl_config,
95                                  const SSLInfo& ssl_info) OVERRIDE;
96  virtual void OnNeedsProxyAuth(
97      const HttpResponseInfo& response_info,
98      const SSLConfig& used_ssl_config,
99      const ProxyInfo& used_proxy_info,
100      HttpAuthController* auth_controller) OVERRIDE;
101  virtual void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
102                                 SSLCertRequestInfo* cert_info) OVERRIDE;
103  virtual void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info,
104                                          const SSLConfig& used_ssl_config,
105                                          const ProxyInfo& used_proxy_info,
106                                          HttpStreamBase* stream) OVERRIDE;
107
108 private:
109  friend class HttpNetworkTransactionSSLTest;
110
111  FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
112                           ResetStateForRestart);
113  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
114                           WindowUpdateReceived);
115  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
116                           WindowUpdateSent);
117  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
118                           WindowUpdateOverflow);
119  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
120                           FlowControlStallResume);
121  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
122                           FlowControlStallResumeAfterSettings);
123  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
124                           FlowControlNegativeSendWindowSize);
125
126  enum State {
127    STATE_NOTIFY_BEFORE_CREATE_STREAM,
128    STATE_CREATE_STREAM,
129    STATE_CREATE_STREAM_COMPLETE,
130    STATE_INIT_STREAM,
131    STATE_INIT_STREAM_COMPLETE,
132    STATE_GENERATE_PROXY_AUTH_TOKEN,
133    STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE,
134    STATE_GENERATE_SERVER_AUTH_TOKEN,
135    STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE,
136    STATE_INIT_REQUEST_BODY,
137    STATE_INIT_REQUEST_BODY_COMPLETE,
138    STATE_BUILD_REQUEST,
139    STATE_BUILD_REQUEST_COMPLETE,
140    STATE_SEND_REQUEST,
141    STATE_SEND_REQUEST_COMPLETE,
142    STATE_READ_HEADERS,
143    STATE_READ_HEADERS_COMPLETE,
144    STATE_READ_BODY,
145    STATE_READ_BODY_COMPLETE,
146    STATE_DRAIN_BODY_FOR_AUTH_RESTART,
147    STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE,
148    STATE_NONE
149  };
150
151  bool is_https_request() const;
152
153  void DoCallback(int result);
154  void OnIOComplete(int result);
155
156  // Runs the state transition loop.
157  int DoLoop(int result);
158
159  // Each of these methods corresponds to a State value.  Those with an input
160  // argument receive the result from the previous state.  If a method returns
161  // ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
162  // next state method as the result arg.
163  int DoNotifyBeforeCreateStream();
164  int DoCreateStream();
165  int DoCreateStreamComplete(int result);
166  int DoInitStream();
167  int DoInitStreamComplete(int result);
168  int DoGenerateProxyAuthToken();
169  int DoGenerateProxyAuthTokenComplete(int result);
170  int DoGenerateServerAuthToken();
171  int DoGenerateServerAuthTokenComplete(int result);
172  int DoInitRequestBody();
173  int DoInitRequestBodyComplete(int result);
174  int DoBuildRequest();
175  int DoBuildRequestComplete(int result);
176  int DoSendRequest();
177  int DoSendRequestComplete(int result);
178  int DoReadHeaders();
179  int DoReadHeadersComplete(int result);
180  int DoReadBody();
181  int DoReadBodyComplete(int result);
182  int DoDrainBodyForAuthRestart();
183  int DoDrainBodyForAuthRestartComplete(int result);
184
185  void BuildRequestHeaders(bool using_proxy);
186
187  // Record histogram of time until first byte of header is received.
188  void LogTransactionConnectedMetrics();
189
190  // Record histogram of latency (durations until last byte received).
191  void LogTransactionMetrics() const;
192
193  // Writes a log message to help debugging in the field when we block a proxy
194  // response to a CONNECT request.
195  void LogBlockedTunnelResponse(int response_code) const;
196
197  // Called to handle a client certificate request.
198  int HandleCertificateRequest(int error);
199
200  // Called to possibly handle a client authentication error.
201  void HandleClientAuthError(int error);
202
203  // Called to possibly recover from an SSL handshake error.  Sets next_state_
204  // and returns OK if recovering from the error.  Otherwise, the same error
205  // code is returned.
206  int HandleSSLHandshakeError(int error);
207
208  // Called to possibly recover from the given error.  Sets next_state_ and
209  // returns OK if recovering from the error.  Otherwise, the same error code
210  // is returned.
211  int HandleIOError(int error);
212
213  // Gets the response headers from the HttpStream.
214  HttpResponseHeaders* GetResponseHeaders() const;
215
216  // Called when the socket is unexpectedly closed.  Returns true if the request
217  // should be resent in case of a socket reuse/close race.
218  bool ShouldResendRequest() const;
219
220  // Resets the connection and the request headers for resend.  Called when
221  // ShouldResendRequest() is true.
222  void ResetConnectionAndRequestForResend();
223
224  // Sets up the state machine to restart the transaction with auth.
225  void PrepareForAuthRestart(HttpAuth::Target target);
226
227  // Called when we don't need to drain the response body or have drained it.
228  // Resets |connection_| unless |keep_alive| is true, then calls
229  // ResetStateForRestart.  Sets |next_state_| appropriately.
230  void DidDrainBodyForAuthRestart(bool keep_alive);
231
232  // Resets the members of the transaction so it can be restarted.
233  void ResetStateForRestart();
234
235  // Resets the members of the transaction, except |stream_|, which needs
236  // to be maintained for multi-round auth.
237  void ResetStateForAuthRestart();
238
239  // Returns true if we should try to add a Proxy-Authorization header
240  bool ShouldApplyProxyAuth() const;
241
242  // Returns true if we should try to add an Authorization header.
243  bool ShouldApplyServerAuth() const;
244
245  // Handles HTTP status code 401 or 407.
246  // HandleAuthChallenge() returns a network error code, or OK on success.
247  // May update |pending_auth_target_| or |response_.auth_challenge|.
248  int HandleAuthChallenge();
249
250  // Returns true if we have auth credentials for the given target.
251  bool HaveAuth(HttpAuth::Target target) const;
252
253  // Get the {scheme, host, path, port} for the authentication target
254  GURL AuthURL(HttpAuth::Target target) const;
255
256  // Returns true if this transaction is for a WebSocket handshake
257  bool ForWebSocketHandshake() const;
258
259  // Debug helper.
260  static std::string DescribeState(State state);
261
262  void SetStream(HttpStreamBase* stream);
263
264  scoped_refptr<HttpAuthController>
265      auth_controllers_[HttpAuth::AUTH_NUM_TARGETS];
266
267  // Whether this transaction is waiting for proxy auth, server auth, or is
268  // not waiting for any auth at all. |pending_auth_target_| is read and
269  // cleared by RestartWithAuth().
270  HttpAuth::Target pending_auth_target_;
271
272  CompletionCallback io_callback_;
273  CompletionCallback callback_;
274
275  HttpNetworkSession* session_;
276
277  BoundNetLog net_log_;
278  const HttpRequestInfo* request_;
279  RequestPriority priority_;
280  HttpResponseInfo response_;
281
282  // |proxy_info_| is the ProxyInfo used by the HttpStreamRequest.
283  ProxyInfo proxy_info_;
284
285  scoped_ptr<HttpStreamRequest> stream_request_;
286  scoped_ptr<HttpStreamBase> stream_;
287
288  // True if we've validated the headers that the stream parser has returned.
289  bool headers_valid_;
290
291  // True if we've logged the time of the first response byte.  Used to
292  // prevent logging across authentication activity where we see multiple
293  // responses.
294  bool logged_response_time_;
295
296  SSLConfig server_ssl_config_;
297  SSLConfig proxy_ssl_config_;
298  // fallback_error_code contains the error code that caused the last TLS
299  // fallback. If the fallback connection results in
300  // ERR_SSL_INAPPROPRIATE_FALLBACK (i.e. the server indicated that the
301  // fallback should not have been needed) then we use this value to return the
302  // original error that triggered the fallback.
303  int fallback_error_code_;
304
305  HttpRequestHeaders request_headers_;
306
307  // The size in bytes of the buffer we use to drain the response body that
308  // we want to throw away.  The response body is typically a small error
309  // page just a few hundred bytes long.
310  static const int kDrainBodyBufferSize = 1024;
311
312  // User buffer and length passed to the Read method.
313  scoped_refptr<IOBuffer> read_buf_;
314  int read_buf_len_;
315
316  // Total number of bytes received on streams for this transaction.
317  int64 total_received_bytes_;
318
319  // The time the Start method was called.
320  base::Time start_time_;
321
322  // When the transaction started / finished sending the request, including
323  // the body, if present.
324  base::TimeTicks send_start_time_;
325  base::TimeTicks send_end_time_;
326
327  // The next state in the state machine.
328  State next_state_;
329
330  // True when the tunnel is in the process of being established - we can't
331  // read from the socket until the tunnel is done.
332  bool establishing_tunnel_;
333
334  // The helper object to use to create WebSocketHandshakeStreamBase
335  // objects. Only relevant when establishing a WebSocket connection.
336  WebSocketHandshakeStreamBase::CreateHelper*
337      websocket_handshake_stream_base_create_helper_;
338
339  BeforeNetworkStartCallback before_network_start_callback_;
340  BeforeProxyHeadersSentCallback before_proxy_headers_sent_callback_;
341
342  DISALLOW_COPY_AND_ASSIGN(HttpNetworkTransaction);
343};
344
345}  // namespace net
346
347#endif  // NET_HTTP_HTTP_NETWORK_TRANSACTION_H_
348