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_NETWORK_TRANSACTION_H_
6#define NET_HTTP_HTTP_NETWORK_TRANSACTION_H_
7#pragma once
8
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/gtest_prod_util.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/time.h"
16#include "net/base/net_log.h"
17#include "net/base/request_priority.h"
18#include "net/base/ssl_config_service.h"
19#include "net/http/http_auth.h"
20#include "net/http/http_request_headers.h"
21#include "net/http/http_response_info.h"
22#include "net/http/http_stream_factory.h"
23#include "net/http/http_transaction.h"
24#include "net/proxy/proxy_service.h"
25
26namespace net {
27
28class HttpAuthController;
29class HttpNetworkSession;
30class HttpStream;
31class HttpStreamRequest;
32class IOBuffer;
33struct HttpRequestInfo;
34
35class HttpNetworkTransaction : public HttpTransaction,
36                               public HttpStreamRequest::Delegate {
37 public:
38  explicit HttpNetworkTransaction(HttpNetworkSession* session);
39
40  virtual ~HttpNetworkTransaction();
41
42  // HttpTransaction methods:
43  virtual int Start(const HttpRequestInfo* request_info,
44                    CompletionCallback* callback,
45                    const BoundNetLog& net_log);
46  virtual int RestartIgnoringLastError(CompletionCallback* callback);
47  virtual int RestartWithCertificate(X509Certificate* client_cert,
48                                     CompletionCallback* callback);
49  virtual int RestartWithAuth(const string16& username,
50                              const string16& password,
51                              CompletionCallback* callback);
52  virtual bool IsReadyToRestartForAuth();
53
54  virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
55  virtual void StopCaching() {}
56  virtual const HttpResponseInfo* GetResponseInfo() const;
57  virtual LoadState GetLoadState() const;
58  virtual uint64 GetUploadProgress() const;
59
60  // HttpStreamRequest::Delegate methods:
61  virtual void OnStreamReady(const SSLConfig& used_ssl_config,
62                             const ProxyInfo& used_proxy_info,
63                             HttpStream* stream);
64  virtual void OnStreamFailed(int status,
65                              const SSLConfig& used_ssl_config);
66  virtual void OnCertificateError(int status,
67                                  const SSLConfig& used_ssl_config,
68                                  const SSLInfo& ssl_info);
69  virtual void OnNeedsProxyAuth(
70      const HttpResponseInfo& response_info,
71      const SSLConfig& used_ssl_config,
72      const ProxyInfo& used_proxy_info,
73      HttpAuthController* auth_controller);
74  virtual void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
75                                 SSLCertRequestInfo* cert_info);
76  virtual void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info,
77                                          const SSLConfig& used_ssl_config,
78                                          const ProxyInfo& used_proxy_info,
79                                          HttpStream* stream);
80
81 private:
82  FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, ResetStateForRestart);
83  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateReceived);
84  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateSent);
85  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateOverflow);
86  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, FlowControlStallResume);
87
88  enum State {
89    STATE_CREATE_STREAM,
90    STATE_CREATE_STREAM_COMPLETE,
91    STATE_INIT_STREAM,
92    STATE_INIT_STREAM_COMPLETE,
93    STATE_GENERATE_PROXY_AUTH_TOKEN,
94    STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE,
95    STATE_GENERATE_SERVER_AUTH_TOKEN,
96    STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE,
97    STATE_BUILD_REQUEST,
98    STATE_BUILD_REQUEST_COMPLETE,
99    STATE_SEND_REQUEST,
100    STATE_SEND_REQUEST_COMPLETE,
101    STATE_READ_HEADERS,
102    STATE_READ_HEADERS_COMPLETE,
103    STATE_READ_BODY,
104    STATE_READ_BODY_COMPLETE,
105    STATE_DRAIN_BODY_FOR_AUTH_RESTART,
106    STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE,
107    STATE_NONE
108  };
109
110  bool is_https_request() const;
111
112  void DoCallback(int result);
113  void OnIOComplete(int result);
114
115  // Runs the state transition loop.
116  int DoLoop(int result);
117
118  // Each of these methods corresponds to a State value.  Those with an input
119  // argument receive the result from the previous state.  If a method returns
120  // ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
121  // next state method as the result arg.
122  int DoCreateStream();
123  int DoCreateStreamComplete(int result);
124  int DoInitStream();
125  int DoInitStreamComplete(int result);
126  int DoGenerateProxyAuthToken();
127  int DoGenerateProxyAuthTokenComplete(int result);
128  int DoGenerateServerAuthToken();
129  int DoGenerateServerAuthTokenComplete(int result);
130  int DoBuildRequest();
131  int DoBuildRequestComplete(int result);
132  int DoSendRequest();
133  int DoSendRequestComplete(int result);
134  int DoReadHeaders();
135  int DoReadHeadersComplete(int result);
136  int DoReadBody();
137  int DoReadBodyComplete(int result);
138  int DoDrainBodyForAuthRestart();
139  int DoDrainBodyForAuthRestartComplete(int result);
140
141  void BuildRequestHeaders(bool using_proxy);
142
143  // Record histogram of time until first byte of header is received.
144  void LogTransactionConnectedMetrics();
145
146  // Record histogram of latency (durations until last byte received).
147  void LogTransactionMetrics() const;
148
149  // Writes a log message to help debugging in the field when we block a proxy
150  // response to a CONNECT request.
151  void LogBlockedTunnelResponse(int response_code) const;
152
153  // Called to handle a client certificate request.
154  int HandleCertificateRequest(int error);
155
156  // Called to possibly recover from an SSL handshake error.  Sets next_state_
157  // and returns OK if recovering from the error.  Otherwise, the same error
158  // code is returned.
159  int HandleSSLHandshakeError(int error);
160
161  // Called to possibly recover from the given error.  Sets next_state_ and
162  // returns OK if recovering from the error.  Otherwise, the same error code
163  // is returned.
164  int HandleIOError(int error);
165
166  // Gets the response headers from the HttpStream.
167  HttpResponseHeaders* GetResponseHeaders() const;
168
169  // Called when we reached EOF or got an error.  Returns true if we should
170  // resend the request.  |error| is OK when we reached EOF.
171  bool ShouldResendRequest(int error) const;
172
173  // Resets the connection and the request headers for resend.  Called when
174  // ShouldResendRequest() is true.
175  void ResetConnectionAndRequestForResend();
176
177  // Decides the policy when the connection is closed before the end of headers
178  // has been read. This only applies to reading responses, and not writing
179  // requests.
180  int HandleConnectionClosedBeforeEndOfHeaders();
181
182  // Sets up the state machine to restart the transaction with auth.
183  void PrepareForAuthRestart(HttpAuth::Target target);
184
185  // Called when we don't need to drain the response body or have drained it.
186  // Resets |connection_| unless |keep_alive| is true, then calls
187  // ResetStateForRestart.  Sets |next_state_| appropriately.
188  void DidDrainBodyForAuthRestart(bool keep_alive);
189
190  // Resets the members of the transaction so it can be restarted.
191  void ResetStateForRestart();
192
193  // Resets the members of the transaction, except |stream_|, which needs
194  // to be maintained for multi-round auth.
195  void ResetStateForAuthRestart();
196
197  // Returns true if we should try to add a Proxy-Authorization header
198  bool ShouldApplyProxyAuth() const;
199
200  // Returns true if we should try to add an Authorization header.
201  bool ShouldApplyServerAuth() const;
202
203  // Handles HTTP status code 401 or 407.
204  // HandleAuthChallenge() returns a network error code, or OK on success.
205  // May update |pending_auth_target_| or |response_.auth_challenge|.
206  int HandleAuthChallenge();
207
208  // Returns true if we have auth credentials for the given target.
209  bool HaveAuth(HttpAuth::Target target) const;
210
211  // Get the {scheme, host, path, port} for the authentication target
212  GURL AuthURL(HttpAuth::Target target) const;
213
214  // Debug helper.
215  static std::string DescribeState(State state);
216
217  scoped_refptr<HttpAuthController>
218      auth_controllers_[HttpAuth::AUTH_NUM_TARGETS];
219
220  // Whether this transaction is waiting for proxy auth, server auth, or is
221  // not waiting for any auth at all. |pending_auth_target_| is read and
222  // cleared by RestartWithAuth().
223  HttpAuth::Target pending_auth_target_;
224
225  CompletionCallbackImpl<HttpNetworkTransaction> io_callback_;
226  scoped_refptr<CancelableCompletionCallback<HttpNetworkTransaction> >
227      delegate_callback_;
228  CompletionCallback* user_callback_;
229  scoped_ptr<UploadDataStream> request_body_;
230
231  scoped_refptr<HttpNetworkSession> session_;
232
233  BoundNetLog net_log_;
234  const HttpRequestInfo* request_;
235  HttpResponseInfo response_;
236
237  // |proxy_info_| is the ProxyInfo used by the HttpStreamRequest.
238  ProxyInfo proxy_info_;
239
240  scoped_ptr<HttpStreamRequest> stream_request_;
241  scoped_ptr<HttpStream> stream_;
242
243  // True if we've validated the headers that the stream parser has returned.
244  bool headers_valid_;
245
246  // True if we've logged the time of the first response byte.  Used to
247  // prevent logging across authentication activity where we see multiple
248  // responses.
249  bool logged_response_time_;
250
251  SSLConfig ssl_config_;
252
253  HttpRequestHeaders request_headers_;
254
255  // The size in bytes of the buffer we use to drain the response body that
256  // we want to throw away.  The response body is typically a small error
257  // page just a few hundred bytes long.
258  static const int kDrainBodyBufferSize = 1024;
259
260  // User buffer and length passed to the Read method.
261  scoped_refptr<IOBuffer> read_buf_;
262  int read_buf_len_;
263
264  // The time the Start method was called.
265  base::Time start_time_;
266
267  // The next state in the state machine.
268  State next_state_;
269
270  // True when the tunnel is in the process of being established - we can't
271  // read from the socket until the tunnel is done.
272  bool establishing_tunnel_;
273
274  DISALLOW_COPY_AND_ASSIGN(HttpNetworkTransaction);
275};
276
277}  // namespace net
278
279#endif  // NET_HTTP_HTTP_NETWORK_TRANSACTION_H_
280