Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Unified Diff: net/http/http_stream_factory_impl_job_controller.cc

Issue 2260623002: Race TCP connection to proxies with QUIC connections (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Test fix Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/http/http_stream_factory_impl_job_controller.cc
diff --git a/net/http/http_stream_factory_impl_job_controller.cc b/net/http/http_stream_factory_impl_job_controller.cc
index f526618acdb36b55c222b2ece8f30284d7099b3b..0083cc433832a126fd423fae0f82e14f04297ec6 100644
--- a/net/http/http_stream_factory_impl_job_controller.cc
+++ b/net/http/http_stream_factory_impl_job_controller.cc
@@ -9,8 +9,10 @@
#include "base/strings/string_util.h"
#include "base/values.h"
#include "net/base/host_mapping_rules.h"
+#include "net/base/proxy_delegate.h"
#include "net/http/bidirectional_stream_impl.h"
#include "net/http/transport_security_state.h"
+#include "net/proxy/proxy_server.h"
#include "net/spdy/spdy_session.h"
namespace net {
@@ -38,6 +40,7 @@ HttpStreamFactoryImpl::JobController::JobController(
job_bound_(false),
main_job_is_blocked_(false),
bound_job_(nullptr),
+ can_start_alternative_proxy_job_(false),
ptr_factory_(this) {
DCHECK(factory);
}
@@ -355,6 +358,45 @@ void HttpStreamFactoryImpl::JobController::OnNeedsProxyAuth(
auth_controller);
}
+void HttpStreamFactoryImpl::JobController::OnResolveProxyComplete(
+ Job* job,
+ const HttpRequestInfo& request_info,
+ RequestPriority priority,
+ const SSLConfig& server_ssl_config,
+ const SSLConfig& proxy_ssl_config,
+ HttpStreamRequest::StreamType stream_type) {
+ DCHECK(job);
+
+ ProxyServer alternative_proxy_server;
+ if (!ShouldCreateAlternativeProxyServerJob(job, job->proxy_info(),
+ request_info.url,
+ &alternative_proxy_server)) {
+ return;
+ }
+
+ DCHECK(main_job_);
+ DCHECK_EQ(MAIN, job->job_type());
+ DCHECK(!alternative_job_);
+ DCHECK(!main_job_is_blocked_);
+
+ HostPortPair destination(HostPortPair::FromURL(request_info.url));
+ GURL origin_url = ApplyHostMappingRules(request_info.url, &destination);
+
+ alternative_job_.reset(job_factory_->CreateJob(
+ this, ALTERNATIVE, session_, request_info, priority, server_ssl_config,
+ proxy_ssl_config, destination, origin_url, alternative_proxy_server,
+ job->net_log().net_log()));
+ AttachJob(alternative_job_.get());
+
+ can_start_alternative_proxy_job_ = false;
+ main_job_is_blocked_ = true;
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&HttpStreamFactoryImpl::Job::Start,
+ base::Unretained(alternative_job_.get()),
+ request_->stream_type()));
+}
+
void HttpStreamFactoryImpl::JobController::OnNewSpdySessionReady(
Job* job,
const base::WeakPtr<SpdySession>& spdy_session,
@@ -607,6 +649,8 @@ void HttpStreamFactoryImpl::JobController::CreateJobs(
main_job_is_blocked_ = true;
alternative_job_->Start(request_->stream_type());
+ } else {
+ can_start_alternative_proxy_job_ = true;
}
// Even if |alternative_job| has already finished, it will not have notified
// the request yet, since we defer that to the next iteration of the
@@ -895,4 +939,73 @@ HttpStreamFactoryImpl::JobController::GetAlternativeServiceForInternal(
return first_alternative_service;
}
+
+bool HttpStreamFactoryImpl::JobController::
+ ShouldCreateAlternativeProxyServerJob(
+ Job* job,
+ const ProxyInfo& proxy_info,
+ const GURL& url,
+ ProxyServer* alternative_proxy_server) const {
+ DCHECK(!alternative_proxy_server->is_valid());
+ if (!can_start_alternative_proxy_job_) {
+ // Either an alternative service job or an alternative proxy server job has
+ // already been started.
+ return false;
+ }
+
+ if (job->job_type() == ALTERNATIVE) {
+ // If |job| is using alternative service, then alternative proxy server
+ // should not be used.
+ return false;
+ }
+
+ if (job->job_type() == PRECONNECT) {
+ // Preconnects should be fetched using only the main job to keep the
+ // resource utilization down.
+ return false;
+ }
+
+ if (proxy_info.is_empty() || proxy_info.is_direct() || proxy_info.is_quic()) {
+ // Alternative proxy server job can be created only if |job| fetches the
+ // |request_| through a non-QUIC proxy.
+ return false;
+ }
+
+ if (!url.SchemeIs(url::kHttpScheme)) {
+ // Only HTTP URLs can be fetched through alternative proxy server, since the
+ // alternative proxy server may not support fetching of URLs with other
+ // schemes.
+ return false;
+ }
+
+ ProxyDelegate* proxy_delegate = session_->params().proxy_delegate;
+ if (!proxy_delegate)
+ return false;
+
+ proxy_delegate->GetAlternativeProxy(url, proxy_info.proxy_server(),
+ alternative_proxy_server);
+
+ if (!alternative_proxy_server->is_valid())
+ return false;
+
+ DCHECK(!(*alternative_proxy_server == proxy_info.proxy_server()));
+
+ if (!alternative_proxy_server->is_https() &&
+ !alternative_proxy_server->is_quic()) {
+ // Alternative proxy server should be a secure server.
+ return false;
+ }
+
+ if (alternative_proxy_server->is_quic()) {
+ // Check that QUIC is enabled globally, and it is not disabled on
+ // the specified port.
+ if (!session_->params().enable_quic ||
+ session_->quic_stream_factory()->IsQuicDisabled(
+ alternative_proxy_server->host_port_pair().port())) {
+ return false;
+ }
+ }
+
+ return true;
+}
}
« no previous file with comments | « net/http/http_stream_factory_impl_job_controller.h ('k') | net/http/http_stream_factory_impl_job_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698