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