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