diff options
Diffstat (limited to 'chromium/net')
50 files changed, 701 insertions, 806 deletions
diff --git a/chromium/net/BUILD.gn b/chromium/net/BUILD.gn index 35012c34cae..43dd5286438 100644 --- a/chromium/net/BUILD.gn +++ b/chromium/net/BUILD.gn @@ -474,8 +474,6 @@ component("net") { "base/network_activity_monitor.h", "base/network_change_notifier.cc", "base/network_change_notifier.h", - "base/network_change_notifier_chromeos.cc", - "base/network_change_notifier_chromeos.h", "base/network_change_notifier_factory.h", "base/network_change_notifier_linux.cc", "base/network_change_notifier_linux.h", @@ -1869,6 +1867,13 @@ component("net") { } } + if (is_android || is_chromeos) { + sources += [ + "base/network_change_notifier_posix.cc", + "base/network_change_notifier_posix.h", + ] + } + if (is_win) { sources -= [ "ntlm/ntlm.cc", @@ -4774,7 +4779,6 @@ test("net_unittests") { "base/mime_util_unittest.cc", "base/net_string_util_unittest.cc", "base/network_activity_monitor_unittest.cc", - "base/network_change_notifier_chromeos_unittest.cc", "base/network_change_notifier_unittest.cc", "base/network_change_notifier_win_unittest.cc", "base/network_interfaces_linux_unittest.cc", @@ -5404,6 +5408,10 @@ test("net_unittests") { sources += [ "socket/udp_socket_posix_unittest.cc" ] } + if (is_android || is_chromeos) { + sources += [ "base/network_change_notifier_posix_unittest.cc" ] + } + if (enable_reporting) { sources += [ "network_error_logging/network_error_logging_service_unittest.cc", diff --git a/chromium/net/android/network_change_notifier_android.h b/chromium/net/android/network_change_notifier_android.h index b7fcf5897c0..6317acef864 100644 --- a/chromium/net/android/network_change_notifier_android.h +++ b/chromium/net/android/network_change_notifier_android.h @@ -75,6 +75,8 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierAndroid // delegate class. using NetworkChangeNotifier::GetMaxBandwidthMbpsForConnectionSubtype; + static NetworkChangeCalculatorParams NetworkChangeCalculatorParamsAndroid(); + protected: void OnFinalizingMetricsLogRecord() override; @@ -90,8 +92,6 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierAndroid explicit NetworkChangeNotifierAndroid( NetworkChangeNotifierDelegateAndroid* delegate); - static NetworkChangeCalculatorParams NetworkChangeCalculatorParamsAndroid(); - NetworkChangeNotifierDelegateAndroid* const delegate_; std::unique_ptr<DnsConfigServiceThread> dns_config_service_thread_; bool force_network_handles_supported_for_testing_; diff --git a/chromium/net/base/load_timing_info.h b/chromium/net/base/load_timing_info.h index d5df508c7ec..73ff26a9df5 100644 --- a/chromium/net/base/load_timing_info.h +++ b/chromium/net/base/load_timing_info.h @@ -58,7 +58,7 @@ namespace net { // have SSL times. One exception to this is when a proxy server itself returns // a redirect response. In this case, the connect times treat the proxy as the // host. The send and receive times will all be null, however. -// See HttpNetworkTransaction::OnHttpsProxyTunnelResponse. +// See HttpNetworkTransaction::OnHttpsProxyTunnelResponseRedirect. // TODO(mmenke): Is this worth fixing? // struct NET_EXPORT LoadTimingInfo { diff --git a/chromium/net/base/net_error_list.h b/chromium/net/base/net_error_list.h index 61fbd8e7c14..b7b7063fc0e 100644 --- a/chromium/net/base/net_error_list.h +++ b/chromium/net/base/net_error_list.h @@ -261,9 +261,12 @@ NET_ERROR(NETWORK_ACCESS_DENIED, -138) NET_ERROR(TEMPORARILY_THROTTLED, -139) // A request to create an SSL tunnel connection through the HTTPS proxy -// received a non-200 (OK) and non-407 (Proxy Auth) response. The response -// body might include a description of why the request failed. -NET_ERROR(HTTPS_PROXY_TUNNEL_RESPONSE, -140) +// received a 302 (temporary redirect) response. The response body might +// include a description of why the request failed. +// +// TODO(https://crbug.com/928551): This is deprecated and should not be used by +// new code. +NET_ERROR(HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT, -140) // We were unable to sign the CertificateVerify data of an SSL client auth // handshake with the client certificate's private key. diff --git a/chromium/net/base/network_change_notifier.cc b/chromium/net/base/network_change_notifier.cc index a4c5486a888..55772fc82a6 100644 --- a/chromium/net/base/network_change_notifier.cc +++ b/chromium/net/base/network_change_notifier.cc @@ -34,7 +34,7 @@ #elif defined(OS_MACOSX) #include "net/base/network_change_notifier_mac.h" #elif defined(OS_CHROMEOS) -#include "net/base/network_change_notifier_chromeos.h" +#include "net/base/network_change_notifier_posix.h" #elif defined(OS_FUCHSIA) #include "net/base/network_change_notifier_fuchsia.h" #endif @@ -213,7 +213,7 @@ NetworkChangeNotifier* NetworkChangeNotifier::Create() { CHECK(false); return NULL; #elif defined(OS_CHROMEOS) - return new NetworkChangeNotifierChromeos(); + return new NetworkChangeNotifierPosix(CONNECTION_UNKNOWN, SUBTYPE_UNKNOWN); #elif defined(OS_LINUX) return new NetworkChangeNotifierLinux(std::unordered_set<std::string>()); #elif defined(OS_MACOSX) diff --git a/chromium/net/base/network_change_notifier_chromeos.cc b/chromium/net/base/network_change_notifier_posix.cc index 6eb948b6a22..89a1ff461ce 100644 --- a/chromium/net/base/network_change_notifier_chromeos.cc +++ b/chromium/net/base/network_change_notifier_posix.cc @@ -5,14 +5,19 @@ #include <string> #include "base/bind.h" -#include "net/base/network_change_notifier_chromeos.h" +#include "build/build_config.h" +#include "net/base/network_change_notifier_posix.h" #include "net/dns/dns_config_service_posix.h" +#if defined(OS_ANDROID) +#include "net/android/network_change_notifier_android.h" +#endif + namespace net { -// DNS config services on Chrome OS are signalled by the network state handler -// rather than relying on watching files in /etc. -class NetworkChangeNotifierChromeos::DnsConfigService +// DNS config services on Chrome OS and Android are signalled by the network +// state handler rather than relying on watching files in /etc. +class NetworkChangeNotifierPosix::DnsConfigService : public net::internal::DnsConfigServicePosix { public: DnsConfigService() = default; @@ -32,21 +37,21 @@ class NetworkChangeNotifierChromeos::DnsConfigService } }; -NetworkChangeNotifierChromeos::NotifierThread::NotifierThread() +NetworkChangeNotifierPosix::NotifierThread::NotifierThread() : base::Thread("NetworkChangeNotifier") { DETACH_FROM_SEQUENCE(sequence_checker_); } -NetworkChangeNotifierChromeos::NotifierThread::~NotifierThread() { +NetworkChangeNotifierPosix::NotifierThread::~NotifierThread() { DCHECK(!Thread::IsRunning()); } -void NetworkChangeNotifierChromeos::NotifierThread::OnNetworkChange() { +void NetworkChangeNotifierPosix::NotifierThread::OnNetworkChange() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); dns_config_service_->OnNetworkChange(); } -void NetworkChangeNotifierChromeos::NotifierThread::Init() { +void NetworkChangeNotifierPosix::NotifierThread::Init() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); dns_config_service_.reset(new DnsConfigService()); dns_config_service_->WatchConfig( @@ -54,42 +59,44 @@ void NetworkChangeNotifierChromeos::NotifierThread::Init() { dns_config_service_->OnNetworkChange(); } -void NetworkChangeNotifierChromeos::NotifierThread::CleanUp() { +void NetworkChangeNotifierPosix::NotifierThread::CleanUp() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); dns_config_service_.reset(); } -NetworkChangeNotifierChromeos::NetworkChangeNotifierChromeos() - : NetworkChangeNotifier(NetworkChangeCalculatorParamsChromeos()), - connection_type_(CONNECTION_NONE), +NetworkChangeNotifierPosix::NetworkChangeNotifierPosix( + NetworkChangeNotifier::ConnectionType initial_connection_type, + NetworkChangeNotifier::ConnectionSubtype initial_connection_subtype) + : NetworkChangeNotifier(NetworkChangeCalculatorParamsPosix()), + connection_type_(initial_connection_type), max_bandwidth_mbps_( NetworkChangeNotifier::GetMaxBandwidthMbpsForConnectionSubtype( - SUBTYPE_NONE)) { + initial_connection_subtype)) { notifier_thread_.StartWithOptions( base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); } -NetworkChangeNotifierChromeos::~NetworkChangeNotifierChromeos() { +NetworkChangeNotifierPosix::~NetworkChangeNotifierPosix() { notifier_thread_.Stop(); } -void NetworkChangeNotifierChromeos::OnDNSChanged() { +void NetworkChangeNotifierPosix::OnDNSChanged() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // The Unretained thread pointer is ok here because if the thread gets // deleted, the callback won't be called. notifier_thread_.task_runner()->PostTask( FROM_HERE, base::BindOnce( - &NetworkChangeNotifierChromeos::NotifierThread::OnNetworkChange, + &NetworkChangeNotifierPosix::NotifierThread::OnNetworkChange, base::Unretained(¬ifier_thread_))); } -void NetworkChangeNotifierChromeos::OnIPAddressChanged() { +void NetworkChangeNotifierPosix::OnIPAddressChanged() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); NetworkChangeNotifier::NotifyObserversOfIPAddressChange(); } -void NetworkChangeNotifierChromeos::OnConnectionChanged( +void NetworkChangeNotifierPosix::OnConnectionChanged( NetworkChangeNotifier::ConnectionType connection_type) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); { @@ -99,7 +106,7 @@ void NetworkChangeNotifierChromeos::OnConnectionChanged( NetworkChangeNotifier::NotifyObserversOfConnectionTypeChange(); } -void NetworkChangeNotifierChromeos::OnConnectionSubtypeChanged( +void NetworkChangeNotifierPosix::OnConnectionSubtypeChanged( NetworkChangeNotifier::ConnectionType connection_type, NetworkChangeNotifier::ConnectionSubtype connection_subtype) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -114,12 +121,12 @@ void NetworkChangeNotifierChromeos::OnConnectionSubtypeChanged( } NetworkChangeNotifier::ConnectionType -NetworkChangeNotifierChromeos::GetCurrentConnectionType() const { +NetworkChangeNotifierPosix::GetCurrentConnectionType() const { base::AutoLock scoped_lock(lock_); return connection_type_; } -void NetworkChangeNotifierChromeos::GetCurrentMaxBandwidthAndConnectionType( +void NetworkChangeNotifierPosix::GetCurrentMaxBandwidthAndConnectionType( double* max_bandwidth_mbps, ConnectionType* connection_type) const { base::AutoLock scoped_lock(lock_); @@ -129,8 +136,9 @@ void NetworkChangeNotifierChromeos::GetCurrentMaxBandwidthAndConnectionType( // static NetworkChangeNotifier::NetworkChangeCalculatorParams -NetworkChangeNotifierChromeos::NetworkChangeCalculatorParamsChromeos() { +NetworkChangeNotifierPosix::NetworkChangeCalculatorParamsPosix() { NetworkChangeCalculatorParams params; +#if defined(OS_CHROMEOS) // Delay values arrived at by simple experimentation and adjusted so as to // produce a single signal when switching between network connections. params.ip_address_offline_delay_ = base::TimeDelta::FromMilliseconds(4000); @@ -138,6 +146,12 @@ NetworkChangeNotifierChromeos::NetworkChangeCalculatorParamsChromeos() { params.connection_type_offline_delay_ = base::TimeDelta::FromMilliseconds(500); params.connection_type_online_delay_ = base::TimeDelta::FromMilliseconds(500); +#elif defined(OS_ANDROID) + params = + net::NetworkChangeNotifierAndroid::NetworkChangeCalculatorParamsAndroid(); +#else + NOTIMPLEMENTED(); +#endif return params; } diff --git a/chromium/net/base/network_change_notifier_chromeos.h b/chromium/net/base/network_change_notifier_posix.h index 822d3f6cf65..37e6ae405ad 100644 --- a/chromium/net/base/network_change_notifier_chromeos.h +++ b/chromium/net/base/network_change_notifier_posix.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_BASE_NETWORK_CHANGE_NOTIFIER_CHROMEOS_H_ -#define NET_BASE_NETWORK_CHANGE_NOTIFIER_CHROMEOS_H_ +#ifndef NET_BASE_NETWORK_CHANGE_NOTIFIER_POSIX_H_ +#define NET_BASE_NETWORK_CHANGE_NOTIFIER_POSIX_H_ #include "base/gtest_prod_util.h" #include "base/macros.h" @@ -18,13 +18,15 @@ namespace net { // A NetworkChangeNotifier that needs to be told about network changes by some -// other object. This class can't directly listen for network changes because -// on ChromeOS only objects running in the browser process can listen for -// network state changes. -class NET_EXPORT NetworkChangeNotifierChromeos : public NetworkChangeNotifier { +// other object. This class can't directly listen for network changes because on +// ChromeOS and Android only objects running in the browser process can listen +// for network state changes. +class NET_EXPORT NetworkChangeNotifierPosix : public NetworkChangeNotifier { public: - NetworkChangeNotifierChromeos(); - ~NetworkChangeNotifierChromeos() override; + NetworkChangeNotifierPosix( + NetworkChangeNotifier::ConnectionType initial_connection_type, + NetworkChangeNotifier::ConnectionSubtype initial_connection_subtype); + ~NetworkChangeNotifierPosix() override; // These methods are used to notify this object that a network property has // changed. These must be called from the thread that owns this object. @@ -45,9 +47,7 @@ class NET_EXPORT NetworkChangeNotifierChromeos : public NetworkChangeNotifier { ConnectionType* connection_type) const override; private: - FRIEND_TEST_ALL_PREFIXES(NetworkChangeNotifierChromeosTest, - ConnectionTypeFromShill); - friend class NetworkChangeNotifierChromeosTest; + friend class NetworkChangeNotifierPosixTest; class DnsConfigService; @@ -75,7 +75,7 @@ class NET_EXPORT NetworkChangeNotifierChromeos : public NetworkChangeNotifier { // Calculates parameters used for network change notifier online/offline // signals. static NetworkChangeNotifier::NetworkChangeCalculatorParams - NetworkChangeCalculatorParamsChromeos(); + NetworkChangeCalculatorParamsPosix(); THREAD_CHECKER(thread_checker_); @@ -86,9 +86,9 @@ class NET_EXPORT NetworkChangeNotifierChromeos : public NetworkChangeNotifier { NotifierThread notifier_thread_; - DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifierChromeos); + DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifierPosix); }; } // namespace net -#endif // NET_BASE_NETWORK_CHANGE_NOTIFIER_CHROMEOS_H_ +#endif // NET_BASE_NETWORK_CHANGE_NOTIFIER_POSIX_H_ diff --git a/chromium/net/base/network_change_notifier_chromeos_unittest.cc b/chromium/net/base/network_change_notifier_posix_unittest.cc index 00d7ad234fa..c540877f651 100644 --- a/chromium/net/base/network_change_notifier_chromeos_unittest.cc +++ b/chromium/net/base/network_change_notifier_posix_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/base/network_change_notifier_chromeos.h" +#include "net/base/network_change_notifier_posix.h" #include "base/test/scoped_task_environment.h" #include "net/base/network_change_notifier.h" @@ -10,23 +10,25 @@ namespace net { -class NetworkChangeNotifierChromeosTest : public testing::Test { +class NetworkChangeNotifierPosixTest : public testing::Test { public: - NetworkChangeNotifierChromeosTest() + NetworkChangeNotifierPosixTest() : scoped_task_environment_( base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME), - notifier_(new NetworkChangeNotifierChromeos()) {} + notifier_(new NetworkChangeNotifierPosix( + NetworkChangeNotifier::CONNECTION_UNKNOWN, + NetworkChangeNotifier::SUBTYPE_UNKNOWN)) {} void FastForwardUntilIdle() { scoped_task_environment_.FastForwardUntilNoTasksRemain(); } - NetworkChangeNotifierChromeos* notifier() { return notifier_.get(); } + NetworkChangeNotifierPosix* notifier() { return notifier_.get(); } private: base::test::ScopedTaskEnvironment scoped_task_environment_; net::NetworkChangeNotifier::DisableForTest mock_notifier_disabler_; - std::unique_ptr<NetworkChangeNotifierChromeos> notifier_; + std::unique_ptr<NetworkChangeNotifierPosix> notifier_; }; class MockIPAddressObserver : public NetworkChangeNotifier::IPAddressObserver { @@ -34,7 +36,7 @@ class MockIPAddressObserver : public NetworkChangeNotifier::IPAddressObserver { MOCK_METHOD0(OnIPAddressChanged, void()); }; -TEST_F(NetworkChangeNotifierChromeosTest, OnIPAddressChanged) { +TEST_F(NetworkChangeNotifierPosixTest, OnIPAddressChanged) { testing::StrictMock<MockIPAddressObserver> observer; NetworkChangeNotifier::AddIPAddressObserver(&observer); @@ -51,7 +53,7 @@ class MockNetworkChangeObserver MOCK_METHOD1(OnNetworkChanged, void(NetworkChangeNotifier::ConnectionType)); }; -TEST_F(NetworkChangeNotifierChromeosTest, OnNetworkChanged) { +TEST_F(NetworkChangeNotifierPosixTest, OnNetworkChanged) { testing::StrictMock<MockNetworkChangeObserver> observer; NetworkChangeNotifier::AddNetworkChangeObserver(&observer); @@ -71,7 +73,7 @@ class MockMaxBandwidthObserver void(double, NetworkChangeNotifier::ConnectionType)); }; -TEST_F(NetworkChangeNotifierChromeosTest, OnMaxBandwidthChanged) { +TEST_F(NetworkChangeNotifierPosixTest, OnMaxBandwidthChanged) { testing::StrictMock<MockMaxBandwidthObserver> observer; NetworkChangeNotifier::AddMaxBandwidthObserver(&observer); diff --git a/chromium/net/base/registry_controlled_domains/effective_tld_names.dat b/chromium/net/base/registry_controlled_domains/effective_tld_names.dat index 69c78881f08..59db7d0c52f 100644 --- a/chromium/net/base/registry_controlled_domains/effective_tld_names.dat +++ b/chromium/net/base/registry_controlled_domains/effective_tld_names.dat @@ -4663,9 +4663,6 @@ web.ni // ccTLD for the Netherlands nl -// BV.nl will be a registry for dutch BV's (besloten vennootschap) -bv.nl - // no : http://www.norid.no/regelverk/index.en.html // The Norwegian registry has declined to notify us of updates. The web pages // referenced below are the official source of the data. There is also an @@ -7111,9 +7108,6 @@ accountants // aco : 2015-01-08 ACO Severin Ahlmann GmbH & Co. KG aco -// active : 2014-05-01 Active Network, LLC -active - // actor : 2013-12-12 United TLD Holdco Ltd. actor @@ -7414,9 +7408,6 @@ black // blackfriday : 2014-01-16 Uniregistry, Corp. blackfriday -// blanco : 2015-07-16 BLANCO GmbH + Co KG -blanco - // blockbuster : 2015-07-30 Dish DBS Corporation blockbuster @@ -8026,9 +8017,6 @@ engineering // enterprises : 2013-09-20 Binky Moon, LLC enterprises -// epost : 2015-07-23 Deutsche Post AG -epost - // epson : 2014-12-04 Seiko Epson Corporation epson @@ -9850,9 +9838,6 @@ soy // space : 2014-04-03 DotSpace Inc. space -// spiegel : 2014-02-05 SPIEGEL-Verlag Rudolf Augstein GmbH & Co. KG -spiegel - // sport : 2017-11-16 Global Association of International Sports Federations (GAISF) sport @@ -10687,9 +10672,6 @@ zero // zip : 2014-05-08 Charleston Road Registry Inc. zip -// zippo : 2015-07-02 Zadco Company -zippo - // zone : 2013-11-14 Binky Moon, LLC zone @@ -11092,6 +11074,11 @@ firm.dk reg.dk store.dk +// dapps.earth : https://dapps.earth/ +// Submitted by Daniil Burdakov <icqkill@gmail.com> +*.dapps.earth +*.bzz.dapps.earth + // Debian : https://www.debian.org/ // Submitted by Peter Palfrader / Debian Sysadmin Team <dsa-publicsuffixlist@debian.org> debian.net @@ -11638,6 +11625,7 @@ channelsdvr.net // Fastly Inc. : http://www.fastly.com/ // Submitted by Fastly Security <security@fastly.com> +fastly-terrarium.com fastlylb.net map.fastlylb.net freetls.fastly.net @@ -11672,6 +11660,12 @@ mydobiss.com // Filegear Inc. : https://www.filegear.com // Submitted by Jason Zhu <jason@owtware.com> filegear.me +filegear-au.me +filegear-de.me +filegear-gb.me +filegear-ie.me +filegear-jp.me +filegear-sg.me // Firebase, Inc. // Submitted by Chris Raynor <chris@firebase.com> @@ -11734,6 +11728,8 @@ goip.de // Google, Inc. // Submitted by Eduardo Vela <evn@google.com> +run.app +a.run.app *.0emm.com appspot.com blogspot.ae @@ -11853,6 +11849,19 @@ moonscale.net // Submitted by Hannu Aronsson <haa@iki.fi> iki.fi +// Individual Network Berlin e.V. : https://www.in-berlin.de/ +// Submitted by Christian Seitz <chris@in-berlin.de> +dyn-berlin.de +in-berlin.de +in-brb.de +in-butter.de +in-dsl.de +in-dsl.net +in-dsl.org +in-vpn.de +in-vpn.net +in-vpn.org + // info.at : http://www.info.at/ biz.at info.at @@ -11939,6 +11948,22 @@ git-repos.de lcube-server.de svn-repos.de +// Leadpages : https://www.leadpages.net +// Submitted by Greg Dallavalle <domains@leadpages.net> +leadpages.co +lpages.co +lpusercontent.com + +// Lifetime Hosting : https://Lifetime.Hosting/ +// Submitted by Mike Fillator <support@lifetime.hosting> +co.business +co.education +co.events +co.financial +co.network +co.place +co.technology + // Lightmaker Property Manager, Inc. : https://app.lmpm.com/ // Submitted by Greg Holland <greg.holland@lmpm.com> app.lmpm.com @@ -12494,6 +12519,10 @@ spacekit.io // Submitted by Stefan Neufeind <info@speedpartner.de> customer.speedpartner.de +// Standard Library : https://stdlib.com +// Submitted by Jacob Lee <jacob@stdlib.com> +api.stdlib.com + // Storj Labs Inc. : https://storj.io/ // Submitted by Philip Hutchins <hostmaster@storj.io> storj.farm @@ -12506,6 +12535,11 @@ utwente.io // Submitted by Dan Miller <dm@sub6.com> temp-dns.com +// Swisscom Application Cloud: https://developer.swisscom.com +// Submitted by Matthias.Winzeler <matthias.winzeler@swisscom.com> +applicationcloud.io +scapp.io + // Synology, Inc. : https://www.synology.com/ // Submitted by Rony Weng <ronyweng@synology.com> diskstation.me @@ -12534,6 +12568,12 @@ gdynia.pl med.pl sopot.pl +// Telebit : https://telebit.cloud +// Submitted by AJ ONeal <aj@telebit.cloud> +telebit.app +telebit.io +*.telebit.xyz + // The Gwiddle Foundation : https://gwiddlefoundation.org.uk // Submitted by Joshua Bayfield <joshua.bayfield@gwiddlefoundation.org.uk> gwiddle.co.uk @@ -12693,6 +12733,10 @@ za.org // Submitted by Olli Vanhoja <olli@zeit.co> now.sh +// Zine EOOD : https://zine.bg/ +// Submitted by Martin Angelov <martin@zine.bg> +bss.design + // Zone.id : https://zone.id/ // Submitted by Su Hendro <admin@zone.id> zone.id diff --git a/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf b/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf index 9443898779d..56f3713b15e 100644 --- a/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf +++ b/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf @@ -44,6 +44,7 @@ struct DomainRule { 9guacu.br, 0 a.bg, 0 a.prod.fastly.net, 4 +a.run.app, 4 a.se, 0 a.ssl.fastly.net, 4 aa.no, 0 @@ -129,7 +130,6 @@ achi.nagano.jp, 0 aco, 0 act.au, 0 act.edu.au, 0 -active, 0 actor, 0 ad, 0 ad.jp, 0 @@ -337,6 +337,7 @@ ap.it, 0 ap.leg.br, 4 aparecida.br, 0 apartments, 0 +api.stdlib.com, 4 apigee.io, 4 app, 0 app.lmpm.com, 4 @@ -344,6 +345,7 @@ app.os.fedoraproject.org, 4 app.os.stg.fedoraproject.org, 4 appchizi.com, 4 apple, 0 +applicationcloud.io, 4 applinzi.com, 4 apps.fbsbx.com, 4 apps.lair.io, 4 @@ -732,7 +734,6 @@ bl.it, 0 black, 0 blackbaudcdn.net, 4 blackfriday, 0 -blanco, 0 blockbuster, 0 blog, 0 blog.bo, 0 @@ -910,6 +911,7 @@ bryne.no, 0 bs, 0 bs.it, 0 bsb.br, 0 +bss.design, 4 bt, 0 bt.it, 0 bu.no, 0 @@ -936,7 +938,6 @@ buyshouses.net, 4 buzen.fukuoka.jp, 0 buzz, 0 bv, 0 -bv.nl, 0 bw, 0 by, 0 bydgoszcz.pl, 0 @@ -947,6 +948,7 @@ bytom.pl, 0 bz, 0 bz.it, 0 bzh, 0 +bzz.dapps.earth, 6 c.bg, 0 c.cdn77.org, 4 c.la, 4 @@ -1275,6 +1277,7 @@ co.ao, 0 co.at, 0 co.bb, 0 co.bi, 0 +co.business, 4 co.bw, 0 co.ca, 4 co.ci, 0 @@ -1284,6 +1287,9 @@ co.com, 4 co.cr, 0 co.cz, 4 co.dk, 4 +co.education, 4 +co.events, 4 +co.financial, 4 co.gg, 0 co.gl, 0 co.gy, 0 @@ -1308,18 +1314,21 @@ co.mu, 0 co.mw, 0 co.mz, 0 co.na, 0 +co.network, 4 co.ni, 0 co.nl, 4 co.no, 4 co.nz, 0 co.om, 0 co.pl, 4 +co.place, 4 co.pn, 0 co.pw, 0 co.rs, 0 co.rw, 0 co.st, 0 co.sz, 0 +co.technology, 4 co.th, 0 co.tj, 0 co.tm, 0 @@ -1625,6 +1634,7 @@ dallas.museum, 0 damnserver.com, 4 dance, 0 daplie.me, 4 +dapps.earth, 6 data, 0 database.museum, 0 date, 0 @@ -1801,6 +1811,7 @@ dvr, 0 dvrcam.info, 4 dvrdns.org, 4 dy.fi, 4 +dyn-berlin.de, 4 dyn-ip24.de, 4 dyn-o-saur.com, 4 dyn-vpn.de, 4 @@ -2061,7 +2072,6 @@ entomology.museum, 0 environment.museum, 0 environmentalconservation.museum, 0 epilepsy.museum, 0 -epost, 0 epson, 0 equipment, 0 equipment.aero, 0 @@ -2156,6 +2166,7 @@ farmstead.museum, 0 farsund.no, 0 fashion, 0 fast, 0 +fastly-terrarium.com, 4 fastlylb.net, 4 fastpanel.direct, 4 fastvps-server.com, 4 @@ -2196,6 +2207,12 @@ fie.ee, 0 field.museum, 0 figueres.museum, 0 filatelia.museum, 0 +filegear-au.me, 4 +filegear-de.me, 4 +filegear-gb.me, 4 +filegear-ie.me, 4 +filegear-jp.me, 4 +filegear-sg.me, 4 filegear.me, 4 film, 0 film.hu, 0 @@ -3268,7 +3285,16 @@ immobilien, 0 imperia.it, 0 in, 0 in-addr.arpa, 0 +in-berlin.de, 4 +in-brb.de, 4 +in-butter.de, 4 +in-dsl.de, 4 +in-dsl.net, 4 +in-dsl.org, 4 in-the-band.net, 4 +in-vpn.de, 4 +in-vpn.net, 4 +in-vpn.org, 4 in.eu.org, 4 in.futurecms.at, 6 in.na, 0 @@ -4153,6 +4179,7 @@ lc.it, 0 lcube-server.de, 4 lds, 0 le.it, 0 +leadpages.co, 4 leangaviika.no, 0 lease, 0 leasing.aero, 0 @@ -4322,8 +4349,10 @@ louvre.museum, 0 love, 0 lowicz.pl, 0 loyalist.museum, 0 +lpages.co, 4 lpl, 0 lplfinancial, 0 +lpusercontent.com, 4 lr, 0 ls, 0 lt, 0 @@ -6378,6 +6407,7 @@ ru.net, 4 rugby, 0 ruhr, 0 run, 0 +run.app, 4 ruovat.no, 0 russia.museum, 0 rv.ua, 0 @@ -6587,6 +6617,7 @@ sc.tz, 0 sc.ug, 0 sc.us, 0 sca, 0 +scapp.io, 4 scb, 0 sch.ae, 0 sch.id, 0 @@ -6979,7 +7010,6 @@ spdns.de, 4 spdns.eu, 4 spdns.org, 4 spectrum.myjino.ru, 6 -spiegel, 0 spjelkavik.no, 0 sport, 0 sport.hu, 0 @@ -7267,6 +7297,9 @@ tecnologia.bo, 0 tel, 0 tel.tr, 0 tele.amune.org, 4 +telebit.app, 4 +telebit.io, 4 +telebit.xyz, 6 telefonica, 0 telekommunikation.museum, 0 television.museum, 0 @@ -8636,7 +8669,6 @@ zgorzelec.pl, 0 zhitomir.ua, 0 zhytomyr.ua, 0 zip, 0 -zippo, 0 zj.cn, 0 zlg.br, 0 zm, 0 diff --git a/chromium/net/dns/BUILD.gn b/chromium/net/dns/BUILD.gn index 741a5b5685c..3b87b89a687 100644 --- a/chromium/net/dns/BUILD.gn +++ b/chromium/net/dns/BUILD.gn @@ -210,7 +210,7 @@ source_set("host_resolver_impl") { # Whitelist-only access so we can keep track of all usage external to the # network stack. friend = [ - # chromeos/network/network_change_notifier_chromeos.cc + # chromeos/network/network_change_notifier_posix.cc # ChromeOS-specific change notifier with some overrides for DnsConfigService # TODO(crbug.com/882610): Remove/cleanup once we figure out servicification. "//chromeos/network", diff --git a/chromium/net/http/bidirectional_stream.cc b/chromium/net/http/bidirectional_stream.cc index 404602b0e92..ecb0c63bfa6 100644 --- a/chromium/net/http/bidirectional_stream.cc +++ b/chromium/net/http/bidirectional_stream.cc @@ -420,14 +420,14 @@ void BidirectionalStream::OnNeedsClientAuth(const SSLConfig& used_ssl_config, StartRequest(ssl_config); } -void BidirectionalStream::OnHttpsProxyTunnelResponse( +void BidirectionalStream::OnHttpsProxyTunnelResponseRedirect( const HttpResponseInfo& response_info, const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, std::unique_ptr<HttpStream> stream) { DCHECK(stream_request_); - NotifyFailed(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); + NotifyFailed(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT); } void BidirectionalStream::OnQuicBroken() {} diff --git a/chromium/net/http/bidirectional_stream.h b/chromium/net/http/bidirectional_stream.h index 61fa08cae12..2cfeca08b6c 100644 --- a/chromium/net/http/bidirectional_stream.h +++ b/chromium/net/http/bidirectional_stream.h @@ -218,10 +218,11 @@ class NET_EXPORT BidirectionalStream : public BidirectionalStreamImpl::Delegate, HttpAuthController* auth_controller) override; void OnNeedsClientAuth(const SSLConfig& used_ssl_config, SSLCertRequestInfo* cert_info) override; - void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - std::unique_ptr<HttpStream> stream) override; + void OnHttpsProxyTunnelResponseRedirect( + const HttpResponseInfo& response_info, + const SSLConfig& used_ssl_config, + const ProxyInfo& used_proxy_info, + std::unique_ptr<HttpStream> stream) override; void OnQuicBroken() override; // Helper method to notify delegate if there is an error. diff --git a/chromium/net/http/http_network_transaction.cc b/chromium/net/http/http_network_transaction.cc index 19631949abf..ce86e621144 100644 --- a/chromium/net/http/http_network_transaction.cc +++ b/chromium/net/http/http_network_transaction.cc @@ -650,7 +650,7 @@ void HttpNetworkTransaction::OnNeedsClientAuth( OnIOComplete(ERR_SSL_CLIENT_AUTH_CERT_NEEDED); } -void HttpNetworkTransaction::OnHttpsProxyTunnelResponse( +void HttpNetworkTransaction::OnHttpsProxyTunnelResponseRedirect( const HttpResponseInfo& response_info, const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, @@ -670,7 +670,7 @@ void HttpNetworkTransaction::OnHttpsProxyTunnelResponse( stream_ = std::move(stream); stream_->SetRequestHeadersCallback(request_headers_callback_); stream_request_.reset(); // we're done with the stream request - OnIOComplete(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); + OnIOComplete(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT); } void HttpNetworkTransaction::OnQuicBroken() { @@ -856,11 +856,12 @@ int HttpNetworkTransaction::DoCreateStream() { } int HttpNetworkTransaction::DoCreateStreamComplete(int result) { - // If |result| is ERR_HTTPS_PROXY_TUNNEL_RESPONSE, then - // DoCreateStreamComplete is being called from OnHttpsProxyTunnelResponse, - // which resets the stream request first. Therefore, we have to grab the - // connection attempts in *that* function instead of here in that case. - if (result != ERR_HTTPS_PROXY_TUNNEL_RESPONSE) + // If |result| is ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT, then + // DoCreateStreamComplete is being called from + // OnHttpsProxyTunnelResponseRedirect, which resets the stream request first. + // Therefore, we have to grab the connection attempts in *that* function + // instead of here in that case. + if (result != ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT) CopyConnectionAttemptsFromStreamRequest(); if (result == OK) { @@ -868,10 +869,8 @@ int HttpNetworkTransaction::DoCreateStreamComplete(int result) { DCHECK(stream_.get()); } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { result = HandleCertificateRequest(result); - } else if (result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { - // Return OK and let the caller read the proxy's error page - next_state_ = STATE_NONE; - return OK; + } else if (result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT) { + return DoCreateStreamCompletedTunnelResponseRedirect(); } else if (result == ERR_HTTP_1_1_REQUIRED || result == ERR_PROXY_HTTP_1_1_REQUIRED) { return HandleHttp11Required(result); @@ -1937,4 +1936,45 @@ bool HttpNetworkTransaction::ContentEncodingsValid() const { return result; } +static HttpNetworkTransaction::TunnelRedirectHistogramValue +GetTunnelRedirectHistogramValue(bool is_main_frame, bool was_auto_detected) { + if (!is_main_frame && !was_auto_detected) + return HttpNetworkTransaction::kSubresourceByExplicitProxy; + if (is_main_frame && !was_auto_detected) + return HttpNetworkTransaction::kMainFrameByExplicitProxy; + if (!is_main_frame && was_auto_detected) + return HttpNetworkTransaction::kSubresourceByAutoDetectedProxy; + return HttpNetworkTransaction::kMainFrameByAutoDetectedProxy; +} + +// TODO(https://crbug.com/928551): Support for redirect on CONNECT is +// deprecated, and support will be removed. +// +// The code in this method handles the temporary histogramming and +// compatibility-mode policy during the phase-out. +int HttpNetworkTransaction::DoCreateStreamCompletedTunnelResponseRedirect() { + bool is_main_frame = (request_->load_flags & LOAD_MAIN_FRAME_DEPRECATED) == + LOAD_MAIN_FRAME_DEPRECATED; + bool was_auto_detected = proxy_info_.did_use_auto_detected_pac_script(); + + UMA_HISTOGRAM_ENUMERATION( + "Net.Proxy.RedirectDuringConnect", + GetTunnelRedirectHistogramValue(is_main_frame, was_auto_detected)); + + // For legacy compatibility, the proxy is allowed to redirect CONNECT + // if: + // (a) the request was for a top-level frame + // (b) the proxy server was explicitly configured (i.e. not + // auto-detected). + if (is_main_frame && !was_auto_detected) { + // Return OK and let the caller read the proxy's error page + next_state_ = STATE_NONE; + return OK; + } + + // Otherwise let the request fail. + stream_.reset(); + return ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT; +} + } // namespace net diff --git a/chromium/net/http/http_network_transaction.h b/chromium/net/http/http_network_transaction.h index 7ccc5f9b681..736c98f3de3 100644 --- a/chromium/net/http/http_network_transaction.h +++ b/chromium/net/http/http_network_transaction.h @@ -50,6 +50,16 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction : public HttpTransaction, public HttpStreamRequest::Delegate { public: + // Enumeration used by Net.Proxy.RedirectDuringConnect. Exposed here for + // sharing by unit-tests. + enum TunnelRedirectHistogramValue { + kSubresourceByExplicitProxy = 0, + kMainFrameByExplicitProxy = 1, + kSubresourceByAutoDetectedProxy = 2, + kMainFrameByAutoDetectedProxy = 3, + kMaxValue = kMainFrameByAutoDetectedProxy + }; + HttpNetworkTransaction(RequestPriority priority, HttpNetworkSession* session); @@ -117,10 +127,11 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction HttpAuthController* auth_controller) override; void OnNeedsClientAuth(const SSLConfig& used_ssl_config, SSLCertRequestInfo* cert_info) override; - void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - std::unique_ptr<HttpStream> stream) override; + void OnHttpsProxyTunnelResponseRedirect( + const HttpResponseInfo& response_info, + const SSLConfig& used_ssl_config, + const ProxyInfo& used_proxy_info, + std::unique_ptr<HttpStream> stream) override; void OnQuicBroken() override; void GetConnectionAttempts(ConnectionAttempts* out) const override; @@ -309,6 +320,10 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction // "Accept-Encoding". bool ContentEncodingsValid() const; + // Logic for handling ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT seen during + // DoCreateStreamCompletedTunnel(). + int DoCreateStreamCompletedTunnelResponseRedirect(); + scoped_refptr<HttpAuthController> auth_controllers_[HttpAuth::AUTH_NUM_TARGETS]; diff --git a/chromium/net/http/http_network_transaction_unittest.cc b/chromium/net/http/http_network_transaction_unittest.cc index ae5b2324085..0a9d165ded9 100644 --- a/chromium/net/http/http_network_transaction_unittest.cc +++ b/chromium/net/http/http_network_transaction_unittest.cc @@ -9514,7 +9514,7 @@ TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) { CONNECT_TIMING_HAS_SSL_TIMES); } -// Test an HTTPS Proxy's ability to redirect a CONNECT request +// Test that an HTTPS Proxy can redirect a CONNECT request for main frames. TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) { session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixedFromPacResult( @@ -9523,6 +9523,7 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) { session_deps_.net_log = &net_log; HttpRequestInfo request; + request.load_flags = LOAD_MAIN_FRAME_DEPRECATED; request.method = "GET"; request.url = GURL("https://www.example.org/"); request.traffic_annotation = @@ -9569,7 +9570,7 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) { // In the case of redirects from proxies, HttpNetworkTransaction returns // timing for the proxy connection instead of the connection to the host, // and no send / receive times. - // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse. + // See HttpNetworkTransaction::OnHttpsProxyTunnelResponseRedirect. LoadTimingInfo load_timing_info; EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); @@ -9590,13 +9591,120 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) { EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); } -// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request +// Test that an HTTPS Proxy cannot redirect a CONNECT request for subresources. +TEST_F(HttpNetworkTransactionTest, + RedirectOfHttpsConnectSubresourceViaHttpsProxy) { + base::HistogramTester histograms; + session_deps_.proxy_resolution_service = + ProxyResolutionService::CreateFixedFromPacResult( + "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); + TestNetLog net_log; + session_deps_.net_log = &net_log; + + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("https://www.example.org/"); + request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + + MockWrite data_writes[] = { + MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org:443\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + }; + + MockRead data_reads[] = { + MockRead("HTTP/1.1 302 Redirect\r\n"), + MockRead("Location: http://login.example.com/\r\n"), + MockRead("Content-Length: 0\r\n\r\n"), + MockRead(SYNCHRONOUS, OK), + }; + + StaticSocketDataProvider data(data_reads, data_writes); + SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy + + session_deps_.socket_factory->AddSocketDataProvider(&data); + session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); + + TestCompletionCallback callback; + + std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); + + int rv = trans.Start(&request, callback.callback(), NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + rv = callback.WaitForResult(); + EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT)); + + histograms.ExpectUniqueSample( + "Net.Proxy.RedirectDuringConnect", + HttpNetworkTransaction::kSubresourceByExplicitProxy, 1); +} + +// Test that an HTTPS Proxy which was auto-detected cannot redirect a CONNECT +// request for main frames. +TEST_F(HttpNetworkTransactionTest, + RedirectOfHttpsConnectViaAutoDetectedHttpsProxy) { + base::HistogramTester histograms; + session_deps_.proxy_resolution_service = + ProxyResolutionService::CreateFixedFromAutoDetectedPacResult( + "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); + TestNetLog net_log; + session_deps_.net_log = &net_log; + + HttpRequestInfo request; + request.load_flags = LOAD_MAIN_FRAME_DEPRECATED; + request.method = "GET"; + request.url = GURL("https://www.example.org/"); + request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + + MockWrite data_writes[] = { + MockWrite(ASYNC, 0, + "CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org:443\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + }; + + MockRead data_reads[] = { + MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"), + MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"), + MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"), + }; + + SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes); + SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy + + session_deps_.socket_factory->AddSocketDataProvider(&data); + session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); + + TestCompletionCallback callback; + + std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); + + int rv = trans.Start(&request, callback.callback(), NetLogWithSource()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + rv = callback.WaitForResult(); + EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT)); + + histograms.ExpectUniqueSample( + "Net.Proxy.RedirectDuringConnect", + HttpNetworkTransaction::kMainFrameByAutoDetectedProxy, 1); +} + +// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request for main +// frames. TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) { + base::HistogramTester histograms; session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); HttpRequestInfo request; request.method = "GET"; + request.load_flags = LOAD_MAIN_FRAME_DEPRECATED; request.url = GURL("https://www.example.org/"); request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); @@ -9645,6 +9753,10 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) { std::string url; EXPECT_TRUE(response->headers->IsRedirect(&url)); EXPECT_EQ("http://login.example.com/", url); + + histograms.ExpectUniqueSample( + "Net.Proxy.RedirectDuringConnect", + HttpNetworkTransaction::kMainFrameByExplicitProxy, 1); } // Test that an HTTPS proxy's response to a CONNECT request is filtered. diff --git a/chromium/net/http/http_proxy_client_socket.cc b/chromium/net/http/http_proxy_client_socket.cc index 12cfb3dfea9..dd877223a03 100644 --- a/chromium/net/http/http_proxy_client_socket.cc +++ b/chromium/net/http/http_proxy_client_socket.cc @@ -484,7 +484,7 @@ int HttpProxyClientSocket::DoReadHeadersComplete(int result) { &redirect_load_timing_info_); transport_.reset(); http_stream_parser_.reset(); - return ERR_HTTPS_PROXY_TUNNEL_RESPONSE; + return ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT; case 407: // Proxy Authentication Required // We need this status code to allow proxy authentication. Our diff --git a/chromium/net/http/http_proxy_client_socket_pool.cc b/chromium/net/http/http_proxy_client_socket_pool.cc index 21ace98a69e..d7d704f4f57 100644 --- a/chromium/net/http/http_proxy_client_socket_pool.cc +++ b/chromium/net/http/http_proxy_client_socket_pool.cc @@ -293,7 +293,7 @@ int HttpProxyConnectJob::HandleConnectResult(int result) { error_response_info_ = client_socket_->GetAdditionalErrorState(); if (result == OK || result == ERR_PROXY_AUTH_REQUESTED || - result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { + result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT) { SetSocket(std::move(client_socket_)); } return result; diff --git a/chromium/net/http/http_proxy_client_socket_pool_unittest.cc b/chromium/net/http/http_proxy_client_socket_pool_unittest.cc index 4397ae6c31c..3fbd7ab86a7 100644 --- a/chromium/net/http/http_proxy_client_socket_pool_unittest.cc +++ b/chromium/net/http/http_proxy_client_socket_pool_unittest.cc @@ -793,7 +793,7 @@ TEST_P(HttpProxyClientSocketPoolTest, TunnelSetupRedirect) { EXPECT_FALSE(handle_.socket()); } else { // Expect ProxyClientSocket to return the proxy's response, sanitized. - EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE)); + EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT)); EXPECT_TRUE(handle_.is_initialized()); ASSERT_TRUE(handle_.socket()); diff --git a/chromium/net/http/http_stream_factory_job.cc b/chromium/net/http/http_stream_factory_job.cc index 5579cae972a..8c4eb8ec46d 100644 --- a/chromium/net/http/http_stream_factory_job.cc +++ b/chromium/net/http/http_stream_factory_job.cc @@ -532,13 +532,13 @@ void HttpStreamFactory::Job::OnNeedsClientAuthCallback( // |this| may be deleted after this call. } -void HttpStreamFactory::Job::OnHttpsProxyTunnelResponseCallback( +void HttpStreamFactory::Job::OnHttpsProxyTunnelResponseRedirectCallback( const HttpResponseInfo& response_info, std::unique_ptr<HttpStream> stream) { DCHECK_NE(job_type_, PRECONNECT); - delegate_->OnHttpsProxyTunnelResponse(this, response_info, server_ssl_config_, - proxy_info_, std::move(stream)); + delegate_->OnHttpsProxyTunnelResponseRedirect( + this, response_info, server_ssl_config_, proxy_info_, std::move(stream)); // |this| may be deleted after this call. } @@ -638,7 +638,7 @@ void HttpStreamFactory::Job::RunLoop(int result) { connection_->ssl_error_response_info().cert_request_info))); return; - case ERR_HTTPS_PROXY_TUNNEL_RESPONSE: { + case ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT: { DCHECK(connection_.get()); DCHECK(connection_->socket()); DCHECK(establishing_tunnel_); @@ -647,8 +647,8 @@ void HttpStreamFactory::Job::RunLoop(int result) { static_cast<ProxyClientSocket*>(connection_->socket()); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind( - &Job::OnHttpsProxyTunnelResponseCallback, + base::BindOnce( + &Job::OnHttpsProxyTunnelResponseRedirectCallback, ptr_factory_.GetWeakPtr(), *proxy_socket->GetConnectResponseInfo(), base::Passed(proxy_socket->CreateConnectResponseStream()))); @@ -1090,7 +1090,7 @@ int HttpStreamFactory::Job::DoInitConnectionComplete(int result) { } if (result == ERR_PROXY_AUTH_REQUESTED || - result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { + result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT) { DCHECK(!ssl_started); // Other state (i.e. |using_ssl_|) suggests that |connection_| will have an // SSL socket, but there was an error before that could happen. This diff --git a/chromium/net/http/http_stream_factory_job.h b/chromium/net/http/http_stream_factory_job.h index 4d50b0c75f7..7dc0399a4aa 100644 --- a/chromium/net/http/http_stream_factory_job.h +++ b/chromium/net/http/http_stream_factory_job.h @@ -92,9 +92,9 @@ class HttpStreamFactory::Job { const SSLConfig& used_ssl_config, const SSLInfo& ssl_info) = 0; - // Invoked when |job| has a failure of the CONNECT request through an HTTPS - // proxy. - virtual void OnHttpsProxyTunnelResponse( + // Invoked when |job| has a failure of the CONNECT request (due to a 302 + // redirect) through an HTTPS proxy. + virtual void OnHttpsProxyTunnelResponseRedirect( Job* job, const HttpResponseInfo& response_info, const SSLConfig& used_ssl_config, @@ -302,8 +302,9 @@ class HttpStreamFactory::Job { void OnNeedsProxyAuthCallback(const HttpResponseInfo& response_info, HttpAuthController* auth_controller); void OnNeedsClientAuthCallback(SSLCertRequestInfo* cert_info); - void OnHttpsProxyTunnelResponseCallback(const HttpResponseInfo& response_info, - std::unique_ptr<HttpStream> stream); + void OnHttpsProxyTunnelResponseRedirectCallback( + const HttpResponseInfo& response_info, + std::unique_ptr<HttpStream> stream); void OnPreconnectsComplete(); void OnIOComplete(int result); diff --git a/chromium/net/http/http_stream_factory_job_controller.cc b/chromium/net/http/http_stream_factory_job_controller.cc index dd79f0a3be1..c76c66df273 100644 --- a/chromium/net/http/http_stream_factory_job_controller.cc +++ b/chromium/net/http/http_stream_factory_job_controller.cc @@ -414,7 +414,7 @@ void HttpStreamFactory::JobController::OnCertificateError( delegate_->OnCertificateError(status, used_ssl_config, ssl_info); } -void HttpStreamFactory::JobController::OnHttpsProxyTunnelResponse( +void HttpStreamFactory::JobController::OnHttpsProxyTunnelResponseRedirect( Job* job, const HttpResponseInfo& response_info, const SSLConfig& used_ssl_config, @@ -433,8 +433,8 @@ void HttpStreamFactory::JobController::OnHttpsProxyTunnelResponse( BindJob(job); if (!request_) return; - delegate_->OnHttpsProxyTunnelResponse(response_info, used_ssl_config, - used_proxy_info, std::move(stream)); + delegate_->OnHttpsProxyTunnelResponseRedirect( + response_info, used_ssl_config, used_proxy_info, std::move(stream)); } void HttpStreamFactory::JobController::OnNeedsClientAuth( diff --git a/chromium/net/http/http_stream_factory_job_controller.h b/chromium/net/http/http_stream_factory_job_controller.h index 6c4c2b0acac..5a7b0ff4da3 100644 --- a/chromium/net/http/http_stream_factory_job_controller.h +++ b/chromium/net/http/http_stream_factory_job_controller.h @@ -120,13 +120,14 @@ class HttpStreamFactory::JobController const SSLConfig& used_ssl_config, const SSLInfo& ssl_info) override; - // Invoked when |job| has a failure of the CONNECT request through an HTTPS - // proxy. - void OnHttpsProxyTunnelResponse(Job* job, - const HttpResponseInfo& response_info, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - std::unique_ptr<HttpStream> stream) override; + // Invoked when |job| has a failure of the CONNECT request (due to 302 + // redirect) through an HTTPS proxy. + void OnHttpsProxyTunnelResponseRedirect( + Job* job, + const HttpResponseInfo& response_info, + const SSLConfig& used_ssl_config, + const ProxyInfo& used_proxy_info, + std::unique_ptr<HttpStream> stream) override; // Invoked when |job| raises failure for SSL Client Auth. void OnNeedsClientAuth(Job* job, diff --git a/chromium/net/http/http_stream_factory_test_util.h b/chromium/net/http/http_stream_factory_test_util.h index c186f1006ca..c944019712d 100644 --- a/chromium/net/http/http_stream_factory_test_util.h +++ b/chromium/net/http/http_stream_factory_test_util.h @@ -93,11 +93,11 @@ class MockHttpStreamRequestDelegate : public HttpStreamRequest::Delegate { SSLCertRequestInfo* cert_info)); // std::unique_ptr is not copyable and therefore cannot be mocked. - void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - std::unique_ptr<HttpStream> stream) override { - } + void OnHttpsProxyTunnelResponseRedirect( + const HttpResponseInfo& response_info, + const SSLConfig& used_ssl_config, + const ProxyInfo& used_proxy_info, + std::unique_ptr<HttpStream> stream) override {} MOCK_METHOD0(OnQuicBroken, void()); diff --git a/chromium/net/http/http_stream_factory_unittest.cc b/chromium/net/http/http_stream_factory_unittest.cc index 1166709885a..6a37330b031 100644 --- a/chromium/net/http/http_stream_factory_unittest.cc +++ b/chromium/net/http/http_stream_factory_unittest.cc @@ -262,11 +262,11 @@ class StreamRequestWaiter : public HttpStreamRequest::Delegate { void OnNeedsClientAuth(const SSLConfig& used_ssl_config, SSLCertRequestInfo* cert_info) override {} - void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - std::unique_ptr<HttpStream> stream) override { - } + void OnHttpsProxyTunnelResponseRedirect( + const HttpResponseInfo& response_info, + const SSLConfig& used_ssl_config, + const ProxyInfo& used_proxy_info, + std::unique_ptr<HttpStream> stream) override {} void OnQuicBroken() override {} diff --git a/chromium/net/http/http_stream_request.h b/chromium/net/http/http_stream_request.h index c07e7f62d5f..602854c7387 100644 --- a/chromium/net/http/http_stream_request.h +++ b/chromium/net/http/http_stream_request.h @@ -125,9 +125,9 @@ class NET_EXPORT_PRIVATE HttpStreamRequest { virtual void OnNeedsClientAuth(const SSLConfig& used_ssl_config, SSLCertRequestInfo* cert_info) = 0; - // This is the failure of the CONNECT request through an HTTPS proxy. - // Headers can be read from |response_info|, while the body can be read - // from |stream|. + // This is the failure of the CONNECT request through an HTTPS proxy due to + // a 302 redirect. Headers can be read from |response_info|, while the body + // can be read from |stream|. // // |used_ssl_config| indicates the actual SSL configuration used for this // stream, since the HttpStreamRequest may have modified the configuration @@ -137,7 +137,7 @@ class NET_EXPORT_PRIVATE HttpStreamRequest { // since the HttpStreamRequest performs the proxy resolution. // // Ownership of |stream| is transferred to the delegate. - virtual void OnHttpsProxyTunnelResponse( + virtual void OnHttpsProxyTunnelResponseRedirect( const HttpResponseInfo& response_info, const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, diff --git a/chromium/net/nqe/network_quality_estimator.cc b/chromium/net/nqe/network_quality_estimator.cc index 0ebf546963e..93831e7a160 100644 --- a/chromium/net/nqe/network_quality_estimator.cc +++ b/chromium/net/nqe/network_quality_estimator.cc @@ -747,6 +747,8 @@ void NetworkQualityEstimator::ComputeEffectiveConnectionType() { .downstream_throughput_kbps()); } + ClampKbpsBasedOnEct(); + UMA_HISTOGRAM_ENUMERATION("NQE.EffectiveConnectionType.OnECTComputation", effective_connection_type_, EFFECTIVE_CONNECTION_TYPE_LAST); @@ -791,6 +793,38 @@ void NetworkQualityEstimator::ComputeEffectiveConnectionType() { new_throughput_observations_since_last_ect_computation_ = 0; } +void NetworkQualityEstimator::ClampKbpsBasedOnEct() { + // No need to clamp when ECT is unknown or if the connection speed is fast. + if (effective_connection_type_ == EFFECTIVE_CONNECTION_TYPE_UNKNOWN || + effective_connection_type_ == EFFECTIVE_CONNECTION_TYPE_OFFLINE || + effective_connection_type_ == EFFECTIVE_CONNECTION_TYPE_4G) { + return; + } + + if (params_->upper_bound_typical_kbps_multiplier() <= 0.0) + return; + + DCHECK_LT(0, params_->TypicalNetworkQuality(effective_connection_type_) + .downstream_throughput_kbps()); + // For a given ECT, upper bound on Kbps can't be less than the typical Kbps + // for that ECT. + DCHECK_LE(1.0, params_->upper_bound_typical_kbps_multiplier()); + + if (effective_connection_type_ == EFFECTIVE_CONNECTION_TYPE_SLOW_2G || + effective_connection_type_ == EFFECTIVE_CONNECTION_TYPE_2G || + effective_connection_type_ == EFFECTIVE_CONNECTION_TYPE_3G) { + // Put an upper bound on Kbps. + network_quality_.set_downstream_throughput_kbps( + std::min(network_quality_.downstream_throughput_kbps(), + static_cast<int>( + params_->TypicalNetworkQuality(effective_connection_type_) + .downstream_throughput_kbps() * + params_->upper_bound_typical_kbps_multiplier()))); + return; + } + NOTREACHED(); +} + EffectiveConnectionType NetworkQualityEstimator::GetCappedECTBasedOnSignalStrength() const { if (!params_->cap_ect_based_on_signal_strength()) diff --git a/chromium/net/nqe/network_quality_estimator.h b/chromium/net/nqe/network_quality_estimator.h index 02da7517318..556ad97786e 100644 --- a/chromium/net/nqe/network_quality_estimator.h +++ b/chromium/net/nqe/network_quality_estimator.h @@ -521,6 +521,10 @@ class NET_EXPORT_PRIVATE NetworkQualityEstimator // value lower than |effective_connection_type_| may be returned. EffectiveConnectionType GetCappedECTBasedOnSignalStrength() const; + // Clamps the throughput estimate based on the current effective connection + // type. + void ClampKbpsBasedOnEct(); + // Determines if the requests to local host can be used in estimating the // network quality. Set to true only for tests. bool use_localhost_requests_; diff --git a/chromium/net/nqe/network_quality_estimator_params.cc b/chromium/net/nqe/network_quality_estimator_params.cc index e4c5d1a76d4..8b4ba3020fb 100644 --- a/chromium/net/nqe/network_quality_estimator_params.cc +++ b/chromium/net/nqe/network_quality_estimator_params.cc @@ -505,6 +505,11 @@ NetworkQualityEstimatorParams::NetworkQualityEstimatorParams( params_, "cap_ect_based_on_signal_strength", "false") == "true"), + upper_bound_typical_kbps_multiplier_( + GetDoubleValueForVariationParamWithDefaultValue( + params_, + "upper_bound_typical_kbps_multiplier", + 3.5)), use_small_responses_(false) { DCHECK(hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_ == -1 || hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_ > 0); diff --git a/chromium/net/nqe/network_quality_estimator_params.h b/chromium/net/nqe/network_quality_estimator_params.h index f5f53ff0ebf..f98a2848c08 100644 --- a/chromium/net/nqe/network_quality_estimator_params.h +++ b/chromium/net/nqe/network_quality_estimator_params.h @@ -246,6 +246,15 @@ class NET_EXPORT NetworkQualityEstimatorParams { return cap_ect_based_on_signal_strength_; } + // Returns a multiplier which is used to clamp Kbps on slow connections. For + // a given ECT, the upper bound on Kbps is computed based on this returned + // multiplier and the typical Kbps for the given ECT. If + // upper_bound_typical_kbps_multiplier() is -1, then clamping should be + // disabled. + double upper_bound_typical_kbps_multiplier() const { + return upper_bound_typical_kbps_multiplier_; + } + // Sets the forced effective connection type as |type|. void SetForcedEffectiveConnectionTypeForTesting(EffectiveConnectionType type); @@ -278,6 +287,7 @@ class NET_EXPORT NetworkQualityEstimatorParams { const base::TimeDelta socket_watchers_min_notification_interval_; const bool use_end_to_end_rtt_; const bool cap_ect_based_on_signal_strength_; + const double upper_bound_typical_kbps_multiplier_; bool use_small_responses_; diff --git a/chromium/net/nqe/network_quality_estimator_unittest.cc b/chromium/net/nqe/network_quality_estimator_unittest.cc index b92ee2b5055..3456778806e 100644 --- a/chromium/net/nqe/network_quality_estimator_unittest.cc +++ b/chromium/net/nqe/network_quality_estimator_unittest.cc @@ -811,7 +811,7 @@ TEST_F(NetworkQualityEstimatorTest, DefaultObservationsOverridden) { std::map<std::string, std::string> variation_params; variation_params["Unknown.DefaultMedianKbps"] = "100"; variation_params["WiFi.DefaultMedianKbps"] = "200"; - variation_params["2G.DefaultMedianKbps"] = "300"; + variation_params["2G.DefaultMedianKbps"] = "250"; variation_params["Unknown.DefaultMedianRTTMsec"] = "1000"; variation_params["WiFi.DefaultMedianRTTMsec"] = "2000"; @@ -878,7 +878,7 @@ TEST_F(NetworkQualityEstimatorTest, DefaultObservationsOverridden) { EXPECT_EQ(rtt, estimator.GetTransportRTT().value()); EXPECT_TRUE( estimator.GetRecentDownlinkThroughputKbps(base::TimeTicks(), &kbps)); - EXPECT_EQ(300, kbps); + EXPECT_EQ(250, kbps); EXPECT_EQ(kbps, estimator.GetDownstreamThroughputKbps().value()); // Simulate network change to 3G. Default estimates should be available. @@ -970,6 +970,78 @@ TEST_F(NetworkQualityEstimatorTest, ObtainThresholdsOnlyRTT) { } } +TEST_F(NetworkQualityEstimatorTest, ClampKbpsBasedOnEct) { + const int32_t kTypicalDownlinkKbpsEffectiveConnectionType + [net::EFFECTIVE_CONNECTION_TYPE_LAST] = {0, 0, 40, 75, 400, 1600}; + + const struct { + std::string upper_bound_typical_kbps_multiplier; + int32_t set_rtt_msec; + int32_t set_downstream_kbps; + EffectiveConnectionType expected_ect; + int32_t expected_downstream_throughput; + } tests[] = { + // Clamping multiplier set to 3.5 by default. + {"", 3000, INT32_MAX, EFFECTIVE_CONNECTION_TYPE_SLOW_2G, + kTypicalDownlinkKbpsEffectiveConnectionType + [EFFECTIVE_CONNECTION_TYPE_SLOW_2G] * + 3.5}, + // Clamping disabled. + {"-1", 3000, INT32_MAX, EFFECTIVE_CONNECTION_TYPE_SLOW_2G, INT32_MAX}, + // Clamping multiplier overridden to 1000. + {"1000.0", 3000, INT32_MAX, EFFECTIVE_CONNECTION_TYPE_SLOW_2G, + kTypicalDownlinkKbpsEffectiveConnectionType + [EFFECTIVE_CONNECTION_TYPE_SLOW_2G] * + 1000}, + // Clamping multiplier overridden to 1000. + {"1000.0", 1500, INT32_MAX, EFFECTIVE_CONNECTION_TYPE_2G, + kTypicalDownlinkKbpsEffectiveConnectionType + [EFFECTIVE_CONNECTION_TYPE_2G] * + 1000}, + // Clamping multiplier overridden to 1000. + {"1000.0", 700, INT32_MAX, EFFECTIVE_CONNECTION_TYPE_3G, + kTypicalDownlinkKbpsEffectiveConnectionType + [EFFECTIVE_CONNECTION_TYPE_3G] * + 1000}, + // Clamping multiplier set to 3.5 by default. + {"", 500, INT32_MAX, EFFECTIVE_CONNECTION_TYPE_3G, + kTypicalDownlinkKbpsEffectiveConnectionType + [EFFECTIVE_CONNECTION_TYPE_3G] * + 3.5}, + // Clamping ineffective when the observed throughput is lower than the + // clamped throughput. + {"", 500, 100, EFFECTIVE_CONNECTION_TYPE_3G, 100}, + // Clamping disabled on 4G ECT. + {"1.0", 40, INT32_MAX, EFFECTIVE_CONNECTION_TYPE_4G, INT32_MAX}, + // Clamping disabled on 4G ECT. + {"1.0", 40, 100, EFFECTIVE_CONNECTION_TYPE_4G, 100}, + }; + + for (const auto& test : tests) { + std::map<std::string, std::string> variation_params; + variation_params["upper_bound_typical_kbps_multiplier"] = + test.upper_bound_typical_kbps_multiplier; + TestNetworkQualityEstimator estimator(variation_params); + + // Simulate the connection type as Wi-Fi so that GetEffectiveConnectionType + // does not return Offline if the device is offline. + estimator.SimulateNetworkChange(NetworkChangeNotifier::CONNECTION_WIFI, + "test"); + + estimator.set_recent_http_rtt( + base::TimeDelta::FromMilliseconds(test.set_rtt_msec)); + estimator.set_start_time_null_downlink_throughput_kbps(INT32_MAX); + estimator.set_recent_downlink_throughput_kbps(test.set_downstream_kbps); + estimator.set_start_time_null_downlink_throughput_kbps( + test.set_downstream_kbps); + estimator.SetStartTimeNullHttpRtt( + base::TimeDelta::FromMilliseconds(test.set_rtt_msec)); + EXPECT_EQ(test.expected_ect, estimator.GetEffectiveConnectionType()); + EXPECT_EQ(test.expected_downstream_throughput, + estimator.GetDownstreamThroughputKbps().value()); + } +} + // Tests that default HTTP RTT thresholds for different effective // connection types are correctly set. TEST_F(NetworkQualityEstimatorTest, DefaultHttpRTTBasedThresholds) { @@ -1356,7 +1428,7 @@ TEST_F(NetworkQualityEstimatorTest, MAYBE_TestEffectiveConnectionTypeObserver) { EXPECT_EQ(0U, observer.effective_connection_types().size()); estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(1500)); - estimator.set_start_time_null_downlink_throughput_kbps(100000); + estimator.set_start_time_null_downlink_throughput_kbps(164); tick_clock.Advance(base::TimeDelta::FromMinutes(60)); @@ -1380,9 +1452,9 @@ TEST_F(NetworkQualityEstimatorTest, MAYBE_TestEffectiveConnectionTypeObserver) { EXPECT_EQ(-1, estimator.GetNetLogLastIntegerValue( NetLogEventType::NETWORK_QUALITY_CHANGED, "transport_rtt_ms")); - EXPECT_EQ(100000, estimator.GetNetLogLastIntegerValue( - NetLogEventType::NETWORK_QUALITY_CHANGED, - "downstream_throughput_kbps")); + EXPECT_EQ(164, estimator.GetNetLogLastIntegerValue( + NetLogEventType::NETWORK_QUALITY_CHANGED, + "downstream_throughput_kbps")); histogram_tester.ExpectUniqueSample("NQE.MainFrame.EffectiveConnectionType", EFFECTIVE_CONNECTION_TYPE_2G, 1); diff --git a/chromium/net/proxy_resolution/pac_file_decider.cc b/chromium/net/proxy_resolution/pac_file_decider.cc index 8b5b37c72b3..2999df80a80 100644 --- a/chromium/net/proxy_resolution/pac_file_decider.cc +++ b/chromium/net/proxy_resolution/pac_file_decider.cc @@ -42,8 +42,6 @@ bool LooksLikePacScript(const base::string16& script) { base::string16::npos; } -} // anonymous namespace - // This is the hard-coded location used by the DNS portion of web proxy // auto-discovery. // @@ -56,10 +54,17 @@ bool LooksLikePacScript(const base::string16& script) { // // For more details, also check out this comment: // http://code.google.com/p/chromium/issues/detail?id=18575#c20 -namespace { const char kWpadUrl[] = "http://wpad/wpad.dat"; const int kQuickCheckDelayMs = 1000; -}; // namespace + +} // namespace + +PacFileDataWithSource::PacFileDataWithSource() = default; +PacFileDataWithSource::~PacFileDataWithSource() = default; +PacFileDataWithSource::PacFileDataWithSource(const PacFileDataWithSource&) = + default; +PacFileDataWithSource& PacFileDataWithSource::operator=( + const PacFileDataWithSource&) = default; std::unique_ptr<base::Value> PacFileDecider::PacSource::NetLogCallback( const GURL* effective_pac_url, @@ -156,7 +161,7 @@ const ProxyConfigWithAnnotation& PacFileDecider::effective_config() const { return effective_config_; } -const scoped_refptr<PacFileData>& PacFileDecider::script_data() const { +const PacFileDataWithSource& PacFileDecider::script_data() const { DCHECK_EQ(STATE_NONE, next_state_); return script_data_; } @@ -375,12 +380,13 @@ int PacFileDecider::DoVerifyPacScriptComplete(int result) { const PacSource& pac_source = current_pac_source(); // Extract the current script data. + script_data_.from_auto_detect = pac_source.type != PacSource::CUSTOM; if (fetch_pac_bytes_) { - script_data_ = PacFileData::FromUTF16(pac_script_); + script_data_.data = PacFileData::FromUTF16(pac_script_); } else { - script_data_ = pac_source.type == PacSource::CUSTOM - ? PacFileData::FromURL(pac_source.url) - : PacFileData::ForAutoDetect(); + script_data_.data = pac_source.type == PacSource::CUSTOM + ? PacFileData::FromURL(pac_source.url) + : PacFileData::ForAutoDetect(); } // Let the caller know which automatic setting we ended up initializing the diff --git a/chromium/net/proxy_resolution/pac_file_decider.h b/chromium/net/proxy_resolution/pac_file_decider.h index e1f038d5a69..b41b78a5162 100644 --- a/chromium/net/proxy_resolution/pac_file_decider.h +++ b/chromium/net/proxy_resolution/pac_file_decider.h @@ -36,6 +36,24 @@ class NetLogCaptureMode; class ProxyResolver; class PacFileFetcher; +// Structure that encapsulates the result a PacFileData along with an +// indication of its origin: was it obtained implicitly from auto-detect, +// or was it read from a more explicitly configured URL. +// +// Note that |!from_auto_detect| does NOT imply the script was securely +// delivered. Most commonly PAC scripts are configured from http:// URLs, +// both for auto-detect and not. +struct NET_EXPORT_PRIVATE PacFileDataWithSource { + PacFileDataWithSource(); + explicit PacFileDataWithSource(const PacFileDataWithSource&); + ~PacFileDataWithSource(); + + PacFileDataWithSource& operator=(const PacFileDataWithSource&); + + scoped_refptr<PacFileData> data; + bool from_auto_detect = false; +}; + // PacFileDecider is a helper class used by ProxyResolutionService to // determine which PAC script to use given our proxy configuration. // @@ -87,7 +105,7 @@ class NET_EXPORT_PRIVATE PacFileDecider { const ProxyConfigWithAnnotation& effective_config() const; - const scoped_refptr<PacFileData>& script_data() const; + const PacFileDataWithSource& script_data() const; void set_quick_check_enabled(bool enabled) { quick_check_enabled_ = enabled; } @@ -197,7 +215,7 @@ class NET_EXPORT_PRIVATE PacFileDecider { // Results. ProxyConfigWithAnnotation effective_config_; - scoped_refptr<PacFileData> script_data_; + PacFileDataWithSource script_data_; std::unique_ptr<HostResolver::ResolveHostRequest> resolve_request_; diff --git a/chromium/net/proxy_resolution/pac_file_decider_unittest.cc b/chromium/net/proxy_resolution/pac_file_decider_unittest.cc index fd10db4204b..3d736718386 100644 --- a/chromium/net/proxy_resolution/pac_file_decider_unittest.cc +++ b/chromium/net/proxy_resolution/pac_file_decider_unittest.cc @@ -215,7 +215,8 @@ TEST(PacFileDeciderTest, CustomPacSucceeds) { config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), IsOk()); - EXPECT_EQ(rule.text(), decider.script_data()->utf16()); + EXPECT_EQ(rule.text(), decider.script_data().data->utf16()); + EXPECT_FALSE(decider.script_data().from_auto_detect); // Check the NetLog was filled correctly. TestNetLogEntry::List entries; @@ -253,7 +254,7 @@ TEST(PacFileDeciderTest, CustomPacFails1) { config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), IsError(kFailedDownloading)); - EXPECT_FALSE(decider.script_data()); + EXPECT_FALSE(decider.script_data().data); // Check the NetLog was filled correctly. TestNetLogEntry::List entries; @@ -289,7 +290,7 @@ TEST(PacFileDeciderTest, CustomPacFails2) { config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), IsError(kFailedParsing)); - EXPECT_FALSE(decider.script_data()); + EXPECT_FALSE(decider.script_data().data); } // Fail downloading the custom PAC script, because the fetcher was NULL. @@ -306,7 +307,7 @@ TEST(PacFileDeciderTest, HasNullPacFileFetcher) { config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), IsError(ERR_UNEXPECTED)); - EXPECT_FALSE(decider.script_data()); + EXPECT_FALSE(decider.script_data().data); } // Succeeds in choosing autodetect (WPAD DNS). @@ -326,7 +327,8 @@ TEST(PacFileDeciderTest, AutodetectSuccess) { config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), IsOk()); - EXPECT_EQ(rule.text(), decider.script_data()->utf16()); + EXPECT_EQ(rule.text(), decider.script_data().data->utf16()); + EXPECT_TRUE(decider.script_data().from_auto_detect); EXPECT_TRUE(decider.effective_config().value().has_pac_url()); EXPECT_EQ(rule.url, decider.effective_config().value().pac_url()); @@ -371,7 +373,8 @@ TEST_F(PacFileDeciderQuickCheckTest, SyncSuccess) { resolver_.rules_map()[HostResolverSource::SYSTEM]->AddRule("wpad", "1.2.3.4"); EXPECT_THAT(StartDecider(), IsOk()); - EXPECT_EQ(rule_.text(), decider_->script_data()->utf16()); + EXPECT_EQ(rule_.text(), decider_->script_data().data->utf16()); + EXPECT_TRUE(decider_->script_data().from_auto_detect); EXPECT_TRUE(decider_->effective_config().value().has_pac_url()); EXPECT_EQ(rule_.url, decider_->effective_config().value().pac_url()); @@ -388,7 +391,8 @@ TEST_F(PacFileDeciderQuickCheckTest, AsyncSuccess) { resolver_.ResolveAllPending(); callback_.WaitForResult(); EXPECT_FALSE(resolver_.has_pending_requests()); - EXPECT_EQ(rule_.text(), decider_->script_data()->utf16()); + EXPECT_EQ(rule_.text(), decider_->script_data().data->utf16()); + EXPECT_TRUE(decider_->script_data().from_auto_detect); EXPECT_TRUE(decider_->effective_config().value().has_pac_url()); EXPECT_EQ(rule_.url, decider_->effective_config().value().pac_url()); } @@ -500,7 +504,8 @@ TEST(PacFileDeciderTest, AutodetectFailCustomSuccess1) { config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), IsOk()); - EXPECT_EQ(rule.text(), decider.script_data()->utf16()); + EXPECT_EQ(rule.text(), decider.script_data().data->utf16()); + EXPECT_FALSE(decider.script_data().from_auto_detect); EXPECT_TRUE(decider.effective_config().value().has_pac_url()); EXPECT_EQ(rule.url, decider.effective_config().value().pac_url()); @@ -529,7 +534,8 @@ TEST(PacFileDeciderTest, AutodetectFailCustomSuccess2) { config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), IsOk()); - EXPECT_EQ(rule.text(), decider.script_data()->utf16()); + EXPECT_EQ(rule.text(), decider.script_data().data->utf16()); + EXPECT_FALSE(decider.script_data().from_auto_detect); // Verify that the effective configuration no longer contains auto detect or // any of the manual settings. @@ -592,7 +598,7 @@ TEST(PacFileDeciderTest, AutodetectFailCustomFails1) { config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), IsError(kFailedDownloading)); - EXPECT_FALSE(decider.script_data()); + EXPECT_FALSE(decider.script_data().data); } // Fails at WPAD (downloading), and fails at custom PAC (parsing). @@ -614,7 +620,7 @@ TEST(PacFileDeciderTest, AutodetectFailCustomFails2) { config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), IsError(kFailedParsing)); - EXPECT_FALSE(decider.script_data()); + EXPECT_FALSE(decider.script_data().data); } // This is a copy-paste of CustomPacFails1, with the exception that we give it @@ -642,7 +648,7 @@ TEST(PacFileDeciderTest, CustomPacFails1_WithPositiveDelay) { IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsError(kFailedDownloading)); - EXPECT_FALSE(decider.script_data()); + EXPECT_FALSE(decider.script_data().data); // Check the NetLog was filled correctly. TestNetLogEntry::List entries; @@ -684,7 +690,7 @@ TEST(PacFileDeciderTest, CustomPacFails1_WithNegativeDelay) { ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta::FromSeconds(-5), true, callback.callback()), IsError(kFailedDownloading)); - EXPECT_FALSE(decider.script_data()); + EXPECT_FALSE(decider.script_data().data); // Check the NetLog was filled correctly. TestNetLogEntry::List entries; @@ -752,7 +758,8 @@ TEST(PacFileDeciderTest, AutodetectDhcpSuccess) { config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), IsOk()); - EXPECT_EQ(dhcp_fetcher.expected_text(), decider.script_data()->utf16()); + EXPECT_EQ(dhcp_fetcher.expected_text(), decider.script_data().data->utf16()); + EXPECT_TRUE(decider.script_data().from_auto_detect); EXPECT_TRUE(decider.effective_config().value().has_pac_url()); EXPECT_EQ(GURL("http://dhcppac/"), @@ -779,7 +786,7 @@ TEST(PacFileDeciderTest, AutodetectDhcpFailParse) { config, TRAFFIC_ANNOTATION_FOR_TESTS), base::TimeDelta(), true, callback.callback()), IsError(kFailedDownloading)); - EXPECT_FALSE(decider.script_data()); + EXPECT_FALSE(decider.script_data().data); EXPECT_FALSE(decider.effective_config().value().has_pac_url()); } diff --git a/chromium/net/proxy_resolution/proxy_info.cc b/chromium/net/proxy_resolution/proxy_info.cc index cb0bf4eb0f6..762756d9a4e 100644 --- a/chromium/net/proxy_resolution/proxy_info.cc +++ b/chromium/net/proxy_resolution/proxy_info.cc @@ -8,7 +8,10 @@ namespace net { -ProxyInfo::ProxyInfo() : did_bypass_proxy_(false), did_use_pac_script_(false) {} +ProxyInfo::ProxyInfo() + : did_bypass_proxy_(false), + did_use_pac_script_(false), + did_use_auto_detected_pac_script_(false) {} ProxyInfo::ProxyInfo(const ProxyInfo& other) = default; @@ -22,6 +25,7 @@ void ProxyInfo::Use(const ProxyInfo& other) { traffic_annotation_ = other.traffic_annotation_; did_bypass_proxy_ = other.did_bypass_proxy_; did_use_pac_script_ = other.did_use_pac_script_; + did_use_auto_detected_pac_script_ = other.did_use_auto_detected_pac_script_; } void ProxyInfo::UseDirect() { @@ -88,6 +92,7 @@ void ProxyInfo::Reset() { traffic_annotation_.reset(); did_bypass_proxy_ = false; did_use_pac_script_ = false; + did_use_auto_detected_pac_script_ = false; } } // namespace net diff --git a/chromium/net/proxy_resolution/proxy_info.h b/chromium/net/proxy_resolution/proxy_info.h index e3ea8da6a07..daa5862ebda 100644 --- a/chromium/net/proxy_resolution/proxy_info.h +++ b/chromium/net/proxy_resolution/proxy_info.h @@ -127,6 +127,12 @@ class NET_EXPORT ProxyInfo { return did_use_pac_script_; } + // Returns true if the proxy list was obtained from a PAC script that + // was auto-detected. + bool did_use_auto_detected_pac_script() const { + return did_use_auto_detected_pac_script_; + } + // Returns the first valid proxy server. is_empty() must be false to be able // to call this function. const ProxyServer& proxy_server() const { return proxy_list_.Get(); } @@ -203,6 +209,7 @@ class NET_EXPORT ProxyInfo { // Whether we used a PAC script for resolving the proxy. bool did_use_pac_script_; + bool did_use_auto_detected_pac_script_; // How long it took to resolve the proxy. Times are both null if proxy was // determined synchronously without running a PAC. diff --git a/chromium/net/proxy_resolution/proxy_resolution_service.cc b/chromium/net/proxy_resolution/proxy_resolution_service.cc index cf2a9621221..155119ff73c 100644 --- a/chromium/net/proxy_resolution/proxy_resolution_service.cc +++ b/chromium/net/proxy_resolution/proxy_resolution_service.cc @@ -432,6 +432,7 @@ class ProxyResolutionService::InitProxyResolver { InitProxyResolver() : proxy_resolver_factory_(nullptr), proxy_resolver_(NULL), + resolver_using_auto_detected_script_(nullptr), next_state_(STATE_NONE), quick_check_enabled_(true) {} @@ -442,8 +443,12 @@ class ProxyResolutionService::InitProxyResolver { // Begins initializing the proxy resolver; calls |callback| when done. A // ProxyResolver instance will be created using |proxy_resolver_factory| and - // returned via |proxy_resolver| if the final result is OK. + // assigned to |*proxy_resolver| if the final result is OK. + // |*resolver_using_auto_detected_script| will be set to true if + // |proxy_resolver| was initialized using script data that originates from + // proxy auto-detection. int Start(std::unique_ptr<ProxyResolver>* proxy_resolver, + bool* resolver_using_auto_detected_script, ProxyResolverFactory* proxy_resolver_factory, PacFileFetcher* pac_file_fetcher, DhcpPacFileFetcher* dhcp_pac_file_fetcher, @@ -453,6 +458,7 @@ class ProxyResolutionService::InitProxyResolver { CompletionOnceCallback callback) { DCHECK_EQ(STATE_NONE, next_state_); proxy_resolver_ = proxy_resolver; + resolver_using_auto_detected_script_ = resolver_using_auto_detected_script; proxy_resolver_factory_ = proxy_resolver_factory; decider_.reset( @@ -469,16 +475,21 @@ class ProxyResolutionService::InitProxyResolver { // Similar to Start(), however it skips the PacFileDecider stage. Instead // |effective_config|, |decider_result| and |script_data| will be used as the // inputs for initializing the ProxyResolver. A ProxyResolver instance will - // be created using |proxy_resolver_factory| and returned via - // |proxy_resolver| if the final result is OK. + // be created using |proxy_resolver_factory| and assigned to + // |*proxy_resolver| if the final result is OK. + // |*resolver_using_auto_detected_script| will be set to true if + // |proxy_resolver| was initialized using script data that originates from + // proxy auto-detection. int StartSkipDecider(std::unique_ptr<ProxyResolver>* proxy_resolver, + bool* resolver_using_auto_detected_script, ProxyResolverFactory* proxy_resolver_factory, const ProxyConfigWithAnnotation& effective_config, int decider_result, - PacFileData* script_data, + const PacFileDataWithSource& script_data, CompletionOnceCallback callback) { DCHECK_EQ(STATE_NONE, next_state_); proxy_resolver_ = proxy_resolver; + resolver_using_auto_detected_script_ = resolver_using_auto_detected_script; proxy_resolver_factory_ = proxy_resolver_factory; effective_config_ = effective_config; @@ -501,7 +512,7 @@ class ProxyResolutionService::InitProxyResolver { // Returns the PAC script data that was selected by PacFileDecider. // Should only be called upon completion of the initialization. - const scoped_refptr<PacFileData>& script_data() { + const PacFileDataWithSource& script_data() { DCHECK_EQ(STATE_NONE, next_state_); return script_data_; } @@ -583,18 +594,21 @@ class ProxyResolutionService::InitProxyResolver { } int DoCreateResolver() { - DCHECK(script_data_.get()); + DCHECK(script_data_.data); // TODO(eroman): Should log this latency to the NetLog. next_state_ = STATE_CREATE_RESOLVER_COMPLETE; return proxy_resolver_factory_->CreateProxyResolver( - script_data_, proxy_resolver_, + script_data_.data, proxy_resolver_, base::Bind(&InitProxyResolver::OnIOCompletion, base::Unretained(this)), &create_resolver_request_); } int DoCreateResolverComplete(int result) { - if (result != OK) + if (result == OK) { + *resolver_using_auto_detected_script_ = script_data_.from_auto_detect; + } else { proxy_resolver_->reset(); + } return result; } @@ -607,12 +621,13 @@ class ProxyResolutionService::InitProxyResolver { ProxyConfigWithAnnotation config_; ProxyConfigWithAnnotation effective_config_; - scoped_refptr<PacFileData> script_data_; + PacFileDataWithSource script_data_; TimeDelta wait_delay_; std::unique_ptr<PacFileDecider> decider_; ProxyResolverFactory* proxy_resolver_factory_; std::unique_ptr<ProxyResolverFactory::Request> create_resolver_request_; std::unique_ptr<ProxyResolver>* proxy_resolver_; + bool* resolver_using_auto_detected_script_; CompletionOnceCallback callback_; State next_state_; bool quick_check_enabled_; @@ -629,7 +644,7 @@ class ProxyResolutionService::InitProxyResolver { class ProxyResolutionService::PacFileDeciderPoller { public: typedef base::Callback< - void(int, PacFileData*, const ProxyConfigWithAnnotation&)> + void(int, const PacFileDataWithSource&, const ProxyConfigWithAnnotation&)> ChangeCallback; // Builds a poller helper, and starts polling for updates. Whenever a change @@ -658,7 +673,7 @@ class ProxyResolutionService::PacFileDeciderPoller { PacFileFetcher* pac_file_fetcher, DhcpPacFileFetcher* dhcp_pac_file_fetcher, int init_net_error, - const scoped_refptr<PacFileData>& init_script_data, + const PacFileDataWithSource& init_script_data, NetLog* net_log) : change_callback_(callback), config_(config), @@ -768,7 +783,7 @@ class ProxyResolutionService::PacFileDeciderPoller { } bool HasScriptDataChanged(int result, - const scoped_refptr<PacFileData>& script_data) { + const PacFileDataWithSource& script_data) { if (result != last_error_) { // Something changed -- it was failing before and now it succeeded, or // conversely it succeeded before and now it failed. Or it failed in @@ -785,16 +800,17 @@ class ProxyResolutionService::PacFileDeciderPoller { // Otherwise if it succeeded both this time and last time, we need to look // closer and see if we ended up downloading different content for the PAC // script. - return !script_data->Equals(last_script_data_.get()); + return !script_data.data->Equals(last_script_data_.data.get()) || + (script_data.from_auto_detect != last_script_data_.from_auto_detect); } void NotifyProxyResolutionServiceOfChange( int result, - const scoped_refptr<PacFileData>& script_data, + const PacFileDataWithSource& script_data, const ProxyConfigWithAnnotation& effective_config) { // Note that |this| may be deleted after calling into the // ProxyResolutionService. - change_callback_.Run(result, script_data.get(), effective_config); + change_callback_.Run(result, script_data, effective_config); } ChangeCallback change_callback_; @@ -804,7 +820,7 @@ class ProxyResolutionService::PacFileDeciderPoller { DhcpPacFileFetcher* dhcp_pac_file_fetcher_; int last_error_; - scoped_refptr<PacFileData> last_script_data_; + PacFileDataWithSource last_script_data_; std::unique_ptr<PacFileDecider> decider_; TimeDelta next_poll_delay_; @@ -879,6 +895,7 @@ class ProxyResolutionService::RequestImpl // Outstanding requests are cancelled during ~ProxyResolutionService, so this // is guaranteed to be valid throughout our lifetime. ProxyResolutionService* service_; + bool resolver_using_auto_detected_script_; CompletionOnceCallback user_callback_; ProxyInfo* results_; GURL url_; @@ -937,6 +954,8 @@ int ProxyResolutionService::RequestImpl::Start() { if (service_->ApplyPacBypassRules(url_, results_)) return OK; + resolver_using_auto_detected_script_ = + service_->resolver_using_auto_detected_script_; return resolver()->GetProxyForURL( url_, results_, base::Bind(&ProxyResolutionService::RequestImpl::QueryComplete, @@ -974,6 +993,8 @@ int ProxyResolutionService::RequestImpl::QueryDidComplete(int result_code) { // Make a note in the results which configuration was in use at the // time of the resolve. results_->did_use_pac_script_ = true; + results_->did_use_auto_detected_pac_script_ = + resolver_using_auto_detected_script_; results_->proxy_resolve_start_time_ = creation_time_; results_->proxy_resolve_end_time_ = TimeTicks::Now(); @@ -1105,6 +1126,22 @@ ProxyResolutionService::CreateFixedFromPacResult( // ProxyResolver dependency we give it will never be used. std::unique_ptr<ProxyConfigService> proxy_config_service( new ProxyConfigServiceFixed(ProxyConfigWithAnnotation( + ProxyConfig::CreateFromCustomPacURL( + GURL("https://my-pac-script.invalid/wpad.dat")), + traffic_annotation))); + + return std::make_unique<ProxyResolutionService>( + std::move(proxy_config_service), + std::make_unique<ProxyResolverFactoryForPacResult>(pac_string), nullptr); +} + +// static +std::unique_ptr<ProxyResolutionService> +ProxyResolutionService::CreateFixedFromAutoDetectedPacResult( + const std::string& pac_string, + const NetworkTrafficAnnotationTag& traffic_annotation) { + std::unique_ptr<ProxyConfigService> proxy_config_service( + new ProxyConfigServiceFixed(ProxyConfigWithAnnotation( ProxyConfig::CreateAutoDetect(), traffic_annotation))); return std::make_unique<ProxyResolutionService>( @@ -1655,7 +1692,8 @@ void ProxyResolutionService::InitializeUsingLastFetchedConfig() { init_proxy_resolver_.reset(new InitProxyResolver()); init_proxy_resolver_->set_quick_check_enabled(quick_check_enabled_); int rv = init_proxy_resolver_->Start( - &resolver_, resolver_factory_.get(), pac_file_fetcher_.get(), + &resolver_, &resolver_using_auto_detected_script_, + resolver_factory_.get(), pac_file_fetcher_.get(), dhcp_pac_file_fetcher_.get(), net_log_, fetched_config_.value(), wait_delay, base::Bind(&ProxyResolutionService::OnInitProxyResolverComplete, @@ -1667,7 +1705,7 @@ void ProxyResolutionService::InitializeUsingLastFetchedConfig() { void ProxyResolutionService::InitializeUsingDecidedConfig( int decider_result, - PacFileData* script_data, + const PacFileDataWithSource& script_data, const ProxyConfigWithAnnotation& effective_config) { DCHECK(fetched_config_); DCHECK(fetched_config_->value().HasAutomaticSettings()); @@ -1678,8 +1716,8 @@ void ProxyResolutionService::InitializeUsingDecidedConfig( init_proxy_resolver_.reset(new InitProxyResolver()); int rv = init_proxy_resolver_->StartSkipDecider( - &resolver_, resolver_factory_.get(), effective_config, decider_result, - script_data, + &resolver_, &resolver_using_auto_detected_script_, + resolver_factory_.get(), effective_config, decider_result, script_data, base::Bind(&ProxyResolutionService::OnInitProxyResolverComplete, base::Unretained(this))); diff --git a/chromium/net/proxy_resolution/proxy_resolution_service.h b/chromium/net/proxy_resolution/proxy_resolution_service.h index 6d7f7ed301a..3ead15516ce 100644 --- a/chromium/net/proxy_resolution/proxy_resolution_service.h +++ b/chromium/net/proxy_resolution/proxy_resolution_service.h @@ -41,10 +41,10 @@ namespace net { class DhcpPacFileFetcher; class NetLog; +class PacFileFetcher; class ProxyDelegate; class ProxyResolverFactory; -class PacFileData; -class PacFileFetcher; +struct PacFileDataWithSource; // This class can be used to resolve the proxy server to use when loading a // HTTP(S) URL. It uses the given ProxyResolver to handle the actual proxy @@ -270,6 +270,13 @@ class NET_EXPORT ProxyResolutionService const std::string& pac_string, const NetworkTrafficAnnotationTag& traffic_annotation); + // Same as CreateFixedFromPacResult(), except the resulting ProxyInfo from + // resolutions will be tagged as having been auto-detected. + static std::unique_ptr<ProxyResolutionService> + CreateFixedFromAutoDetectedPacResult( + const std::string& pac_string, + const NetworkTrafficAnnotationTag& traffic_annotation); + // Creates a config service appropriate for this platform that fetches the // system proxy settings. |main_task_runner| is the thread where the consumer // of the ProxyConfigService will live. @@ -374,7 +381,7 @@ class NET_EXPORT ProxyResolutionService // Start the initialization skipping past the "decision" phase. void InitializeUsingDecidedConfig( int decider_result, - PacFileData* script_data, + const PacFileDataWithSource& script_data, const ProxyConfigWithAnnotation& effective_config); // NetworkChangeNotifier::IPAddressObserver @@ -398,7 +405,12 @@ class NET_EXPORT ProxyResolutionService std::unique_ptr<ProxyConfigService> config_service_; std::unique_ptr<ProxyResolverFactory> resolver_factory_; + + // If non-null, the initialized ProxyResolver to use for requests, and a + // boolean indicating whether it was initialized using an auto-detected + // script. std::unique_ptr<ProxyResolver> resolver_; + bool resolver_using_auto_detected_script_; // We store the proxy configuration that was last fetched from the // ProxyConfigService, as well as the resulting "effective" configuration. diff --git a/chromium/net/quic/quic_proxy_client_socket.cc b/chromium/net/quic/quic_proxy_client_socket.cc index f870a8b72c4..2d04bdf4411 100644 --- a/chromium/net/quic/quic_proxy_client_socket.cc +++ b/chromium/net/quic/quic_proxy_client_socket.cc @@ -415,7 +415,7 @@ int QuicProxyClientSocket::DoReadReplyComplete(int result) { redirect_has_load_timing_info_ = GetLoadTimingInfo(&redirect_load_timing_info_); next_state_ = STATE_DISCONNECTED; - return ERR_HTTPS_PROXY_TUNNEL_RESPONSE; + return ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT; case 407: // Proxy Authentication Required next_state_ = STATE_CONNECT_COMPLETE; diff --git a/chromium/net/quic/quic_proxy_client_socket_unittest.cc b/chromium/net/quic/quic_proxy_client_socket_unittest.cc index 0c4411f1b8d..a385cc1df87 100644 --- a/chromium/net/quic/quic_proxy_client_socket_unittest.cc +++ b/chromium/net/quic/quic_proxy_client_socket_unittest.cc @@ -656,7 +656,7 @@ TEST_P(QuicProxyClientSocketTest, ConnectRedirects) { Initialize(); - AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); + AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT); const HttpResponseInfo* response = sock_->GetConnectResponseInfo(); ASSERT_TRUE(response != nullptr); diff --git a/chromium/net/socket/ssl_client_socket_pool.cc b/chromium/net/socket/ssl_client_socket_pool.cc index 190b096dcf9..6b78c0de20c 100644 --- a/chromium/net/socket/ssl_client_socket_pool.cc +++ b/chromium/net/socket/ssl_client_socket_pool.cc @@ -310,7 +310,7 @@ int SSLConnectJob::DoTunnelConnectComplete(int result) { if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { error_response_info_ = transport_socket_handle_->ssl_error_response_info(); } else if (result == ERR_PROXY_AUTH_REQUESTED || - result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { + result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT) { StreamSocket* socket = transport_socket_handle_->socket(); ProxyClientSocket* tunnel_socket = static_cast<ProxyClientSocket*>(socket); error_response_info_ = *tunnel_socket->GetConnectResponseInfo(); diff --git a/chromium/net/spdy/fuzzing/hpack_decoder_fuzzer.cc b/chromium/net/spdy/fuzzing/hpack_decoder_fuzzer.cc deleted file mode 100644 index 16df5e09e8a..00000000000 --- a/chromium/net/spdy/fuzzing/hpack_decoder_fuzzer.cc +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> -#include <stdint.h> - -#include <list> -#include <vector> - -#include "base/test/fuzzed_data_provider.h" -#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_decoder.h" - -// Entry point for LibFuzzer. -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - // At least 4 bytes of fuzz data are needed to generate a max string size. - if (size < 4) - return 0; - - base::FuzzedDataProvider fuzzed_data_provider(data, size); - size_t max_string_size = - fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 10 * size); - http2::HpackDecoder decoder(http2::HpackDecoderNoOpListener::NoOpListener(), - max_string_size); - decoder.StartDecodingBlock(); - - // Store all chunks in a function scope list, as the API requires the caller - // to make sure the fragment chunks data is accessible during the whole - // decoding process. |http2::DecodeBuffer| does not copy the data, it is just - // a wrapper for the chunk provided in its constructor. - std::list<std::vector<char>> all_chunks; - while (fuzzed_data_provider.remaining_bytes() > 0) { - size_t chunk_size = fuzzed_data_provider.ConsumeIntegralInRange(1, 32); - all_chunks.emplace_back( - fuzzed_data_provider.ConsumeBytes<char>(chunk_size)); - const auto& chunk = all_chunks.back(); - - // http2::DecodeBuffer constructor does not accept nullptr buffer. - if (chunk.data() == nullptr) - continue; - - http2::DecodeBuffer fragment(chunk.data(), chunk.size()); - decoder.DecodeFragment(&fragment); - } - decoder.EndDecodingBlock(); - return 0; -} diff --git a/chromium/net/spdy/fuzzing/hpack_example_generator.cc b/chromium/net/spdy/fuzzing/hpack_example_generator.cc deleted file mode 100644 index c38b28870f3..00000000000 --- a/chromium/net/spdy/fuzzing/hpack_example_generator.cc +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/at_exit.h" -#include "base/command_line.h" -#include "base/files/file.h" -#include "base/files/file_util.h" -#include "base/strings/string_number_conversions.h" -#include "net/spdy/fuzzing/hpack_fuzz_util.h" -#include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" -#include "net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h" -#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" -#include "net/third_party/quiche/src/spdy/platform/api/spdy_string.h" - -namespace { - -// Target file for generated HPACK header sets. -const char kFileToWrite[] = "file-to-write"; - -// Number of header sets to generate. -const char kExampleCount[] = "example-count"; - -} // namespace - -using spdy::HpackFuzzUtil; -using spdy::SpdyString; -using std::map; - -// Generates a configurable number of header sets (using HpackFuzzUtil), and -// sequentially encodes each header set with an HpackEncoder. Encoded header -// sets are written to the output file in length-prefixed blocks. -int main(int argc, char** argv) { - base::AtExitManager exit_manager; - - base::CommandLine::Init(argc, argv); - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - - if (!command_line.HasSwitch(kFileToWrite) || - !command_line.HasSwitch(kExampleCount)) { - LOG(ERROR) << "Usage: " << argv[0] << " --" << kFileToWrite - << "=/path/to/file.out" - << " --" << kExampleCount << "=1000"; - return -1; - } - spdy::SpdyString file_to_write = - command_line.GetSwitchValueASCII(kFileToWrite); - - int example_count = 0; - base::StringToInt(command_line.GetSwitchValueASCII(kExampleCount), - &example_count); - - DVLOG(1) << "Writing output to " << file_to_write; - base::File file_out(base::FilePath::FromUTF8Unsafe(file_to_write), - base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); - CHECK(file_out.IsValid()) << file_out.error_details(); - - HpackFuzzUtil::GeneratorContext context; - HpackFuzzUtil::InitializeGeneratorContext(&context); - spdy::HpackEncoder encoder(spdy::ObtainHpackHuffmanTable()); - - for (int i = 0; i != example_count; ++i) { - spdy::SpdyHeaderBlock headers = - HpackFuzzUtil::NextGeneratedHeaderSet(&context); - - spdy::SpdyString buffer; - CHECK(encoder.EncodeHeaderSet(headers, &buffer)); - - spdy::SpdyString prefix = HpackFuzzUtil::HeaderBlockPrefix(buffer.size()); - - CHECK_LT(0, file_out.WriteAtCurrentPos(prefix.data(), prefix.size())); - CHECK_LT(0, file_out.WriteAtCurrentPos(buffer.data(), buffer.size())); - } - CHECK(file_out.Flush()); - DVLOG(1) << "Generated " << example_count << " blocks."; - return 0; -} diff --git a/chromium/net/spdy/fuzzing/hpack_fuzz_util.cc b/chromium/net/spdy/fuzzing/hpack_fuzz_util.cc deleted file mode 100644 index 400ed0dde09..00000000000 --- a/chromium/net/spdy/fuzzing/hpack_fuzz_util.cc +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/spdy/fuzzing/hpack_fuzz_util.h" - -#include <algorithm> -#include <cmath> - -#include "base/rand_util.h" -#include "base/sys_byteorder.h" -#include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h" -#include "net/third_party/quiche/src/spdy/platform/api/spdy_ptr_util.h" - -namespace spdy { - -namespace { - -// Sampled exponential distribution parameters: -// Number of headers in each header set. -const size_t kHeaderCountMean = 7; -const size_t kHeaderCountMax = 50; -// Selected index within list of headers. -const size_t kHeaderIndexMean = 20; -const size_t kHeaderIndexMax = 200; -// Approximate distribution of header name lengths. -const size_t kNameLengthMean = 5; -const size_t kNameLengthMax = 30; -// Approximate distribution of header value lengths. -const size_t kValueLengthMean = 15; -const size_t kValueLengthMax = 75; - -} // namespace - -using base::RandBytesAsString; -using std::map; - -HpackFuzzUtil::GeneratorContext::GeneratorContext() = default; -HpackFuzzUtil::GeneratorContext::~GeneratorContext() = default; - -HpackFuzzUtil::Input::Input() : offset(0) {} -HpackFuzzUtil::Input::~Input() = default; - -HpackFuzzUtil::FuzzerContext::FuzzerContext() = default; -HpackFuzzUtil::FuzzerContext::~FuzzerContext() = default; - -// static -void HpackFuzzUtil::InitializeGeneratorContext(GeneratorContext* context) { - // Seed the generator with common header fixtures. - context->names.push_back(":authority"); - context->names.push_back(":path"); - context->names.push_back(":status"); - context->names.push_back("cookie"); - context->names.push_back("content-type"); - context->names.push_back("cache-control"); - context->names.push_back("date"); - context->names.push_back("user-agent"); - context->names.push_back("via"); - - context->values.push_back("/"); - context->values.push_back("/index.html"); - context->values.push_back("200"); - context->values.push_back("404"); - context->values.push_back(""); - context->values.push_back("baz=bing; foo=bar; garbage"); - context->values.push_back("baz=bing; fizzle=fazzle; garbage"); - context->values.push_back("rudolph=the-red-nosed-reindeer"); - context->values.push_back("had=a;very_shiny=nose"); - context->values.push_back("and\0if\0you\0ever\1saw\0it;"); - context->values.push_back("u; would=even;say-it\xffglows"); -} - -// static -SpdyHeaderBlock HpackFuzzUtil::NextGeneratedHeaderSet( - GeneratorContext* context) { - SpdyHeaderBlock headers; - - size_t header_count = - 1 + SampleExponential(kHeaderCountMean, kHeaderCountMax); - for (size_t j = 0; j != header_count; ++j) { - size_t name_index = SampleExponential(kHeaderIndexMean, kHeaderIndexMax); - size_t value_index = SampleExponential(kHeaderIndexMean, kHeaderIndexMax); - SpdyString name, value; - if (name_index >= context->names.size()) { - context->names.push_back(RandBytesAsString( - 1 + SampleExponential(kNameLengthMean, kNameLengthMax))); - name = context->names.back(); - } else { - name = context->names[name_index]; - } - if (value_index >= context->values.size()) { - context->values.push_back(RandBytesAsString( - 1 + SampleExponential(kValueLengthMean, kValueLengthMax))); - value = context->values.back(); - } else { - value = context->values[value_index]; - } - headers[name] = value; - } - return headers; -} - -// static -size_t HpackFuzzUtil::SampleExponential(size_t mean, size_t sanity_bound) { - return std::min(static_cast<size_t>(-std::log(base::RandDouble()) * mean), - sanity_bound); -} - -// static -bool HpackFuzzUtil::NextHeaderBlock(Input* input, SpdyStringPiece* out) { - // ClusterFuzz may truncate input files if the fuzzer ran out of allocated - // disk space. Be tolerant of these. - CHECK_LE(input->offset, input->input.size()); - if (input->remaining() < sizeof(uint32_t)) { - return false; - } - - size_t length = - base::NetToHost32(*reinterpret_cast<const uint32_t*>(input->ptr())); - input->offset += sizeof(uint32_t); - - if (input->remaining() < length) { - return false; - } - *out = SpdyStringPiece(input->ptr(), length); - input->offset += length; - return true; -} - -// static -SpdyString HpackFuzzUtil::HeaderBlockPrefix(size_t block_size) { - uint32_t length = base::HostToNet32(static_cast<uint32_t>(block_size)); - return SpdyString(reinterpret_cast<char*>(&length), sizeof(uint32_t)); -} - -// static -void HpackFuzzUtil::InitializeFuzzerContext(FuzzerContext* context) { - context->first_stage = SpdyMakeUnique<HpackDecoderAdapter>(); - context->second_stage = - SpdyMakeUnique<HpackEncoder>(ObtainHpackHuffmanTable()); - context->third_stage = SpdyMakeUnique<HpackDecoderAdapter>(); -} - -// static -bool HpackFuzzUtil::RunHeaderBlockThroughFuzzerStages( - FuzzerContext* context, - SpdyStringPiece input_block) { - // First stage: Decode the input header block. This may fail on invalid input. - if (!context->first_stage->HandleControlFrameHeadersData( - input_block.data(), input_block.size())) { - return false; - } - if (!context->first_stage->HandleControlFrameHeadersComplete(nullptr)) { - return false; - } - // Second stage: Re-encode the decoded header block. This must succeed. - SpdyString second_stage_out; - CHECK(context->second_stage->EncodeHeaderSet( - context->first_stage->decoded_block(), &second_stage_out)); - - // Third stage: Expect a decoding of the re-encoded block to succeed, but - // don't require it. It's possible for the stage-two encoder to produce an - // output which violates decoder size tolerances. - if (!context->third_stage->HandleControlFrameHeadersData( - second_stage_out.data(), second_stage_out.length())) { - return false; - } - if (!context->third_stage->HandleControlFrameHeadersComplete(nullptr)) { - return false; - } - return true; -} - -// static -void HpackFuzzUtil::FlipBits(uint8_t* buffer, - size_t buffer_length, - size_t flip_per_thousand) { - uint64_t buffer_bit_length = buffer_length * 8u; - uint64_t bits_to_flip = flip_per_thousand * (1 + buffer_bit_length / 1024); - - // Iteratively identify & flip offsets in the buffer bit-sequence. - for (uint64_t i = 0; i != bits_to_flip; ++i) { - uint64_t bit_offset = base::RandUint64() % buffer_bit_length; - buffer[bit_offset / 8u] ^= (1 << (bit_offset % 8u)); - } -} - -} // namespace spdy diff --git a/chromium/net/spdy/fuzzing/hpack_fuzz_util.h b/chromium/net/spdy/fuzzing/hpack_fuzz_util.h deleted file mode 100644 index 5d95ca22d29..00000000000 --- a/chromium/net/spdy/fuzzing/hpack_fuzz_util.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_ -#define NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <memory> -#include <vector> - -#include "net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter.h" -#include "net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h" -#include "net/third_party/quiche/src/spdy/platform/api/spdy_export.h" -#include "net/third_party/quiche/src/spdy/platform/api/spdy_string.h" -#include "net/third_party/quiche/src/spdy/platform/api/spdy_string_piece.h" - -namespace spdy { - -class HpackFuzzUtil { - public: - // A GeneratorContext holds ordered header names & values which are - // initially seeded and then expanded with dynamically generated data. - struct GeneratorContext { - GeneratorContext(); - ~GeneratorContext(); - std::vector<SpdyString> names; - std::vector<SpdyString> values; - }; - - // Initializes a GeneratorContext with a random seed and name/value fixtures. - static void InitializeGeneratorContext(GeneratorContext* context); - - // Generates a header set from the generator context. - static SpdyHeaderBlock NextGeneratedHeaderSet(GeneratorContext* context); - - // Samples a size from the exponential distribution with mean |mean|, - // upper-bounded by |sanity_bound|. - static size_t SampleExponential(size_t mean, size_t sanity_bound); - - // Holds an input SpdyString, and manages an offset into that SpdyString. - struct Input { - Input(); // Initializes |offset| to zero. - ~Input(); - - size_t remaining() { return input.size() - offset; } - const char* ptr() { return input.data() + offset; } - - SpdyString input; - size_t offset; - }; - - // Returns true if the next header block was set at |out|. Returns - // false if no input header blocks remain. - static bool NextHeaderBlock(Input* input, SpdyStringPiece* out); - - // Returns the serialized header block length prefix for a block of - // |block_size| bytes. - static SpdyString HeaderBlockPrefix(size_t block_size); - - // A FuzzerContext holds fuzzer input, as well as each of the decoder and - // encoder stages which fuzzed header blocks are processed through. - struct FuzzerContext { - FuzzerContext(); - ~FuzzerContext(); - std::unique_ptr<HpackDecoderAdapter> first_stage; - std::unique_ptr<HpackEncoder> second_stage; - std::unique_ptr<HpackDecoderAdapter> third_stage; - }; - - static void InitializeFuzzerContext(FuzzerContext* context); - - // Runs |input_block| through |first_stage| and, iff that succeeds, - // |second_stage| and |third_stage| as well. Returns whether all stages - // processed the input without error. - static bool RunHeaderBlockThroughFuzzerStages(FuzzerContext* context, - SpdyStringPiece input_block); - - // Flips random bits within |buffer|. The total number of flips is - // |flip_per_thousand| bits for every 1,024 bytes of |buffer_length|, - // rounding up. - static void FlipBits(uint8_t* buffer, - size_t buffer_length, - size_t flip_per_thousand); -}; - -} // namespace spdy - -#endif // NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_ diff --git a/chromium/net/spdy/fuzzing/hpack_fuzz_util_test.cc b/chromium/net/spdy/fuzzing/hpack_fuzz_util_test.cc deleted file mode 100644 index 8294fd4eb1f..00000000000 --- a/chromium/net/spdy/fuzzing/hpack_fuzz_util_test.cc +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/spdy/fuzzing/hpack_fuzz_util.h" - -#include <map> - -#include "base/base_paths.h" -#include "base/files/file.h" -#include "base/files/file_util.h" -#include "base/path_service.h" -#include "base/stl_util.h" -#include "net/third_party/quiche/src/spdy/platform/api/spdy_string_utils.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace spdy { -namespace test { - -using std::map; - -TEST(HpackFuzzUtilTest, GeneratorContextInitialization) { - HpackFuzzUtil::GeneratorContext context; - HpackFuzzUtil::InitializeGeneratorContext(&context); - - // Context was seeded with initial name & value fixtures. - EXPECT_LT(0u, context.names.size()); - EXPECT_LT(0u, context.values.size()); -} - -TEST(HpackFuzzUtil, GeneratorContextExpansion) { - HpackFuzzUtil::GeneratorContext context; - - SpdyHeaderBlock headers = HpackFuzzUtil::NextGeneratedHeaderSet(&context); - - // Headers were generated, and the generator context was expanded. - EXPECT_LT(0u, headers.size()); - EXPECT_LT(0u, context.names.size()); - EXPECT_LT(0u, context.values.size()); -} - -// TODO(jgraettinger): A better test would mock a random generator and -// evaluate SampleExponential along fixed points of the [0,1] domain. -TEST(HpackFuzzUtilTest, SampleExponentialRegression) { - // TODO(jgraettinger): Upstream uses a seeded random generator here to pin - // the behavior of SampleExponential. Chromium's random generation utilities - // are strongly secure, but provide no way to seed the generator. - for (size_t i = 0; i != 100; ++i) { - EXPECT_GE(30u, HpackFuzzUtil::SampleExponential(10, 30)); - } -} - -TEST(HpackFuzzUtilTest, ParsesSequenceOfHeaderBlocks) { - char fixture[] = - "\x00\x00\x00\x05" - "aaaaa" - "\x00\x00\x00\x04" - "bbbb" - "\x00\x00\x00\x03" - "ccc" - "\x00\x00\x00\x02" - "dd" - "\x00\x00\x00\x01" - "e" - "\x00\x00\x00\x00" - "" - "\x00\x00\x00\x03" - "fin"; - - HpackFuzzUtil::Input input; - input.input.assign(fixture, base::size(fixture) - 1); - - SpdyStringPiece block; - - EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); - EXPECT_EQ("aaaaa", block); - EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); - EXPECT_EQ("bbbb", block); - EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); - EXPECT_EQ("ccc", block); - EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); - EXPECT_EQ("dd", block); - EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); - EXPECT_EQ("e", block); - EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); - EXPECT_EQ("", block); - EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); - EXPECT_EQ("fin", block); - EXPECT_FALSE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); -} - -TEST(HpackFuzzUtilTest, SerializedHeaderBlockPrefixes) { - EXPECT_EQ(SpdyString("\x00\x00\x00\x00", 4), - HpackFuzzUtil::HeaderBlockPrefix(0)); - EXPECT_EQ(SpdyString("\x00\x00\x00\x05", 4), - HpackFuzzUtil::HeaderBlockPrefix(5)); - EXPECT_EQ("\x4f\xb3\x0a\x91", HpackFuzzUtil::HeaderBlockPrefix(1337133713)); -} - -TEST(HpackFuzzUtilTest, PassValidInputThroughAllStages) { - // Example lifted from HpackDecoderTest.SectionD4RequestHuffmanExamples. - SpdyString input = SpdyHexDecode("828684418cf1e3c2e5f23a6ba0ab90f4ff"); - - HpackFuzzUtil::FuzzerContext context; - HpackFuzzUtil::InitializeFuzzerContext(&context); - - EXPECT_TRUE( - HpackFuzzUtil::RunHeaderBlockThroughFuzzerStages(&context, input)); - - SpdyHeaderBlock expect; - expect[":method"] = "GET"; - expect[":scheme"] = "http"; - expect[":path"] = "/"; - expect[":authority"] = "www.example.com"; - EXPECT_EQ(expect, context.third_stage->decoded_block()); -} - -TEST(HpackFuzzUtilTest, ValidFuzzExamplesRegressionTest) { - base::FilePath source_root; - ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root)); - - // Load the example fixtures versioned with the source tree. - HpackFuzzUtil::Input input; - ASSERT_TRUE(base::ReadFileToString( - source_root.Append(FILE_PATH_LITERAL("net")) - .Append(FILE_PATH_LITERAL("data")) - .Append(FILE_PATH_LITERAL("spdy_tests")) - .Append(FILE_PATH_LITERAL("examples_07.hpack")), - &input.input)); - - HpackFuzzUtil::FuzzerContext context; - HpackFuzzUtil::InitializeFuzzerContext(&context); - - SpdyStringPiece block; - while (HpackFuzzUtil::NextHeaderBlock(&input, &block)) { - // As these are valid examples, all fuzz stages should succeed. - EXPECT_TRUE( - HpackFuzzUtil::RunHeaderBlockThroughFuzzerStages(&context, block)); - } -} - -TEST(HpackFuzzUtilTest, FlipBitsMutatesBuffer) { - char buffer[] = "testbuffer1234567890"; - SpdyString unmodified(buffer, base::size(buffer) - 1); - - EXPECT_EQ(unmodified, buffer); - HpackFuzzUtil::FlipBits(reinterpret_cast<uint8_t*>(buffer), - base::size(buffer) - 1, 1); - EXPECT_NE(unmodified, buffer); -} - -} // namespace test -} // namespace spdy diff --git a/chromium/net/spdy/fuzzing/http2_frame_decoder_fuzzer.cc b/chromium/net/spdy/fuzzing/http2_frame_decoder_fuzzer.cc deleted file mode 100644 index f89de197d6e..00000000000 --- a/chromium/net/spdy/fuzzing/http2_frame_decoder_fuzzer.cc +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> -#include <stdint.h> - -#include <list> -#include <vector> - -#include "base/test/fuzzed_data_provider.h" -#include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder.h" - -// Entry point for LibFuzzer. -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - base::FuzzedDataProvider fuzzed_data_provider(data, size); - http2::Http2FrameDecoder decoder; - - // Store all chunks in a function scope list, as the API requires the caller - // to make sure the fragment chunks data is accessible during the whole - // decoding process. |http2::DecodeBuffer| does not copy the data, it is just - // a wrapper for the chunk provided in its constructor. - std::list<std::vector<char>> all_chunks; - while (fuzzed_data_provider.remaining_bytes() > 0) { - size_t chunk_size = fuzzed_data_provider.ConsumeIntegralInRange(1, 32); - all_chunks.emplace_back( - fuzzed_data_provider.ConsumeBytes<char>(chunk_size)); - const auto& chunk = all_chunks.back(); - - // http2::DecodeBuffer constructor does not accept nullptr buffer. - if (chunk.data() == nullptr) - continue; - - http2::DecodeBuffer frame_data(chunk.data(), chunk.size()); - decoder.DecodeFrame(&frame_data); - } - return 0; -} diff --git a/chromium/net/spdy/spdy_proxy_client_socket.cc b/chromium/net/spdy/spdy_proxy_client_socket.cc index 724bbd81e90..f8d4713d0ab 100644 --- a/chromium/net/spdy/spdy_proxy_client_socket.cc +++ b/chromium/net/spdy/spdy_proxy_client_socket.cc @@ -418,7 +418,7 @@ int SpdyProxyClientSocket::DoReadReplyComplete(int result) { // Note that this triggers a spdy::ERROR_CODE_CANCEL. spdy_stream_->DetachDelegate(); next_state_ = STATE_DISCONNECTED; - return ERR_HTTPS_PROXY_TUNNEL_RESPONSE; + return ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT; case 407: // Proxy Authentication Required next_state_ = STATE_OPEN; diff --git a/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc b/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc index 0f31adca336..8e53e3084bc 100644 --- a/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc +++ b/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc @@ -498,7 +498,7 @@ TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) { Initialize(reads, writes); - AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); + AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT); const HttpResponseInfo* response = sock_->GetConnectResponseInfo(); ASSERT_TRUE(response != NULL); diff --git a/chromium/net/url_request/http_with_dns_over_https_unittest.cc b/chromium/net/url_request/http_with_dns_over_https_unittest.cc index 70754b4f34c..59a42d3b156 100644 --- a/chromium/net/url_request/http_with_dns_over_https_unittest.cc +++ b/chromium/net/url_request/http_with_dns_over_https_unittest.cc @@ -162,11 +162,11 @@ class TestHttpDelegate : public HttpStreamRequest::Delegate { void OnNeedsClientAuth(const SSLConfig& used_ssl_config, SSLCertRequestInfo* cert_info) override {} - void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info, - const SSLConfig& used_ssl_config, - const ProxyInfo& used_proxy_info, - std::unique_ptr<HttpStream> stream) override { - } + void OnHttpsProxyTunnelResponseRedirect( + const HttpResponseInfo& response_info, + const SSLConfig& used_ssl_config, + const ProxyInfo& used_proxy_info, + std::unique_ptr<HttpStream> stream) override {} void OnQuicBroken() override {} |