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 ProxyInfo;
     35 class SpdySession;
     36 struct HttpRequestInfo;
     37 
     38 class 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