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