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