| 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_stream_factory_impl_job.h" | 5 #include "net/http/http_stream_factory_impl_job.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 } | 133 } |
| 134 | 134 |
| 135 void HttpStreamFactoryImpl::Job::Start(Request* request) { | 135 void HttpStreamFactoryImpl::Job::Start(Request* request) { |
| 136 DCHECK(request); | 136 DCHECK(request); |
| 137 request_ = request; | 137 request_ = request; |
| 138 StartInternal(); | 138 StartInternal(); |
| 139 } | 139 } |
| 140 | 140 |
| 141 int HttpStreamFactoryImpl::Job::Preconnect(int num_streams) { | 141 int HttpStreamFactoryImpl::Job::Preconnect(int num_streams) { |
| 142 DCHECK_GT(num_streams, 0); | 142 DCHECK_GT(num_streams, 0); |
| 143 HostPortPair origin_server = | 143 HostPortPair origin_server = HostPortPair( |
| 144 HostPortPair(request_info_.url.HostNoBrackets(), | 144 request_info_.url.HostNoBrackets(), request_info_.url.EffectiveIntPort()); |
| 145 request_info_.url.EffectiveIntPort()); | |
| 146 base::WeakPtr<HttpServerProperties> http_server_properties = | 145 base::WeakPtr<HttpServerProperties> http_server_properties = |
| 147 session_->http_server_properties(); | 146 session_->http_server_properties(); |
| 148 if (http_server_properties && | 147 if (http_server_properties && |
| 149 http_server_properties->SupportsSpdy(origin_server)) { | 148 http_server_properties->SupportsSpdy(origin_server)) { |
| 150 num_streams_ = 1; | 149 num_streams_ = 1; |
| 151 } else { | 150 } else { |
| 152 num_streams_ = num_streams; | 151 num_streams_ = num_streams; |
| 153 } | 152 } |
| 154 return StartInternal(); | 153 return StartInternal(); |
| 155 } | 154 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 void HttpStreamFactoryImpl::Job::Resume(Job* job) { | 196 void HttpStreamFactoryImpl::Job::Resume(Job* job) { |
| 198 DCHECK_EQ(blocking_job_, job); | 197 DCHECK_EQ(blocking_job_, job); |
| 199 blocking_job_ = NULL; | 198 blocking_job_ = NULL; |
| 200 | 199 |
| 201 // We know we're blocked if the next_state_ is STATE_WAIT_FOR_JOB_COMPLETE. | 200 // We know we're blocked if the next_state_ is STATE_WAIT_FOR_JOB_COMPLETE. |
| 202 // Unblock |this|. | 201 // Unblock |this|. |
| 203 if (next_state_ == STATE_WAIT_FOR_JOB_COMPLETE) { | 202 if (next_state_ == STATE_WAIT_FOR_JOB_COMPLETE) { |
| 204 base::MessageLoop::current()->PostTask( | 203 base::MessageLoop::current()->PostTask( |
| 205 FROM_HERE, | 204 FROM_HERE, |
| 206 base::Bind(&HttpStreamFactoryImpl::Job::OnIOComplete, | 205 base::Bind(&HttpStreamFactoryImpl::Job::OnIOComplete, |
| 207 ptr_factory_.GetWeakPtr(), OK)); | 206 ptr_factory_.GetWeakPtr(), |
| 207 OK)); |
| 208 } | 208 } |
| 209 } | 209 } |
| 210 | 210 |
| 211 void HttpStreamFactoryImpl::Job::Orphan(const Request* request) { | 211 void HttpStreamFactoryImpl::Job::Orphan(const Request* request) { |
| 212 DCHECK_EQ(request_, request); | 212 DCHECK_EQ(request_, request); |
| 213 request_ = NULL; | 213 request_ = NULL; |
| 214 if (blocking_job_) { | 214 if (blocking_job_) { |
| 215 // We've been orphaned, but there's a job we're blocked on. Don't bother | 215 // We've been orphaned, but there's a job we're blocked on. Don't bother |
| 216 // racing, just cancel ourself. | 216 // racing, just cancel ourself. |
| 217 DCHECK(blocking_job_->waiting_job_); | 217 DCHECK(blocking_job_->waiting_job_); |
| 218 blocking_job_->waiting_job_ = NULL; | 218 blocking_job_->waiting_job_ = NULL; |
| 219 blocking_job_ = NULL; | 219 blocking_job_ = NULL; |
| 220 if (stream_factory_->for_websockets_ && | 220 if (stream_factory_->for_websockets_ && connection_ && |
| 221 connection_ && connection_->socket()) | 221 connection_->socket()) |
| 222 connection_->socket()->Disconnect(); | 222 connection_->socket()->Disconnect(); |
| 223 stream_factory_->OnOrphanedJobComplete(this); | 223 stream_factory_->OnOrphanedJobComplete(this); |
| 224 } else if (stream_factory_->for_websockets_) { | 224 } else if (stream_factory_->for_websockets_) { |
| 225 // We cancel this job because a WebSocketHandshakeStream can't be created | 225 // We cancel this job because a WebSocketHandshakeStream can't be created |
| 226 // without a WebSocketHandshakeStreamBase::CreateHelper which is stored in | 226 // without a WebSocketHandshakeStreamBase::CreateHelper which is stored in |
| 227 // the Request class and isn't accessible from this job. | 227 // the Request class and isn't accessible from this job. |
| 228 if (connection_ && connection_->socket()) | 228 if (connection_ && connection_->socket()) |
| 229 connection_->socket()->Disconnect(); | 229 connection_->socket()->Disconnect(); |
| 230 stream_factory_->OnOrphanedJobComplete(this); | 230 stream_factory_->OnOrphanedJobComplete(this); |
| 231 } | 231 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 SpdySessionKey HttpStreamFactoryImpl::Job::GetSpdySessionKey() const { | 273 SpdySessionKey HttpStreamFactoryImpl::Job::GetSpdySessionKey() const { |
| 274 // In the case that we're using an HTTPS proxy for an HTTP url, | 274 // In the case that we're using an HTTPS proxy for an HTTP url, |
| 275 // we look for a SPDY session *to* the proxy, instead of to the | 275 // we look for a SPDY session *to* the proxy, instead of to the |
| 276 // origin server. | 276 // origin server. |
| 277 PrivacyMode privacy_mode = request_info_.privacy_mode; | 277 PrivacyMode privacy_mode = request_info_.privacy_mode; |
| 278 if (IsHttpsProxyAndHttpUrl()) { | 278 if (IsHttpsProxyAndHttpUrl()) { |
| 279 return SpdySessionKey(proxy_info_.proxy_server().host_port_pair(), | 279 return SpdySessionKey(proxy_info_.proxy_server().host_port_pair(), |
| 280 ProxyServer::Direct(), | 280 ProxyServer::Direct(), |
| 281 privacy_mode); | 281 privacy_mode); |
| 282 } else { | 282 } else { |
| 283 return SpdySessionKey(origin_, | 283 return SpdySessionKey(origin_, proxy_info_.proxy_server(), privacy_mode); |
| 284 proxy_info_.proxy_server(), | |
| 285 privacy_mode); | |
| 286 } | 284 } |
| 287 } | 285 } |
| 288 | 286 |
| 289 bool HttpStreamFactoryImpl::Job::CanUseExistingSpdySession() const { | 287 bool HttpStreamFactoryImpl::Job::CanUseExistingSpdySession() const { |
| 290 // We need to make sure that if a spdy session was created for | 288 // We need to make sure that if a spdy session was created for |
| 291 // https://somehost/ that we don't use that session for http://somehost:443/. | 289 // https://somehost/ that we don't use that session for http://somehost:443/. |
| 292 // The only time we can use an existing session is if the request URL is | 290 // The only time we can use an existing session is if the request URL is |
| 293 // https (the normal case) or if we're connection to a SPDY proxy, or | 291 // https (the normal case) or if we're connection to a SPDY proxy, or |
| 294 // if we're running with force_spdy_always_. crbug.com/133176 | 292 // if we're running with force_spdy_always_. crbug.com/133176 |
| 295 // TODO(ricea): Add "wss" back to this list when SPDY WebSocket support is | 293 // TODO(ricea): Add "wss" back to this list when SPDY WebSocket support is |
| 296 // working. | 294 // working. |
| 297 return request_info_.url.SchemeIs("https") || | 295 return request_info_.url.SchemeIs("https") || |
| 298 proxy_info_.proxy_server().is_https() || | 296 proxy_info_.proxy_server().is_https() || force_spdy_always_; |
| 299 force_spdy_always_; | |
| 300 } | 297 } |
| 301 | 298 |
| 302 void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() { | 299 void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() { |
| 303 DCHECK(stream_.get()); | 300 DCHECK(stream_.get()); |
| 304 DCHECK(!IsPreconnecting()); | 301 DCHECK(!IsPreconnecting()); |
| 305 DCHECK(!stream_factory_->for_websockets_); | 302 DCHECK(!stream_factory_->for_websockets_); |
| 306 if (IsOrphaned()) { | 303 if (IsOrphaned()) { |
| 307 stream_factory_->OnOrphanedJobComplete(this); | 304 stream_factory_->OnOrphanedJobComplete(this); |
| 308 } else { | 305 } else { |
| 309 request_->Complete(was_npn_negotiated(), | 306 request_->Complete( |
| 310 protocol_negotiated(), | 307 was_npn_negotiated(), protocol_negotiated(), using_spdy(), net_log_); |
| 311 using_spdy(), | 308 request_->OnStreamReady( |
| 312 net_log_); | 309 this, server_ssl_config_, proxy_info_, stream_.release()); |
| 313 request_->OnStreamReady(this, server_ssl_config_, proxy_info_, | |
| 314 stream_.release()); | |
| 315 } | 310 } |
| 316 // |this| may be deleted after this call. | 311 // |this| may be deleted after this call. |
| 317 } | 312 } |
| 318 | 313 |
| 319 void HttpStreamFactoryImpl::Job::OnWebSocketHandshakeStreamReadyCallback() { | 314 void HttpStreamFactoryImpl::Job::OnWebSocketHandshakeStreamReadyCallback() { |
| 320 DCHECK(websocket_stream_); | 315 DCHECK(websocket_stream_); |
| 321 DCHECK(!IsPreconnecting()); | 316 DCHECK(!IsPreconnecting()); |
| 322 DCHECK(stream_factory_->for_websockets_); | 317 DCHECK(stream_factory_->for_websockets_); |
| 323 // An orphaned WebSocket job will be closed immediately and | 318 // An orphaned WebSocket job will be closed immediately and |
| 324 // never be ready. | 319 // never be ready. |
| 325 DCHECK(!IsOrphaned()); | 320 DCHECK(!IsOrphaned()); |
| 326 request_->Complete(was_npn_negotiated(), | 321 request_->Complete( |
| 327 protocol_negotiated(), | 322 was_npn_negotiated(), protocol_negotiated(), using_spdy(), net_log_); |
| 328 using_spdy(), | 323 request_->OnWebSocketHandshakeStreamReady( |
| 329 net_log_); | 324 this, server_ssl_config_, proxy_info_, websocket_stream_.release()); |
| 330 request_->OnWebSocketHandshakeStreamReady(this, | |
| 331 server_ssl_config_, | |
| 332 proxy_info_, | |
| 333 websocket_stream_.release()); | |
| 334 // |this| may be deleted after this call. | 325 // |this| may be deleted after this call. |
| 335 } | 326 } |
| 336 | 327 |
| 337 void HttpStreamFactoryImpl::Job::OnNewSpdySessionReadyCallback() { | 328 void HttpStreamFactoryImpl::Job::OnNewSpdySessionReadyCallback() { |
| 338 DCHECK(stream_.get()); | 329 DCHECK(stream_.get()); |
| 339 DCHECK(!IsPreconnecting()); | 330 DCHECK(!IsPreconnecting()); |
| 340 DCHECK(using_spdy()); | 331 DCHECK(using_spdy()); |
| 341 // Note: an event loop iteration has passed, so |new_spdy_session_| may be | 332 // Note: an event loop iteration has passed, so |new_spdy_session_| may be |
| 342 // NULL at this point if the SpdySession closed immediately after creation. | 333 // NULL at this point if the SpdySession closed immediately after creation. |
| 343 base::WeakPtr<SpdySession> spdy_session = new_spdy_session_; | 334 base::WeakPtr<SpdySession> spdy_session = new_spdy_session_; |
| 344 new_spdy_session_.reset(); | 335 new_spdy_session_.reset(); |
| 345 if (IsOrphaned()) { | 336 if (IsOrphaned()) { |
| 346 if (spdy_session) { | 337 if (spdy_session) { |
| 347 stream_factory_->OnNewSpdySessionReady( | 338 stream_factory_->OnNewSpdySessionReady(spdy_session, |
| 348 spdy_session, spdy_session_direct_, server_ssl_config_, proxy_info_, | 339 spdy_session_direct_, |
| 349 was_npn_negotiated(), protocol_negotiated(), using_spdy(), net_log_); | 340 server_ssl_config_, |
| 341 proxy_info_, |
| 342 was_npn_negotiated(), |
| 343 protocol_negotiated(), |
| 344 using_spdy(), |
| 345 net_log_); |
| 350 } | 346 } |
| 351 stream_factory_->OnOrphanedJobComplete(this); | 347 stream_factory_->OnOrphanedJobComplete(this); |
| 352 } else { | 348 } else { |
| 353 request_->OnNewSpdySessionReady( | 349 request_->OnNewSpdySessionReady( |
| 354 this, stream_.Pass(), spdy_session, spdy_session_direct_); | 350 this, stream_.Pass(), spdy_session, spdy_session_direct_); |
| 355 } | 351 } |
| 356 // |this| may be deleted after this call. | 352 // |this| may be deleted after this call. |
| 357 } | 353 } |
| 358 | 354 |
| 359 void HttpStreamFactoryImpl::Job::OnStreamFailedCallback(int result) { | 355 void HttpStreamFactoryImpl::Job::OnStreamFailedCallback(int result) { |
| 360 DCHECK(!IsPreconnecting()); | 356 DCHECK(!IsPreconnecting()); |
| 361 if (IsOrphaned()) | 357 if (IsOrphaned()) |
| 362 stream_factory_->OnOrphanedJobComplete(this); | 358 stream_factory_->OnOrphanedJobComplete(this); |
| 363 else | 359 else |
| 364 request_->OnStreamFailed(this, result, server_ssl_config_); | 360 request_->OnStreamFailed(this, result, server_ssl_config_); |
| 365 // |this| may be deleted after this call. | 361 // |this| may be deleted after this call. |
| 366 } | 362 } |
| 367 | 363 |
| 368 void HttpStreamFactoryImpl::Job::OnCertificateErrorCallback( | 364 void HttpStreamFactoryImpl::Job::OnCertificateErrorCallback( |
| 369 int result, const SSLInfo& ssl_info) { | 365 int result, |
| 366 const SSLInfo& ssl_info) { |
| 370 DCHECK(!IsPreconnecting()); | 367 DCHECK(!IsPreconnecting()); |
| 371 if (IsOrphaned()) | 368 if (IsOrphaned()) |
| 372 stream_factory_->OnOrphanedJobComplete(this); | 369 stream_factory_->OnOrphanedJobComplete(this); |
| 373 else | 370 else |
| 374 request_->OnCertificateError(this, result, server_ssl_config_, ssl_info); | 371 request_->OnCertificateError(this, result, server_ssl_config_, ssl_info); |
| 375 // |this| may be deleted after this call. | 372 // |this| may be deleted after this call. |
| 376 } | 373 } |
| 377 | 374 |
| 378 void HttpStreamFactoryImpl::Job::OnNeedsProxyAuthCallback( | 375 void HttpStreamFactoryImpl::Job::OnNeedsProxyAuthCallback( |
| 379 const HttpResponseInfo& response, | 376 const HttpResponseInfo& response, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 | 424 |
| 428 // static | 425 // static |
| 429 int HttpStreamFactoryImpl::Job::OnHostResolution( | 426 int HttpStreamFactoryImpl::Job::OnHostResolution( |
| 430 SpdySessionPool* spdy_session_pool, | 427 SpdySessionPool* spdy_session_pool, |
| 431 const SpdySessionKey& spdy_session_key, | 428 const SpdySessionKey& spdy_session_key, |
| 432 const AddressList& addresses, | 429 const AddressList& addresses, |
| 433 const BoundNetLog& net_log) { | 430 const BoundNetLog& net_log) { |
| 434 // It is OK to dereference spdy_session_pool, because the | 431 // It is OK to dereference spdy_session_pool, because the |
| 435 // ClientSocketPoolManager will be destroyed in the same callback that | 432 // ClientSocketPoolManager will be destroyed in the same callback that |
| 436 // destroys the SpdySessionPool. | 433 // destroys the SpdySessionPool. |
| 437 return | 434 return spdy_session_pool->FindAvailableSession(spdy_session_key, net_log) |
| 438 spdy_session_pool->FindAvailableSession(spdy_session_key, net_log) ? | 435 ? ERR_SPDY_SESSION_ALREADY_EXISTS |
| 439 ERR_SPDY_SESSION_ALREADY_EXISTS : OK; | 436 : OK; |
| 440 } | 437 } |
| 441 | 438 |
| 442 void HttpStreamFactoryImpl::Job::OnIOComplete(int result) { | 439 void HttpStreamFactoryImpl::Job::OnIOComplete(int result) { |
| 443 RunLoop(result); | 440 RunLoop(result); |
| 444 } | 441 } |
| 445 | 442 |
| 446 int HttpStreamFactoryImpl::Job::RunLoop(int result) { | 443 int HttpStreamFactoryImpl::Job::RunLoop(int result) { |
| 447 result = DoLoop(result); | 444 result = DoLoop(result); |
| 448 | 445 |
| 449 if (result == ERR_IO_PENDING) | 446 if (result == ERR_IO_PENDING) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 462 } | 459 } |
| 463 | 460 |
| 464 if (IsCertificateError(result)) { | 461 if (IsCertificateError(result)) { |
| 465 // Retrieve SSL information from the socket. | 462 // Retrieve SSL information from the socket. |
| 466 GetSSLInfo(); | 463 GetSSLInfo(); |
| 467 | 464 |
| 468 next_state_ = STATE_WAITING_USER_ACTION; | 465 next_state_ = STATE_WAITING_USER_ACTION; |
| 469 base::MessageLoop::current()->PostTask( | 466 base::MessageLoop::current()->PostTask( |
| 470 FROM_HERE, | 467 FROM_HERE, |
| 471 base::Bind(&HttpStreamFactoryImpl::Job::OnCertificateErrorCallback, | 468 base::Bind(&HttpStreamFactoryImpl::Job::OnCertificateErrorCallback, |
| 472 ptr_factory_.GetWeakPtr(), result, ssl_info_)); | 469 ptr_factory_.GetWeakPtr(), |
| 470 result, |
| 471 ssl_info_)); |
| 473 return ERR_IO_PENDING; | 472 return ERR_IO_PENDING; |
| 474 } | 473 } |
| 475 | 474 |
| 476 switch (result) { | 475 switch (result) { |
| 477 case ERR_PROXY_AUTH_REQUESTED: { | 476 case ERR_PROXY_AUTH_REQUESTED: { |
| 478 DCHECK(connection_.get()); | 477 DCHECK(connection_.get()); |
| 479 DCHECK(connection_->socket()); | 478 DCHECK(connection_->socket()); |
| 480 DCHECK(establishing_tunnel_); | 479 DCHECK(establishing_tunnel_); |
| 481 | 480 |
| 482 next_state_ = STATE_WAITING_USER_ACTION; | 481 next_state_ = STATE_WAITING_USER_ACTION; |
| 483 ProxyClientSocket* proxy_socket = | 482 ProxyClientSocket* proxy_socket = |
| 484 static_cast<ProxyClientSocket*>(connection_->socket()); | 483 static_cast<ProxyClientSocket*>(connection_->socket()); |
| 485 base::MessageLoop::current()->PostTask( | 484 base::MessageLoop::current()->PostTask( |
| 486 FROM_HERE, | 485 FROM_HERE, |
| 487 base::Bind(&Job::OnNeedsProxyAuthCallback, ptr_factory_.GetWeakPtr(), | 486 base::Bind(&Job::OnNeedsProxyAuthCallback, |
| 487 ptr_factory_.GetWeakPtr(), |
| 488 *proxy_socket->GetConnectResponseInfo(), | 488 *proxy_socket->GetConnectResponseInfo(), |
| 489 proxy_socket->GetAuthController())); | 489 proxy_socket->GetAuthController())); |
| 490 return ERR_IO_PENDING; | 490 return ERR_IO_PENDING; |
| 491 } | 491 } |
| 492 | 492 |
| 493 case ERR_SSL_CLIENT_AUTH_CERT_NEEDED: | 493 case ERR_SSL_CLIENT_AUTH_CERT_NEEDED: |
| 494 base::MessageLoop::current()->PostTask( | 494 base::MessageLoop::current()->PostTask( |
| 495 FROM_HERE, | 495 FROM_HERE, |
| 496 base::Bind(&Job::OnNeedsClientAuthCallback, ptr_factory_.GetWeakPtr(), | 496 base::Bind(&Job::OnNeedsClientAuthCallback, |
| 497 ptr_factory_.GetWeakPtr(), |
| 497 connection_->ssl_error_response_info().cert_request_info)); | 498 connection_->ssl_error_response_info().cert_request_info)); |
| 498 return ERR_IO_PENDING; | 499 return ERR_IO_PENDING; |
| 499 | 500 |
| 500 case ERR_HTTPS_PROXY_TUNNEL_RESPONSE: { | 501 case ERR_HTTPS_PROXY_TUNNEL_RESPONSE: { |
| 501 DCHECK(connection_.get()); | 502 DCHECK(connection_.get()); |
| 502 DCHECK(connection_->socket()); | 503 DCHECK(connection_->socket()); |
| 503 DCHECK(establishing_tunnel_); | 504 DCHECK(establishing_tunnel_); |
| 504 | 505 |
| 505 ProxyClientSocket* proxy_socket = | 506 ProxyClientSocket* proxy_socket = |
| 506 static_cast<ProxyClientSocket*>(connection_->socket()); | 507 static_cast<ProxyClientSocket*>(connection_->socket()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 530 DCHECK(stream_.get()); | 531 DCHECK(stream_.get()); |
| 531 base::MessageLoop::current()->PostTask( | 532 base::MessageLoop::current()->PostTask( |
| 532 FROM_HERE, | 533 FROM_HERE, |
| 533 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); | 534 base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); |
| 534 } | 535 } |
| 535 return ERR_IO_PENDING; | 536 return ERR_IO_PENDING; |
| 536 | 537 |
| 537 default: | 538 default: |
| 538 base::MessageLoop::current()->PostTask( | 539 base::MessageLoop::current()->PostTask( |
| 539 FROM_HERE, | 540 FROM_HERE, |
| 540 base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), | 541 base::Bind( |
| 541 result)); | 542 &Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), result)); |
| 542 return ERR_IO_PENDING; | 543 return ERR_IO_PENDING; |
| 543 } | 544 } |
| 544 } | 545 } |
| 545 | 546 |
| 546 int HttpStreamFactoryImpl::Job::DoLoop(int result) { | 547 int HttpStreamFactoryImpl::Job::DoLoop(int result) { |
| 547 DCHECK_NE(next_state_, STATE_NONE); | 548 DCHECK_NE(next_state_, STATE_NONE); |
| 548 int rv = result; | 549 int rv = result; |
| 549 do { | 550 do { |
| 550 State state = next_state_; | 551 State state = next_state_; |
| 551 next_state_ = STATE_NONE; | 552 next_state_ = STATE_NONE; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 CHECK_EQ(STATE_NONE, next_state_); | 606 CHECK_EQ(STATE_NONE, next_state_); |
| 606 next_state_ = STATE_START; | 607 next_state_ = STATE_START; |
| 607 int rv = RunLoop(OK); | 608 int rv = RunLoop(OK); |
| 608 DCHECK_EQ(ERR_IO_PENDING, rv); | 609 DCHECK_EQ(ERR_IO_PENDING, rv); |
| 609 return rv; | 610 return rv; |
| 610 } | 611 } |
| 611 | 612 |
| 612 int HttpStreamFactoryImpl::Job::DoStart() { | 613 int HttpStreamFactoryImpl::Job::DoStart() { |
| 613 int port = request_info_.url.EffectiveIntPort(); | 614 int port = request_info_.url.EffectiveIntPort(); |
| 614 origin_ = HostPortPair(request_info_.url.HostNoBrackets(), port); | 615 origin_ = HostPortPair(request_info_.url.HostNoBrackets(), port); |
| 615 origin_url_ = stream_factory_->ApplyHostMappingRules( | 616 origin_url_ = |
| 616 request_info_.url, &origin_); | 617 stream_factory_->ApplyHostMappingRules(request_info_.url, &origin_); |
| 617 http_pipelining_key_.reset(new HttpPipelinedHost::Key(origin_)); | 618 http_pipelining_key_.reset(new HttpPipelinedHost::Key(origin_)); |
| 618 | 619 |
| 619 net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_JOB, | 620 net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_JOB, |
| 620 base::Bind(&NetLogHttpStreamJobCallback, | 621 base::Bind(&NetLogHttpStreamJobCallback, |
| 621 &request_info_.url, &origin_url_, | 622 &request_info_.url, |
| 623 &origin_url_, |
| 622 priority_)); | 624 priority_)); |
| 623 | 625 |
| 624 // Don't connect to restricted ports. | 626 // Don't connect to restricted ports. |
| 625 bool is_port_allowed = IsPortAllowedByDefault(port); | 627 bool is_port_allowed = IsPortAllowedByDefault(port); |
| 626 if (request_info_.url.SchemeIs("ftp")) { | 628 if (request_info_.url.SchemeIs("ftp")) { |
| 627 // Never share connection with other jobs for FTP requests. | 629 // Never share connection with other jobs for FTP requests. |
| 628 DCHECK(!waiting_job_); | 630 DCHECK(!waiting_job_); |
| 629 | 631 |
| 630 is_port_allowed = IsPortAllowedByFtp(port); | 632 is_port_allowed = IsPortAllowedByFtp(port); |
| 631 } | 633 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 return rv && !HttpStreamFactory::HasSpdyExclusion(origin_); | 699 return rv && !HttpStreamFactory::HasSpdyExclusion(origin_); |
| 698 } | 700 } |
| 699 | 701 |
| 700 bool HttpStreamFactoryImpl::Job::ShouldForceSpdyWithoutSSL() const { | 702 bool HttpStreamFactoryImpl::Job::ShouldForceSpdyWithoutSSL() const { |
| 701 bool rv = force_spdy_always_ && !force_spdy_over_ssl_; | 703 bool rv = force_spdy_always_ && !force_spdy_over_ssl_; |
| 702 return rv && !HttpStreamFactory::HasSpdyExclusion(origin_); | 704 return rv && !HttpStreamFactory::HasSpdyExclusion(origin_); |
| 703 } | 705 } |
| 704 | 706 |
| 705 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { | 707 bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { |
| 706 return session_->params().enable_quic && | 708 return session_->params().enable_quic && |
| 707 session_->params().origin_to_force_quic_on.Equals(origin_) && | 709 session_->params().origin_to_force_quic_on.Equals(origin_) && |
| 708 proxy_info_.is_direct(); | 710 proxy_info_.is_direct(); |
| 709 } | 711 } |
| 710 | 712 |
| 711 int HttpStreamFactoryImpl::Job::DoWaitForJob() { | 713 int HttpStreamFactoryImpl::Job::DoWaitForJob() { |
| 712 DCHECK(blocking_job_); | 714 DCHECK(blocking_job_); |
| 713 next_state_ = STATE_WAIT_FOR_JOB_COMPLETE; | 715 next_state_ = STATE_WAIT_FOR_JOB_COMPLETE; |
| 714 return ERR_IO_PENDING; | 716 return ERR_IO_PENDING; |
| 715 } | 717 } |
| 716 | 718 |
| 717 int HttpStreamFactoryImpl::Job::DoWaitForJobComplete(int result) { | 719 int HttpStreamFactoryImpl::Job::DoWaitForJobComplete(int result) { |
| 718 DCHECK(!blocking_job_); | 720 DCHECK(!blocking_job_); |
| 719 DCHECK_EQ(OK, result); | 721 DCHECK_EQ(OK, result); |
| 720 next_state_ = STATE_INIT_CONNECTION; | 722 next_state_ = STATE_INIT_CONNECTION; |
| 721 return OK; | 723 return OK; |
| 722 } | 724 } |
| 723 | 725 |
| 724 int HttpStreamFactoryImpl::Job::DoInitConnection() { | 726 int HttpStreamFactoryImpl::Job::DoInitConnection() { |
| 725 DCHECK(!blocking_job_); | 727 DCHECK(!blocking_job_); |
| 726 DCHECK(!connection_->is_initialized()); | 728 DCHECK(!connection_->is_initialized()); |
| 727 DCHECK(proxy_info_.proxy_server().is_valid()); | 729 DCHECK(proxy_info_.proxy_server().is_valid()); |
| 728 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 730 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
| 729 | 731 |
| 730 using_ssl_ = request_info_.url.SchemeIs("https") || | 732 using_ssl_ = request_info_.url.SchemeIs("https") || |
| 731 request_info_.url.SchemeIs("wss") || ShouldForceSpdySSL(); | 733 request_info_.url.SchemeIs("wss") || ShouldForceSpdySSL(); |
| 732 using_spdy_ = false; | 734 using_spdy_ = false; |
| 733 | 735 |
| 734 if (ShouldForceQuic()) | 736 if (ShouldForceQuic()) |
| 735 using_quic_ = true; | 737 using_quic_ = true; |
| 736 | 738 |
| 737 if (proxy_info_.is_quic()) | 739 if (proxy_info_.is_quic()) |
| 738 using_quic_ = true; | 740 using_quic_ = true; |
| 739 | 741 |
| 740 if (using_quic_) { | 742 if (using_quic_) { |
| 741 DCHECK(session_->params().enable_quic); | 743 DCHECK(session_->params().enable_quic); |
| 742 if (proxy_info_.is_quic() && !request_info_.url.SchemeIs("http")) { | 744 if (proxy_info_.is_quic() && !request_info_.url.SchemeIs("http")) { |
| 743 NOTREACHED(); | 745 NOTREACHED(); |
| 744 // TODO(rch): support QUIC proxies for HTTPS urls. | 746 // TODO(rch): support QUIC proxies for HTTPS urls. |
| 745 return ERR_NOT_IMPLEMENTED; | 747 return ERR_NOT_IMPLEMENTED; |
| 746 } | 748 } |
| 747 HostPortPair destination = proxy_info_.is_quic() ? | 749 HostPortPair destination = proxy_info_.is_quic() |
| 748 proxy_info_.proxy_server().host_port_pair() : origin_; | 750 ? proxy_info_.proxy_server().host_port_pair() |
| 751 : origin_; |
| 749 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 752 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
| 750 bool secure_quic = using_ssl_ || proxy_info_.is_quic(); | 753 bool secure_quic = using_ssl_ || proxy_info_.is_quic(); |
| 751 int rv = quic_request_.Request( | 754 int rv = quic_request_.Request(destination, |
| 752 destination, secure_quic, request_info_.privacy_mode, | 755 secure_quic, |
| 753 request_info_.method, net_log_, io_callback_); | 756 request_info_.privacy_mode, |
| 757 request_info_.method, |
| 758 net_log_, |
| 759 io_callback_); |
| 754 if (rv == OK) { | 760 if (rv == OK) { |
| 755 using_existing_quic_session_ = true; | 761 using_existing_quic_session_ = true; |
| 756 } else { | 762 } else { |
| 757 // OK, there's no available QUIC session. Let |waiting_job_| resume | 763 // OK, there's no available QUIC session. Let |waiting_job_| resume |
| 758 // if it's paused. | 764 // if it's paused. |
| 759 if (waiting_job_) { | 765 if (waiting_job_) { |
| 760 waiting_job_->Resume(this); | 766 waiting_job_->Resume(this); |
| 761 waiting_job_ = NULL; | 767 waiting_job_ = NULL; |
| 762 } | 768 } |
| 763 } | 769 } |
| 764 return rv; | 770 return rv; |
| 765 } | 771 } |
| 766 | 772 |
| 767 // Check first if we have a spdy session for this group. If so, then go | 773 // Check first if we have a spdy session for this group. If so, then go |
| 768 // straight to using that. | 774 // straight to using that. |
| 769 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 775 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| 770 base::WeakPtr<SpdySession> spdy_session = | 776 base::WeakPtr<SpdySession> spdy_session = |
| 771 session_->spdy_session_pool()->FindAvailableSession( | 777 session_->spdy_session_pool()->FindAvailableSession(spdy_session_key, |
| 772 spdy_session_key, net_log_); | 778 net_log_); |
| 773 if (spdy_session && CanUseExistingSpdySession()) { | 779 if (spdy_session && CanUseExistingSpdySession()) { |
| 774 // If we're preconnecting, but we already have a SpdySession, we don't | 780 // If we're preconnecting, but we already have a SpdySession, we don't |
| 775 // actually need to preconnect any sockets, so we're done. | 781 // actually need to preconnect any sockets, so we're done. |
| 776 if (IsPreconnecting()) | 782 if (IsPreconnecting()) |
| 777 return OK; | 783 return OK; |
| 778 using_spdy_ = true; | 784 using_spdy_ = true; |
| 779 next_state_ = STATE_CREATE_STREAM; | 785 next_state_ = STATE_CREATE_STREAM; |
| 780 existing_spdy_session_ = spdy_session; | 786 existing_spdy_session_ = spdy_session; |
| 781 return OK; | 787 return OK; |
| 782 } else if (request_ && (using_ssl_ || ShouldForceSpdyWithoutSSL())) { | 788 } else if (request_ && (using_ssl_ || ShouldForceSpdyWithoutSSL())) { |
| 783 // Update the spdy session key for the request that launched this job. | 789 // Update the spdy session key for the request that launched this job. |
| 784 request_->SetSpdySessionKey(spdy_session_key); | 790 request_->SetSpdySessionKey(spdy_session_key); |
| 785 } else if (IsRequestEligibleForPipelining()) { | 791 } else if (IsRequestEligibleForPipelining()) { |
| 786 // TODO(simonjam): With pipelining, we might be better off using fewer | 792 // TODO(simonjam): With pipelining, we might be better off using fewer |
| 787 // connections and thus should make fewer preconnections. Explore | 793 // connections and thus should make fewer preconnections. Explore |
| 788 // preconnecting fewer than the requested num_connections. | 794 // preconnecting fewer than the requested num_connections. |
| 789 // | 795 // |
| 790 // Separate note: A forced pipeline is always available if one exists for | 796 // Separate note: A forced pipeline is always available if one exists for |
| 791 // this key. This is different than normal pipelines, which may be | 797 // this key. This is different than normal pipelines, which may be |
| 792 // unavailable or unusable. So, there is no need to worry about a race | 798 // unavailable or unusable. So, there is no need to worry about a race |
| 793 // between when a pipeline becomes available and when this job blocks. | 799 // between when a pipeline becomes available and when this job blocks. |
| 794 existing_available_pipeline_ = stream_factory_->http_pipelined_host_pool_. | 800 existing_available_pipeline_ = |
| 795 IsExistingPipelineAvailableForKey(*http_pipelining_key_.get()); | 801 stream_factory_->http_pipelined_host_pool_ |
| 802 .IsExistingPipelineAvailableForKey(*http_pipelining_key_.get()); |
| 796 if (existing_available_pipeline_) { | 803 if (existing_available_pipeline_) { |
| 797 return OK; | 804 return OK; |
| 798 } else { | 805 } else { |
| 799 bool was_new_key = request_->SetHttpPipeliningKey( | 806 bool was_new_key = |
| 800 *http_pipelining_key_.get()); | 807 request_->SetHttpPipeliningKey(*http_pipelining_key_.get()); |
| 801 if (!was_new_key && session_->force_http_pipelining()) { | 808 if (!was_new_key && session_->force_http_pipelining()) { |
| 802 return ERR_IO_PENDING; | 809 return ERR_IO_PENDING; |
| 803 } | 810 } |
| 804 } | 811 } |
| 805 } | 812 } |
| 806 | 813 |
| 807 // OK, there's no available SPDY session. Let |waiting_job_| resume if it's | 814 // OK, there's no available SPDY session. Let |waiting_job_| resume if it's |
| 808 // paused. | 815 // paused. |
| 809 | 816 |
| 810 if (waiting_job_) { | 817 if (waiting_job_) { |
| 811 waiting_job_->Resume(this); | 818 waiting_job_->Resume(this); |
| 812 waiting_job_ = NULL; | 819 waiting_job_ = NULL; |
| 813 } | 820 } |
| 814 | 821 |
| 815 if (proxy_info_.is_http() || proxy_info_.is_https()) | 822 if (proxy_info_.is_http() || proxy_info_.is_https()) |
| 816 establishing_tunnel_ = using_ssl_; | 823 establishing_tunnel_ = using_ssl_; |
| 817 | 824 |
| 818 bool want_spdy_over_npn = original_url_ != NULL; | 825 bool want_spdy_over_npn = original_url_ != NULL; |
| 819 | 826 |
| 820 if (proxy_info_.is_https()) { | 827 if (proxy_info_.is_https()) { |
| 821 InitSSLConfig(proxy_info_.proxy_server().host_port_pair(), | 828 InitSSLConfig(proxy_info_.proxy_server().host_port_pair(), |
| 822 &proxy_ssl_config_, | 829 &proxy_ssl_config_, |
| 823 true /* is a proxy server */); | 830 true /* is a proxy server */); |
| 824 // Disable revocation checking for HTTPS proxies since the revocation | 831 // Disable revocation checking for HTTPS proxies since the revocation |
| 825 // requests are probably going to need to go through the proxy too. | 832 // requests are probably going to need to go through the proxy too. |
| 826 proxy_ssl_config_.rev_checking_enabled = false; | 833 proxy_ssl_config_.rev_checking_enabled = false; |
| 827 } | 834 } |
| 828 if (using_ssl_) { | 835 if (using_ssl_) { |
| 829 InitSSLConfig(origin_, &server_ssl_config_, | 836 InitSSLConfig(origin_, &server_ssl_config_, false /* not a proxy server */); |
| 830 false /* not a proxy server */); | |
| 831 } | 837 } |
| 832 | 838 |
| 833 if (IsPreconnecting()) { | 839 if (IsPreconnecting()) { |
| 834 DCHECK(!stream_factory_->for_websockets_); | 840 DCHECK(!stream_factory_->for_websockets_); |
| 835 return PreconnectSocketsForHttpRequest( | 841 return PreconnectSocketsForHttpRequest(origin_url_, |
| 836 origin_url_, | 842 request_info_.extra_headers, |
| 837 request_info_.extra_headers, | 843 request_info_.load_flags, |
| 838 request_info_.load_flags, | 844 priority_, |
| 839 priority_, | 845 session_, |
| 840 session_, | 846 proxy_info_, |
| 841 proxy_info_, | 847 ShouldForceSpdySSL(), |
| 842 ShouldForceSpdySSL(), | 848 want_spdy_over_npn, |
| 843 want_spdy_over_npn, | 849 server_ssl_config_, |
| 844 server_ssl_config_, | 850 proxy_ssl_config_, |
| 845 proxy_ssl_config_, | 851 request_info_.privacy_mode, |
| 846 request_info_.privacy_mode, | 852 net_log_, |
| 847 net_log_, | 853 num_streams_); |
| 848 num_streams_); | |
| 849 } else { | 854 } else { |
| 850 // If we can't use a SPDY session, don't both checking for one after | 855 // If we can't use a SPDY session, don't both checking for one after |
| 851 // the hostname is resolved. | 856 // the hostname is resolved. |
| 852 OnHostResolutionCallback resolution_callback = CanUseExistingSpdySession() ? | 857 OnHostResolutionCallback resolution_callback = |
| 853 base::Bind(&Job::OnHostResolution, session_->spdy_session_pool(), | 858 CanUseExistingSpdySession() ? base::Bind(&Job::OnHostResolution, |
| 854 GetSpdySessionKey()) : | 859 session_->spdy_session_pool(), |
| 855 OnHostResolutionCallback(); | 860 GetSpdySessionKey()) |
| 861 : OnHostResolutionCallback(); |
| 856 if (stream_factory_->for_websockets_) { | 862 if (stream_factory_->for_websockets_) { |
| 857 // TODO(ricea): Re-enable NPN when WebSockets over SPDY is supported. | 863 // TODO(ricea): Re-enable NPN when WebSockets over SPDY is supported. |
| 858 SSLConfig websocket_server_ssl_config = server_ssl_config_; | 864 SSLConfig websocket_server_ssl_config = server_ssl_config_; |
| 859 websocket_server_ssl_config.next_protos.clear(); | 865 websocket_server_ssl_config.next_protos.clear(); |
| 860 return InitSocketHandleForWebSocketRequest( | 866 return InitSocketHandleForWebSocketRequest(origin_url_, |
| 861 origin_url_, request_info_.extra_headers, request_info_.load_flags, | 867 request_info_.extra_headers, |
| 862 priority_, session_, proxy_info_, ShouldForceSpdySSL(), | 868 request_info_.load_flags, |
| 863 want_spdy_over_npn, websocket_server_ssl_config, proxy_ssl_config_, | 869 priority_, |
| 864 request_info_.privacy_mode, net_log_, | 870 session_, |
| 865 connection_.get(), resolution_callback, io_callback_); | 871 proxy_info_, |
| 872 ShouldForceSpdySSL(), |
| 873 want_spdy_over_npn, |
| 874 websocket_server_ssl_config, |
| 875 proxy_ssl_config_, |
| 876 request_info_.privacy_mode, |
| 877 net_log_, |
| 878 connection_.get(), |
| 879 resolution_callback, |
| 880 io_callback_); |
| 866 } | 881 } |
| 867 return InitSocketHandleForHttpRequest( | 882 return InitSocketHandleForHttpRequest(origin_url_, |
| 868 origin_url_, request_info_.extra_headers, request_info_.load_flags, | 883 request_info_.extra_headers, |
| 869 priority_, session_, proxy_info_, ShouldForceSpdySSL(), | 884 request_info_.load_flags, |
| 870 want_spdy_over_npn, server_ssl_config_, proxy_ssl_config_, | 885 priority_, |
| 871 request_info_.privacy_mode, net_log_, | 886 session_, |
| 872 connection_.get(), resolution_callback, io_callback_); | 887 proxy_info_, |
| 888 ShouldForceSpdySSL(), |
| 889 want_spdy_over_npn, |
| 890 server_ssl_config_, |
| 891 proxy_ssl_config_, |
| 892 request_info_.privacy_mode, |
| 893 net_log_, |
| 894 connection_.get(), |
| 895 resolution_callback, |
| 896 io_callback_); |
| 873 } | 897 } |
| 874 } | 898 } |
| 875 | 899 |
| 876 int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { | 900 int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { |
| 877 if (IsPreconnecting()) { | 901 if (IsPreconnecting()) { |
| 878 if (using_quic_) | 902 if (using_quic_) |
| 879 return result; | 903 return result; |
| 880 DCHECK_EQ(OK, result); | 904 DCHECK_EQ(OK, result); |
| 881 return OK; | 905 return OK; |
| 882 } | 906 } |
| 883 | 907 |
| 884 if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { | 908 if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { |
| 885 // We found a SPDY connection after resolving the host. This is | 909 // We found a SPDY connection after resolving the host. This is |
| 886 // probably an IP pooled connection. | 910 // probably an IP pooled connection. |
| 887 SpdySessionKey spdy_session_key = GetSpdySessionKey(); | 911 SpdySessionKey spdy_session_key = GetSpdySessionKey(); |
| 888 existing_spdy_session_ = | 912 existing_spdy_session_ = |
| 889 session_->spdy_session_pool()->FindAvailableSession( | 913 session_->spdy_session_pool()->FindAvailableSession(spdy_session_key, |
| 890 spdy_session_key, net_log_); | 914 net_log_); |
| 891 if (existing_spdy_session_) { | 915 if (existing_spdy_session_) { |
| 892 using_spdy_ = true; | 916 using_spdy_ = true; |
| 893 next_state_ = STATE_CREATE_STREAM; | 917 next_state_ = STATE_CREATE_STREAM; |
| 894 } else { | 918 } else { |
| 895 // It is possible that the spdy session no longer exists. | 919 // It is possible that the spdy session no longer exists. |
| 896 ReturnToStateInitConnection(true /* close connection */); | 920 ReturnToStateInitConnection(true /* close connection */); |
| 897 } | 921 } |
| 898 return OK; | 922 return OK; |
| 899 } | 923 } |
| 900 | 924 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 932 static_cast<SSLClientSocket*>(connection_->socket()); | 956 static_cast<SSLClientSocket*>(connection_->socket()); |
| 933 if (ssl_socket->WasNpnNegotiated()) { | 957 if (ssl_socket->WasNpnNegotiated()) { |
| 934 was_npn_negotiated_ = true; | 958 was_npn_negotiated_ = true; |
| 935 std::string proto; | 959 std::string proto; |
| 936 std::string server_protos; | 960 std::string server_protos; |
| 937 SSLClientSocket::NextProtoStatus status = | 961 SSLClientSocket::NextProtoStatus status = |
| 938 ssl_socket->GetNextProto(&proto, &server_protos); | 962 ssl_socket->GetNextProto(&proto, &server_protos); |
| 939 NextProto protocol_negotiated = | 963 NextProto protocol_negotiated = |
| 940 SSLClientSocket::NextProtoFromString(proto); | 964 SSLClientSocket::NextProtoFromString(proto); |
| 941 protocol_negotiated_ = protocol_negotiated; | 965 protocol_negotiated_ = protocol_negotiated; |
| 942 net_log_.AddEvent( | 966 net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_REQUEST_PROTO, |
| 943 NetLog::TYPE_HTTP_STREAM_REQUEST_PROTO, | 967 base::Bind(&NetLogHttpStreamProtoCallback, |
| 944 base::Bind(&NetLogHttpStreamProtoCallback, | 968 status, |
| 945 status, &proto, &server_protos)); | 969 &proto, |
| 970 &server_protos)); |
| 946 if (ssl_socket->was_spdy_negotiated()) | 971 if (ssl_socket->was_spdy_negotiated()) |
| 947 SwitchToSpdyMode(); | 972 SwitchToSpdyMode(); |
| 948 } | 973 } |
| 949 if (ShouldForceSpdySSL()) | 974 if (ShouldForceSpdySSL()) |
| 950 SwitchToSpdyMode(); | 975 SwitchToSpdyMode(); |
| 951 } | 976 } |
| 952 } else if (proxy_info_.is_https() && connection_->socket() && | 977 } else if (proxy_info_.is_https() && connection_->socket() && result == OK) { |
| 953 result == OK) { | |
| 954 ProxyClientSocket* proxy_socket = | 978 ProxyClientSocket* proxy_socket = |
| 955 static_cast<ProxyClientSocket*>(connection_->socket()); | 979 static_cast<ProxyClientSocket*>(connection_->socket()); |
| 956 if (proxy_socket->IsUsingSpdy()) { | 980 if (proxy_socket->IsUsingSpdy()) { |
| 957 was_npn_negotiated_ = true; | 981 was_npn_negotiated_ = true; |
| 958 protocol_negotiated_ = proxy_socket->GetProtocolNegotiated(); | 982 protocol_negotiated_ = proxy_socket->GetProtocolNegotiated(); |
| 959 SwitchToSpdyMode(); | 983 SwitchToSpdyMode(); |
| 960 } | 984 } |
| 961 } | 985 } |
| 962 | 986 |
| 963 // We may be using spdy without SSL | 987 // We may be using spdy without SSL |
| 964 if (ShouldForceSpdyWithoutSSL()) | 988 if (ShouldForceSpdyWithoutSSL()) |
| 965 SwitchToSpdyMode(); | 989 SwitchToSpdyMode(); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1052 // this socket. Is there a race for two SPDY requests? We really | 1076 // this socket. Is there a race for two SPDY requests? We really |
| 1053 // need to plumb this through to the connect level. | 1077 // need to plumb this through to the connect level. |
| 1054 if (connection_->socket() && !connection_->is_reused()) | 1078 if (connection_->socket() && !connection_->is_reused()) |
| 1055 SetSocketMotivation(); | 1079 SetSocketMotivation(); |
| 1056 | 1080 |
| 1057 if (!using_spdy_) { | 1081 if (!using_spdy_) { |
| 1058 // We may get ftp scheme when fetching ftp resources through proxy. | 1082 // We may get ftp scheme when fetching ftp resources through proxy. |
| 1059 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && | 1083 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && |
| 1060 (request_info_.url.SchemeIs("http") || | 1084 (request_info_.url.SchemeIs("http") || |
| 1061 request_info_.url.SchemeIs("ftp")); | 1085 request_info_.url.SchemeIs("ftp")); |
| 1062 if (stream_factory_->http_pipelined_host_pool_. | 1086 if (stream_factory_->http_pipelined_host_pool_ |
| 1063 IsExistingPipelineAvailableForKey(*http_pipelining_key_.get())) { | 1087 .IsExistingPipelineAvailableForKey(*http_pipelining_key_.get())) { |
| 1064 DCHECK(!stream_factory_->for_websockets_); | 1088 DCHECK(!stream_factory_->for_websockets_); |
| 1065 stream_.reset(stream_factory_->http_pipelined_host_pool_. | 1089 stream_.reset( |
| 1066 CreateStreamOnExistingPipeline( | 1090 stream_factory_->http_pipelined_host_pool_ |
| 1067 *http_pipelining_key_.get())); | 1091 .CreateStreamOnExistingPipeline(*http_pipelining_key_.get())); |
| 1068 CHECK(stream_.get()); | 1092 CHECK(stream_.get()); |
| 1069 } else if (stream_factory_->for_websockets_) { | 1093 } else if (stream_factory_->for_websockets_) { |
| 1070 DCHECK(request_); | 1094 DCHECK(request_); |
| 1071 DCHECK(request_->websocket_handshake_stream_create_helper()); | 1095 DCHECK(request_->websocket_handshake_stream_create_helper()); |
| 1072 websocket_stream_.reset( | 1096 websocket_stream_.reset( |
| 1073 request_->websocket_handshake_stream_create_helper() | 1097 request_->websocket_handshake_stream_create_helper() |
| 1074 ->CreateBasicStream(connection_.Pass(), using_proxy)); | 1098 ->CreateBasicStream(connection_.Pass(), using_proxy)); |
| 1075 } else if (!using_proxy && IsRequestEligibleForPipelining()) { | 1099 } else if (!using_proxy && IsRequestEligibleForPipelining()) { |
| 1076 // TODO(simonjam): Support proxies. | 1100 // TODO(simonjam): Support proxies. |
| 1077 stream_.reset( | 1101 stream_.reset( |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 fallback = FALLBACK_SSL3; | 1285 fallback = FALLBACK_SSL3; |
| 1262 break; | 1286 break; |
| 1263 case SSL_PROTOCOL_VERSION_TLS1: | 1287 case SSL_PROTOCOL_VERSION_TLS1: |
| 1264 fallback = FALLBACK_TLS1; | 1288 fallback = FALLBACK_TLS1; |
| 1265 break; | 1289 break; |
| 1266 case SSL_PROTOCOL_VERSION_TLS1_1: | 1290 case SSL_PROTOCOL_VERSION_TLS1_1: |
| 1267 fallback = FALLBACK_TLS1_1; | 1291 fallback = FALLBACK_TLS1_1; |
| 1268 break; | 1292 break; |
| 1269 } | 1293 } |
| 1270 } | 1294 } |
| 1271 UMA_HISTOGRAM_ENUMERATION("Net.ConnectionUsedSSLVersionFallback", | 1295 UMA_HISTOGRAM_ENUMERATION( |
| 1272 fallback, FALLBACK_MAX); | 1296 "Net.ConnectionUsedSSLVersionFallback", fallback, FALLBACK_MAX); |
| 1273 | 1297 |
| 1274 // We also wish to measure the amount of fallback connections for a host that | 1298 // We also wish to measure the amount of fallback connections for a host that |
| 1275 // we know implements TLS up to 1.2. Ideally there would be no fallback here | 1299 // we know implements TLS up to 1.2. Ideally there would be no fallback here |
| 1276 // but high numbers of SSLv3 would suggest that SSLv3 fallback is being | 1300 // but high numbers of SSLv3 would suggest that SSLv3 fallback is being |
| 1277 // caused by network middleware rather than buggy HTTPS servers. | 1301 // caused by network middleware rather than buggy HTTPS servers. |
| 1278 const std::string& host = origin_server.host(); | 1302 const std::string& host = origin_server.host(); |
| 1279 if (!is_proxy && | 1303 if (!is_proxy && host.size() >= 10 && |
| 1280 host.size() >= 10 && | |
| 1281 host.compare(host.size() - 10, 10, "google.com") == 0 && | 1304 host.compare(host.size() - 10, 10, "google.com") == 0 && |
| 1282 (host.size() == 10 || host[host.size()-11] == '.')) { | 1305 (host.size() == 10 || host[host.size() - 11] == '.')) { |
| 1283 UMA_HISTOGRAM_ENUMERATION("Net.GoogleConnectionUsedSSLVersionFallback", | 1306 UMA_HISTOGRAM_ENUMERATION( |
| 1284 fallback, FALLBACK_MAX); | 1307 "Net.GoogleConnectionUsedSSLVersionFallback", fallback, FALLBACK_MAX); |
| 1285 } | 1308 } |
| 1286 | 1309 |
| 1287 if (request_info_.load_flags & LOAD_VERIFY_EV_CERT) | 1310 if (request_info_.load_flags & LOAD_VERIFY_EV_CERT) |
| 1288 ssl_config->verify_ev_cert = true; | 1311 ssl_config->verify_ev_cert = true; |
| 1289 | 1312 |
| 1290 // Disable Channel ID if privacy mode is enabled. | 1313 // Disable Channel ID if privacy mode is enabled. |
| 1291 if (request_info_.privacy_mode == PRIVACY_MODE_ENABLED) | 1314 if (request_info_.privacy_mode == PRIVACY_MODE_ENABLED) |
| 1292 ssl_config->channel_id_enabled = false; | 1315 ssl_config->channel_id_enabled = false; |
| 1293 } | 1316 } |
| 1294 | 1317 |
| 1295 | |
| 1296 int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) { | 1318 int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) { |
| 1297 DCHECK(!pac_request_); | 1319 DCHECK(!pac_request_); |
| 1298 | 1320 |
| 1299 // A failure to resolve the hostname or any error related to establishing a | 1321 // A failure to resolve the hostname or any error related to establishing a |
| 1300 // TCP connection could be grounds for trying a new proxy configuration. | 1322 // TCP connection could be grounds for trying a new proxy configuration. |
| 1301 // | 1323 // |
| 1302 // Why do this when a hostname cannot be resolved? Some URLs only make sense | 1324 // Why do this when a hostname cannot be resolved? Some URLs only make sense |
| 1303 // to proxy servers. The hostname in those URLs might fail to resolve if we | 1325 // to proxy servers. The hostname in those URLs might fail to resolve if we |
| 1304 // are still using a non-proxy config. We need to check if a proxy config | 1326 // are still using a non-proxy config. We need to check if a proxy config |
| 1305 // now exists that corresponds to a proxy server that could load the URL. | 1327 // now exists that corresponds to a proxy server that could load the URL. |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 } | 1427 } |
| 1406 | 1428 |
| 1407 void HttpStreamFactoryImpl::Job::SwitchToSpdyMode() { | 1429 void HttpStreamFactoryImpl::Job::SwitchToSpdyMode() { |
| 1408 if (HttpStreamFactory::spdy_enabled()) | 1430 if (HttpStreamFactory::spdy_enabled()) |
| 1409 using_spdy_ = true; | 1431 using_spdy_ = true; |
| 1410 } | 1432 } |
| 1411 | 1433 |
| 1412 // static | 1434 // static |
| 1413 void HttpStreamFactoryImpl::Job::LogHttpConnectedMetrics( | 1435 void HttpStreamFactoryImpl::Job::LogHttpConnectedMetrics( |
| 1414 const ClientSocketHandle& handle) { | 1436 const ClientSocketHandle& handle) { |
| 1415 UMA_HISTOGRAM_ENUMERATION("Net.HttpSocketType", handle.reuse_type(), | 1437 UMA_HISTOGRAM_ENUMERATION( |
| 1416 ClientSocketHandle::NUM_TYPES); | 1438 "Net.HttpSocketType", handle.reuse_type(), ClientSocketHandle::NUM_TYPES); |
| 1417 | 1439 |
| 1418 switch (handle.reuse_type()) { | 1440 switch (handle.reuse_type()) { |
| 1419 case ClientSocketHandle::UNUSED: | 1441 case ClientSocketHandle::UNUSED: |
| 1420 UMA_HISTOGRAM_CUSTOM_TIMES("Net.HttpConnectionLatency", | 1442 UMA_HISTOGRAM_CUSTOM_TIMES("Net.HttpConnectionLatency", |
| 1421 handle.setup_time(), | 1443 handle.setup_time(), |
| 1422 base::TimeDelta::FromMilliseconds(1), | 1444 base::TimeDelta::FromMilliseconds(1), |
| 1423 base::TimeDelta::FromMinutes(10), | 1445 base::TimeDelta::FromMinutes(10), |
| 1424 100); | 1446 100); |
| 1425 break; | 1447 break; |
| 1426 case ClientSocketHandle::UNUSED_IDLE: | 1448 case ClientSocketHandle::UNUSED_IDLE: |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 } | 1501 } |
| 1480 if (!session_->params().http_pipelining_enabled) { | 1502 if (!session_->params().http_pipelining_enabled) { |
| 1481 return false; | 1503 return false; |
| 1482 } | 1504 } |
| 1483 if (using_ssl_) { | 1505 if (using_ssl_) { |
| 1484 return false; | 1506 return false; |
| 1485 } | 1507 } |
| 1486 if (request_info_.method != "GET" && request_info_.method != "HEAD") { | 1508 if (request_info_.method != "GET" && request_info_.method != "HEAD") { |
| 1487 return false; | 1509 return false; |
| 1488 } | 1510 } |
| 1489 if (request_info_.load_flags & | 1511 if (request_info_.load_flags & (net::LOAD_MAIN_FRAME | net::LOAD_SUB_FRAME | |
| 1490 (net::LOAD_MAIN_FRAME | net::LOAD_SUB_FRAME | net::LOAD_PREFETCH | | 1512 net::LOAD_PREFETCH | net::LOAD_IS_DOWNLOAD)) { |
| 1491 net::LOAD_IS_DOWNLOAD)) { | |
| 1492 // Avoid pipelining resources that may be streamed for a long time. | 1513 // Avoid pipelining resources that may be streamed for a long time. |
| 1493 return false; | 1514 return false; |
| 1494 } | 1515 } |
| 1495 return stream_factory_->http_pipelined_host_pool_.IsKeyEligibleForPipelining( | 1516 return stream_factory_->http_pipelined_host_pool_.IsKeyEligibleForPipelining( |
| 1496 *http_pipelining_key_.get()); | 1517 *http_pipelining_key_.get()); |
| 1497 } | 1518 } |
| 1498 | 1519 |
| 1499 } // namespace net | 1520 } // namespace net |
| OLD | NEW |