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