| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/http/http_network_transaction.h" | 5 #include "net/http/http_network_transaction.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 #include "net/spdy/spdy_session_pool.h" | 60 #include "net/spdy/spdy_session_pool.h" |
| 61 #include "net/ssl/ssl_cert_request_info.h" | 61 #include "net/ssl/ssl_cert_request_info.h" |
| 62 #include "net/ssl/ssl_connection_status_flags.h" | 62 #include "net/ssl/ssl_connection_status_flags.h" |
| 63 #include "url/gurl.h" | 63 #include "url/gurl.h" |
| 64 | 64 |
| 65 #if defined(SPDY_PROXY_AUTH_ORIGIN) | 65 #if defined(SPDY_PROXY_AUTH_ORIGIN) |
| 66 #include <algorithm> | 66 #include <algorithm> |
| 67 #include "net/proxy/proxy_server.h" | 67 #include "net/proxy/proxy_server.h" |
| 68 #endif | 68 #endif |
| 69 | 69 |
| 70 | |
| 71 using base::Time; | 70 using base::Time; |
| 72 using base::TimeDelta; | 71 using base::TimeDelta; |
| 73 | 72 |
| 74 namespace net { | 73 namespace net { |
| 75 | 74 |
| 76 namespace { | 75 namespace { |
| 77 | 76 |
| 78 void ProcessAlternateProtocol( | 77 void ProcessAlternateProtocol( |
| 79 HttpStreamFactory* factory, | 78 HttpStreamFactory* factory, |
| 80 const base::WeakPtr<HttpServerProperties>& http_server_properties, | 79 const base::WeakPtr<HttpServerProperties>& http_server_properties, |
| 81 const HttpResponseHeaders& headers, | 80 const HttpResponseHeaders& headers, |
| 82 const HostPortPair& http_host_port_pair) { | 81 const HostPortPair& http_host_port_pair) { |
| 83 std::string alternate_protocol_str; | 82 std::string alternate_protocol_str; |
| 84 | 83 |
| 85 if (!headers.EnumerateHeader(NULL, kAlternateProtocolHeader, | 84 if (!headers.EnumerateHeader( |
| 86 &alternate_protocol_str)) { | 85 NULL, kAlternateProtocolHeader, &alternate_protocol_str)) { |
| 87 // Header is not present. | 86 // Header is not present. |
| 88 return; | 87 return; |
| 89 } | 88 } |
| 90 | 89 |
| 91 factory->ProcessAlternateProtocol(http_server_properties, | 90 factory->ProcessAlternateProtocol( |
| 92 alternate_protocol_str, | 91 http_server_properties, alternate_protocol_str, http_host_port_pair); |
| 93 http_host_port_pair); | |
| 94 } | 92 } |
| 95 | 93 |
| 96 // Returns true if |error| is a client certificate authentication error. | 94 // Returns true if |error| is a client certificate authentication error. |
| 97 bool IsClientCertificateError(int error) { | 95 bool IsClientCertificateError(int error) { |
| 98 switch (error) { | 96 switch (error) { |
| 99 case ERR_BAD_SSL_CLIENT_AUTH_CERT: | 97 case ERR_BAD_SSL_CLIENT_AUTH_CERT: |
| 100 case ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED: | 98 case ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED: |
| 101 case ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY: | 99 case ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY: |
| 102 case ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED: | 100 case ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED: |
| 103 return true; | 101 return true; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 } | 146 } |
| 149 proxy_ssl_config_ = server_ssl_config_; | 147 proxy_ssl_config_ = server_ssl_config_; |
| 150 } | 148 } |
| 151 | 149 |
| 152 HttpNetworkTransaction::~HttpNetworkTransaction() { | 150 HttpNetworkTransaction::~HttpNetworkTransaction() { |
| 153 if (stream_.get()) { | 151 if (stream_.get()) { |
| 154 HttpResponseHeaders* headers = GetResponseHeaders(); | 152 HttpResponseHeaders* headers = GetResponseHeaders(); |
| 155 // TODO(mbelshe): The stream_ should be able to compute whether or not the | 153 // TODO(mbelshe): The stream_ should be able to compute whether or not the |
| 156 // stream should be kept alive. No reason to compute here | 154 // stream should be kept alive. No reason to compute here |
| 157 // and pass it in. | 155 // and pass it in. |
| 158 bool try_to_keep_alive = | 156 bool try_to_keep_alive = next_state_ == STATE_NONE && |
| 159 next_state_ == STATE_NONE && | 157 stream_->CanFindEndOfResponse() && |
| 160 stream_->CanFindEndOfResponse() && | 158 (!headers || headers->IsKeepAlive()); |
| 161 (!headers || headers->IsKeepAlive()); | |
| 162 if (!try_to_keep_alive) { | 159 if (!try_to_keep_alive) { |
| 163 stream_->Close(true /* not reusable */); | 160 stream_->Close(true /* not reusable */); |
| 164 } else { | 161 } else { |
| 165 if (stream_->IsResponseBodyComplete()) { | 162 if (stream_->IsResponseBodyComplete()) { |
| 166 // If the response body is complete, we can just reuse the socket. | 163 // If the response body is complete, we can just reuse the socket. |
| 167 stream_->Close(false /* reusable */); | 164 stream_->Close(false /* reusable */); |
| 168 } else if (stream_->IsSpdyHttpStream()) { | 165 } else if (stream_->IsSpdyHttpStream()) { |
| 169 // Doesn't really matter for SpdyHttpStream. Just close it. | 166 // Doesn't really matter for SpdyHttpStream. Just close it. |
| 170 stream_->Close(true /* not reusable */); | 167 stream_->Close(true /* not reusable */); |
| 171 } else { | 168 } else { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 189 request_ = request_info; | 186 request_ = request_info; |
| 190 start_time_ = base::Time::Now(); | 187 start_time_ = base::Time::Now(); |
| 191 | 188 |
| 192 if (request_->load_flags & LOAD_DISABLE_CERT_REVOCATION_CHECKING) { | 189 if (request_->load_flags & LOAD_DISABLE_CERT_REVOCATION_CHECKING) { |
| 193 server_ssl_config_.rev_checking_enabled = false; | 190 server_ssl_config_.rev_checking_enabled = false; |
| 194 proxy_ssl_config_.rev_checking_enabled = false; | 191 proxy_ssl_config_.rev_checking_enabled = false; |
| 195 } | 192 } |
| 196 | 193 |
| 197 // Channel ID is disabled if privacy mode is enabled for this request. | 194 // Channel ID is disabled if privacy mode is enabled for this request. |
| 198 bool channel_id_enabled = server_ssl_config_.channel_id_enabled && | 195 bool channel_id_enabled = server_ssl_config_.channel_id_enabled && |
| 199 (request_->privacy_mode == PRIVACY_MODE_DISABLED); | 196 (request_->privacy_mode == PRIVACY_MODE_DISABLED); |
| 200 server_ssl_config_.channel_id_enabled = channel_id_enabled; | 197 server_ssl_config_.channel_id_enabled = channel_id_enabled; |
| 201 | 198 |
| 202 next_state_ = STATE_NOTIFY_BEFORE_CREATE_STREAM; | 199 next_state_ = STATE_NOTIFY_BEFORE_CREATE_STREAM; |
| 203 int rv = DoLoop(OK); | 200 int rv = DoLoop(OK); |
| 204 if (rv == ERR_IO_PENDING) | 201 if (rv == ERR_IO_PENDING) |
| 205 callback_ = callback; | 202 callback_ = callback; |
| 206 return rv; | 203 return rv; |
| 207 } | 204 } |
| 208 | 205 |
| 209 int HttpNetworkTransaction::RestartIgnoringLastError( | 206 int HttpNetworkTransaction::RestartIgnoringLastError( |
| 210 const CompletionCallback& callback) { | 207 const CompletionCallback& callback) { |
| 211 DCHECK(!stream_.get()); | 208 DCHECK(!stream_.get()); |
| 212 DCHECK(!stream_request_.get()); | 209 DCHECK(!stream_request_.get()); |
| 213 DCHECK_EQ(STATE_NONE, next_state_); | 210 DCHECK_EQ(STATE_NONE, next_state_); |
| 214 | 211 |
| 215 next_state_ = STATE_CREATE_STREAM; | 212 next_state_ = STATE_CREATE_STREAM; |
| 216 | 213 |
| 217 int rv = DoLoop(OK); | 214 int rv = DoLoop(OK); |
| 218 if (rv == ERR_IO_PENDING) | 215 if (rv == ERR_IO_PENDING) |
| 219 callback_ = callback; | 216 callback_ = callback; |
| 220 return rv; | 217 return rv; |
| 221 } | 218 } |
| 222 | 219 |
| 223 int HttpNetworkTransaction::RestartWithCertificate( | 220 int HttpNetworkTransaction::RestartWithCertificate( |
| 224 X509Certificate* client_cert, const CompletionCallback& callback) { | 221 X509Certificate* client_cert, |
| 222 const CompletionCallback& callback) { |
| 225 // In HandleCertificateRequest(), we always tear down existing stream | 223 // In HandleCertificateRequest(), we always tear down existing stream |
| 226 // requests to force a new connection. So we shouldn't have one here. | 224 // requests to force a new connection. So we shouldn't have one here. |
| 227 DCHECK(!stream_request_.get()); | 225 DCHECK(!stream_request_.get()); |
| 228 DCHECK(!stream_.get()); | 226 DCHECK(!stream_.get()); |
| 229 DCHECK_EQ(STATE_NONE, next_state_); | 227 DCHECK_EQ(STATE_NONE, next_state_); |
| 230 | 228 |
| 231 SSLConfig* ssl_config = response_.cert_request_info->is_proxy ? | 229 SSLConfig* ssl_config = response_.cert_request_info->is_proxy |
| 232 &proxy_ssl_config_ : &server_ssl_config_; | 230 ? &proxy_ssl_config_ |
| 231 : &server_ssl_config_; |
| 233 ssl_config->send_client_cert = true; | 232 ssl_config->send_client_cert = true; |
| 234 ssl_config->client_cert = client_cert; | 233 ssl_config->client_cert = client_cert; |
| 235 session_->ssl_client_auth_cache()->Add( | 234 session_->ssl_client_auth_cache()->Add( |
| 236 response_.cert_request_info->host_and_port, client_cert); | 235 response_.cert_request_info->host_and_port, client_cert); |
| 237 // Reset the other member variables. | 236 // Reset the other member variables. |
| 238 // Note: this is necessary only with SSL renegotiation. | 237 // Note: this is necessary only with SSL renegotiation. |
| 239 ResetStateForRestart(); | 238 ResetStateForRestart(); |
| 240 next_state_ = STATE_CREATE_STREAM; | 239 next_state_ = STATE_CREATE_STREAM; |
| 241 int rv = DoLoop(OK); | 240 int rv = DoLoop(OK); |
| 242 if (rv == ERR_IO_PENDING) | 241 if (rv == ERR_IO_PENDING) |
| 243 callback_ = callback; | 242 callback_ = callback; |
| 244 return rv; | 243 return rv; |
| 245 } | 244 } |
| 246 | 245 |
| 247 int HttpNetworkTransaction::RestartWithAuth( | 246 int HttpNetworkTransaction::RestartWithAuth( |
| 248 const AuthCredentials& credentials, const CompletionCallback& callback) { | 247 const AuthCredentials& credentials, |
| 248 const CompletionCallback& callback) { |
| 249 HttpAuth::Target target = pending_auth_target_; | 249 HttpAuth::Target target = pending_auth_target_; |
| 250 if (target == HttpAuth::AUTH_NONE) { | 250 if (target == HttpAuth::AUTH_NONE) { |
| 251 NOTREACHED(); | 251 NOTREACHED(); |
| 252 return ERR_UNEXPECTED; | 252 return ERR_UNEXPECTED; |
| 253 } | 253 } |
| 254 pending_auth_target_ = HttpAuth::AUTH_NONE; | 254 pending_auth_target_ = HttpAuth::AUTH_NONE; |
| 255 | 255 |
| 256 auth_controllers_[target]->ResetAuth(credentials); | 256 auth_controllers_[target]->ResetAuth(credentials); |
| 257 | 257 |
| 258 DCHECK(callback_.is_null()); | 258 DCHECK(callback_.is_null()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 279 return rv; | 279 return rv; |
| 280 } | 280 } |
| 281 | 281 |
| 282 void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) { | 282 void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) { |
| 283 DCHECK(HaveAuth(target)); | 283 DCHECK(HaveAuth(target)); |
| 284 DCHECK(!stream_request_.get()); | 284 DCHECK(!stream_request_.get()); |
| 285 | 285 |
| 286 bool keep_alive = false; | 286 bool keep_alive = false; |
| 287 // Even if the server says the connection is keep-alive, we have to be | 287 // Even if the server says the connection is keep-alive, we have to be |
| 288 // able to find the end of each response in order to reuse the connection. | 288 // able to find the end of each response in order to reuse the connection. |
| 289 if (GetResponseHeaders()->IsKeepAlive() && | 289 if (GetResponseHeaders()->IsKeepAlive() && stream_->CanFindEndOfResponse()) { |
| 290 stream_->CanFindEndOfResponse()) { | |
| 291 // If the response body hasn't been completely read, we need to drain | 290 // If the response body hasn't been completely read, we need to drain |
| 292 // it first. | 291 // it first. |
| 293 if (!stream_->IsResponseBodyComplete()) { | 292 if (!stream_->IsResponseBodyComplete()) { |
| 294 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART; | 293 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART; |
| 295 read_buf_ = new IOBuffer(kDrainBodyBufferSize); // A bit bucket. | 294 read_buf_ = new IOBuffer(kDrainBodyBufferSize); // A bit bucket. |
| 296 read_buf_len_ = kDrainBodyBufferSize; | 295 read_buf_len_ = kDrainBodyBufferSize; |
| 297 return; | 296 return; |
| 298 } | 297 } |
| 299 keep_alive = true; | 298 keep_alive = true; |
| 300 } | 299 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 331 } | 330 } |
| 332 stream_.reset(new_stream); | 331 stream_.reset(new_stream); |
| 333 } | 332 } |
| 334 | 333 |
| 335 // Reset the other member variables. | 334 // Reset the other member variables. |
| 336 ResetStateForAuthRestart(); | 335 ResetStateForAuthRestart(); |
| 337 } | 336 } |
| 338 | 337 |
| 339 bool HttpNetworkTransaction::IsReadyToRestartForAuth() { | 338 bool HttpNetworkTransaction::IsReadyToRestartForAuth() { |
| 340 return pending_auth_target_ != HttpAuth::AUTH_NONE && | 339 return pending_auth_target_ != HttpAuth::AUTH_NONE && |
| 341 HaveAuth(pending_auth_target_); | 340 HaveAuth(pending_auth_target_); |
| 342 } | 341 } |
| 343 | 342 |
| 344 int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len, | 343 int HttpNetworkTransaction::Read(IOBuffer* buf, |
| 344 int buf_len, |
| 345 const CompletionCallback& callback) { | 345 const CompletionCallback& callback) { |
| 346 DCHECK(buf); | 346 DCHECK(buf); |
| 347 DCHECK_LT(0, buf_len); | 347 DCHECK_LT(0, buf_len); |
| 348 | 348 |
| 349 State next_state = STATE_NONE; | 349 State next_state = STATE_NONE; |
| 350 | 350 |
| 351 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders()); | 351 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders()); |
| 352 if (headers_valid_ && headers.get() && stream_request_.get()) { | 352 if (headers_valid_ && headers.get() && stream_request_.get()) { |
| 353 // We're trying to read the body of the response but we're still trying | 353 // We're trying to read the body of the response but we're still trying |
| 354 // to establish an SSL tunnel through an HTTP proxy. We can't read these | 354 // to establish an SSL tunnel through an HTTP proxy. We can't read these |
| (...skipping 18 matching lines...) Expand all Loading... |
| 373 read_buf_ = buf; | 373 read_buf_ = buf; |
| 374 read_buf_len_ = buf_len; | 374 read_buf_len_ = buf_len; |
| 375 | 375 |
| 376 next_state_ = next_state; | 376 next_state_ = next_state; |
| 377 int rv = DoLoop(OK); | 377 int rv = DoLoop(OK); |
| 378 if (rv == ERR_IO_PENDING) | 378 if (rv == ERR_IO_PENDING) |
| 379 callback_ = callback; | 379 callback_ = callback; |
| 380 return rv; | 380 return rv; |
| 381 } | 381 } |
| 382 | 382 |
| 383 void HttpNetworkTransaction::StopCaching() {} | 383 void HttpNetworkTransaction::StopCaching() { |
| 384 } |
| 384 | 385 |
| 385 bool HttpNetworkTransaction::GetFullRequestHeaders( | 386 bool HttpNetworkTransaction::GetFullRequestHeaders( |
| 386 HttpRequestHeaders* headers) const { | 387 HttpRequestHeaders* headers) const { |
| 387 // TODO(ttuttle): Make sure we've populated request_headers_. | 388 // TODO(ttuttle): Make sure we've populated request_headers_. |
| 388 *headers = request_headers_; | 389 *headers = request_headers_; |
| 389 return true; | 390 return true; |
| 390 } | 391 } |
| 391 | 392 |
| 392 int64 HttpNetworkTransaction::GetTotalReceivedBytes() const { | 393 int64 HttpNetworkTransaction::GetTotalReceivedBytes() const { |
| 393 int64 total_received_bytes = total_received_bytes_; | 394 int64 total_received_bytes = total_received_bytes_; |
| 394 if (stream_) | 395 if (stream_) |
| 395 total_received_bytes += stream_->GetTotalReceivedBytes(); | 396 total_received_bytes += stream_->GetTotalReceivedBytes(); |
| 396 return total_received_bytes; | 397 return total_received_bytes; |
| 397 } | 398 } |
| 398 | 399 |
| 399 void HttpNetworkTransaction::DoneReading() {} | 400 void HttpNetworkTransaction::DoneReading() { |
| 401 } |
| 400 | 402 |
| 401 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { | 403 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { |
| 402 return ((headers_valid_ && response_.headers.get()) || | 404 return ((headers_valid_ && response_.headers.get()) || |
| 403 response_.ssl_info.cert.get() || response_.cert_request_info.get()) | 405 response_.ssl_info.cert.get() || response_.cert_request_info.get()) |
| 404 ? &response_ | 406 ? &response_ |
| 405 : NULL; | 407 : NULL; |
| 406 } | 408 } |
| 407 | 409 |
| 408 LoadState HttpNetworkTransaction::GetLoadState() const { | 410 LoadState HttpNetworkTransaction::GetLoadState() const { |
| 409 // TODO(wtc): Define a new LoadState value for the | 411 // TODO(wtc): Define a new LoadState value for the |
| (...skipping 18 matching lines...) Expand all Loading... |
| 428 | 430 |
| 429 UploadProgress HttpNetworkTransaction::GetUploadProgress() const { | 431 UploadProgress HttpNetworkTransaction::GetUploadProgress() const { |
| 430 if (!stream_.get()) | 432 if (!stream_.get()) |
| 431 return UploadProgress(); | 433 return UploadProgress(); |
| 432 | 434 |
| 433 // TODO(bashi): This cast is temporary. Remove later. | 435 // TODO(bashi): This cast is temporary. Remove later. |
| 434 return static_cast<HttpStream*>(stream_.get())->GetUploadProgress(); | 436 return static_cast<HttpStream*>(stream_.get())->GetUploadProgress(); |
| 435 } | 437 } |
| 436 | 438 |
| 437 void HttpNetworkTransaction::SetQuicServerInfo( | 439 void HttpNetworkTransaction::SetQuicServerInfo( |
| 438 QuicServerInfo* quic_server_info) {} | 440 QuicServerInfo* quic_server_info) { |
| 441 } |
| 439 | 442 |
| 440 bool HttpNetworkTransaction::GetLoadTimingInfo( | 443 bool HttpNetworkTransaction::GetLoadTimingInfo( |
| 441 LoadTimingInfo* load_timing_info) const { | 444 LoadTimingInfo* load_timing_info) const { |
| 442 if (!stream_ || !stream_->GetLoadTimingInfo(load_timing_info)) | 445 if (!stream_ || !stream_->GetLoadTimingInfo(load_timing_info)) |
| 443 return false; | 446 return false; |
| 444 | 447 |
| 445 load_timing_info->proxy_resolve_start = | 448 load_timing_info->proxy_resolve_start = |
| 446 proxy_info_.proxy_resolve_start_time(); | 449 proxy_info_.proxy_resolve_start_time(); |
| 447 load_timing_info->proxy_resolve_end = proxy_info_.proxy_resolve_end_time(); | 450 load_timing_info->proxy_resolve_end = proxy_info_.proxy_resolve_end_time(); |
| 448 load_timing_info->send_start = send_start_time_; | 451 load_timing_info->send_start = send_start_time_; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 headers_valid_ = true; | 549 headers_valid_ = true; |
| 547 server_ssl_config_ = used_ssl_config; | 550 server_ssl_config_ = used_ssl_config; |
| 548 proxy_info_ = used_proxy_info; | 551 proxy_info_ = used_proxy_info; |
| 549 | 552 |
| 550 auth_controllers_[HttpAuth::AUTH_PROXY] = auth_controller; | 553 auth_controllers_[HttpAuth::AUTH_PROXY] = auth_controller; |
| 551 pending_auth_target_ = HttpAuth::AUTH_PROXY; | 554 pending_auth_target_ = HttpAuth::AUTH_PROXY; |
| 552 | 555 |
| 553 DoCallback(OK); | 556 DoCallback(OK); |
| 554 } | 557 } |
| 555 | 558 |
| 556 void HttpNetworkTransaction::OnNeedsClientAuth( | 559 void HttpNetworkTransaction::OnNeedsClientAuth(const SSLConfig& used_ssl_config, |
| 557 const SSLConfig& used_ssl_config, | 560 SSLCertRequestInfo* cert_info) { |
| 558 SSLCertRequestInfo* cert_info) { | |
| 559 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | 561 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); |
| 560 | 562 |
| 561 server_ssl_config_ = used_ssl_config; | 563 server_ssl_config_ = used_ssl_config; |
| 562 response_.cert_request_info = cert_info; | 564 response_.cert_request_info = cert_info; |
| 563 OnIOComplete(ERR_SSL_CLIENT_AUTH_CERT_NEEDED); | 565 OnIOComplete(ERR_SSL_CLIENT_AUTH_CERT_NEEDED); |
| 564 } | 566 } |
| 565 | 567 |
| 566 void HttpNetworkTransaction::OnHttpsProxyTunnelResponse( | 568 void HttpNetworkTransaction::OnHttpsProxyTunnelResponse( |
| 567 const HttpResponseInfo& response_info, | 569 const HttpResponseInfo& response_info, |
| 568 const SSLConfig& used_ssl_config, | 570 const SSLConfig& used_ssl_config, |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 return OK; | 717 return OK; |
| 716 return ERR_IO_PENDING; | 718 return ERR_IO_PENDING; |
| 717 } | 719 } |
| 718 | 720 |
| 719 int HttpNetworkTransaction::DoCreateStream() { | 721 int HttpNetworkTransaction::DoCreateStream() { |
| 720 next_state_ = STATE_CREATE_STREAM_COMPLETE; | 722 next_state_ = STATE_CREATE_STREAM_COMPLETE; |
| 721 if (ForWebSocketHandshake()) { | 723 if (ForWebSocketHandshake()) { |
| 722 stream_request_.reset( | 724 stream_request_.reset( |
| 723 session_->http_stream_factory_for_websocket() | 725 session_->http_stream_factory_for_websocket() |
| 724 ->RequestWebSocketHandshakeStream( | 726 ->RequestWebSocketHandshakeStream( |
| 725 *request_, | 727 *request_, |
| 726 priority_, | 728 priority_, |
| 727 server_ssl_config_, | 729 server_ssl_config_, |
| 728 proxy_ssl_config_, | 730 proxy_ssl_config_, |
| 729 this, | 731 this, |
| 730 websocket_handshake_stream_base_create_helper_, | 732 websocket_handshake_stream_base_create_helper_, |
| 731 net_log_)); | 733 net_log_)); |
| 732 } else { | 734 } else { |
| 733 stream_request_.reset( | 735 stream_request_.reset( |
| 734 session_->http_stream_factory()->RequestStream( | 736 session_->http_stream_factory()->RequestStream(*request_, |
| 735 *request_, | 737 priority_, |
| 736 priority_, | 738 server_ssl_config_, |
| 737 server_ssl_config_, | 739 proxy_ssl_config_, |
| 738 proxy_ssl_config_, | 740 this, |
| 739 this, | 741 net_log_)); |
| 740 net_log_)); | |
| 741 } | 742 } |
| 742 DCHECK(stream_request_.get()); | 743 DCHECK(stream_request_.get()); |
| 743 return ERR_IO_PENDING; | 744 return ERR_IO_PENDING; |
| 744 } | 745 } |
| 745 | 746 |
| 746 int HttpNetworkTransaction::DoCreateStreamComplete(int result) { | 747 int HttpNetworkTransaction::DoCreateStreamComplete(int result) { |
| 747 if (result == OK) { | 748 if (result == OK) { |
| 748 next_state_ = STATE_INIT_STREAM; | 749 next_state_ = STATE_INIT_STREAM; |
| 749 DCHECK(stream_.get()); | 750 DCHECK(stream_.get()); |
| 750 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 751 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 772 | 773 |
| 773 int HttpNetworkTransaction::DoInitStreamComplete(int result) { | 774 int HttpNetworkTransaction::DoInitStreamComplete(int result) { |
| 774 if (result == OK) { | 775 if (result == OK) { |
| 775 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; | 776 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
| 776 } else { | 777 } else { |
| 777 if (result < 0) | 778 if (result < 0) |
| 778 result = HandleIOError(result); | 779 result = HandleIOError(result); |
| 779 | 780 |
| 780 // The stream initialization failed, so this stream will never be useful. | 781 // The stream initialization failed, so this stream will never be useful. |
| 781 if (stream_) | 782 if (stream_) |
| 782 total_received_bytes_ += stream_->GetTotalReceivedBytes(); | 783 total_received_bytes_ += stream_->GetTotalReceivedBytes(); |
| 783 stream_.reset(); | 784 stream_.reset(); |
| 784 } | 785 } |
| 785 | 786 |
| 786 return result; | 787 return result; |
| 787 } | 788 } |
| 788 | 789 |
| 789 int HttpNetworkTransaction::DoGenerateProxyAuthToken() { | 790 int HttpNetworkTransaction::DoGenerateProxyAuthToken() { |
| 790 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE; | 791 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE; |
| 791 if (!ShouldApplyProxyAuth()) | 792 if (!ShouldApplyProxyAuth()) |
| 792 return OK; | 793 return OK; |
| 793 HttpAuth::Target target = HttpAuth::AUTH_PROXY; | 794 HttpAuth::Target target = HttpAuth::AUTH_PROXY; |
| 794 if (!auth_controllers_[target].get()) | 795 if (!auth_controllers_[target].get()) |
| 795 auth_controllers_[target] = | 796 auth_controllers_[target] = |
| 796 new HttpAuthController(target, | 797 new HttpAuthController(target, |
| 797 AuthURL(target), | 798 AuthURL(target), |
| 798 session_->http_auth_cache(), | 799 session_->http_auth_cache(), |
| 799 session_->http_auth_handler_factory()); | 800 session_->http_auth_handler_factory()); |
| 800 return auth_controllers_[target]->MaybeGenerateAuthToken(request_, | 801 return auth_controllers_[target]->MaybeGenerateAuthToken( |
| 801 io_callback_, | 802 request_, io_callback_, net_log_); |
| 802 net_log_); | |
| 803 } | 803 } |
| 804 | 804 |
| 805 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) { | 805 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) { |
| 806 DCHECK_NE(ERR_IO_PENDING, rv); | 806 DCHECK_NE(ERR_IO_PENDING, rv); |
| 807 if (rv == OK) | 807 if (rv == OK) |
| 808 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN; | 808 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN; |
| 809 return rv; | 809 return rv; |
| 810 } | 810 } |
| 811 | 811 |
| 812 int HttpNetworkTransaction::DoGenerateServerAuthToken() { | 812 int HttpNetworkTransaction::DoGenerateServerAuthToken() { |
| 813 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE; | 813 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE; |
| 814 HttpAuth::Target target = HttpAuth::AUTH_SERVER; | 814 HttpAuth::Target target = HttpAuth::AUTH_SERVER; |
| 815 if (!auth_controllers_[target].get()) { | 815 if (!auth_controllers_[target].get()) { |
| 816 auth_controllers_[target] = | 816 auth_controllers_[target] = |
| 817 new HttpAuthController(target, | 817 new HttpAuthController(target, |
| 818 AuthURL(target), | 818 AuthURL(target), |
| 819 session_->http_auth_cache(), | 819 session_->http_auth_cache(), |
| 820 session_->http_auth_handler_factory()); | 820 session_->http_auth_handler_factory()); |
| 821 if (request_->load_flags & LOAD_DO_NOT_USE_EMBEDDED_IDENTITY) | 821 if (request_->load_flags & LOAD_DO_NOT_USE_EMBEDDED_IDENTITY) |
| 822 auth_controllers_[target]->DisableEmbeddedIdentity(); | 822 auth_controllers_[target]->DisableEmbeddedIdentity(); |
| 823 } | 823 } |
| 824 if (!ShouldApplyServerAuth()) | 824 if (!ShouldApplyServerAuth()) |
| 825 return OK; | 825 return OK; |
| 826 return auth_controllers_[target]->MaybeGenerateAuthToken(request_, | 826 return auth_controllers_[target]->MaybeGenerateAuthToken( |
| 827 io_callback_, | 827 request_, io_callback_, net_log_); |
| 828 net_log_); | |
| 829 } | 828 } |
| 830 | 829 |
| 831 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) { | 830 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) { |
| 832 DCHECK_NE(ERR_IO_PENDING, rv); | 831 DCHECK_NE(ERR_IO_PENDING, rv); |
| 833 if (rv == OK) | 832 if (rv == OK) |
| 834 next_state_ = STATE_INIT_REQUEST_BODY; | 833 next_state_ = STATE_INIT_REQUEST_BODY; |
| 835 return rv; | 834 return rv; |
| 836 } | 835 } |
| 837 | 836 |
| 838 void HttpNetworkTransaction::BuildRequestHeaders(bool using_proxy) { | 837 void HttpNetworkTransaction::BuildRequestHeaders(bool using_proxy) { |
| 839 request_headers_.SetHeader(HttpRequestHeaders::kHost, | 838 request_headers_.SetHeader(HttpRequestHeaders::kHost, |
| 840 GetHostAndOptionalPort(request_->url)); | 839 GetHostAndOptionalPort(request_->url)); |
| 841 | 840 |
| 842 // For compat with HTTP/1.0 servers and proxies: | 841 // For compat with HTTP/1.0 servers and proxies: |
| 843 if (using_proxy) { | 842 if (using_proxy) { |
| 844 request_headers_.SetHeader(HttpRequestHeaders::kProxyConnection, | 843 request_headers_.SetHeader(HttpRequestHeaders::kProxyConnection, |
| 845 "keep-alive"); | 844 "keep-alive"); |
| 846 } else { | 845 } else { |
| 847 request_headers_.SetHeader(HttpRequestHeaders::kConnection, "keep-alive"); | 846 request_headers_.SetHeader(HttpRequestHeaders::kConnection, "keep-alive"); |
| 848 } | 847 } |
| 849 | 848 |
| 850 // Add a content length header? | 849 // Add a content length header? |
| 851 if (request_->upload_data_stream) { | 850 if (request_->upload_data_stream) { |
| 852 if (request_->upload_data_stream->is_chunked()) { | 851 if (request_->upload_data_stream->is_chunked()) { |
| 853 request_headers_.SetHeader( | 852 request_headers_.SetHeader(HttpRequestHeaders::kTransferEncoding, |
| 854 HttpRequestHeaders::kTransferEncoding, "chunked"); | 853 "chunked"); |
| 855 } else { | 854 } else { |
| 856 request_headers_.SetHeader( | 855 request_headers_.SetHeader( |
| 857 HttpRequestHeaders::kContentLength, | 856 HttpRequestHeaders::kContentLength, |
| 858 base::Uint64ToString(request_->upload_data_stream->size())); | 857 base::Uint64ToString(request_->upload_data_stream->size())); |
| 859 } | 858 } |
| 860 } else if (request_->method == "POST" || request_->method == "PUT" || | 859 } else if (request_->method == "POST" || request_->method == "PUT" || |
| 861 request_->method == "HEAD") { | 860 request_->method == "HEAD") { |
| 862 // An empty POST/PUT request still needs a content length. As for HEAD, | 861 // An empty POST/PUT request still needs a content length. As for HEAD, |
| 863 // IE and Safari also add a content length header. Presumably it is to | 862 // IE and Safari also add a content length header. Presumably it is to |
| 864 // support sending a HEAD request to an URL that only expects to be sent a | 863 // support sending a HEAD request to an URL that only expects to be sent a |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 } | 901 } |
| 903 | 902 |
| 904 int HttpNetworkTransaction::DoBuildRequest() { | 903 int HttpNetworkTransaction::DoBuildRequest() { |
| 905 next_state_ = STATE_BUILD_REQUEST_COMPLETE; | 904 next_state_ = STATE_BUILD_REQUEST_COMPLETE; |
| 906 headers_valid_ = false; | 905 headers_valid_ = false; |
| 907 | 906 |
| 908 // This is constructed lazily (instead of within our Start method), so that | 907 // This is constructed lazily (instead of within our Start method), so that |
| 909 // we have proxy info available. | 908 // we have proxy info available. |
| 910 if (request_headers_.IsEmpty()) { | 909 if (request_headers_.IsEmpty()) { |
| 911 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && | 910 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && |
| 912 !is_https_request(); | 911 !is_https_request(); |
| 913 BuildRequestHeaders(using_proxy); | 912 BuildRequestHeaders(using_proxy); |
| 914 } | 913 } |
| 915 | 914 |
| 916 return OK; | 915 return OK; |
| 917 } | 916 } |
| 918 | 917 |
| 919 int HttpNetworkTransaction::DoBuildRequestComplete(int result) { | 918 int HttpNetworkTransaction::DoBuildRequestComplete(int result) { |
| 920 if (result == OK) | 919 if (result == OK) |
| 921 next_state_ = STATE_SEND_REQUEST; | 920 next_state_ = STATE_SEND_REQUEST; |
| 922 return result; | 921 return result; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 bool data_reduction_fallback_proxy_used = false; | 999 bool data_reduction_fallback_proxy_used = false; |
| 1001 #if defined(DATA_REDUCTION_FALLBACK_HOST) | 1000 #if defined(DATA_REDUCTION_FALLBACK_HOST) |
| 1002 if (!data_reduction_proxy_used) { | 1001 if (!data_reduction_proxy_used) { |
| 1003 data_reduction_fallback_proxy_used = | 1002 data_reduction_fallback_proxy_used = |
| 1004 proxy_info_.proxy_server().isDataReductionProxyFallback(); | 1003 proxy_info_.proxy_server().isDataReductionProxyFallback(); |
| 1005 } | 1004 } |
| 1006 #endif | 1005 #endif |
| 1007 | 1006 |
| 1008 if (data_reduction_proxy_used || data_reduction_fallback_proxy_used) { | 1007 if (data_reduction_proxy_used || data_reduction_fallback_proxy_used) { |
| 1009 net::HttpResponseHeaders::DataReductionProxyInfo | 1008 net::HttpResponseHeaders::DataReductionProxyInfo |
| 1010 data_reduction_proxy_info; | 1009 data_reduction_proxy_info; |
| 1011 proxy_bypass_event | 1010 proxy_bypass_event = |
| 1012 = response_.headers->GetDataReductionProxyBypassEventType( | 1011 response_.headers->GetDataReductionProxyBypassEventType( |
| 1013 &data_reduction_proxy_info); | 1012 &data_reduction_proxy_info); |
| 1014 if (proxy_bypass_event < ProxyService::BYPASS_EVENT_TYPE_MAX) { | 1013 if (proxy_bypass_event < ProxyService::BYPASS_EVENT_TYPE_MAX) { |
| 1015 ProxyService* proxy_service = session_->proxy_service(); | 1014 ProxyService* proxy_service = session_->proxy_service(); |
| 1016 | 1015 |
| 1017 proxy_service->RecordDataReductionProxyBypassInfo( | 1016 proxy_service->RecordDataReductionProxyBypassInfo( |
| 1018 data_reduction_proxy_used, proxy_info_.proxy_server(), | 1017 data_reduction_proxy_used, |
| 1018 proxy_info_.proxy_server(), |
| 1019 proxy_bypass_event); | 1019 proxy_bypass_event); |
| 1020 | 1020 |
| 1021 ProxyServer proxy_server; | 1021 ProxyServer proxy_server; |
| 1022 #if defined(DATA_REDUCTION_FALLBACK_HOST) | 1022 #if defined(DATA_REDUCTION_FALLBACK_HOST) |
| 1023 if (data_reduction_proxy_used && data_reduction_proxy_info.bypass_all) { | 1023 if (data_reduction_proxy_used && data_reduction_proxy_info.bypass_all) { |
| 1024 // TODO(bengr): Rename as DATA_REDUCTION_FALLBACK_ORIGIN. | 1024 // TODO(bengr): Rename as DATA_REDUCTION_FALLBACK_ORIGIN. |
| 1025 GURL proxy_url(DATA_REDUCTION_FALLBACK_HOST); | 1025 GURL proxy_url(DATA_REDUCTION_FALLBACK_HOST); |
| 1026 if (proxy_url.SchemeIsHTTPOrHTTPS()) { | 1026 if (proxy_url.SchemeIsHTTPOrHTTPS()) { |
| 1027 proxy_server = ProxyServer(proxy_url.SchemeIs("http") ? | 1027 proxy_server = ProxyServer(proxy_url.SchemeIs("http") |
| 1028 ProxyServer::SCHEME_HTTP : | 1028 ? ProxyServer::SCHEME_HTTP |
| 1029 ProxyServer::SCHEME_HTTPS, | 1029 : ProxyServer::SCHEME_HTTPS, |
| 1030 HostPortPair::FromURL(proxy_url)); | 1030 HostPortPair::FromURL(proxy_url)); |
| 1031 } | 1031 } |
| 1032 } | 1032 } |
| 1033 #endif | 1033 #endif |
| 1034 if (proxy_service->MarkProxiesAsBadUntil( | 1034 if (proxy_service->MarkProxiesAsBadUntil( |
| 1035 proxy_info_, | 1035 proxy_info_, |
| 1036 data_reduction_proxy_info.bypass_duration, | 1036 data_reduction_proxy_info.bypass_duration, |
| 1037 proxy_server, | 1037 proxy_server, |
| 1038 net_log_)) { | 1038 net_log_)) { |
| 1039 // Only retry idempotent methods. We don't want to resubmit a POST | 1039 // Only retry idempotent methods. We don't want to resubmit a POST |
| 1040 // if the proxy took some action. | 1040 // if the proxy took some action. |
| 1041 if (request_->method == "GET" || | 1041 if (request_->method == "GET" || request_->method == "OPTIONS" || |
| 1042 request_->method == "OPTIONS" || | 1042 request_->method == "HEAD" || request_->method == "PUT" || |
| 1043 request_->method == "HEAD" || | 1043 request_->method == "DELETE" || request_->method == "TRACE") { |
| 1044 request_->method == "PUT" || | |
| 1045 request_->method == "DELETE" || | |
| 1046 request_->method == "TRACE") { | |
| 1047 ResetConnectionAndRequestForResend(); | 1044 ResetConnectionAndRequestForResend(); |
| 1048 return OK; | 1045 return OK; |
| 1049 } | 1046 } |
| 1050 } | 1047 } |
| 1051 } | 1048 } |
| 1052 } | 1049 } |
| 1053 } | 1050 } |
| 1054 #endif // defined(SPDY_PROXY_AUTH_ORIGIN) | 1051 #endif // defined(SPDY_PROXY_AUTH_ORIGIN) |
| 1055 | 1052 |
| 1056 // Like Net.HttpResponseCode, but only for MAIN_FRAME loads. | 1053 // Like Net.HttpResponseCode, but only for MAIN_FRAME loads. |
| 1057 if (request_->load_flags & LOAD_MAIN_FRAME) { | 1054 if (request_->load_flags & LOAD_MAIN_FRAME) { |
| 1058 const int response_code = response_.headers->response_code(); | 1055 const int response_code = response_.headers->response_code(); |
| 1059 UMA_HISTOGRAM_ENUMERATION( | 1056 UMA_HISTOGRAM_ENUMERATION( |
| 1060 "Net.HttpResponseCode_Nxx_MainFrame", response_code/100, 10); | 1057 "Net.HttpResponseCode_Nxx_MainFrame", response_code / 100, 10); |
| 1061 } | 1058 } |
| 1062 | 1059 |
| 1063 net_log_.AddEvent( | 1060 net_log_.AddEvent( |
| 1064 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS, | 1061 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS, |
| 1065 base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers)); | 1062 base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers)); |
| 1066 | 1063 |
| 1067 if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0)) { | 1064 if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0)) { |
| 1068 // HTTP/0.9 doesn't support the PUT method, so lack of response headers | 1065 // HTTP/0.9 doesn't support the PUT method, so lack of response headers |
| 1069 // indicates a buggy server. See: | 1066 // indicates a buggy server. See: |
| 1070 // https://bugzilla.mozilla.org/show_bug.cgi?id=193921 | 1067 // https://bugzilla.mozilla.org/show_bug.cgi?id=193921 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 } | 1199 } |
| 1203 | 1200 |
| 1204 void HttpNetworkTransaction::LogTransactionConnectedMetrics() { | 1201 void HttpNetworkTransaction::LogTransactionConnectedMetrics() { |
| 1205 if (logged_response_time_) | 1202 if (logged_response_time_) |
| 1206 return; | 1203 return; |
| 1207 | 1204 |
| 1208 logged_response_time_ = true; | 1205 logged_response_time_ = true; |
| 1209 | 1206 |
| 1210 base::TimeDelta total_duration = response_.response_time - start_time_; | 1207 base::TimeDelta total_duration = response_.response_time - start_time_; |
| 1211 | 1208 |
| 1212 UMA_HISTOGRAM_CUSTOM_TIMES( | 1209 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Connected", |
| 1213 "Net.Transaction_Connected", | 1210 total_duration, |
| 1214 total_duration, | 1211 base::TimeDelta::FromMilliseconds(1), |
| 1215 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), | 1212 base::TimeDelta::FromMinutes(10), |
| 1216 100); | 1213 100); |
| 1217 | 1214 |
| 1218 bool reused_socket = stream_->IsConnectionReused(); | 1215 bool reused_socket = stream_->IsConnectionReused(); |
| 1219 if (!reused_socket) { | 1216 if (!reused_socket) { |
| 1220 UMA_HISTOGRAM_CUSTOM_TIMES( | 1217 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Connected_New_b", |
| 1221 "Net.Transaction_Connected_New_b", | 1218 total_duration, |
| 1222 total_duration, | 1219 base::TimeDelta::FromMilliseconds(1), |
| 1223 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), | 1220 base::TimeDelta::FromMinutes(10), |
| 1224 100); | 1221 100); |
| 1225 } | 1222 } |
| 1226 | 1223 |
| 1227 // Currently, non-HIGHEST priority requests are frame or sub-frame resource | 1224 // Currently, non-HIGHEST priority requests are frame or sub-frame resource |
| 1228 // types. This will change when we also prioritize certain subresources like | 1225 // types. This will change when we also prioritize certain subresources like |
| 1229 // css, js, etc. | 1226 // css, js, etc. |
| 1230 if (priority_ != HIGHEST) { | 1227 if (priority_ != HIGHEST) { |
| 1231 UMA_HISTOGRAM_CUSTOM_TIMES( | 1228 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Priority_High_Latency_b", |
| 1232 "Net.Priority_High_Latency_b", | 1229 total_duration, |
| 1233 total_duration, | 1230 base::TimeDelta::FromMilliseconds(1), |
| 1234 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), | 1231 base::TimeDelta::FromMinutes(10), |
| 1235 100); | 1232 100); |
| 1236 } else { | 1233 } else { |
| 1237 UMA_HISTOGRAM_CUSTOM_TIMES( | 1234 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Priority_Low_Latency_b", |
| 1238 "Net.Priority_Low_Latency_b", | 1235 total_duration, |
| 1239 total_duration, | 1236 base::TimeDelta::FromMilliseconds(1), |
| 1240 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), | 1237 base::TimeDelta::FromMinutes(10), |
| 1241 100); | 1238 100); |
| 1242 } | 1239 } |
| 1243 } | 1240 } |
| 1244 | 1241 |
| 1245 void HttpNetworkTransaction::LogTransactionMetrics() const { | 1242 void HttpNetworkTransaction::LogTransactionMetrics() const { |
| 1246 base::TimeDelta duration = base::Time::Now() - | 1243 base::TimeDelta duration = base::Time::Now() - response_.request_time; |
| 1247 response_.request_time; | |
| 1248 if (60 < duration.InMinutes()) | 1244 if (60 < duration.InMinutes()) |
| 1249 return; | 1245 return; |
| 1250 | 1246 |
| 1251 base::TimeDelta total_duration = base::Time::Now() - start_time_; | 1247 base::TimeDelta total_duration = base::Time::Now() - start_time_; |
| 1252 | 1248 |
| 1253 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Latency_b", duration, | 1249 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Latency_b", |
| 1250 duration, |
| 1254 base::TimeDelta::FromMilliseconds(1), | 1251 base::TimeDelta::FromMilliseconds(1), |
| 1255 base::TimeDelta::FromMinutes(10), | 1252 base::TimeDelta::FromMinutes(10), |
| 1256 100); | 1253 100); |
| 1257 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Latency_Total", | 1254 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Latency_Total", |
| 1258 total_duration, | 1255 total_duration, |
| 1259 base::TimeDelta::FromMilliseconds(1), | 1256 base::TimeDelta::FromMilliseconds(1), |
| 1260 base::TimeDelta::FromMinutes(10), 100); | 1257 base::TimeDelta::FromMinutes(10), |
| 1258 100); |
| 1261 | 1259 |
| 1262 if (!stream_->IsConnectionReused()) { | 1260 if (!stream_->IsConnectionReused()) { |
| 1263 UMA_HISTOGRAM_CUSTOM_TIMES( | 1261 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Latency_Total_New_Connection", |
| 1264 "Net.Transaction_Latency_Total_New_Connection", | 1262 total_duration, |
| 1265 total_duration, base::TimeDelta::FromMilliseconds(1), | 1263 base::TimeDelta::FromMilliseconds(1), |
| 1266 base::TimeDelta::FromMinutes(10), 100); | 1264 base::TimeDelta::FromMinutes(10), |
| 1265 100); |
| 1267 } | 1266 } |
| 1268 } | 1267 } |
| 1269 | 1268 |
| 1270 int HttpNetworkTransaction::HandleCertificateRequest(int error) { | 1269 int HttpNetworkTransaction::HandleCertificateRequest(int error) { |
| 1271 // There are two paths through which the server can request a certificate | 1270 // There are two paths through which the server can request a certificate |
| 1272 // from us. The first is during the initial handshake, the second is | 1271 // from us. The first is during the initial handshake, the second is |
| 1273 // during SSL renegotiation. | 1272 // during SSL renegotiation. |
| 1274 // | 1273 // |
| 1275 // In both cases, we want to close the connection before proceeding. | 1274 // In both cases, we want to close the connection before proceeding. |
| 1276 // We do this for two reasons: | 1275 // We do this for two reasons: |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1303 return error; | 1302 return error; |
| 1304 | 1303 |
| 1305 // Check that the certificate selected is still a certificate the server | 1304 // Check that the certificate selected is still a certificate the server |
| 1306 // is likely to accept, based on the criteria supplied in the | 1305 // is likely to accept, based on the criteria supplied in the |
| 1307 // CertificateRequest message. | 1306 // CertificateRequest message. |
| 1308 if (client_cert.get()) { | 1307 if (client_cert.get()) { |
| 1309 const std::vector<std::string>& cert_authorities = | 1308 const std::vector<std::string>& cert_authorities = |
| 1310 response_.cert_request_info->cert_authorities; | 1309 response_.cert_request_info->cert_authorities; |
| 1311 | 1310 |
| 1312 bool cert_still_valid = cert_authorities.empty() || | 1311 bool cert_still_valid = cert_authorities.empty() || |
| 1313 client_cert->IsIssuedByEncoded(cert_authorities); | 1312 client_cert->IsIssuedByEncoded(cert_authorities); |
| 1314 if (!cert_still_valid) | 1313 if (!cert_still_valid) |
| 1315 return error; | 1314 return error; |
| 1316 } | 1315 } |
| 1317 | 1316 |
| 1318 // TODO(davidben): Add a unit test which covers this path; we need to be | 1317 // TODO(davidben): Add a unit test which covers this path; we need to be |
| 1319 // able to send a legitimate certificate and also bypass/clear the | 1318 // able to send a legitimate certificate and also bypass/clear the |
| 1320 // SSL session cache. | 1319 // SSL session cache. |
| 1321 SSLConfig* ssl_config = response_.cert_request_info->is_proxy ? | 1320 SSLConfig* ssl_config = response_.cert_request_info->is_proxy |
| 1322 &proxy_ssl_config_ : &server_ssl_config_; | 1321 ? &proxy_ssl_config_ |
| 1322 : &server_ssl_config_; |
| 1323 ssl_config->send_client_cert = true; | 1323 ssl_config->send_client_cert = true; |
| 1324 ssl_config->client_cert = client_cert; | 1324 ssl_config->client_cert = client_cert; |
| 1325 next_state_ = STATE_CREATE_STREAM; | 1325 next_state_ = STATE_CREATE_STREAM; |
| 1326 // Reset the other member variables. | 1326 // Reset the other member variables. |
| 1327 // Note: this is necessary only with SSL renegotiation. | 1327 // Note: this is necessary only with SSL renegotiation. |
| 1328 ResetStateForRestart(); | 1328 ResetStateForRestart(); |
| 1329 return OK; | 1329 return OK; |
| 1330 } | 1330 } |
| 1331 | 1331 |
| 1332 void HttpNetworkTransaction::HandleClientAuthError(int error) { | 1332 void HttpNetworkTransaction::HandleClientAuthError(int error) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1386 case ERR_SSL_INAPPROPRIATE_FALLBACK: | 1386 case ERR_SSL_INAPPROPRIATE_FALLBACK: |
| 1387 // The server told us that we should not have fallen back. A buggy server | 1387 // The server told us that we should not have fallen back. A buggy server |
| 1388 // could trigger ERR_SSL_INAPPROPRIATE_FALLBACK with the initial | 1388 // could trigger ERR_SSL_INAPPROPRIATE_FALLBACK with the initial |
| 1389 // connection. |fallback_error_code_| is initialised to | 1389 // connection. |fallback_error_code_| is initialised to |
| 1390 // ERR_SSL_INAPPROPRIATE_FALLBACK to catch this case. | 1390 // ERR_SSL_INAPPROPRIATE_FALLBACK to catch this case. |
| 1391 error = fallback_error_code_; | 1391 error = fallback_error_code_; |
| 1392 break; | 1392 break; |
| 1393 } | 1393 } |
| 1394 | 1394 |
| 1395 if (should_fallback) { | 1395 if (should_fallback) { |
| 1396 net_log_.AddEvent( | 1396 net_log_.AddEvent(NetLog::TYPE_SSL_VERSION_FALLBACK, |
| 1397 NetLog::TYPE_SSL_VERSION_FALLBACK, | 1397 base::Bind(&NetLogSSLVersionFallbackCallback, |
| 1398 base::Bind(&NetLogSSLVersionFallbackCallback, | 1398 &request_->url, |
| 1399 &request_->url, error, server_ssl_config_.version_max, | 1399 error, |
| 1400 version_max)); | 1400 server_ssl_config_.version_max, |
| 1401 version_max)); |
| 1401 fallback_error_code_ = error; | 1402 fallback_error_code_ = error; |
| 1402 server_ssl_config_.version_max = version_max; | 1403 server_ssl_config_.version_max = version_max; |
| 1403 server_ssl_config_.version_fallback = true; | 1404 server_ssl_config_.version_fallback = true; |
| 1404 ResetConnectionAndRequestForResend(); | 1405 ResetConnectionAndRequestForResend(); |
| 1405 error = OK; | 1406 error = OK; |
| 1406 } | 1407 } |
| 1407 | 1408 |
| 1408 return error; | 1409 return error; |
| 1409 } | 1410 } |
| 1410 | 1411 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1508 | 1509 |
| 1509 // We need to clear request_headers_ because it contains the real request | 1510 // We need to clear request_headers_ because it contains the real request |
| 1510 // headers, but we may need to resend the CONNECT request first to recreate | 1511 // headers, but we may need to resend the CONNECT request first to recreate |
| 1511 // the SSL tunnel. | 1512 // the SSL tunnel. |
| 1512 request_headers_.Clear(); | 1513 request_headers_.Clear(); |
| 1513 next_state_ = STATE_CREATE_STREAM; // Resend the request. | 1514 next_state_ = STATE_CREATE_STREAM; // Resend the request. |
| 1514 } | 1515 } |
| 1515 | 1516 |
| 1516 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { | 1517 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { |
| 1517 return !is_https_request() && | 1518 return !is_https_request() && |
| 1518 (proxy_info_.is_https() || proxy_info_.is_http()); | 1519 (proxy_info_.is_https() || proxy_info_.is_http()); |
| 1519 } | 1520 } |
| 1520 | 1521 |
| 1521 bool HttpNetworkTransaction::ShouldApplyServerAuth() const { | 1522 bool HttpNetworkTransaction::ShouldApplyServerAuth() const { |
| 1522 return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA); | 1523 return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA); |
| 1523 } | 1524 } |
| 1524 | 1525 |
| 1525 int HttpNetworkTransaction::HandleAuthChallenge() { | 1526 int HttpNetworkTransaction::HandleAuthChallenge() { |
| 1526 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders()); | 1527 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders()); |
| 1527 DCHECK(headers.get()); | 1528 DCHECK(headers.get()); |
| 1528 | 1529 |
| 1529 int status = headers->response_code(); | 1530 int status = headers->response_code(); |
| 1530 if (status != HTTP_UNAUTHORIZED && | 1531 if (status != HTTP_UNAUTHORIZED && |
| 1531 status != HTTP_PROXY_AUTHENTICATION_REQUIRED) | 1532 status != HTTP_PROXY_AUTHENTICATION_REQUIRED) |
| 1532 return OK; | 1533 return OK; |
| 1533 HttpAuth::Target target = status == HTTP_PROXY_AUTHENTICATION_REQUIRED ? | 1534 HttpAuth::Target target = status == HTTP_PROXY_AUTHENTICATION_REQUIRED |
| 1534 HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER; | 1535 ? HttpAuth::AUTH_PROXY |
| 1536 : HttpAuth::AUTH_SERVER; |
| 1535 if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct()) | 1537 if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct()) |
| 1536 return ERR_UNEXPECTED_PROXY_AUTH; | 1538 return ERR_UNEXPECTED_PROXY_AUTH; |
| 1537 | 1539 |
| 1538 // This case can trigger when an HTTPS server responds with a "Proxy | 1540 // This case can trigger when an HTTPS server responds with a "Proxy |
| 1539 // authentication required" status code through a non-authenticating | 1541 // authentication required" status code through a non-authenticating |
| 1540 // proxy. | 1542 // proxy. |
| 1541 if (!auth_controllers_[target].get()) | 1543 if (!auth_controllers_[target].get()) |
| 1542 return ERR_UNEXPECTED_PROXY_AUTH; | 1544 return ERR_UNEXPECTED_PROXY_AUTH; |
| 1543 | 1545 |
| 1544 int rv = auth_controllers_[target]->HandleAuthChallenge( | 1546 int rv = auth_controllers_[target]->HandleAuthChallenge( |
| 1545 headers, (request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA) != 0, false, | 1547 headers, |
| 1548 (request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA) != 0, |
| 1549 false, |
| 1546 net_log_); | 1550 net_log_); |
| 1547 if (auth_controllers_[target]->HaveAuthHandler()) | 1551 if (auth_controllers_[target]->HaveAuthHandler()) |
| 1548 pending_auth_target_ = target; | 1552 pending_auth_target_ = target; |
| 1549 | 1553 |
| 1550 scoped_refptr<AuthChallengeInfo> auth_info = | 1554 scoped_refptr<AuthChallengeInfo> auth_info = |
| 1551 auth_controllers_[target]->auth_info(); | 1555 auth_controllers_[target]->auth_info(); |
| 1552 if (auth_info.get()) | 1556 if (auth_info.get()) |
| 1553 response_.auth_challenge = auth_info; | 1557 response_.auth_challenge = auth_info; |
| 1554 | 1558 |
| 1555 return rv; | 1559 return rv; |
| 1556 } | 1560 } |
| 1557 | 1561 |
| 1558 bool HttpNetworkTransaction::HaveAuth(HttpAuth::Target target) const { | 1562 bool HttpNetworkTransaction::HaveAuth(HttpAuth::Target target) const { |
| 1559 return auth_controllers_[target].get() && | 1563 return auth_controllers_[target].get() && |
| 1560 auth_controllers_[target]->HaveAuth(); | 1564 auth_controllers_[target]->HaveAuth(); |
| 1561 } | 1565 } |
| 1562 | 1566 |
| 1563 GURL HttpNetworkTransaction::AuthURL(HttpAuth::Target target) const { | 1567 GURL HttpNetworkTransaction::AuthURL(HttpAuth::Target target) const { |
| 1564 switch (target) { | 1568 switch (target) { |
| 1565 case HttpAuth::AUTH_PROXY: { | 1569 case HttpAuth::AUTH_PROXY: { |
| 1566 if (!proxy_info_.proxy_server().is_valid() || | 1570 if (!proxy_info_.proxy_server().is_valid() || |
| 1567 proxy_info_.proxy_server().is_direct()) { | 1571 proxy_info_.proxy_server().is_direct()) { |
| 1568 return GURL(); // There is no proxy server. | 1572 return GURL(); // There is no proxy server. |
| 1569 } | 1573 } |
| 1570 const char* scheme = proxy_info_.is_https() ? "https://" : "http://"; | 1574 const char* scheme = proxy_info_.is_https() ? "https://" : "http://"; |
| 1571 return GURL(scheme + | 1575 return GURL(scheme + |
| 1572 proxy_info_.proxy_server().host_port_pair().ToString()); | 1576 proxy_info_.proxy_server().host_port_pair().ToString()); |
| 1573 } | 1577 } |
| 1574 case HttpAuth::AUTH_SERVER: | 1578 case HttpAuth::AUTH_SERVER: |
| 1575 return request_->url; | 1579 return request_->url; |
| 1576 default: | 1580 default: |
| 1577 return GURL(); | 1581 return GURL(); |
| 1578 } | 1582 } |
| 1579 } | 1583 } |
| 1580 | 1584 |
| 1581 bool HttpNetworkTransaction::ForWebSocketHandshake() const { | 1585 bool HttpNetworkTransaction::ForWebSocketHandshake() const { |
| 1582 return websocket_handshake_stream_base_create_helper_ && | 1586 return websocket_handshake_stream_base_create_helper_ && |
| 1583 request_->url.SchemeIsWSOrWSS(); | 1587 request_->url.SchemeIsWSOrWSS(); |
| 1584 } | 1588 } |
| 1585 | 1589 |
| 1586 #define STATE_CASE(s) \ | 1590 #define STATE_CASE(s) \ |
| 1587 case s: \ | 1591 case s: \ |
| 1588 description = base::StringPrintf("%s (0x%08X)", #s, s); \ | 1592 description = base::StringPrintf("%s (0x%08X)", #s, s); \ |
| 1589 break | 1593 break |
| 1590 | 1594 |
| 1591 std::string HttpNetworkTransaction::DescribeState(State state) { | 1595 std::string HttpNetworkTransaction::DescribeState(State state) { |
| 1592 std::string description; | 1596 std::string description; |
| 1593 switch (state) { | 1597 switch (state) { |
| 1594 STATE_CASE(STATE_NOTIFY_BEFORE_CREATE_STREAM); | 1598 STATE_CASE(STATE_NOTIFY_BEFORE_CREATE_STREAM); |
| 1595 STATE_CASE(STATE_CREATE_STREAM); | 1599 STATE_CASE(STATE_CREATE_STREAM); |
| 1596 STATE_CASE(STATE_CREATE_STREAM_COMPLETE); | 1600 STATE_CASE(STATE_CREATE_STREAM_COMPLETE); |
| 1597 STATE_CASE(STATE_INIT_REQUEST_BODY); | 1601 STATE_CASE(STATE_INIT_REQUEST_BODY); |
| 1598 STATE_CASE(STATE_INIT_REQUEST_BODY_COMPLETE); | 1602 STATE_CASE(STATE_INIT_REQUEST_BODY_COMPLETE); |
| 1599 STATE_CASE(STATE_BUILD_REQUEST); | 1603 STATE_CASE(STATE_BUILD_REQUEST); |
| 1600 STATE_CASE(STATE_BUILD_REQUEST_COMPLETE); | 1604 STATE_CASE(STATE_BUILD_REQUEST_COMPLETE); |
| 1601 STATE_CASE(STATE_SEND_REQUEST); | 1605 STATE_CASE(STATE_SEND_REQUEST); |
| 1602 STATE_CASE(STATE_SEND_REQUEST_COMPLETE); | 1606 STATE_CASE(STATE_SEND_REQUEST_COMPLETE); |
| 1603 STATE_CASE(STATE_READ_HEADERS); | 1607 STATE_CASE(STATE_READ_HEADERS); |
| 1604 STATE_CASE(STATE_READ_HEADERS_COMPLETE); | 1608 STATE_CASE(STATE_READ_HEADERS_COMPLETE); |
| 1605 STATE_CASE(STATE_READ_BODY); | 1609 STATE_CASE(STATE_READ_BODY); |
| 1606 STATE_CASE(STATE_READ_BODY_COMPLETE); | 1610 STATE_CASE(STATE_READ_BODY_COMPLETE); |
| 1607 STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART); | 1611 STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART); |
| 1608 STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE); | 1612 STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE); |
| 1609 STATE_CASE(STATE_NONE); | 1613 STATE_CASE(STATE_NONE); |
| 1610 default: | 1614 default: |
| 1611 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, | 1615 description = |
| 1612 state); | 1616 base::StringPrintf("Unknown state 0x%08X (%u)", state, state); |
| 1613 break; | 1617 break; |
| 1614 } | 1618 } |
| 1615 return description; | 1619 return description; |
| 1616 } | 1620 } |
| 1617 | 1621 |
| 1618 #undef STATE_CASE | 1622 #undef STATE_CASE |
| 1619 | 1623 |
| 1620 } // namespace net | 1624 } // namespace net |
| OLD | NEW |