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 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