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