Home | History | Annotate | Download | only in http
      1 // Copyright (c) 2006-2009 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/ref_counted.h"
     12 #include "base/scoped_ptr.h"
     13 #include "base/time.h"
     14 #include "net/base/address_list.h"
     15 #include "net/base/host_resolver.h"
     16 #include "net/base/io_buffer.h"
     17 #include "net/base/load_flags.h"
     18 #include "net/base/load_states.h"
     19 #include "net/base/ssl_config_service.h"
     20 #include "net/http/http_auth.h"
     21 #include "net/http/http_auth_handler.h"
     22 #include "net/http/http_response_info.h"
     23 #include "net/http/http_transaction.h"
     24 #include "net/proxy/proxy_service.h"
     25 #include "net/socket/client_socket_pool.h"
     26 #include "testing/gtest/include/gtest/gtest_prod.h"
     27 
     28 namespace net {
     29 
     30 class ClientSocketFactory;
     31 class ClientSocketHandle;
     32 class FlipStream;
     33 class HttpNetworkSession;
     34 class HttpStream;
     35 
     36 class HttpNetworkTransaction : public HttpTransaction {
     37  public:
     38   explicit HttpNetworkTransaction(HttpNetworkSession* session);
     39 
     40   virtual ~HttpNetworkTransaction();
     41 
     42   // Sets the next protocol negotiation value used during the SSL handshake.
     43   static void SetNextProtos(const std::string& next_protos);
     44 
     45   // HttpTransaction methods:
     46   virtual int Start(const HttpRequestInfo* request_info,
     47                     CompletionCallback* callback,
     48                     LoadLog* load_log);
     49   virtual int RestartIgnoringLastError(CompletionCallback* callback);
     50   virtual int RestartWithCertificate(X509Certificate* client_cert,
     51                                      CompletionCallback* callback);
     52   virtual int RestartWithAuth(const std::wstring& username,
     53                               const std::wstring& password,
     54                               CompletionCallback* callback);
     55   virtual bool IsReadyToRestartForAuth() {
     56     return pending_auth_target_ != HttpAuth::AUTH_NONE &&
     57         HaveAuth(pending_auth_target_);
     58   }
     59 
     60   virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
     61   virtual const HttpResponseInfo* GetResponseInfo() const;
     62   virtual LoadState GetLoadState() const;
     63   virtual uint64 GetUploadProgress() const;
     64 
     65  private:
     66   FRIEND_TEST(HttpNetworkTransactionTest, ResetStateForRestart);
     67 
     68   enum State {
     69     STATE_RESOLVE_PROXY,
     70     STATE_RESOLVE_PROXY_COMPLETE,
     71     STATE_INIT_CONNECTION,
     72     STATE_INIT_CONNECTION_COMPLETE,
     73     STATE_SOCKS_CONNECT,
     74     STATE_SOCKS_CONNECT_COMPLETE,
     75     STATE_SSL_CONNECT,
     76     STATE_SSL_CONNECT_COMPLETE,
     77     STATE_SEND_REQUEST,
     78     STATE_SEND_REQUEST_COMPLETE,
     79     STATE_READ_HEADERS,
     80     STATE_READ_HEADERS_COMPLETE,
     81     STATE_READ_BODY,
     82     STATE_READ_BODY_COMPLETE,
     83     STATE_DRAIN_BODY_FOR_AUTH_RESTART,
     84     STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE,
     85     STATE_SPDY_SEND_REQUEST,
     86     STATE_SPDY_SEND_REQUEST_COMPLETE,
     87     STATE_SPDY_READ_HEADERS,
     88     STATE_SPDY_READ_HEADERS_COMPLETE,
     89     STATE_SPDY_READ_BODY,
     90     STATE_SPDY_READ_BODY_COMPLETE,
     91     STATE_NONE
     92   };
     93 
     94   enum ProxyMode {
     95     kDirectConnection,  // If using a direct connection
     96     kHTTPProxy,  // If using a proxy for HTTP (not HTTPS)
     97     kHTTPProxyUsingTunnel,  // If using a tunnel for HTTPS
     98     kSOCKSProxy,  // If using a SOCKS proxy
     99   };
    100 
    101   void DoCallback(int result);
    102   void OnIOComplete(int result);
    103 
    104   // Runs the state transition loop.
    105   int DoLoop(int result);
    106 
    107   // Each of these methods corresponds to a State value.  Those with an input
    108   // argument receive the result from the previous state.  If a method returns
    109   // ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
    110   // next state method as the result arg.
    111   int DoResolveProxy();
    112   int DoResolveProxyComplete(int result);
    113   int DoInitConnection();
    114   int DoInitConnectionComplete(int result);
    115   int DoSOCKSConnect();
    116   int DoSOCKSConnectComplete(int result);
    117   int DoSSLConnect();
    118   int DoSSLConnectComplete(int result);
    119   int DoSendRequest();
    120   int DoSendRequestComplete(int result);
    121   int DoReadHeaders();
    122   int DoReadHeadersComplete(int result);
    123   int DoReadBody();
    124   int DoReadBodyComplete(int result);
    125   int DoDrainBodyForAuthRestart();
    126   int DoDrainBodyForAuthRestartComplete(int result);
    127   int DoSpdySendRequest();
    128   int DoSpdySendRequestComplete(int result);
    129   int DoSpdyReadHeaders();
    130   int DoSpdyReadHeadersComplete(int result);
    131   int DoSpdyReadBody();
    132   int DoSpdyReadBodyComplete(int result);
    133 
    134   // Record histograms of latency until Connect() completes.
    135   static void LogTCPConnectedMetrics(const ClientSocketHandle& handle);
    136 
    137   // Record histogram of time until first byte of header is received.
    138   void LogTransactionConnectedMetrics() const;
    139 
    140   // Record histogram of latency (durations until last byte received).
    141   void LogTransactionMetrics() const;
    142 
    143   // Writes a log message to help debugging in the field when we block a proxy
    144   // response to a CONNECT request.
    145   void LogBlockedTunnelResponse(int response_code) const;
    146 
    147   static void LogIOErrorMetrics(const ClientSocketHandle& handle);
    148 
    149   // Called to handle a certificate error.  Returns OK if the error should be
    150   // ignored.  Otherwise, stores the certificate in response_.ssl_info and
    151   // returns the same error code.
    152   int HandleCertificateError(int error);
    153 
    154   // Called to handle a client certificate request.
    155   int HandleCertificateRequest(int error);
    156 
    157   // Called to possibly recover from an SSL handshake error.  Sets next_state_
    158   // and returns OK if recovering from the error.  Otherwise, the same error
    159   // code is returned.
    160   int HandleSSLHandshakeError(int error);
    161 
    162   // Called to possibly recover from the given error.  Sets next_state_ and
    163   // returns OK if recovering from the error.  Otherwise, the same error code
    164   // is returned.
    165   int HandleIOError(int error);
    166 
    167   // Gets the response headers from the HttpStream.
    168   HttpResponseHeaders* GetResponseHeaders() const;
    169 
    170   // Called when we reached EOF or got an error.  Returns true if we should
    171   // resend the request.  |error| is OK when we reached EOF.
    172   bool ShouldResendRequest(int error) const;
    173 
    174   // Resets the connection and the request headers for resend.  Called when
    175   // ShouldResendRequest() is true.
    176   void ResetConnectionAndRequestForResend();
    177 
    178   // Called when we encounter a network error that could be resolved by trying
    179   // a new proxy configuration.  If there is another proxy configuration to try
    180   // then this method sets next_state_ appropriately and returns either OK or
    181   // ERR_IO_PENDING depending on whether or not the new proxy configuration is
    182   // available synchronously or asynchronously.  Otherwise, the given error
    183   // code is simply returned.
    184   int ReconsiderProxyAfterError(int error);
    185 
    186   // Decides the policy when the connection is closed before the end of headers
    187   // has been read. This only applies to reading responses, and not writing
    188   // requests.
    189   int HandleConnectionClosedBeforeEndOfHeaders();
    190 
    191   // Sets up the state machine to restart the transaction with auth.
    192   void PrepareForAuthRestart(HttpAuth::Target target);
    193 
    194   // Called when we don't need to drain the response body or have drained it.
    195   // Resets |connection_| unless |keep_alive| is true, then calls
    196   // ResetStateForRestart.  Sets |next_state_| appropriately.
    197   void DidDrainBodyForAuthRestart(bool keep_alive);
    198 
    199   // Resets the members of the transaction so it can be restarted.
    200   void ResetStateForRestart();
    201 
    202   // Returns true if we should try to add a Proxy-Authorization header
    203   bool ShouldApplyProxyAuth() const;
    204 
    205   // Returns true if we should try to add an Authorization header.
    206   bool ShouldApplyServerAuth() const;
    207 
    208   // Builds either the proxy auth header, or the origin server auth header,
    209   // as specified by |target|.
    210   std::string BuildAuthorizationHeader(HttpAuth::Target target) const;
    211 
    212   // Returns a log message for all the response headers related to the auth
    213   // challenge.
    214   std::string AuthChallengeLogMessage() const;
    215 
    216   // Handles HTTP status code 401 or 407.
    217   // HandleAuthChallenge() returns a network error code, or OK on success.
    218   // May update |pending_auth_target_| or |response_.auth_challenge|.
    219   int HandleAuthChallenge();
    220 
    221   // Populates response_.auth_challenge with the challenge information, so that
    222   // URLRequestHttpJob can prompt for a username/password.
    223   void PopulateAuthChallenge(HttpAuth::Target target,
    224                              const GURL& auth_origin);
    225 
    226   // Invalidates any auth cache entries after authentication has failed.
    227   // The identity that was rejected is auth_identity_[target].
    228   void InvalidateRejectedAuthFromCache(HttpAuth::Target target,
    229                                        const GURL& auth_origin);
    230 
    231   // Sets auth_identity_[target] to the next identity that the transaction
    232   // should try. It chooses candidates by searching the auth cache
    233   // and the URL for a username:password. Returns true if an identity
    234   // was found.
    235   bool SelectNextAuthIdentityToTry(HttpAuth::Target target,
    236                                    const GURL& auth_origin);
    237 
    238   // Searches the auth cache for an entry that encompasses the request's path.
    239   // If such an entry is found, updates auth_identity_[target] and
    240   // auth_handler_[target] with the cache entry's data and returns true.
    241   bool SelectPreemptiveAuth(HttpAuth::Target target);
    242 
    243   bool HaveAuth(HttpAuth::Target target) const {
    244     return auth_handler_[target].get() && !auth_identity_[target].invalid;
    245   }
    246 
    247   // Get the {scheme, host, port} for the authentication target
    248   GURL AuthOrigin(HttpAuth::Target target) const;
    249 
    250   // Get the absolute path of the resource needing authentication.
    251   // For proxy authentication the path is always empty string.
    252   std::string AuthPath(HttpAuth::Target target) const;
    253 
    254   // Returns a string representation of a HttpAuth::Target value that can be
    255   // used in log messages.
    256   static std::string AuthTargetString(HttpAuth::Target target);
    257 
    258   static std::string* g_next_protos;
    259 
    260   // The following three auth members are arrays of size two -- index 0 is
    261   // for the proxy server, and index 1 is for the origin server.
    262   // Use the enum HttpAuth::Target to index into them.
    263 
    264   // auth_handler encapsulates the logic for the particular auth-scheme.
    265   // This includes the challenge's parameters. If NULL, then there is no
    266   // associated auth handler.
    267   scoped_refptr<HttpAuthHandler> auth_handler_[2];
    268 
    269   // auth_identity_ holds the (username/password) that should be used by
    270   // the auth_handler_ to generate credentials. This identity can come from
    271   // a number of places (url, cache, prompt).
    272   HttpAuth::Identity auth_identity_[2];
    273 
    274   // Whether this transaction is waiting for proxy auth, server auth, or is
    275   // not waiting for any auth at all. |pending_auth_target_| is read and
    276   // cleared by RestartWithAuth().
    277   HttpAuth::Target pending_auth_target_;
    278 
    279   CompletionCallbackImpl<HttpNetworkTransaction> io_callback_;
    280   CompletionCallback* user_callback_;
    281 
    282   scoped_refptr<HttpNetworkSession> session_;
    283 
    284   scoped_refptr<LoadLog> load_log_;
    285   const HttpRequestInfo* request_;
    286   HttpResponseInfo response_;
    287 
    288   ProxyService::PacRequest* pac_request_;
    289   ProxyInfo proxy_info_;
    290 
    291   scoped_ptr<ClientSocketHandle> connection_;
    292   scoped_ptr<HttpStream> http_stream_;
    293   scoped_refptr<FlipStream> spdy_stream_;
    294   bool reused_socket_;
    295 
    296   // True if we've validated the headers that the stream parser has returned.
    297   bool headers_valid_;
    298 
    299   // True if we've logged the time of the first response byte.  Used to
    300   // prevent logging across authentication activity where we see multiple
    301   // responses.
    302   bool logged_response_time;
    303 
    304   bool using_ssl_;     // True if handling a HTTPS request
    305   ProxyMode proxy_mode_;
    306 
    307   // True while establishing a tunnel.  This allows the HTTP CONNECT
    308   // request/response to reuse the STATE_SEND_REQUEST,
    309   // STATE_SEND_REQUEST_COMPLETE, STATE_READ_HEADERS, and
    310   // STATE_READ_HEADERS_COMPLETE states and allows us to tell them apart from
    311   // the real request/response of the transaction.
    312   bool establishing_tunnel_;
    313 
    314   // True if we've used the username/password embedded in the URL.  This
    315   // makes sure we use the embedded identity only once for the transaction,
    316   // preventing an infinite auth restart loop.
    317   bool embedded_identity_used_;
    318 
    319   SSLConfig ssl_config_;
    320 
    321   std::string request_headers_;
    322 
    323   // The size in bytes of the buffer we use to drain the response body that
    324   // we want to throw away.  The response body is typically a small error
    325   // page just a few hundred bytes long.
    326   enum { kDrainBodyBufferSize = 1024 };
    327 
    328   // User buffer and length passed to the Read method.
    329   scoped_refptr<IOBuffer> read_buf_;
    330   int read_buf_len_;
    331 
    332   // The time the Start method was called.
    333   base::Time start_time_;
    334 
    335   // The time the DoSSLConnect() method was called (if it got called).
    336   base::TimeTicks ssl_connect_start_time_;
    337 
    338   // The next state in the state machine.
    339   State next_state_;
    340 };
    341 
    342 }  // namespace net
    343 
    344 #endif  // NET_HTTP_HTTP_NETWORK_TRANSACTION_H_
    345