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