diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-05-16 09:59:13 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-05-20 10:28:53 +0000 |
commit | 6c11fb357ec39bf087b8b632e2b1e375aef1b38b (patch) | |
tree | c8315530db18a8ee566521c39ab8a6af4f72bc03 /chromium/net/http | |
parent | 3ffaed019d0772e59d6cdb2d0d32fe4834c31f72 (diff) | |
download | qtwebengine-chromium-6c11fb357ec39bf087b8b632e2b1e375aef1b38b.tar.gz |
BASELINE: Update Chromium to 74.0.3729.159
Change-Id: I8d2497da544c275415aedd94dd25328d555de811
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/net/http')
99 files changed, 7766 insertions, 3906 deletions
diff --git a/chromium/net/http/bidirectional_stream.cc b/chromium/net/http/bidirectional_stream.cc index ecb0c63bfa6..404ac0738f1 100644 --- a/chromium/net/http/bidirectional_stream.cc +++ b/chromium/net/http/bidirectional_stream.cc @@ -107,8 +107,8 @@ BidirectionalStream::BidirectionalStream( if (!request_info_->url.SchemeIs(url::kHttpsScheme)) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&BidirectionalStream::NotifyFailed, - weak_factory_.GetWeakPtr(), ERR_DISALLOWED_URL_SCHEME)); + base::BindOnce(&BidirectionalStream::NotifyFailed, + weak_factory_.GetWeakPtr(), ERR_DISALLOWED_URL_SCHEME)); return; } diff --git a/chromium/net/http/bidirectional_stream_unittest.cc b/chromium/net/http/bidirectional_stream_unittest.cc index 1c023ec117a..7f6387d79c2 100644 --- a/chromium/net/http/bidirectional_stream_unittest.cc +++ b/chromium/net/http/bidirectional_stream_unittest.cc @@ -17,6 +17,7 @@ #include "base/strings/string_number_conversions.h" #include "base/time/time.h" #include "base/timer/mock_timer.h" +#include "base/timer/timer.h" #include "build/build_config.h" #include "net/base/completion_once_callback.h" #include "net/base/load_timing_info.h" diff --git a/chromium/net/http/broken_alternative_services.cc b/chromium/net/http/broken_alternative_services.cc index 44e378abf8f..e2a71855b03 100644 --- a/chromium/net/http/broken_alternative_services.cc +++ b/chromium/net/http/broken_alternative_services.cc @@ -4,6 +4,7 @@ #include "net/http/broken_alternative_services.h" +#include "base/bind.h" #include "base/memory/singleton.h" #include "base/time/tick_clock.h" #include "base/time/time.h" diff --git a/chromium/net/http/http_auth.cc b/chromium/net/http/http_auth.cc index 54bc7812ebe..68ae3b1f867 100644 --- a/chromium/net/http/http_auth.cc +++ b/chromium/net/http/http_auth.cc @@ -10,6 +10,7 @@ #include "base/strings/string_tokenizer.h" #include "base/strings/string_util.h" #include "net/base/net_errors.h" +#include "net/dns/host_resolver.h" #include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_auth_handler.h" #include "net/http/http_auth_handler_factory.h" @@ -31,6 +32,7 @@ void HttpAuth::ChooseBestChallenge( const GURL& origin, const std::set<Scheme>& disabled_schemes, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) { DCHECK(http_auth_handler_factory); DCHECK(handler->get() == NULL); @@ -43,7 +45,7 @@ void HttpAuth::ChooseBestChallenge( while (response_headers.EnumerateHeader(&iter, header_name, &cur_challenge)) { std::unique_ptr<HttpAuthHandler> cur; int rv = http_auth_handler_factory->CreateAuthHandlerFromString( - cur_challenge, target, ssl_info, origin, net_log, &cur); + cur_challenge, target, ssl_info, origin, net_log, host_resolver, &cur); if (rv != OK) { VLOG(1) << "Unable to create AuthHandler. Status: " << ErrorToString(rv) << " Challenge: " << cur_challenge; diff --git a/chromium/net/http/http_auth.h b/chromium/net/http/http_auth.h index e4419e1f675..cd29acda9a2 100644 --- a/chromium/net/http/http_auth.h +++ b/chromium/net/http/http_auth.h @@ -20,6 +20,7 @@ namespace net { class HttpAuthHandler; class HttpAuthHandlerFactory; class HttpResponseHeaders; +class HostResolver; class NetLogWithSource; class SSLInfo; @@ -102,6 +103,18 @@ class NET_EXPORT_PRIVATE HttpAuth { AUTH_SCHEME_MAX, }; + // Type of Kerberos credentials delegation to be performed during + // authentication. + enum class DelegationType { + // Disallow delegation. + kNone, + // Delegate if approved by KDC policy. Implemented in GSSAPI. + kByKdcPolicy, + // Unconstrained delegation. On Windows both kByKdcPolicy and kUnconstraned + // check KDC policy. + kUnconstrained, + }; + // Helper structure used by HttpNetworkTransaction to track // the current identity being used for authorization. struct Identity { @@ -147,6 +160,7 @@ class NET_EXPORT_PRIVATE HttpAuth { const GURL& origin, const std::set<Scheme>& disabled_schemes, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler); // Handle a 401/407 response from a server/proxy after a previous diff --git a/chromium/net/http/http_auth_cache_unittest.cc b/chromium/net/http/http_auth_cache_unittest.cc index eadfbe45e62..41016b0c2fc 100644 --- a/chromium/net/http/http_auth_cache_unittest.cc +++ b/chromium/net/http/http_auth_cache_unittest.cc @@ -12,7 +12,6 @@ #include "base/test/simple_test_tick_clock.h" #include "net/base/net_errors.h" #include "net/http/http_auth_cache.h" -#include "net/http/http_auth_handler.h" #include "testing/gtest/include/gtest/gtest.h" using base::ASCIIToUTF16; @@ -21,43 +20,6 @@ namespace net { namespace { -class MockAuthHandler : public HttpAuthHandler { - public: - MockAuthHandler(HttpAuth::Scheme scheme, - const std::string& realm, - HttpAuth::Target target) { - // Can't use initializer list since these are members of the base class. - auth_scheme_ = scheme; - realm_ = realm; - score_ = 1; - target_ = target; - properties_ = 0; - } - - HttpAuth::AuthorizationResult HandleAnotherChallenge( - HttpAuthChallengeTokenizer* challenge) override { - return HttpAuth::AUTHORIZATION_RESULT_REJECT; - } - - protected: - bool Init(HttpAuthChallengeTokenizer* challenge, - const SSLInfo& ssl_info) override { - return false; // Unused. - } - - int GenerateAuthTokenImpl(const AuthCredentials*, - const HttpRequestInfo*, - CompletionOnceCallback callback, - std::string* auth_token) override { - *auth_token = "mock-credentials"; - return OK; - } - - - private: - ~MockAuthHandler() override = default; -}; - const char kRealm1[] = "Realm1"; const char kRealm2[] = "Realm2"; const char kRealm3[] = "Realm3"; @@ -90,75 +52,54 @@ TEST(HttpAuthCacheTest, Basic) { // Add cache entries for 4 realms: "Realm1", "Realm2", "Realm3" and // "Realm4" - std::unique_ptr<HttpAuthHandler> realm1_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm1, HttpAuth::AUTH_SERVER)); - cache.Add(origin, realm1_handler->realm(), realm1_handler->auth_scheme(), - "Basic realm=Realm1", + cache.Add(origin, kRealm1, HttpAuth::AUTH_SCHEME_BASIC, "Basic realm=Realm1", CreateASCIICredentials("realm1-user", "realm1-password"), "/foo/bar/index.html"); - std::unique_ptr<HttpAuthHandler> realm2_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm2, HttpAuth::AUTH_SERVER)); - cache.Add(origin, realm2_handler->realm(), realm2_handler->auth_scheme(), - "Basic realm=Realm2", + cache.Add(origin, kRealm2, HttpAuth::AUTH_SCHEME_BASIC, "Basic realm=Realm2", CreateASCIICredentials("realm2-user", "realm2-password"), "/foo2/index.html"); - std::unique_ptr<HttpAuthHandler> realm3_basic_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm3, HttpAuth::AUTH_PROXY)); cache.Add( - origin, - realm3_basic_handler->realm(), - realm3_basic_handler->auth_scheme(), - "Basic realm=Realm3", + origin, kRealm3, HttpAuth::AUTH_SCHEME_BASIC, "Basic realm=Realm3", CreateASCIICredentials("realm3-basic-user", "realm3-basic-password"), std::string()); - std::unique_ptr<HttpAuthHandler> realm3_digest_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_DIGEST, kRealm3, HttpAuth::AUTH_PROXY)); - cache.Add(origin, realm3_digest_handler->realm(), - realm3_digest_handler->auth_scheme(), "Digest realm=Realm3", - CreateASCIICredentials("realm3-digest-user", - "realm3-digest-password"), - "/baz/index.html"); - - std::unique_ptr<HttpAuthHandler> realm4_basic_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm4, HttpAuth::AUTH_SERVER)); - cache.Add(origin, realm4_basic_handler->realm(), - realm4_basic_handler->auth_scheme(), "Basic realm=Realm4", - CreateASCIICredentials("realm4-basic-user", - "realm4-basic-password"), - "/"); - - std::unique_ptr<HttpAuthHandler> origin2_realm5_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm5, HttpAuth::AUTH_SERVER)); - cache.Add(origin2, origin2_realm5_handler->realm(), - origin2_realm5_handler->auth_scheme(), "Basic realm=Realm5", + cache.Add( + origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST, "Digest realm=Realm3", + CreateASCIICredentials("realm3-digest-user", "realm3-digest-password"), + "/baz/index.html"); + + cache.Add( + origin, kRealm4, HttpAuth::AUTH_SCHEME_BASIC, "Basic realm=Realm4", + CreateASCIICredentials("realm4-basic-user", "realm4-basic-password"), + "/"); + + cache.Add(origin2, kRealm5, HttpAuth::AUTH_SCHEME_BASIC, "Basic realm=Realm5", CreateASCIICredentials("realm5-user", "realm5-password"), "/"); cache.Add( - origin2, realm3_basic_handler->realm(), - realm3_basic_handler->auth_scheme(), "Basic realm=Realm3", + origin2, kRealm3, HttpAuth::AUTH_SCHEME_BASIC, "Basic realm=Realm3", CreateASCIICredentials("realm3-basic-user", "realm3-basic-password"), std::string()); // There is no Realm5 in origin entry = cache.Lookup(origin, kRealm5, HttpAuth::AUTH_SCHEME_BASIC); - EXPECT_TRUE(NULL == entry); + EXPECT_FALSE(entry); // While Realm3 does exist, the origin scheme is wrong. entry = cache.Lookup(GURL("https://www.google.com"), kRealm3, HttpAuth::AUTH_SCHEME_BASIC); - EXPECT_TRUE(NULL == entry); + EXPECT_FALSE(entry); // Realm, origin scheme ok, authentication scheme wrong entry = cache.Lookup (GURL("http://www.google.com"), kRealm1, HttpAuth::AUTH_SCHEME_DIGEST); - EXPECT_TRUE(NULL == entry); + EXPECT_FALSE(entry); // Valid lookup by origin, realm, scheme. entry = cache.Lookup( GURL("http://www.google.com:80"), kRealm3, HttpAuth::AUTH_SCHEME_BASIC); - ASSERT_FALSE(NULL == entry); + ASSERT_TRUE(entry); EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme()); EXPECT_EQ(kRealm3, entry->realm()); EXPECT_EQ("Basic realm=Realm3", entry->auth_challenge()); @@ -169,14 +110,14 @@ TEST(HttpAuthCacheTest, Basic) { // Same realm, scheme with different origins HttpAuthCache::Entry* entry2 = cache.Lookup( GURL("http://www.foobar.com:80"), kRealm3, HttpAuth::AUTH_SCHEME_BASIC); - ASSERT_FALSE(NULL == entry2); + ASSERT_TRUE(entry2); EXPECT_NE(entry, entry2); // Valid lookup by origin, realm, scheme when there's a duplicate // origin, realm in the cache entry = cache.Lookup( GURL("http://www.google.com:80"), kRealm3, HttpAuth::AUTH_SCHEME_DIGEST); - ASSERT_FALSE(NULL == entry); + ASSERT_TRUE(entry); EXPECT_EQ(HttpAuth::AUTH_SCHEME_DIGEST, entry->scheme()); EXPECT_EQ(kRealm3, entry->realm()); EXPECT_EQ("Digest realm=Realm3", entry->auth_challenge()); @@ -187,7 +128,7 @@ TEST(HttpAuthCacheTest, Basic) { // Valid lookup by realm. entry = cache.Lookup(origin, kRealm2, HttpAuth::AUTH_SCHEME_BASIC); - ASSERT_FALSE(NULL == entry); + ASSERT_TRUE(entry); EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme()); EXPECT_EQ(kRealm2, entry->realm()); EXPECT_EQ("Basic realm=Realm2", entry->auth_challenge()); @@ -199,8 +140,8 @@ TEST(HttpAuthCacheTest, Basic) { cache.Lookup(origin, kRealm2, HttpAuth::AUTH_SCHEME_BASIC); HttpAuthCache::Entry* p_realm4_entry = cache.Lookup(origin, kRealm4, HttpAuth::AUTH_SCHEME_BASIC); - EXPECT_FALSE(NULL == p_realm2_entry); - EXPECT_FALSE(NULL == p_realm4_entry); + EXPECT_TRUE(p_realm2_entry); + EXPECT_TRUE(p_realm4_entry); HttpAuthCache::Entry realm2_entry = *p_realm2_entry; HttpAuthCache::Entry realm4_entry = *p_realm4_entry; // Realm4 applies to '/' and Realm2 applies to '/foo2/'. @@ -228,7 +169,7 @@ TEST(HttpAuthCacheTest, Basic) { // Confirm we find the same realm, different auth scheme by path lookup HttpAuthCache::Entry* p_realm3_digest_entry = cache.Lookup(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST); - EXPECT_FALSE(NULL == p_realm3_digest_entry); + EXPECT_TRUE(p_realm3_digest_entry); HttpAuthCache::Entry realm3_digest_entry = *p_realm3_digest_entry; entry = cache.LookupByPath(origin, "/baz/index.html"); EXPECT_TRUE(realm3_digest_entry.IsEqualForTesting(*entry)); @@ -240,7 +181,7 @@ TEST(HttpAuthCacheTest, Basic) { // Confirm we find the same realm, different auth scheme by path lookup HttpAuthCache::Entry* p_realm3DigestEntry = cache.Lookup(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST); - EXPECT_FALSE(NULL == p_realm3DigestEntry); + EXPECT_TRUE(p_realm3DigestEntry); HttpAuthCache::Entry realm3DigestEntry = *p_realm3DigestEntry; entry = cache.LookupByPath(origin, "/baz/index.html"); EXPECT_TRUE(realm3DigestEntry.IsEqualForTesting(*entry)); @@ -251,7 +192,7 @@ TEST(HttpAuthCacheTest, Basic) { // Lookup using empty path (may be used for proxy). entry = cache.LookupByPath(origin, std::string()); - EXPECT_FALSE(NULL == entry); + EXPECT_TRUE(entry); EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme()); EXPECT_EQ(kRealm3, entry->realm()); } @@ -293,20 +234,19 @@ TEST(HttpAuthCacheTest, AddPath) { TEST(HttpAuthCacheTest, AddToExistingEntry) { HttpAuthCache cache; GURL origin("http://www.foobar.com:70"); - const std::string auth_challenge = "Basic realm=MyRealm"; - - std::unique_ptr<HttpAuthHandler> handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, "MyRealm", HttpAuth::AUTH_SERVER)); - HttpAuthCache::Entry* orig_entry = cache.Add( - origin, handler->realm(), handler->auth_scheme(), auth_challenge, - CreateASCIICredentials("user1", "password1"), "/x/y/z/"); - cache.Add(origin, handler->realm(), handler->auth_scheme(), auth_challenge, + const std::string kAuthChallenge = "Basic realm=MyRealm"; + const std::string kRealm = "MyRealm"; + + HttpAuthCache::Entry* orig_entry = + cache.Add(origin, kRealm, HttpAuth::AUTH_SCHEME_BASIC, kAuthChallenge, + CreateASCIICredentials("user1", "password1"), "/x/y/z/"); + cache.Add(origin, kRealm, HttpAuth::AUTH_SCHEME_BASIC, kAuthChallenge, CreateASCIICredentials("user2", "password2"), "/z/y/x/"); - cache.Add(origin, handler->realm(), handler->auth_scheme(), auth_challenge, + cache.Add(origin, kRealm, HttpAuth::AUTH_SCHEME_BASIC, kAuthChallenge, CreateASCIICredentials("user3", "password3"), "/z/y"); - HttpAuthCache::Entry* entry = cache.Lookup( - origin, "MyRealm", HttpAuth::AUTH_SCHEME_BASIC); + HttpAuthCache::Entry* entry = + cache.Lookup(origin, kRealm, HttpAuth::AUTH_SCHEME_BASIC); EXPECT_TRUE(entry == orig_entry); EXPECT_EQ(ASCIIToUTF16("user3"), entry->credentials().username()); @@ -320,30 +260,15 @@ TEST(HttpAuthCacheTest, AddToExistingEntry) { TEST(HttpAuthCacheTest, Remove) { GURL origin("http://foobar2.com"); - std::unique_ptr<HttpAuthHandler> realm1_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm1, HttpAuth::AUTH_SERVER)); - - std::unique_ptr<HttpAuthHandler> realm2_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm2, HttpAuth::AUTH_SERVER)); - - std::unique_ptr<HttpAuthHandler> realm3_basic_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm3, HttpAuth::AUTH_SERVER)); - - std::unique_ptr<HttpAuthHandler> realm3_digest_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_DIGEST, kRealm3, HttpAuth::AUTH_SERVER)); - HttpAuthCache cache; - cache.Add(origin, realm1_handler->realm(), realm1_handler->auth_scheme(), - "basic realm=Realm1", AuthCredentials(kAlice, k123), "/"); - cache.Add(origin, realm2_handler->realm(), realm2_handler->auth_scheme(), - "basic realm=Realm2", CreateASCIICredentials("bob", "princess"), - "/"); - cache.Add(origin, realm3_basic_handler->realm(), - realm3_basic_handler->auth_scheme(), "basic realm=Realm3", + cache.Add(origin, kRealm1, HttpAuth::AUTH_SCHEME_BASIC, "basic realm=Realm1", + AuthCredentials(kAlice, k123), "/"); + cache.Add(origin, kRealm2, HttpAuth::AUTH_SCHEME_BASIC, "basic realm=Realm2", + CreateASCIICredentials("bob", "princess"), "/"); + cache.Add(origin, kRealm3, HttpAuth::AUTH_SCHEME_BASIC, "basic realm=Realm3", AuthCredentials(kAdmin, kPassword), "/"); - cache.Add(origin, realm3_digest_handler->realm(), - realm3_digest_handler->auth_scheme(), "digest realm=Realm3", - AuthCredentials(kRoot, kWileCoyote), "/"); + cache.Add(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST, + "digest realm=Realm3", AuthCredentials(kRoot, kWileCoyote), "/"); // Fails, because there is no realm "Realm5". EXPECT_FALSE(cache.Remove( @@ -387,9 +312,8 @@ TEST(HttpAuthCacheTest, Remove) { AuthCredentials(kRoot, kWileCoyote))); // Succeed as above, but when entries were added in opposite order - cache.Add(origin, realm3_digest_handler->realm(), - realm3_digest_handler->auth_scheme(), "digest realm=Realm3", - AuthCredentials(kRoot, kWileCoyote), "/"); + cache.Add(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST, + "digest realm=Realm3", AuthCredentials(kRoot, kWileCoyote), "/"); EXPECT_TRUE(cache.Remove( origin, kRealm3, HttpAuth::AUTH_SCHEME_BASIC, AuthCredentials(kAdmin, kPassword))); @@ -531,12 +455,8 @@ TEST(HttpAuthCacheTest, ClearAllEntries) { TEST(HttpAuthCacheTest, UpdateStaleChallenge) { HttpAuthCache cache; GURL origin("http://foobar2.com"); - std::unique_ptr<HttpAuthHandler> digest_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_DIGEST, kRealm1, HttpAuth::AUTH_PROXY)); HttpAuthCache::Entry* entry_pre = cache.Add( - origin, - digest_handler->realm(), - digest_handler->auth_scheme(), + origin, kRealm1, HttpAuth::AUTH_SCHEME_DIGEST, "Digest realm=Realm1," "nonce=\"s3MzvFhaBAA=4c520af5acd9d8d7ae26947529d18c8eae1e98f4\"", CreateASCIICredentials("realm-digest-user", "realm-digest-password"), @@ -548,9 +468,7 @@ TEST(HttpAuthCacheTest, UpdateStaleChallenge) { EXPECT_EQ(4, entry_pre->IncrementNonceCount()); bool update_success = cache.UpdateStaleChallenge( - origin, - digest_handler->realm(), - digest_handler->auth_scheme(), + origin, kRealm1, HttpAuth::AUTH_SCHEME_DIGEST, "Digest realm=Realm1," "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\"," "stale=\"true\""); @@ -558,18 +476,14 @@ TEST(HttpAuthCacheTest, UpdateStaleChallenge) { // After the stale update, the entry should still exist in the cache and // the nonce count should be reset to 0. - HttpAuthCache::Entry* entry_post = cache.Lookup( - origin, - digest_handler->realm(), - digest_handler->auth_scheme()); + HttpAuthCache::Entry* entry_post = + cache.Lookup(origin, kRealm1, HttpAuth::AUTH_SCHEME_DIGEST); ASSERT_TRUE(entry_post != NULL); EXPECT_EQ(2, entry_post->IncrementNonceCount()); // UpdateStaleChallenge will fail if an entry doesn't exist in the cache. bool update_failure = cache.UpdateStaleChallenge( - origin, - kRealm2, - digest_handler->auth_scheme(), + origin, kRealm2, HttpAuth::AUTH_SCHEME_DIGEST, "Digest realm=Realm2," "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\"," "stale=\"true\""); @@ -581,46 +495,30 @@ TEST(HttpAuthCacheTest, UpdateAllFrom) { std::string path("/some/path"); std::string another_path("/another/path"); - std::unique_ptr<HttpAuthHandler> realm1_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm1, HttpAuth::AUTH_SERVER)); - - std::unique_ptr<HttpAuthHandler> realm2_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm2, HttpAuth::AUTH_PROXY)); - - std::unique_ptr<HttpAuthHandler> realm3_digest_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_DIGEST, kRealm3, HttpAuth::AUTH_SERVER)); - - std::unique_ptr<HttpAuthHandler> realm4_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm4, HttpAuth::AUTH_SERVER)); - HttpAuthCache first_cache; HttpAuthCache::Entry* entry; - first_cache.Add(origin, realm1_handler->realm(), - realm1_handler->auth_scheme(), "basic realm=Realm1", - AuthCredentials(kAlice, k123), path); - first_cache.Add(origin, realm2_handler->realm(), - realm2_handler->auth_scheme(), "basic realm=Realm2", - AuthCredentials(kAlice2, k1234), path); - first_cache.Add(origin, realm3_digest_handler->realm(), - realm3_digest_handler->auth_scheme(), "digest realm=Realm3", - AuthCredentials(kRoot, kWileCoyote), path); - entry = first_cache.Add( - origin, realm3_digest_handler->realm(), - realm3_digest_handler->auth_scheme(), "digest realm=Realm3", - AuthCredentials(kRoot, kWileCoyote), another_path); + first_cache.Add(origin, kRealm1, HttpAuth::AUTH_SCHEME_BASIC, + "basic realm=Realm1", AuthCredentials(kAlice, k123), path); + first_cache.Add(origin, kRealm2, HttpAuth::AUTH_SCHEME_BASIC, + "basic realm=Realm2", AuthCredentials(kAlice2, k1234), path); + first_cache.Add(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST, + "digest realm=Realm3", AuthCredentials(kRoot, kWileCoyote), + path); + entry = first_cache.Add(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST, + "digest realm=Realm3", + AuthCredentials(kRoot, kWileCoyote), another_path); EXPECT_EQ(2, entry->IncrementNonceCount()); HttpAuthCache second_cache; // Will be overwritten by kRoot:kWileCoyote. - second_cache.Add(origin, realm3_digest_handler->realm(), - realm3_digest_handler->auth_scheme(), "digest realm=Realm3", - AuthCredentials(kAlice2, k1234), path); + second_cache.Add(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST, + "digest realm=Realm3", AuthCredentials(kAlice2, k1234), + path); // Should be left intact. - second_cache.Add(origin, realm4_handler->realm(), - realm4_handler->auth_scheme(), "basic realm=Realm4", - AuthCredentials(kAdmin, kRoot), path); + second_cache.Add(origin, kRealm4, HttpAuth::AUTH_SCHEME_BASIC, + "basic realm=Realm4", AuthCredentials(kAdmin, kRoot), path); second_cache.UpdateAllFrom(first_cache); diff --git a/chromium/net/http/http_auth_challenge_tokenizer.cc b/chromium/net/http/http_auth_challenge_tokenizer.cc index 7ccd60b27af..dfeb6325fe2 100644 --- a/chromium/net/http/http_auth_challenge_tokenizer.cc +++ b/chromium/net/http/http_auth_challenge_tokenizer.cc @@ -32,7 +32,7 @@ std::string HttpAuthChallengeTokenizer::base64_param() const { // (See https://bugzilla.mozilla.org/show_bug.cgi?id=230351.) // // Our base64 decoder requires that the length be a multiple of 4. - int encoded_length = params_end_ - params_begin_; + auto encoded_length = params_end_ - params_begin_; while (encoded_length > 0 && encoded_length % 4 != 0 && params_begin_[encoded_length - 1] == '=') { --encoded_length; diff --git a/chromium/net/http/http_auth_controller.cc b/chromium/net/http/http_auth_controller.cc index e682f26e0ac..12cc4f2a182 100644 --- a/chromium/net/http/http_auth_controller.cc +++ b/chromium/net/http/http_auth_controller.cc @@ -129,7 +129,8 @@ HttpAuthController::HttpAuthController( HttpAuth::Target target, const GURL& auth_url, HttpAuthCache* http_auth_cache, - HttpAuthHandlerFactory* http_auth_handler_factory) + HttpAuthHandlerFactory* http_auth_handler_factory, + HostResolver* host_resolver) : target_(target), auth_url_(auth_url), auth_origin_(auth_url.GetOrigin()), @@ -137,8 +138,8 @@ HttpAuthController::HttpAuthController( embedded_identity_used_(false), default_credentials_used_(false), http_auth_cache_(http_auth_cache), - http_auth_handler_factory_(http_auth_handler_factory) { -} + http_auth_handler_factory_(http_auth_handler_factory), + host_resolver_(host_resolver) {} HttpAuthController::~HttpAuthController() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -193,11 +194,11 @@ bool HttpAuthController::SelectPreemptiveAuth(const NetLogWithSource& net_log) { // Try to create a handler using the previous auth challenge. std::unique_ptr<HttpAuthHandler> handler_preemptive; - int rv_create = http_auth_handler_factory_-> - CreatePreemptiveAuthHandlerFromString(entry->auth_challenge(), target_, - auth_origin_, - entry->IncrementNonceCount(), - net_log, &handler_preemptive); + int rv_create = + http_auth_handler_factory_->CreatePreemptiveAuthHandlerFromString( + entry->auth_challenge(), target_, auth_origin_, + entry->IncrementNonceCount(), net_log, host_resolver_, + &handler_preemptive); if (rv_create != OK) return false; @@ -288,9 +289,9 @@ int HttpAuthController::HandleAuthChallenge( do { if (!handler_.get() && can_send_auth) { // Find the best authentication challenge that we support. - HttpAuth::ChooseBestChallenge(http_auth_handler_factory_, *headers, - ssl_info, target_, auth_origin_, - disabled_schemes_, net_log, &handler_); + HttpAuth::ChooseBestChallenge( + http_auth_handler_factory_, *headers, ssl_info, target_, auth_origin_, + disabled_schemes_, net_log, host_resolver_, &handler_); if (handler_.get()) HistogramAuthEvent(handler_.get(), AUTH_EVENT_START); } diff --git a/chromium/net/http/http_auth_controller.h b/chromium/net/http/http_auth_controller.h index 327b380a801..e71c3f93baa 100644 --- a/chromium/net/http/http_auth_controller.h +++ b/chromium/net/http/http_auth_controller.h @@ -24,6 +24,7 @@ class HttpAuthHandler; class HttpAuthHandlerFactory; class HttpAuthCache; class HttpRequestHeaders; +class HostResolver; class NetLogWithSource; struct HttpRequestInfo; class SSLInfo; @@ -46,7 +47,8 @@ class NET_EXPORT_PRIVATE HttpAuthController HttpAuthController(HttpAuth::Target target, const GURL& auth_url, HttpAuthCache* http_auth_cache, - HttpAuthHandlerFactory* http_auth_handler_factory); + HttpAuthHandlerFactory* http_auth_handler_factory, + HostResolver* host_resolver); // Generate an authentication token for |target| if necessary. The return // value is a net error code. |OK| will be returned both in the case that @@ -184,6 +186,7 @@ class NET_EXPORT_PRIVATE HttpAuthController // for the lifetime of this object. HttpAuthCache* const http_auth_cache_; HttpAuthHandlerFactory* const http_auth_handler_factory_; + HostResolver* const host_resolver_; std::set<HttpAuth::Scheme> disabled_schemes_; diff --git a/chromium/net/http/http_auth_controller_unittest.cc b/chromium/net/http/http_auth_controller_unittest.cc index 8c94fcf86ba..b2c9036583b 100644 --- a/chromium/net/http/http_auth_controller_unittest.cc +++ b/chromium/net/http/http_auth_controller_unittest.cc @@ -10,6 +10,7 @@ #include "base/test/scoped_task_environment.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" +#include "net/dns/mock_host_resolver.h" #include "net/http/http_auth_cache.h" #include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_auth_handler_mock.h" @@ -71,11 +72,11 @@ void RunSingleRoundAuthTest(HandlerRunMode run_mode, handler_rv); auth_handler_factory.AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY); auth_handler_factory.set_do_init_from_challenge(true); + auto host_resolver = std::make_unique<MockHostResolver>(); - scoped_refptr<HttpAuthController> controller( - new HttpAuthController(HttpAuth::AUTH_PROXY, - GURL("http://example.com"), - &dummy_auth_cache, &auth_handler_factory)); + scoped_refptr<HttpAuthController> controller(new HttpAuthController( + HttpAuth::AUTH_PROXY, GURL("http://example.com"), &dummy_auth_cache, + &auth_handler_factory, host_resolver.get())); SSLInfo null_ssl_info; ASSERT_EQ(OK, controller->HandleAuthChallenge(headers, null_ssl_info, false, false, dummy_log)); @@ -217,10 +218,11 @@ TEST(HttpAuthControllerTest, NoExplicitCredentialsAllowed) { HttpAuth::AUTH_SERVER); auth_handler_factory.set_do_init_from_challenge(true); - scoped_refptr<HttpAuthController> controller( - new HttpAuthController(HttpAuth::AUTH_SERVER, - GURL("http://example.com"), - &dummy_auth_cache, &auth_handler_factory)); + auto host_resolver = std::make_unique<MockHostResolver>(); + + scoped_refptr<HttpAuthController> controller(new HttpAuthController( + HttpAuth::AUTH_SERVER, GURL("http://example.com"), &dummy_auth_cache, + &auth_handler_factory, host_resolver.get())); SSLInfo null_ssl_info; ASSERT_EQ(OK, controller->HandleAuthChallenge(headers, null_ssl_info, false, false, dummy_log)); diff --git a/chromium/net/http/http_auth_gssapi_posix.cc b/chromium/net/http/http_auth_gssapi_posix.cc index d85cba85f48..5dab06a370d 100644 --- a/chromium/net/http/http_auth_gssapi_posix.cc +++ b/chromium/net/http/http_auth_gssapi_posix.cc @@ -77,6 +77,8 @@ gss_OID GSS_C_NT_EXPORT_NAME = &GSS_C_NT_EXPORT_NAME_VAL; namespace net { +using DelegationType = HttpAuth::DelegationType; + // Exported mechanism for GSSAPI. We always use SPNEGO: // iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2) @@ -378,6 +380,17 @@ std::string DescribeContext(GSSAPILibrary* gssapi_lib, return description; } +OM_uint32 DelegationTypeToFlag(DelegationType delegation_type) { + switch (delegation_type) { + case DelegationType::kNone: + return 0; + case DelegationType::kByKdcPolicy: + return GSS_C_DELEG_POLICY_FLAG; + case DelegationType::kUnconstrained: + return GSS_C_DELEG_FLAG; + } +} + } // namespace GSSAPISharedLibrary::GSSAPISharedLibrary(const std::string& gssapi_library_name) @@ -666,8 +679,7 @@ HttpAuthGSSAPI::HttpAuthGSSAPI(GSSAPILibrary* library, : scheme_(scheme), gss_oid_(gss_oid), library_(library), - scoped_sec_context_(library), - can_delegate_(false) { + scoped_sec_context_(library) { DCHECK(library_); } @@ -687,8 +699,8 @@ bool HttpAuthGSSAPI::AllowsExplicitCredentials() const { return false; } -void HttpAuthGSSAPI::Delegate() { - can_delegate_ = true; +void HttpAuthGSSAPI::SetDelegation(DelegationType delegation_type) { + delegation_type_ = delegation_type; } HttpAuth::AuthorizationResult HttpAuthGSSAPI::ParseChallenge( @@ -850,9 +862,7 @@ int HttpAuthGSSAPI::GetNextSecurityToken(const std::string& spn, ScopedName scoped_name(principal_name, library_); // Continue creating a security context. - OM_uint32 req_flags = 0; - if (can_delegate_) - req_flags |= GSS_C_DELEG_FLAG; + OM_uint32 req_flags = DelegationTypeToFlag(delegation_type_); major_status = library_->init_sec_context( &minor_status, GSS_C_NO_CREDENTIAL, scoped_sec_context_.receive(), principal_name, gss_oid_, req_flags, GSS_C_INDEFINITE, diff --git a/chromium/net/http/http_auth_gssapi_posix.h b/chromium/net/http/http_auth_gssapi_posix.h index df88f4978e7..eba04bbd7f2 100644 --- a/chromium/net/http/http_auth_gssapi_posix.h +++ b/chromium/net/http/http_auth_gssapi_posix.h @@ -241,7 +241,7 @@ class NET_EXPORT_PRIVATE HttpAuthGSSAPI : public HttpNegotiateAuthSystem { const std::string& channel_bindings, std::string* auth_token, CompletionOnceCallback callback) override; - void Delegate() override; + void SetDelegation(HttpAuth::DelegationType delegation_type) override; private: int GetNextSecurityToken(const std::string& spn, @@ -254,7 +254,7 @@ class NET_EXPORT_PRIVATE HttpAuthGSSAPI : public HttpNegotiateAuthSystem { GSSAPILibrary* library_; std::string decoded_server_auth_token_; ScopedSecurityContext scoped_sec_context_; - bool can_delegate_; + HttpAuth::DelegationType delegation_type_ = HttpAuth::DelegationType::kNone; }; } // namespace net diff --git a/chromium/net/http/http_auth_gssapi_posix_unittest.cc b/chromium/net/http/http_auth_gssapi_posix_unittest.cc index 416a873a7ca..8efd35824d9 100644 --- a/chromium/net/http/http_auth_gssapi_posix_unittest.cc +++ b/chromium/net/http/http_auth_gssapi_posix_unittest.cc @@ -6,6 +6,7 @@ #include <memory> +#include "base/bind.h" #include "base/logging.h" #include "base/native_library.h" #include "base/stl_util.h" diff --git a/chromium/net/http/http_auth_handler_basic.cc b/chromium/net/http/http_auth_handler_basic.cc index bf84a121599..cdec2824de2 100644 --- a/chromium/net/http/http_auth_handler_basic.cc +++ b/chromium/net/http/http_auth_handler_basic.cc @@ -11,6 +11,7 @@ #include "base/strings/utf_string_conversions.h" #include "net/base/net_errors.h" #include "net/base/net_string_util.h" +#include "net/dns/host_resolver.h" #include "net/http/http_auth.h" #include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_auth_scheme.h" @@ -115,6 +116,7 @@ int HttpAuthHandlerBasic::Factory::CreateAuthHandler( CreateReason reason, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) { // TODO(cbentzel): Move towards model of parsing in the factory // method and only constructing when valid. diff --git a/chromium/net/http/http_auth_handler_basic.h b/chromium/net/http/http_auth_handler_basic.h index 02e3dd749d6..b42aec14f9f 100644 --- a/chromium/net/http/http_auth_handler_basic.h +++ b/chromium/net/http/http_auth_handler_basic.h @@ -5,6 +5,7 @@ #ifndef NET_HTTP_HTTP_AUTH_HANDLER_BASIC_H_ #define NET_HTTP_HTTP_AUTH_HANDLER_BASIC_H_ +#include <memory> #include <string> #include "net/base/completion_once_callback.h" @@ -29,6 +30,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerBasic : public HttpAuthHandler { CreateReason reason, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) override; }; diff --git a/chromium/net/http/http_auth_handler_basic_unittest.cc b/chromium/net/http/http_auth_handler_basic_unittest.cc index 1f6ea6fc031..f2c80e641bd 100644 --- a/chromium/net/http/http_auth_handler_basic_unittest.cc +++ b/chromium/net/http/http_auth_handler_basic_unittest.cc @@ -12,6 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" +#include "net/dns/mock_host_resolver.h" #include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_request_info.h" #include "net/log/net_log_with_source.h" @@ -43,10 +44,11 @@ TEST(HttpAuthHandlerBasicTest, GenerateAuthToken) { for (size_t i = 0; i < base::size(tests); ++i) { std::string challenge = "Basic realm=\"Atlantis\""; SSLInfo null_ssl_info; + auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> basic; EXPECT_EQ(OK, factory.CreateAuthHandlerFromString( challenge, HttpAuth::AUTH_SERVER, null_ssl_info, origin, - NetLogWithSource(), &basic)); + NetLogWithSource(), host_resolver.get(), &basic)); AuthCredentials credentials(base::ASCIIToUTF16(tests[i].username), base::ASCIIToUTF16(tests[i].password)); HttpRequestInfo request_info; @@ -97,10 +99,11 @@ TEST(HttpAuthHandlerBasicTest, HandleAnotherChallenge) { GURL origin("http://www.example.com"); HttpAuthHandlerBasic::Factory factory; SSLInfo null_ssl_info; + auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> basic; EXPECT_EQ(OK, factory.CreateAuthHandlerFromString( tests[0].challenge, HttpAuth::AUTH_SERVER, null_ssl_info, - origin, NetLogWithSource(), &basic)); + origin, NetLogWithSource(), host_resolver.get(), &basic)); for (size_t i = 0; i < base::size(tests); ++i) { std::string challenge(tests[i].challenge); @@ -198,10 +201,11 @@ TEST(HttpAuthHandlerBasicTest, InitFromChallenge) { for (size_t i = 0; i < base::size(tests); ++i) { std::string challenge = tests[i].challenge; SSLInfo null_ssl_info; + auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> basic; int rv = factory.CreateAuthHandlerFromString( challenge, HttpAuth::AUTH_SERVER, null_ssl_info, origin, - NetLogWithSource(), &basic); + NetLogWithSource(), host_resolver.get(), &basic); EXPECT_EQ(tests[i].expected_rv, rv); if (rv == OK) EXPECT_EQ(tests[i].expected_realm, basic->realm()); diff --git a/chromium/net/http/http_auth_handler_digest.cc b/chromium/net/http/http_auth_handler_digest.cc index 50941f40355..424340f8156 100644 --- a/chromium/net/http/http_auth_handler_digest.cc +++ b/chromium/net/http/http_auth_handler_digest.cc @@ -15,6 +15,7 @@ #include "net/base/net_errors.h" #include "net/base/net_string_util.h" #include "net/base/url_util.h" +#include "net/dns/host_resolver.h" #include "net/http/http_auth.h" #include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_auth_scheme.h" @@ -94,6 +95,7 @@ int HttpAuthHandlerDigest::Factory::CreateAuthHandler( CreateReason reason, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) { // TODO(cbentzel): Move towards model of parsing in the factory // method and only constructing when valid. diff --git a/chromium/net/http/http_auth_handler_digest.h b/chromium/net/http/http_auth_handler_digest.h index cfe6569d4cf..90731b82138 100644 --- a/chromium/net/http/http_auth_handler_digest.h +++ b/chromium/net/http/http_auth_handler_digest.h @@ -73,6 +73,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerDigest : public HttpAuthHandler { CreateReason reason, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) override; private: diff --git a/chromium/net/http/http_auth_handler_digest_unittest.cc b/chromium/net/http/http_auth_handler_digest_unittest.cc index 86097ff99b8..4af18578f84 100644 --- a/chromium/net/http/http_auth_handler_digest_unittest.cc +++ b/chromium/net/http/http_auth_handler_digest_unittest.cc @@ -9,6 +9,7 @@ #include "base/strings/utf_string_conversions.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" +#include "net/dns/mock_host_resolver.h" #include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_auth_handler_digest.h" #include "net/http/http_request_info.h" @@ -56,6 +57,7 @@ bool RespondToChallenge(HttpAuth::Target target, HttpAuthHandlerDigest::NonceGenerator* nonce_generator = new HttpAuthHandlerDigest::FixedNonceGenerator("client_nonce"); factory->set_nonce_generator(nonce_generator); + auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> handler; // Create a handler for a particular challenge. @@ -63,7 +65,7 @@ bool RespondToChallenge(HttpAuth::Target target, GURL url_origin(target == HttpAuth::AUTH_SERVER ? request_url : proxy_name); int rv_create = factory->CreateAuthHandlerFromString( challenge, target, null_ssl_info, url_origin.GetOrigin(), - NetLogWithSource(), &handler); + NetLogWithSource(), host_resolver.get(), &handler); if (rv_create != OK || handler.get() == NULL) { ADD_FAILURE() << "Unable to create auth handler."; return false; @@ -361,10 +363,11 @@ TEST(HttpAuthHandlerDigestTest, ParseChallenge) { new HttpAuthHandlerDigest::Factory()); for (size_t i = 0; i < base::size(tests); ++i) { SSLInfo null_ssl_info; + auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> handler; int rv = factory->CreateAuthHandlerFromString( tests[i].challenge, HttpAuth::AUTH_SERVER, null_ssl_info, origin, - NetLogWithSource(), &handler); + NetLogWithSource(), host_resolver.get(), &handler); if (tests[i].parsed_success) { EXPECT_THAT(rv, IsOk()); } else { @@ -525,10 +528,11 @@ TEST(HttpAuthHandlerDigestTest, AssembleCredentials) { new HttpAuthHandlerDigest::Factory()); for (size_t i = 0; i < base::size(tests); ++i) { SSLInfo null_ssl_info; + auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> handler; int rv = factory->CreateAuthHandlerFromString( tests[i].challenge, HttpAuth::AUTH_SERVER, null_ssl_info, origin, - NetLogWithSource(), &handler); + NetLogWithSource(), host_resolver.get(), &handler); EXPECT_THAT(rv, IsOk()); ASSERT_TRUE(handler != NULL); @@ -550,6 +554,7 @@ TEST(HttpAuthHandlerDigestTest, AssembleCredentials) { TEST(HttpAuthHandlerDigest, HandleAnotherChallenge) { std::unique_ptr<HttpAuthHandlerDigest::Factory> factory( new HttpAuthHandlerDigest::Factory()); + auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> handler; std::string default_challenge = "Digest realm=\"Oblivion\", nonce=\"nonce-value\""; @@ -557,7 +562,7 @@ TEST(HttpAuthHandlerDigest, HandleAnotherChallenge) { SSLInfo null_ssl_info; int rv = factory->CreateAuthHandlerFromString( default_challenge, HttpAuth::AUTH_SERVER, null_ssl_info, origin, - NetLogWithSource(), &handler); + NetLogWithSource(), host_resolver.get(), &handler); EXPECT_THAT(rv, IsOk()); ASSERT_TRUE(handler.get() != NULL); HttpAuthChallengeTokenizer tok_default(default_challenge.begin(), diff --git a/chromium/net/http/http_auth_handler_factory.cc b/chromium/net/http/http_auth_handler_factory.cc index 6b3dd0ea81f..0e5610eec55 100644 --- a/chromium/net/http/http_auth_handler_factory.cc +++ b/chromium/net/http/http_auth_handler_factory.cc @@ -4,11 +4,14 @@ #include "net/http/http_auth_handler_factory.h" +#include <set> + #include "base/memory/ptr_util.h" #include "base/stl_util.h" #include "base/strings/string_util.h" #include "build/build_config.h" #include "net/base/net_errors.h" +#include "net/dns/host_resolver.h" #include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_auth_filter.h" #include "net/http/http_auth_handler_basic.h" @@ -31,10 +34,11 @@ int HttpAuthHandlerFactory::CreateAuthHandlerFromString( const SSLInfo& ssl_info, const GURL& origin, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) { HttpAuthChallengeTokenizer props(challenge.begin(), challenge.end()); return CreateAuthHandler(&props, target, ssl_info, origin, CREATE_CHALLENGE, - 1, net_log, handler); + 1, net_log, host_resolver, handler); } int HttpAuthHandlerFactory::CreatePreemptiveAuthHandlerFromString( @@ -43,12 +47,13 @@ int HttpAuthHandlerFactory::CreatePreemptiveAuthHandlerFromString( const GURL& origin, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) { HttpAuthChallengeTokenizer props(challenge.begin(), challenge.end()); SSLInfo null_ssl_info; return CreateAuthHandler(&props, target, null_ssl_info, origin, CREATE_PREEMPTIVE, digest_nonce_count, net_log, - handler); + host_resolver, handler); } namespace { @@ -97,7 +102,6 @@ HttpAuthHandlerFactory* HttpAuthHandlerRegistryFactory::GetSchemeFactory( // static std::unique_ptr<HttpAuthHandlerRegistryFactory> HttpAuthHandlerFactory::CreateDefault( - HostResolver* host_resolver, const HttpAuthPreferences* prefs #if defined(OS_CHROMEOS) , @@ -113,7 +117,7 @@ HttpAuthHandlerFactory::CreateDefault( ) { std::vector<std::string> auth_types(std::begin(kDefaultAuthSchemes), std::end(kDefaultAuthSchemes)); - return HttpAuthHandlerRegistryFactory::Create(host_resolver, prefs, auth_types + return HttpAuthHandlerRegistryFactory::Create(prefs, auth_types #if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS) , gssapi_library_name @@ -132,7 +136,6 @@ HttpAuthHandlerFactory::CreateDefault( // static std::unique_ptr<HttpAuthHandlerRegistryFactory> HttpAuthHandlerRegistryFactory::Create( - HostResolver* host_resolver, const HttpAuthPreferences* prefs, const std::vector<std::string>& auth_schemes #if defined(OS_CHROMEOS) @@ -173,7 +176,6 @@ HttpAuthHandlerRegistryFactory::Create( #if BUILDFLAG(USE_KERBEROS) if (base::ContainsKey(auth_schemes_set, kNegotiateAuthScheme)) { - DCHECK(host_resolver); HttpAuthHandlerNegotiate::Factory* negotiate_factory = new HttpAuthHandlerNegotiate::Factory(negotiate_auth_system_factory); #if defined(OS_WIN) @@ -185,7 +187,6 @@ HttpAuthHandlerRegistryFactory::Create( negotiate_factory->set_library(std::make_unique<GSSAPISharedLibrary>("")); negotiate_factory->set_allow_gssapi_library_load(allow_gssapi_library_load); #endif - negotiate_factory->set_host_resolver(host_resolver); registry_factory->RegisterSchemeFactory(kNegotiateAuthScheme, negotiate_factory); } @@ -208,6 +209,7 @@ int HttpAuthHandlerRegistryFactory::CreateAuthHandler( CreateReason reason, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) { std::string scheme = challenge->scheme(); if (scheme.empty()) { @@ -223,7 +225,7 @@ int HttpAuthHandlerRegistryFactory::CreateAuthHandler( DCHECK(it->second); return it->second->CreateAuthHandler(challenge, target, ssl_info, origin, reason, digest_nonce_count, net_log, - handler); + host_resolver, handler); } } // namespace net diff --git a/chromium/net/http/http_auth_handler_factory.h b/chromium/net/http/http_auth_handler_factory.h index 0c51a98fa8a..c0e0659c596 100644 --- a/chromium/net/http/http_auth_handler_factory.h +++ b/chromium/net/http/http_auth_handler_factory.h @@ -85,6 +85,12 @@ class NET_EXPORT HttpAuthHandlerFactory { // NOTE: This will apply to ALL |origin| values if the filters are empty. // // |*challenge| should not be reused after a call to |CreateAuthHandler()|, + // + // |host_resolver| is used by the Negotiate authentication handler to perform + // CNAME lookups to generate a Kerberos SPN for the server. If the "negotiate" + // scheme is used and the factory was created with + // |negotiate_disable_cname_lookup| false, |host_resolver| must not be null, + // and it must remain valid for the lifetime of the created |handler|. virtual int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge, HttpAuth::Target target, const SSLInfo& ssl_info, @@ -92,6 +98,7 @@ class NET_EXPORT HttpAuthHandlerFactory { CreateReason create_reason, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) = 0; // Creates an HTTP authentication handler based on the authentication @@ -104,6 +111,7 @@ class NET_EXPORT HttpAuthHandlerFactory { const SSLInfo& ssl_info, const GURL& origin, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler); // Creates an HTTP authentication handler based on the authentication @@ -117,6 +125,7 @@ class NET_EXPORT HttpAuthHandlerFactory { const GURL& origin, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler); // Factory callback to create the auth system used for Negotiate @@ -129,16 +138,9 @@ class NET_EXPORT HttpAuthHandlerFactory { // responsible for deleting the factory. // The default factory supports Basic, Digest, NTLM, and Negotiate schemes. // - // |resolver| is used by the Negotiate authentication handler to perform - // CNAME lookups to generate a Kerberos SPN for the server. It must be - // non-NULL. |resolver| must remain valid for the lifetime of the - // HttpAuthHandlerRegistryFactory and any HttpAuthHandlers created by said - // factory. - // // |negotiate_auth_system_factory| is used to override the default auth system // used by the Negotiate authentication handler. static std::unique_ptr<HttpAuthHandlerRegistryFactory> CreateDefault( - HostResolver* resolver, const HttpAuthPreferences* prefs = nullptr #if defined(OS_CHROMEOS) , @@ -193,11 +195,6 @@ class NET_EXPORT HttpAuthHandlerRegistryFactory // Creates an HttpAuthHandlerRegistryFactory. // - // |host_resolver| is used by the Negotiate authentication handler to perform - // CNAME lookups to generate a Kerberos SPN for the server. If the "negotiate" - // scheme is used and |negotiate_disable_cname_lookup| is false, - // |host_resolver| must not be NULL. - // // |prefs| is a pointer to the (single) authentication preferences object. // That object tracks preference, and hence policy, updates relevant to HTTP // authentication, and provides the current values of the preferences. @@ -208,7 +205,6 @@ class NET_EXPORT HttpAuthHandlerRegistryFactory // |negotiate_auth_system_factory| is used to override the default auth system // used by the Negotiate authentication handler. static std::unique_ptr<HttpAuthHandlerRegistryFactory> Create( - HostResolver* host_resolver, const HttpAuthPreferences* prefs, const std::vector<std::string>& auth_schemes #if defined(OS_CHROMEOS) @@ -227,6 +223,12 @@ class NET_EXPORT HttpAuthHandlerRegistryFactory // Creates an auth handler by dispatching out to the registered factories // based on the first token in |challenge|. + // + // |host_resolver| is used by the Negotiate authentication handler to perform + // CNAME lookups to generate a Kerberos SPN for the server. If the "negotiate" + // scheme is used and the factory was created with + // |negotiate_disable_cname_lookup| false, |host_resolver| must not be null, + // and it must remain valid for the lifetime of the created |handler|. int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge, HttpAuth::Target target, const SSLInfo& ssl_info, @@ -234,6 +236,7 @@ class NET_EXPORT HttpAuthHandlerRegistryFactory CreateReason reason, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) override; private: diff --git a/chromium/net/http/http_auth_handler_factory_unittest.cc b/chromium/net/http/http_auth_handler_factory_unittest.cc index f37101838de..b6ae977a394 100644 --- a/chromium/net/http/http_auth_handler_factory_unittest.cc +++ b/chromium/net/http/http_auth_handler_factory_unittest.cc @@ -8,6 +8,7 @@ #include "build/build_config.h" #include "net/base/net_errors.h" +#include "net/dns/host_resolver.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_auth_handler.h" #include "net/http/http_auth_scheme.h" @@ -40,6 +41,7 @@ class MockHttpAuthHandlerFactory : public HttpAuthHandlerFactory { CreateReason reason, int nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) override { handler->reset(); return return_code_; @@ -67,55 +69,60 @@ TEST(HttpAuthHandlerFactoryTest, RegistryFactory) { MockHttpAuthHandlerFactory* mock_factory_digest_replace = new MockHttpAuthHandlerFactory(kDigestReturnCodeReplace); + auto host_resovler = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> handler; // No schemes should be supported in the beginning. EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME, registry_factory.CreateAuthHandlerFromString( "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, gurl, - NetLogWithSource(), &handler)); + NetLogWithSource(), host_resovler.get(), &handler)); // Test what happens with a single scheme. registry_factory.RegisterSchemeFactory("Basic", mock_factory_basic); - EXPECT_EQ(kBasicReturnCode, registry_factory.CreateAuthHandlerFromString( - "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, - gurl, NetLogWithSource(), &handler)); + EXPECT_EQ(kBasicReturnCode, + registry_factory.CreateAuthHandlerFromString( + "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, gurl, + NetLogWithSource(), host_resovler.get(), &handler)); EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME, registry_factory.CreateAuthHandlerFromString( "Digest", HttpAuth::AUTH_SERVER, null_ssl_info, gurl, - NetLogWithSource(), &handler)); + NetLogWithSource(), host_resovler.get(), &handler)); // Test multiple schemes registry_factory.RegisterSchemeFactory("Digest", mock_factory_digest); - EXPECT_EQ(kBasicReturnCode, registry_factory.CreateAuthHandlerFromString( - "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, - gurl, NetLogWithSource(), &handler)); + EXPECT_EQ(kBasicReturnCode, + registry_factory.CreateAuthHandlerFromString( + "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, gurl, + NetLogWithSource(), host_resovler.get(), &handler)); EXPECT_EQ(kDigestReturnCode, registry_factory.CreateAuthHandlerFromString( "Digest", HttpAuth::AUTH_SERVER, null_ssl_info, gurl, - NetLogWithSource(), &handler)); + NetLogWithSource(), host_resovler.get(), &handler)); // Test case-insensitivity - EXPECT_EQ(kBasicReturnCode, registry_factory.CreateAuthHandlerFromString( - "basic", HttpAuth::AUTH_SERVER, null_ssl_info, - gurl, NetLogWithSource(), &handler)); + EXPECT_EQ(kBasicReturnCode, + registry_factory.CreateAuthHandlerFromString( + "basic", HttpAuth::AUTH_SERVER, null_ssl_info, gurl, + NetLogWithSource(), host_resovler.get(), &handler)); // Test replacement of existing auth scheme registry_factory.RegisterSchemeFactory("Digest", mock_factory_digest_replace); - EXPECT_EQ(kBasicReturnCode, registry_factory.CreateAuthHandlerFromString( - "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, - gurl, NetLogWithSource(), &handler)); + EXPECT_EQ(kBasicReturnCode, + registry_factory.CreateAuthHandlerFromString( + "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, gurl, + NetLogWithSource(), host_resovler.get(), &handler)); EXPECT_EQ(kDigestReturnCodeReplace, registry_factory.CreateAuthHandlerFromString( "Digest", HttpAuth::AUTH_SERVER, null_ssl_info, gurl, - NetLogWithSource(), &handler)); + NetLogWithSource(), host_resovler.get(), &handler)); } TEST(HttpAuthHandlerFactoryTest, DefaultFactory) { std::unique_ptr<HostResolver> host_resolver(new MockHostResolver()); MockAllowHttpAuthPreferences http_auth_preferences; std::unique_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory( - HttpAuthHandlerFactory::CreateDefault(host_resolver.get())); + HttpAuthHandlerFactory::CreateDefault()); http_auth_handler_factory->SetHttpAuthPreferences(kNegotiateAuthScheme, &http_auth_preferences); GURL server_origin("http://www.example.com"); @@ -125,7 +132,7 @@ TEST(HttpAuthHandlerFactoryTest, DefaultFactory) { std::unique_ptr<HttpAuthHandler> handler; int rv = http_auth_handler_factory->CreateAuthHandlerFromString( "Basic realm=\"FooBar\"", HttpAuth::AUTH_SERVER, null_ssl_info, - server_origin, NetLogWithSource(), &handler); + server_origin, NetLogWithSource(), host_resolver.get(), &handler); EXPECT_THAT(rv, IsOk()); ASSERT_FALSE(handler.get() == NULL); EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, handler->auth_scheme()); @@ -138,7 +145,7 @@ TEST(HttpAuthHandlerFactoryTest, DefaultFactory) { std::unique_ptr<HttpAuthHandler> handler; int rv = http_auth_handler_factory->CreateAuthHandlerFromString( "UNSUPPORTED realm=\"FooBar\"", HttpAuth::AUTH_SERVER, null_ssl_info, - server_origin, NetLogWithSource(), &handler); + server_origin, NetLogWithSource(), host_resolver.get(), &handler); EXPECT_THAT(rv, IsError(ERR_UNSUPPORTED_AUTH_SCHEME)); EXPECT_TRUE(handler.get() == NULL); } @@ -146,7 +153,8 @@ TEST(HttpAuthHandlerFactoryTest, DefaultFactory) { std::unique_ptr<HttpAuthHandler> handler; int rv = http_auth_handler_factory->CreateAuthHandlerFromString( "Digest realm=\"FooBar\", nonce=\"xyz\"", HttpAuth::AUTH_PROXY, - null_ssl_info, proxy_origin, NetLogWithSource(), &handler); + null_ssl_info, proxy_origin, NetLogWithSource(), host_resolver.get(), + &handler); EXPECT_THAT(rv, IsOk()); ASSERT_FALSE(handler.get() == NULL); EXPECT_EQ(HttpAuth::AUTH_SCHEME_DIGEST, handler->auth_scheme()); @@ -159,7 +167,7 @@ TEST(HttpAuthHandlerFactoryTest, DefaultFactory) { std::unique_ptr<HttpAuthHandler> handler; int rv = http_auth_handler_factory->CreateAuthHandlerFromString( "NTLM", HttpAuth::AUTH_SERVER, null_ssl_info, server_origin, - NetLogWithSource(), &handler); + NetLogWithSource(), host_resolver.get(), &handler); EXPECT_THAT(rv, IsOk()); ASSERT_FALSE(handler.get() == NULL); EXPECT_EQ(HttpAuth::AUTH_SCHEME_NTLM, handler->auth_scheme()); @@ -172,7 +180,7 @@ TEST(HttpAuthHandlerFactoryTest, DefaultFactory) { std::unique_ptr<HttpAuthHandler> handler; int rv = http_auth_handler_factory->CreateAuthHandlerFromString( "Negotiate", HttpAuth::AUTH_SERVER, null_ssl_info, server_origin, - NetLogWithSource(), &handler); + NetLogWithSource(), host_resolver.get(), &handler); // Note the default factory doesn't support Kerberos on Android #if BUILDFLAG(USE_KERBEROS) && !defined(OS_ANDROID) EXPECT_THAT(rv, IsOk()); diff --git a/chromium/net/http/http_auth_handler_mock.cc b/chromium/net/http/http_auth_handler_mock.cc index 0ac30e18b29..850f20ad90e 100644 --- a/chromium/net/http/http_auth_handler_mock.cc +++ b/chromium/net/http/http_auth_handler_mock.cc @@ -14,6 +14,7 @@ #include "base/strings/string_util.h" #include "base/threading/thread_task_runner_handle.h" #include "net/base/net_errors.h" +#include "net/dns/host_resolver.h" #include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_request_info.h" #include "testing/gmock/include/gmock/gmock.h" @@ -115,8 +116,8 @@ int HttpAuthHandlerMock::GenerateAuthTokenImpl( callback_ = std::move(callback); auth_token_ = auth_token; base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&HttpAuthHandlerMock::OnGenerateAuthToken, - weak_factory_.GetWeakPtr())); + FROM_HERE, base::BindOnce(&HttpAuthHandlerMock::OnGenerateAuthToken, + weak_factory_.GetWeakPtr())); state_ = State::TOKEN_PENDING; return ERR_IO_PENDING; } else { @@ -166,6 +167,7 @@ int HttpAuthHandlerMock::Factory::CreateAuthHandler( CreateReason reason, int nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) { if (handlers_[target].empty()) return ERR_UNEXPECTED; diff --git a/chromium/net/http/http_auth_handler_mock.h b/chromium/net/http/http_auth_handler_mock.h index f2083092ff7..ffbadb5b3e6 100644 --- a/chromium/net/http/http_auth_handler_mock.h +++ b/chromium/net/http/http_auth_handler_mock.h @@ -50,6 +50,7 @@ class HttpAuthHandlerMock : public HttpAuthHandler { CreateReason reason, int nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) override; private: diff --git a/chromium/net/http/http_auth_handler_negotiate.cc b/chromium/net/http/http_auth_handler_negotiate.cc index 1356fdb9d1a..1733efc56fb 100644 --- a/chromium/net/http/http_auth_handler_negotiate.cc +++ b/chromium/net/http/http_auth_handler_negotiate.cc @@ -17,6 +17,7 @@ #include "net/base/host_port_pair.h" #include "net/base/net_errors.h" #include "net/cert/x509_util.h" +#include "net/dns/host_resolver.h" #include "net/http/http_auth_filter.h" #include "net/http/http_auth_preferences.h" #include "net/log/net_log_capture_mode.h" @@ -26,6 +27,8 @@ namespace net { +using DelegationType = HttpAuth::DelegationType; + namespace { std::unique_ptr<base::Value> NetLogParameterChannelBindings( @@ -74,11 +77,6 @@ HttpAuthHandlerNegotiate::Factory::Factory( HttpAuthHandlerNegotiate::Factory::~Factory() = default; -void HttpAuthHandlerNegotiate::Factory::set_host_resolver( - HostResolver* resolver) { - resolver_ = resolver; -} - #if !defined(OS_ANDROID) && defined(OS_POSIX) const std::string& HttpAuthHandlerNegotiate::Factory::GetLibraryNameForTesting() const { @@ -94,6 +92,7 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( CreateReason reason, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) { #if defined(OS_WIN) if (is_unsupported_ || reason == CREATE_PREEMPTIVE) @@ -111,7 +110,7 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( std::unique_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNegotiate( CreateAuthSystem(auth_library_.get(), max_token_length_, http_auth_preferences(), negotiate_auth_system_factory_), - http_auth_preferences(), resolver_)); + http_auth_preferences(), host_resolver)); #elif defined(OS_ANDROID) if (is_unsupported_ || !http_auth_preferences() || http_auth_preferences()->AuthAndroidNegotiateAccountType().empty() || @@ -121,7 +120,7 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( // method and only constructing when valid. std::unique_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNegotiate( CreateAuthSystem(http_auth_preferences(), negotiate_auth_system_factory_), - http_auth_preferences(), resolver_)); + http_auth_preferences(), host_resolver)); #elif defined(OS_POSIX) if (is_unsupported_ || !allow_gssapi_library_load_) return ERR_UNSUPPORTED_AUTH_SCHEME; @@ -134,7 +133,7 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( std::unique_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNegotiate( CreateAuthSystem(auth_library_.get(), http_auth_preferences(), negotiate_auth_system_factory_), - http_auth_preferences(), resolver_)); + http_auth_preferences(), host_resolver)); #endif if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info, origin, net_log)) @@ -195,8 +194,7 @@ bool HttpAuthHandlerNegotiate::Init(HttpAuthChallengeTokenizer* challenge, if (!AllowsDefaultCredentials()) return false; #endif - if (CanDelegate()) - auth_system_->Delegate(); + auth_system_->SetDelegation(GetDelegationType()); auth_scheme_ = HttpAuth::AUTH_SCHEME_NEGOTIATE; score_ = 4; properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED; @@ -390,13 +388,15 @@ int HttpAuthHandlerNegotiate::DoGenerateAuthTokenComplete(int rv) { return rv; } -bool HttpAuthHandlerNegotiate::CanDelegate() const { +DelegationType HttpAuthHandlerNegotiate::GetDelegationType() const { + if (!http_auth_preferences_) + return DelegationType::kNone; + // TODO(cbentzel): Should delegation be allowed on proxies? if (target_ == HttpAuth::AUTH_PROXY) - return false; - if (!http_auth_preferences_) - return false; - return http_auth_preferences_->CanDelegate(origin_); + return DelegationType::kNone; + + return http_auth_preferences_->GetDelegationType(origin_); } } // namespace net diff --git a/chromium/net/http/http_auth_handler_negotiate.h b/chromium/net/http/http_auth_handler_negotiate.h index a1f7fa86130..945b1da58c6 100644 --- a/chromium/net/http/http_auth_handler_negotiate.h +++ b/chromium/net/http/http_auth_handler_negotiate.h @@ -44,11 +44,9 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler { class NET_EXPORT_PRIVATE Factory : public HttpAuthHandlerFactory { public: - Factory(NegotiateAuthSystemFactory negotiate_auth_system_factory); + explicit Factory(NegotiateAuthSystemFactory negotiate_auth_system_factory); ~Factory() override; - void set_host_resolver(HostResolver* host_resolver); - #if !defined(OS_ANDROID) // Sets the system library to use, thereby assuming ownership of // |auth_library|. @@ -76,11 +74,11 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler { CreateReason reason, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) override; private: NegotiateAuthSystemFactory negotiate_auth_system_factory_; - HostResolver* resolver_ = nullptr; #if defined(OS_WIN) ULONG max_token_length_ = 0; #endif @@ -136,7 +134,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler { int DoResolveCanonicalNameComplete(int rv); int DoGenerateAuthToken(); int DoGenerateAuthTokenComplete(int rv); - bool CanDelegate() const; + HttpAuth::DelegationType GetDelegationType() const; std::unique_ptr<HttpNegotiateAuthSystem> auth_system_; HostResolver* const resolver_; diff --git a/chromium/net/http/http_auth_handler_negotiate_unittest.cc b/chromium/net/http/http_auth_handler_negotiate_unittest.cc index ca8aa08bd95..eff278ed5e1 100644 --- a/chromium/net/http/http_auth_handler_negotiate_unittest.cc +++ b/chromium/net/http/http_auth_handler_negotiate_unittest.cc @@ -6,6 +6,7 @@ #include <string> +#include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/stl_util.h" #include "base/strings/string_util.h" @@ -68,7 +69,6 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest, #if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_ANDROID)) factory_->set_library(base::WrapUnique(auth_library_)); #endif - factory_->set_host_resolver(resolver_.get()); } #if defined(OS_ANDROID) @@ -225,7 +225,7 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest, SSLInfo null_ssl_info; int rv = factory_->CreateAuthHandlerFromString( "Negotiate", HttpAuth::AUTH_SERVER, null_ssl_info, gurl, - NetLogWithSource(), &generic_handler); + NetLogWithSource(), resolver_.get(), &generic_handler); if (rv != OK) return rv; HttpAuthHandlerNegotiate* negotiate_handler = @@ -427,7 +427,7 @@ class TestAuthSystem : public HttpNegotiateAuthSystem { return net::OK; } - void Delegate() override {} + void SetDelegation(HttpAuth::DelegationType delegation_type) override {} }; TEST_F(HttpAuthHandlerNegotiateTest, OverrideAuthSystem) { @@ -436,7 +436,6 @@ TEST_F(HttpAuthHandlerNegotiateTest, OverrideAuthSystem) { -> std::unique_ptr<HttpNegotiateAuthSystem> { return std::make_unique<TestAuthSystem>(); })); - negotiate_factory->set_host_resolver(resolver()); negotiate_factory->set_http_auth_preferences(http_auth_preferences()); #if !defined(OS_ANDROID) auto auth_library = std::make_unique<MockAuthLibrary>(); @@ -448,7 +447,7 @@ TEST_F(HttpAuthHandlerNegotiateTest, OverrideAuthSystem) { std::unique_ptr<HttpAuthHandler> handler; EXPECT_EQ(OK, negotiate_factory->CreateAuthHandlerFromString( "Negotiate", HttpAuth::AUTH_SERVER, SSLInfo(), gurl, - NetLogWithSource(), &handler)); + NetLogWithSource(), resolver(), &handler)); EXPECT_TRUE(handler); TestCompletionCallback callback; diff --git a/chromium/net/http/http_auth_handler_ntlm.h b/chromium/net/http/http_auth_handler_ntlm.h index 92dad89e679..2d9f0f94d1c 100644 --- a/chromium/net/http/http_auth_handler_ntlm.h +++ b/chromium/net/http/http_auth_handler_ntlm.h @@ -27,6 +27,7 @@ #include "net/ntlm/ntlm_client.h" #endif +#include <memory> #include <string> #include <vector> @@ -56,6 +57,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler { CreateReason reason, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) override; #if defined(NTLM_SSPI) // Set the SSPILibrary to use. Typically the only callers which need to use @@ -66,6 +68,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler { sspi_library_.reset(sspi_library); } #endif // defined(NTLM_SSPI) + private: #if defined(NTLM_SSPI) ULONG max_token_length_; diff --git a/chromium/net/http/http_auth_handler_ntlm_portable.cc b/chromium/net/http/http_auth_handler_ntlm_portable.cc index cc350d84652..1b13f78216a 100644 --- a/chromium/net/http/http_auth_handler_ntlm_portable.cc +++ b/chromium/net/http/http_auth_handler_ntlm_portable.cc @@ -8,6 +8,7 @@ #include "base/time/time.h" #include "net/base/net_errors.h" #include "net/base/network_interfaces.h" +#include "net/dns/host_resolver.h" #include "net/http/http_auth_preferences.h" namespace net { @@ -119,6 +120,7 @@ int HttpAuthHandlerNTLM::Factory::CreateAuthHandler( CreateReason reason, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) { if (reason == CREATE_PREEMPTIVE) return ERR_UNSUPPORTED_AUTH_SCHEME; diff --git a/chromium/net/http/http_auth_handler_ntlm_portable_unittest.cc b/chromium/net/http/http_auth_handler_ntlm_portable_unittest.cc index 5614330b4c3..ff42afffea6 100644 --- a/chromium/net/http/http_auth_handler_ntlm_portable_unittest.cc +++ b/chromium/net/http/http_auth_handler_ntlm_portable_unittest.cc @@ -52,7 +52,7 @@ class HttpAuthHandlerNtlmPortableTest : public PlatformTest { return factory_->CreateAuthHandlerFromString( "NTLM", HttpAuth::AUTH_SERVER, null_ssl_info, gurl, NetLogWithSource(), - &auth_handler_); + nullptr, &auth_handler_); } std::string CreateNtlmAuthHeader(base::span<const uint8_t> buffer) { diff --git a/chromium/net/http/http_auth_handler_ntlm_win.cc b/chromium/net/http/http_auth_handler_ntlm_win.cc index 70f8d317bfe..a92b013bdb7 100644 --- a/chromium/net/http/http_auth_handler_ntlm_win.cc +++ b/chromium/net/http/http_auth_handler_ntlm_win.cc @@ -11,6 +11,7 @@ #include "base/strings/string_util.h" #include "net/base/net_errors.h" +#include "net/dns/host_resolver.h" #include "net/http/http_auth_preferences.h" #include "net/http/http_auth_sspi_win.h" @@ -55,6 +56,7 @@ int HttpAuthHandlerNTLM::Factory::CreateAuthHandler( CreateReason reason, int digest_nonce_count, const NetLogWithSource& net_log, + HostResolver* host_resolver, std::unique_ptr<HttpAuthHandler>* handler) { if (is_unsupported_ || reason == CREATE_PREEMPTIVE) return ERR_UNSUPPORTED_AUTH_SCHEME; diff --git a/chromium/net/http/http_auth_preferences.cc b/chromium/net/http/http_auth_preferences.cc index 71def8814f1..79271fad436 100644 --- a/chromium/net/http/http_auth_preferences.cc +++ b/chromium/net/http/http_auth_preferences.cc @@ -44,8 +44,17 @@ bool HttpAuthPreferences::CanUseDefaultCredentials( return security_manager_->CanUseDefaultCredentials(auth_origin); } -bool HttpAuthPreferences::CanDelegate(const GURL& auth_origin) const { - return security_manager_->CanDelegate(auth_origin); +using DelegationType = HttpAuth::DelegationType; + +DelegationType HttpAuthPreferences::GetDelegationType( + const GURL& auth_origin) const { + if (!security_manager_->CanDelegate(auth_origin)) + return DelegationType::kNone; + + if (delegate_by_kdc_policy()) + return DelegationType::kByKdcPolicy; + + return DelegationType::kUnconstrained; } void HttpAuthPreferences::SetServerWhitelist( diff --git a/chromium/net/http/http_auth_preferences.h b/chromium/net/http/http_auth_preferences.h index 766e5a17aaa..6aeba3f4512 100644 --- a/chromium/net/http/http_auth_preferences.h +++ b/chromium/net/http/http_auth_preferences.h @@ -13,6 +13,7 @@ #include "base/macros.h" #include "build/build_config.h" #include "net/base/net_export.h" +#include "net/http/http_auth.h" #include "url/gurl.h" namespace net { @@ -35,7 +36,14 @@ class NET_EXPORT HttpAuthPreferences { virtual std::string AuthAndroidNegotiateAccountType() const; #endif virtual bool CanUseDefaultCredentials(const GURL& auth_origin) const; - virtual bool CanDelegate(const GURL& auth_origin) const; + virtual HttpAuth::DelegationType GetDelegationType( + const GURL& auth_origin) const; + + void set_delegate_by_kdc_policy(bool delegate_by_kdc_policy) { + delegate_by_kdc_policy_ = delegate_by_kdc_policy; + } + + bool delegate_by_kdc_policy() const { return delegate_by_kdc_policy_; } void set_negotiate_disable_cname_lookup(bool negotiate_disable_cname_lookup) { negotiate_disable_cname_lookup_ = negotiate_disable_cname_lookup; @@ -63,6 +71,7 @@ class NET_EXPORT HttpAuthPreferences { #endif private: + bool delegate_by_kdc_policy_ = false; bool negotiate_disable_cname_lookup_ = false; bool negotiate_enable_port_ = false; diff --git a/chromium/net/http/http_auth_preferences_unittest.cc b/chromium/net/http/http_auth_preferences_unittest.cc index 3da40288c5e..67302986270 100644 --- a/chromium/net/http/http_auth_preferences_unittest.cc +++ b/chromium/net/http/http_auth_preferences_unittest.cc @@ -58,12 +58,24 @@ TEST(HttpAuthPreferencesTest, AuthServerWhitelist) { EXPECT_TRUE(http_auth_preferences.CanUseDefaultCredentials(GURL("abc"))); } -TEST(HttpAuthPreferencesTest, AuthDelegateWhitelist) { +TEST(HttpAuthPreferencesTest, DelegationType) { + using DelegationType = HttpAuth::DelegationType; HttpAuthPreferences http_auth_preferences; // Check initial value - EXPECT_FALSE(http_auth_preferences.CanDelegate(GURL("abc"))); + EXPECT_EQ(DelegationType::kNone, + http_auth_preferences.GetDelegationType(GURL("abc"))); + http_auth_preferences.SetDelegateWhitelist("*"); - EXPECT_TRUE(http_auth_preferences.CanDelegate(GURL("abc"))); + EXPECT_EQ(DelegationType::kUnconstrained, + http_auth_preferences.GetDelegationType(GURL("abc"))); + + http_auth_preferences.set_delegate_by_kdc_policy(true); + EXPECT_EQ(DelegationType::kByKdcPolicy, + http_auth_preferences.GetDelegationType(GURL("abc"))); + + http_auth_preferences.SetDelegateWhitelist(""); + EXPECT_EQ(DelegationType::kNone, + http_auth_preferences.GetDelegationType(GURL("abc"))); } } // namespace net diff --git a/chromium/net/http/http_auth_sspi_win.cc b/chromium/net/http/http_auth_sspi_win.cc index cfd8a874dac..767a4de6350 100644 --- a/chromium/net/http/http_auth_sspi_win.cc +++ b/chromium/net/http/http_auth_sspi_win.cc @@ -17,6 +17,8 @@ namespace net { +using DelegationType = HttpAuth::DelegationType; + namespace { int MapAcquireCredentialsStatusToError(SECURITY_STATUS status, @@ -55,14 +57,14 @@ int AcquireExplicitCredentials(SSPILibrary* library, CredHandle* cred) { SEC_WINNT_AUTH_IDENTITY identity; identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; - identity.User = - reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(user.c_str())); + identity.User = reinterpret_cast<unsigned short*>( + const_cast<wchar_t*>(base::as_wcstr(user))); identity.UserLength = user.size(); - identity.Domain = - reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(domain.c_str())); + identity.Domain = reinterpret_cast<unsigned short*>( + const_cast<wchar_t*>(base::as_wcstr(domain))); identity.DomainLength = domain.size(); - identity.Password = - reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(password.c_str())); + identity.Password = reinterpret_cast<unsigned short*>( + const_cast<wchar_t*>(base::as_wcstr(password))); identity.PasswordLength = password.size(); TimeStamp expiry; @@ -247,7 +249,7 @@ HttpAuthSSPI::HttpAuthSSPI(SSPILibrary* library, scheme_(scheme), security_package_(security_package), max_token_length_(max_token_length), - can_delegate_(false) { + delegation_type_(DelegationType::kNone) { DCHECK(library_); SecInvalidateHandle(&cred_); SecInvalidateHandle(&ctxt_); @@ -273,8 +275,8 @@ bool HttpAuthSSPI::AllowsExplicitCredentials() const { return true; } -void HttpAuthSSPI::Delegate() { - can_delegate_ = true; +void HttpAuthSSPI::SetDelegation(DelegationType delegation_type) { + delegation_type_ = delegation_type; } void HttpAuthSSPI::ResetSecurityContext() { @@ -414,26 +416,27 @@ int HttpAuthSSPI::GetNextSecurityToken(const std::string& spn, DWORD context_flags = 0; // Firefox only sets ISC_REQ_DELEGATE, but MSDN documentation indicates that - // ISC_REQ_MUTUAL_AUTH must also be set. - if (can_delegate_) + // ISC_REQ_MUTUAL_AUTH must also be set. On Windows delegation by KDC policy + // is always respected. + if (delegation_type_ != DelegationType::kNone) context_flags |= (ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH); // This returns a token that is passed to the remote server. DWORD context_attribute; base::string16 spn16 = base::ASCIIToUTF16(spn); SECURITY_STATUS status = library_->InitializeSecurityContext( - &cred_, // phCredential - ctxt_ptr, // phContext - const_cast<base::char16*>(spn16.c_str()), // pszTargetName - context_flags, // fContextReq - 0, // Reserved1 (must be 0) - SECURITY_NATIVE_DREP, // TargetDataRep - in_buffer_desc_ptr, // pInput - 0, // Reserved2 (must be 0) - &ctxt_, // phNewContext - &out_buffer_desc, // pOutput - &context_attribute, // pfContextAttr - nullptr); // ptsExpiry + &cred_, // phCredential + ctxt_ptr, // phContext + base::as_writable_wcstr(spn16), // pszTargetName + context_flags, // fContextReq + 0, // Reserved1 (must be 0) + SECURITY_NATIVE_DREP, // TargetDataRep + in_buffer_desc_ptr, // pInput + 0, // Reserved2 (must be 0) + &ctxt_, // phNewContext + &out_buffer_desc, // pOutput + &context_attribute, // pfContextAttr + nullptr); // ptsExpiry int rv = MapInitializeSecurityContextStatusToError(status); if (rv != OK) { ResetSecurityContext(); diff --git a/chromium/net/http/http_auth_sspi_win.h b/chromium/net/http/http_auth_sspi_win.h index 0e393c61cd7..693bfd1121b 100644 --- a/chromium/net/http/http_auth_sspi_win.h +++ b/chromium/net/http/http_auth_sspi_win.h @@ -126,7 +126,7 @@ class NET_EXPORT_PRIVATE HttpAuthSSPI : public HttpNegotiateAuthSystem { const std::string& channel_bindings, std::string* auth_token, CompletionOnceCallback callback) override; - void Delegate() override; + void SetDelegation(HttpAuth::DelegationType delegation_type) override; private: int OnFirstRound(const AuthCredentials* credentials); @@ -147,7 +147,7 @@ class NET_EXPORT_PRIVATE HttpAuthSSPI : public HttpNegotiateAuthSystem { ULONG max_token_length_; CredHandle cred_; CtxtHandle ctxt_; - bool can_delegate_; + HttpAuth::DelegationType delegation_type_; }; // Splits |combined| into domain and username. diff --git a/chromium/net/http/http_auth_sspi_win_unittest.cc b/chromium/net/http/http_auth_sspi_win_unittest.cc index 105ca8ae83d..33c796d5d92 100644 --- a/chromium/net/http/http_auth_sspi_win_unittest.cc +++ b/chromium/net/http/http_auth_sspi_win_unittest.cc @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "net/http/http_auth_sspi_win.h" +#include "base/bind.h" #include "net/base/net_errors.h" #include "net/http/http_auth_challenge_tokenizer.h" -#include "net/http/http_auth_sspi_win.h" #include "net/http/mock_sspi_library_win.h" #include "net/test/gtest_util.h" #include "testing/gmock/include/gmock/gmock.h" @@ -17,11 +18,11 @@ namespace net { namespace { -void MatchDomainUserAfterSplit(const std::wstring& combined, - const std::wstring& expected_domain, - const std::wstring& expected_user) { - std::wstring actual_domain; - std::wstring actual_user; +void MatchDomainUserAfterSplit(const base::string16& combined, + const base::string16& expected_domain, + const base::string16& expected_user) { + base::string16 actual_domain; + base::string16 actual_user; SplitDomainAndUser(combined, &actual_domain, &actual_user); EXPECT_EQ(expected_domain, actual_domain); EXPECT_EQ(expected_user, actual_user); @@ -38,8 +39,10 @@ void UnexpectedCallback(int result) { } // namespace TEST(HttpAuthSSPITest, SplitUserAndDomain) { - MatchDomainUserAfterSplit(L"foobar", L"", L"foobar"); - MatchDomainUserAfterSplit(L"FOO\\bar", L"FOO", L"bar"); + MatchDomainUserAfterSplit(STRING16_LITERAL("foobar"), STRING16_LITERAL(""), + STRING16_LITERAL("foobar")); + MatchDomainUserAfterSplit(STRING16_LITERAL("FOO\\bar"), + STRING16_LITERAL("FOO"), STRING16_LITERAL("bar")); } TEST(HttpAuthSSPITest, DetermineMaxTokenLength_Normal) { diff --git a/chromium/net/http/http_auth_unittest.cc b/chromium/net/http/http_auth_unittest.cc index 43a7514b816..c4a0c32fb24 100644 --- a/chromium/net/http/http_auth_unittest.cc +++ b/chromium/net/http/http_auth_unittest.cc @@ -127,7 +127,7 @@ TEST(HttpAuthTest, ChooseBestChallenge) { MockAllowHttpAuthPreferences http_auth_preferences; std::unique_ptr<HostResolver> host_resolver(new MockHostResolver()); std::unique_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory( - HttpAuthHandlerFactory::CreateDefault(host_resolver.get())); + HttpAuthHandlerFactory::CreateDefault()); http_auth_handler_factory->SetHttpAuthPreferences(kNegotiateAuthScheme, &http_auth_preferences); @@ -143,7 +143,7 @@ TEST(HttpAuthTest, ChooseBestChallenge) { HttpAuth::ChooseBestChallenge(http_auth_handler_factory.get(), *headers, null_ssl_info, HttpAuth::AUTH_SERVER, origin, disabled_schemes, NetLogWithSource(), - &handler); + host_resolver.get(), &handler); if (handler.get()) { EXPECT_EQ(tests[i].challenge_scheme, handler->auth_scheme()); diff --git a/chromium/net/http/http_basic_state.cc b/chromium/net/http/http_basic_state.cc index 6a9d4b97dca..3c1eb5836ac 100644 --- a/chromium/net/http/http_basic_state.cc +++ b/chromium/net/http/http_basic_state.cc @@ -41,8 +41,9 @@ void HttpBasicState::Initialize(const HttpRequestInfo* request_info, url_ = request_info->url; traffic_annotation_ = request_info->traffic_annotation; request_method_ = request_info->method; - parser_.reset(new HttpStreamParser( - connection_.get(), request_info, read_buf_.get(), net_log)); + parser_ = std::make_unique<HttpStreamParser>( + connection_->socket(), connection_->is_reused(), request_info, + read_buf_.get(), net_log); parser_->set_http_09_on_non_default_ports_enabled( http_09_on_non_default_ports_enabled_); can_send_early_ = can_send_early; @@ -76,4 +77,9 @@ std::string HttpBasicState::GenerateRequestLine() const { return request_line; } +bool HttpBasicState::IsConnectionReused() const { + return connection_->is_reused() || + connection_->reuse_type() == ClientSocketHandle::UNUSED_IDLE; +} + } // namespace net diff --git a/chromium/net/http/http_basic_state.h b/chromium/net/http/http_basic_state.h index 58efbae8a17..58c122caba1 100644 --- a/chromium/net/http/http_basic_state.h +++ b/chromium/net/http/http_basic_state.h @@ -65,13 +65,21 @@ class NET_EXPORT_PRIVATE HttpBasicState { return traffic_annotation_; } + // Returns true if the connection has been "reused" as defined by HttpStream - + // either actually reused, or has not been used yet, but has been idle for + // some time. + // + // TODO(mmenke): Consider renaming this concept, to avoid confusion with + // ClientSocketHandle::is_reused(). + bool IsConnectionReused() const; + private: scoped_refptr<GrowableIOBuffer> read_buf_; - std::unique_ptr<HttpStreamParser> parser_; - std::unique_ptr<ClientSocketHandle> connection_; + std::unique_ptr<HttpStreamParser> parser_; + const bool using_proxy_; bool can_send_early_; diff --git a/chromium/net/http/http_basic_stream.cc b/chromium/net/http/http_basic_stream.cc index c623fbc7df6..9278d66134b 100644 --- a/chromium/net/http/http_basic_stream.cc +++ b/chromium/net/http/http_basic_stream.cc @@ -11,6 +11,8 @@ #include "net/http/http_response_body_drainer.h" #include "net/http/http_stream_parser.h" #include "net/socket/client_socket_handle.h" +#include "net/ssl/ssl_cert_request_info.h" +#include "net/ssl/ssl_info.h" namespace net { @@ -62,9 +64,18 @@ int HttpBasicStream::ReadResponseBody(IOBuffer* buf, void HttpBasicStream::Close(bool not_reusable) { // parser() is null if |this| is created by an orphaned HttpStreamFactory::Job - // in which case InitializeStream() will not have been called. - if (parser()) - parser()->Close(not_reusable); + // in which case InitializeStream() will not have been called. This also + // protects against null dereference in the case where + // state_.ReleaseConnection() has been called. + // + // TODO(mmenke): Can these cases be handled a bit more cleanly? + // WebSocketHandshakeStream will need to be updated as well. + if (!parser()) + return; + StreamSocket* socket = state_.connection()->socket(); + if (not_reusable && socket) + socket->Disconnect(); + state_.connection()->Reset(); } HttpStream* HttpBasicStream::RenewStreamForAuth() { @@ -83,13 +94,15 @@ bool HttpBasicStream::IsResponseBodyComplete() const { } bool HttpBasicStream::IsConnectionReused() const { - return parser()->IsConnectionReused(); + return state_.IsConnectionReused(); } -void HttpBasicStream::SetConnectionReused() { parser()->SetConnectionReused(); } +void HttpBasicStream::SetConnectionReused() { + state_.connection()->set_reuse_type(ClientSocketHandle::REUSED_IDLE); +} bool HttpBasicStream::CanReuseConnection() const { - return parser()->CanReuseConnection(); + return state_.connection()->socket() && parser()->CanReuseConnection(); } int64_t HttpBasicStream::GetTotalReceivedBytes() const { @@ -122,11 +135,19 @@ bool HttpBasicStream::GetAlternativeService( } void HttpBasicStream::GetSSLInfo(SSLInfo* ssl_info) { + if (!state_.connection()->socket()) { + ssl_info->Reset(); + return; + } parser()->GetSSLInfo(ssl_info); } void HttpBasicStream::GetSSLCertRequestInfo( SSLCertRequestInfo* cert_request_info) { + if (!state_.connection()->socket()) { + cert_request_info->Reset(); + return; + } parser()->GetSSLCertRequestInfo(cert_request_info); } diff --git a/chromium/net/http/http_cache.cc b/chromium/net/http/http_cache.cc index 45ac4825bb2..199074f4e75 100644 --- a/chromium/net/http/http_cache.cc +++ b/chromium/net/http/http_cache.cc @@ -137,7 +137,7 @@ bool HttpCache::ActiveEntry::TransactionInReaders( // This structure keeps track of work items that are attempting to create or // open cache entries or the backend itself. struct HttpCache::PendingOp { - PendingOp() : disk_entry(NULL), callback_will_delete(false) {} + PendingOp() : callback_will_delete(false) {} ~PendingOp() = default; // Returns the estimate of dynamically allocated memory in bytes. @@ -148,7 +148,8 @@ struct HttpCache::PendingOp { base::trace_event::EstimateMemoryUsage(pending_queue); } - disk_cache::Entry* disk_entry; + disk_cache::EntryWithOpened disk_entry_struct; + std::unique_ptr<disk_cache::Backend> backend; std::unique_ptr<WorkItem> writer; // True if there is a posted OnPendingOpComplete() task that might delete @@ -161,29 +162,23 @@ struct HttpCache::PendingOp { //----------------------------------------------------------------------------- -// The type of operation represented by a work item. -enum WorkItemOperation { - WI_CREATE_BACKEND, - WI_OPEN_ENTRY, - WI_CREATE_ENTRY, - WI_DOOM_ENTRY -}; - // A work item encapsulates a single request to the backend with all the // information needed to complete that request. class HttpCache::WorkItem { public: - WorkItem(WorkItemOperation operation, Transaction* trans, ActiveEntry** entry) + WorkItem(WorkItemOperation operation, + Transaction* transaction, + ActiveEntry** entry) : operation_(operation), - trans_(trans), + transaction_(transaction), entry_(entry), backend_(NULL) {} WorkItem(WorkItemOperation operation, - Transaction* trans, + Transaction* transaction, CompletionOnceCallback callback, disk_cache::Backend** backend) : operation_(operation), - trans_(trans), + transaction_(transaction), entry_(NULL), callback_(std::move(callback)), backend_(backend) {} @@ -194,8 +189,8 @@ class HttpCache::WorkItem { DCHECK(!entry || entry->disk_entry); if (entry_) *entry_ = entry; - if (trans_) - trans_->io_callback().Run(result); + if (transaction_) + transaction_->io_callback().Run(result); } // Notifies the caller about the operation completion. Returns true if the @@ -211,18 +206,22 @@ class HttpCache::WorkItem { } WorkItemOperation operation() { return operation_; } - void ClearTransaction() { trans_ = NULL; } + void ClearTransaction() { transaction_ = NULL; } void ClearEntry() { entry_ = NULL; } void ClearCallback() { callback_.Reset(); } - bool Matches(Transaction* trans) const { return trans == trans_; } - bool IsValid() const { return trans_ || entry_ || !callback_.is_null(); } + bool Matches(Transaction* transaction) const { + return transaction == transaction_; + } + bool IsValid() const { + return transaction_ || entry_ || !callback_.is_null(); + } // Returns the estimate of dynamically allocated memory in bytes. size_t EstimateMemoryUsage() const { return 0; } private: WorkItemOperation operation_; - Transaction* trans_; + Transaction* transaction_; ActiveEntry** entry_; CompletionOnceCallback callback_; // User callback. disk_cache::Backend** backend_; @@ -234,8 +233,8 @@ class HttpCache::WorkItem { // to a given entry. class HttpCache::MetadataWriter { public: - explicit MetadataWriter(HttpCache::Transaction* trans) - : verified_(false), buf_len_(0), transaction_(trans) {} + explicit MetadataWriter(HttpCache::Transaction* transaction) + : verified_(false), buf_len_(0), transaction_(transaction) {} ~MetadataWriter() = default; @@ -437,9 +436,9 @@ void HttpCache::WriteMetadata(const GURL& url, CreateBackend(NULL, CompletionOnceCallback()); } - HttpCache::Transaction* trans = + HttpCache::Transaction* transaction = new HttpCache::Transaction(priority, this); - MetadataWriter* writer = new MetadataWriter(trans); + MetadataWriter* writer = new MetadataWriter(transaction); // The writer will self destruct when done. writer->Write(url, expected_response_time, buf, buf_len); @@ -472,24 +471,25 @@ void HttpCache::OnExternalCacheHit( disk_cache_->OnExternalCacheHit(key); } -int HttpCache::CreateTransaction(RequestPriority priority, - std::unique_ptr<HttpTransaction>* trans) { +int HttpCache::CreateTransaction( + RequestPriority priority, + std::unique_ptr<HttpTransaction>* transaction) { // Do lazy initialization of disk cache if needed. if (!disk_cache_.get()) { // We don't care about the result. CreateBackend(NULL, CompletionOnceCallback()); } - HttpCache::Transaction* transaction = + HttpCache::Transaction* new_transaction = new HttpCache::Transaction(priority, this); if (bypass_lock_for_test_) - transaction->BypassLockForTest(); + new_transaction->BypassLockForTest(); if (bypass_lock_after_headers_for_test_) - transaction->BypassLockAfterHeadersForTest(); + new_transaction->BypassLockAfterHeadersForTest(); if (fail_conditionalization_for_test_) - transaction->FailConditionalizationForTest(); + new_transaction->FailConditionalizationForTest(); - trans->reset(transaction); + transaction->reset(new_transaction); return OK; } @@ -529,6 +529,23 @@ void HttpCache::DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd, //----------------------------------------------------------------------------- +net::Error HttpCache::CreateAndSetWorkItem(ActiveEntry** entry, + Transaction* transaction, + WorkItemOperation operation, + PendingOp* pending_op) { + auto item = std::make_unique<WorkItem>(operation, transaction, entry); + + if (pending_op->writer) { + pending_op->pending_queue.push_back(std::move(item)); + return ERR_IO_PENDING; + } + + DCHECK(pending_op->pending_queue.empty()); + + pending_op->writer = std::move(item); + return OK; +} + int HttpCache::CreateBackend(disk_cache::Backend** backend, CompletionOnceCallback callback) { if (!backend_factory_.get()) @@ -567,7 +584,7 @@ int HttpCache::CreateBackend(disk_cache::Backend** backend, return rv; } -int HttpCache::GetBackendForTransaction(Transaction* trans) { +int HttpCache::GetBackendForTransaction(Transaction* transaction) { if (disk_cache_.get()) return OK; @@ -575,7 +592,7 @@ int HttpCache::GetBackendForTransaction(Transaction* trans) { return ERR_FAILED; std::unique_ptr<WorkItem> item = std::make_unique<WorkItem>( - WI_CREATE_BACKEND, trans, CompletionOnceCallback(), nullptr); + WI_CREATE_BACKEND, transaction, CompletionOnceCallback(), nullptr); PendingOp* pending_op = GetPendingOp(std::string()); DCHECK(pending_op->writer); pending_op->pending_queue.push_back(std::move(item)); @@ -625,15 +642,15 @@ void HttpCache::DoomActiveEntry(const std::string& key) { DCHECK_EQ(OK, rv); } -int HttpCache::DoomEntry(const std::string& key, Transaction* trans) { +int HttpCache::DoomEntry(const std::string& key, Transaction* transaction) { // Need to abandon the ActiveEntry, but any transaction attached to the entry // should not be impacted. Dooming an entry only means that it will no // longer be returned by FindActiveEntry (and it will also be destroyed once // all consumers are finished with the entry). auto it = active_entries_.find(key); if (it == active_entries_.end()) { - DCHECK(trans); - return AsyncDoomEntry(key, trans); + DCHECK(transaction); + return AsyncDoomEntry(key, transaction); } std::unique_ptr<ActiveEntry> entry = std::move(it->second); @@ -652,24 +669,19 @@ int HttpCache::DoomEntry(const std::string& key, Transaction* trans) { return OK; } -int HttpCache::AsyncDoomEntry(const std::string& key, Transaction* trans) { - std::unique_ptr<WorkItem> item = - std::make_unique<WorkItem>(WI_DOOM_ENTRY, trans, nullptr); +int HttpCache::AsyncDoomEntry(const std::string& key, + Transaction* transaction) { PendingOp* pending_op = GetPendingOp(key); - if (pending_op->writer) { - pending_op->pending_queue.push_back(std::move(item)); - return ERR_IO_PENDING; - } - - DCHECK(pending_op->pending_queue.empty()); - - pending_op->writer = std::move(item); - - net::RequestPriority priority = trans ? trans->priority() : net::LOWEST; int rv = - disk_cache_->DoomEntry(key, priority, - base::BindOnce(&HttpCache::OnPendingOpComplete, - GetWeakPtr(), pending_op)); + CreateAndSetWorkItem(nullptr, transaction, WI_DOOM_ENTRY, pending_op); + if (rv != OK) + return rv; + + net::RequestPriority priority = + transaction ? transaction->priority() : net::LOWEST; + rv = disk_cache_->DoomEntry(key, priority, + base::BindOnce(&HttpCache::OnPendingOpComplete, + GetWeakPtr(), pending_op)); if (rv == ERR_IO_PENDING) { pending_op->callback_will_delete = true; return rv; @@ -762,8 +774,8 @@ HttpCache::PendingOp* HttpCache::GetPendingOp(const std::string& key) { void HttpCache::DeletePendingOp(PendingOp* pending_op) { std::string key; - if (pending_op->disk_entry) - key = pending_op->disk_entry->GetKey(); + if (pending_op->disk_entry_struct.entry) + key = pending_op->disk_entry_struct.entry->GetKey(); if (!key.empty()) { auto it = pending_ops_.find(key); @@ -782,26 +794,50 @@ void HttpCache::DeletePendingOp(PendingOp* pending_op) { delete pending_op; } -int HttpCache::OpenEntry(const std::string& key, ActiveEntry** entry, - Transaction* trans) { +int HttpCache::OpenOrCreateEntry(const std::string& key, + ActiveEntry** entry, + Transaction* transaction) { DCHECK(!FindActiveEntry(key)); - std::unique_ptr<WorkItem> item = - std::make_unique<WorkItem>(WI_OPEN_ENTRY, trans, entry); PendingOp* pending_op = GetPendingOp(key); - if (pending_op->writer) { - pending_op->pending_queue.push_back(std::move(item)); - return ERR_IO_PENDING; + int rv = CreateAndSetWorkItem(entry, transaction, WI_OPEN_OR_CREATE_ENTRY, + pending_op); + if (rv != OK) + return rv; + + rv = disk_cache_->OpenOrCreateEntry( + key, transaction->priority(), &(pending_op->disk_entry_struct), + base::BindOnce(&HttpCache::OnPendingOpComplete, GetWeakPtr(), + pending_op)); + + if (rv == ERR_IO_PENDING) { + pending_op->callback_will_delete = true; + return rv; } - DCHECK(pending_op->pending_queue.empty()); + pending_op->writer->ClearTransaction(); + OnPendingOpComplete(GetWeakPtr(), pending_op, rv); + return rv; +} - pending_op->writer = std::move(item); +int HttpCache::OpenEntry(const std::string& key, + ActiveEntry** entry, + Transaction* transaction) { + DCHECK(!FindActiveEntry(key)); + + PendingOp* pending_op = GetPendingOp(key); + int rv = CreateAndSetWorkItem(entry, transaction, WI_OPEN_ENTRY, pending_op); + if (rv != OK) + return rv; + + rv = disk_cache_->OpenEntry(key, transaction->priority(), + &(pending_op->disk_entry_struct.entry), + base::BindOnce(&HttpCache::OnPendingOpComplete, + GetWeakPtr(), pending_op)); + // Manually set the opened flag as disk_cache::OpenEntry() doesn't use + // EntryWithOpened struct. + pending_op->disk_entry_struct.opened = true; - int rv = - disk_cache_->OpenEntry(key, trans->priority(), &(pending_op->disk_entry), - base::BindOnce(&HttpCache::OnPendingOpComplete, - GetWeakPtr(), pending_op)); if (rv == ERR_IO_PENDING) { pending_op->callback_will_delete = true; return rv; @@ -812,28 +848,27 @@ int HttpCache::OpenEntry(const std::string& key, ActiveEntry** entry, return rv; } -int HttpCache::CreateEntry(const std::string& key, ActiveEntry** entry, - Transaction* trans) { +int HttpCache::CreateEntry(const std::string& key, + ActiveEntry** entry, + Transaction* transaction) { if (FindActiveEntry(key)) { return ERR_CACHE_RACE; } - std::unique_ptr<WorkItem> item = - std::make_unique<WorkItem>(WI_CREATE_ENTRY, trans, entry); PendingOp* pending_op = GetPendingOp(key); - if (pending_op->writer) { - pending_op->pending_queue.push_back(std::move(item)); - return ERR_IO_PENDING; - } + int rv = + CreateAndSetWorkItem(entry, transaction, WI_CREATE_ENTRY, pending_op); + if (rv != OK) + return rv; - DCHECK(pending_op->pending_queue.empty()); + rv = disk_cache_->CreateEntry(key, transaction->priority(), + &(pending_op->disk_entry_struct.entry), + base::BindOnce(&HttpCache::OnPendingOpComplete, + GetWeakPtr(), pending_op)); + // Manually set the opened flag as disk_cache::CreateEntry() doesn't use + // EntryWithOpened struct. + pending_op->disk_entry_struct.opened = false; - pending_op->writer = std::move(item); - - int rv = disk_cache_->CreateEntry( - key, trans->priority(), &(pending_op->disk_entry), - base::BindOnce(&HttpCache::OnPendingOpComplete, GetWeakPtr(), - pending_op)); if (rv == ERR_IO_PENDING) { pending_op->callback_will_delete = true; return rv; @@ -1013,7 +1048,8 @@ void HttpCache::DoomEntryValidationNoMatch(ActiveEntry* entry) { for (auto* transaction : entry->add_to_entry_queue) { transaction->ResetCachePendingState(); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(transaction->io_callback(), net::ERR_CACHE_RACE)); + FROM_HERE, + base::BindOnce(transaction->io_callback(), net::ERR_CACHE_RACE)); } entry->add_to_entry_queue.clear(); } @@ -1082,8 +1118,8 @@ void HttpCache::ProcessQueuedTransactions(ActiveEntry* entry) { // Post a task instead of invoking the io callback of another transaction here // to avoid re-entrancy. base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(&HttpCache::OnProcessQueuedTransactions, GetWeakPtr(), entry)); + FROM_HERE, base::BindOnce(&HttpCache::OnProcessQueuedTransactions, + GetWeakPtr(), entry)); } void HttpCache::ProcessAddToEntryQueue(ActiveEntry* entry) { @@ -1229,8 +1265,8 @@ bool HttpCache::IsWritingInProgress(ActiveEntry* entry) const { } LoadState HttpCache::GetLoadStateForPendingTransaction( - const Transaction* trans) { - auto i = active_entries_.find(trans->key()); + const Transaction* transaction) { + auto i = active_entries_.find(transaction->key()); if (i == active_entries_.end()) { // If this is really a pending transaction, and it is not part of // active_entries_, we should be creating the backend or the entry. @@ -1241,11 +1277,11 @@ LoadState HttpCache::GetLoadStateForPendingTransaction( return !writers ? LOAD_STATE_WAITING_FOR_CACHE : writers->GetLoadState(); } -void HttpCache::RemovePendingTransaction(Transaction* trans) { - auto i = active_entries_.find(trans->key()); +void HttpCache::RemovePendingTransaction(Transaction* transaction) { + auto i = active_entries_.find(transaction->key()); bool found = false; if (i != active_entries_.end()) - found = RemovePendingTransactionFromEntry(i->second.get(), trans); + found = RemovePendingTransactionFromEntry(i->second.get(), transaction); if (found) return; @@ -1253,22 +1289,22 @@ void HttpCache::RemovePendingTransaction(Transaction* trans) { if (building_backend_) { auto j = pending_ops_.find(std::string()); if (j != pending_ops_.end()) - found = RemovePendingTransactionFromPendingOp(j->second, trans); + found = RemovePendingTransactionFromPendingOp(j->second, transaction); if (found) return; } - auto j = pending_ops_.find(trans->key()); + auto j = pending_ops_.find(transaction->key()); if (j != pending_ops_.end()) - found = RemovePendingTransactionFromPendingOp(j->second, trans); + found = RemovePendingTransactionFromPendingOp(j->second, transaction); if (found) return; for (auto k = doomed_entries_.begin(); k != doomed_entries_.end() && !found; ++k) { - found = RemovePendingTransactionFromEntry(k->first, trans); + found = RemovePendingTransactionFromEntry(k->first, transaction); } DCHECK(found) << "Pending transaction not found"; @@ -1287,9 +1323,10 @@ bool HttpCache::RemovePendingTransactionFromEntry(ActiveEntry* entry, return true; } -bool HttpCache::RemovePendingTransactionFromPendingOp(PendingOp* pending_op, - Transaction* trans) { - if (pending_op->writer->Matches(trans)) { +bool HttpCache::RemovePendingTransactionFromPendingOp( + PendingOp* pending_op, + Transaction* transaction) { + if (pending_op->writer->Matches(transaction)) { pending_op->writer->ClearTransaction(); pending_op->writer->ClearEntry(); return true; @@ -1297,7 +1334,7 @@ bool HttpCache::RemovePendingTransactionFromPendingOp(PendingOp* pending_op, WorkItemList& pending_queue = pending_op->pending_queue; for (auto it = pending_queue.begin(); it != pending_queue.end(); ++it) { - if ((*it)->Matches(trans)) { + if ((*it)->Matches(transaction)) { pending_queue.erase(it); return true; } @@ -1353,24 +1390,25 @@ void HttpCache::OnIOComplete(int result, PendingOp* pending_op) { return OnBackendCreated(result, pending_op); std::unique_ptr<WorkItem> item = std::move(pending_op->writer); - bool fail_requests = false; + bool try_restart_requests = false; - ActiveEntry* entry = NULL; + ActiveEntry* entry = nullptr; std::string key; if (result == OK) { if (op == WI_DOOM_ENTRY) { // Anything after a Doom has to be restarted. - fail_requests = true; + try_restart_requests = true; } else if (item->IsValid()) { - key = pending_op->disk_entry->GetKey(); - entry = ActivateEntry(pending_op->disk_entry); + key = pending_op->disk_entry_struct.entry->GetKey(); + entry = ActivateEntry(pending_op->disk_entry_struct.entry); } else { // The writer transaction is gone. - if (op == WI_CREATE_ENTRY) - pending_op->disk_entry->Doom(); - pending_op->disk_entry->Close(); - pending_op->disk_entry = NULL; - fail_requests = true; + if (!pending_op->disk_entry_struct.opened) + pending_op->disk_entry_struct.entry->Doom(); + + pending_op->disk_entry_struct.entry->Close(); + pending_op->disk_entry_struct.entry = nullptr; + try_restart_requests = true; } } @@ -1397,36 +1435,48 @@ void HttpCache::OnIOComplete(int result, PendingOp* pending_op) { if (item->operation() == WI_DOOM_ENTRY) { // A queued doom request is always a race. - fail_requests = true; + try_restart_requests = true; } else if (result == OK) { entry = FindActiveEntry(key); if (!entry) - fail_requests = true; + try_restart_requests = true; } - if (fail_requests) { + if (try_restart_requests) { item->NotifyTransaction(ERR_CACHE_RACE, NULL); continue; } - + // At this point item->operation() is anything except Doom. if (item->operation() == WI_CREATE_ENTRY) { if (result == OK) { - // A second Create request, but the first request succeeded. + // Successful OpenOrCreate, Open, or Create followed by a Create. item->NotifyTransaction(ERR_CACHE_CREATE_FAILURE, NULL); } else { - if (op != WI_CREATE_ENTRY) { - // Failed Open followed by a Create. + if (op != WI_CREATE_ENTRY && op != WI_OPEN_OR_CREATE_ENTRY) { + // Failed Open or Doom followed by a Create. item->NotifyTransaction(ERR_CACHE_RACE, NULL); - fail_requests = true; + try_restart_requests = true; } else { item->NotifyTransaction(result, entry); } } - } else { + } + // item->operation() is OpenOrCreate or Open + else if (item->operation() == WI_OPEN_OR_CREATE_ENTRY) { + if ((op == WI_OPEN_ENTRY || op == WI_CREATE_ENTRY) && result != OK) { + // Failed Open or Create followed by an OpenOrCreate. + item->NotifyTransaction(ERR_CACHE_RACE, NULL); + try_restart_requests = true; + } else { + item->NotifyTransaction(result, entry); + } + } + // item->operation() is Open. + else { if (op == WI_CREATE_ENTRY && result != OK) { // Failed Create followed by an Open. item->NotifyTransaction(ERR_CACHE_RACE, NULL); - fail_requests = true; + try_restart_requests = true; } else { item->NotifyTransaction(result, entry); } @@ -1474,8 +1524,8 @@ void HttpCache::OnBackendCreated(int result, PendingOp* pending_op) { pending_op->writer = std::move(pending_item); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&HttpCache::OnBackendCreated, GetWeakPtr(), - result, pending_op)); + FROM_HERE, base::BindOnce(&HttpCache::OnBackendCreated, GetWeakPtr(), + result, pending_op)); } else { building_backend_ = false; DeletePendingOp(pending_op); diff --git a/chromium/net/http/http_cache.h b/chromium/net/http/http_cache.h index 7dda9c08e56..cb2792bf373 100644 --- a/chromium/net/http/http_cache.h +++ b/chromium/net/http/http_cache.h @@ -58,7 +58,6 @@ class HttpNetworkSession; class HttpResponseInfo; class IOBuffer; class NetLog; -class ViewCacheHelper; struct HttpRequestInfo; class NET_EXPORT HttpCache : public HttpTransactionFactory { @@ -89,7 +88,7 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { #if defined(OS_ANDROID) virtual void SetAppStatusListener( - base::android::ApplicationStatusListener* app_status_listener){}; + base::android::ApplicationStatusListener* app_status_listener) {} #endif }; @@ -257,7 +256,7 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { // HttpTransactionFactory implementation: int CreateTransaction(RequestPriority priority, - std::unique_ptr<HttpTransaction>* trans) override; + std::unique_ptr<HttpTransaction>* transaction) override; HttpCache* GetCache() override; HttpNetworkSession* GetSession() override; @@ -279,6 +278,15 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { private: // Types -------------------------------------------------------------------- + // The type of operation represented by a work item. + enum WorkItemOperation { + WI_CREATE_BACKEND, + WI_OPEN_OR_CREATE_ENTRY, + WI_OPEN_ENTRY, + WI_CREATE_ENTRY, + WI_DOOM_ENTRY + }; + // Disk cache entry data indices. enum { kResponseInfoIndex = 0, @@ -299,11 +307,11 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { friend class TestHttpCacheTransaction; friend class TestHttpCache; friend class Transaction; - friend class ViewCacheHelper; struct PendingOp; // Info for an entry under construction. // To help with testing. friend class MockHttpCache; + friend class HttpCacheIOCallbackTest; using TransactionList = std::list<Transaction*>; using TransactionSet = std::unordered_set<Transaction*>; @@ -381,17 +389,24 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { // Methods ------------------------------------------------------------------ + // Creates a WorkItem and sets it as the |pending_op|'s writer, or adds it to + // the queue if a writer already exists. + net::Error CreateAndSetWorkItem(ActiveEntry** entry, + Transaction* transaction, + WorkItemOperation operation, + PendingOp* pending_op); + // Creates the |backend| object and notifies the |callback| when the operation // completes. Returns an error code. int CreateBackend(disk_cache::Backend** backend, CompletionOnceCallback callback); // Makes sure that the backend creation is complete before allowing the - // provided transaction to use the object. Returns an error code. |trans| - // will be notified via its IO callback if this method returns ERR_IO_PENDING. - // The transaction is free to use the backend directly at any time after - // receiving the notification. - int GetBackendForTransaction(Transaction* trans); + // provided transaction to use the object. Returns an error code. + // |transaction| will be notified via its IO callback if this method returns + // ERR_IO_PENDING. The transaction is free to use the backend directly at any + // time after receiving the notification. + int GetBackendForTransaction(Transaction* transaction); // Generates the cache key for this request. std::string GenerateCacheKey(const HttpRequestInfo*); @@ -400,17 +415,17 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { // entries. void DoomActiveEntry(const std::string& key); - // Dooms the entry selected by |key|. |trans| will be notified via its IO - // callback if this method returns ERR_IO_PENDING. The entry can be - // currently in use or not. If entry is in use and the invoking transaction - // is associated with this entry and this entry is already doomed, this API + // Dooms the entry selected by |key|. |transaction| will be notified via its + // IO callback if this method returns ERR_IO_PENDING. The entry can be + // currently in use or not. If entry is in use and the invoking transaction is + // associated with this entry and this entry is already doomed, this API // should not be invoked. - int DoomEntry(const std::string& key, Transaction* trans); + int DoomEntry(const std::string& key, Transaction* transaction); - // Dooms the entry selected by |key|. |trans| will be notified via its IO - // callback if this method returns ERR_IO_PENDING. The entry should not - // be currently in use. - int AsyncDoomEntry(const std::string& key, Transaction* trans); + // Dooms the entry selected by |key|. |transaction| will be notified via its + // IO callback if this method returns ERR_IO_PENDING. The entry should not be + // currently in use. + int AsyncDoomEntry(const std::string& key, Transaction* transaction); // Dooms the entry associated with a GET for a given |url|, loaded from // a page with top-level frame at |top_frame_origin|. @@ -440,19 +455,30 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { // Deletes a PendingOp. void DeletePendingOp(PendingOp* pending_op); + // Opens the disk cache entry associated with |key|, creating the entry if it + // does not already exist, returning an ActiveEntry in |*entry|. |transaction| + // will be notified via its IO callback if this method returns ERR_IO_PENDING. + // This should not be called if there already is an active entry associated + // with |key|, e.g. you should call FindActiveEntry first. + int OpenOrCreateEntry(const std::string& key, + ActiveEntry** entry, + Transaction* transaction); + // Opens the disk cache entry associated with |key|, returning an ActiveEntry - // in |*entry|. |trans| will be notified via its IO callback if this method - // returns ERR_IO_PENDING. This should not be called if there already is - // an active entry associated with |key|, e.g. you should call FindActiveEntry - // first. - int OpenEntry(const std::string& key, ActiveEntry** entry, - Transaction* trans); + // in |*entry|. |transaction| will be notified via its IO callback if this + // method returns ERR_IO_PENDING. This should not be called if there already + // is an active entry associated with |key|, e.g. you should call + // FindActiveEntry first. + int OpenEntry(const std::string& key, + ActiveEntry** entry, + Transaction* transaction); // Creates the disk cache entry associated with |key|, returning an - // ActiveEntry in |*entry|. |trans| will be notified via its IO callback if - // this method returns ERR_IO_PENDING. - int CreateEntry(const std::string& key, ActiveEntry** entry, - Transaction* trans); + // ActiveEntry in |*entry|. |transaction| will be notified via its IO callback + // if this method returns ERR_IO_PENDING. + int CreateEntry(const std::string& key, + ActiveEntry** entry, + Transaction* transaction); // Destroys an ActiveEntry (active or doomed). Should only be called if // entry->SafeToDestroy() returns true. @@ -557,19 +583,20 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { bool IsWritingInProgress(ActiveEntry* entry) const; // Returns the LoadState of the provided pending transaction. - LoadState GetLoadStateForPendingTransaction(const Transaction* trans); + LoadState GetLoadStateForPendingTransaction(const Transaction* transaction); - // Removes the transaction |trans|, from the pending list of an entry + // Removes the transaction |transaction|, from the pending list of an entry // (PendingOp, active or doomed entry). - void RemovePendingTransaction(Transaction* trans); + void RemovePendingTransaction(Transaction* transaction); - // Removes the transaction |trans|, from the pending list of |entry|. + // Removes the transaction |transaction|, from the pending list of |entry|. bool RemovePendingTransactionFromEntry(ActiveEntry* entry, - Transaction* trans); + Transaction* transaction); - // Removes the transaction |trans|, from the pending list of |pending_op|. + // Removes the transaction |transaction|, from the pending list of + // |pending_op|. bool RemovePendingTransactionFromPendingOp(PendingOp* pending_op, - Transaction* trans); + Transaction* transaction); // Events (called via PostTask) --------------------------------------------- diff --git a/chromium/net/http/http_cache_lookup_manager.cc b/chromium/net/http/http_cache_lookup_manager.cc index 650929ef680..3f105f8ac00 100644 --- a/chromium/net/http/http_cache_lookup_manager.cc +++ b/chromium/net/http/http_cache_lookup_manager.cc @@ -6,6 +6,7 @@ #include <memory> +#include "base/bind.h" #include "base/values.h" #include "net/base/load_flags.h" diff --git a/chromium/net/http/http_cache_transaction.cc b/chromium/net/http/http_cache_transaction.cc index 16ece824e84..6964c708698 100644 --- a/chromium/net/http/http_cache_transaction.cc +++ b/chromium/net/http/http_cache_transaction.cc @@ -1056,6 +1056,10 @@ int HttpCache::Transaction::DoGetBackendComplete(int result) { // function can be invoked multiple times for a transaction. mode_ = NONE; + // Keep track of the fraction of requests that we can double-key. + UMA_HISTOGRAM_BOOLEAN("HttpCache.TopFrameOriginPresent", + request_->top_frame_origin.has_value()); + if (!ShouldPassThrough()) { cache_key_ = cache_->GenerateCacheKey(request_); @@ -1329,8 +1333,8 @@ void HttpCache::Transaction::AddCacheLockTimeoutHandler(ActiveEntry* entry) { next_state_ == STATE_FINISH_HEADERS_COMPLETE)) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&HttpCache::Transaction::OnCacheLockTimeout, - weak_factory_.GetWeakPtr(), entry_lock_waiting_since_)); + base::BindOnce(&HttpCache::Transaction::OnCacheLockTimeout, + weak_factory_.GetWeakPtr(), entry_lock_waiting_since_)); } else { int timeout_milliseconds = 20 * 1000; if (partial_ && entry->writers && !entry->writers->IsEmpty() && @@ -1356,8 +1360,8 @@ void HttpCache::Transaction::AddCacheLockTimeoutHandler(ActiveEntry* entry) { } base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, - base::Bind(&HttpCache::Transaction::OnCacheLockTimeout, - weak_factory_.GetWeakPtr(), entry_lock_waiting_since_), + base::BindOnce(&HttpCache::Transaction::OnCacheLockTimeout, + weak_factory_.GetWeakPtr(), entry_lock_waiting_since_), TimeDelta::FromMilliseconds(timeout_milliseconds)); } } @@ -2431,6 +2435,17 @@ bool HttpCache::Transaction::ShouldPassThrough() { if (effective_load_flags_ & LOAD_DISABLE_CACHE) return true; + // Prevent resources whose origin is opaque from being cached. Blink's memory + // cache should take care of reusing resources within the current page load, + // but otherwise a resource with an opaque top-frame origin won’t be used + // again. Also, if the request does not have a top frame origin, bypass the + // cache otherwise resources from different pages could share a cached entry + // in such cases. + if (base::FeatureList::IsEnabled(features::kSplitCacheByTopFrameOrigin) && + (!request_->top_frame_origin || request_->top_frame_origin->opaque())) { + return true; + } + if (method_ == "GET" || method_ == "HEAD") return false; @@ -2477,7 +2492,6 @@ int HttpCache::Transaction::BeginCacheRead() { } else { TransitionToState(STATE_FINISH_HEADERS); } - return OK; } diff --git a/chromium/net/http/http_cache_transaction.h b/chromium/net/http/http_cache_transaction.h index d489b92131c..0a7bdbd4916 100644 --- a/chromium/net/http/http_cache_transaction.h +++ b/chromium/net/http/http_cache_transaction.h @@ -115,6 +115,10 @@ class NET_EXPORT_PRIVATE HttpCache::Transaction : public HttpTransaction { const CompletionRepeatingCallback& io_callback() { return io_callback_; } + void SetIOCallBackForTest(CompletionRepeatingCallback cb) { + io_callback_ = cb; + } + const NetLogWithSource& net_log() const; // Bypasses the cache lock whenever there is lock contention. diff --git a/chromium/net/http/http_cache_unittest.cc b/chromium/net/http/http_cache_unittest.cc index 777fe08266c..308a95723aa 100644 --- a/chromium/net/http/http_cache_unittest.cc +++ b/chromium/net/http/http_cache_unittest.cc @@ -696,6 +696,47 @@ bool LogContainsEventType(const BoundTestNetLog& log, } // namespace using HttpCacheTest = TestWithScopedTaskEnvironment; +class HttpCacheIOCallbackTest : public HttpCacheTest { + public: + HttpCacheIOCallbackTest() {} + ~HttpCacheIOCallbackTest() override = default; + + // HttpCache::ActiveEntry is private, doing this allows tests to use it + using ActiveEntry = HttpCache::ActiveEntry; + using Transaction = HttpCache::Transaction; + + // The below functions are forwarding calls to the HttpCache class. + int OpenEntry(HttpCache* cache, + const std::string& key, + HttpCache::ActiveEntry** entry, + HttpCache::Transaction* trans) { + return cache->OpenEntry(key, entry, trans); + } + + int OpenOrCreateEntry(HttpCache* cache, + const std::string& key, + HttpCache::ActiveEntry** entry, + HttpCache::Transaction* trans) { + return cache->OpenOrCreateEntry(key, entry, trans); + } + + int CreateEntry(HttpCache* cache, + const std::string& key, + HttpCache::ActiveEntry** entry, + HttpCache::Transaction* trans) { + return cache->CreateEntry(key, entry, trans); + } + + int DoomEntry(HttpCache* cache, + const std::string& key, + HttpCache::Transaction* trans) { + return cache->DoomEntry(key, trans); + } + + void DeactivateEntry(HttpCache* cache, ActiveEntry* entry) { + cache->DeactivateEntry(entry); + } +}; //----------------------------------------------------------------------------- // Tests. @@ -736,7 +777,7 @@ TEST_F(HttpCacheTest, SimpleGET) { TEST_F(HttpCacheTest, SimpleGETNoDiskCache) { MockHttpCache cache; - cache.disk_cache()->set_fail_requests(); + cache.disk_cache()->set_fail_requests(true); BoundTestNetLog log; LoadTimingInfo load_timing_info; @@ -2189,7 +2230,7 @@ TEST_F(HttpCacheTest, RangeGET_ParallelValidationCouldConditionalize) { mock_transaction.data = kFullRangeData; std::string response_headers_str = base::StrCat( {"ETag: StrongOne\n", - "Content-Length:", base::IntToString(strlen(kFullRangeData)), "\n"}); + "Content-Length:", base::NumberToString(strlen(kFullRangeData)), "\n"}); mock_transaction.response_headers = response_headers_str.c_str(); ScopedMockTransaction transaction(mock_transaction); @@ -3368,7 +3409,7 @@ TEST_F(HttpCacheTest, SimpleGET_ParallelWritingHuge) { MockTransaction transaction(kSimpleGET_Transaction); std::string response_headers = base::StrCat( {kSimpleGET_Transaction.response_headers, "Content-Length: ", - base::IntToString(strlen(kSimpleGET_Transaction.data)), "\n"}); + base::NumberToString(strlen(kSimpleGET_Transaction.data)), "\n"}); transaction.response_headers = response_headers.c_str(); AddMockTransaction(&transaction); MockHttpRequest request(transaction); @@ -8340,10 +8381,12 @@ TEST_F(HttpCacheTest, WriteResponseInfo_Truncated) { // Tests basic pickling/unpickling of HttpResponseInfo. TEST_F(HttpCacheTest, PersistHttpResponseInfo) { + const IPEndPoint expected_endpoint = + IPEndPoint(net::IPAddress(1, 2, 3, 4), 80); // Set some fields (add more if needed.) HttpResponseInfo response1; response1.was_cached = false; - response1.socket_address = HostPortPair("1.2.3.4", 80); + response1.remote_endpoint = expected_endpoint; response1.headers = new HttpResponseHeaders("HTTP/1.1 200 OK"); // Pickle. @@ -8358,8 +8401,7 @@ TEST_F(HttpCacheTest, PersistHttpResponseInfo) { // Verify fields. EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag. - EXPECT_EQ("1.2.3.4", response2.socket_address.host()); - EXPECT_EQ(80, response2.socket_address.port()); + EXPECT_EQ(expected_endpoint, response2.remote_endpoint); EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); } @@ -9469,21 +9511,25 @@ TEST_F(HttpCacheTest, SplitCache) { base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature(net::features::kSplitCacheByTopFrameOrigin); + base::HistogramTester histograms; MockHttpCache cache; HttpResponseInfo response; url::Origin origin_a = url::Origin::Create(GURL("http://a.com")); url::Origin origin_b = url::Origin::Create(GURL("http://b.com")); + url::Origin origin_data = + url::Origin::Create(GURL("data:text/html,<body>Hello World</body>")); - // A request without a top frame origin is cached normally. + // A request without a top frame origin is not cached at all. MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction); RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction, trans_info, &response); EXPECT_FALSE(response.was_cached); + histograms.ExpectUniqueSample("HttpCache.TopFrameOriginPresent", false, 1); RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction, trans_info, &response); - EXPECT_TRUE(response.was_cached); + EXPECT_FALSE(response.was_cached); // Now request with a.com as the top frame origin. It shouldn't be cached // since the cached resource has a different top frame origin. @@ -9491,6 +9537,8 @@ TEST_F(HttpCacheTest, SplitCache) { RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction, trans_info, &response); EXPECT_FALSE(response.was_cached); + histograms.ExpectBucketCount("HttpCache.TopFrameOriginPresent", true, 1); + histograms.ExpectTotalCount("HttpCache.TopFrameOriginPresent", 3); // The second request should be cached. RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction, @@ -9514,6 +9562,19 @@ TEST_F(HttpCacheTest, SplitCache) { trans_info, &response); EXPECT_TRUE(response.was_cached); + // Now make a request with an opaque top frame origin. It shouldn't be + // cached. + trans_info.top_frame_origin = origin_data; + EXPECT_TRUE(trans_info.top_frame_origin->opaque()); + RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction, + trans_info, &response); + EXPECT_FALSE(response.was_cached); + + // On the second request, it still shouldn't be cached. + RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction, + trans_info, &response); + EXPECT_FALSE(response.was_cached); + // Verify that a post transaction with a data stream uses a separate key. const int64_t kUploadId = 1; // Just a dummy value. @@ -9537,6 +9598,7 @@ TEST_F(HttpCacheTest, NonSplitCache) { feature_list.InitAndDisableFeature( net::features::kSplitCacheByTopFrameOrigin); + base::HistogramTester histograms; MockHttpCache cache; HttpResponseInfo response; @@ -9557,6 +9619,8 @@ TEST_F(HttpCacheTest, NonSplitCache) { RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction, trans_info, &response); EXPECT_TRUE(response.was_cached); + histograms.ExpectBucketCount("HttpCache.TopFrameOriginPresent", true, 1); + histograms.ExpectTotalCount("HttpCache.TopFrameOriginPresent", 3); } // Tests that we can write metadata to an entry. @@ -10326,7 +10390,7 @@ HttpCacheHugeResourceTest::GetTestModes() { std::list<HugeCacheTestConfiguration> HttpCacheHugeResourceTest::kTestModes = HttpCacheHugeResourceTest::GetTestModes(); -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( _, HttpCacheHugeResourceTest, ::testing::ValuesIn(HttpCacheHugeResourceTest::kTestModes)); @@ -10336,7 +10400,7 @@ INSTANTIATE_TEST_CASE_P( // Test what happens when StopCaching() is called while reading a huge resource // fetched via GET. Various combinations of cache state and when StopCaching() // is called is controlled by the parameter passed into the test via the -// INSTANTIATE_TEST_CASE_P invocation above. +// INSTANTIATE_TEST_SUITE_P invocation above. TEST_P(HttpCacheHugeResourceTest, StopCachingFollowedByReadForHugeTruncatedResource) { // This test is going to be repeated for all combinations of TransactionPhase @@ -11187,11 +11251,639 @@ TEST_F(HttpCacheTest, CacheEntryStatusCantConditionalize) { response_info.cache_entry_status); } +class TestCompletionCallbackForHttpCache : public TestCompletionCallback { + public: + TestCompletionCallbackForHttpCache() {} + ~TestCompletionCallbackForHttpCache() override = default; + + const std::vector<int>& results() { return results_; } + + private: + std::vector<int> results_; + + protected: + void SetResult(int result) override { + results_.push_back(result); + DidSetResult(); + } +}; + +TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByOpen) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to DoomEntry and OpenEntry + // below require that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry1 = nullptr; + + cache.disk_cache()->set_force_fail_callback_later(true); + + // Queue up our operations. + int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + cache.disk_cache()->set_force_fail_callback_later(false); + rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify that DoomEntry failed correctly. + ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE); + // Verify that OpenEntry fails with the same code. + ASSERT_EQ(cb.results()[1], ERR_CACHE_DOOM_FAILURE); + ASSERT_EQ(entry1, nullptr); +} + +TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByCreate) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to DoomEntry and CreateEntry + // below require that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry1 = nullptr; + + cache.disk_cache()->set_force_fail_callback_later(true); + + // Queue up our operations. + int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + cache.disk_cache()->set_force_fail_callback_later(false); + rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify that DoomEntry failed correctly. + ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE); + // Verify that CreateEntry requests a restart (CACHE_RACE). + ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE); + ASSERT_EQ(entry1, nullptr); +} + +TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByDoom) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to DoomEntry below require that + // it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + cache.disk_cache()->set_force_fail_callback_later(true); + + // Queue up our operations. + int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + cache.disk_cache()->set_force_fail_callback_later(false); + rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify that DoomEntry failed correctly. + ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE); + // Verify that the second DoomEntry requests a restart (CACHE_RACE). + ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE); +} + +TEST_F(HttpCacheIOCallbackTest, FailedOpenFollowedByCreate) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to OpenEntry and CreateEntry + // below require that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry1 = nullptr; + ActiveEntry* entry2 = nullptr; + + cache.disk_cache()->set_force_fail_callback_later(true); + + // Queue up our operations. + int rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + cache.disk_cache()->set_force_fail_callback_later(false); + rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify that OpenEntry failed correctly. + ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_FAILURE); + ASSERT_EQ(entry1, nullptr); + // Verify that the CreateEntry requests a restart (CACHE_RACE). + ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE); + ASSERT_EQ(entry2, nullptr); +} + +TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByOpen) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to CreateEntry and OpenEntry + // below require that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry1 = nullptr; + ActiveEntry* entry2 = nullptr; + + cache.disk_cache()->set_force_fail_callback_later(true); + + // Queue up our operations. + int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + cache.disk_cache()->set_force_fail_callback_later(false); + rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry2, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify that CreateEntry failed correctly. + ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE); + ASSERT_EQ(entry1, nullptr); + // Verify that the OpenEntry requests a restart (CACHE_RACE). + ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE); + ASSERT_EQ(entry2, nullptr); +} + +TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByCreate) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to CreateEntry below require + // that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry1 = nullptr; + ActiveEntry* entry2 = nullptr; + + cache.disk_cache()->set_force_fail_callback_later(true); + + // Queue up our operations. + int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + cache.disk_cache()->set_force_fail_callback_later(false); + rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify the CreateEntry(s) failed. + ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE); + ASSERT_EQ(entry1, nullptr); + ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE); + ASSERT_EQ(entry2, nullptr); +} + +TEST_F(HttpCacheIOCallbackTest, CreateFollowedByCreate) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to CreateEntry below require + // that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry1 = nullptr; + ActiveEntry* entry2 = nullptr; + + // Queue up our operations. + int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify that the first CreateEntry succeeded. + ASSERT_EQ(cb.results()[0], OK); + ASSERT_NE(entry1, nullptr); + // Verify that the second CreateEntry failed. + ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE); + ASSERT_EQ(entry2, nullptr); +} + +TEST_F(HttpCacheIOCallbackTest, OperationFollowedByDoom) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to CreateEntry and DoomEntry + // below require that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry1 = nullptr; + + // Queue up our operations. + // For this test all we need is some operation followed by a doom, a create + // fulfills that requirement. + int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify that the CreateEntry succeeded. + ASSERT_EQ(cb.results()[0], OK); + // Verify that the DoomEntry requests a restart (CACHE_RACE). + ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE); +} + +TEST_F(HttpCacheIOCallbackTest, CreateFollowedByOpenOrCreate) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to CreateEntry and + // OpenOrCreateEntry below require that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry1 = nullptr; + ActiveEntry* entry2 = nullptr; + + // Queue up our operations. + int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify that the CreateEntry succeeded. + ASSERT_EQ(cb.results()[0], OK); + ASSERT_NE(entry1, nullptr); + // Verify that OpenOrCreateEntry succeeded. + ASSERT_EQ(cb.results()[1], OK); + ASSERT_NE(entry2, nullptr); + ASSERT_EQ(entry1->disk_entry, entry2->disk_entry); +} + +TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByOpenOrCreate) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to CreateEntry and + // OpenOrCreateEntry below require that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry1 = nullptr; + ActiveEntry* entry2 = nullptr; + + cache.disk_cache()->set_force_fail_callback_later(true); + + // Queue up our operations. + int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + cache.disk_cache()->set_force_fail_callback_later(false); + rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify that CreateEntry failed correctly. + ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE); + ASSERT_EQ(entry1, nullptr); + // Verify that the OpenOrCreateEntry requests a restart (CACHE_RACE). + ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE); + ASSERT_EQ(entry2, nullptr); +} + +TEST_F(HttpCacheIOCallbackTest, OpenFollowedByOpenOrCreate) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to OpenEntry and + // OpenOrCreateEntry below require that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry0 = nullptr; + ActiveEntry* entry1 = nullptr; + ActiveEntry* entry2 = nullptr; + + // First need to create and entry so we can open it. + int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry0, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), static_cast<size_t>(1)); + ASSERT_EQ(cb.results()[0], OK); + ASSERT_NE(entry0, nullptr); + // Manually DeactivateEntry() because OpenEntry() fails if there is an + // existing active entry. + DeactivateEntry(cache.http_cache(), entry0); + + // Queue up our operations. + rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 3u); + + // Verify that the OpenEntry succeeded. + ASSERT_EQ(cb.results()[1], OK); + ASSERT_NE(entry1, nullptr); + // Verify that OpenOrCreateEntry succeeded. + ASSERT_EQ(cb.results()[2], OK); + ASSERT_NE(entry2, nullptr); + ASSERT_EQ(entry1->disk_entry, entry2->disk_entry); +} + +TEST_F(HttpCacheIOCallbackTest, FailedOpenFollowedByOpenOrCreate) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to OpenEntry and + // OpenOrCreateEntry below require that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry1 = nullptr; + ActiveEntry* entry2 = nullptr; + + cache.disk_cache()->set_force_fail_callback_later(true); + + // Queue up our operations. + int rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + cache.disk_cache()->set_force_fail_callback_later(false); + rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify that OpenEntry failed correctly. + ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_FAILURE); + ASSERT_EQ(entry1, nullptr); + // Verify that the OpenOrCreateEntry requests a restart (CACHE_RACE). + ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE); + ASSERT_EQ(entry2, nullptr); +} + +TEST_F(HttpCacheIOCallbackTest, OpenOrCreateFollowedByCreate) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to OpenOrCreateEntry and + // CreateEntry below require that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry1 = nullptr; + ActiveEntry* entry2 = nullptr; + + // Queue up our operations. + int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify that the OpenOrCreateEntry succeeded. + ASSERT_EQ(cb.results()[0], OK); + ASSERT_NE(entry1, nullptr); + // Verify that CreateEntry failed. + ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE); + ASSERT_EQ(entry2, nullptr); +} + +TEST_F(HttpCacheIOCallbackTest, OpenOrCreateFollowedByOpenOrCreate) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to OpenOrCreateEntry below + // require that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry1 = nullptr; + ActiveEntry* entry2 = nullptr; + + // Queue up our operations. + int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify that the OpenOrCreateEntry succeeded. + ASSERT_EQ(cb.results()[0], OK); + ASSERT_NE(entry1, nullptr); + // Verify that the other succeeded. + ASSERT_EQ(cb.results()[1], OK); + ASSERT_NE(entry2, nullptr); +} + +TEST_F(HttpCacheIOCallbackTest, FailedOpenOrCreateFollowedByOpenOrCreate) { + MockHttpCache cache; + TestCompletionCallbackForHttpCache cb; + std::unique_ptr<Transaction> transaction = + std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache()); + + transaction->SetIOCallBackForTest(cb.callback()); + + // Create the backend here as our direct calls to OpenOrCreateEntry below + // require that it exists. + cache.backend(); + + // Need a mock transaction in order to use some of MockHttpCache's + // functions. + ScopedMockTransaction m_transaction(kSimpleGET_Transaction); + + ActiveEntry* entry1 = nullptr; + ActiveEntry* entry2 = nullptr; + + cache.disk_cache()->set_force_fail_callback_later(true); + + // Queue up our operations. + int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + cache.disk_cache()->set_force_fail_callback_later(false); + rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2, + transaction.get()); + ASSERT_EQ(rv, ERR_IO_PENDING); + + // Wait for all the results to arrive. + cb.GetResult(rv); + ASSERT_EQ(cb.results().size(), 2u); + + // Verify that the OpenOrCreateEntry failed. + ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_OR_CREATE_FAILURE); + ASSERT_EQ(entry1, nullptr); + // Verify that the other failed. + ASSERT_EQ(cb.results()[1], ERR_CACHE_OPEN_OR_CREATE_FAILURE); + ASSERT_EQ(entry2, nullptr); +} + class HttpCacheMemoryDumpTest : public testing::TestWithParam<base::trace_event::MemoryDumpLevelOfDetail>, public WithScopedTaskEnvironment {}; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( /* no prefix */, HttpCacheMemoryDumpTest, ::testing::Values(base::trace_event::MemoryDumpLevelOfDetail::DETAILED, diff --git a/chromium/net/http/http_cache_writers.cc b/chromium/net/http/http_cache_writers.cc index 0468ef8fb98..6842520d78a 100644 --- a/chromium/net/http/http_cache_writers.cc +++ b/chromium/net/http/http_cache_writers.cc @@ -8,8 +8,10 @@ #include <utility> #include "base/auto_reset.h" +#include "base/bind.h" +#include "base/bind_helpers.h" #include "base/logging.h" - +#include "base/threading/thread_task_runner_handle.h" #include "net/base/net_errors.h" #include "net/disk_cache/disk_cache.h" #include "net/http/http_cache_transaction.h" diff --git a/chromium/net/http/http_cache_writers_unittest.cc b/chromium/net/http/http_cache_writers_unittest.cc index 4f96101bd02..02c10ea4189 100644 --- a/chromium/net/http/http_cache_writers_unittest.cc +++ b/chromium/net/http/http_cache_writers_unittest.cc @@ -10,6 +10,7 @@ #include <utility> #include <vector> +#include "base/bind.h" #include "base/run_loop.h" #include "net/http/http_cache.h" #include "net/http/http_cache_transaction.h" diff --git a/chromium/net/http/http_negotiate_auth_system.h b/chromium/net/http/http_negotiate_auth_system.h index 9d3acb0a672..2a9bb0eceb8 100644 --- a/chromium/net/http/http_negotiate_auth_system.h +++ b/chromium/net/http/http_negotiate_auth_system.h @@ -59,10 +59,10 @@ class NET_EXPORT_PRIVATE HttpNegotiateAuthSystem { std::string* auth_token, CompletionOnceCallback callback) = 0; - // Delegation is allowed on the Kerberos ticket. This allows certain servers - // to act as the user, such as an IIS server retrieving data from a - // Kerberized MSSQL server. - virtual void Delegate() = 0; + // Sets the delegation type allowed on the Kerberos ticket. This allows + // certain servers to act as the user, such as an IIS server retrieving data + // from a Kerberized MSSQL server. + virtual void SetDelegation(HttpAuth::DelegationType delegation_type) = 0; }; } // namespace net diff --git a/chromium/net/http/http_network_session.cc b/chromium/net/http/http_network_session.cc index b71a6ebbaa8..2cf4002a052 100644 --- a/chromium/net/http/http_network_session.cc +++ b/chromium/net/http/http_network_session.cc @@ -10,7 +10,6 @@ #include "base/atomic_sequence_num.h" #include "base/compiler_specific.h" -#include "base/debug/stack_trace.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -19,6 +18,7 @@ #include "base/trace_event/memory_dump_request_args.h" #include "base/trace_event/process_memory_dump.h" #include "base/values.h" +#include "net/dns/host_resolver.h" #include "net/http/http_auth_handler_factory.h" #include "net/http/http_response_body_drainer.h" #include "net/http/http_stream_factory.h" @@ -41,12 +41,11 @@ namespace net { namespace { -base::AtomicSequenceNumber g_next_shard_id; - std::unique_ptr<ClientSocketPoolManager> CreateSocketPoolManager( HttpNetworkSession::SocketPoolType pool_type, const HttpNetworkSession::Context& context, - const std::string& ssl_session_cache_shard, + SSLClientSessionCache* ssl_client_session_cache, + SSLClientSessionCache* ssl_client_session_cache_privacy_mode, WebSocketEndpointLockManager* websocket_endpoint_lock_manager) { // TODO(yutak): Differentiate WebSocket pool manager and allow more // simultaneous connections for WebSockets. @@ -58,9 +57,9 @@ std::unique_ptr<ClientSocketPoolManager> CreateSocketPoolManager( context.network_quality_estimator, context.host_resolver, context.cert_verifier, context.channel_id_service, context.transport_security_state, context.cert_transparency_verifier, - context.ct_policy_enforcer, ssl_session_cache_shard, - context.ssl_config_service, websocket_endpoint_lock_manager, - context.proxy_delegate, pool_type); + context.ct_policy_enforcer, ssl_client_session_cache, + ssl_client_session_cache_privacy_mode, context.ssl_config_service, + websocket_endpoint_lock_manager, context.proxy_delegate, pool_type); } } // unnamed namespace @@ -120,6 +119,8 @@ HttpNetworkSession::Params::Params() quic_goaway_sessions_on_ip_change(false), quic_idle_connection_timeout_seconds(kIdleConnectionTimeoutSeconds), quic_reduced_ping_timeout_seconds(quic::kPingTimeoutSecs), + quic_retransmittable_on_wire_timeout_milliseconds( + kDefaultRetransmittableOnWireTimeoutMillisecs), quic_max_time_before_crypto_handshake_seconds( quic::kMaxTimeForCryptoHandshakeSecs), quic_max_idle_time_before_crypto_handshake_seconds( @@ -127,8 +128,9 @@ HttpNetworkSession::Params::Params() quic_migrate_sessions_on_network_change_v2(false), quic_migrate_sessions_early_v2(false), quic_retry_on_alternate_network_before_handshake(false), - quic_race_stale_dns_on_connection(false), - quic_go_away_on_path_degrading(false), + quic_migrate_idle_sessions(false), + quic_idle_session_migration_period(base::TimeDelta::FromSeconds( + kDefaultIdleSessionMigrationPeriodSeconds)), quic_max_time_on_non_default_network( base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs)), quic_max_migrations_to_non_default_network_on_write_error( @@ -137,8 +139,9 @@ HttpNetworkSession::Params::Params() kMaxMigrationsToNonDefaultNetworkOnPathDegrading), quic_allow_server_migration(false), quic_allow_remote_alt_svc(true), + quic_race_stale_dns_on_connection(false), + quic_go_away_on_path_degrading(false), quic_disable_bidirectional_streams(false), - quic_force_hol_blocking(false), quic_race_cert_verification(false), quic_estimate_initial_rtt(false), quic_headers_include_h2_stream_dependency(false), @@ -188,12 +191,15 @@ HttpNetworkSession::HttpNetworkSession(const Params& params, http_server_properties_(context.http_server_properties), cert_verifier_(context.cert_verifier), http_auth_handler_factory_(context.http_auth_handler_factory), + host_resolver_(context.host_resolver), #if BUILDFLAG(ENABLE_REPORTING) reporting_service_(context.reporting_service), network_error_logging_service_(context.network_error_logging_service), #endif proxy_resolution_service_(context.proxy_resolution_service), ssl_config_service_(context.ssl_config_service), + ssl_client_session_cache_(SSLClientSessionCache::Config()), + ssl_client_session_cache_privacy_mode_(SSLClientSessionCache::Config()), push_delegate_(nullptr), quic_stream_factory_( context.net_log, @@ -221,17 +227,20 @@ HttpNetworkSession::HttpNetworkSession(const Params& params, params.mark_quic_broken_when_network_blackholes, params.quic_idle_connection_timeout_seconds, params.quic_reduced_ping_timeout_seconds, + params.quic_retransmittable_on_wire_timeout_milliseconds, params.quic_max_time_before_crypto_handshake_seconds, params.quic_max_idle_time_before_crypto_handshake_seconds, params.quic_migrate_sessions_on_network_change_v2, params.quic_migrate_sessions_early_v2, params.quic_retry_on_alternate_network_before_handshake, - params.quic_race_stale_dns_on_connection, - params.quic_go_away_on_path_degrading, + params.quic_migrate_idle_sessions, + params.quic_idle_session_migration_period, params.quic_max_time_on_non_default_network, params.quic_max_migrations_to_non_default_network_on_write_error, params.quic_max_migrations_to_non_default_network_on_path_degrading, params.quic_allow_server_migration, + params.quic_race_stale_dns_on_connection, + params.quic_go_away_on_path_degrading, params.quic_race_cert_verification, params.quic_estimate_initial_rtt, params.quic_headers_include_h2_stream_dependency, @@ -257,13 +266,13 @@ HttpNetworkSession::HttpNetworkSession(const Params& params, DCHECK(ssl_config_service_); CHECK(http_server_properties_); - const std::string ssl_session_cache_shard = - "http_network_session/" + base::IntToString(g_next_shard_id.GetNext()); normal_socket_pool_manager_ = CreateSocketPoolManager( - NORMAL_SOCKET_POOL, context, ssl_session_cache_shard, + NORMAL_SOCKET_POOL, context, &ssl_client_session_cache_, + &ssl_client_session_cache_privacy_mode_, &websocket_endpoint_lock_manager_); websocket_socket_pool_manager_ = CreateSocketPoolManager( - WEBSOCKET_SOCKET_POOL, context, ssl_session_cache_shard, + WEBSOCKET_SOCKET_POOL, context, &ssl_client_session_cache_, + &ssl_client_session_cache_privacy_mode_, &websocket_endpoint_lock_manager_); if (params_.enable_http2) { @@ -304,35 +313,10 @@ void HttpNetworkSession::RemoveResponseDrainer( response_drainers_.erase(drainer); } -TransportClientSocketPool* HttpNetworkSession::GetTransportSocketPool( - SocketPoolType pool_type) { - return GetSocketPoolManager(pool_type)->GetTransportSocketPool(); -} - -SSLClientSocketPool* HttpNetworkSession::GetSSLSocketPool( - SocketPoolType pool_type) { - return GetSocketPoolManager(pool_type)->GetSSLSocketPool(); -} - -SOCKSClientSocketPool* HttpNetworkSession::GetSocketPoolForSOCKSProxy( - SocketPoolType pool_type, - const ProxyServer& socks_proxy) { - return GetSocketPoolManager(pool_type)->GetSocketPoolForSOCKSProxy( - socks_proxy); -} - -HttpProxyClientSocketPool* HttpNetworkSession::GetSocketPoolForHTTPLikeProxy( - SocketPoolType pool_type, - const ProxyServer& http_proxy) { - return GetSocketPoolManager(pool_type)->GetSocketPoolForHTTPLikeProxy( - http_proxy); -} - -SSLClientSocketPool* HttpNetworkSession::GetSocketPoolForSSLWithProxy( +TransportClientSocketPool* HttpNetworkSession::GetSocketPool( SocketPoolType pool_type, const ProxyServer& proxy_server) { - return GetSocketPoolManager(pool_type)->GetSocketPoolForSSLWithProxy( - proxy_server); + return GetSocketPoolManager(pool_type)->GetSocketPool(proxy_server); } std::unique_ptr<base::Value> HttpNetworkSession::SocketPoolInfoToValue() const { @@ -388,12 +372,13 @@ std::unique_ptr<base::Value> HttpNetworkSession::QuicInfoToValue() const { params_.quic_migrate_sessions_on_network_change_v2); dict->SetBoolean("migrate_sessions_early_v2", params_.quic_migrate_sessions_early_v2); + dict->SetInteger("retransmittable_on_wire_timeout_milliseconds", + params_.quic_retransmittable_on_wire_timeout_milliseconds); dict->SetBoolean("retry_on_alternate_network_before_handshake", params_.quic_retry_on_alternate_network_before_handshake); - dict->SetBoolean("race_stale_dns_on_connection", - params_.quic_race_stale_dns_on_connection); - dict->SetBoolean("go_away_on_path_degrading", - params_.quic_go_away_on_path_degrading); + dict->SetBoolean("migrate_idle_sessions", params_.quic_migrate_idle_sessions); + dict->SetInteger("idle_session_migration_period_seconds", + params_.quic_idle_session_migration_period.InSeconds()); dict->SetInteger("max_time_on_non_default_network_seconds", params_.quic_max_time_on_non_default_network.InSeconds()); dict->SetInteger( @@ -404,8 +389,11 @@ std::unique_ptr<base::Value> HttpNetworkSession::QuicInfoToValue() const { params_.quic_max_migrations_to_non_default_network_on_path_degrading); dict->SetBoolean("allow_server_migration", params_.quic_allow_server_migration); + dict->SetBoolean("race_stale_dns_on_connection", + params_.quic_race_stale_dns_on_connection); + dict->SetBoolean("go_away_on_path_degrading", + params_.quic_go_away_on_path_degrading); dict->SetBoolean("estimate_initial_rtt", params_.quic_estimate_initial_rtt); - dict->SetBoolean("force_hol_blocking", params_.quic_force_hol_blocking); dict->SetBoolean("server_push_cancellation", params_.enable_server_push_cancellation); @@ -490,6 +478,7 @@ void HttpNetworkSession::DumpMemoryStats( } quic_stream_factory_.DumpMemoryStats( pmd, http_network_session_dump->absolute_name()); + ssl_client_session_cache_.DumpMemoryStats(pmd, name); } // Create an empty row under parent's dump so size can be attributed correctly @@ -509,6 +498,11 @@ void HttpNetworkSession::DisableQuic() { params_.enable_quic = false; } +void HttpNetworkSession::ClearSSLSessionCache() { + ssl_client_session_cache_.Flush(); + ssl_client_session_cache_privacy_mode_.Flush(); +} + ClientSocketPoolManager* HttpNetworkSession::GetSocketPoolManager( SocketPoolType pool_type) { switch (pool_type) { diff --git a/chromium/net/http/http_network_session.h b/chromium/net/http/http_network_session.h index 0c42c754de3..3b0bc86a269 100644 --- a/chromium/net/http/http_network_session.h +++ b/chromium/net/http/http_network_session.h @@ -26,7 +26,6 @@ #include "net/base/host_mapping_rules.h" #include "net/base/host_port_pair.h" #include "net/base/net_export.h" -#include "net/dns/host_resolver.h" #include "net/http/http_auth_cache.h" #include "net/http/http_stream_factory.h" #include "net/net_buildflags.h" @@ -35,6 +34,7 @@ #include "net/socket/websocket_endpoint_lock_manager.h" #include "net/spdy/spdy_session_pool.h" #include "net/ssl/ssl_client_auth_cache.h" +#include "net/ssl/ssl_client_session_cache.h" #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" namespace base { @@ -59,7 +59,6 @@ class CTVerifier; class HostResolver; class HttpAuthHandlerFactory; class HttpNetworkSessionPeer; -class HttpProxyClientSocketPool; class HttpResponseBodyDrainer; class HttpServerProperties; class NetLog; @@ -75,8 +74,6 @@ class QuicCryptoClientStreamFactory; class ReportingService; #endif class SocketPerformanceWatcherFactory; -class SOCKSClientSocketPool; -class SSLClientSocketPool; class SSLConfigService; class TransportClientSocketPool; class TransportSecurityState; @@ -177,6 +174,9 @@ class NET_EXPORT HttpNetworkSession { // Specifies the reduced ping timeout subsequent connections should use when // a connection was timed out with open streams. int quic_reduced_ping_timeout_seconds; + // Maximum time that a session can have no retransmittable packets on the + // wire. + int quic_retransmittable_on_wire_timeout_milliseconds; // Maximum time the session can be alive before crypto handshake is // finished. int quic_max_time_before_crypto_handshake_seconds; @@ -192,11 +192,11 @@ class NET_EXPORT HttpNetworkSession { // If true, a new connection may be kicked off on an alternate network when // a connection fails on the default network before handshake is confirmed. bool quic_retry_on_alternate_network_before_handshake; - // If true, the quic stream factory may race connection from stale dns - // result with the original dns resolution - bool quic_race_stale_dns_on_connection; - // If true, the quic session may mark itself as GOAWAY on path degrading. - bool quic_go_away_on_path_degrading; + // If true, an idle session will be migrated within the idle migration + // period. + bool quic_migrate_idle_sessions; + // A session can be migrated if its idle time is within this period. + base::TimeDelta quic_idle_session_migration_period; // Maximum time the session could be on the non-default network before // migrates back to default network. Defaults to // kMaxTimeOnNonDefaultNetwork. @@ -213,10 +213,13 @@ class NET_EXPORT HttpNetworkSession { // If true, allows QUIC to use alternative services with a different // hostname from the origin. bool quic_allow_remote_alt_svc; + // If true, the quic stream factory may race connection from stale dns + // result with the original dns resolution + bool quic_race_stale_dns_on_connection; + // If true, the quic session may mark itself as GOAWAY on path degrading. + bool quic_go_away_on_path_degrading; // If true, bidirectional streams over QUIC will be disabled. bool quic_disable_bidirectional_streams; - // If true, enable force HOL blocking. For measurement purposes. - bool quic_force_hol_blocking; // If true, race cert verification with host resolution. bool quic_race_cert_verification; // If true, estimate the initial RTT for QUIC connections based on network. @@ -292,17 +295,11 @@ class NET_EXPORT HttpNetworkSession { // Removes the drainer from the session. Does not dispose of it. void RemoveResponseDrainer(HttpResponseBodyDrainer* drainer); - TransportClientSocketPool* GetTransportSocketPool(SocketPoolType pool_type); - SSLClientSocketPool* GetSSLSocketPool(SocketPoolType pool_type); - SOCKSClientSocketPool* GetSocketPoolForSOCKSProxy( - SocketPoolType pool_type, - const ProxyServer& socks_proxy); - HttpProxyClientSocketPool* GetSocketPoolForHTTPLikeProxy( - SocketPoolType pool_type, - const ProxyServer& http_proxy); - SSLClientSocketPool* GetSocketPoolForSSLWithProxy( - SocketPoolType pool_type, - const ProxyServer& proxy_server); + // Returns the socket pool of the given type for use with the specified + // ProxyServer. Use ProxyServer::Direct() to get the pool for use with direct + // connections. + TransportClientSocketPool* GetSocketPool(SocketPoolType pool_type, + const ProxyServer& proxy_server); CertVerifier* cert_verifier() { return cert_verifier_; } ProxyResolutionService* proxy_resolution_service() { @@ -326,6 +323,7 @@ class NET_EXPORT HttpNetworkSession { NetLog* net_log() { return net_log_; } + HostResolver* host_resolver() { return host_resolver_; } #if BUILDFLAG(ENABLE_REPORTING) ReportingService* reporting_service() const { return reporting_service_; } NetworkErrorLoggingService* network_error_logging_service() const { @@ -375,6 +373,10 @@ class NET_EXPORT HttpNetworkSession { // Disable QUIC for new streams. void DisableQuic(); + // Clear the SSL session cache. + void ClearSSLSessionCache(); + void ClearSSLSessionCachePrivacyMode(); + private: friend class HttpNetworkSessionPeer; @@ -388,6 +390,7 @@ class NET_EXPORT HttpNetworkSession { HttpServerProperties* const http_server_properties_; CertVerifier* const cert_verifier_; HttpAuthHandlerFactory* const http_auth_handler_factory_; + HostResolver* const host_resolver_; #if BUILDFLAG(ENABLE_REPORTING) ReportingService* const reporting_service_; @@ -398,6 +401,8 @@ class NET_EXPORT HttpNetworkSession { HttpAuthCache http_auth_cache_; SSLClientAuthCache ssl_client_auth_cache_; + SSLClientSessionCache ssl_client_session_cache_; + SSLClientSessionCache ssl_client_session_cache_privacy_mode_; WebSocketEndpointLockManager websocket_endpoint_lock_manager_; std::unique_ptr<ClientSocketPoolManager> normal_socket_pool_manager_; std::unique_ptr<ClientSocketPoolManager> websocket_socket_pool_manager_; diff --git a/chromium/net/http/http_network_session_peer.cc b/chromium/net/http/http_network_session_peer.cc index bfcc592ad2c..c9440d65df8 100644 --- a/chromium/net/http/http_network_session_peer.cc +++ b/chromium/net/http/http_network_session_peer.cc @@ -4,11 +4,8 @@ #include "net/http/http_network_session_peer.h" -#include "net/http/http_proxy_client_socket_pool.h" #include "net/proxy_resolution/proxy_resolution_service.h" #include "net/socket/client_socket_pool_manager.h" -#include "net/socket/socks_client_socket_pool.h" -#include "net/socket/ssl_client_socket_pool.h" #include "net/socket/transport_client_socket_pool.h" namespace net { diff --git a/chromium/net/http/http_network_transaction.cc b/chromium/net/http/http_network_transaction.cc index ce86e621144..359d488a064 100644 --- a/chromium/net/http/http_network_transaction.cc +++ b/chromium/net/http/http_network_transaction.cc @@ -43,7 +43,6 @@ #include "net/http/http_chunked_decoder.h" #include "net/http/http_network_session.h" #include "net/http/http_proxy_client_socket.h" -#include "net/http/http_proxy_client_socket_pool.h" #include "net/http/http_request_headers.h" #include "net/http/http_request_info.h" #include "net/http/http_response_headers.h" @@ -58,7 +57,6 @@ #include "net/log/net_log_event_type.h" #include "net/socket/client_socket_factory.h" #include "net/socket/next_proto.h" -#include "net/socket/socks_client_socket_pool.h" #include "net/socket/transport_client_socket_pool.h" #include "net/spdy/spdy_http_stream.h" #include "net/spdy/spdy_session.h" @@ -130,14 +128,9 @@ HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority, HttpNetworkTransaction::~HttpNetworkTransaction() { #if BUILDFLAG(ENABLE_REPORTING) - // Report a success if we have not already done so. Errors would have been - // reported from DoCallback(), DoReadBodyComplete(), HandleIOError(), or - // DoReadHeadersComplete(). - // Note: This may incorrectly report an error as a success, e.g. if the - // request is cancelled after successfully receiving headers but would - // otherwise have encountered an error on reading the body. - if (headers_valid_ && next_state_ == STATE_NONE) - GenerateNetworkErrorLoggingReport(OK); + // If no error or success report has been generated yet at this point, then + // this network transaction was prematurely cancelled. + GenerateNetworkErrorLoggingReport(ERR_ABORTED); #endif // BUILDFLAG(ENABLE_REPORTING) if (stream_.get()) { // TODO(mbelshe): The stream_ should be able to compute whether or not the @@ -954,11 +947,9 @@ int HttpNetworkTransaction::DoGenerateProxyAuthToken() { return OK; HttpAuth::Target target = HttpAuth::AUTH_PROXY; if (!auth_controllers_[target].get()) - auth_controllers_[target] = - new HttpAuthController(target, - AuthURL(target), - session_->http_auth_cache(), - session_->http_auth_handler_factory()); + auth_controllers_[target] = new HttpAuthController( + target, AuthURL(target), session_->http_auth_cache(), + session_->http_auth_handler_factory(), session_->host_resolver()); return auth_controllers_[target]->MaybeGenerateAuthToken(request_, io_callback_, net_log_); @@ -975,11 +966,9 @@ int HttpNetworkTransaction::DoGenerateServerAuthToken() { next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE; HttpAuth::Target target = HttpAuth::AUTH_SERVER; if (!auth_controllers_[target].get()) { - auth_controllers_[target] = - new HttpAuthController(target, - AuthURL(target), - session_->http_auth_cache(), - session_->http_auth_handler_factory()); + auth_controllers_[target] = new HttpAuthController( + target, AuthURL(target), session_->http_auth_cache(), + session_->http_auth_handler_factory(), session_->host_resolver()); if (request_->load_flags & LOAD_DO_NOT_USE_EMBEDDED_IDENTITY) auth_controllers_[target]->DisableEmbeddedIdentity(); } @@ -1257,12 +1246,15 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { ProcessNetworkErrorLoggingHeader(); // Generate NEL report here if we have to report an HTTP error (4xx or 5xx - // code), or if the response body will not be read. + // code), or if the response body will not be read, or on a redirect. + // Note: This will report a success for a redirect even if an error is + // encountered later while draining the body. int response_code = response_.headers->response_code(); if ((response_code >= 400 && response_code < 600) || response_code == HTTP_NO_CONTENT || response_code == HTTP_RESET_CONTENT || response_code == HTTP_NOT_MODIFIED || request_->method == "HEAD" || - response_.headers->GetContentLength() == 0) { + response_.headers->GetContentLength() == 0 || + response_.headers->IsRedirect(nullptr /* location */)) { GenerateNetworkErrorLoggingReport(OK); } #endif // BUILDFLAG(ENABLE_REPORTING) @@ -1421,6 +1413,11 @@ void HttpNetworkTransaction::ProcessNetworkErrorLoggingHeader() { return; } + // Don't accept NEL headers received via a proxy, because the IP address of + // the destination server is not known. + if (response_.was_fetched_via_proxy) + return; + // Only accept NEL headers on HTTPS connections that have no certificate // errors. if (!response_.ssl_info.is_valid()) { @@ -1463,6 +1460,17 @@ void HttpNetworkTransaction::GenerateNetworkErrorLoggingReport(int rv) { return; } + // Don't report on proxy auth challenges. + if (response_.headers && response_.headers->response_code() == + HTTP_PROXY_AUTHENTICATION_REQUIRED) { + return; + } + + // Don't generate NEL reports if we are behind a proxy, to avoid leaking + // internal network details. + if (response_.was_fetched_via_proxy) + return; + // Ignore errors from non-HTTPS origins. if (!url_.SchemeIsCryptographic()) { NetworkErrorLoggingService::RecordRequestDiscardedForInsecureOrigin(); @@ -1853,15 +1861,7 @@ GURL HttpNetworkTransaction::AuthURL(HttpAuth::Target target) const { } case HttpAuth::AUTH_SERVER: if (ForWebSocketHandshake()) { - const GURL& url = request_->url; - url::Replacements<char> ws_to_http; - if (url.SchemeIs("ws")) { - ws_to_http.SetScheme("http", url::Component(0, 4)); - } else { - DCHECK(url.SchemeIs("wss")); - ws_to_http.SetScheme("https", url::Component(0, 5)); - } - return url.ReplaceComponents(ws_to_http); + return net::ChangeWebSocketSchemeToHttpScheme(request_->url); } return request_->url; default: diff --git a/chromium/net/http/http_network_transaction_unittest.cc b/chromium/net/http/http_network_transaction_unittest.cc index 0a9d165ded9..27455857f08 100644 --- a/chromium/net/http/http_network_transaction_unittest.cc +++ b/chromium/net/http/http_network_transaction_unittest.cc @@ -14,6 +14,7 @@ #include <utility> #include <vector> +#include "base/bind.h" #include "base/compiler_specific.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -21,12 +22,14 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "base/run_loop.h" #include "base/stl_util.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_task_environment.h" #include "base/test/simple_test_clock.h" #include "base/test/simple_test_tick_clock.h" #include "base/test/test_file_util.h" @@ -35,6 +38,8 @@ #include "net/base/chunked_upload_data_stream.h" #include "net/base/completion_once_callback.h" #include "net/base/elements_upload_data_stream.h" +#include "net/base/host_port_pair.h" +#include "net/base/ip_endpoint.h" #include "net/base/load_timing_info.h" #include "net/base/load_timing_info_test_util.h" #include "net/base/net_errors.h" @@ -47,7 +52,6 @@ #include "net/base/upload_file_element_reader.h" #include "net/cert/cert_status_flags.h" #include "net/cert/mock_cert_verifier.h" -#include "net/dns/host_cache.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_auth_handler_digest.h" @@ -83,10 +87,12 @@ #include "net/socket/next_proto.h" #include "net/socket/socket_tag.h" #include "net/socket/socket_test_util.h" +#include "net/socket/socks_connect_job.h" #include "net/socket/ssl_client_socket.h" #include "net/spdy/spdy_session.h" #include "net/spdy/spdy_session_pool.h" #include "net/spdy/spdy_test_util_common.h" +#include "net/ssl/client_cert_identity_test_util.h" #include "net/ssl/default_channel_id_store.h" #include "net/ssl/ssl_cert_request_info.h" #include "net/ssl/ssl_config_service.h" @@ -147,17 +153,16 @@ const char kAlternativeServiceHttpHeader[] = "Alt-Svc: h2=\"mail.example.org:443\"\r\n"; int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) { - return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL) - ->IdleSocketCount(); -} - -int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) { - return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL) + return session + ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL, + ProxyServer::Direct()) ->IdleSocketCount(); } bool IsTransportSocketPoolStalled(HttpNetworkSession* session) { - return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL) + return session + ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL, + ProxyServer::Direct()) ->IsStalled(); } @@ -470,8 +475,8 @@ class HttpNetworkTransactionTest : public PlatformTest, } out.status_line = response->headers->GetStatusLine(); - EXPECT_EQ("127.0.0.1", response->socket_address.host()); - EXPECT_EQ(80, response->socket_address.port()); + EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort()); + EXPECT_EQ(80, response->remote_endpoint.port()); bool got_endpoint = trans.GetRemoteEndpoint(&out.remote_endpoint_after_start); @@ -646,14 +651,16 @@ class CaptureGroupNameSocketPool : public ParentPool { bool socket_requested() const { return socket_requested_; } - int RequestSocket(const std::string& group_name, - const void* socket_params, - RequestPriority priority, - const SocketTag& socket_tag, - ClientSocketPool::RespectLimits respect_limits, - ClientSocketHandle* handle, - CompletionOnceCallback callback, - const NetLogWithSource& net_log) override { + int RequestSocket( + const std::string& group_name, + const void* socket_params, + RequestPriority priority, + const SocketTag& socket_tag, + ClientSocketPool::RespectLimits respect_limits, + ClientSocketHandle* handle, + CompletionOnceCallback callback, + const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback, + const NetLogWithSource& net_log) override { last_group_name_ = group_name; socket_requested_ = true; return ERR_IO_PENDING; @@ -666,7 +673,7 @@ class CaptureGroupNameSocketPool : public ParentPool { void CloseIdleSockets() override {} void CloseIdleSocketsInGroup(const std::string& group_name) override {} int IdleSocketCount() const override { return 0; } - int IdleSocketCountInGroup(const std::string& group_name) const override { + size_t IdleSocketCountInGroup(const std::string& group_name) const override { return 0; } LoadState GetLoadState(const std::string& group_name, @@ -681,44 +688,28 @@ class CaptureGroupNameSocketPool : public ParentPool { typedef CaptureGroupNameSocketPool<TransportClientSocketPool> CaptureGroupNameTransportSocketPool; -typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool> -CaptureGroupNameHttpProxySocketPool; -typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool> -CaptureGroupNameSOCKSSocketPool; -typedef CaptureGroupNameSocketPool<SSLClientSocketPool> -CaptureGroupNameSSLSocketPool; template <typename ParentPool> CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool( HostResolver* host_resolver, CertVerifier* /* cert_verifier */) - : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {} - -template <> -CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool( - HostResolver* /* host_resolver */, - CertVerifier* /* cert_verifier */) - : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL, NULL) {} - -template <> -CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool( - HostResolver* /* host_resolver */, - CertVerifier* cert_verifier) - : SSLClientSocketPool(0, - 0, - cert_verifier, - NULL, - NULL, - NULL, - NULL, - std::string(), - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL) {} + : ParentPool(0, + 0, + base::TimeDelta(), + NULL, + host_resolver, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL) {} //----------------------------------------------------------------------------- @@ -734,6 +725,16 @@ bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) { return true; } +bool CheckBasicSecureServerAuth(const AuthChallengeInfo* auth_challenge) { + if (!auth_challenge) + return false; + EXPECT_FALSE(auth_challenge->is_proxy); + EXPECT_EQ("https://www.example.org", auth_challenge->challenger.Serialize()); + EXPECT_EQ("MyRealm1", auth_challenge->realm); + EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme); + return true; +} + bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) { if (!auth_challenge) return false; @@ -1828,7 +1829,7 @@ void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest( // Wait for the preconnect to complete. // TODO(davidben): Some way to wait for an idle socket count might be handy. base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); + EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); // Make the request. TestCompletionCallback callback; @@ -5122,7 +5123,7 @@ TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) { // pass. EXPECT_EQ(test_case.expected_idle_socks4_sockets, session - ->GetSocketPoolForSOCKSProxy( + ->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer(ProxyServer::SCHEME_SOCKS4, SameProxyWithDifferentSchemesProxyResolver:: @@ -5130,7 +5131,7 @@ TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) { ->IdleSocketCount()); EXPECT_EQ(test_case.expected_idle_socks5_sockets, session - ->GetSocketPoolForSOCKSProxy( + ->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer(ProxyServer::SCHEME_SOCKS5, SameProxyWithDifferentSchemesProxyResolver:: @@ -5138,7 +5139,7 @@ TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) { ->IdleSocketCount()); EXPECT_EQ(test_case.expected_idle_http_sockets, session - ->GetSocketPoolForHTTPLikeProxy( + ->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer(ProxyServer::SCHEME_HTTP, SameProxyWithDifferentSchemesProxyResolver:: @@ -5146,7 +5147,7 @@ TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) { ->IdleSocketCount()); EXPECT_EQ(test_case.expected_idle_https_sockets, session - ->GetSocketPoolForHTTPLikeProxy( + ->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer(ProxyServer::SCHEME_HTTPS, SameProxyWithDifferentSchemesProxyResolver:: @@ -5154,7 +5155,7 @@ TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) { ->IdleSocketCount()); EXPECT_EQ(test_case.expected_idle_trusted_https_sockets, session - ->GetSocketPoolForHTTPLikeProxy( + ->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer(ProxyServer::SCHEME_HTTPS, SameProxyWithDifferentSchemesProxyResolver:: @@ -8025,7 +8026,7 @@ TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) { base::RunLoop().RunUntilIdle(); // We now check to make sure the socket was added back to the pool. - EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); + EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); } // Grab a SSL socket, use it, and put it back into the pool. Then, reuse it @@ -8090,7 +8091,7 @@ TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) { base::RunLoop().RunUntilIdle(); // We now check to make sure the socket was added back to the pool. - EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); + EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); // Now start the second transaction, which should reuse the previous socket. @@ -8118,7 +8119,7 @@ TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) { base::RunLoop().RunUntilIdle(); // We now check to make sure the socket was added back to the pool. - EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); + EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); } // Grab a socket, use it, and put it back into the pool. Then, make @@ -8298,7 +8299,7 @@ TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) { std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get())); + EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); int rv = trans.Start(&request, callback.callback(), NetLogWithSource()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -8314,7 +8315,7 @@ TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) { base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get())); + EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); std::string response_data; rv = ReadTransaction(&trans, &response_data); @@ -8326,14 +8327,14 @@ TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) { base::RunLoop().RunUntilIdle(); // We now check to make sure the socket was added back to the pool. - EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get())); + EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); // Make memory notification once again and ensure idle socket is closed. base::MemoryPressureListener::NotifyMemoryPressure( base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get())); + EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); } // Make sure that we recycle a socket after a zero-length response. @@ -9522,6 +9523,10 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) { TestNetLog net_log; session_deps_.net_log = &net_log; + base::TimeTicks start_time = base::TimeTicks::Now(); + const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4); + session_deps_.host_resolver->set_ondemand_mode(true); + HttpRequestInfo request; request.load_flags = LOAD_MAIN_FRAME_DEPRECATED; request.method = "GET"; @@ -9530,19 +9535,21 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) { net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); MockWrite data_writes[] = { - MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + 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("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), + // Pause on first read. + MockRead(ASYNC, ERR_IO_PENDING, 1), + MockRead(ASYNC, 2, "HTTP/1.1 302 Redirect\r\n"), + MockRead(ASYNC, 3, "Location: http://login.example.com/\r\n"), + MockRead(ASYNC, 4, "Content-Length: 0\r\n\r\n"), }; - StaticSocketDataProvider data(data_reads, data_writes); + SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes); SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy session_deps_.socket_factory->AddSocketDataProvider(&data); @@ -9555,6 +9562,21 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) { int rv = trans.Start(&request, callback.callback(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests()); + + // Host resolution takes |kTimeIncrement|. + FastForwardBy(kTimeIncrement); + // Resolving the current request with |ResolveNow| will cause the pending + // request to instantly complete, and the async connect will start as well. + session_deps_.host_resolver->ResolveOnlyRequestNow(); + + // Connecting takes |kTimeIncrement|. + FastForwardBy(kTimeIncrement); + data.RunUntilPaused(); + + // The server takes |kTimeIncrement| to respond. + FastForwardBy(kTimeIncrement); + data.Resume(); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); @@ -9567,24 +9589,29 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) { EXPECT_TRUE(response->headers->IsRedirect(&url)); EXPECT_EQ("http://login.example.com/", url); - // 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::OnHttpsProxyTunnelResponseRedirect. LoadTimingInfo load_timing_info; EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); EXPECT_FALSE(load_timing_info.socket_reused); EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id); - EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null()); - EXPECT_LE(load_timing_info.proxy_resolve_start, - load_timing_info.proxy_resolve_end); - EXPECT_LE(load_timing_info.proxy_resolve_end, - load_timing_info.connect_timing.connect_start); - ExpectConnectTimingHasTimes( - load_timing_info.connect_timing, - CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES); + // In the case of redirects from proxies, just as with all responses from + // proxies, DNS and SSL times reflect timing to look up the destination's + // name, and negotiate an SSL connection to it (Neither of which are done in + // this case), which the DNS and SSL times for the proxy are all included in + // connect_start / connect_end. See + // HttpNetworkTransaction::OnHttpsProxyTunnelResponseRedirect + + EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null()); + EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null()); + EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null()); + EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null()); + + EXPECT_EQ(start_time, load_timing_info.proxy_resolve_start); + EXPECT_EQ(start_time, load_timing_info.proxy_resolve_end); + EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start); + EXPECT_EQ(start_time + 3 * kTimeIncrement, + load_timing_info.connect_timing.connect_end); EXPECT_TRUE(load_timing_info.send_start.is_null()); EXPECT_TRUE(load_timing_info.send_end.is_null()); @@ -9608,19 +9635,19 @@ TEST_F(HttpNetworkTransactionTest, net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); MockWrite data_writes[] = { - MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + 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("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), + 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"), }; - StaticSocketDataProvider data(data_reads, data_writes); + SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes); SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy session_deps_.socket_factory->AddSocketDataProvider(&data); @@ -9701,6 +9728,12 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) { base::HistogramTester histograms; session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); + TestNetLog net_log; + session_deps_.net_log = &net_log; + + base::TimeTicks start_time = base::TimeTicks::Now(); + const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4); + session_deps_.host_resolver->set_ondemand_mode(true); HttpRequestInfo request; request.method = "GET"; @@ -9715,7 +9748,7 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) { spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL)); MockWrite data_writes[] = { CreateMockWrite(conn, 0, SYNCHRONOUS), - CreateMockWrite(goaway, 2, SYNCHRONOUS), + CreateMockWrite(goaway, 3, SYNCHRONOUS), }; static const char* const kExtraHeaders[] = { @@ -9725,10 +9758,12 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) { spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError( "302", kExtraHeaders, base::size(kExtraHeaders) / 2, 1)); MockRead data_reads[] = { - CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF + // Pause on first read. + MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2), + MockRead(ASYNC, 0, 4), // EOF }; - SequencedSocketData data(data_reads, data_writes); + SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes); SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy proxy_ssl.next_proto = kProtoHTTP2; @@ -9742,7 +9777,20 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) { int rv = trans.Start(&request, callback.callback(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests()); + + // Host resolution takes |kTimeIncrement|. + FastForwardBy(kTimeIncrement); + // Resolving the current request with |ResolveNow| will cause the pending + // request to instantly complete, and the async connect will start as well. + session_deps_.host_resolver->ResolveOnlyRequestNow(); + + // Connecting takes |kTimeIncrement|. + FastForwardBy(kTimeIncrement); + data.RunUntilPaused(); + FastForwardBy(kTimeIncrement); + data.Resume(); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); const HttpResponseInfo* response = trans.GetResponseInfo(); @@ -9754,6 +9802,36 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) { EXPECT_TRUE(response->headers->IsRedirect(&url)); EXPECT_EQ("http://login.example.com/", url); + LoadTimingInfo load_timing_info; + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); + + EXPECT_FALSE(load_timing_info.socket_reused); + EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id); + + // No proxy resolution times, since there's no PAC script. + EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); + EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); + + // In the case of redirects from proxies, just as with all responses from + // proxies, DNS and SSL times reflect timing to look up the destination's + // name, and negotiate an SSL connection to it (Neither of which are done in + // this case), which the DNS and SSL times for the proxy are all included in + // connect_start / connect_end. See + // HttpNetworkTransaction::OnHttpsProxyTunnelResponseRedirect. + + EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null()); + EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null()); + EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null()); + EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null()); + + EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start); + EXPECT_EQ(start_time + 3 * kTimeIncrement, + load_timing_info.connect_timing.connect_end); + + EXPECT_TRUE(load_timing_info.send_start.is_null()); + EXPECT_TRUE(load_timing_info.send_end.is_null()); + EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); + histograms.ExpectUniqueSample( "Net.Proxy.RedirectDuringConnect", HttpNetworkTransaction::kMainFrameByExplicitProxy, 1); @@ -11178,27 +11256,16 @@ TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) { HttpNetworkSessionPeer peer(session.get()); CaptureGroupNameTransportSocketPool* transport_conn_pool = new CaptureGroupNameTransportSocketPool(nullptr, nullptr); - CaptureGroupNameSSLSocketPool* ssl_conn_pool = - new CaptureGroupNameSSLSocketPool(nullptr, nullptr); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetTransportSocketPool(transport_conn_pool); - mock_pool_manager->SetSSLSocketPool(ssl_conn_pool); + mock_pool_manager->SetSocketPool(ProxyServer::Direct(), + base::WrapUnique(transport_conn_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); EXPECT_EQ(ERR_IO_PENDING, GroupNameTransactionHelper(tests[i].url, session.get())); - if (tests[i].ssl) { - EXPECT_EQ(tests[i].expected_group_name, - ssl_conn_pool->last_group_name_received()); - } else { - EXPECT_EQ(tests[i].expected_group_name, - transport_conn_pool->last_group_name_received()); - } - // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|. - EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested()); - // When SSL proxy is not in use, socket must be requested from - // |transport_conn_pool|. - EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested()); + EXPECT_EQ(tests[i].expected_group_name, + transport_conn_pool->last_group_name_received()); + EXPECT_TRUE(transport_conn_pool->socket_requested()); } } @@ -11237,26 +11304,17 @@ TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) { ProxyServer proxy_server(ProxyServer::SCHEME_HTTP, HostPortPair("http_proxy", 80)); - CaptureGroupNameHttpProxySocketPool* http_proxy_pool = - new CaptureGroupNameHttpProxySocketPool(NULL, NULL); - CaptureGroupNameSSLSocketPool* ssl_conn_pool = - new CaptureGroupNameSSLSocketPool(NULL, NULL); + CaptureGroupNameTransportSocketPool* http_proxy_pool = + new CaptureGroupNameTransportSocketPool(NULL, NULL); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetSocketPoolForHTTPProxy( - proxy_server, base::WrapUnique(http_proxy_pool)); - mock_pool_manager->SetSocketPoolForSSLWithProxy( - proxy_server, base::WrapUnique(ssl_conn_pool)); + mock_pool_manager->SetSocketPool(proxy_server, + base::WrapUnique(http_proxy_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); EXPECT_EQ(ERR_IO_PENDING, GroupNameTransactionHelper(tests[i].url, session.get())); - if (tests[i].ssl) { - EXPECT_EQ(tests[i].expected_group_name, - ssl_conn_pool->last_group_name_received()); - } else { - EXPECT_EQ(tests[i].expected_group_name, - http_proxy_pool->last_group_name_received()); - } + EXPECT_EQ(tests[i].expected_group_name, + http_proxy_pool->last_group_name_received()); } } @@ -11309,27 +11367,19 @@ TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) { ProxyServer proxy_server( ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP)); ASSERT_TRUE(proxy_server.is_valid()); - CaptureGroupNameSOCKSSocketPool* socks_conn_pool = - new CaptureGroupNameSOCKSSocketPool(NULL, NULL); - CaptureGroupNameSSLSocketPool* ssl_conn_pool = - new CaptureGroupNameSSLSocketPool(NULL, NULL); + CaptureGroupNameTransportSocketPool* socks_conn_pool = + new CaptureGroupNameTransportSocketPool(NULL, NULL); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetSocketPoolForSOCKSProxy( - proxy_server, base::WrapUnique(socks_conn_pool)); - mock_pool_manager->SetSocketPoolForSSLWithProxy( - proxy_server, base::WrapUnique(ssl_conn_pool)); + mock_pool_manager->SetSocketPool(proxy_server, + base::WrapUnique(socks_conn_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); EXPECT_EQ(ERR_IO_PENDING, GroupNameTransactionHelper(tests[i].url, session.get())); - if (tests[i].ssl) - EXPECT_EQ(tests[i].expected_group_name, - ssl_conn_pool->last_group_name_received()); - else - EXPECT_EQ(tests[i].expected_group_name, - socks_conn_pool->last_group_name_received()); + EXPECT_EQ(tests[i].expected_group_name, + socks_conn_pool->last_group_name_received()); } } @@ -11376,26 +11426,10 @@ TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) { HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Warm up the host cache so it has an entry for "www.example.org". - AddressList addrlist; - TestCompletionCallback callback; - std::unique_ptr<HostResolver::Request> request1; - int rv = session_deps_.host_resolver->Resolve( - HostResolver::RequestInfo(HostPortPair("www.example.org", 80)), - DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1, - NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - rv = callback.WaitForResult(); + int rv = session_deps_.host_resolver->LoadIntoCache( + HostPortPair("www.example.org", 80), base::nullopt); EXPECT_THAT(rv, IsOk()); - // Verify that it was added to host cache, by doing a subsequent async lookup - // and confirming it completes synchronously. - std::unique_ptr<HostResolver::Request> request2; - rv = session_deps_.host_resolver->Resolve( - HostResolver::RequestInfo(HostPortPair("www.example.org", 80)), - DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2, - NetLogWithSource()); - ASSERT_THAT(rv, IsOk()); - // Inject a failure the next time that "www.example.org" is resolved. This way // we can tell if the next lookup hit the cache, or the "network". // (cache --> success, "network" --> failure). @@ -11408,6 +11442,7 @@ TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) { session_deps_.socket_factory->AddSocketDataProvider(&data); // Run the request. + TestCompletionCallback callback; rv = trans.Start(&request_info, callback.callback(), NetLogWithSource()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -13470,18 +13505,15 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { // and TestRound's created with the default constructor should not be used. struct TestRound { TestRound() - : expected_rv(ERR_UNEXPECTED), - extra_write(NULL), - extra_read(NULL) { - } - TestRound(const MockWrite& write_arg, const MockRead& read_arg, + : expected_rv(ERR_UNEXPECTED), extra_write(NULL), extra_read(NULL) {} + TestRound(const MockWrite& write_arg, + const MockRead& read_arg, int expected_rv_arg) : write(write_arg), read(read_arg), expected_rv(expected_rv_arg), extra_write(NULL), - extra_read(NULL) { - } + extra_read(NULL) {} TestRound(const MockWrite& write_arg, const MockRead& read_arg, int expected_rv_arg, const MockWrite* extra_write_arg, const MockRead* extra_read_arg) @@ -14349,12 +14381,23 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { // each round of multi-round authentication. HttpNetworkSessionPeer session_peer(session.get()); TransportClientSocketPool* transport_pool = new TransportClientSocketPool( - 50, // Max sockets for pool - 1, // Max sockets per group - session_deps_.host_resolver.get(), session_deps_.socket_factory.get(), - NULL, session_deps_.net_log); + 50, // Max sockets for pool + 1, // Max sockets per group + base::TimeDelta::FromSeconds(10), // unused_idle_socket_timeout + session_deps_.socket_factory.get(), session_deps_.host_resolver.get(), + nullptr /* proxy_delegate */, session_deps_.cert_verifier.get(), + session_deps_.channel_id_service.get(), + session_deps_.transport_security_state.get(), + session_deps_.cert_transparency_verifier.get(), + session_deps_.ct_policy_enforcer.get(), + nullptr /* ssl_client_session_cache */, + nullptr /* ssl_client_session_cache_privacy_mode */, + session_deps_.ssl_config_service.get(), + nullptr /* socket_performance_watcher_factory */, + nullptr /* network_quality_estimator */, session_deps_.net_log); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetTransportSocketPool(transport_pool); + mock_pool_manager->SetSocketPool(ProxyServer::Direct(), + base::WrapUnique(transport_pool)); session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); @@ -14420,7 +14463,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->auth_challenge); - EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); + EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN, auth_handler->state()); @@ -14445,7 +14488,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); - EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); + EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN, auth_handler->state()); @@ -14458,7 +14501,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); - EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); + EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN, auth_handler->state()); @@ -14471,7 +14514,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); - EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); + EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real // auth handler should transition to a DONE state in concert with the remote @@ -14491,7 +14534,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { EXPECT_EQ(0, rv); // There are still 0 idle sockets, since the trans_compete transaction // will be handed it immediately after trans releases it to the group. - EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); + EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); // The competing request can now finish. Wait for the headers and then // read the body. @@ -14505,7 +14548,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { EXPECT_EQ(0, rv); // Finally, the socket is released to the group. - EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup)); + EXPECT_EQ(1u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); } // This tests the case that a request is issued via http instead of spdy after @@ -15467,15 +15510,8 @@ TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) { EXPECT_EQ("hello!", response_data); // Preload mail.example.com into HostCache. - HostPortPair host_port("mail.example.com", 443); - HostResolver::RequestInfo resolve_info(host_port); - AddressList ignored; - std::unique_ptr<HostResolver::Request> request; - rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY, - &ignored, callback.callback(), - &request, NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - rv = callback.WaitForResult(); + rv = session_deps_.host_resolver->LoadIntoCache( + HostPortPair("mail.example.com", 443), base::nullopt); EXPECT_THAT(rv, IsOk()); HttpRequestInfo request2; @@ -15646,16 +15682,8 @@ TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) { AddSSLSocketData(); // Preload mail.example.org into HostCache. - HostPortPair host_port("mail.example.org", 443); - HostResolver::RequestInfo resolve_info(host_port); - AddressList ignored; - std::unique_ptr<HostResolver::Request> request; - TestCompletionCallback callback; - int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY, - &ignored, callback.callback(), - &request, NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - rv = callback.WaitForResult(); + int rv = session_deps_.host_resolver->LoadIntoCache( + HostPortPair("mail.example.com", 443), base::nullopt); EXPECT_THAT(rv, IsOk()); HttpRequestInfo request1; @@ -15666,6 +15694,7 @@ TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) { net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); + TestCompletionCallback callback; rv = trans1.Start(&request1, callback.callback(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -15779,16 +15808,8 @@ TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) { AddSSLSocketData(); // Preload mail.example.org into HostCache. - HostPortPair host_port("mail.example.org", 443); - HostResolver::RequestInfo resolve_info(host_port); - AddressList ignored; - std::unique_ptr<HostResolver::Request> request; - TestCompletionCallback callback; - int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY, - &ignored, callback.callback(), - &request, NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - rv = callback.WaitForResult(); + int rv = session_deps_.host_resolver->LoadIntoCache( + HostPortPair("mail.example.com", 443), base::nullopt); EXPECT_THAT(rv, IsOk()); HttpRequestInfo request1; @@ -15799,6 +15820,7 @@ TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) { net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); + TestCompletionCallback callback; rv = trans1.Start(&request1, callback.callback(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -15841,30 +15863,11 @@ TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) { EXPECT_EQ("hello!", response_data); } -class OneTimeCachingHostResolver : public MockHostResolverBase { - public: - explicit OneTimeCachingHostResolver(const HostPortPair& host_port) - : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {} - ~OneTimeCachingHostResolver() override = default; - - int ResolveFromCache(const RequestInfo& info, - AddressList* addresses, - const NetLogWithSource& net_log) override { - int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log); - if (rv == OK && info.host_port_pair().Equals(host_port_)) - GetHostCache()->clear(); - return rv; - } - - private: - const HostPortPair host_port_; -}; - TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingWithHostCacheExpiration) { - // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver. - session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>( - HostPortPair("mail.example.com", 443)); + // Set up HostResolver to invalidate cached entries after 1 cached resolve. + session_deps_.host_resolver = + std::make_unique<MockCachingHostResolver>(1 /* cache_invalidation_num */); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); AddSSLSocketData(); @@ -15919,14 +15922,8 @@ TEST_F(HttpNetworkTransactionTest, EXPECT_EQ("hello!", response_data); // Preload cache entries into HostCache. - HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443)); - AddressList ignored; - std::unique_ptr<HostResolver::Request> request; - rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY, - &ignored, callback.callback(), - &request, NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - rv = callback.WaitForResult(); + rv = session_deps_.host_resolver->LoadIntoCache( + HostPortPair("mail.example.com", 443), base::nullopt); EXPECT_THAT(rv, IsOk()); HttpRequestInfo request2; @@ -17128,7 +17125,7 @@ TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) { // The SSL socket should automatically be closed, so the HTTP request can // start. - EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get())); + EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); ASSERT_FALSE(IsTransportSocketPoolStalled(session.get())); // The HTTP request can now complete. @@ -17192,7 +17189,7 @@ TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) { // cancelled when a normal transaction is cancelled. HttpStreamFactory* http_stream_factory = session->http_stream_factory(); http_stream_factory->PreconnectStreams(1, ssl_request); - EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get())); + EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); // Start the HTTP request. Pool should stall. TestCompletionCallback http_callback; @@ -18261,6 +18258,11 @@ class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest { request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + MockWrite data_writes[] = { + MockWrite("GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n\r\n"), + }; MockRead data_reads[] = { MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, " @@ -18270,11 +18272,6 @@ class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest { MockRead("hello world"), MockRead(SYNCHRONOUS, OK), }; - MockWrite data_writes[] = { - MockWrite("GET / HTTP/1.1\r\n" - "Host: www.example.org\r\n" - "Connection: keep-alive\r\n\r\n"), - }; StaticSocketDataProvider reads(data_reads, data_writes); session_deps_.socket_factory->AddSocketDataProvider(&reads); @@ -18389,13 +18386,6 @@ class HttpNetworkTransactionNetworkErrorLoggingTest // Makes an HTTPS request that should install a valid NEL policy. void RequestPolicy(CertStatus cert_status = 0) { std::string extra_header_string = extra_headers_.ToString(); - MockRead data_reads[] = { - MockRead("HTTP/1.0 200 OK\r\n"), - MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"), - MockRead("\r\n"), - MockRead("hello world"), - MockRead(SYNCHRONOUS, OK), - }; MockWrite data_writes[] = { MockWrite("GET / HTTP/1.1\r\n" "Host: www.example.org\r\n" @@ -18403,6 +18393,13 @@ class HttpNetworkTransactionNetworkErrorLoggingTest MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()), }; + MockRead data_reads[] = { + MockRead("HTTP/1.0 200 OK\r\n"), + MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"), + MockRead("\r\n"), + MockRead("hello world"), + MockRead(SYNCHRONOUS, OK), + }; StaticSocketDataProvider reads(data_reads, data_writes); session_deps_.socket_factory->AddSocketDataProvider(&reads); @@ -18480,6 +18477,70 @@ TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1); } +// Don't set NEL policies received on a proxied connection. +TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, + DontProcessNelHeaderProxy) { + session_deps_.proxy_resolution_service = + ProxyResolutionService::CreateFixedFromPacResult( + "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); + BoundTestNetLog log; + session_deps_.net_log = log.bound().net_log(); + std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("https://www.example.org/"); + request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + + // Since we have proxy, should try to establish tunnel. + MockWrite data_writes1[] = { + 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"), + + MockWrite("GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n\r\n"), + }; + + MockRead data_reads1[] = { + MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), + + MockRead("HTTP/1.1 200 OK\r\n"), + MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"), + MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), + MockRead("Content-Length: 100\r\n\r\n"), + MockRead(SYNCHRONOUS, OK), + }; + + StaticSocketDataProvider data1(data_reads1, data_writes1); + session_deps_.socket_factory->AddSocketDataProvider(&data1); + SSLSocketDataProvider ssl(ASYNC, OK); + ssl.ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"); + ASSERT_TRUE(ssl.ssl_info.cert); + ssl.ssl_info.cert_status = 0; + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); + + TestCompletionCallback callback1; + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); + + int rv = trans.Start(&request, callback1.callback(), log.bound()); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + rv = callback1.WaitForResult(); + EXPECT_THAT(rv, IsOk()); + + const HttpResponseInfo* response = trans.GetResponseInfo(); + ASSERT_TRUE(response); + EXPECT_EQ(200, response->headers->response_code()); + EXPECT_TRUE(response->was_fetched_via_proxy); + + // No NEL header was set. + EXPECT_EQ(0u, network_error_logging_service()->headers().size()); +} + TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) { RequestPolicy(); ASSERT_EQ(1u, network_error_logging_service()->headers().size()); @@ -18557,18 +18618,18 @@ TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportReadBodyError) { std::string extra_header_string = extra_headers_.ToString(); - MockRead data_reads[] = { - MockRead("HTTP/1.0 200 OK\r\n"), - MockRead("Content-Length: 100\r\n\r\n"), // wrong content length - MockRead("hello world"), - MockRead(SYNCHRONOUS, OK), - }; MockWrite data_writes[] = { MockWrite("GET / HTTP/1.1\r\n" "Host: www.example.org\r\n" "Connection: keep-alive\r\n"), MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()), }; + MockRead data_reads[] = { + MockRead("HTTP/1.0 200 OK\r\n"), + MockRead("Content-Length: 100\r\n\r\n"), // wrong content length + MockRead("hello world"), + MockRead(SYNCHRONOUS, OK), + }; StaticSocketDataProvider reads(data_reads, data_writes); session_deps_.socket_factory->AddSocketDataProvider(&reads); @@ -18611,18 +18672,18 @@ TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportReadBodyErrorAsync) { std::string extra_header_string = extra_headers_.ToString(); - MockRead data_reads[] = { - MockRead("HTTP/1.0 200 OK\r\n"), - MockRead("Content-Length: 100\r\n\r\n"), // wrong content length - MockRead("hello world"), - MockRead(ASYNC, OK), - }; MockWrite data_writes[] = { MockWrite("GET / HTTP/1.1\r\n" "Host: www.example.org\r\n" "Connection: keep-alive\r\n"), MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()), }; + MockRead data_reads[] = { + MockRead("HTTP/1.0 200 OK\r\n"), + MockRead("Content-Length: 100\r\n\r\n"), // wrong content length + MockRead("hello world"), + MockRead(ASYNC, OK), + }; StaticSocketDataProvider reads(data_reads, data_writes); session_deps_.socket_factory->AddSocketDataProvider(&reads); @@ -19091,15 +19152,9 @@ TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, AddSSLSocketData(); // Preload mail.example.org into HostCache. - HostPortPair host_port("mail.example.org", 443); - HostResolver::RequestInfo resolve_info(host_port); - AddressList ignored; - std::unique_ptr<HostResolver::Request> request; - TestCompletionCallback callback; - int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY, - &ignored, callback.callback(), - &request, NetLogWithSource()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); + int rv = session_deps_.host_resolver->LoadIntoCache( + HostPortPair("mail.example.com", 443), base::nullopt); + EXPECT_THAT(rv, IsOk()); HttpRequestInfo request1; request1.method = "GET"; @@ -19110,6 +19165,7 @@ TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, auto trans1 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + TestCompletionCallback callback; rv = trans1->Start(&request1, callback.callback(), NetLogWithSource()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -19193,6 +19249,67 @@ TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, EXPECT_EQ(0, error3.reporting_upload_depth); } +TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, + CreateReportCancelAfterStart) { + StaticSocketDataProvider data; + data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); + session_deps_.socket_factory->AddSocketDataProvider(&data); + + TestCompletionCallback callback; + auto session = CreateSession(&session_deps_); + auto trans = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + int rv = trans->Start(&request_, callback.callback(), NetLogWithSource()); + EXPECT_EQ(rv, ERR_IO_PENDING); + + // Cancel after start. + trans.reset(); + + ASSERT_EQ(1u, network_error_logging_service()->errors().size()); + CheckReport(0 /* index */, 0 /* status_code */, ERR_ABORTED, + IPAddress() /* server_ip */); +} + +TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, + CreateReportCancelBeforeReadingBody) { + std::string extra_header_string = extra_headers_.ToString(); + MockWrite data_writes[] = { + MockWrite("GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n"), + MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()), + }; + MockRead data_reads[] = { + MockRead("HTTP/1.0 200 OK\r\n"), + MockRead("Content-Length: 100\r\n\r\n"), // Body is never read. + }; + + StaticSocketDataProvider data(data_reads, data_writes); + session_deps_.socket_factory->AddSocketDataProvider(&data); + + SSLSocketDataProvider ssl(ASYNC, OK); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); + + TestCompletionCallback callback; + auto session = CreateSession(&session_deps_); + auto trans = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + int rv = trans->Start(&request_, callback.callback(), NetLogWithSource()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + + const HttpResponseInfo* response = trans->GetResponseInfo(); + ASSERT_TRUE(response); + + EXPECT_TRUE(response->headers); + EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); + + // Cancel before reading the body. + trans.reset(); + + ASSERT_EQ(1u, network_error_logging_service()->errors().size()); + CheckReport(0 /* index */, 200 /* status_code */, ERR_ABORTED); +} + TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) { base::HistogramTester histograms; RequestPolicy(); @@ -19213,8 +19330,8 @@ TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) { MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()), }; - StaticSocketDataProvider reads(data_reads, data_writes); - session_deps_.socket_factory->AddSocketDataProvider(&reads); + StaticSocketDataProvider data(data_reads, data_writes); + session_deps_.socket_factory->AddSocketDataProvider(&data); // Insecure url url_ = "http://www.example.org/"; @@ -19234,7 +19351,7 @@ TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) { // Insecure request does not generate a report histograms.ExpectBucketCount( NetworkErrorLoggingService::kRequestOutcomeHistogram, - NetworkErrorLoggingService::RequestOutcome::DISCARDED_INSECURE_ORIGIN, 1); + NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1); EXPECT_EQ(1u, network_error_logging_service()->errors().size()); } @@ -19270,11 +19387,107 @@ TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, // policy for the origin. histograms.ExpectBucketCount( NetworkErrorLoggingService::kRequestOutcomeHistogram, - NetworkErrorLoggingService::RequestOutcome::DISCARDED_INSECURE_ORIGIN, 1); + NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1); EXPECT_EQ(1u, network_error_logging_service()->errors().size()); } +// Don't report on proxy auth challenges, don't report if connecting through a +// proxy. +TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportProxy) { + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("https://www.example.org/"); + request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + + // Configure against proxy server "myproxy:70". + session_deps_.proxy_resolution_service = + ProxyResolutionService::CreateFixedFromPacResult( + "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); + std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + + // Since we have proxy, should try to establish tunnel. + MockWrite data_writes1[] = { + 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"), + }; + + // The proxy responds to the connect with a 407, using a non-persistent + // connection. + MockRead data_reads1[] = { + // No credentials. + MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"), + MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), + MockRead("Proxy-Connection: close\r\n\r\n"), + }; + + MockWrite data_writes2[] = { + // After calling trans->RestartWithAuth(), this is the request we should + // be issuing -- the final header line contains the credentials. + MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org:443\r\n" + "Proxy-Connection: keep-alive\r\n" + "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), + + MockWrite("GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n\r\n"), + }; + + MockRead data_reads2[] = { + MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), + + MockRead("HTTP/1.1 200 OK\r\n"), + MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), + MockRead("Content-Length: 5\r\n\r\n"), + MockRead(SYNCHRONOUS, "hello"), + }; + + StaticSocketDataProvider data1(data_reads1, data_writes1); + session_deps_.socket_factory->AddSocketDataProvider(&data1); + StaticSocketDataProvider data2(data_reads2, data_writes2); + session_deps_.socket_factory->AddSocketDataProvider(&data2); + SSLSocketDataProvider ssl(ASYNC, OK); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); + + TestCompletionCallback callback1; + + auto trans = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + + int rv = trans->Start(&request, callback1.callback(), NetLogWithSource()); + EXPECT_THAT(callback1.GetResult(rv), IsOk()); + + const HttpResponseInfo* response = trans->GetResponseInfo(); + EXPECT_EQ(407, response->headers->response_code()); + + std::string response_data; + rv = ReadTransaction(trans.get(), &response_data); + EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED)); + + // No NEL report is generated for the 407. + EXPECT_EQ(0u, network_error_logging_service()->errors().size()); + + TestCompletionCallback callback2; + + rv = + trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback()); + EXPECT_THAT(callback2.GetResult(rv), IsOk()); + + response = trans->GetResponseInfo(); + EXPECT_EQ(200, response->headers->response_code()); + + ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + EXPECT_EQ("hello", response_data); + + trans.reset(); + + // No NEL report is generated because we are behind a proxy. + EXPECT_EQ(0u, network_error_logging_service()->errors().size()); +} + TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportContainsUploadDepth) { reporting_upload_depth_ = 7; @@ -19350,4 +19563,488 @@ TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) { #endif // BUILDFLAG(ENABLE_REPORTING) +// Test the proxy and origin server each requesting both TLS client certificates +// and HTTP auth. This is a regression test for https://crbug.com/946406. +TEST_F(HttpNetworkTransactionTest, AuthEverything) { + // Note these hosts must match the CheckBasic*Auth() functions. + session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed( + "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); + + auto cert_request_info_proxy = base::MakeRefCounted<SSLCertRequestInfo>(); + cert_request_info_proxy->host_and_port = HostPortPair("myproxy", 70); + + std::unique_ptr<FakeClientCertIdentity> identity_proxy = + FakeClientCertIdentity::CreateFromCertAndKeyFiles( + GetTestCertsDirectory(), "client_1.pem", "client_1.pk8"); + ASSERT_TRUE(identity_proxy); + + auto cert_request_info_origin = base::MakeRefCounted<SSLCertRequestInfo>(); + cert_request_info_origin->host_and_port = + HostPortPair("www.example.org", 443); + + std::unique_ptr<FakeClientCertIdentity> identity_origin = + FakeClientCertIdentity::CreateFromCertAndKeyFiles( + GetTestCertsDirectory(), "client_2.pem", "client_2.pk8"); + ASSERT_TRUE(identity_origin); + + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("https://www.example.org/"); + request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + + // First, the client connects to the proxy, which requests a client + // certificate. + SSLSocketDataProvider ssl_proxy1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED); + ssl_proxy1.cert_request_info = cert_request_info_proxy.get(); + ssl_proxy1.expected_send_client_cert = false; + StaticSocketDataProvider data1; + session_deps_.socket_factory->AddSocketDataProvider(&data1); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy1); + + // The client responds with a certificate on a new connection. The handshake + // succeeds. + SSLSocketDataProvider ssl_proxy2(ASYNC, OK); + ssl_proxy2.expected_send_client_cert = true; + ssl_proxy2.expected_client_cert = identity_proxy->certificate(); + // The client attempts an HTTP CONNECT, but the proxy requests basic auth. + std::vector<MockWrite> mock_writes2; + std::vector<MockRead> mock_reads2; + mock_writes2.emplace_back( + "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"); + mock_reads2.emplace_back( + "HTTP/1.1 407 Proxy Authentication Required\r\n" + "Content-Length: 0\r\n" + "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"); + // The client retries with credentials. + mock_writes2.emplace_back( + "CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org:443\r\n" + "Proxy-Connection: keep-alive\r\n" + // Authenticate as proxyuser:proxypass. + "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n"); + mock_reads2.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n"); + // The origin requests client certificates. + SSLSocketDataProvider ssl_origin2(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED); + ssl_origin2.cert_request_info = cert_request_info_origin.get(); + StaticSocketDataProvider data2(mock_reads2, mock_writes2); + session_deps_.socket_factory->AddSocketDataProvider(&data2); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy2); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin2); + + // The client responds to the origin client certificate request on a new + // connection. + SSLSocketDataProvider ssl_proxy3(ASYNC, OK); + ssl_proxy3.expected_send_client_cert = true; + ssl_proxy3.expected_client_cert = identity_proxy->certificate(); + std::vector<MockWrite> mock_writes3; + std::vector<MockRead> mock_reads3; + mock_writes3.emplace_back( + "CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org:443\r\n" + "Proxy-Connection: keep-alive\r\n" + // Authenticate as proxyuser:proxypass. + "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n"); + mock_reads3.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n"); + SSLSocketDataProvider ssl_origin3(ASYNC, OK); + ssl_origin3.expected_send_client_cert = true; + ssl_origin3.expected_client_cert = identity_origin->certificate(); + // The client sends the origin HTTP request, which results in another HTTP + // auth request. + mock_writes3.emplace_back( + "GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n\r\n"); + mock_reads3.emplace_back( + "HTTP/1.1 401 Unauthorized\r\n" + "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n" + "Content-Length: 0\r\n\r\n"); + // The client retries with credentials, and the request finally succeeds. + mock_writes3.emplace_back( + "GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n" + // Authenticate as user:pass. + "Authorization: Basic dXNlcjpwYXNz\r\n\r\n"); + mock_reads3.emplace_back( + "HTTP/1.1 200 OK\r\n" + "Content-Length: 0\r\n\r\n"); + StaticSocketDataProvider data3(mock_reads3, mock_writes3); + session_deps_.socket_factory->AddSocketDataProvider(&data3); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy3); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin3); + + std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + + // Start the request. + TestCompletionCallback callback; + auto trans = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + int rv = callback.GetResult( + trans->Start(&request, callback.callback(), NetLogWithSource())); + + // Handle the proxy client certificate challenge. + ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED)); + SSLCertRequestInfo* cert_request_info = + trans->GetResponseInfo()->cert_request_info.get(); + ASSERT_TRUE(cert_request_info); + EXPECT_TRUE(cert_request_info->is_proxy); + EXPECT_EQ(cert_request_info->host_and_port, + cert_request_info_proxy->host_and_port); + rv = callback.GetResult(trans->RestartWithCertificate( + identity_proxy->certificate(), identity_proxy->ssl_private_key(), + callback.callback())); + + // Handle the proxy HTTP auth challenge. + ASSERT_THAT(rv, IsOk()); + EXPECT_EQ(407, trans->GetResponseInfo()->headers->response_code()); + EXPECT_TRUE(CheckBasicSecureProxyAuth( + trans->GetResponseInfo()->auth_challenge.get())); + rv = callback.GetResult(trans->RestartWithAuth( + AuthCredentials(ASCIIToUTF16("proxyuser"), ASCIIToUTF16("proxypass")), + callback.callback())); + + // Handle the origin client certificate challenge. + ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED)); + cert_request_info = trans->GetResponseInfo()->cert_request_info.get(); + ASSERT_TRUE(cert_request_info); + EXPECT_FALSE(cert_request_info->is_proxy); + EXPECT_EQ(cert_request_info->host_and_port, + cert_request_info_origin->host_and_port); + rv = callback.GetResult(trans->RestartWithCertificate( + identity_origin->certificate(), identity_origin->ssl_private_key(), + callback.callback())); + + // Handle the origin HTTP auth challenge. + ASSERT_THAT(rv, IsOk()); + EXPECT_EQ(401, trans->GetResponseInfo()->headers->response_code()); + EXPECT_TRUE(CheckBasicSecureServerAuth( + trans->GetResponseInfo()->auth_challenge.get())); + rv = callback.GetResult(trans->RestartWithAuth( + AuthCredentials(ASCIIToUTF16("user"), ASCIIToUTF16("pass")), + callback.callback())); + + // The request completes. + ASSERT_THAT(rv, IsOk()); + EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code()); +} + +// Test the proxy and origin server each requesting both TLS client certificates +// and HTTP auth and each HTTP auth closing the connection. This is a regression +// test for https://crbug.com/946406. +TEST_F(HttpNetworkTransactionTest, AuthEverythingWithConnectClose) { + // Note these hosts must match the CheckBasic*Auth() functions. + session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed( + "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); + + auto cert_request_info_proxy = base::MakeRefCounted<SSLCertRequestInfo>(); + cert_request_info_proxy->host_and_port = HostPortPair("myproxy", 70); + + std::unique_ptr<FakeClientCertIdentity> identity_proxy = + FakeClientCertIdentity::CreateFromCertAndKeyFiles( + GetTestCertsDirectory(), "client_1.pem", "client_1.pk8"); + ASSERT_TRUE(identity_proxy); + + auto cert_request_info_origin = base::MakeRefCounted<SSLCertRequestInfo>(); + cert_request_info_origin->host_and_port = + HostPortPair("www.example.org", 443); + + std::unique_ptr<FakeClientCertIdentity> identity_origin = + FakeClientCertIdentity::CreateFromCertAndKeyFiles( + GetTestCertsDirectory(), "client_2.pem", "client_2.pk8"); + ASSERT_TRUE(identity_origin); + + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("https://www.example.org/"); + request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + + // First, the client connects to the proxy, which requests a client + // certificate. + SSLSocketDataProvider ssl_proxy1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED); + ssl_proxy1.cert_request_info = cert_request_info_proxy.get(); + ssl_proxy1.expected_send_client_cert = false; + StaticSocketDataProvider data1; + session_deps_.socket_factory->AddSocketDataProvider(&data1); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy1); + + // The client responds with a certificate on a new connection. The handshake + // succeeds. + SSLSocketDataProvider ssl_proxy2(ASYNC, OK); + ssl_proxy2.expected_send_client_cert = true; + ssl_proxy2.expected_client_cert = identity_proxy->certificate(); + // The client attempts an HTTP CONNECT, but the proxy requests basic auth. + std::vector<MockWrite> mock_writes2; + std::vector<MockRead> mock_reads2; + mock_writes2.emplace_back( + "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"); + mock_reads2.emplace_back( + "HTTP/1.1 407 Proxy Authentication Required\r\n" + "Content-Length: 0\r\n" + "Proxy-Connection: close\r\n" + "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"); + StaticSocketDataProvider data2(mock_reads2, mock_writes2); + session_deps_.socket_factory->AddSocketDataProvider(&data2); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy2); + + // The client retries with credentials on a new connection. + SSLSocketDataProvider ssl_proxy3(ASYNC, OK); + ssl_proxy3.expected_send_client_cert = true; + ssl_proxy3.expected_client_cert = identity_proxy->certificate(); + std::vector<MockWrite> mock_writes3; + std::vector<MockRead> mock_reads3; + mock_writes3.emplace_back( + "CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org:443\r\n" + "Proxy-Connection: keep-alive\r\n" + // Authenticate as proxyuser:proxypass. + "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n"); + mock_reads3.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n"); + // The origin requests client certificates. + SSLSocketDataProvider ssl_origin3(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED); + ssl_origin3.cert_request_info = cert_request_info_origin.get(); + StaticSocketDataProvider data3(mock_reads3, mock_writes3); + session_deps_.socket_factory->AddSocketDataProvider(&data3); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy3); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin3); + + // The client responds to the origin client certificate request on a new + // connection. + SSLSocketDataProvider ssl_proxy4(ASYNC, OK); + ssl_proxy4.expected_send_client_cert = true; + ssl_proxy4.expected_client_cert = identity_proxy->certificate(); + std::vector<MockWrite> mock_writes4; + std::vector<MockRead> mock_reads4; + mock_writes4.emplace_back( + "CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org:443\r\n" + "Proxy-Connection: keep-alive\r\n" + // Authenticate as proxyuser:proxypass. + "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n"); + mock_reads4.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n"); + SSLSocketDataProvider ssl_origin4(ASYNC, OK); + ssl_origin4.expected_send_client_cert = true; + ssl_origin4.expected_client_cert = identity_origin->certificate(); + // The client sends the origin HTTP request, which results in another HTTP + // auth request and closed connection. + mock_writes4.emplace_back( + "GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n\r\n"); + mock_reads4.emplace_back( + "HTTP/1.1 401 Unauthorized\r\n" + "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n" + "Connection: close\r\n" + "Content-Length: 0\r\n\r\n"); + StaticSocketDataProvider data4(mock_reads4, mock_writes4); + session_deps_.socket_factory->AddSocketDataProvider(&data4); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy4); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin4); + + // The client retries with credentials on a new connection, and the request + // finally succeeds. + SSLSocketDataProvider ssl_proxy5(ASYNC, OK); + ssl_proxy5.expected_send_client_cert = true; + ssl_proxy5.expected_client_cert = identity_proxy->certificate(); + std::vector<MockWrite> mock_writes5; + std::vector<MockRead> mock_reads5; + mock_writes5.emplace_back( + "CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org:443\r\n" + "Proxy-Connection: keep-alive\r\n" + // Authenticate as proxyuser:proxypass. + "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n"); + mock_reads5.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n"); + SSLSocketDataProvider ssl_origin5(ASYNC, OK); + ssl_origin5.expected_send_client_cert = true; + ssl_origin5.expected_client_cert = identity_origin->certificate(); + mock_writes5.emplace_back( + "GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n" + // Authenticate as user:pass. + "Authorization: Basic dXNlcjpwYXNz\r\n\r\n"); + mock_reads5.emplace_back( + "HTTP/1.1 200 OK\r\n" + "Connection: close\r\n" + "Content-Length: 0\r\n\r\n"); + StaticSocketDataProvider data5(mock_reads5, mock_writes5); + session_deps_.socket_factory->AddSocketDataProvider(&data5); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy5); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin5); + + std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + + // Start the request. + TestCompletionCallback callback; + auto trans = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + int rv = callback.GetResult( + trans->Start(&request, callback.callback(), NetLogWithSource())); + + // Handle the proxy client certificate challenge. + ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED)); + SSLCertRequestInfo* cert_request_info = + trans->GetResponseInfo()->cert_request_info.get(); + ASSERT_TRUE(cert_request_info); + EXPECT_TRUE(cert_request_info->is_proxy); + EXPECT_EQ(cert_request_info->host_and_port, + cert_request_info_proxy->host_and_port); + rv = callback.GetResult(trans->RestartWithCertificate( + identity_proxy->certificate(), identity_proxy->ssl_private_key(), + callback.callback())); + + // Handle the proxy HTTP auth challenge. + ASSERT_THAT(rv, IsOk()); + EXPECT_EQ(407, trans->GetResponseInfo()->headers->response_code()); + EXPECT_TRUE(CheckBasicSecureProxyAuth( + trans->GetResponseInfo()->auth_challenge.get())); + rv = callback.GetResult(trans->RestartWithAuth( + AuthCredentials(ASCIIToUTF16("proxyuser"), ASCIIToUTF16("proxypass")), + callback.callback())); + + // Handle the origin client certificate challenge. + ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED)); + cert_request_info = trans->GetResponseInfo()->cert_request_info.get(); + ASSERT_TRUE(cert_request_info); + EXPECT_FALSE(cert_request_info->is_proxy); + EXPECT_EQ(cert_request_info->host_and_port, + cert_request_info_origin->host_and_port); + rv = callback.GetResult(trans->RestartWithCertificate( + identity_origin->certificate(), identity_origin->ssl_private_key(), + callback.callback())); + + // Handle the origin HTTP auth challenge. + ASSERT_THAT(rv, IsOk()); + EXPECT_EQ(401, trans->GetResponseInfo()->headers->response_code()); + EXPECT_TRUE(CheckBasicSecureServerAuth( + trans->GetResponseInfo()->auth_challenge.get())); + rv = callback.GetResult(trans->RestartWithAuth( + AuthCredentials(ASCIIToUTF16("user"), ASCIIToUTF16("pass")), + callback.callback())); + + // The request completes. + ASSERT_THAT(rv, IsOk()); + EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code()); +} + +// Test the proxy requesting HTTP auth and the server requesting TLS client +// certificates. This is a regression test for https://crbug.com/946406. +TEST_F(HttpNetworkTransactionTest, ProxyHTTPAndServerTLSAuth) { + // Note these hosts must match the CheckBasic*Auth() functions. + session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed( + "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); + + auto cert_request_info_origin = base::MakeRefCounted<SSLCertRequestInfo>(); + cert_request_info_origin->host_and_port = + HostPortPair("www.example.org", 443); + + std::unique_ptr<FakeClientCertIdentity> identity_origin = + FakeClientCertIdentity::CreateFromCertAndKeyFiles( + GetTestCertsDirectory(), "client_2.pem", "client_2.pk8"); + ASSERT_TRUE(identity_origin); + + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("https://www.example.org/"); + request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + + // The client connects to the proxy. The handshake succeeds. + SSLSocketDataProvider ssl_proxy1(ASYNC, OK); + // The client attempts an HTTP CONNECT, but the proxy requests basic auth. + std::vector<MockWrite> mock_writes1; + std::vector<MockRead> mock_reads1; + mock_writes1.emplace_back( + "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"); + mock_reads1.emplace_back( + "HTTP/1.1 407 Proxy Authentication Required\r\n" + "Content-Length: 0\r\n" + "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"); + // The client retries with credentials, and the request finally succeeds. + mock_writes1.emplace_back( + "CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org:443\r\n" + "Proxy-Connection: keep-alive\r\n" + // Authenticate as proxyuser:proxypass. + "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n"); + mock_reads1.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n"); + // The origin requests client certificates. + SSLSocketDataProvider ssl_origin1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED); + ssl_origin1.cert_request_info = cert_request_info_origin.get(); + StaticSocketDataProvider data1(mock_reads1, mock_writes1); + session_deps_.socket_factory->AddSocketDataProvider(&data1); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy1); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin1); + + // The client responds to the origin client certificate request on a new + // connection. + SSLSocketDataProvider ssl_proxy2(ASYNC, OK); + std::vector<MockWrite> mock_writes2; + std::vector<MockRead> mock_reads2; + mock_writes2.emplace_back( + "CONNECT www.example.org:443 HTTP/1.1\r\n" + "Host: www.example.org:443\r\n" + "Proxy-Connection: keep-alive\r\n" + // Authenticate as proxyuser:proxypass. + "Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n"); + mock_reads2.emplace_back("HTTP/1.1 200 Connection Established\r\n\r\n"); + SSLSocketDataProvider ssl_origin2(ASYNC, OK); + ssl_origin2.expected_send_client_cert = true; + ssl_origin2.expected_client_cert = identity_origin->certificate(); + // The client sends the origin HTTP request, which succeeds. + mock_writes2.emplace_back( + "GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n\r\n"); + mock_reads2.emplace_back( + "HTTP/1.1 200 OK\r\n" + "Content-Length: 0\r\n\r\n"); + StaticSocketDataProvider data2(mock_reads2, mock_writes2); + session_deps_.socket_factory->AddSocketDataProvider(&data2); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_proxy2); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_origin2); + + std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + + // Start the request. + TestCompletionCallback callback; + auto trans = + std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get()); + int rv = callback.GetResult( + trans->Start(&request, callback.callback(), NetLogWithSource())); + + // Handle the proxy HTTP auth challenge. + ASSERT_THAT(rv, IsOk()); + EXPECT_EQ(407, trans->GetResponseInfo()->headers->response_code()); + EXPECT_TRUE(CheckBasicSecureProxyAuth( + trans->GetResponseInfo()->auth_challenge.get())); + rv = callback.GetResult(trans->RestartWithAuth( + AuthCredentials(ASCIIToUTF16("proxyuser"), ASCIIToUTF16("proxypass")), + callback.callback())); + + // Handle the origin client certificate challenge. + ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED)); + SSLCertRequestInfo* cert_request_info = + trans->GetResponseInfo()->cert_request_info.get(); + ASSERT_TRUE(cert_request_info); + EXPECT_FALSE(cert_request_info->is_proxy); + EXPECT_EQ(cert_request_info->host_and_port, + cert_request_info_origin->host_and_port); + rv = callback.GetResult(trans->RestartWithCertificate( + identity_origin->certificate(), identity_origin->ssl_private_key(), + callback.callback())); + + // The request completes. + ASSERT_THAT(rv, IsOk()); + EXPECT_EQ(200, trans->GetResponseInfo()->headers->response_code()); +} + } // namespace net diff --git a/chromium/net/http/http_proxy_client_socket.cc b/chromium/net/http/http_proxy_client_socket.cc index dd877223a03..710f9581d0b 100644 --- a/chromium/net/http/http_proxy_client_socket.cc +++ b/chromium/net/http/http_proxy_client_socket.cc @@ -20,10 +20,9 @@ #include "net/http/http_request_info.h" #include "net/http/http_response_headers.h" #include "net/http/http_stream_parser.h" -#include "net/http/proxy_connect_redirect_http_stream.h" #include "net/log/net_log.h" #include "net/log/net_log_event_type.h" -#include "net/socket/client_socket_handle.h" +#include "net/socket/stream_socket.h" #include "url/gurl.h" namespace net { @@ -31,7 +30,7 @@ namespace net { const int HttpProxyClientSocket::kDrainBodyBufferSize; HttpProxyClientSocket::HttpProxyClientSocket( - std::unique_ptr<ClientSocketHandle> transport_socket, + std::unique_ptr<StreamSocket> socket, const std::string& user_agent, const HostPortPair& endpoint, const ProxyServer& proxy_server, @@ -45,19 +44,19 @@ HttpProxyClientSocket::HttpProxyClientSocket( : io_callback_(base::BindRepeating(&HttpProxyClientSocket::OnIOComplete, base::Unretained(this))), next_state_(STATE_NONE), - transport_(std::move(transport_socket)), + socket_(std::move(socket)), + is_reused_(false), endpoint_(endpoint), auth_(http_auth_controller), tunnel_(tunnel), using_spdy_(using_spdy), negotiated_protocol_(negotiated_protocol), is_https_proxy_(is_https_proxy), - redirect_has_load_timing_info_(false), proxy_server_(proxy_server), proxy_delegate_(proxy_delegate), traffic_annotation_(traffic_annotation), - net_log_(transport_->socket()->NetLog()) { - // Synthesize the bits of a request that we actually use. + net_log_(socket_->NetLog()) { + // Synthesize the bits of a request that are actually used. request_.url = GURL("https://" + endpoint.ToString()); request_.method = "CONNECT"; if (!user_agent.empty()) @@ -103,15 +102,8 @@ const HttpResponseInfo* HttpProxyClientSocket::GetConnectResponseInfo() const { return response_.headers.get() ? &response_ : NULL; } -std::unique_ptr<HttpStream> -HttpProxyClientSocket::CreateConnectResponseStream() { - return std::make_unique<ProxyConnectRedirectHttpStream>( - redirect_has_load_timing_info_ ? &redirect_load_timing_info_ : nullptr); -} - int HttpProxyClientSocket::Connect(CompletionOnceCallback callback) { - DCHECK(transport_.get()); - DCHECK(transport_->socket()); + DCHECK(socket_); DCHECK(user_callback_.is_null()); // TODO(rch): figure out the right way to set up a tunnel with SPDY. @@ -134,8 +126,8 @@ int HttpProxyClientSocket::Connect(CompletionOnceCallback callback) { } void HttpProxyClientSocket::Disconnect() { - if (transport_.get()) - transport_->socket()->Disconnect(); + if (socket_) + socket_->Disconnect(); // Reset other states to make sure they aren't mistakenly used later. // These are the states initialized by Connect(). @@ -144,12 +136,11 @@ void HttpProxyClientSocket::Disconnect() { } bool HttpProxyClientSocket::IsConnected() const { - return next_state_ == STATE_DONE && transport_->socket()->IsConnected(); + return next_state_ == STATE_DONE && socket_->IsConnected(); } bool HttpProxyClientSocket::IsConnectedAndIdle() const { - return next_state_ == STATE_DONE && - transport_->socket()->IsConnectedAndIdle(); + return next_state_ == STATE_DONE && socket_->IsConnectedAndIdle(); } const NetLogWithSource& HttpProxyClientSocket::NetLog() const { @@ -157,33 +148,29 @@ const NetLogWithSource& HttpProxyClientSocket::NetLog() const { } bool HttpProxyClientSocket::WasEverUsed() const { - if (transport_.get() && transport_->socket()) { - return transport_->socket()->WasEverUsed(); - } + if (socket_) + return socket_->WasEverUsed(); NOTREACHED(); return false; } bool HttpProxyClientSocket::WasAlpnNegotiated() const { - if (transport_.get() && transport_->socket()) { - return transport_->socket()->WasAlpnNegotiated(); - } + if (socket_) + return socket_->WasAlpnNegotiated(); NOTREACHED(); return false; } NextProto HttpProxyClientSocket::GetNegotiatedProtocol() const { - if (transport_.get() && transport_->socket()) { - return transport_->socket()->GetNegotiatedProtocol(); - } + if (socket_) + return socket_->GetNegotiatedProtocol(); NOTREACHED(); return kProtoUnknown; } bool HttpProxyClientSocket::GetSSLInfo(SSLInfo* ssl_info) { - if (transport_.get() && transport_->socket()) { - return transport_->socket()->GetSSLInfo(ssl_info); - } + if (socket_) + return socket_->GetSSLInfo(ssl_info); NOTREACHED(); return false; } @@ -194,11 +181,11 @@ void HttpProxyClientSocket::GetConnectionAttempts( } int64_t HttpProxyClientSocket::GetTotalReceivedBytes() const { - return transport_->socket()->GetTotalReceivedBytes(); + return socket_->GetTotalReceivedBytes(); } void HttpProxyClientSocket::ApplySocketTag(const SocketTag& tag) { - return transport_->socket()->ApplySocketTag(tag); + return socket_->ApplySocketTag(tag); } int HttpProxyClientSocket::Read(IOBuffer* buf, @@ -208,7 +195,7 @@ int HttpProxyClientSocket::Read(IOBuffer* buf, if (!CheckDone()) return ERR_TUNNEL_CONNECTION_FAILED; - return transport_->socket()->Read(buf, buf_len, std::move(callback)); + return socket_->Read(buf, buf_len, std::move(callback)); } int HttpProxyClientSocket::ReadIfReady(IOBuffer* buf, @@ -218,11 +205,11 @@ int HttpProxyClientSocket::ReadIfReady(IOBuffer* buf, if (!CheckDone()) return ERR_TUNNEL_CONNECTION_FAILED; - return transport_->socket()->ReadIfReady(buf, buf_len, std::move(callback)); + return socket_->ReadIfReady(buf, buf_len, std::move(callback)); } int HttpProxyClientSocket::CancelReadIfReady() { - return transport_->socket()->CancelReadIfReady(); + return socket_->CancelReadIfReady(); } int HttpProxyClientSocket::Write( @@ -233,24 +220,23 @@ int HttpProxyClientSocket::Write( DCHECK_EQ(STATE_DONE, next_state_); DCHECK(user_callback_.is_null()); - return transport_->socket()->Write(buf, buf_len, std::move(callback), - traffic_annotation); + return socket_->Write(buf, buf_len, std::move(callback), traffic_annotation); } int HttpProxyClientSocket::SetReceiveBufferSize(int32_t size) { - return transport_->socket()->SetReceiveBufferSize(size); + return socket_->SetReceiveBufferSize(size); } int HttpProxyClientSocket::SetSendBufferSize(int32_t size) { - return transport_->socket()->SetSendBufferSize(size); + return socket_->SetSendBufferSize(size); } int HttpProxyClientSocket::GetPeerAddress(IPEndPoint* address) const { - return transport_->socket()->GetPeerAddress(address); + return socket_->GetPeerAddress(address); } int HttpProxyClientSocket::GetLocalAddress(IPEndPoint* address) const { - return transport_->socket()->GetLocalAddress(address); + return socket_->GetLocalAddress(address); } int HttpProxyClientSocket::PrepareForAuthRestart() { @@ -261,9 +247,8 @@ int HttpProxyClientSocket::PrepareForAuthRestart() { // ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH. The request will be retried // at a higher layer. if (!response_.headers->IsKeepAlive() || - !http_stream_parser_->CanFindEndOfResponse() || - !transport_->socket()->IsConnected()) { - transport_->socket()->Disconnect(); + !http_stream_parser_->CanFindEndOfResponse() || !socket_->IsConnected()) { + socket_->Disconnect(); return ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH; } @@ -279,11 +264,11 @@ int HttpProxyClientSocket::PrepareForAuthRestart() { int HttpProxyClientSocket::DidDrainBodyForAuthRestart() { // Can't reuse the socket if there's still unread data on it. - if (!transport_->socket()->IsConnectedAndIdle()) + if (!socket_->IsConnectedAndIdle()) return ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH; next_state_ = STATE_GENERATE_AUTH_TOKEN; - transport_->set_reuse_type(ClientSocketHandle::REUSED_IDLE); + is_reused_ = true; // Reset the other member variables. drain_buf_ = nullptr; @@ -394,8 +379,8 @@ int HttpProxyClientSocket::DoSendRequest() { if (proxy_delegate_) { HttpRequestHeaders proxy_delegate_headers; - proxy_delegate_->OnBeforeTunnelRequest(proxy_server_, - &proxy_delegate_headers); + proxy_delegate_->OnBeforeHttp1TunnelRequest(proxy_server_, + &proxy_delegate_headers); extra_headers.MergeFrom(proxy_delegate_headers); } @@ -415,7 +400,7 @@ int HttpProxyClientSocket::DoSendRequest() { parser_buf_ = base::MakeRefCounted<GrowableIOBuffer>(); http_stream_parser_.reset(new HttpStreamParser( - transport_.get(), &request_, parser_buf_.get(), net_log_)); + socket_.get(), is_reused_, &request_, parser_buf_.get(), net_log_)); return http_stream_parser_->SendRequest(request_line_, request_headers_, traffic_annotation_, &response_, io_callback_); @@ -447,8 +432,8 @@ int HttpProxyClientSocket::DoReadHeadersComplete(int result) { base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers)); if (proxy_delegate_) { - int rv = proxy_delegate_->OnTunnelHeadersReceived(proxy_server_, - *response_.headers); + int rv = proxy_delegate_->OnHttp1TunnelHeadersReceived(proxy_server_, + *response_.headers); if (rv != OK) { DCHECK_NE(ERR_IO_PENDING, rv); return rv; @@ -479,11 +464,9 @@ int HttpProxyClientSocket::DoReadHeadersComplete(int result) { if (!is_https_proxy_ || !SanitizeProxyRedirect(&response_)) return ERR_TUNNEL_CONNECTION_FAILED; - redirect_has_load_timing_info_ = transport_->GetLoadTimingInfo( - http_stream_parser_->IsConnectionReused(), - &redirect_load_timing_info_); - transport_.reset(); http_stream_parser_.reset(); + socket_.reset(); + is_reused_ = false; return ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT; case 407: // Proxy Authentication Required diff --git a/chromium/net/http/http_proxy_client_socket.h b/chromium/net/http/http_proxy_client_socket.h index 45a4130d686..7509bfdd9a5 100644 --- a/chromium/net/http/http_proxy_client_socket.h +++ b/chromium/net/http/http_proxy_client_socket.h @@ -16,7 +16,6 @@ #include "net/base/completion_once_callback.h" #include "net/base/completion_repeating_callback.h" #include "net/base/host_port_pair.h" -#include "net/base/load_timing_info.h" #include "net/base/net_export.h" #include "net/base/proxy_server.h" #include "net/http/http_auth_controller.h" @@ -30,19 +29,18 @@ namespace net { -class ClientSocketHandle; class GrowableIOBuffer; -class HttpStream; class HttpStreamParser; class IOBuffer; class ProxyDelegate; +class StreamSocket; class NET_EXPORT_PRIVATE HttpProxyClientSocket : public ProxyClientSocket { public: - // Takes ownership of |transport_socket|, which should already be connected - // by the time Connect() is called. If tunnel is true then on Connect() - // this socket will establish an Http tunnel. - HttpProxyClientSocket(std::unique_ptr<ClientSocketHandle> transport_socket, + // Takes ownership of |socket|, which should already be connected by the time + // Connect() is called. |socket| is assumed to be a freash socket. If tunnel + // is true then on Connect() this socket will establish an Http tunnel. + HttpProxyClientSocket(std::unique_ptr<StreamSocket> socket, const std::string& user_agent, const HostPortPair& endpoint, const ProxyServer& proxy_server, @@ -59,7 +57,6 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocket : public ProxyClientSocket { // ProxyClientSocket implementation. const HttpResponseInfo* GetConnectResponseInfo() const override; - std::unique_ptr<HttpStream> CreateConnectResponseStream() override; int RestartWithAuth(CompletionOnceCallback callback) override; const scoped_refptr<HttpAuthController>& GetAuthController() const override; bool IsUsingSpdy() const override; @@ -149,8 +146,11 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocket : public ProxyClientSocket { std::unique_ptr<HttpStreamParser> http_stream_parser_; scoped_refptr<IOBuffer> drain_buf_; - // Stores the underlying socket. - std::unique_ptr<ClientSocketHandle> transport_; + std::unique_ptr<StreamSocket> socket_; + + // Whether or not |socket_| has been previously used. Once auth credentials + // are sent, set to true. + bool is_reused_; // The hostname and port of the endpoint. This is not necessarily the one // specified by the URL, due to Alternate-Protocol or fixed testing ports. @@ -167,10 +167,6 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocket : public ProxyClientSocket { std::string request_line_; HttpRequestHeaders request_headers_; - // Used only for redirects. - bool redirect_has_load_timing_info_; - LoadTimingInfo redirect_load_timing_info_; - const ProxyServer proxy_server_; // This delegate must outlive this proxy client socket. diff --git a/chromium/net/http/http_proxy_client_socket_fuzzer.cc b/chromium/net/http/http_proxy_client_socket_fuzzer.cc index af12e96c197..cbe9090c453 100644 --- a/chromium/net/http/http_proxy_client_socket_fuzzer.cc +++ b/chromium/net/http/http_proxy_client_socket_fuzzer.cc @@ -23,7 +23,6 @@ #include "net/http/http_auth_handler_factory.h" #include "net/http/http_auth_scheme.h" #include "net/log/test_net_log.h" -#include "net/socket/client_socket_handle.h" #include "net/socket/fuzzed_socket.h" #include "net/socket/next_proto.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" @@ -44,10 +43,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { new net::FuzzedSocket(&data_provider, &test_net_log)); CHECK_EQ(net::OK, fuzzed_socket->Connect(callback.callback())); - std::unique_ptr<net::ClientSocketHandle> socket_handle( - new net::ClientSocketHandle()); - socket_handle->SetSocket(std::move(fuzzed_socket)); - // Create auth handler supporting basic and digest schemes. Other schemes can // make system calls, which doesn't seem like a great idea. net::HttpAuthCache auth_cache; @@ -60,12 +55,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { scoped_refptr<net::HttpAuthController> auth_controller( new net::HttpAuthController(net::HttpAuth::AUTH_PROXY, GURL("http://proxy:42/"), &auth_cache, - &auth_handler_factory)); + &auth_handler_factory, nullptr)); // Determine if the HttpProxyClientSocket should be told the underlying socket // is HTTPS. bool is_https_proxy = data_provider.ConsumeBool(); net::HttpProxyClientSocket socket( - std::move(socket_handle), "Bond/007", net::HostPortPair("foo", 80), + std::move(fuzzed_socket), "Bond/007", net::HostPortPair("foo", 80), net::ProxyServer(net::ProxyServer::SCHEME_HTTP, net::HostPortPair("proxy", 42)), auth_controller.get(), true /* tunnel */, false /* using_spdy */, diff --git a/chromium/net/http/http_proxy_client_socket_pool.h b/chromium/net/http/http_proxy_client_socket_pool.h deleted file mode 100644 index a8696319c63..00000000000 --- a/chromium/net/http/http_proxy_client_socket_pool.h +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright (c) 2012 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_HTTP_HTTP_PROXY_CLIENT_SOCKET_POOL_H_ -#define NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_POOL_H_ - -#include <stdint.h> - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/time/time.h" -#include "net/base/completion_once_callback.h" -#include "net/base/host_port_pair.h" -#include "net/base/net_export.h" -#include "net/http/http_auth.h" -#include "net/http/http_response_info.h" -#include "net/http/proxy_client_socket.h" -#include "net/socket/client_socket_pool.h" -#include "net/socket/client_socket_pool_base.h" -#include "net/socket/ssl_client_socket.h" -#include "net/spdy/spdy_session.h" -#include "net/traffic_annotation/network_traffic_annotation.h" - -namespace net { - -class HttpAuthCache; -class HttpAuthHandlerFactory; -class HttpProxyClientSocketWrapper; -class NetLog; -class NetworkQualityEstimator; -class ProxyDelegate; -class QuicStreamFactory; -class SSLClientSocketPool; -class SSLSocketParams; -class SpdySessionPool; -class TransportClientSocketPool; -class TransportSocketParams; - -// HttpProxySocketParams only needs the socket params for one of the proxy -// types. The other param must be NULL. When using an HTTP proxy, -// |transport_params| must be set. When using an HTTPS proxy or QUIC proxy, -// |ssl_params| must be set. Also, if using a QUIC proxy, |quic_version| must -// not be quic::QUIC_VERSION_UNSUPPORTED. -class NET_EXPORT_PRIVATE HttpProxySocketParams - : public base::RefCounted<HttpProxySocketParams> { - public: - HttpProxySocketParams( - const scoped_refptr<TransportSocketParams>& transport_params, - const scoped_refptr<SSLSocketParams>& ssl_params, - quic::QuicTransportVersion quic_version, - const std::string& user_agent, - const HostPortPair& endpoint, - HttpAuthCache* http_auth_cache, - HttpAuthHandlerFactory* http_auth_handler_factory, - SpdySessionPool* spdy_session_pool, - QuicStreamFactory* quic_stream_factory, - bool is_trusted_proxy, - bool tunnel, - const NetworkTrafficAnnotationTag traffic_annotation); - - const scoped_refptr<TransportSocketParams>& transport_params() const { - return transport_params_; - } - const scoped_refptr<SSLSocketParams>& ssl_params() const { - return ssl_params_; - } - quic::QuicTransportVersion quic_version() const { return quic_version_; } - const std::string& user_agent() const { return user_agent_; } - const HostPortPair& endpoint() const { return endpoint_; } - HttpAuthCache* http_auth_cache() const { return http_auth_cache_; } - HttpAuthHandlerFactory* http_auth_handler_factory() const { - return http_auth_handler_factory_; - } - SpdySessionPool* spdy_session_pool() { - return spdy_session_pool_; - } - QuicStreamFactory* quic_stream_factory() const { - return quic_stream_factory_; - } - bool is_trusted_proxy() const { return is_trusted_proxy_; } - bool tunnel() const { return tunnel_; } - const NetworkTrafficAnnotationTag traffic_annotation() const { - return traffic_annotation_; - } - - private: - friend class base::RefCounted<HttpProxySocketParams>; - ~HttpProxySocketParams(); - - const scoped_refptr<TransportSocketParams> transport_params_; - const scoped_refptr<SSLSocketParams> ssl_params_; - quic::QuicTransportVersion quic_version_; - SpdySessionPool* spdy_session_pool_; - QuicStreamFactory* quic_stream_factory_; - const std::string user_agent_; - const HostPortPair endpoint_; - HttpAuthCache* const http_auth_cache_; - HttpAuthHandlerFactory* const http_auth_handler_factory_; - const bool is_trusted_proxy_; - const bool tunnel_; - const NetworkTrafficAnnotationTag traffic_annotation_; - - DISALLOW_COPY_AND_ASSIGN(HttpProxySocketParams); -}; - -// HttpProxyConnectJob optionally establishes a tunnel through the proxy -// server after connecting the underlying transport socket. -class HttpProxyConnectJob : public ConnectJob { - public: - HttpProxyConnectJob(const std::string& group_name, - RequestPriority priority, - const SocketTag& socket_tag, - ClientSocketPool::RespectLimits respect_limits, - const scoped_refptr<HttpProxySocketParams>& params, - ProxyDelegate* proxy_delegate, - TransportClientSocketPool* transport_pool, - SSLClientSocketPool* ssl_pool, - NetworkQualityEstimator* network_quality_estimator, - Delegate* delegate, - NetLog* net_log); - ~HttpProxyConnectJob() override; - - // ConnectJob methods. - LoadState GetLoadState() const override; - - void GetAdditionalErrorState(ClientSocketHandle* handle) override; - - // Returns the connection timeout that will be used by a HttpProxyConnectJob - // created with the specified parameters, given current network conditions. - NET_EXPORT_PRIVATE static base::TimeDelta ConnectionTimeout( - const HttpProxySocketParams& params, - const NetworkQualityEstimator* network_quality_estimator); - - // Updates the field trial parameters used in calculating timeouts. - NET_EXPORT_PRIVATE static void UpdateFieldTrialParametersForTesting(); - - private: - // Begins the tcp connection and the optional Http proxy tunnel. If the - // request is not immediately servicable (likely), the request will return - // ERR_IO_PENDING. An OK return from this function or the callback means - // that the connection is established; ERR_PROXY_AUTH_REQUESTED means - // that the tunnel needs authentication credentials, the socket will be - // returned in this case, and must be release back to the pool; or - // a standard net error code will be returned. - int ConnectInternal() override; - - void ChangePriorityInternal(RequestPriority priority) override; - - void OnConnectComplete(int result); - - int HandleConnectResult(int result); - - std::unique_ptr<HttpProxyClientSocketWrapper> client_socket_; - - std::unique_ptr<HttpResponseInfo> error_response_info_; - - DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJob); -}; - -class NET_EXPORT_PRIVATE HttpProxyClientSocketPool - : public ClientSocketPool, - public HigherLayeredPool { - public: - typedef HttpProxySocketParams SocketParams; - - HttpProxyClientSocketPool(int max_sockets, - int max_sockets_per_group, - TransportClientSocketPool* transport_pool, - SSLClientSocketPool* ssl_pool, - ProxyDelegate* proxy_delegate, - NetworkQualityEstimator* network_quality_estimator, - NetLog* net_log); - - ~HttpProxyClientSocketPool() override; - - // ClientSocketPool implementation. - int RequestSocket(const std::string& group_name, - const void* connect_params, - RequestPriority priority, - const SocketTag& socket_tag, - RespectLimits respect_limits, - ClientSocketHandle* handle, - CompletionOnceCallback callback, - const NetLogWithSource& net_log) override; - - void RequestSockets(const std::string& group_name, - const void* params, - int num_sockets, - const NetLogWithSource& net_log) override; - - void SetPriority(const std::string& group_name, - ClientSocketHandle* handle, - RequestPriority priority) override; - - void CancelRequest(const std::string& group_name, - ClientSocketHandle* handle) override; - - void ReleaseSocket(const std::string& group_name, - std::unique_ptr<StreamSocket> socket, - int id) override; - - void FlushWithError(int error) override; - - void CloseIdleSockets() override; - - void CloseIdleSocketsInGroup(const std::string& group_name) override; - - int IdleSocketCount() const override; - - int IdleSocketCountInGroup(const std::string& group_name) const override; - - LoadState GetLoadState(const std::string& group_name, - const ClientSocketHandle* handle) const override; - - std::unique_ptr<base::DictionaryValue> GetInfoAsValue( - const std::string& name, - const std::string& type, - bool include_nested_pools) const override; - - // LowerLayeredPool implementation. - bool IsStalled() const override; - - void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override; - - void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override; - - // HigherLayeredPool implementation. - bool CloseOneIdleConnection() override; - - private: - FRIEND_TEST_ALL_PREFIXES(HttpProxyClientSocketPoolTest, - ProxyPoolTimeoutWithConnectionProperty); - - typedef ClientSocketPoolBase<HttpProxySocketParams> PoolBase; - - class NET_EXPORT_PRIVATE HttpProxyConnectJobFactory - : public PoolBase::ConnectJobFactory { - public: - HttpProxyConnectJobFactory( - TransportClientSocketPool* transport_pool, - SSLClientSocketPool* ssl_pool, - ProxyDelegate* proxy_delegate, - NetworkQualityEstimator* network_quality_estimator, - NetLog* net_log); - - // ClientSocketPoolBase::ConnectJobFactory methods. - std::unique_ptr<ConnectJob> NewConnectJob( - const std::string& group_name, - const PoolBase::Request& request, - ConnectJob::Delegate* delegate) const override; - - private: - FRIEND_TEST_ALL_PREFIXES(HttpProxyClientSocketPoolTest, - ProxyPoolTimeoutWithConnectionProperty); - - TransportClientSocketPool* const transport_pool_; - SSLClientSocketPool* const ssl_pool_; - ProxyDelegate* const proxy_delegate_; - NetworkQualityEstimator* const network_quality_estimator_; - - NetLog* net_log_; - - DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJobFactory); - }; - - TransportClientSocketPool* const transport_pool_; - SSLClientSocketPool* const ssl_pool_; - PoolBase base_; - - DISALLOW_COPY_AND_ASSIGN(HttpProxyClientSocketPool); -}; - -} // namespace net - -#endif // NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_POOL_H_ 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 3fbd7ab86a7..f3344d521db 100644 --- a/chromium/net/http/http_proxy_client_socket_pool_unittest.cc +++ b/chromium/net/http/http_proxy_client_socket_pool_unittest.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/http/http_proxy_client_socket_pool.h" #include <map> #include <string> @@ -10,9 +9,6 @@ #include "base/callback.h" #include "base/compiler_specific.h" -#include "base/metrics/field_trial.h" -#include "base/metrics/field_trial_param_associator.h" -#include "base/metrics/field_trial_params.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -24,6 +20,7 @@ #include "net/base/test_proxy_delegate.h" #include "net/http/http_network_session.h" #include "net/http/http_proxy_client_socket.h" +#include "net/http/http_proxy_connect_job.h" #include "net/http/http_response_headers.h" #include "net/log/net_log_with_source.h" #include "net/nqe/network_quality_estimator_test_util.h" @@ -31,6 +28,9 @@ #include "net/socket/next_proto.h" #include "net/socket/socket_tag.h" #include "net/socket/socket_test_util.h" +#include "net/socket/socks_connect_job.h" +#include "net/socket/ssl_connect_job.h" +#include "net/socket/transport_client_socket_pool.h" #include "net/socket/transport_connect_job.h" #include "net/spdy/spdy_test_util_common.h" #include "net/test/gtest_util.h" @@ -49,6 +49,8 @@ namespace { const int kMaxSockets = 32; const int kMaxSocketsPerGroup = 6; +constexpr base::TimeDelta kUnusedIdleSocketTimeout = + base::TimeDelta::FromSeconds(10); const char * const kAuthHeaders[] = { "proxy-authorization", "Basic Zm9vOmJhcg==" }; @@ -70,77 +72,44 @@ class HttpProxyClientSocketPoolTest public WithScopedTaskEnvironment { protected: HttpProxyClientSocketPoolTest() - : transport_socket_pool_(kMaxSockets, - kMaxSocketsPerGroup, - &socket_factory_), - ssl_socket_pool_(kMaxSockets, - kMaxSocketsPerGroup, - session_deps_.cert_verifier.get(), - NULL /* channel_id_store */, - NULL /* transport_security_state */, - NULL /* cert_transparency_verifier */, - NULL /* ct_policy_enforcer */, - std::string() /* ssl_session_cache_shard */, - &socket_factory_, - &transport_socket_pool_, - NULL /* socks_pool */, - NULL /* http_proxy_pool */, - session_deps_.ssl_config_service.get(), - NULL /* network_quality_estimator */, - NetLogWithSource().net_log()), - field_trial_list_(nullptr), - pool_( - std::make_unique<HttpProxyClientSocketPool>(kMaxSockets, - kMaxSocketsPerGroup, - &transport_socket_pool_, - &ssl_socket_pool_, - nullptr, - &estimator_, - nullptr)) { + : pool_(std::make_unique<TransportClientSocketPool>( + kMaxSockets, + kMaxSocketsPerGroup, + kUnusedIdleSocketTimeout, + &socket_factory_, + session_deps_.host_resolver.get(), + nullptr /* proxy_delegate */, + session_deps_.cert_verifier.get(), + session_deps_.channel_id_service.get(), + session_deps_.transport_security_state.get(), + session_deps_.cert_transparency_verifier.get(), + session_deps_.ct_policy_enforcer.get(), + nullptr /* ssl_client_session_cache */, + nullptr /* ssl_client_session_cache_privacy_mode */, + session_deps_.ssl_config_service.get(), + nullptr /* socket_performance_watcher_factory */, + &estimator_, + nullptr /* net_log */)) { + session_deps_.host_resolver->set_synchronous_mode(true); session_ = CreateNetworkSession(); } - virtual ~HttpProxyClientSocketPoolTest() { - // Reset global field trial parameters to defaults values. - base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting(); - HttpProxyConnectJob::UpdateFieldTrialParametersForTesting(); - } - - // Initializes the field trial paramters for the field trial that determines - // connection timeout based on the network quality. - void InitAdaptiveTimeoutFieldTrialWithParams( - bool use_default_params, - int ssl_http_rtt_multiplier, - int non_ssl_http_rtt_multiplier, - base::TimeDelta min_proxy_connection_timeout, - base::TimeDelta max_proxy_connection_timeout) { - std::string trial_name = "NetAdaptiveProxyConnectionTimeout"; - std::string group_name = "GroupName"; - - std::map<std::string, std::string> params; - if (!use_default_params) { - params["ssl_http_rtt_multiplier"] = - base::IntToString(ssl_http_rtt_multiplier); - params["non_ssl_http_rtt_multiplier"] = - base::IntToString(non_ssl_http_rtt_multiplier); - params["min_proxy_connection_timeout_seconds"] = - base::IntToString(min_proxy_connection_timeout.InSeconds()); - params["max_proxy_connection_timeout_seconds"] = - base::IntToString(max_proxy_connection_timeout.InSeconds()); - } - base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting(); - EXPECT_TRUE( - base::AssociateFieldTrialParams(trial_name, group_name, params)); - EXPECT_TRUE(base::FieldTrialList::CreateFieldTrial(trial_name, group_name)); - - // Force static global that reads the field trials to update. - HttpProxyConnectJob::UpdateFieldTrialParametersForTesting(); - } + ~HttpProxyClientSocketPoolTest() override = default; void InitPoolWithProxyDelegate(ProxyDelegate* proxy_delegate) { - pool_ = std::make_unique<HttpProxyClientSocketPool>( - kMaxSockets, kMaxSocketsPerGroup, &transport_socket_pool_, - &ssl_socket_pool_, proxy_delegate, &estimator_, nullptr); + pool_ = std::make_unique<TransportClientSocketPool>( + kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, + &socket_factory_, session_deps_.host_resolver.get(), proxy_delegate, + session_deps_.cert_verifier.get(), + session_deps_.channel_id_service.get(), + session_deps_.transport_security_state.get(), + session_deps_.cert_transparency_verifier.get(), + session_deps_.ct_policy_enforcer.get(), + nullptr /* ssl_client_session_cache */, + nullptr /* ssl_client_session_cache_privacy_mode */, + session_deps_.ssl_config_service.get(), + nullptr /* socket_performance_watcher_factory */, &estimator_, + nullptr /* net_log */); } void AddAuthToCache() { @@ -176,21 +145,27 @@ class HttpProxyClientSocketPoolTest // Returns the a correctly constructed HttpProxyParms // for the HTTP or HTTPS proxy. - scoped_refptr<HttpProxySocketParams> CreateParams(bool tunnel) { - return base::MakeRefCounted<HttpProxySocketParams>( - CreateHttpProxyParams(), CreateHttpsProxyParams(), - quic::QUIC_VERSION_UNSUPPORTED, std::string(), - HostPortPair("www.google.com", tunnel ? 443 : 80), - session_->http_auth_cache(), session_->http_auth_handler_factory(), - session_->spdy_session_pool(), session_->quic_stream_factory(), - /*is_trusted_proxy=*/false, tunnel, TRAFFIC_ANNOTATION_FOR_TESTS); + scoped_refptr<TransportClientSocketPool::SocketParams> CreateParams( + bool tunnel) { + return TransportClientSocketPool::SocketParams:: + CreateFromHttpProxySocketParams( + base::MakeRefCounted<HttpProxySocketParams>( + CreateHttpProxyParams(), CreateHttpsProxyParams(), + quic::QUIC_VERSION_UNSUPPORTED, std::string(), + HostPortPair("www.google.com", tunnel ? 443 : 80), + session_->http_auth_cache(), + session_->http_auth_handler_factory(), + session_->spdy_session_pool(), session_->quic_stream_factory(), + /*is_trusted_proxy=*/false, tunnel, + TRAFFIC_ANNOTATION_FOR_TESTS)); } - scoped_refptr<HttpProxySocketParams> CreateTunnelParams() { + scoped_refptr<TransportClientSocketPool::SocketParams> CreateTunnelParams() { return CreateParams(true); } - scoped_refptr<HttpProxySocketParams> CreateNoTunnelParams() { + scoped_refptr<TransportClientSocketPool::SocketParams> + CreateNoTunnelParams() { return CreateParams(false); } @@ -225,371 +200,31 @@ class HttpProxyClientSocketPoolTest return SpdySessionDependencies::SpdyCreateSession(&session_deps_); } - RequestPriority GetLastTransportRequestPriority() const { - return transport_socket_pool_.last_request_priority(); - } - - RequestPriority GetTransportRequestPriority(size_t index) const { - return transport_socket_pool_.requests()[index]->priority(); - } - const base::HistogramTester& histogram_tester() { return histogram_tester_; } - TestNetworkQualityEstimator* estimator() { return &estimator_; } - - MockTransportClientSocketPool* transport_socket_pool() { - return &transport_socket_pool_; - } - SSLClientSocketPool* ssl_socket_pool() { return &ssl_socket_pool_; } - - base::TimeDelta GetProxyConnectionTimeout() { - // Doesn't actually matter whether or not this is for a tunnel - the - // connection timeout is the same, though it probably shouldn't be the same, - // since tunnels need an extra round trip. - return HttpProxyConnectJob::ConnectionTimeout( - *CreateParams(true /* tunnel */), &estimator_); - } - protected: MockTaggingClientSocketFactory socket_factory_; SpdySessionDependencies session_deps_; TestNetworkQualityEstimator estimator_; - MockTransportClientSocketPool transport_socket_pool_; - MockHostResolver host_resolver_; - std::unique_ptr<CertVerifier> cert_verifier_; - SSLClientSocketPool ssl_socket_pool_; - std::unique_ptr<HttpNetworkSession> session_; base::HistogramTester histogram_tester_; - base::FieldTrialList field_trial_list_; - SpdyTestUtil spdy_util_; std::unique_ptr<SSLSocketDataProvider> ssl_data_; std::unique_ptr<SequencedSocketData> data_; - std::unique_ptr<HttpProxyClientSocketPool> pool_; + std::unique_ptr<TransportClientSocketPool> pool_; ClientSocketHandle handle_; TestCompletionCallback callback_; }; // All tests are run with three different proxy types: HTTP, HTTPS (non-SPDY) // and SPDY. -INSTANTIATE_TEST_CASE_P(HttpProxyType, - HttpProxyClientSocketPoolTest, - ::testing::Values(HTTP, HTTPS, SPDY)); - -TEST_P(HttpProxyClientSocketPoolTest, NoTunnel) { - TestProxyDelegate proxy_delegate; - InitPoolWithProxyDelegate(&proxy_delegate); - - Initialize(base::span<MockRead>(), base::span<MockWrite>(), - base::span<MockRead>(), base::span<MockWrite>()); - - int rv = - handle_.Init("a", CreateNoTunnelParams(), LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(handle_.is_initialized()); - ASSERT_TRUE(handle_.socket()); - EXPECT_TRUE(handle_.socket()->IsConnected()); - EXPECT_FALSE(proxy_delegate.on_before_tunnel_request_called()); - - bool is_secure_proxy = GetParam() == HTTPS || GetParam() == SPDY; - histogram_tester().ExpectTotalCount( - "Net.HttpProxy.ConnectLatency.Insecure.Success", is_secure_proxy ? 0 : 1); - histogram_tester().ExpectTotalCount( - "Net.HttpProxy.ConnectLatency.Secure.Success", is_secure_proxy ? 1 : 0); -} - -TEST_P(HttpProxyClientSocketPoolTest, ProxyDelegateExtraHeaders) { - // It's pretty much impossible to make the SPDY case behave synchronously - // so we skip this test for SPDY. - if (GetParam() == SPDY) - return; - - TestProxyDelegate proxy_delegate; - InitPoolWithProxyDelegate(&proxy_delegate); - - const ProxyServer proxy_server( - GetParam() == HTTP ? ProxyServer::SCHEME_HTTP : ProxyServer::SCHEME_HTTPS, - HostPortPair(GetParam() == HTTP ? kHttpProxyHost : kHttpsProxyHost, - GetParam() == HTTP ? 80 : 443)); - const std::string request = - "CONNECT www.google.com:443 HTTP/1.1\r\n" - "Host: www.google.com:443\r\n" - "Proxy-Connection: keep-alive\r\n" - "Foo: " + - proxy_server.ToURI() + "\r\n\r\n"; - MockWrite writes[] = { - MockWrite(SYNCHRONOUS, 0, request.c_str()), - }; - - const std::string response_header_name = "Foo"; - const std::string response_header_value = "Response"; - const std::string response = "HTTP/1.1 200 Connection Established\r\n" + - response_header_name + ": " + - response_header_value + "\r\n\r\n"; - MockRead reads[] = { - MockRead(SYNCHRONOUS, 1, response.c_str()), - }; - - Initialize(reads, writes, base::span<MockRead>(), base::span<MockWrite>()); - - int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_.callback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsOk()); - - proxy_delegate.VerifyOnTunnelHeadersReceived( - proxy_server, response_header_name, response_header_value); -} - -// Make sure that HttpProxyConnectJob passes on its priority to its -// (non-SSL) socket request on Init. -TEST_P(HttpProxyClientSocketPoolTest, SetSocketRequestPriorityOnInit) { - Initialize(base::span<MockRead>(), base::span<MockWrite>(), - base::span<MockRead>(), base::span<MockWrite>()); - EXPECT_EQ(OK, handle_.Init("a", CreateNoTunnelParams(), HIGHEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), pool_.get(), - NetLogWithSource())); - EXPECT_EQ(HIGHEST, GetLastTransportRequestPriority()); - EXPECT_EQ(HIGHEST, GetTransportRequestPriority(0)); -} - -TEST_P(HttpProxyClientSocketPoolTest, SetPriority) { - data_ = std::make_unique<SequencedSocketData>(); - data_->set_connect_data(MockConnect(ASYNC, OK)); - - socket_factory()->AddSocketDataProvider(data_.get()); - - int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_.callback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - EXPECT_FALSE(handle_.is_initialized()); - EXPECT_FALSE(handle_.socket()); - - EXPECT_EQ(LOW, GetTransportRequestPriority(0)); - - handle_.SetPriority(HIGHEST); - EXPECT_EQ(HIGHEST, GetTransportRequestPriority(0)); -} - -TEST_P(HttpProxyClientSocketPoolTest, NeedAuth) { - MockWrite writes[] = { - MockWrite(ASYNC, 0, - "CONNECT www.google.com:443 HTTP/1.1\r\n" - "Host: www.google.com:443\r\n" - "Proxy-Connection: keep-alive\r\n\r\n"), - }; - MockRead reads[] = { - // No credentials. - MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"), - MockRead(ASYNC, 2, "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), - MockRead(ASYNC, 3, "Content-Length: 10\r\n\r\n"), - MockRead(ASYNC, 4, "0123456789"), - }; - spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect( - NULL, 0, 1, LOW, HostPortPair("www.google.com", 443))); - spdy::SpdySerializedFrame rst( - spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL)); - MockWrite spdy_writes[] = { - CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC), - }; - spdy::SpdyHeaderBlock resp_block; - resp_block[spdy::kHttp2StatusHeader] = "407"; - resp_block["proxy-authenticate"] = "Basic realm=\"MyRealm1\""; - - spdy::SpdySerializedFrame resp( - spdy_util_.ConstructSpdyReply(1, std::move(resp_block))); - MockRead spdy_reads[] = {CreateMockRead(resp, 1, ASYNC), - MockRead(ASYNC, 0, 3)}; - - Initialize(reads, writes, spdy_reads, spdy_writes); - - int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_.callback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - EXPECT_FALSE(handle_.is_initialized()); - EXPECT_FALSE(handle_.socket()); - - rv = callback_.WaitForResult(); - EXPECT_THAT(rv, IsError(ERR_PROXY_AUTH_REQUESTED)); - EXPECT_TRUE(handle_.is_initialized()); - ASSERT_TRUE(handle_.socket()); - ProxyClientSocket* tunnel_socket = - static_cast<ProxyClientSocket*>(handle_.socket()); - if (GetParam() == SPDY) { - EXPECT_TRUE(tunnel_socket->IsConnected()); - EXPECT_TRUE(tunnel_socket->IsUsingSpdy()); - } else { - EXPECT_FALSE(tunnel_socket->IsConnected()); - EXPECT_FALSE(tunnel_socket->IsUsingSpdy()); - } -} - -TEST_P(HttpProxyClientSocketPoolTest, HaveAuth) { - // It's pretty much impossible to make the SPDY case behave synchronously - // so we skip this test for SPDY - if (GetParam() == SPDY) - return; - MockWrite writes[] = { - MockWrite(SYNCHRONOUS, 0, - "CONNECT www.google.com:443 HTTP/1.1\r\n" - "Host: www.google.com:443\r\n" - "Proxy-Connection: keep-alive\r\n" - "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), - }; - MockRead reads[] = { - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"), - }; - - Initialize(reads, writes, base::span<MockRead>(), base::span<MockWrite>()); - AddAuthToCache(); - - int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_.callback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(handle_.is_initialized()); - ASSERT_TRUE(handle_.socket()); - EXPECT_TRUE(handle_.socket()->IsConnected()); -} - -TEST_P(HttpProxyClientSocketPoolTest, AsyncHaveAuth) { - MockWrite writes[] = { - MockWrite(ASYNC, 0, - "CONNECT www.google.com:443 HTTP/1.1\r\n" - "Host: www.google.com:443\r\n" - "Proxy-Connection: keep-alive\r\n" - "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), - }; - MockRead reads[] = { - MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"), - }; - - spdy::SpdySerializedFrame req( - spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1, LOW, - HostPortPair("www.google.com", 443))); - MockWrite spdy_writes[] = {CreateMockWrite(req, 0, ASYNC)}; - spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1)); - MockRead spdy_reads[] = { - CreateMockRead(resp, 1, ASYNC), - // Connection stays open. - MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), - }; - - Initialize(reads, writes, spdy_reads, spdy_writes); - AddAuthToCache(); - - int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_.callback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - EXPECT_FALSE(handle_.is_initialized()); - EXPECT_FALSE(handle_.socket()); - - EXPECT_THAT(callback_.WaitForResult(), IsOk()); - EXPECT_TRUE(handle_.is_initialized()); - ASSERT_TRUE(handle_.socket()); - EXPECT_TRUE(handle_.socket()->IsConnected()); -} - -// Make sure that HttpProxyConnectJob passes on its priority to its -// SPDY session's socket request on Init, and on SetPriority. -TEST_P(HttpProxyClientSocketPoolTest, SetSpdySessionSocketRequestPriority) { - if (GetParam() != SPDY) - return; - - spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect( - kAuthHeaders, kAuthHeadersSize, 1, HIGHEST, - HostPortPair("www.google.com", 443))); - MockWrite spdy_writes[] = {CreateMockWrite(req, 0, ASYNC)}; - spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1)); - MockRead spdy_reads[] = {CreateMockRead(resp, 1, ASYNC), - MockRead(ASYNC, 0, 2)}; - - Initialize(base::span<MockRead>(), base::span<MockWrite>(), spdy_reads, - spdy_writes); - AddAuthToCache(); - - EXPECT_EQ( - ERR_IO_PENDING, - handle_.Init("a", CreateTunnelParams(), MEDIUM, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_.callback(), pool_.get(), NetLogWithSource())); - EXPECT_EQ(MEDIUM, GetLastTransportRequestPriority()); - EXPECT_EQ(MEDIUM, GetTransportRequestPriority(0)); - - handle_.SetPriority(HIGHEST); - // Expect frame with HIGHEST priority, not MEDIUM. - EXPECT_THAT(callback_.WaitForResult(), IsOk()); -} - -TEST_P(HttpProxyClientSocketPoolTest, TCPError) { - if (GetParam() == SPDY) - return; - data_.reset(new SequencedSocketData()); - data_->set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_CLOSED)); - - socket_factory()->AddSocketDataProvider(data_.get()); - - int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_.callback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - EXPECT_FALSE(handle_.is_initialized()); - EXPECT_FALSE(handle_.socket()); - - EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_PROXY_CONNECTION_FAILED)); - - EXPECT_FALSE(handle_.is_initialized()); - EXPECT_FALSE(handle_.socket()); - - bool is_secure_proxy = GetParam() == HTTPS; - histogram_tester().ExpectTotalCount( - "Net.HttpProxy.ConnectLatency.Insecure.Error", is_secure_proxy ? 0 : 1); - histogram_tester().ExpectTotalCount( - "Net.HttpProxy.ConnectLatency.Secure.Error", is_secure_proxy ? 1 : 0); -} - -TEST_P(HttpProxyClientSocketPoolTest, SSLError) { - if (GetParam() == HTTP) - return; - data_.reset(new SequencedSocketData()); - data_->set_connect_data(MockConnect(ASYNC, OK)); - socket_factory()->AddSocketDataProvider(data_.get()); - - ssl_data_.reset(new SSLSocketDataProvider(ASYNC, - ERR_CERT_AUTHORITY_INVALID)); - if (GetParam() == SPDY) { - InitializeSpdySsl(); - } - socket_factory()->AddSSLSocketDataProvider(ssl_data_.get()); - - int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_.callback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - EXPECT_FALSE(handle_.is_initialized()); - EXPECT_FALSE(handle_.socket()); - - EXPECT_THAT(callback_.WaitForResult(), - IsError(ERR_PROXY_CERTIFICATE_INVALID)); - - EXPECT_FALSE(handle_.is_initialized()); - EXPECT_FALSE(handle_.socket()); - histogram_tester().ExpectTotalCount( - "Net.HttpProxy.ConnectLatency.Secure.Error", 1); - histogram_tester().ExpectTotalCount( - "Net.HttpProxy.ConnectLatency.Insecure.Error", 0); -} +INSTANTIATE_TEST_SUITE_P(HttpProxyType, + HttpProxyClientSocketPoolTest, + ::testing::Values(HTTP, HTTPS, SPDY)); TEST_P(HttpProxyClientSocketPoolTest, SslClientAuth) { if (GetParam() == HTTP) @@ -605,9 +240,10 @@ TEST_P(HttpProxyClientSocketPoolTest, SslClientAuth) { } socket_factory()->AddSSLSocketDataProvider(ssl_data_.get()); - int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_.callback(), pool_.get(), NetLogWithSource()); + int rv = handle_.Init( + "a", CreateTunnelParams(), LOW, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, callback_.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle_.is_initialized()); EXPECT_FALSE(handle_.socket()); @@ -623,119 +259,6 @@ TEST_P(HttpProxyClientSocketPoolTest, SslClientAuth) { "Net.HttpProxy.ConnectLatency.Insecure.Error", 0); } -TEST_P(HttpProxyClientSocketPoolTest, TunnelUnexpectedClose) { - MockWrite writes[] = { - MockWrite(ASYNC, 0, - "CONNECT www.google.com:443 HTTP/1.1\r\n" - "Host: www.google.com:443\r\n" - "Proxy-Connection: keep-alive\r\n" - "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), - }; - MockRead reads[] = { - MockRead(ASYNC, 1, "HTTP/1.1 200 Conn"), - MockRead(ASYNC, ERR_CONNECTION_CLOSED, 2), - }; - spdy::SpdySerializedFrame req( - spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1, LOW, - HostPortPair("www.google.com", 443))); - MockWrite spdy_writes[] = {CreateMockWrite(req, 0, ASYNC)}; - MockRead spdy_reads[] = { - MockRead(ASYNC, ERR_CONNECTION_CLOSED, 1), - }; - - Initialize(reads, writes, spdy_reads, spdy_writes); - AddAuthToCache(); - - int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_.callback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - EXPECT_FALSE(handle_.is_initialized()); - EXPECT_FALSE(handle_.socket()); - - if (GetParam() == SPDY) { - // SPDY cannot process a headers block unless it's complete and so it - // returns ERR_CONNECTION_CLOSED in this case. - EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_CONNECTION_CLOSED)); - } else { - EXPECT_THAT(callback_.WaitForResult(), - IsError(ERR_RESPONSE_HEADERS_TRUNCATED)); - } - EXPECT_FALSE(handle_.is_initialized()); - EXPECT_FALSE(handle_.socket()); -} - -TEST_P(HttpProxyClientSocketPoolTest, Tunnel1xxResponse) { - // Tests that 1xx responses are rejected for a CONNECT request. - if (GetParam() == SPDY) { - // SPDY doesn't have 1xx responses. - return; - } - - MockWrite writes[] = { - MockWrite(ASYNC, 0, - "CONNECT www.google.com:443 HTTP/1.1\r\n" - "Host: www.google.com:443\r\n" - "Proxy-Connection: keep-alive\r\n\r\n"), - }; - MockRead reads[] = { - MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"), - MockRead(ASYNC, 2, "HTTP/1.1 200 Connection Established\r\n\r\n"), - }; - - Initialize(reads, writes, base::span<MockRead>(), base::span<MockWrite>()); - - int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_.callback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - EXPECT_FALSE(handle_.is_initialized()); - EXPECT_FALSE(handle_.socket()); - - EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_TUNNEL_CONNECTION_FAILED)); -} - -TEST_P(HttpProxyClientSocketPoolTest, TunnelSetupError) { - MockWrite writes[] = { - MockWrite(ASYNC, 0, - "CONNECT www.google.com:443 HTTP/1.1\r\n" - "Host: www.google.com:443\r\n" - "Proxy-Connection: keep-alive\r\n" - "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), - }; - MockRead reads[] = { - MockRead(ASYNC, 1, "HTTP/1.1 304 Not Modified\r\n\r\n"), - }; - spdy::SpdySerializedFrame req( - spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1, LOW, - HostPortPair("www.google.com", 443))); - spdy::SpdySerializedFrame rst( - spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL)); - MockWrite spdy_writes[] = { - CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC), - }; - spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1)); - MockRead spdy_reads[] = { - CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3), - }; - - Initialize(reads, writes, spdy_reads, spdy_writes); - AddAuthToCache(); - - int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_.callback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - EXPECT_FALSE(handle_.is_initialized()); - EXPECT_FALSE(handle_.socket()); - - rv = callback_.WaitForResult(); - // All Proxy CONNECT responses are not trustworthy - EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED)); - EXPECT_FALSE(handle_.is_initialized()); - EXPECT_FALSE(handle_.socket()); -} - TEST_P(HttpProxyClientSocketPoolTest, TunnelSetupRedirect) { const std::string redirectTarget = "https://foo.google.com/"; @@ -777,9 +300,10 @@ TEST_P(HttpProxyClientSocketPoolTest, TunnelSetupRedirect) { Initialize(reads, writes, spdy_reads, spdy_writes); AddAuthToCache(); - int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_.callback(), pool_.get(), NetLogWithSource()); + int rv = handle_.Init( + "a", CreateTunnelParams(), LOW, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, callback_.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle_.is_initialized()); EXPECT_FALSE(handle_.socket()); @@ -815,250 +339,4 @@ TEST_P(HttpProxyClientSocketPoolTest, TunnelSetupRedirect) { } } -TEST_P(HttpProxyClientSocketPoolTest, ProxyPoolMinTimeout) { - // Set RTT estimate to a low value. - base::TimeDelta rtt_estimate = base::TimeDelta::FromMilliseconds(1); - estimator()->SetStartTimeNullHttpRtt(rtt_estimate); - - EXPECT_LE(base::TimeDelta(), GetProxyConnectionTimeout()); - - // Test against a large value. - EXPECT_GE(base::TimeDelta::FromMinutes(10), GetProxyConnectionTimeout()); - -#if (defined(OS_ANDROID) || defined(OS_IOS)) - EXPECT_EQ(base::TimeDelta::FromSeconds(8), GetProxyConnectionTimeout()); -#else - EXPECT_EQ(base::TimeDelta::FromSeconds(30), GetProxyConnectionTimeout()); -#endif -} - -TEST_P(HttpProxyClientSocketPoolTest, ProxyPoolMaxTimeout) { - // Set RTT estimate to a high value. - base::TimeDelta rtt_estimate = base::TimeDelta::FromSeconds(100); - estimator()->SetStartTimeNullHttpRtt(rtt_estimate); - - EXPECT_LE(base::TimeDelta(), GetProxyConnectionTimeout()); - - // Test against a large value. - EXPECT_GE(base::TimeDelta::FromMinutes(10), GetProxyConnectionTimeout()); - -#if (defined(OS_ANDROID) || defined(OS_IOS)) - EXPECT_EQ(base::TimeDelta::FromSeconds(30), GetProxyConnectionTimeout()); -#else - EXPECT_EQ(base::TimeDelta::FromSeconds(60), GetProxyConnectionTimeout()); -#endif -} - -// Tests the connection timeout values when the field trial parameters are -// specified. -TEST_P(HttpProxyClientSocketPoolTest, ProxyPoolTimeoutWithExperiment) { - // Timeout should be kMultiplier times the HTTP RTT estimate. - const int kMultiplier = 4; - const base::TimeDelta kMinTimeout = base::TimeDelta::FromSeconds(8); - const base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(20); - - InitAdaptiveTimeoutFieldTrialWithParams(false, kMultiplier, kMultiplier, - kMinTimeout, kMaxTimeout); - EXPECT_LE(base::TimeDelta(), GetProxyConnectionTimeout()); - - base::TimeDelta rtt_estimate = base::TimeDelta::FromSeconds(4); - estimator()->SetStartTimeNullHttpRtt(rtt_estimate); - base::TimeDelta expected_connection_timeout = kMultiplier * rtt_estimate; - EXPECT_EQ(expected_connection_timeout, GetProxyConnectionTimeout()); - - // Connection timeout should not exceed kMaxTimeout. - rtt_estimate = base::TimeDelta::FromSeconds(25); - estimator()->SetStartTimeNullHttpRtt(rtt_estimate); - EXPECT_EQ(kMaxTimeout, GetProxyConnectionTimeout()); - - // Connection timeout should not be less than kMinTimeout. - rtt_estimate = base::TimeDelta::FromSeconds(0); - estimator()->SetStartTimeNullHttpRtt(rtt_estimate); - EXPECT_EQ(kMinTimeout, GetProxyConnectionTimeout()); -} - -// Tests the connection timeout values when the field trial parameters are -// specified. -TEST_P(HttpProxyClientSocketPoolTest, - ProxyPoolTimeoutWithExperimentDifferentParams) { - // Timeout should be kMultiplier times the HTTP RTT estimate. - const int kMultiplier = 3; - const base::TimeDelta kMinTimeout = base::TimeDelta::FromSeconds(2); - const base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(30); - - InitAdaptiveTimeoutFieldTrialWithParams(false, kMultiplier, kMultiplier, - kMinTimeout, kMaxTimeout); - EXPECT_LE(base::TimeDelta(), GetProxyConnectionTimeout()); - - base::TimeDelta rtt_estimate = base::TimeDelta::FromSeconds(2); - estimator()->SetStartTimeNullHttpRtt(rtt_estimate); - EXPECT_EQ(kMultiplier * rtt_estimate, GetProxyConnectionTimeout()); - - // A change in RTT estimate should also change the connection timeout. - rtt_estimate = base::TimeDelta::FromSeconds(7); - estimator()->SetStartTimeNullHttpRtt(rtt_estimate); - EXPECT_EQ(kMultiplier * rtt_estimate, GetProxyConnectionTimeout()); - - // Connection timeout should not exceed kMaxTimeout. - rtt_estimate = base::TimeDelta::FromSeconds(35); - estimator()->SetStartTimeNullHttpRtt(rtt_estimate); - EXPECT_EQ(kMaxTimeout, GetProxyConnectionTimeout()); - - // Connection timeout should not be less than kMinTimeout. - rtt_estimate = base::TimeDelta::FromSeconds(0); - estimator()->SetStartTimeNullHttpRtt(rtt_estimate); - EXPECT_EQ(kMinTimeout, GetProxyConnectionTimeout()); -} - -TEST_P(HttpProxyClientSocketPoolTest, ProxyPoolTimeoutWithConnectionProperty) { - const int kSecureMultiplier = 3; - const int kNonSecureMultiplier = 5; - const base::TimeDelta kMinTimeout = base::TimeDelta::FromSeconds(2); - const base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(30); - - InitAdaptiveTimeoutFieldTrialWithParams( - false, kSecureMultiplier, kNonSecureMultiplier, kMinTimeout, kMaxTimeout); - - HttpProxyClientSocketPool::HttpProxyConnectJobFactory job_factory( - transport_socket_pool(), ssl_socket_pool(), nullptr, estimator(), - nullptr); - - const base::TimeDelta kRttEstimate = base::TimeDelta::FromSeconds(2); - estimator()->SetStartTimeNullHttpRtt(kRttEstimate); - // By default, connection timeout should return the timeout for secure - // proxies. - if (GetParam() != HTTP) { - EXPECT_EQ(kSecureMultiplier * kRttEstimate, GetProxyConnectionTimeout()); - } else { - EXPECT_EQ(kNonSecureMultiplier * kRttEstimate, GetProxyConnectionTimeout()); - } -} - -// Tests the connection timeout values when the field trial parameters are not -// specified. -TEST_P(HttpProxyClientSocketPoolTest, - ProxyPoolTimeoutWithExperimentDefaultParams) { - InitAdaptiveTimeoutFieldTrialWithParams(true, 0, 0, base::TimeDelta(), - base::TimeDelta()); - EXPECT_LE(base::TimeDelta(), GetProxyConnectionTimeout()); - - // Timeout should be |http_rtt_multiplier| times the HTTP RTT - // estimate. - base::TimeDelta rtt_estimate = base::TimeDelta::FromMilliseconds(10); - estimator()->SetStartTimeNullHttpRtt(rtt_estimate); - // Connection timeout should not be less than the HTTP RTT estimate. - EXPECT_LE(rtt_estimate, GetProxyConnectionTimeout()); - - // A change in RTT estimate should also change the connection timeout. - rtt_estimate = base::TimeDelta::FromSeconds(10); - estimator()->SetStartTimeNullHttpRtt(rtt_estimate); - // Connection timeout should not be less than the HTTP RTT estimate. - EXPECT_LE(rtt_estimate, GetProxyConnectionTimeout()); - - // Set RTT to a very large value. - rtt_estimate = base::TimeDelta::FromMinutes(60); - estimator()->SetStartTimeNullHttpRtt(rtt_estimate); - EXPECT_GT(rtt_estimate, GetProxyConnectionTimeout()); - - // Set RTT to a very small value. - rtt_estimate = base::TimeDelta::FromSeconds(0); - estimator()->SetStartTimeNullHttpRtt(rtt_estimate); - EXPECT_LT(rtt_estimate, GetProxyConnectionTimeout()); -} - -// It would be nice to also test the timeouts in HttpProxyClientSocketPool. - -// Test that SocketTag passed into HttpProxyClientSocketPool is applied to -// returned underlying TCP sockets. -#if defined(OS_ANDROID) -TEST_P(HttpProxyClientSocketPoolTest, Tag) { - // Socket tagging only supports Android without data reduction proxy, so only - // HTTP proxies are supported. - if (GetParam() != HTTP) - return; - Initialize(base::span<MockRead>(), base::span<MockWrite>(), - base::span<MockRead>(), base::span<MockWrite>()); - SocketTag tag1(SocketTag::UNSET_UID, 0x12345678); - SocketTag tag2(getuid(), 0x87654321); - - // Verify requested socket is tagged properly. - int rv = - handle_.Init("a", CreateNoTunnelParams(), LOW, tag1, - ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(handle_.is_initialized()); - ASSERT_TRUE(handle_.socket()); - EXPECT_TRUE(handle_.socket()->IsConnected()); - EXPECT_EQ(socket_factory()->GetLastProducedTCPSocket()->tag(), tag1); - EXPECT_TRUE( - socket_factory()->GetLastProducedTCPSocket()->tagged_before_connected()); - - // Verify reused socket is retagged properly. - StreamSocket* socket = handle_.socket(); - handle_.Reset(); - rv = handle_.Init("a", CreateNoTunnelParams(), LOW, tag2, - ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(handle_.socket()); - EXPECT_TRUE(handle_.socket()->IsConnected()); - EXPECT_EQ(handle_.socket(), socket); - EXPECT_EQ(socket_factory()->GetLastProducedTCPSocket()->tag(), tag2); - handle_.socket()->Disconnect(); - handle_.Reset(); -} - -TEST_P(HttpProxyClientSocketPoolTest, TagWithProxy) { - // Socket tagging only supports Android without data reduction proxy, so only - // HTTP proxies are supported. - if (GetParam() != HTTP) - return; - std::string request = - "CONNECT www.google.com:443 HTTP/1.1\r\n" - "Host: www.google.com:443\r\n" - "Proxy-Connection: keep-alive\r\n" - "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"; - MockWrite writes[] = { - MockWrite(SYNCHRONOUS, 0, request.c_str()), - }; - MockRead reads[] = { - MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"), - }; - - Initialize(reads, writes, base::span<MockRead>(), base::span<MockWrite>()); - AddAuthToCache(); - - SocketTag tag1(SocketTag::UNSET_UID, 0x12345678); - SocketTag tag2(getuid(), 0x87654321); - - // Verify requested socket is tagged properly. - int rv = - handle_.Init("a", CreateTunnelParams(), LOW, tag1, - ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(handle_.is_initialized()); - ASSERT_TRUE(handle_.socket()); - EXPECT_TRUE(handle_.socket()->IsConnected()); - EXPECT_EQ(socket_factory()->GetLastProducedTCPSocket()->tag(), tag1); - EXPECT_TRUE( - socket_factory()->GetLastProducedTCPSocket()->tagged_before_connected()); - - // Verify reused socket is retagged properly. - StreamSocket* socket = handle_.socket(); - handle_.Reset(); - rv = handle_.Init("a", CreateNoTunnelParams(), LOW, tag2, - ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), pool_.get(), NetLogWithSource()); - EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(handle_.socket()); - EXPECT_TRUE(handle_.socket()->IsConnected()); - EXPECT_EQ(handle_.socket(), socket); - EXPECT_EQ(socket_factory()->GetLastProducedTCPSocket()->tag(), tag2); - handle_.socket()->Disconnect(); - handle_.Reset(); -} -#endif - } // namespace net diff --git a/chromium/net/http/http_proxy_client_socket_unittest.cc b/chromium/net/http/http_proxy_client_socket_unittest.cc index d4d11b99d7f..226a671030a 100644 --- a/chromium/net/http/http_proxy_client_socket_unittest.cc +++ b/chromium/net/http/http_proxy_client_socket_unittest.cc @@ -8,7 +8,6 @@ #include "net/base/address_list.h" #include "net/base/host_port_pair.h" #include "net/base/proxy_server.h" -#include "net/log/test_net_log.h" #include "net/socket/next_proto.h" #include "net/socket/socket_tag.h" #include "net/socket/socket_test_util.h" @@ -21,18 +20,16 @@ namespace { TEST(HttpProxyClientSocketTest, Tag) { StaticSocketDataProvider data; - TestNetLog log; MockTaggingStreamSocket* tagging_sock = - new MockTaggingStreamSocket(std::unique_ptr<StreamSocket>( - new MockTCPClientSocket(AddressList(), &log, &data))); - - std::unique_ptr<ClientSocketHandle> connection(new ClientSocketHandle); - // |connection| takes ownership of |tagging_sock|, but keep a - // non-owning pointer to it. - connection->SetSocket(std::unique_ptr<StreamSocket>(tagging_sock)); - HttpProxyClientSocket socket( - std::move(connection), "", HostPortPair(), ProxyServer(), nullptr, false, - false, NextProto(), nullptr, false, TRAFFIC_ANNOTATION_FOR_TESTS); + new MockTaggingStreamSocket(std::make_unique<MockTCPClientSocket>( + AddressList(), nullptr /* net_log */, &data)); + + // |socket| takes ownership of |tagging_sock|, but the test keeps a non-owning + // pointer to it. + HttpProxyClientSocket socket(std::unique_ptr<StreamSocket>(tagging_sock), "", + HostPortPair(), ProxyServer(), nullptr, false, + false, NextProto(), nullptr, false, + TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_EQ(tagging_sock->tag(), SocketTag()); #if defined(OS_ANDROID) diff --git a/chromium/net/http/http_proxy_client_socket_wrapper.cc b/chromium/net/http/http_proxy_client_socket_wrapper.cc index dcc9c6ae6e6..2829cb4a22f 100644 --- a/chromium/net/http/http_proxy_client_socket_wrapper.cc +++ b/chromium/net/http/http_proxy_client_socket_wrapper.cc @@ -8,9 +8,11 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/callback.h" #include "base/callback_helpers.h" #include "base/memory/weak_ptr.h" #include "base/metrics/histogram_macros.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "net/base/proxy_delegate.h" #include "net/http/http_proxy_client_socket.h" @@ -23,7 +25,7 @@ #include "net/socket/client_socket_factory.h" #include "net/socket/client_socket_handle.h" #include "net/socket/socket_tag.h" -#include "net/socket/transport_client_socket_pool.h" +#include "net/socket/ssl_connect_job.h" #include "net/socket/transport_connect_job.h" #include "net/spdy/spdy_proxy_client_socket.h" #include "net/spdy/spdy_session.h" @@ -36,14 +38,11 @@ namespace net { HttpProxyClientSocketWrapper::HttpProxyClientSocketWrapper( - const std::string& group_name, + const OnProxyAuthChallengeCallback& on_proxy_auth_callback, RequestPriority priority, - const SocketTag& socket_tag, - ClientSocketPool::RespectLimits respect_limits, base::TimeDelta connect_timeout_duration, base::TimeDelta proxy_negotiation_timeout_duration, - TransportClientSocketPool* transport_pool, - SSLClientSocketPool* ssl_pool, + const CommonConnectJobParams& common_connect_job_params, const scoped_refptr<TransportSocketParams>& transport_params, const scoped_refptr<SSLSocketParams>& ssl_params, quic::QuicTransportVersion quic_version, @@ -55,18 +54,13 @@ HttpProxyClientSocketWrapper::HttpProxyClientSocketWrapper( QuicStreamFactory* quic_stream_factory, bool is_trusted_proxy, bool tunnel, - ProxyDelegate* proxy_delegate, const NetworkTrafficAnnotationTag& traffic_annotation, const NetLogWithSource& net_log) - : next_state_(STATE_NONE), - group_name_(group_name), + : on_proxy_auth_callback_(on_proxy_auth_callback), + next_state_(STATE_NONE), priority_(priority), - initial_socket_tag_(socket_tag), - respect_limits_(respect_limits), connect_timeout_duration_(connect_timeout_duration), proxy_negotiation_timeout_duration_(proxy_negotiation_timeout_duration), - transport_pool_(transport_pool), - ssl_pool_(ssl_pool), transport_params_(transport_params), ssl_params_(ssl_params), quic_version_(quic_version), @@ -75,22 +69,25 @@ HttpProxyClientSocketWrapper::HttpProxyClientSocketWrapper( spdy_session_pool_(spdy_session_pool), has_restarted_(false), tunnel_(tunnel), - proxy_delegate_(proxy_delegate), + common_connect_job_params_(common_connect_job_params), using_spdy_(false), is_trusted_proxy_(is_trusted_proxy), + has_established_connection_(false), quic_stream_factory_(quic_stream_factory), http_auth_controller_( tunnel ? new HttpAuthController( HttpAuth::AUTH_PROXY, GURL((ssl_params_.get() ? "https://" : "http://") + - GetDestination().host_port_pair().ToString()), + GetDestination().ToString()), http_auth_cache, - http_auth_handler_factory) + http_auth_handler_factory, + common_connect_job_params_.host_resolver) : nullptr), net_log_(NetLogWithSource::Make( net_log.net_log(), NetLogSourceType::PROXY_CLIENT_SOCKET_WRAPPER)), - traffic_annotation_(traffic_annotation) { + traffic_annotation_(traffic_annotation), + weak_ptr_factory_(this) { net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE, net_log.source().ToEventParametersCallback()); // If doing a QUIC proxy, |quic_version| must not be @@ -112,12 +109,11 @@ HttpProxyClientSocketWrapper::~HttpProxyClientSocketWrapper() { LoadState HttpProxyClientSocketWrapper::GetConnectLoadState() const { switch (next_state_) { - case STATE_BEGIN_CONNECT: case STATE_TCP_CONNECT: case STATE_TCP_CONNECT_COMPLETE: case STATE_SSL_CONNECT: case STATE_SSL_CONNECT_COMPLETE: - return transport_socket_handle_->GetLoadState(); + return nested_connect_job_->GetLoadState(); case STATE_HTTP_PROXY_CONNECT: case STATE_HTTP_PROXY_CONNECT_COMPLETE: case STATE_SPDY_PROXY_CREATE_STREAM: @@ -128,6 +124,7 @@ LoadState HttpProxyClientSocketWrapper::GetConnectLoadState() const { case STATE_RESTART_WITH_AUTH: case STATE_RESTART_WITH_AUTH_COMPLETE: return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL; + case STATE_BEGIN_CONNECT: case STATE_NONE: // May be possible for this method to be called after an error, shouldn't // be called after a successful connect. @@ -142,15 +139,10 @@ HttpProxyClientSocketWrapper::GetAdditionalErrorState() { } void HttpProxyClientSocketWrapper::SetPriority(RequestPriority priority) { - if (respect_limits_ == ClientSocketPool::RespectLimits::DISABLED) { - DCHECK_EQ(MAXIMUM_PRIORITY, priority_); - return; - } - priority_ = priority; - if (transport_socket_handle_) - transport_socket_handle_->SetPriority(priority); + if (nested_connect_job_) + nested_connect_job_->ChangePriority(priority); if (spdy_stream_request_) spdy_stream_request_->SetPriority(priority); @@ -169,23 +161,12 @@ const HttpResponseInfo* HttpProxyClientSocketWrapper::GetConnectResponseInfo() return nullptr; } -std::unique_ptr<HttpStream> -HttpProxyClientSocketWrapper::CreateConnectResponseStream() { - if (transport_socket_) - return transport_socket_->CreateConnectResponseStream(); - return nullptr; -} - int HttpProxyClientSocketWrapper::RestartWithAuth( CompletionOnceCallback callback) { - DCHECK(!callback.is_null()); - DCHECK(connect_callback_.is_null()); - DCHECK(transport_socket_); - DCHECK_EQ(STATE_NONE, next_state_); - - connect_callback_ = std::move(callback); - next_state_ = STATE_RESTART_WITH_AUTH; - return DoLoop(OK); + // TODO(mmenke): Remove this method, once this class is merged with + // HttpProxyConnectJob. + NOTREACHED(); + return ERR_UNEXPECTED; } const scoped_refptr<HttpAuthController>& @@ -231,15 +212,8 @@ void HttpProxyClientSocketWrapper::Disconnect() { next_state_ = STATE_NONE; spdy_stream_request_.reset(); quic_stream_request_.reset(); - if (transport_socket_handle_) { - if (transport_socket_handle_->socket()) - transport_socket_handle_->socket()->Disconnect(); - transport_socket_handle_->Reset(); - transport_socket_handle_.reset(); - } - - if (transport_socket_) - transport_socket_->Disconnect(); + nested_connect_job_.reset(); + transport_socket_.reset(); } bool HttpProxyClientSocketWrapper::IsConnected() const { @@ -397,6 +371,37 @@ int HttpProxyClientSocketWrapper::GetLocalAddress(IPEndPoint* address) const { return ERR_SOCKET_NOT_CONNECTED; } +void HttpProxyClientSocketWrapper::OnConnectJobComplete(int result, + ConnectJob* job) { + DCHECK_EQ(nested_connect_job_.get(), job); + DCHECK(next_state_ == STATE_TCP_CONNECT_COMPLETE || + next_state_ == STATE_SSL_CONNECT_COMPLETE); + OnIOComplete(result); +} + +bool HttpProxyClientSocketWrapper::HasEstablishedConnection() { + if (has_established_connection_) + return true; + + // It's possible the nested connect job has established a connection, but + // hasn't completed yet (For example, an SSLConnectJob may be negotiating + // SSL). + if (nested_connect_job_) { + has_established_connection_ = + nested_connect_job_->HasEstablishedConnection(); + } + return has_established_connection_; +} + +void HttpProxyClientSocketWrapper::OnNeedsProxyAuth( + const HttpResponseInfo& response, + HttpAuthController* auth_controller, + base::OnceClosure restart_with_auth_callback, + ConnectJob* job) { + // This class can't sit on top of another proxy socket class. + NOTREACHED(); +} + ProxyServer::Scheme HttpProxyClientSocketWrapper::GetProxyServerScheme() const { if (quic_version_ != quic::QUIC_VERSION_UNSUPPORTED) return ProxyServer::SCHEME_QUIC; @@ -416,6 +421,18 @@ void HttpProxyClientSocketWrapper::OnIOComplete(int result) { } } +void HttpProxyClientSocketWrapper::RestartWithAuthCredentials() { + DCHECK(!connect_callback_.is_null()); + DCHECK(transport_socket_); + DCHECK_EQ(STATE_NONE, next_state_); + + // Always do this asynchronously, to avoid re-entrancy. + next_state_ = STATE_RESTART_WITH_AUTH; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&HttpProxyClientSocketWrapper::OnIOComplete, + weak_ptr_factory_.GetWeakPtr(), net::OK)); +} + int HttpProxyClientSocketWrapper::DoLoop(int result) { DCHECK_NE(next_state_, STATE_NONE); @@ -489,6 +506,11 @@ int HttpProxyClientSocketWrapper::DoBeginConnect() { switch (GetProxyServerScheme()) { case ProxyServer::SCHEME_QUIC: next_state_ = STATE_QUIC_PROXY_CREATE_SESSION; + // QUIC connections are always considered to have been established. + // |has_established_connection_| is only used to start retries if a + // connection hasn't been established yet, and QUIC has its own connection + // establishment logic. + has_established_connection_ = true; break; case ProxyServer::SCHEME_HTTP: next_state_ = STATE_TCP_CONNECT; @@ -504,15 +526,10 @@ int HttpProxyClientSocketWrapper::DoBeginConnect() { int HttpProxyClientSocketWrapper::DoTransportConnect() { next_state_ = STATE_TCP_CONNECT_COMPLETE; - transport_socket_handle_.reset(new ClientSocketHandle()); - return transport_socket_handle_->Init( - group_name_, - TransportClientSocketPool::SocketParams::CreateFromTransportSocketParams( - transport_params_), - priority_, initial_socket_tag_, respect_limits_, - base::Bind(&HttpProxyClientSocketWrapper::OnIOComplete, - base::Unretained(this)), - transport_pool_, net_log_); + nested_connect_job_ = TransportConnectJob::CreateTransportConnectJob( + transport_params_, priority_, common_connect_job_params_, this, + &net_log_); + return nested_connect_job_->Connect(); } int HttpProxyClientSocketWrapper::DoTransportConnectComplete(int result) { @@ -528,6 +545,8 @@ int HttpProxyClientSocketWrapper::DoTransportConnectComplete(int result) { return ERR_PROXY_CONNECTION_FAILED; } + has_established_connection_ = true; + // Reset the timer to just the length of time allowed for HttpProxy handshake // so that a fast TCP connection plus a slow HttpProxy failure doesn't take // longer to timeout than it should. @@ -540,12 +559,10 @@ int HttpProxyClientSocketWrapper::DoTransportConnectComplete(int result) { int HttpProxyClientSocketWrapper::DoSSLConnect() { DCHECK(ssl_params_); if (tunnel_) { - SpdySessionKey key(ssl_params_->GetDirectConnectionParams() - ->destination() - .host_port_pair(), + SpdySessionKey key(ssl_params_->GetDirectConnectionParams()->destination(), ProxyServer::Direct(), PRIVACY_MODE_DISABLED, SpdySessionKey::IsProxySession::kTrue, - initial_socket_tag_); + common_connect_job_params_.socket_tag); if (spdy_session_pool_->FindAvailableSession( key, /* enable_ip_based_pooling = */ true, /* is_websocket = */ false, net_log_)) { @@ -555,22 +572,23 @@ int HttpProxyClientSocketWrapper::DoSSLConnect() { } } next_state_ = STATE_SSL_CONNECT_COMPLETE; - transport_socket_handle_.reset(new ClientSocketHandle()); - return transport_socket_handle_->Init( - group_name_, ssl_params_, priority_, initial_socket_tag_, respect_limits_, - base::Bind(&HttpProxyClientSocketWrapper::OnIOComplete, - base::Unretained(this)), - ssl_pool_, net_log_); + nested_connect_job_ = std::make_unique<SSLConnectJob>( + priority_, common_connect_job_params_, ssl_params_, this, &net_log_); + return nested_connect_job_->Connect(); } int HttpProxyClientSocketWrapper::DoSSLConnectComplete(int result) { if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { - DCHECK( - transport_socket_handle_->ssl_error_response_info().cert_request_info); + // Not really used to hold a socket. + // TODO(mmenke): Implement a better API to get this information. + ClientSocketHandle client_socket_handle; + nested_connect_job_->GetAdditionalErrorState(&client_socket_handle); + + DCHECK(client_socket_handle.ssl_error_response_info().cert_request_info); UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpProxy.ConnectLatency.Secure.Error", base::TimeTicks::Now() - connect_start_time_); - error_response_info_.reset(new HttpResponseInfo( - transport_socket_handle_->ssl_error_response_info())); + error_response_info_ = std::make_unique<HttpResponseInfo>( + client_socket_handle.ssl_error_response_info()); error_response_info_->cert_request_info->is_proxy = true; return result; } @@ -580,26 +598,24 @@ int HttpProxyClientSocketWrapper::DoSSLConnectComplete(int result) { base::TimeTicks::Now() - connect_start_time_); // TODO(rch): allow the user to deal with proxy cert errors in the // same way as server cert errors. - transport_socket_handle_->socket()->Disconnect(); return ERR_PROXY_CERTIFICATE_INVALID; } // A SPDY session to the proxy completed prior to resolving the proxy // hostname. Surface this error, and allow the delegate to retry. // See crbug.com/334413. if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { - DCHECK(!transport_socket_handle_->socket()); + DCHECK(!nested_connect_job_->socket()); return ERR_SPDY_SESSION_ALREADY_EXISTS; } if (result < 0) { UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpProxy.ConnectLatency.Secure.Error", base::TimeTicks::Now() - connect_start_time_); - if (transport_socket_handle_->socket()) - transport_socket_handle_->socket()->Disconnect(); return ERR_PROXY_CONNECTION_FAILED; } - negotiated_protocol_ = - transport_socket_handle_->socket()->GetNegotiatedProtocol(); + has_established_connection_ = true; + + negotiated_protocol_ = nested_connect_job_->socket()->GetNegotiatedProtocol(); using_spdy_ = negotiated_protocol_ == kProtoHTTP2; // Reset the timer to just the length of time allowed for HttpProxy handshake @@ -634,18 +650,27 @@ int HttpProxyClientSocketWrapper::DoHttpProxyConnect() { // Add a HttpProxy connection on top of the tcp socket. transport_socket_ = - transport_pool_->client_socket_factory()->CreateProxyClientSocket( - std::move(transport_socket_handle_), user_agent_, endpoint_, - ProxyServer(GetProxyServerScheme(), - GetDestination().host_port_pair()), + common_connect_job_params_.client_socket_factory->CreateProxyClientSocket( + nested_connect_job_->PassSocket(), user_agent_, endpoint_, + ProxyServer(GetProxyServerScheme(), GetDestination()), http_auth_controller_.get(), tunnel_, using_spdy_, - negotiated_protocol_, proxy_delegate_, ssl_params_.get() != nullptr, - traffic_annotation_); + negotiated_protocol_, common_connect_job_params_.proxy_delegate, + ssl_params_.get() != nullptr, traffic_annotation_); + nested_connect_job_.reset(); return transport_socket_->Connect(base::Bind( &HttpProxyClientSocketWrapper::OnIOComplete, base::Unretained(this))); } int HttpProxyClientSocketWrapper::DoHttpProxyConnectComplete(int result) { + // Always inform caller of auth requests asynchronously. + if (result == ERR_PROXY_AUTH_REQUESTED) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&HttpProxyClientSocketWrapper::OnAuthChallenge, + weak_ptr_factory_.GetWeakPtr())); + return ERR_IO_PENDING; + } + if (result == ERR_HTTP_1_1_REQUIRED) return ERR_PROXY_HTTP_1_1_REQUIRED; @@ -656,34 +681,32 @@ int HttpProxyClientSocketWrapper::DoSpdyProxyCreateStream() { DCHECK(using_spdy_); DCHECK(tunnel_); DCHECK(ssl_params_); - SpdySessionKey key( - ssl_params_->GetDirectConnectionParams()->destination().host_port_pair(), - ProxyServer::Direct(), PRIVACY_MODE_DISABLED, - SpdySessionKey::IsProxySession::kTrue, initial_socket_tag_); + SpdySessionKey key(ssl_params_->GetDirectConnectionParams()->destination(), + ProxyServer::Direct(), PRIVACY_MODE_DISABLED, + SpdySessionKey::IsProxySession::kTrue, + common_connect_job_params_.socket_tag); base::WeakPtr<SpdySession> spdy_session = spdy_session_pool_->FindAvailableSession( key, /* enable_ip_based_pooling = */ true, /* is_websocket = */ false, net_log_); // It's possible that a session to the proxy has recently been created if (spdy_session) { - if (transport_socket_handle_.get()) { - if (transport_socket_handle_->socket()) - transport_socket_handle_->socket()->Disconnect(); - transport_socket_handle_->Reset(); - } + nested_connect_job_.reset(); } else { // Create a session direct to the proxy itself spdy_session = spdy_session_pool_->CreateAvailableSessionFromSocket( - key, is_trusted_proxy_, std::move(transport_socket_handle_), net_log_); + key, is_trusted_proxy_, nested_connect_job_->PassSocket(), + nested_connect_job_->connect_timing(), net_log_); DCHECK(spdy_session); + nested_connect_job_.reset(); } next_state_ = STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE; spdy_stream_request_ = std::make_unique<SpdyStreamRequest>(); return spdy_stream_request_->StartRequest( SPDY_BIDIRECTIONAL_STREAM, spdy_session, - GURL("https://" + endpoint_.ToString()), priority_, initial_socket_tag_, - spdy_session->net_log(), + GURL("https://" + endpoint_.ToString()), priority_, + common_connect_job_params_.socket_tag, spdy_session->net_log(), base::Bind(&HttpProxyClientSocketWrapper::OnIOComplete, base::Unretained(this)), traffic_annotation_); @@ -711,12 +734,13 @@ int HttpProxyClientSocketWrapper::DoQuicProxyCreateSession() { DCHECK(tunnel_); next_state_ = STATE_QUIC_PROXY_CREATE_STREAM; const HostPortPair& proxy_server = - ssl_params_->GetDirectConnectionParams()->destination().host_port_pair(); + ssl_params_->GetDirectConnectionParams()->destination(); quic_stream_request_ = std::make_unique<QuicStreamRequest>(quic_stream_factory_); return quic_stream_request_->Request( proxy_server, quic_version_, ssl_params_->privacy_mode(), priority_, - initial_socket_tag_, ssl_params_->ssl_config().GetCertVerifyFlags(), + common_connect_job_params_.socket_tag, + ssl_params_->ssl_config().GetCertVerifyFlags(), GURL("https://" + proxy_server.ToString()), net_log_, &quic_net_error_details_, /*failed_on_default_network_callback=*/CompletionOnceCallback(), @@ -771,6 +795,9 @@ int HttpProxyClientSocketWrapper::DoRestartWithAuth() { int HttpProxyClientSocketWrapper::DoRestartWithAuthComplete(int result) { DCHECK_NE(ERR_IO_PENDING, result); + if (result == OK && !transport_socket_->IsConnected()) + result = ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH; + // If the connection could not be reused to attempt to send proxy auth // credentials, try reconnecting. Do not reset the HttpAuthController in this // case; the server may, for instance, send "Proxy-Connection: close" and @@ -796,20 +823,16 @@ int HttpProxyClientSocketWrapper::DoRestartWithAuthComplete(int result) { if (reconnect) { // Attempt to create a new one. transport_socket_.reset(); - - // Reconnect with HIGHEST priority to get in front of other requests that - // don't yet have the information |http_auth_controller_| does. - // TODO(mmenke): This may still result in waiting in line, if there are - // other HIGHEST priority requests. Consider a workaround for - // that. Starting the new request before releasing the old - // socket and using RespectLimits::Disabled would work, - // without exceding the the socket pool limits (Since the old - // socket would free up the extra socket slot when destroyed). - priority_ = HIGHEST; + using_spdy_ = false; + negotiated_protocol_ = NextProto(); next_state_ = STATE_BEGIN_CONNECT; return OK; } + // If not reconnecting, treat the result as the result of establishing a + // tunnel through the proxy. This important in the case another auth challenge + // is seen. + next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE; return result; } @@ -841,8 +864,16 @@ void HttpProxyClientSocketWrapper::ConnectTimeout() { std::move(callback).Run(ERR_CONNECTION_TIMED_OUT); } -const HostResolver::RequestInfo& -HttpProxyClientSocketWrapper::GetDestination() { +void HttpProxyClientSocketWrapper::OnAuthChallenge() { + connect_timer_.Stop(); + on_proxy_auth_callback_.Run( + *transport_socket_->GetConnectResponseInfo(), + transport_socket_->GetAuthController().get(), + base::BindOnce(&HttpProxyClientSocketWrapper::RestartWithAuthCredentials, + weak_ptr_factory_.GetWeakPtr())); +} + +const HostPortPair& HttpProxyClientSocketWrapper::GetDestination() { if (transport_params_) { return transport_params_->destination(); } else { diff --git a/chromium/net/http/http_proxy_client_socket_wrapper.h b/chromium/net/http/http_proxy_client_socket_wrapper.h index a28efa3ec6d..2284743e633 100644 --- a/chromium/net/http/http_proxy_client_socket_wrapper.h +++ b/chromium/net/http/http_proxy_client_socket_wrapper.h @@ -10,8 +10,10 @@ #include <memory> #include <string> +#include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "net/base/completion_callback.h" @@ -23,24 +25,20 @@ #include "net/http/proxy_client_socket.h" #include "net/log/net_log_with_source.h" #include "net/quic/quic_stream_factory.h" +#include "net/socket/connect_job.h" #include "net/socket/next_proto.h" #include "net/socket/ssl_client_socket.h" -#include "net/socket/ssl_client_socket_pool.h" #include "net/spdy/spdy_session.h" #include "net/traffic_annotation/network_traffic_annotation.h" namespace net { -class ClientSocketHandle; class IOBuffer; class HttpAuthCache; class HttpResponseInfo; -class HttpStream; class IOBuffer; -class ProxyDelegate; class SpdySessionPool; -class SSLClientSocketPool; -class TransportClientSocketPool; +class SSLSocketParams; class TransportSocketParams; // Class that establishes connections by calling into the lower layer socket @@ -55,17 +53,20 @@ class TransportSocketParams; // TODO(mmenke): Ideally, we'd have a central location store auth state across // multiple connections to the same server instead. class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper - : public ProxyClientSocket { + : public ProxyClientSocket, + public ConnectJob::Delegate { public: + using OnProxyAuthChallengeCallback = base::RepeatingCallback<void( + const HttpResponseInfo& response, + HttpAuthController* auth_controller, + base::OnceClosure restart_with_auth_callback)>; + HttpProxyClientSocketWrapper( - const std::string& group_name, + const OnProxyAuthChallengeCallback& on_proxy_auth_callback, RequestPriority priority, - const SocketTag& socket_tag, - ClientSocketPool::RespectLimits respect_limits, base::TimeDelta connect_timeout_duration, base::TimeDelta proxy_negotiation_timeout_duration, - TransportClientSocketPool* transport_pool, - SSLClientSocketPool* ssl_pool, + const CommonConnectJobParams& common_connect_job_params, const scoped_refptr<TransportSocketParams>& transport_params, const scoped_refptr<SSLSocketParams>& ssl_params, quic::QuicTransportVersion quic_version, @@ -77,7 +78,6 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper QuicStreamFactory* quic_stream_factory, bool is_trusted_proxy, bool tunnel, - ProxyDelegate* proxy_delegate, const NetworkTrafficAnnotationTag& traffic_annotation, const NetLogWithSource& net_log); @@ -94,7 +94,6 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper // ProxyClientSocket implementation. const HttpResponseInfo* GetConnectResponseInfo() const override; - std::unique_ptr<HttpStream> CreateConnectResponseStream() override; int RestartWithAuth(CompletionOnceCallback callback) override; const scoped_refptr<HttpAuthController>& GetAuthController() const override; bool IsUsingSpdy() const override; @@ -133,6 +132,15 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper int GetPeerAddress(IPEndPoint* address) const override; int GetLocalAddress(IPEndPoint* address) const override; + // ConnectJob::Delegate implementation. + void OnConnectJobComplete(int result, ConnectJob* job) override; + + bool HasEstablishedConnection(); + void OnNeedsProxyAuth(const HttpResponseInfo& response, + HttpAuthController* auth_controller, + base::OnceClosure restart_with_auth_callback, + ConnectJob* job) override; + NetErrorDetails* quic_net_error_details() { return &quic_net_error_details_; } private: @@ -158,6 +166,8 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper void OnIOComplete(int result); + void RestartWithAuthCredentials(); + // Runs the state transition loop. int DoLoop(int result); @@ -186,19 +196,18 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper void SetConnectTimer(base::TimeDelta duration); void ConnectTimeout(); - const HostResolver::RequestInfo& GetDestination(); + void OnAuthChallenge(); + + const HostPortPair& GetDestination(); + + const OnProxyAuthChallengeCallback on_proxy_auth_callback_; State next_state_; - const std::string group_name_; RequestPriority priority_; - const SocketTag initial_socket_tag_; - ClientSocketPool::RespectLimits respect_limits_; const base::TimeDelta connect_timeout_duration_; const base::TimeDelta proxy_negotiation_timeout_duration_; - TransportClientSocketPool* const transport_pool_; - SSLClientSocketPool* const ssl_pool_; const scoped_refptr<TransportSocketParams> transport_params_; const scoped_refptr<SSLSocketParams> ssl_params_; @@ -210,15 +219,20 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper bool has_restarted_; const bool tunnel_; - ProxyDelegate* const proxy_delegate_; + + const CommonConnectJobParams common_connect_job_params_; bool using_spdy_; bool is_trusted_proxy_; NextProto negotiated_protocol_; + // Set to true once a connection has been successfully established. Remains + // true even if a new socket is being connected to retry with auth. + bool has_established_connection_; + std::unique_ptr<HttpResponseInfo> error_response_info_; - std::unique_ptr<ClientSocketHandle> transport_socket_handle_; + std::unique_ptr<ConnectJob> nested_connect_job_; std::unique_ptr<ProxyClientSocket> transport_socket_; // Called when a connection is established. Also used when restarting with @@ -246,6 +260,8 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper // Time when the connection to the proxy was started. base::TimeTicks connect_start_time_; + base::WeakPtrFactory<HttpProxyClientSocketWrapper> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(HttpProxyClientSocketWrapper); }; diff --git a/chromium/net/http/http_proxy_client_socket_wrapper_unittest.cc b/chromium/net/http/http_proxy_client_socket_wrapper_unittest.cc deleted file mode 100644 index d5d3d563464..00000000000 --- a/chromium/net/http/http_proxy_client_socket_wrapper_unittest.cc +++ /dev/null @@ -1,381 +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 "net/http/http_proxy_client_socket_wrapper.h" - -#include <cstdio> -#include <memory> - -#include "build/build_config.h" -#include "net/cert/ct_policy_enforcer.h" -#include "net/cert/do_nothing_ct_verifier.h" -#include "net/cert/mock_cert_verifier.h" -#include "net/dns/mock_host_resolver.h" -#include "net/http/http_auth_cache.h" -#include "net/http/http_auth_handler_factory.h" -#include "net/http/http_server_properties_impl.h" -#include "net/http/transport_security_state.h" -#include "net/quic/mock_crypto_client_stream_factory.h" -#include "net/quic/mock_quic_data.h" -#include "net/quic/quic_http_utils.h" -#include "net/quic/quic_test_packet_maker.h" -#include "net/socket/socket_tag.h" -#include "net/socket/socket_test_util.h" -#include "net/socket/transport_connect_job.h" -#include "net/ssl/channel_id_service.h" -#include "net/ssl/default_channel_id_store.h" -#include "net/test/cert_test_util.h" -#include "net/test/gtest_util.h" -#include "net/test/test_data_directory.h" -#include "net/test/test_with_scoped_task_environment.h" -#include "net/third_party/quic/core/quic_utils.h" -#include "net/third_party/quic/core/quic_versions.h" -#include "net/third_party/quic/test_tools/mock_clock.h" -#include "net/third_party/quic/test_tools/mock_random.h" -#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -namespace { - -const char kProxyHost[] = "proxy.example.org"; -const int kProxyPort = 6121; -const char kOriginHost[] = "www.google.org"; -const int kOriginPort = 443; -const char kUserAgent[] = "Mozilla/1.0"; - -class MockSSLConfigService : public SSLConfigService { - public: - MockSSLConfigService() = default; - ~MockSSLConfigService() override = default; - - void GetSSLConfig(SSLConfig* config) override { *config = config_; } - - bool CanShareConnectionWithClientCerts( - const std::string& hostname) const override { - return false; - } - - private: - SSLConfig config_; -}; - -}; // namespace - -namespace test { - -class HttpProxyClientSocketWrapperTest - : public ::testing::TestWithParam< - std::tuple<quic::QuicTransportVersion, bool>>, - public WithScopedTaskEnvironment { - protected: - static const bool kFin = true; - static const bool kIncludeVersion = true; - static const bool kSendFeedback = true; - - HttpProxyClientSocketWrapperTest() - : proxy_host_port_(kProxyHost, kProxyPort), - endpoint_host_port_(kOriginHost, kOriginPort), - ssl_config_service_(new MockSSLConfigService()), - cert_verifier_(new MockCertVerifier()), - channel_id_service_( - new ChannelIDService(new DefaultChannelIDStore(nullptr))), - cert_transparency_verifier_(new DoNothingCTVerifier()), - random_generator_(0), - quic_version_(std::get<0>(GetParam())), - client_data_stream_id1_( - quic::QuicUtils::GetHeadersStreamId(quic_version_) + - quic::QuicUtils::StreamIdDelta(quic_version_)), - client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())), - client_maker_( - quic_version_, - quic::QuicUtils::CreateRandomConnectionId(&random_generator_), - &clock_, - kProxyHost, - quic::Perspective::IS_CLIENT, - client_headers_include_h2_stream_dependency_), - server_maker_( - quic_version_, - quic::QuicUtils::CreateRandomConnectionId(&random_generator_), - &clock_, - kProxyHost, - quic::Perspective::IS_SERVER, - false), - header_stream_offset_(0), - response_offset_(0), - store_server_configs_in_properties_(false), - idle_connection_timeout_seconds_(kIdleConnectionTimeoutSeconds), - reduced_ping_timeout_seconds_(quic::kPingTimeoutSecs), - allow_server_migration_(false), - race_cert_verification_(false), - estimate_initial_rtt_(false), - quic_stream_factory_(nullptr), - privacy_mode_(PRIVACY_MODE_DISABLED), - http_auth_handler_factory_( - HttpAuthHandlerFactory::CreateDefault(&host_resolver_)), - client_socket_wrapper_(nullptr) { - clock_.AdvanceTime( - quic::QuicTime::Delta::FromSeconds(1)); // why is this here??? - } - - void Initialize() { - DCHECK(!quic_stream_factory_); - quic_stream_factory_.reset(new QuicStreamFactory( - net_log_.net_log(), &host_resolver_, ssl_config_service_.get(), - &socket_factory_, &http_server_properties_, cert_verifier_.get(), - &ct_policy_enforcer_, &transport_security_state_, - cert_transparency_verifier_.get(), - /*SocketPerformanceWatcherFactory=*/nullptr, - &crypto_client_stream_factory_, &random_generator_, &clock_, - quic::kDefaultMaxPacketSize, /*user_agent_id=*/kUserAgent, - store_server_configs_in_properties_, - /*close_sessions_on_ip_change=*/true, - /*goaway_sessions_on_ip_change=*/false, - /*mark_quic_broken_when_network_blackholes=*/false, - idle_connection_timeout_seconds_, reduced_ping_timeout_seconds_, - /*max_time_before_crypto_handshake_seconds=*/ - quic::kMaxTimeForCryptoHandshakeSecs, - /*max_idle_time_before_crypto_handshake_seconds=*/ - quic::kInitialIdleTimeoutSecs, - /*migrate_sessions_on_network_change_v2=*/false, - /*migrate_sessions_early_v2=*/false, - /*retry_on_alternate_network_before_handshake=*/false, - /*race_stale_dns_on_connection=*/false, - /*go_away_on_path_degrading=*/false, - base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs), - kMaxMigrationsToNonDefaultNetworkOnWriteError, - kMaxMigrationsToNonDefaultNetworkOnPathDegrading, - allow_server_migration_, race_cert_verification_, estimate_initial_rtt_, - client_headers_include_h2_stream_dependency_, connection_options_, - client_connection_options_, - /*enable_socket_recv_optimization=*/false)); - } - - void PopulateConnectRequestIR(spdy::SpdyHeaderBlock* block) { - (*block)[":method"] = "CONNECT"; - (*block)[":authority"] = endpoint_host_port_.ToString(); - (*block)["user-agent"] = kUserAgent; - } - - std::unique_ptr<quic::QuicReceivedPacket> ConstructSettingsPacket( - quic::QuicPacketNumber packet_number) { - return client_maker_.MakeInitialSettingsPacket(packet_number, - &header_stream_offset_); - } - - std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectRequestPacket( - quic::QuicPacketNumber packet_number, - RequestPriority priority) { - spdy::SpdyHeaderBlock block; - PopulateConnectRequestIR(&block); - return client_maker_.MakeRequestHeadersPacket( - packet_number, client_data_stream_id1_, kIncludeVersion, !kFin, - ConvertRequestPriorityToQuicPriority(priority), std::move(block), 0, - nullptr, &header_stream_offset_); - } - - std::unique_ptr<quic::QuicReceivedPacket> ConstructServerConnectReplyPacket( - quic::QuicPacketNumber packet_number, - bool fin) { - spdy::SpdyHeaderBlock block; - block[":status"] = "200"; - - return server_maker_.MakeResponseHeadersPacket( - packet_number, client_data_stream_id1_, !kIncludeVersion, fin, - std::move(block), nullptr, &response_offset_); - } - - std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstPacket( - quic::QuicPacketNumber packet_number, - quic::QuicRstStreamErrorCode error_code, - quic::QuicPacketNumber largest_received, - quic::QuicPacketNumber smallest_received, - quic::QuicPacketNumber least_unacked) { - return client_maker_.MakeAckAndRstPacket( - packet_number, !kIncludeVersion, client_data_stream_id1_, error_code, - largest_received, smallest_received, least_unacked, kSendFeedback); - } - - static ProofVerifyDetailsChromium DefaultProofVerifyDetails() { - // Load a certificate that is valid for *.example.org - scoped_refptr<X509Certificate> test_cert( - ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem")); - EXPECT_TRUE(test_cert.get()); - ProofVerifyDetailsChromium verify_details; - verify_details.cert_verify_result.verified_cert = test_cert; - verify_details.cert_verify_result.is_issued_by_known_root = true; - return verify_details; - } - - HostPortPair proxy_host_port_; - HostPortPair endpoint_host_port_; - - quic::MockClock clock_; - MockQuicData mock_quic_data_; - - // QuicStreamFactory environment - NetLogWithSource net_log_; - MockHostResolver host_resolver_; - std::unique_ptr<SSLConfigService> ssl_config_service_; - MockTaggingClientSocketFactory socket_factory_; - HttpServerPropertiesImpl http_server_properties_; - std::unique_ptr<MockCertVerifier> cert_verifier_; - DefaultCTPolicyEnforcer ct_policy_enforcer_; - std::unique_ptr<ChannelIDService> channel_id_service_; - TransportSecurityState transport_security_state_; - std::unique_ptr<DoNothingCTVerifier> cert_transparency_verifier_; - MockCryptoClientStreamFactory crypto_client_stream_factory_; - quic::test::MockRandom random_generator_; - - const quic::QuicTransportVersion quic_version_; - const quic::QuicStreamId client_data_stream_id1_; - const bool client_headers_include_h2_stream_dependency_; - QuicTestPacketMaker client_maker_; - QuicTestPacketMaker server_maker_; - quic::QuicStreamOffset header_stream_offset_; - quic::QuicStreamOffset response_offset_; - - // Variables to configure QuicStreamFactory. - bool store_server_configs_in_properties_; - int idle_connection_timeout_seconds_; - int reduced_ping_timeout_seconds_; - bool allow_server_migration_; - bool race_cert_verification_; - bool estimate_initial_rtt_; - quic::QuicTagVector connection_options_; - quic::QuicTagVector client_connection_options_; - - std::unique_ptr<QuicStreamFactory> quic_stream_factory_; - - // HttpProxyClientSocketWrapper environment - PrivacyMode privacy_mode_; - HttpAuthCache http_auth_cache_; - std::unique_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory_; - - std::unique_ptr<HttpProxyClientSocketWrapper> client_socket_wrapper_; -}; - -TEST_P(HttpProxyClientSocketWrapperTest, QuicProxy) { - Initialize(); - ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); - crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - - mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1)); - mock_quic_data_.AddWrite(SYNCHRONOUS, - ConstructConnectRequestPacket(2, HIGHEST)); - mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin)); - mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - mock_quic_data_.AddWrite( - SYNCHRONOUS, - ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1)); - mock_quic_data_.AddWrite( - SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket( - 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 1, - 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error")); - mock_quic_data_.AddSocketDataToFactory(&socket_factory_); - - scoped_refptr<TransportSocketParams> transport_params = - new TransportSocketParams(proxy_host_port_, false, - OnHostResolutionCallback()); - - scoped_refptr<SSLSocketParams> ssl_params = - new SSLSocketParams(transport_params, nullptr, nullptr, proxy_host_port_, - SSLConfig(), privacy_mode_); - transport_params = nullptr; - - client_socket_wrapper_.reset(new HttpProxyClientSocketWrapper( - /*group_name=*/std::string(), /*requiest_priority=*/DEFAULT_PRIORITY, - /*socket_tag=*/SocketTag(), - /*respect_limits=*/ClientSocketPool::RespectLimits::ENABLED, - /*connect_timeout_duration=*/base::TimeDelta::FromHours(1), - /*proxy_negotiation_timeout_duration=*/base::TimeDelta::FromHours(1), - /*transport_pool=*/nullptr, /*ssl_pool=*/nullptr, - /*transport_params=*/nullptr, ssl_params, quic_version_, kUserAgent, - endpoint_host_port_, &http_auth_cache_, http_auth_handler_factory_.get(), - /*spdy_session_pool=*/nullptr, quic_stream_factory_.get(), - /*is_trusted_proxy=*/false, /*tunnel=*/true, /*proxy_delegate=*/nullptr, - TRAFFIC_ANNOTATION_FOR_TESTS, net_log_)); - - TestCompletionCallback callback; - client_socket_wrapper_->Connect(callback.callback()); - EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_.request_priority(1)); - - client_socket_wrapper_->SetPriority(HIGHEST); - - // Expect connect request packet with HIGHEST priority, not DEFAULT_PRIORITY. - EXPECT_THAT(callback.WaitForResult(), IsOk()); - - client_socket_wrapper_.reset(); - EXPECT_TRUE(mock_quic_data_.AllReadDataConsumed()); -} - -// Test that the SocketTag is appropriately applied to the underlying socket -// for QUIC proxies. -#if defined(OS_ANDROID) -TEST_P(HttpProxyClientSocketWrapperTest, QuicProxySocketTag) { - Initialize(); - ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); - crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - - mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1)); - mock_quic_data_.AddWrite(SYNCHRONOUS, - ConstructConnectRequestPacket(2, DEFAULT_PRIORITY)); - mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin)); - mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - mock_quic_data_.AddWrite( - SYNCHRONOUS, - ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1)); - mock_quic_data_.AddWrite( - SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket( - 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 1, - 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error")); - mock_quic_data_.AddSocketDataToFactory(&socket_factory_); - - scoped_refptr<TransportSocketParams> transport_params = - new TransportSocketParams(proxy_host_port_, false, - OnHostResolutionCallback()); - - scoped_refptr<SSLSocketParams> ssl_params = - new SSLSocketParams(transport_params, nullptr, nullptr, proxy_host_port_, - SSLConfig(), privacy_mode_); - transport_params = nullptr; - SocketTag tag(getuid(), 0x87654321); - - client_socket_wrapper_.reset(new HttpProxyClientSocketWrapper( - /*group_name=*/std::string(), /*requiest_priority=*/DEFAULT_PRIORITY, - /*socket_tag=*/tag, - /*respect_limits=*/ClientSocketPool::RespectLimits::ENABLED, - /*connect_timeout_duration=*/base::TimeDelta::FromHours(1), - /*proxy_negotiation_timeout_duration=*/base::TimeDelta::FromHours(1), - /*transport_pool=*/nullptr, /*ssl_pool=*/nullptr, - /*transport_params=*/nullptr, ssl_params, quic_version_, kUserAgent, - endpoint_host_port_, &http_auth_cache_, http_auth_handler_factory_.get(), - /*spdy_session_pool=*/nullptr, quic_stream_factory_.get(), - /*is_trusted_proxy=*/false, /*tunnel=*/true, /*proxy_delegate=*/nullptr, - TRAFFIC_ANNOTATION_FOR_TESTS, net_log_)); - - TestCompletionCallback callback; - client_socket_wrapper_->Connect(callback.callback()); - - EXPECT_THAT(callback.WaitForResult(), IsOk()); - - EXPECT_EQ(socket_factory_.GetLastProducedUDPSocket()->tag(), tag); - EXPECT_TRUE(socket_factory_.GetLastProducedUDPSocket() - ->tagged_before_data_transferred()); - - client_socket_wrapper_.reset(); - EXPECT_TRUE(mock_quic_data_.AllReadDataConsumed()); -} -#endif - -INSTANTIATE_TEST_CASE_P( - VersionIncludeStreamDependencySequence, - HttpProxyClientSocketWrapperTest, - ::testing::Combine( - ::testing::ValuesIn(quic::AllSupportedTransportVersions()), - ::testing::Bool())); - -}; // namespace test -}; // namespace net diff --git a/chromium/net/http/http_proxy_client_socket_pool.cc b/chromium/net/http/http_proxy_connect_job.cc index d7d704f4f57..de7c2086b3c 100644 --- a/chromium/net/http/http_proxy_client_socket_pool.cc +++ b/chromium/net/http/http_proxy_connect_job.cc @@ -1,15 +1,13 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2019 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/http/http_proxy_client_socket_pool.h" +#include "net/http/http_proxy_connect_job.h" -#include <algorithm> -#include <map> -#include <string> #include <utility> -#include "base/compiler_specific.h" +#include "base/bind.h" +#include "base/callback.h" #include "base/metrics/field_trial.h" #include "base/metrics/field_trial_params.h" #include "base/no_destructor.h" @@ -19,18 +17,15 @@ #include "base/strings/string_util.h" #include "base/values.h" #include "build/build_config.h" -#include "net/base/load_flags.h" #include "net/base/net_errors.h" -#include "net/http/http_network_session.h" #include "net/http/http_proxy_client_socket_wrapper.h" #include "net/log/net_log_source_type.h" #include "net/log/net_log_with_source.h" #include "net/nqe/network_quality_estimator.h" #include "net/socket/client_socket_factory.h" #include "net/socket/client_socket_handle.h" -#include "net/socket/client_socket_pool_base.h" #include "net/socket/ssl_client_socket.h" -#include "net/socket/ssl_client_socket_pool.h" +#include "net/socket/ssl_connect_job.h" #include "net/socket/transport_client_socket_pool.h" #include "net/socket/transport_connect_job.h" #include "net/spdy/spdy_proxy_client_socket.h" @@ -47,9 +42,11 @@ namespace { // HttpProxyConnectJobs will time out after this many seconds. Note this is in // addition to the timeout for the transport socket. #if defined(OS_ANDROID) || defined(OS_IOS) -static const int kHttpProxyConnectJobTimeoutInSeconds = 10; +constexpr base::TimeDelta kHttpProxyConnectJobTunnelTimeout = + base::TimeDelta::FromSeconds(10); #else -static const int kHttpProxyConnectJobTimeoutInSeconds = 30; +constexpr base::TimeDelta kHttpProxyConnectJobTunnelTimeout = + base::TimeDelta::FromSeconds(30); #endif class HttpProxyTimeoutExperiments { @@ -93,7 +90,7 @@ class HttpProxyTimeoutExperiments { } private: - // Return the value of the parameter |param_name| for the field trial + // Returns the value of the parameter |param_name| for the field trial // "NetAdaptiveProxyConnectionTimeout". If the value of the parameter is // unavailable, then |default_value| is available. static int32_t GetInt32Param(const std::string& param_name, @@ -168,35 +165,27 @@ HttpProxySocketParams::HttpProxySocketParams( HttpProxySocketParams::~HttpProxySocketParams() = default; HttpProxyConnectJob::HttpProxyConnectJob( - const std::string& group_name, RequestPriority priority, - const SocketTag& socket_tag, - ClientSocketPool::RespectLimits respect_limits, + const CommonConnectJobParams& common_connect_job_params, const scoped_refptr<HttpProxySocketParams>& params, - ProxyDelegate* proxy_delegate, - TransportClientSocketPool* transport_pool, - SSLClientSocketPool* ssl_pool, - NetworkQualityEstimator* network_quality_estimator, Delegate* delegate, - NetLog* net_log) - : ConnectJob( - group_name, - base::TimeDelta() /* The socket takes care of timeouts */, + const NetLogWithSource* net_log) + : ConnectJob(priority, + base::TimeDelta() /* The socket takes care of timeouts */, + common_connect_job_params, + delegate, + net_log, + NetLogSourceType::HTTP_PROXY_CONNECT_JOB, + NetLogEventType::HTTP_PROXY_CONNECT_JOB_CONNECT), + client_socket_(std::make_unique<HttpProxyClientSocketWrapper>( + base::BindRepeating(&HttpProxyConnectJob::OnNeedsProxyAuth, + base::Unretained(this)), priority, - socket_tag, - respect_limits == ClientSocketPool::RespectLimits::ENABLED, - delegate, - NetLogWithSource::Make(net_log, - NetLogSourceType::HTTP_PROXY_CONNECT_JOB)), - client_socket_(new HttpProxyClientSocketWrapper( - group_name, - priority, - socket_tag, - respect_limits, - ConnectionTimeout(*params, network_quality_estimator), - base::TimeDelta::FromSeconds(kHttpProxyConnectJobTimeoutInSeconds), - transport_pool, - ssl_pool, + ConnectionTimeout( + *params, + common_connect_job_params.network_quality_estimator), + kHttpProxyConnectJobTunnelTimeout, + common_connect_job_params, params->transport_params(), params->ssl_params(), params->quic_version(), @@ -208,9 +197,9 @@ HttpProxyConnectJob::HttpProxyConnectJob( params->quic_stream_factory(), params->is_trusted_proxy(), params->tunnel(), - proxy_delegate, params->traffic_annotation(), - this->net_log())) {} + this->net_log())), + params_(std::move(params)) {} HttpProxyConnectJob::~HttpProxyConnectJob() = default; @@ -218,7 +207,19 @@ LoadState HttpProxyConnectJob::GetLoadState() const { return client_socket_->GetConnectLoadState(); } -void HttpProxyConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) { +bool HttpProxyConnectJob::HasEstablishedConnection() const { + return client_socket_->HasEstablishedConnection(); +} + +void HttpProxyConnectJob::OnNeedsProxyAuth( + const HttpResponseInfo& response, + HttpAuthController* auth_controller, + base::OnceClosure restart_with_auth_callback) { + NotifyDelegateOfProxyAuth(response, auth_controller, + std::move(restart_with_auth_callback)); +} + +void HttpProxyConnectJob::GetAdditionalErrorState(ClientSocketHandle* handle) { if (error_response_info_) { handle->set_ssl_error_response_info(*error_response_info_); handle->set_is_ssl_error(true); @@ -262,8 +263,11 @@ base::TimeDelta HttpProxyConnectJob::ConnectionTimeout( } #endif // !defined(OS_ANDROID) && !defined(OS_IOS) - return nested_job_timeout + - base::TimeDelta::FromSeconds(kHttpProxyConnectJobTimeoutInSeconds); + return nested_job_timeout + kHttpProxyConnectJobTunnelTimeout; +} + +base::TimeDelta HttpProxyConnectJob::TunnelTimeoutForTesting() { + return kHttpProxyConnectJobTunnelTimeout; } void HttpProxyConnectJob::UpdateFieldTrialParametersForTesting() { @@ -271,7 +275,7 @@ void HttpProxyConnectJob::UpdateFieldTrialParametersForTesting() { } int HttpProxyConnectJob::ConnectInternal() { - int result = client_socket_->Connect(base::Bind( + int result = client_socket_->Connect(base::BindOnce( &HttpProxyConnectJob::OnConnectComplete, base::Unretained(this))); return HandleConnectResult(result); } @@ -284,188 +288,23 @@ void HttpProxyConnectJob::ChangePriorityInternal(RequestPriority priority) { void HttpProxyConnectJob::OnConnectComplete(int result) { DCHECK_NE(ERR_IO_PENDING, result); result = HandleConnectResult(result); - NotifyDelegateOfCompletion(result); - // |this| will have been deleted at this point. + if (result != ERR_IO_PENDING) { + NotifyDelegateOfCompletion(result); + // |this| will have been deleted at this point. + } } int HttpProxyConnectJob::HandleConnectResult(int result) { + // Stop the timer. Only needed for the ERR_PROXY_AUTH_REQUESTED case, but + // shouldn't be returning a result more than once, anyways. + ResetTimer(base::TimeDelta()); + if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) error_response_info_ = client_socket_->GetAdditionalErrorState(); - if (result == OK || result == ERR_PROXY_AUTH_REQUESTED || - result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT) { + if (result == OK || result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT) SetSocket(std::move(client_socket_)); - } return result; } -HttpProxyClientSocketPool::HttpProxyConnectJobFactory:: - HttpProxyConnectJobFactory( - TransportClientSocketPool* transport_pool, - SSLClientSocketPool* ssl_pool, - ProxyDelegate* proxy_delegate, - NetworkQualityEstimator* network_quality_estimator, - NetLog* net_log) - : transport_pool_(transport_pool), - ssl_pool_(ssl_pool), - proxy_delegate_(proxy_delegate), - network_quality_estimator_(network_quality_estimator), - net_log_(net_log) {} - -std::unique_ptr<ConnectJob> -HttpProxyClientSocketPool::HttpProxyConnectJobFactory::NewConnectJob( - const std::string& group_name, - const PoolBase::Request& request, - ConnectJob::Delegate* delegate) const { - return std::make_unique<HttpProxyConnectJob>( - group_name, request.priority(), request.socket_tag(), - request.respect_limits(), request.params(), proxy_delegate_, - transport_pool_, ssl_pool_, network_quality_estimator_, delegate, - net_log_); -} - -HttpProxyClientSocketPool::HttpProxyClientSocketPool( - int max_sockets, - int max_sockets_per_group, - TransportClientSocketPool* transport_pool, - SSLClientSocketPool* ssl_pool, - ProxyDelegate* proxy_delegate, - NetworkQualityEstimator* network_quality_estimator, - NetLog* net_log) - : transport_pool_(transport_pool), - ssl_pool_(ssl_pool), - base_(this, - max_sockets, - max_sockets_per_group, - ClientSocketPool::unused_idle_socket_timeout(), - ClientSocketPool::used_idle_socket_timeout(), - new HttpProxyConnectJobFactory(transport_pool, - ssl_pool, - proxy_delegate, - network_quality_estimator, - net_log)) { - // We should always have a |transport_pool_| except in unit tests. - if (transport_pool_) - base_.AddLowerLayeredPool(transport_pool_); - if (ssl_pool_) - base_.AddLowerLayeredPool(ssl_pool_); -} - -HttpProxyClientSocketPool::~HttpProxyClientSocketPool() = default; - -int HttpProxyClientSocketPool::RequestSocket(const std::string& group_name, - const void* socket_params, - RequestPriority priority, - const SocketTag& socket_tag, - RespectLimits respect_limits, - ClientSocketHandle* handle, - CompletionOnceCallback callback, - const NetLogWithSource& net_log) { - const scoped_refptr<HttpProxySocketParams>* casted_socket_params = - static_cast<const scoped_refptr<HttpProxySocketParams>*>(socket_params); - - return base_.RequestSocket(group_name, *casted_socket_params, priority, - socket_tag, respect_limits, handle, - std::move(callback), net_log); -} - -void HttpProxyClientSocketPool::RequestSockets( - const std::string& group_name, - const void* params, - int num_sockets, - const NetLogWithSource& net_log) { - const scoped_refptr<HttpProxySocketParams>* casted_params = - static_cast<const scoped_refptr<HttpProxySocketParams>*>(params); - - base_.RequestSockets(group_name, *casted_params, num_sockets, net_log); -} - -void HttpProxyClientSocketPool::CancelRequest( - const std::string& group_name, - ClientSocketHandle* handle) { - base_.CancelRequest(group_name, handle); -} - -void HttpProxyClientSocketPool::SetPriority(const std::string& group_name, - ClientSocketHandle* handle, - RequestPriority priority) { - base_.SetPriority(group_name, handle, priority); -} - -void HttpProxyClientSocketPool::ReleaseSocket( - const std::string& group_name, - std::unique_ptr<StreamSocket> socket, - int id) { - base_.ReleaseSocket(group_name, std::move(socket), id); -} - -void HttpProxyClientSocketPool::FlushWithError(int error) { - base_.FlushWithError(error); -} - -void HttpProxyClientSocketPool::CloseIdleSockets() { - base_.CloseIdleSockets(); -} - -void HttpProxyClientSocketPool::CloseIdleSocketsInGroup( - const std::string& group_name) { - base_.CloseIdleSocketsInGroup(group_name); -} - -int HttpProxyClientSocketPool::IdleSocketCount() const { - return base_.idle_socket_count(); -} - -int HttpProxyClientSocketPool::IdleSocketCountInGroup( - const std::string& group_name) const { - return base_.IdleSocketCountInGroup(group_name); -} - -LoadState HttpProxyClientSocketPool::GetLoadState( - const std::string& group_name, const ClientSocketHandle* handle) const { - return base_.GetLoadState(group_name, handle); -} - -std::unique_ptr<base::DictionaryValue> -HttpProxyClientSocketPool::GetInfoAsValue(const std::string& name, - const std::string& type, - bool include_nested_pools) const { - std::unique_ptr<base::DictionaryValue> dict(base_.GetInfoAsValue(name, type)); - if (include_nested_pools) { - auto list = std::make_unique<base::ListValue>(); - if (transport_pool_) { - list->Append(transport_pool_->GetInfoAsValue("transport_socket_pool", - "transport_socket_pool", - true)); - } - if (ssl_pool_) { - list->Append(ssl_pool_->GetInfoAsValue("ssl_socket_pool", - "ssl_socket_pool", - true)); - } - dict->Set("nested_pools", std::move(list)); - } - return dict; -} - -bool HttpProxyClientSocketPool::IsStalled() const { - return base_.IsStalled(); -} - -void HttpProxyClientSocketPool::AddHigherLayeredPool( - HigherLayeredPool* higher_pool) { - base_.AddHigherLayeredPool(higher_pool); -} - -void HttpProxyClientSocketPool::RemoveHigherLayeredPool( - HigherLayeredPool* higher_pool) { - base_.RemoveHigherLayeredPool(higher_pool); -} - -bool HttpProxyClientSocketPool::CloseOneIdleConnection() { - if (base_.CloseOneIdleSocket()) - return true; - return base_.CloseOneIdleConnectionInHigherLayeredPool(); -} - } // namespace net diff --git a/chromium/net/http/http_proxy_connect_job.h b/chromium/net/http/http_proxy_connect_job.h new file mode 100644 index 00000000000..ba3eece0b71 --- /dev/null +++ b/chromium/net/http/http_proxy_connect_job.h @@ -0,0 +1,161 @@ +// Copyright 2019 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_HTTP_HTTP_PROXY_CONNECT_JOB_H_ +#define NET_HTTP_HTTP_PROXY_CONNECT_JOB_H_ + +#include <memory> +#include <string> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/time/time.h" +#include "net/base/host_port_pair.h" +#include "net/base/net_export.h" +#include "net/http/http_auth.h" +#include "net/http/http_response_info.h" +#include "net/socket/connect_job.h" +#include "net/socket/ssl_client_socket.h" +#include "net/spdy/spdy_session.h" +#include "net/traffic_annotation/network_traffic_annotation.h" + +namespace net { + +class HttpAuthCache; +class HttpAuthHandlerFactory; +class HttpProxyClientSocketWrapper; +class NetworkQualityEstimator; +class SpdySessionPool; +class SSLSocketParams; +class TransportSocketParams; +class QuicStreamFactory; + +// HttpProxySocketParams only needs the socket params for one of the proxy +// types. The other param must be NULL. When using an HTTP proxy, +// |transport_params| must be set. When using an HTTPS proxy or QUIC proxy, +// |ssl_params| must be set. Also, if using a QUIC proxy, |quic_version| must +// not be quic::QUIC_VERSION_UNSUPPORTED. +class NET_EXPORT_PRIVATE HttpProxySocketParams + : public base::RefCounted<HttpProxySocketParams> { + public: + HttpProxySocketParams( + const scoped_refptr<TransportSocketParams>& transport_params, + const scoped_refptr<SSLSocketParams>& ssl_params, + quic::QuicTransportVersion quic_version, + const std::string& user_agent, + const HostPortPair& endpoint, + HttpAuthCache* http_auth_cache, + HttpAuthHandlerFactory* http_auth_handler_factory, + SpdySessionPool* spdy_session_pool, + QuicStreamFactory* quic_stream_factory, + bool is_trusted_proxy, + bool tunnel, + const NetworkTrafficAnnotationTag traffic_annotation); + + const scoped_refptr<TransportSocketParams>& transport_params() const { + return transport_params_; + } + const scoped_refptr<SSLSocketParams>& ssl_params() const { + return ssl_params_; + } + quic::QuicTransportVersion quic_version() const { return quic_version_; } + const std::string& user_agent() const { return user_agent_; } + const HostPortPair& endpoint() const { return endpoint_; } + HttpAuthCache* http_auth_cache() const { return http_auth_cache_; } + HttpAuthHandlerFactory* http_auth_handler_factory() const { + return http_auth_handler_factory_; + } + SpdySessionPool* spdy_session_pool() { return spdy_session_pool_; } + QuicStreamFactory* quic_stream_factory() const { + return quic_stream_factory_; + } + bool is_trusted_proxy() const { return is_trusted_proxy_; } + bool tunnel() const { return tunnel_; } + const NetworkTrafficAnnotationTag traffic_annotation() const { + return traffic_annotation_; + } + + private: + friend class base::RefCounted<HttpProxySocketParams>; + ~HttpProxySocketParams(); + + const scoped_refptr<TransportSocketParams> transport_params_; + const scoped_refptr<SSLSocketParams> ssl_params_; + quic::QuicTransportVersion quic_version_; + SpdySessionPool* spdy_session_pool_; + QuicStreamFactory* quic_stream_factory_; + const std::string user_agent_; + const HostPortPair endpoint_; + HttpAuthCache* const http_auth_cache_; + HttpAuthHandlerFactory* const http_auth_handler_factory_; + const bool is_trusted_proxy_; + const bool tunnel_; + const NetworkTrafficAnnotationTag traffic_annotation_; + + DISALLOW_COPY_AND_ASSIGN(HttpProxySocketParams); +}; + +// HttpProxyConnectJob optionally establishes a tunnel through the proxy +// server after connecting the underlying transport socket. +class NET_EXPORT_PRIVATE HttpProxyConnectJob : public ConnectJob { + public: + HttpProxyConnectJob(RequestPriority priority, + const CommonConnectJobParams& common_connect_job_params, + const scoped_refptr<HttpProxySocketParams>& params, + Delegate* delegate, + const NetLogWithSource* net_log); + ~HttpProxyConnectJob() override; + + // ConnectJob methods. + LoadState GetLoadState() const override; + bool HasEstablishedConnection() const override; + + void OnNeedsProxyAuth(const HttpResponseInfo& response, + HttpAuthController* auth_controller, + base::OnceClosure restart_with_auth_callback); + + void GetAdditionalErrorState(ClientSocketHandle* handle) override; + + // Returns the connection timeout that will be used by a HttpProxyConnectJob + // created with the specified parameters, given current network conditions. + static base::TimeDelta ConnectionTimeout( + const HttpProxySocketParams& params, + const NetworkQualityEstimator* network_quality_estimator); + + // Returns the timeout for establishing a tunnel after a connection has been + // established. + static base::TimeDelta TunnelTimeoutForTesting(); + + // Updates the field trial parameters used in calculating timeouts. + static void UpdateFieldTrialParametersForTesting(); + + private: + // Begins the tcp connection and the optional Http proxy tunnel. If the + // request is not immediately serviceable (likely), the request will return + // ERR_IO_PENDING. An OK return from this function or the callback means + // that the connection is established; ERR_PROXY_AUTH_REQUESTED means + // that the tunnel needs authentication credentials, the socket will be + // returned in this case, and must be released back to the pool; or + // a standard net error code will be returned. + int ConnectInternal() override; + + void ChangePriorityInternal(RequestPriority priority) override; + + void OnConnectComplete(int result); + + int HandleConnectResult(int result); + + std::unique_ptr<HttpProxyClientSocketWrapper> client_socket_; + + scoped_refptr<HttpProxySocketParams> params_; + + std::unique_ptr<HttpResponseInfo> error_response_info_; + + DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJob); +}; + +} // namespace net + +#endif // NET_HTTP_HTTP_PROXY_CONNECT_JOB_H_ diff --git a/chromium/net/http/http_proxy_connect_job_unittest.cc b/chromium/net/http/http_proxy_connect_job_unittest.cc new file mode 100644 index 00000000000..6d29a658df2 --- /dev/null +++ b/chromium/net/http/http_proxy_connect_job_unittest.cc @@ -0,0 +1,1584 @@ +// Copyright 2019 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/http/http_proxy_connect_job.h" + +#include <algorithm> +#include <map> +#include <string> +#include <utility> + +#include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_param_associator.h" +#include "base/metrics/field_trial_params.h" +#include "base/stl_util.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_task_environment.h" +#include "build/build_config.h" +#include "net/base/host_port_pair.h" +#include "net/base/test_proxy_delegate.h" +#include "net/dns/mock_host_resolver.h" +#include "net/http/http_network_session.h" +#include "net/nqe/network_quality_estimator_test_util.h" +#include "net/socket/client_socket_handle.h" +#include "net/socket/connect_job_test_util.h" +#include "net/socket/socket_test_util.h" +#include "net/socket/socks_connect_job.h" +#include "net/socket/ssl_client_socket.h" +#include "net/socket/ssl_connect_job.h" +#include "net/socket/transport_connect_job.h" +#include "net/spdy/spdy_test_util_common.h" +#include "net/test/gtest_util.h" +#include "net/test/test_with_scoped_task_environment.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { + +namespace { + +const char kEndpointHost[] = "www.endpoint.test"; + +enum HttpProxyType { HTTP, HTTPS, SPDY }; + +const char kHttpProxyHost[] = "httpproxy.example.test"; +const char kHttpsProxyHost[] = "httpsproxy.example.test"; + +} // namespace + +class HttpProxyConnectJobTest : public ::testing::TestWithParam<HttpProxyType>, + public WithScopedTaskEnvironment { + protected: + HttpProxyConnectJobTest() + : WithScopedTaskEnvironment( + base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME, + base::test::ScopedTaskEnvironment::NowSource:: + MAIN_THREAD_MOCK_TIME), + field_trial_list_(nullptr) { + // Set an initial delay to ensure that calls to TimeTicks::Now() do not + // return a null value. + FastForwardBy(base::TimeDelta::FromSeconds(1)); + + // Used a mock HostResolver that does not have a cache. + session_deps_.host_resolver = std::make_unique<MockHostResolver>(); + + network_quality_estimator_ = + std::make_unique<TestNetworkQualityEstimator>(); + session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); + } + + virtual ~HttpProxyConnectJobTest() { + // Reset global field trial parameters to defaults values. + base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting(); + HttpProxyConnectJob::UpdateFieldTrialParametersForTesting(); + } + + // Initializes the field trial parameters for the field trial that determines + // connection timeout based on the network quality. + void InitAdaptiveTimeoutFieldTrialWithParams( + bool use_default_params, + int ssl_http_rtt_multiplier, + int non_ssl_http_rtt_multiplier, + base::TimeDelta min_proxy_connection_timeout, + base::TimeDelta max_proxy_connection_timeout) { + std::string trial_name = "NetAdaptiveProxyConnectionTimeout"; + std::string group_name = "GroupName"; + + std::map<std::string, std::string> params; + if (!use_default_params) { + params["ssl_http_rtt_multiplier"] = + base::NumberToString(ssl_http_rtt_multiplier); + params["non_ssl_http_rtt_multiplier"] = + base::NumberToString(non_ssl_http_rtt_multiplier); + params["min_proxy_connection_timeout_seconds"] = + base::NumberToString(min_proxy_connection_timeout.InSeconds()); + params["max_proxy_connection_timeout_seconds"] = + base::NumberToString(max_proxy_connection_timeout.InSeconds()); + } + base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting(); + EXPECT_TRUE( + base::AssociateFieldTrialParams(trial_name, group_name, params)); + EXPECT_TRUE(base::FieldTrialList::CreateFieldTrial(trial_name, group_name)); + + // Force static global that reads the field trials to update. + HttpProxyConnectJob::UpdateFieldTrialParametersForTesting(); + } + + scoped_refptr<TransportSocketParams> CreateHttpProxyParams() const { + if (GetParam() != HTTP) + return nullptr; + return base::MakeRefCounted<TransportSocketParams>( + HostPortPair(kHttpProxyHost, 80), false, OnHostResolutionCallback()); + } + + scoped_refptr<SSLSocketParams> CreateHttpsProxyParams() const { + if (GetParam() == HTTP) + return nullptr; + return base::MakeRefCounted<SSLSocketParams>( + base::MakeRefCounted<TransportSocketParams>( + HostPortPair(kHttpsProxyHost, 443), false, + OnHostResolutionCallback()), + nullptr, nullptr, HostPortPair(kHttpsProxyHost, 443), SSLConfig(), + PRIVACY_MODE_DISABLED); + } + + // Returns a correctly constructed HttpProxyParams for the HTTP or HTTPS + // proxy. + scoped_refptr<HttpProxySocketParams> CreateParams(bool tunnel) { + return base::MakeRefCounted<HttpProxySocketParams>( + CreateHttpProxyParams(), CreateHttpsProxyParams(), + quic::QUIC_VERSION_UNSUPPORTED, std::string(), + HostPortPair(kEndpointHost, tunnel ? 443 : 80), + session_->http_auth_cache(), session_->http_auth_handler_factory(), + session_->spdy_session_pool(), session_->quic_stream_factory(), + /*is_trusted_proxy=*/false, tunnel, TRAFFIC_ANNOTATION_FOR_TESTS); + } + + std::unique_ptr<HttpProxyConnectJob> CreateConnectJobForHttpRequest( + ConnectJob::Delegate* delegate, + RequestPriority priority = DEFAULT_PRIORITY) { + return CreateConnectJob(CreateParams(false /* tunnel */), delegate, + priority); + } + + std::unique_ptr<HttpProxyConnectJob> CreateConnectJobForTunnel( + ConnectJob::Delegate* delegate, + RequestPriority priority = DEFAULT_PRIORITY) { + return CreateConnectJob(CreateParams(true /* tunnel */), delegate, + priority); + } + + std::unique_ptr<HttpProxyConnectJob> CreateConnectJob( + scoped_refptr<HttpProxySocketParams> http_proxy_socket_params, + ConnectJob::Delegate* delegate, + RequestPriority priority) { + return std::make_unique<HttpProxyConnectJob>( + priority, + CommonConnectJobParams( + SocketTag(), &socket_factory_, session_deps_.host_resolver.get(), + proxy_delegate_.get(), + SSLClientSocketContext( + session_deps_.cert_verifier.get(), + session_deps_.channel_id_service.get(), + session_deps_.transport_security_state.get(), + session_deps_.cert_transparency_verifier.get(), + session_deps_.ct_policy_enforcer.get(), + nullptr /* ssl_session_cache_arg */), + SSLClientSocketContext( + session_deps_.cert_verifier.get(), + session_deps_.channel_id_service.get(), + session_deps_.transport_security_state.get(), + session_deps_.cert_transparency_verifier.get(), + session_deps_.ct_policy_enforcer.get(), + nullptr /* ssl_session_cache_arg */), + nullptr /* socket_performance_watcher_factory */, + network_quality_estimator_.get(), nullptr /* net_log */, + nullptr /* websocket_endpoint_lock_manager */), + std::move(http_proxy_socket_params), delegate, nullptr /* net_log */); + } + + void InitProxyDelegate() { + proxy_delegate_ = std::make_unique<TestProxyDelegate>(); + } + + void Initialize(base::span<const MockRead> reads, + base::span<const MockWrite> writes, + base::span<const MockRead> spdy_reads, + base::span<const MockWrite> spdy_writes, + IoMode connect_and_ssl_io_mode) { + if (GetParam() == SPDY) { + data_ = std::make_unique<SequencedSocketData>(spdy_reads, spdy_writes); + } else { + data_ = std::make_unique<SequencedSocketData>(reads, writes); + } + + data_->set_connect_data(MockConnect(connect_and_ssl_io_mode, OK)); + + socket_factory_.AddSocketDataProvider(data_.get()); + + if (GetParam() != HTTP) { + ssl_data_ = + std::make_unique<SSLSocketDataProvider>(connect_and_ssl_io_mode, OK); + if (GetParam() == SPDY) { + InitializeSpdySsl(ssl_data_.get()); + } + socket_factory_.AddSSLSocketDataProvider(ssl_data_.get()); + } + } + + void InitializeSpdySsl(SSLSocketDataProvider* ssl_data) { + ssl_data->next_proto = kProtoHTTP2; + } + + base::TimeDelta GetProxyConnectionTimeout() { + // Doesn't actually matter whether or not this is for a tunnel - the + // connection timeout is the same, though it probably shouldn't be the same, + // since tunnels need an extra round trip. + return HttpProxyConnectJob::ConnectionTimeout( + *CreateParams(true /* tunnel */), network_quality_estimator_.get()); + } + + protected: + std::unique_ptr<TestProxyDelegate> proxy_delegate_; + + std::unique_ptr<SSLSocketDataProvider> ssl_data_; + std::unique_ptr<SequencedSocketData> data_; + MockClientSocketFactory socket_factory_; + SpdySessionDependencies session_deps_; + + std::unique_ptr<TestNetworkQualityEstimator> network_quality_estimator_; + + std::unique_ptr<HttpNetworkSession> session_; + + base::HistogramTester histogram_tester_; + + base::FieldTrialList field_trial_list_; + + SpdyTestUtil spdy_util_; + + TestCompletionCallback callback_; +}; + +// All tests are run with three different proxy types: HTTP, HTTPS (non-SPDY) +// and SPDY. +INSTANTIATE_TEST_SUITE_P(HttpProxyType, + HttpProxyConnectJobTest, + ::testing::Values(HTTP, HTTPS, SPDY)); + +TEST_P(HttpProxyConnectJobTest, NoTunnel) { + InitProxyDelegate(); + int loop_iterations = 0; + for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) { + SCOPED_TRACE(io_mode); + session_deps_.host_resolver->set_synchronous_mode(io_mode == SYNCHRONOUS); + + Initialize(base::span<MockRead>(), base::span<MockWrite>(), + base::span<MockRead>(), base::span<MockWrite>(), io_mode); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForHttpRequest(&test_delegate); + test_delegate.StartJobExpectingResult(connect_job.get(), OK, + io_mode == SYNCHRONOUS); + EXPECT_FALSE(proxy_delegate_->on_before_tunnel_request_called()); + + ++loop_iterations; + bool is_secure_proxy = GetParam() == HTTPS || GetParam() == SPDY; + histogram_tester_.ExpectTotalCount( + "Net.HttpProxy.ConnectLatency.Insecure.Success", + is_secure_proxy ? 0 : loop_iterations); + histogram_tester_.ExpectTotalCount( + "Net.HttpProxy.ConnectLatency.Secure.Success", + is_secure_proxy ? loop_iterations : 0); + } +} + +// Pauses an HttpProxyConnectJob at various states, and check the value of +// HasEstablishedConnection(). +TEST_P(HttpProxyConnectJobTest, HasEstablishedConnectionNoTunnel) { + session_deps_.host_resolver->set_ondemand_mode(true); + + SequencedSocketData data; + data.set_connect_data(MockConnect(ASYNC, OK)); + socket_factory_.AddSocketDataProvider(&data); + + // Set up SSL, if needed. + SSLSocketDataProvider ssl_data(ASYNC, OK); + switch (GetParam()) { + case HTTP: + // No SSL needed. + break; + case HTTPS: + // SSL negotiation is the last step in non-tunnel connections over HTTPS + // proxies, so pause there, to check the final state before completion. + ssl_data = SSLSocketDataProvider(SYNCHRONOUS, ERR_IO_PENDING); + socket_factory_.AddSSLSocketDataProvider(&ssl_data); + break; + case SPDY: + InitializeSpdySsl(&ssl_data); + socket_factory_.AddSSLSocketDataProvider(&ssl_data); + break; + } + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForHttpRequest(&test_delegate); + + // Connecting should run until the request hits the HostResolver. + EXPECT_THAT(connect_job->Connect(), test::IsError(ERR_IO_PENDING)); + EXPECT_FALSE(test_delegate.has_result()); + EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests()); + EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, connect_job->GetLoadState()); + EXPECT_FALSE(connect_job->HasEstablishedConnection()); + + // Once the HostResolver completes, the job should start establishing a + // connection, which will complete asynchronously. + session_deps_.host_resolver->ResolveOnlyRequestNow(); + EXPECT_FALSE(test_delegate.has_result()); + EXPECT_EQ(LOAD_STATE_CONNECTING, connect_job->GetLoadState()); + EXPECT_FALSE(connect_job->HasEstablishedConnection()); + + switch (GetParam()) { + case HTTP: + case SPDY: + // Connection completes. Since no tunnel is established, the socket is + // returned immediately, and HasEstablishedConnection() is only specified + // to work before the ConnectJob completes. + EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk()); + break; + case HTTPS: + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(test_delegate.has_result()); + EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, connect_job->GetLoadState()); + EXPECT_TRUE(connect_job->HasEstablishedConnection()); + + // Unfortunately, there's no API to advance the paused SSL negotiation, + // so just end the test here. + } +} + +// Pauses an HttpProxyConnectJob at various states, and check the value of +// HasEstablishedConnection(). +TEST_P(HttpProxyConnectJobTest, HasEstablishedConnectionTunnel) { + session_deps_.host_resolver->set_ondemand_mode(true); + + // HTTP proxy CONNECT request / response, with a pause during the read. + MockWrite http1_writes[] = { + MockWrite(ASYNC, 0, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + }; + MockRead http1_reads[] = { + // Pause at first read. + MockRead(ASYNC, ERR_IO_PENDING, 1), + MockRead(ASYNC, 2, "HTTP/1.1 200 Connection Established\r\n\r\n"), + }; + SequencedSocketData http1_data(http1_reads, http1_writes); + http1_data.set_connect_data(MockConnect(ASYNC, OK)); + + // SPDY proxy CONNECT request / response, with a pause during the read. + spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect( + nullptr, 0, 1, DEFAULT_PRIORITY, HostPortPair(kEndpointHost, 443))); + MockWrite spdy_writes[] = {CreateMockWrite(req, 0)}; + spdy::SpdySerializedFrame resp( + spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); + MockRead spdy_reads[] = { + // Pause at first read. + MockRead(ASYNC, ERR_IO_PENDING, 1), + CreateMockRead(resp, 2, ASYNC), + MockRead(ASYNC, 0, 3), + }; + SequencedSocketData spdy_data(spdy_reads, spdy_writes); + spdy_data.set_connect_data(MockConnect(ASYNC, OK)); + + // Will point to either the HTTP/1.x or SPDY data, depending on GetParam(). + SequencedSocketData* sequenced_data = nullptr; + + SSLSocketDataProvider ssl_data(ASYNC, OK); + + switch (GetParam()) { + case HTTP: + sequenced_data = &http1_data; + break; + case HTTPS: + sequenced_data = &http1_data; + socket_factory_.AddSSLSocketDataProvider(&ssl_data); + break; + case SPDY: + sequenced_data = &spdy_data; + InitializeSpdySsl(&ssl_data); + socket_factory_.AddSSLSocketDataProvider(&ssl_data); + break; + } + + socket_factory_.AddSocketDataProvider(sequenced_data); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForTunnel(&test_delegate); + + // Connecting should run until the request hits the HostResolver. + EXPECT_THAT(connect_job->Connect(), test::IsError(ERR_IO_PENDING)); + EXPECT_FALSE(test_delegate.has_result()); + EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests()); + EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, connect_job->GetLoadState()); + EXPECT_FALSE(connect_job->HasEstablishedConnection()); + + // Once the HostResolver completes, the job should start establishing a + // connection, which will complete asynchronously. + session_deps_.host_resolver->ResolveOnlyRequestNow(); + EXPECT_FALSE(test_delegate.has_result()); + EXPECT_EQ(LOAD_STATE_CONNECTING, connect_job->GetLoadState()); + EXPECT_FALSE(connect_job->HasEstablishedConnection()); + + // Run until the socket starts reading the proxy's handshake response. + sequenced_data->RunUntilPaused(); + EXPECT_FALSE(test_delegate.has_result()); + EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL, connect_job->GetLoadState()); + EXPECT_TRUE(connect_job->HasEstablishedConnection()); + + // Finish the read, and run the job until it's complete. + sequenced_data->Resume(); + EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk()); +} + +TEST_P(HttpProxyConnectJobTest, ProxyDelegateExtraHeaders) { + // TODO(https://crbug.com/926427): The ProxyDelegate API is currently broken + // in the SPDY case. + if (GetParam() == SPDY) + return; + + InitProxyDelegate(); + + ProxyServer proxy_server( + GetParam() == HTTP ? ProxyServer::SCHEME_HTTP : ProxyServer::SCHEME_HTTPS, + HostPortPair(GetParam() == HTTP ? kHttpProxyHost : kHttpsProxyHost, + GetParam() == HTTP ? 80 : 443)); + std::string request = + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n" + "Foo: " + + proxy_server.ToURI() + "\r\n\r\n"; + MockWrite writes[] = { + MockWrite(ASYNC, 0, request.c_str()), + }; + + const char kResponseHeaderName[] = "Foo"; + const char kResponseHeaderValue[] = "Response"; + std::string response = base::StringPrintf( + "HTTP/1.1 200 Connection Established\r\n" + "%s: %s\r\n\r\n", + kResponseHeaderName, kResponseHeaderValue); + MockRead reads[] = { + MockRead(ASYNC, 1, response.c_str()), + }; + + Initialize(reads, writes, base::span<MockRead>(), base::span<MockWrite>(), + ASYNC); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForTunnel(&test_delegate); + test_delegate.StartJobExpectingResult(connect_job.get(), OK, + false /* expect_sync_result */); + proxy_delegate_->VerifyOnHttp1TunnelHeadersReceived( + proxy_server, kResponseHeaderName, kResponseHeaderValue); +} + +// Test the case where auth credentials are not cached. +TEST_P(HttpProxyConnectJobTest, NeedAuth) { + for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) { + SCOPED_TRACE(io_mode); + + session_deps_.host_resolver->set_synchronous_mode(io_mode == SYNCHRONOUS); + + MockWrite writes[] = { + MockWrite(io_mode, 0, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + MockWrite(io_mode, 5, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n" + "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), + }; + MockRead reads[] = { + // No credentials. + MockRead(io_mode, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"), + MockRead(io_mode, 2, + "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), + MockRead(io_mode, 3, "Content-Length: 10\r\n\r\n"), + MockRead(io_mode, 4, "0123456789"), + MockRead(io_mode, 6, "HTTP/1.1 200 Connection Established\r\n\r\n"), + }; + + SpdyTestUtil spdy_util; + spdy::SpdySerializedFrame connect(spdy_util.ConstructSpdyConnect( + NULL, 0, 1, DEFAULT_PRIORITY, HostPortPair(kEndpointHost, 443))); + spdy::SpdySerializedFrame rst( + spdy_util.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL)); + spdy_util.UpdateWithStreamDestruction(1); + + // After calling trans.RestartWithAuth(), this is the request we should + // be issuing -- the final header line contains the credentials. + const char* const kSpdyAuthCredentials[] = { + "proxy-authorization", + "Basic Zm9vOmJhcg==", + }; + spdy::SpdySerializedFrame connect2(spdy_util.ConstructSpdyConnect( + kSpdyAuthCredentials, base::size(kSpdyAuthCredentials) / 2, 3, + DEFAULT_PRIORITY, HostPortPair(kEndpointHost, 443))); + + MockWrite spdy_writes[] = { + CreateMockWrite(connect, 0, io_mode), + CreateMockWrite(rst, 2, io_mode), + CreateMockWrite(connect2, 3, io_mode), + }; + + // The proxy responds to the connect with a 407, using a persistent + // connection. + const char kAuthStatus[] = "407"; + const char* const kAuthChallenge[] = { + "proxy-authenticate", + "Basic realm=\"MyRealm1\"", + }; + spdy::SpdySerializedFrame connect_auth_resp( + spdy_util.ConstructSpdyReplyError(kAuthStatus, kAuthChallenge, + base::size(kAuthChallenge) / 2, 1)); + + spdy::SpdySerializedFrame connect2_resp( + spdy_util.ConstructSpdyGetReply(nullptr, 0, 3)); + MockRead spdy_reads[] = { + CreateMockRead(connect_auth_resp, 1, ASYNC), + CreateMockRead(connect2_resp, 4, ASYNC), + MockRead(ASYNC, OK, 5), + }; + + Initialize(reads, writes, spdy_reads, spdy_writes, io_mode); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForTunnel(&test_delegate); + ASSERT_EQ(ERR_IO_PENDING, connect_job->Connect()); + // Auth callback is always invoked asynchronously when a challenge is + // observed. + EXPECT_EQ(0, test_delegate.num_auth_challenges()); + + test_delegate.WaitForAuthChallenge(1); + ASSERT_TRUE(test_delegate.auth_response_info().headers); + EXPECT_EQ(407, test_delegate.auth_response_info().headers->response_code()); + std::string proxy_authenticate; + ASSERT_TRUE(test_delegate.auth_response_info().headers->EnumerateHeader( + nullptr, "Proxy-Authenticate", &proxy_authenticate)); + EXPECT_EQ(proxy_authenticate, "Basic realm=\"MyRealm1\""); + ASSERT_TRUE(test_delegate.auth_controller()); + EXPECT_FALSE(test_delegate.has_result()); + + test_delegate.auth_controller()->ResetAuth( + AuthCredentials(base::ASCIIToUTF16("foo"), base::ASCIIToUTF16("bar"))); + test_delegate.RunAuthCallback(); + // Per API contract, the request can not complete synchronously. + EXPECT_FALSE(test_delegate.has_result()); + + EXPECT_EQ(net::OK, test_delegate.WaitForResult()); + EXPECT_EQ(1, test_delegate.num_auth_challenges()); + + // Close the H2 session to prevent reuse. + if (GetParam() == SPDY) + session_->CloseAllConnections(); + // Also need to clear the auth cache before re-running the test. + session_->http_auth_cache()->ClearAllEntries(); + } +} + +// Test the case where auth credentials are not cached and the first time +// credentials are sent, they are rejected. +TEST_P(HttpProxyConnectJobTest, NeedAuthTwice) { + for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) { + SCOPED_TRACE(io_mode); + + session_deps_.host_resolver->set_synchronous_mode(io_mode == SYNCHRONOUS); + + MockWrite writes[] = { + MockWrite(io_mode, 0, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + MockWrite(io_mode, 2, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n" + "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), + MockWrite(io_mode, 4, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n" + "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), + }; + MockRead reads[] = { + // No credentials. + MockRead(io_mode, 1, + "HTTP/1.1 407 Proxy Authentication Required\r\n" + "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n" + "Content-Length: 0\r\n\r\n"), + MockRead(io_mode, 3, + "HTTP/1.1 407 Proxy Authentication Required\r\n" + "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n" + "Content-Length: 0\r\n\r\n"), + MockRead(io_mode, 5, "HTTP/1.1 200 Connection Established\r\n\r\n"), + }; + + SpdyTestUtil spdy_util; + spdy::SpdySerializedFrame connect(spdy_util.ConstructSpdyConnect( + NULL, 0, 1, DEFAULT_PRIORITY, HostPortPair(kEndpointHost, 443))); + spdy::SpdySerializedFrame rst( + spdy_util.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL)); + spdy_util.UpdateWithStreamDestruction(1); + + // After calling trans.RestartWithAuth(), this is the request we should + // be issuing -- the final header line contains the credentials. + const char* const kSpdyAuthCredentials[] = { + "proxy-authorization", + "Basic Zm9vOmJhcg==", + }; + spdy::SpdySerializedFrame connect2(spdy_util.ConstructSpdyConnect( + kSpdyAuthCredentials, base::size(kSpdyAuthCredentials) / 2, 3, + DEFAULT_PRIORITY, HostPortPair(kEndpointHost, 443))); + spdy::SpdySerializedFrame rst2( + spdy_util.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL)); + spdy_util.UpdateWithStreamDestruction(3); + + spdy::SpdySerializedFrame connect3(spdy_util.ConstructSpdyConnect( + kSpdyAuthCredentials, base::size(kSpdyAuthCredentials) / 2, 5, + DEFAULT_PRIORITY, HostPortPair(kEndpointHost, 443))); + MockWrite spdy_writes[] = { + CreateMockWrite(connect, 0, io_mode), + CreateMockWrite(rst, 2, io_mode), + CreateMockWrite(connect2, 3, io_mode), + CreateMockWrite(rst2, 5, io_mode), + CreateMockWrite(connect3, 6, io_mode), + }; + + // The proxy responds to the connect with a 407, using a persistent + // connection. + const char kAuthStatus[] = "407"; + const char* const kAuthChallenge[] = { + "proxy-authenticate", + "Basic realm=\"MyRealm1\"", + }; + spdy::SpdySerializedFrame connect_auth_resp( + spdy_util.ConstructSpdyReplyError(kAuthStatus, kAuthChallenge, + base::size(kAuthChallenge) / 2, 1)); + spdy::SpdySerializedFrame connect2_auth_resp( + spdy_util.ConstructSpdyReplyError(kAuthStatus, kAuthChallenge, + base::size(kAuthChallenge) / 2, 3)); + spdy::SpdySerializedFrame connect3_resp( + spdy_util.ConstructSpdyGetReply(nullptr, 0, 5)); + MockRead spdy_reads[] = { + CreateMockRead(connect_auth_resp, 1, ASYNC), + CreateMockRead(connect2_auth_resp, 4, ASYNC), + CreateMockRead(connect3_resp, 7, ASYNC), + MockRead(ASYNC, OK, 8), + }; + + Initialize(reads, writes, spdy_reads, spdy_writes, io_mode); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForTunnel(&test_delegate); + ASSERT_EQ(ERR_IO_PENDING, connect_job->Connect()); + // Auth callback is always invoked asynchronously when a challenge is + // observed. + EXPECT_EQ(0, test_delegate.num_auth_challenges()); + + test_delegate.WaitForAuthChallenge(1); + ASSERT_TRUE(test_delegate.auth_response_info().headers); + EXPECT_EQ(407, test_delegate.auth_response_info().headers->response_code()); + std::string proxy_authenticate; + ASSERT_TRUE(test_delegate.auth_response_info().headers->EnumerateHeader( + nullptr, "Proxy-Authenticate", &proxy_authenticate)); + EXPECT_EQ(proxy_authenticate, "Basic realm=\"MyRealm1\""); + EXPECT_FALSE(test_delegate.has_result()); + + test_delegate.auth_controller()->ResetAuth( + AuthCredentials(base::ASCIIToUTF16("foo"), base::ASCIIToUTF16("bar"))); + test_delegate.RunAuthCallback(); + // Per API contract, the auth callback can't be invoked synchronously. + EXPECT_FALSE(test_delegate.auth_controller()); + EXPECT_FALSE(test_delegate.has_result()); + + test_delegate.WaitForAuthChallenge(2); + ASSERT_TRUE(test_delegate.auth_response_info().headers); + EXPECT_EQ(407, test_delegate.auth_response_info().headers->response_code()); + ASSERT_TRUE(test_delegate.auth_response_info().headers->EnumerateHeader( + nullptr, "Proxy-Authenticate", &proxy_authenticate)); + EXPECT_EQ(proxy_authenticate, "Basic realm=\"MyRealm1\""); + EXPECT_FALSE(test_delegate.has_result()); + + test_delegate.auth_controller()->ResetAuth( + AuthCredentials(base::ASCIIToUTF16("foo"), base::ASCIIToUTF16("bar"))); + test_delegate.RunAuthCallback(); + // Per API contract, the request can't complete synchronously. + EXPECT_FALSE(test_delegate.has_result()); + + EXPECT_EQ(net::OK, test_delegate.WaitForResult()); + EXPECT_EQ(2, test_delegate.num_auth_challenges()); + + // Close the H2 session to prevent reuse. + if (GetParam() == SPDY) + session_->CloseAllConnections(); + // Also need to clear the auth cache before re-running the test. + session_->http_auth_cache()->ClearAllEntries(); + } +} + +// Test the case where auth credentials are cached. +TEST_P(HttpProxyConnectJobTest, HaveAuth) { + // Prepopulate auth cache. + const base::string16 kFoo(base::ASCIIToUTF16("foo")); + const base::string16 kBar(base::ASCIIToUTF16("bar")); + GURL proxy_url(GetParam() == HTTP + ? (std::string("http://") + kHttpProxyHost) + : (std::string("https://") + kHttpsProxyHost)); + session_->http_auth_cache()->Add( + proxy_url, "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, + "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/"); + + for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) { + SCOPED_TRACE(io_mode); + + session_deps_.host_resolver->set_synchronous_mode(io_mode == SYNCHRONOUS); + + MockWrite writes[] = { + MockWrite(io_mode, 0, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n" + "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), + }; + MockRead reads[] = { + MockRead(io_mode, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"), + }; + + const char* const kSpdyAuthCredentials[] = { + "proxy-authorization", + "Basic Zm9vOmJhcg==", + }; + SpdyTestUtil spdy_util; + spdy::SpdySerializedFrame connect(spdy_util.ConstructSpdyConnect( + kSpdyAuthCredentials, base::size(kSpdyAuthCredentials) / 2, 1, + DEFAULT_PRIORITY, HostPortPair(kEndpointHost, 443))); + + MockWrite spdy_writes[] = { + CreateMockWrite(connect, 0, ASYNC), + }; + + spdy::SpdySerializedFrame connect_resp( + spdy_util.ConstructSpdyGetReply(nullptr, 0, 1)); + MockRead spdy_reads[] = { + // SpdySession starts trying to read from the socket as soon as it's + // created, so this cannot be SYNCHRONOUS. + CreateMockRead(connect_resp, 1, ASYNC), + MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), + }; + + Initialize(reads, writes, spdy_reads, spdy_writes, io_mode); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForTunnel(&test_delegate); + // SPDY operations always complete asynchronously. + test_delegate.StartJobExpectingResult( + connect_job.get(), OK, io_mode == SYNCHRONOUS && GetParam() != SPDY); + + // Close the H2 session to prevent reuse. + if (GetParam() == SPDY) + session_->CloseAllConnections(); + } +} + +TEST_P(HttpProxyConnectJobTest, RequestPriority) { + // Make request hang during host resolution, so can observe priority there. + session_deps_.host_resolver->set_ondemand_mode(true); + + // Needed to destroy the ConnectJob in the nested socket pools. + // TODO(https://crbug.com/927088): Remove this once there are no nested socket + // pools. + session_deps_.host_resolver->rules()->AddSimulatedFailure(kHttpProxyHost); + session_deps_.host_resolver->rules()->AddSimulatedFailure(kHttpsProxyHost); + + for (int initial_priority = MINIMUM_PRIORITY; + initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) { + SCOPED_TRACE(initial_priority); + for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY; + ++new_priority) { + SCOPED_TRACE(new_priority); + if (initial_priority == new_priority) + continue; + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = CreateConnectJobForHttpRequest( + &test_delegate, static_cast<RequestPriority>(initial_priority)); + EXPECT_THAT(connect_job->Connect(), test::IsError(ERR_IO_PENDING)); + EXPECT_FALSE(test_delegate.has_result()); + + MockHostResolverBase* host_resolver = session_deps_.host_resolver.get(); + size_t request_id = host_resolver->last_id(); + EXPECT_EQ(initial_priority, host_resolver->request_priority(request_id)); + + connect_job->ChangePriority(static_cast<RequestPriority>(new_priority)); + EXPECT_EQ(new_priority, host_resolver->request_priority(request_id)); + + connect_job->ChangePriority( + static_cast<RequestPriority>(initial_priority)); + EXPECT_EQ(initial_priority, host_resolver->request_priority(request_id)); + + // Complete the resolution, which should result in destroying the + // connecting socket. Can't just delete the ConnectJob, since that won't + // destroy the ConnectJobs in the underlying pools. + host_resolver->ResolveAllPending(); + EXPECT_THAT(test_delegate.WaitForResult(), + test::IsError(ERR_PROXY_CONNECTION_FAILED)); + } + } +} + +// Make sure that HttpProxyConnectJob passes on its priority to its +// SPDY session's socket request on Init, and on SetPriority. +TEST_P(HttpProxyConnectJobTest, SetSpdySessionSocketRequestPriority) { + if (GetParam() != SPDY) + return; + session_deps_.host_resolver->set_synchronous_mode(true); + + // The SPDY CONNECT request should have a priority of MEDIUM, even though the + // ConnectJob's priority is set to HIGHEST after connection establishment. + spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect( + nullptr /* extra_headers */, 0 /* extra_header_count */, + 1 /* stream_id */, MEDIUM, HostPortPair(kEndpointHost, 443))); + MockWrite spdy_writes[] = {CreateMockWrite(req, 0, ASYNC)}; + spdy::SpdySerializedFrame resp( + spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); + MockRead spdy_reads[] = {CreateMockRead(resp, 1, ASYNC), + MockRead(ASYNC, 0, 2)}; + + Initialize(base::span<MockRead>(), base::span<MockWrite>(), spdy_reads, + spdy_writes, SYNCHRONOUS); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForTunnel(&test_delegate, MEDIUM); + EXPECT_THAT(connect_job->Connect(), test::IsError(ERR_IO_PENDING)); + EXPECT_FALSE(test_delegate.has_result()); + + connect_job->ChangePriority(HIGHEST); + + // Wait for tunnel to be established. If the frame has a MEDIUM priority + // instead of highest, the written data will not match what is expected, and + // the test will fail. + EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk()); +} + +TEST_P(HttpProxyConnectJobTest, TCPError) { + // SPDY and HTTPS are identical, as they only differ once a connection is + // established. + if (GetParam() == SPDY) + return; + int loop_iterations = 0; + for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) { + SCOPED_TRACE(io_mode); + session_deps_.host_resolver->set_synchronous_mode(io_mode == SYNCHRONOUS); + + SequencedSocketData data; + data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_CLOSED)); + socket_factory_.AddSocketDataProvider(&data); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForHttpRequest(&test_delegate); + test_delegate.StartJobExpectingResult( + connect_job.get(), ERR_PROXY_CONNECTION_FAILED, io_mode == SYNCHRONOUS); + + bool is_secure_proxy = GetParam() == HTTPS; + ++loop_iterations; + histogram_tester_.ExpectTotalCount( + "Net.HttpProxy.ConnectLatency.Insecure.Error", + is_secure_proxy ? 0 : loop_iterations); + histogram_tester_.ExpectTotalCount( + "Net.HttpProxy.ConnectLatency.Secure.Error", + is_secure_proxy ? loop_iterations : 0); + } +} + +TEST_P(HttpProxyConnectJobTest, SSLError) { + if (GetParam() == HTTP) + return; + int loop_iterations = 0; + + for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) { + SCOPED_TRACE(io_mode); + session_deps_.host_resolver->set_synchronous_mode(io_mode == SYNCHRONOUS); + + SequencedSocketData data; + data.set_connect_data(MockConnect(io_mode, OK)); + socket_factory_.AddSocketDataProvider(&data); + + SSLSocketDataProvider ssl_data(io_mode, ERR_CERT_AUTHORITY_INVALID); + if (GetParam() == SPDY) { + InitializeSpdySsl(&ssl_data); + } + socket_factory_.AddSSLSocketDataProvider(&ssl_data); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForTunnel(&test_delegate); + test_delegate.StartJobExpectingResult(connect_job.get(), + ERR_PROXY_CERTIFICATE_INVALID, + io_mode == SYNCHRONOUS); + + ++loop_iterations; + histogram_tester_.ExpectTotalCount( + "Net.HttpProxy.ConnectLatency.Secure.Error", loop_iterations); + histogram_tester_.ExpectTotalCount( + "Net.HttpProxy.ConnectLatency.Insecure.Error", 0); + } +} + +TEST_P(HttpProxyConnectJobTest, TunnelUnexpectedClose) { + for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) { + SCOPED_TRACE(io_mode); + session_deps_.host_resolver->set_synchronous_mode(io_mode == SYNCHRONOUS); + + MockWrite writes[] = { + MockWrite(io_mode, 0, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + }; + MockRead reads[] = { + MockRead(io_mode, 1, "HTTP/1.1 200 Conn"), + MockRead(io_mode, ERR_CONNECTION_CLOSED, 2), + }; + spdy::SpdySerializedFrame req(SpdyTestUtil().ConstructSpdyConnect( + nullptr /*extra_headers */, 0 /*extra_header_count */, + 1 /* stream_id */, DEFAULT_PRIORITY, HostPortPair(kEndpointHost, 443))); + MockWrite spdy_writes[] = {CreateMockWrite(req, 0, io_mode)}; + // Sync reads don't really work with SPDY, since it constantly reads from + // the socket. + MockRead spdy_reads[] = { + MockRead(ASYNC, ERR_CONNECTION_CLOSED, 1), + }; + + Initialize(reads, writes, spdy_reads, spdy_writes, io_mode); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForTunnel(&test_delegate); + + if (GetParam() == SPDY) { + // SPDY cannot process a headers block unless it's complete and so it + // returns ERR_CONNECTION_CLOSED in this case. SPDY also doesn't return + // this failure synchronously. + test_delegate.StartJobExpectingResult(connect_job.get(), + ERR_CONNECTION_CLOSED, + false /* expect_sync_result */); + } else { + test_delegate.StartJobExpectingResult(connect_job.get(), + ERR_RESPONSE_HEADERS_TRUNCATED, + io_mode == SYNCHRONOUS); + } + } +} + +TEST_P(HttpProxyConnectJobTest, Tunnel1xxResponse) { + // Tests that 1xx responses are rejected for a CONNECT request. + if (GetParam() == SPDY) { + // SPDY doesn't have 1xx responses. + return; + } + + for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) { + SCOPED_TRACE(io_mode); + session_deps_.host_resolver->set_synchronous_mode(io_mode == SYNCHRONOUS); + + MockWrite writes[] = { + MockWrite(io_mode, 0, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + }; + MockRead reads[] = { + MockRead(io_mode, 1, "HTTP/1.1 100 Continue\r\n\r\n"), + MockRead(io_mode, 2, "HTTP/1.1 200 Connection Established\r\n\r\n"), + }; + + Initialize(reads, writes, base::span<MockRead>(), base::span<MockWrite>(), + io_mode); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForTunnel(&test_delegate); + test_delegate.StartJobExpectingResult(connect_job.get(), + ERR_TUNNEL_CONNECTION_FAILED, + io_mode == SYNCHRONOUS); + } +} + +TEST_P(HttpProxyConnectJobTest, TunnelSetupError) { + for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) { + SCOPED_TRACE(io_mode); + session_deps_.host_resolver->set_synchronous_mode(io_mode == SYNCHRONOUS); + + MockWrite writes[] = { + MockWrite(io_mode, 0, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + }; + MockRead reads[] = { + MockRead(io_mode, 1, "HTTP/1.1 304 Not Modified\r\n\r\n"), + }; + SpdyTestUtil spdy_util; + spdy::SpdySerializedFrame req(spdy_util.ConstructSpdyConnect( + nullptr /* extra_headers */, 0 /* extra_header_count */, + 1 /* stream_id */, LOW, HostPortPair("www.endpoint.test", 443))); + spdy::SpdySerializedFrame rst( + spdy_util.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL)); + MockWrite spdy_writes[] = { + CreateMockWrite(req, 0, io_mode), + CreateMockWrite(rst, 2, io_mode), + }; + spdy::SpdySerializedFrame resp(spdy_util.ConstructSpdyReplyError(1)); + // Sync reads don't really work with SPDY, since it constantly reads from + // the socket. + MockRead spdy_reads[] = { + CreateMockRead(resp, 1, ASYNC), + MockRead(ASYNC, OK, 3), + }; + + Initialize(reads, writes, spdy_reads, spdy_writes, io_mode); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForTunnel(&test_delegate, LOW); + test_delegate.StartJobExpectingResult( + connect_job.get(), ERR_TUNNEL_CONNECTION_FAILED, + io_mode == SYNCHRONOUS && GetParam() != SPDY); + // Need to close the session to prevent reuse in the next loop iteration. + session_->spdy_session_pool()->CloseAllSessions(); + } +} + +// Test timeouts in the case of an auth challenge and response. +TEST_P(HttpProxyConnectJobTest, TestTimeoutsAuthChallenge) { + // Wait until this amount of time before something times out. + const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1); + + enum class TimeoutPhase { + CONNECT, + PROXY_HANDSHAKE, + SECOND_PROXY_HANDSHAKE, + + NONE, + }; + + const TimeoutPhase kTimeoutPhases[] = { + TimeoutPhase::CONNECT, + TimeoutPhase::PROXY_HANDSHAKE, + TimeoutPhase::SECOND_PROXY_HANDSHAKE, + TimeoutPhase::NONE, + }; + + session_deps_.host_resolver->set_ondemand_mode(true); + + MockWrite writes[] = { + MockWrite(ASYNC, 0, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + MockWrite(ASYNC, 3, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n" + "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), + }; + MockRead reads[] = { + // Pause before first response is read. + MockRead(ASYNC, ERR_IO_PENDING, 1), + MockRead(ASYNC, 2, + "HTTP/1.1 407 Proxy Authentication Required\r\n" + "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n" + "Content-Length: 0\r\n\r\n"), + + // Pause again before second response is read. + MockRead(ASYNC, ERR_IO_PENDING, 4), + MockRead(ASYNC, 5, "HTTP/1.1 200 Connection Established\r\n\r\n"), + }; + + SpdyTestUtil spdy_util; + spdy::SpdySerializedFrame connect(spdy_util.ConstructSpdyConnect( + NULL, 0, 1, DEFAULT_PRIORITY, HostPortPair(kEndpointHost, 443))); + spdy::SpdySerializedFrame rst( + spdy_util.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL)); + spdy_util.UpdateWithStreamDestruction(1); + + // After calling trans.RestartWithAuth(), this is the request we should + // be issuing -- the final header line contains the credentials. + const char* const kSpdyAuthCredentials[] = { + "proxy-authorization", + "Basic Zm9vOmJhcg==", + }; + spdy::SpdySerializedFrame connect2(spdy_util.ConstructSpdyConnect( + kSpdyAuthCredentials, base::size(kSpdyAuthCredentials) / 2, 3, + DEFAULT_PRIORITY, HostPortPair(kEndpointHost, 443))); + // This may be sent in some tests, either when tearing down a successful + // connection, or on timeout. + spdy::SpdySerializedFrame rst2( + spdy_util.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL)); + MockWrite spdy_writes[] = { + CreateMockWrite(connect, 0, ASYNC), + CreateMockWrite(rst, 3, ASYNC), + CreateMockWrite(connect2, 4, ASYNC), + CreateMockWrite(rst2, 8, ASYNC), + }; + + // The proxy responds to the connect with a 407, using a persistent + // connection. + const char kAuthStatus[] = "407"; + const char* const kAuthChallenge[] = { + "proxy-authenticate", + "Basic realm=\"MyRealm1\"", + }; + spdy::SpdySerializedFrame connect_auth_resp(spdy_util.ConstructSpdyReplyError( + kAuthStatus, kAuthChallenge, base::size(kAuthChallenge) / 2, 1)); + spdy::SpdySerializedFrame connect2_resp( + spdy_util.ConstructSpdyGetReply(nullptr, 0, 3)); + MockRead spdy_reads[] = { + // Pause before first response is read. + MockRead(ASYNC, ERR_IO_PENDING, 1), + CreateMockRead(connect_auth_resp, 2, ASYNC), + // Pause again before second response is read. + MockRead(ASYNC, ERR_IO_PENDING, 5), + CreateMockRead(connect2_resp, 6, ASYNC), + MockRead(ASYNC, OK, 7), + }; + + for (TimeoutPhase timeout_phase : kTimeoutPhases) { + SCOPED_TRACE(static_cast<int>(timeout_phase)); + + // Need to close the session to prevent reuse of a session from the last + // loop iteration. + session_->spdy_session_pool()->CloseAllSessions(); + // And clear the auth cache to prevent reusing cache entries. + session_->http_auth_cache()->ClearAllEntries(); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForTunnel(&test_delegate); + + // Connecting should run until the request hits the HostResolver. + EXPECT_THAT(connect_job->Connect(), test::IsError(ERR_IO_PENDING)); + EXPECT_FALSE(test_delegate.has_result()); + EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests()); + EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, connect_job->GetLoadState()); + + // Run until just before timeout. The proxy timeout can be less than the + // connection timeout, as it can be set based on the + // NetworkQualityEstimator, which the connection timeout is not. + FastForwardBy(std::min(TransportConnectJob::ConnectionTimeout(), + GetProxyConnectionTimeout()) - + kTinyTime); + EXPECT_FALSE(test_delegate.has_result()); + + // Wait until timeout, if appropriate. + if (timeout_phase == TimeoutPhase::CONNECT) { + FastForwardBy(kTinyTime); + ASSERT_TRUE(test_delegate.has_result()); + EXPECT_THAT(test_delegate.WaitForResult(), + test::IsError(ERR_CONNECTION_TIMED_OUT)); + continue; + } + + // Add mock reads for socket needed in next step. Connect phase is timed out + // before establishing a connection, so don't need them for + // TimeoutPhase::CONNECT. + Initialize(reads, writes, spdy_reads, spdy_writes, SYNCHRONOUS); + + // Finish resolution. + session_deps_.host_resolver->ResolveOnlyRequestNow(); + EXPECT_FALSE(test_delegate.has_result()); + EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL, + connect_job->GetLoadState()); + + // Wait until just before negotiation with the tunnel should time out. + FastForwardBy(HttpProxyConnectJob::TunnelTimeoutForTesting() - kTinyTime); + EXPECT_FALSE(test_delegate.has_result()); + + if (timeout_phase == TimeoutPhase::PROXY_HANDSHAKE) { + FastForwardBy(kTinyTime); + ASSERT_TRUE(test_delegate.has_result()); + EXPECT_THAT(test_delegate.WaitForResult(), + test::IsError(ERR_CONNECTION_TIMED_OUT)); + continue; + } + + data_->Resume(); + test_delegate.WaitForAuthChallenge(1); + EXPECT_FALSE(test_delegate.has_result()); + + // ConnectJobs cannot timeout while showing an auth dialog. + FastForwardBy(base::TimeDelta::FromDays(1) + GetProxyConnectionTimeout()); + EXPECT_FALSE(test_delegate.has_result()); + + // Send credentials + test_delegate.auth_controller()->ResetAuth( + AuthCredentials(base::ASCIIToUTF16("foo"), base::ASCIIToUTF16("bar"))); + test_delegate.RunAuthCallback(); + EXPECT_FALSE(test_delegate.has_result()); + + // When sending proxy auth on the same socket a challenge was just received + // on, all subsequent proxy handshakes cannot timeout. However, H2 always + // follows the establish new connection path, which means its second proxy + // handshake *can* timeout. Retrying with an already established H2 stream + // uses the entire proxy timeout for just establishing the tunnel, rather + // than the tunnel timeout. + // + // TODO(https://crbug.com/937137): This behavior seems strange. Should we do + // something about it? + if (GetParam() == SPDY) { + FastForwardBy(GetProxyConnectionTimeout() - kTinyTime); + EXPECT_FALSE(test_delegate.has_result()); + + if (timeout_phase == TimeoutPhase::SECOND_PROXY_HANDSHAKE) { + FastForwardBy(kTinyTime); + ASSERT_TRUE(test_delegate.has_result()); + EXPECT_THAT(test_delegate.WaitForResult(), + test::IsError(ERR_CONNECTION_TIMED_OUT)); + continue; + } + } else { + // See above comment for explanation. + FastForwardBy(base::TimeDelta::FromDays(1) + GetProxyConnectionTimeout()); + EXPECT_FALSE(test_delegate.has_result()); + } + + data_->Resume(); + EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk()); + } +} + +// Same as above, except test the case the first connection cannot be reused +// once credentials are received. +TEST_P(HttpProxyConnectJobTest, TestTimeoutsAuthChallengeNewConnection) { + // Proxy-Connection: Close doesn't make sense with H2. + if (GetParam() == SPDY) + return; + + enum class TimeoutPhase { + CONNECT, + PROXY_HANDSHAKE, + SECOND_CONNECT, + SECOND_PROXY_HANDSHAKE, + + // This has to be last for the H2 proxy case, since success will populate + // the H2 session pool. + NONE, + }; + + const TimeoutPhase kTimeoutPhases[] = { + TimeoutPhase::CONNECT, TimeoutPhase::PROXY_HANDSHAKE, + TimeoutPhase::SECOND_CONNECT, TimeoutPhase::SECOND_PROXY_HANDSHAKE, + TimeoutPhase::NONE, + }; + + // Wait until this amount of time before something times out. + const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1); + + session_deps_.host_resolver->set_ondemand_mode(true); + + MockWrite writes[] = { + MockWrite(ASYNC, 0, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), + }; + MockRead reads[] = { + // Pause at read. + MockRead(ASYNC, ERR_IO_PENDING, 1), + MockRead(ASYNC, 2, + "HTTP/1.1 407 Proxy Authentication Required\r\n" + "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n" + "Proxy-Connection: Close\r\n" + "Content-Length: 0\r\n\r\n"), + }; + + MockWrite writes2[] = { + MockWrite(ASYNC, 0, + "CONNECT www.endpoint.test:443 HTTP/1.1\r\n" + "Host: www.endpoint.test:443\r\n" + "Proxy-Connection: keep-alive\r\n" + "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), + }; + MockRead reads2[] = { + // Pause at read. + MockRead(ASYNC, ERR_IO_PENDING, 1), + MockRead(ASYNC, 2, "HTTP/1.1 200 Connection Established\r\n\r\n"), + }; + + for (TimeoutPhase timeout_phase : kTimeoutPhases) { + SCOPED_TRACE(static_cast<int>(timeout_phase)); + + // Need to clear the auth cache to prevent reusing cache entries. + session_->http_auth_cache()->ClearAllEntries(); + + TestConnectJobDelegate test_delegate; + std::unique_ptr<ConnectJob> connect_job = + CreateConnectJobForTunnel(&test_delegate); + + // Connecting should run until the request hits the HostResolver. + EXPECT_THAT(connect_job->Connect(), test::IsError(ERR_IO_PENDING)); + EXPECT_FALSE(test_delegate.has_result()); + EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests()); + EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, connect_job->GetLoadState()); + + // Run until just before timeout. The proxy timeout can be less than the + // connection timeout, as it can be set based on the + // NetworkQualityEstimator, which the connection timeout is not. + FastForwardBy(std::min(TransportConnectJob::ConnectionTimeout(), + GetProxyConnectionTimeout()) - + kTinyTime); + EXPECT_FALSE(test_delegate.has_result()); + + // Wait until timeout, if appropriate. + if (timeout_phase == TimeoutPhase::CONNECT) { + FastForwardBy(kTinyTime); + ASSERT_TRUE(test_delegate.has_result()); + EXPECT_THAT(test_delegate.WaitForResult(), + test::IsError(ERR_CONNECTION_TIMED_OUT)); + continue; + } + + // Add mock reads for socket needed in next step. Connect phase is timed out + // before establishing a connection, so don't need them for + // TimeoutPhase::CONNECT. + Initialize(reads, writes, base::span<MockRead>(), base::span<MockWrite>(), + SYNCHRONOUS); + + // Finish resolution. + session_deps_.host_resolver->ResolveOnlyRequestNow(); + EXPECT_FALSE(test_delegate.has_result()); + EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL, + connect_job->GetLoadState()); + + // Wait until just before negotiation with the tunnel should time out. + FastForwardBy(HttpProxyConnectJob::TunnelTimeoutForTesting() - kTinyTime); + EXPECT_FALSE(test_delegate.has_result()); + + if (timeout_phase == TimeoutPhase::PROXY_HANDSHAKE) { + FastForwardBy(kTinyTime); + ASSERT_TRUE(test_delegate.has_result()); + EXPECT_THAT(test_delegate.WaitForResult(), + test::IsError(ERR_CONNECTION_TIMED_OUT)); + continue; + } + + data_->Resume(); + test_delegate.WaitForAuthChallenge(1); + EXPECT_FALSE(test_delegate.has_result()); + + // ConnectJobs cannot timeout while showing an auth dialog. + FastForwardBy(base::TimeDelta::FromDays(1) + GetProxyConnectionTimeout()); + EXPECT_FALSE(test_delegate.has_result()); + + // Send credentials + test_delegate.auth_controller()->ResetAuth( + AuthCredentials(base::ASCIIToUTF16("foo"), base::ASCIIToUTF16("bar"))); + test_delegate.RunAuthCallback(); + EXPECT_FALSE(test_delegate.has_result()); + + // Since the connection was not reusable, a new connection needs to be + // established. + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(test_delegate.has_result()); + EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests()); + EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, connect_job->GetLoadState()); + + // Run until just before timeout. The proxy timeout can be less than the + // connection timeout, as it can be set based on the + // NetworkQualityEstimator, which the connection timeout is not. + FastForwardBy(std::min(TransportConnectJob::ConnectionTimeout(), + GetProxyConnectionTimeout()) - + kTinyTime); + EXPECT_FALSE(test_delegate.has_result()); + + // Wait until timeout, if appropriate. + if (timeout_phase == TimeoutPhase::SECOND_CONNECT) { + FastForwardBy(kTinyTime); + ASSERT_TRUE(test_delegate.has_result()); + EXPECT_THAT(test_delegate.WaitForResult(), + test::IsError(ERR_CONNECTION_TIMED_OUT)); + continue; + } + + // Add mock reads for socket needed in next step. Connect phase is timed out + // before establishing a connection, so don't need them for + // TimeoutPhase::SECOND_CONNECT. + Initialize(reads2, writes2, base::span<MockRead>(), base::span<MockWrite>(), + SYNCHRONOUS); + + // Finish resolution. + session_deps_.host_resolver->ResolveOnlyRequestNow(); + EXPECT_FALSE(test_delegate.has_result()); + EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL, + connect_job->GetLoadState()); + + // Wait until just before negotiation with the tunnel should time out. + FastForwardBy(HttpProxyConnectJob::TunnelTimeoutForTesting() - kTinyTime); + EXPECT_FALSE(test_delegate.has_result()); + + if (timeout_phase == TimeoutPhase::SECOND_PROXY_HANDSHAKE) { + FastForwardBy(kTinyTime); + ASSERT_TRUE(test_delegate.has_result()); + EXPECT_THAT(test_delegate.WaitForResult(), + test::IsError(ERR_CONNECTION_TIMED_OUT)); + continue; + } + + data_->Resume(); + ASSERT_TRUE(test_delegate.has_result()); + EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk()); + } +} + +TEST_P(HttpProxyConnectJobTest, ConnectionTimeoutMin) { + // Set RTT estimate to a low value. + base::TimeDelta rtt_estimate = base::TimeDelta::FromMilliseconds(1); + network_quality_estimator_->SetStartTimeNullHttpRtt(rtt_estimate); + + EXPECT_LE(base::TimeDelta(), GetProxyConnectionTimeout()); + + // Test against a large value. + EXPECT_GE(base::TimeDelta::FromMinutes(10), GetProxyConnectionTimeout()); + +#if (defined(OS_ANDROID) || defined(OS_IOS)) + EXPECT_EQ(base::TimeDelta::FromSeconds(8), GetProxyConnectionTimeout()); +#else + EXPECT_EQ(base::TimeDelta::FromSeconds(30), GetProxyConnectionTimeout()); +#endif +} + +TEST_P(HttpProxyConnectJobTest, ConnectionTimeoutMax) { + // Set RTT estimate to a high value. + base::TimeDelta rtt_estimate = base::TimeDelta::FromSeconds(100); + network_quality_estimator_->SetStartTimeNullHttpRtt(rtt_estimate); + + EXPECT_LE(base::TimeDelta(), GetProxyConnectionTimeout()); + + // Test against a large value. + EXPECT_GE(base::TimeDelta::FromMinutes(10), GetProxyConnectionTimeout()); + +#if (defined(OS_ANDROID) || defined(OS_IOS)) + EXPECT_EQ(base::TimeDelta::FromSeconds(30), GetProxyConnectionTimeout()); +#else + EXPECT_EQ(base::TimeDelta::FromSeconds(60), GetProxyConnectionTimeout()); +#endif +} + +// Tests the connection timeout values when the field trial parameters are +// specified. +TEST_P(HttpProxyConnectJobTest, ConnectionTimeoutWithExperiment) { + // Timeout should be kMultiplier times the HTTP RTT estimate. + const int kMultiplier = 4; + const base::TimeDelta kMinTimeout = base::TimeDelta::FromSeconds(8); + const base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(20); + + InitAdaptiveTimeoutFieldTrialWithParams(false, kMultiplier, kMultiplier, + kMinTimeout, kMaxTimeout); + EXPECT_LE(base::TimeDelta(), GetProxyConnectionTimeout()); + + base::TimeDelta rtt_estimate = base::TimeDelta::FromSeconds(4); + network_quality_estimator_->SetStartTimeNullHttpRtt(rtt_estimate); + base::TimeDelta expected_connection_timeout = kMultiplier * rtt_estimate; + EXPECT_EQ(expected_connection_timeout, GetProxyConnectionTimeout()); + + // Connection timeout should not exceed kMaxTimeout. + rtt_estimate = base::TimeDelta::FromSeconds(25); + network_quality_estimator_->SetStartTimeNullHttpRtt(rtt_estimate); + EXPECT_EQ(kMaxTimeout, GetProxyConnectionTimeout()); + + // Connection timeout should not be less than kMinTimeout. + rtt_estimate = base::TimeDelta::FromSeconds(0); + network_quality_estimator_->SetStartTimeNullHttpRtt(rtt_estimate); + EXPECT_EQ(kMinTimeout, GetProxyConnectionTimeout()); +} + +// Tests the connection timeout values when the field trial parameters are +// specified. +TEST_P(HttpProxyConnectJobTest, ConnectionTimeoutExperimentDifferentParams) { + // Timeout should be kMultiplier times the HTTP RTT estimate. + const int kMultiplier = 3; + const base::TimeDelta kMinTimeout = base::TimeDelta::FromSeconds(2); + const base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(30); + + InitAdaptiveTimeoutFieldTrialWithParams(false, kMultiplier, kMultiplier, + kMinTimeout, kMaxTimeout); + EXPECT_LE(base::TimeDelta(), GetProxyConnectionTimeout()); + + base::TimeDelta rtt_estimate = base::TimeDelta::FromSeconds(2); + network_quality_estimator_->SetStartTimeNullHttpRtt(rtt_estimate); + EXPECT_EQ(kMultiplier * rtt_estimate, GetProxyConnectionTimeout()); + + // A change in RTT estimate should also change the connection timeout. + rtt_estimate = base::TimeDelta::FromSeconds(7); + network_quality_estimator_->SetStartTimeNullHttpRtt(rtt_estimate); + EXPECT_EQ(kMultiplier * rtt_estimate, GetProxyConnectionTimeout()); + + // Connection timeout should not exceed kMaxTimeout. + rtt_estimate = base::TimeDelta::FromSeconds(35); + network_quality_estimator_->SetStartTimeNullHttpRtt(rtt_estimate); + EXPECT_EQ(kMaxTimeout, GetProxyConnectionTimeout()); + + // Connection timeout should not be less than kMinTimeout. + rtt_estimate = base::TimeDelta::FromSeconds(0); + network_quality_estimator_->SetStartTimeNullHttpRtt(rtt_estimate); + EXPECT_EQ(kMinTimeout, GetProxyConnectionTimeout()); +} + +TEST_P(HttpProxyConnectJobTest, ConnectionTimeoutWithConnectionProperty) { + const int kSecureMultiplier = 3; + const int kNonSecureMultiplier = 5; + const base::TimeDelta kMinTimeout = base::TimeDelta::FromSeconds(2); + const base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(30); + + InitAdaptiveTimeoutFieldTrialWithParams( + false, kSecureMultiplier, kNonSecureMultiplier, kMinTimeout, kMaxTimeout); + + const base::TimeDelta kRttEstimate = base::TimeDelta::FromSeconds(2); + network_quality_estimator_->SetStartTimeNullHttpRtt(kRttEstimate); + // By default, connection timeout should return the timeout for secure + // proxies. + if (GetParam() != HTTP) { + EXPECT_EQ(kSecureMultiplier * kRttEstimate, GetProxyConnectionTimeout()); + } else { + EXPECT_EQ(kNonSecureMultiplier * kRttEstimate, GetProxyConnectionTimeout()); + } +} + +// Tests the connection timeout values when the field trial parameters are not +// specified. +TEST_P(HttpProxyConnectJobTest, ProxyPoolTimeoutWithExperimentDefaultParams) { + InitAdaptiveTimeoutFieldTrialWithParams(true, 0, 0, base::TimeDelta(), + base::TimeDelta()); + EXPECT_LE(base::TimeDelta(), GetProxyConnectionTimeout()); + + // Timeout should be |http_rtt_multiplier| times the HTTP RTT + // estimate. + base::TimeDelta rtt_estimate = base::TimeDelta::FromMilliseconds(10); + network_quality_estimator_->SetStartTimeNullHttpRtt(rtt_estimate); + // Connection timeout should not be less than the HTTP RTT estimate. + EXPECT_LE(rtt_estimate, GetProxyConnectionTimeout()); + + // A change in RTT estimate should also change the connection timeout. + rtt_estimate = base::TimeDelta::FromSeconds(10); + network_quality_estimator_->SetStartTimeNullHttpRtt(rtt_estimate); + // Connection timeout should not be less than the HTTP RTT estimate. + EXPECT_LE(rtt_estimate, GetProxyConnectionTimeout()); + + // Set RTT to a very large value. + rtt_estimate = base::TimeDelta::FromMinutes(60); + network_quality_estimator_->SetStartTimeNullHttpRtt(rtt_estimate); + EXPECT_GT(rtt_estimate, GetProxyConnectionTimeout()); + + // Set RTT to a very small value. + rtt_estimate = base::TimeDelta::FromSeconds(0); + network_quality_estimator_->SetStartTimeNullHttpRtt(rtt_estimate); + EXPECT_LT(rtt_estimate, GetProxyConnectionTimeout()); +} + +} // namespace net diff --git a/chromium/net/http/http_response_body_drainer.cc b/chromium/net/http/http_response_body_drainer.cc index b18b1938955..45f363b6dd8 100644 --- a/chromium/net/http/http_response_body_drainer.cc +++ b/chromium/net/http/http_response_body_drainer.cc @@ -4,6 +4,7 @@ #include "net/http/http_response_body_drainer.h" +#include "base/bind.h" #include "base/compiler_specific.h" #include "base/logging.h" #include "base/memory/ptr_util.h" diff --git a/chromium/net/http/http_response_headers.cc b/chromium/net/http/http_response_headers.cc index 63f47c788a0..7e606be7d17 100644 --- a/chromium/net/http/http_response_headers.cc +++ b/chromium/net/http/http_response_headers.cc @@ -924,9 +924,12 @@ bool HttpResponseHeaders::IsRedirect(std::string* location) const { parsed_[i].value_end); // Escape any non-ASCII characters to preserve them. The server should // only be returning ASCII here, but for compat we need to do this. - *location = base::IsStringASCII(location_strpiece) - ? location_strpiece.as_string() - : EscapeNonASCIIAndPercent(location_strpiece); + // + // The URL parser escapes things internally, but it expect the bytes to be + // valid UTF-8, so encoding errors turn into replacement characters before + // escaping. Escaping here preserves the bytes as-is. See + // https://crbug.com/942073#c14. + *location = EscapeNonASCII(location_strpiece); } return true; diff --git a/chromium/net/http/http_response_headers_unittest.cc b/chromium/net/http/http_response_headers_unittest.cc index 19d09278407..d70fb4d87e7 100644 --- a/chromium/net/http/http_response_headers_unittest.cc +++ b/chromium/net/http/http_response_headers_unittest.cc @@ -303,9 +303,9 @@ TestData response_headers_tests[] = { HttpVersion(1, 1), 200, "OK"}, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - CommonHttpResponseHeadersTest, - testing::ValuesIn(response_headers_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + CommonHttpResponseHeadersTest, + testing::ValuesIn(response_headers_tests)); struct PersistData { HttpResponseHeaders::PersistOptions options; @@ -495,9 +495,9 @@ const struct PersistData persistence_tests[] = { "Bar: 1\n"}, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - PersistenceTest, - testing::ValuesIn(persistence_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + PersistenceTest, + testing::ValuesIn(persistence_tests)); TEST(HttpResponseHeadersTest, EnumerateHeader_Coalesced) { // Ensure that commas in quoted strings are not regarded as value separators. @@ -824,9 +824,9 @@ const ContentTypeTestData mimetype_tests[] = { }; // clang-format on -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - ContentTypeTest, - testing::ValuesIn(mimetype_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + ContentTypeTest, + testing::ValuesIn(mimetype_tests)); struct RequiresValidationTestData { const char* headers; @@ -1022,9 +1022,9 @@ const struct RequiresValidationTestData requires_validation_tests[] = { // TODO(darin): Add many many more tests here. }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - RequiresValidationTest, - testing::ValuesIn(requires_validation_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + RequiresValidationTest, + testing::ValuesIn(requires_validation_tests)); struct UpdateTestData { const char* orig_headers; @@ -1159,9 +1159,9 @@ const UpdateTestData update_tests[] = { "Content-Location: /example_page.html\n"}, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - UpdateTest, - testing::ValuesIn(update_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + UpdateTest, + testing::ValuesIn(update_tests)); struct EnumerateHeaderTestData { const char* headers; @@ -1217,9 +1217,9 @@ const EnumerateHeaderTestData enumerate_header_tests[] = { "Foo: ,, 1,, 2, 3,,\n"}, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - EnumerateHeaderLinesTest, - testing::ValuesIn(enumerate_header_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + EnumerateHeaderLinesTest, + testing::ValuesIn(enumerate_header_tests)); struct IsRedirectTestData { const char* headers; @@ -1304,9 +1304,9 @@ const IsRedirectTestData is_redirect_tests[] = { }, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - IsRedirectTest, - testing::ValuesIn(is_redirect_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + IsRedirectTest, + testing::ValuesIn(is_redirect_tests)); struct ContentLengthTestData { const char* headers; @@ -1381,9 +1381,9 @@ const ContentLengthTestData content_length_tests[] = { -1}, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - GetContentLengthTest, - testing::ValuesIn(content_length_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + GetContentLengthTest, + testing::ValuesIn(content_length_tests)); struct ContentRangeTestData { const char* headers; @@ -1435,9 +1435,9 @@ const ContentRangeTestData content_range_tests[] = { false, -1, -1, -1}, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - ContentRangeTest, - testing::ValuesIn(content_range_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + ContentRangeTest, + testing::ValuesIn(content_range_tests)); struct KeepAliveTestData { const char* headers; @@ -1603,9 +1603,9 @@ const KeepAliveTestData keepalive_tests[] = { }, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - IsKeepAliveTest, - testing::ValuesIn(keepalive_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + IsKeepAliveTest, + testing::ValuesIn(keepalive_tests)); struct HasStrongValidatorsTestData { const char* headers; @@ -1673,9 +1673,9 @@ const HasStrongValidatorsTestData strong_validators_tests[] = { } }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - HasStrongValidatorsTest, - testing::ValuesIn(strong_validators_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + HasStrongValidatorsTest, + testing::ValuesIn(strong_validators_tests)); TEST(HttpResponseHeadersTest, HasValidatorsNone) { std::string headers("HTTP/1.1 200 OK"); @@ -1819,9 +1819,9 @@ const AddHeaderTestData add_header_tests[] = { }, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - AddHeaderTest, - testing::ValuesIn(add_header_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + AddHeaderTest, + testing::ValuesIn(add_header_tests)); struct RemoveHeaderTestData { const char* orig_headers; @@ -1873,9 +1873,9 @@ const RemoveHeaderTestData remove_header_tests[] = { }, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - RemoveHeaderTest, - testing::ValuesIn(remove_header_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + RemoveHeaderTest, + testing::ValuesIn(remove_header_tests)); struct RemoveHeadersTestData { const char* orig_headers; @@ -1935,9 +1935,9 @@ const RemoveHeadersTestData remove_headers_tests[] = { "connection: keep-alive\n"}, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - RemoveHeadersTest, - testing::ValuesIn(remove_headers_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + RemoveHeadersTest, + testing::ValuesIn(remove_headers_tests)); struct RemoveIndividualHeaderTestData { const char* orig_headers; @@ -2038,9 +2038,9 @@ const RemoveIndividualHeaderTestData remove_individual_header_tests[] = { }, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - RemoveIndividualHeaderTest, - testing::ValuesIn(remove_individual_header_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + RemoveIndividualHeaderTest, + testing::ValuesIn(remove_individual_header_tests)); struct ReplaceStatusTestData { const char* orig_headers; @@ -2102,9 +2102,9 @@ const ReplaceStatusTestData replace_status_tests[] = { }, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - ReplaceStatusTest, - testing::ValuesIn(replace_status_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + ReplaceStatusTest, + testing::ValuesIn(replace_status_tests)); struct UpdateWithNewRangeTestData { const char* orig_headers; @@ -2163,9 +2163,9 @@ const UpdateWithNewRangeTestData update_range_tests[] = { }, }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - UpdateWithNewRangeTest, - testing::ValuesIn(update_range_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + UpdateWithNewRangeTest, + testing::ValuesIn(update_range_tests)); TEST_F(HttpResponseHeadersCacheControlTest, AbsentMaxAgeReturnsFalse) { InitializeHeadersWithCacheControl("nocache"); @@ -2244,9 +2244,9 @@ const MaxAgeTestData max_age_tests[] = { std::numeric_limits<int64_t>::max()}, // Overflow int64_t. }; -INSTANTIATE_TEST_CASE_P(HttpResponseHeadersCacheControl, - MaxAgeEdgeCasesTest, - testing::ValuesIn(max_age_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeadersCacheControl, + MaxAgeEdgeCasesTest, + testing::ValuesIn(max_age_tests)); TEST_F(HttpResponseHeadersCacheControlTest, AbsentStaleWhileRevalidateReturnsFalse) { @@ -2337,9 +2337,9 @@ const struct GetCurrentAgeTestData get_current_age_tests[] = { "Fri, 20 Jan 2011 10:40:08 GMT", "Fri, 20 Jan 2011 10:40:12 GMT", "Fri, 20 Jan 2011 10:40:14 GMT", 7}}; -INSTANTIATE_TEST_CASE_P(HttpResponseHeaders, - GetCurrentAgeTest, - testing::ValuesIn(get_current_age_tests)); +INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, + GetCurrentAgeTest, + testing::ValuesIn(get_current_age_tests)); } // namespace diff --git a/chromium/net/http/http_response_info.cc b/chromium/net/http/http_response_info.cc index d1a4eb709be..0dfb809bb80 100644 --- a/chromium/net/http/http_response_info.cc +++ b/chromium/net/http/http_response_info.cc @@ -229,7 +229,13 @@ bool HttpResponseInfo::InitFromPickle(const base::Pickle& pickle, uint16_t socket_address_port; if (!iter.ReadUInt16(&socket_address_port)) return false; - socket_address = HostPortPair(socket_address_host, socket_address_port); + + IPAddress ip_address; + if (ip_address.AssignFromIPLiteral(socket_address_host)) { + remote_endpoint = IPEndPoint(ip_address, socket_address_port); + } else if (ParseURLHostnameToAddress(socket_address_host, &ip_address)) { + remote_endpoint = IPEndPoint(ip_address, socket_address_port); + } // Read protocol-version. if (flags & RESPONSE_INFO_HAS_ALPN_NEGOTIATED_PROTOCOL) { @@ -364,8 +370,8 @@ void HttpResponseInfo::Persist(base::Pickle* pickle, if (vary_data.is_valid()) vary_data.Persist(pickle); - pickle->WriteString(socket_address.host()); - pickle->WriteUInt16(socket_address.port()); + pickle->WriteString(remote_endpoint.ToStringWithoutPort()); + pickle->WriteUInt16(remote_endpoint.port()); if (was_alpn_negotiated) pickle->WriteString(alpn_negotiated_protocol); @@ -413,6 +419,7 @@ bool HttpResponseInfo::DidUseQuic() const { case CONNECTION_INFO_QUIC_44: case CONNECTION_INFO_QUIC_45: case CONNECTION_INFO_QUIC_46: + case CONNECTION_INFO_QUIC_47: case CONNECTION_INFO_QUIC_99: return true; case NUM_OF_CONNECTION_INFOS: @@ -476,6 +483,8 @@ std::string HttpResponseInfo::ConnectionInfoToString( return "http/2+quic/45"; case CONNECTION_INFO_QUIC_46: return "http/2+quic/46"; + case CONNECTION_INFO_QUIC_47: + return "http/2+quic/47"; case CONNECTION_INFO_QUIC_99: return "http/2+quic/99"; case CONNECTION_INFO_HTTP0_9: diff --git a/chromium/net/http/http_response_info.h b/chromium/net/http/http_response_info.h index 166dee91cdf..48fea75c44e 100644 --- a/chromium/net/http/http_response_info.h +++ b/chromium/net/http/http_response_info.h @@ -8,6 +8,7 @@ #include <string> #include "base/time/time.h" +#include "net/base/ip_endpoint.h" #include "net/base/net_export.h" #include "net/base/proxy_server.h" #include "net/http/http_vary_data.h" @@ -59,6 +60,7 @@ class NET_EXPORT HttpResponseInfo { CONNECTION_INFO_QUIC_44 = 23, CONNECTION_INFO_QUIC_45 = 24, CONNECTION_INFO_QUIC_46 = 25, + CONNECTION_INFO_QUIC_47 = 26, NUM_OF_CONNECTION_INFOS, }; @@ -169,7 +171,7 @@ class NET_EXPORT HttpResponseInfo { // originally. This is true even if the response was re-validated using a // different remote address, or if some of the content came from a byte-range // request to a different address. - HostPortPair socket_address; + IPEndPoint remote_endpoint; // Protocol negotiated with the server. std::string alpn_negotiated_protocol; diff --git a/chromium/net/http/http_server_properties_impl_unittest.cc b/chromium/net/http/http_server_properties_impl_unittest.cc index 99dd7f4fd52..5ae3d35fbf1 100644 --- a/chromium/net/http/http_server_properties_impl_unittest.cc +++ b/chromium/net/http/http_server_properties_impl_unittest.cc @@ -8,6 +8,7 @@ #include <string> #include <vector> +#include "base/bind.h" #include "base/json/json_writer.h" #include "base/logging.h" #include "base/run_loop.h" @@ -1184,7 +1185,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc2) { FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[i]); // Ensure brokenness of |alternative_service1| has expired. - EXPECT_FALSE(MainThreadHasPendingTask()); + EXPECT_EQ(0u, GetPendingMainThreadTaskCount()); EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1)); } diff --git a/chromium/net/http/http_server_properties_manager.cc b/chromium/net/http/http_server_properties_manager.cc index b3bd0443f85..d4caa61d375 100644 --- a/chromium/net/http/http_server_properties_manager.cc +++ b/chromium/net/http/http_server_properties_manager.cc @@ -1171,7 +1171,7 @@ void HttpServerPropertiesManager::SaveAlternativeServiceToServerPrefs( // JSON cannot store int64_t, so expiration is converted to a string. alternative_service_dict->SetString( kExpirationKey, - base::Int64ToString( + base::NumberToString( alternative_service_info.expiration().ToInternalValue())); std::unique_ptr<base::ListValue> advertised_versions_list = std::make_unique<base::ListValue>(); @@ -1289,12 +1289,12 @@ void HttpServerPropertiesManager::SaveBrokenAlternativeServicesToPrefs( DCHECK(result); DCHECK(!entry_dict->HasKey(kBrokenUntilKey)); entry_dict->SetKey(kBrokenUntilKey, - base::Value(base::Int64ToString(expiration_int64))); + base::Value(base::NumberToString(expiration_int64))); } else { base::DictionaryValue entry_dict; AddAlternativeServiceFieldsToDictionaryValue(alt_service, &entry_dict); entry_dict.SetKey(kBrokenUntilKey, - base::Value(base::Int64ToString(expiration_int64))); + base::Value(base::NumberToString(expiration_int64))); json_list->GetList().push_back(std::move(entry_dict)); } } diff --git a/chromium/net/http/http_server_properties_manager_unittest.cc b/chromium/net/http/http_server_properties_manager_unittest.cc index b18120f47b0..7a78852a1b9 100644 --- a/chromium/net/http/http_server_properties_manager_unittest.cc +++ b/chromium/net/http/http_server_properties_manager_unittest.cc @@ -121,7 +121,7 @@ class HttpServerPropertiesManagerTest : public testing::TestWithParam<int>, EXPECT_FALSE(http_server_props_manager_->IsInitialized()); pref_delegate_->SetPrefs(base::DictionaryValue()); EXPECT_TRUE(http_server_props_manager_->IsInitialized()); - EXPECT_FALSE(MainThreadHasPendingTask()); + EXPECT_EQ(0u, GetPendingMainThreadTaskCount()); EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); } @@ -150,9 +150,9 @@ class HttpServerPropertiesManagerTest : public testing::TestWithParam<int>, DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManagerTest); }; -INSTANTIATE_TEST_CASE_P(/* no prefix */, - HttpServerPropertiesManagerTest, - ::testing::ValuesIn(kHttpServerPropertiesVersions)); +INSTANTIATE_TEST_SUITE_P(/* no prefix */, + HttpServerPropertiesManagerTest, + ::testing::ValuesIn(kHttpServerPropertiesVersions)); TEST_P(HttpServerPropertiesManagerTest, SingleUpdateForTwoSpdyServerPrefChanges) { @@ -277,7 +277,7 @@ TEST_P(HttpServerPropertiesManagerTest, pref_delegate_->SetPrefs(http_server_properties_dict); // Should be a delayed task to update the cache from the prefs file. - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); // Verify SupportsSpdy. @@ -401,7 +401,7 @@ TEST_P(HttpServerPropertiesManagerTest, BadCachedHostPortPair) { pref_delegate_->SetPrefs(http_server_properties_dict); EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); // Prefs should have been overwritten, due to the bad data. EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -463,7 +463,7 @@ TEST_P(HttpServerPropertiesManagerTest, BadCachedAltProtocolPort) { pref_delegate_->SetPrefs(http_server_properties_dict); EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); // Prefs should have been overwritten, due to the bad data. EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -485,7 +485,7 @@ TEST_P(HttpServerPropertiesManagerTest, SupportsSpdy) { // Run the task. EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -493,7 +493,7 @@ TEST_P(HttpServerPropertiesManagerTest, SupportsSpdy) { // update. http_server_props_manager_->SetSupportsSpdy(spdy_server, true); EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_FALSE(MainThreadHasPendingTask()); + EXPECT_EQ(0u, GetPendingMainThreadTaskCount()); EXPECT_TRUE(http_server_props_manager_->SupportsRequestPriority(spdy_server)); } @@ -527,7 +527,7 @@ TEST_P(HttpServerPropertiesManagerTest, EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); FastForwardBy(base::TimeDelta::FromMilliseconds(20)); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_FALSE(MainThreadHasPendingTask()); + EXPECT_EQ(0u, GetPendingMainThreadTaskCount()); EXPECT_TRUE(http_server_props_manager_->SupportsRequestPriority(spdy_server)); EXPECT_TRUE( @@ -558,7 +558,7 @@ TEST_P(HttpServerPropertiesManagerTest, GetAlternativeServiceInfos) { // Run the task. EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -611,7 +611,7 @@ TEST_P(HttpServerPropertiesManagerTest, SetAlternativeServicesEmpty) { http_server_props_manager_->SetAlternativeServices( spdy_server_mail, AlternativeServiceInfoVector()); - EXPECT_FALSE(MainThreadHasPendingTask()); + EXPECT_EQ(0u, GetPendingMainThreadTaskCount()); EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); EXPECT_FALSE(HasAlternativeService(spdy_server_mail)); @@ -653,7 +653,7 @@ TEST_P(HttpServerPropertiesManagerTest, ConfirmAlternativeService) { EXPECT_EQ(2u, GetPendingMainThreadTaskCount()); // Run the task. - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -702,7 +702,7 @@ TEST_P(HttpServerPropertiesManagerTest, EXPECT_EQ(2u, GetPendingMainThreadTaskCount()); // Run the task. - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -751,7 +751,7 @@ TEST_P(HttpServerPropertiesManagerTest, EXPECT_EQ(2u, GetPendingMainThreadTaskCount()); // Run the task. - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -797,7 +797,7 @@ TEST_P(HttpServerPropertiesManagerTest, OnDefaultNetworkChangedWithBrokenOnly) { EXPECT_EQ(2u, GetPendingMainThreadTaskCount()); // Run the task. - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -818,7 +818,7 @@ TEST_P(HttpServerPropertiesManagerTest, SupportsQuic) { // Run the task. EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -828,7 +828,7 @@ TEST_P(HttpServerPropertiesManagerTest, SupportsQuic) { // Another task should not be scheduled. http_server_props_manager_->SetSupportsQuic(true, actual_address); EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_FALSE(MainThreadHasPendingTask()); + EXPECT_EQ(0u, GetPendingMainThreadTaskCount()); } TEST_P(HttpServerPropertiesManagerTest, ServerNetworkStats) { @@ -844,14 +844,14 @@ TEST_P(HttpServerPropertiesManagerTest, ServerNetworkStats) { // Run the task. EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); // Another task should not be scheduled. http_server_props_manager_->SetServerNetworkStats(mail_server, stats1); EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_FALSE(MainThreadHasPendingTask()); + EXPECT_EQ(GetPendingMainThreadTaskCount(), 0u); const ServerNetworkStats* stats2 = http_server_props_manager_->GetServerNetworkStats(mail_server); @@ -861,7 +861,7 @@ TEST_P(HttpServerPropertiesManagerTest, ServerNetworkStats) { // Run the task. EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -882,7 +882,7 @@ TEST_P(HttpServerPropertiesManagerTest, QuicServerInfo) { // Run the task. EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -893,7 +893,7 @@ TEST_P(HttpServerPropertiesManagerTest, QuicServerInfo) { http_server_props_manager_->SetQuicServerInfo(mail_quic_server_id, quic_server_info1); EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_FALSE(MainThreadHasPendingTask()); + EXPECT_EQ(0u, GetPendingMainThreadTaskCount()); } TEST_P(HttpServerPropertiesManagerTest, Clear) { @@ -930,7 +930,7 @@ TEST_P(HttpServerPropertiesManagerTest, Clear) { // Advance time by just enough so that the prefs update task is executed but // not the task to expire the brokenness of |broken_alternative_service|. FastForwardBy(HttpServerPropertiesManager::GetUpdatePrefsDelayForTesting()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); EXPECT_TRUE(http_server_props_manager_->IsAlternativeServiceBroken( @@ -1230,7 +1230,7 @@ TEST_P(HttpServerPropertiesManagerTest, // Since this test has no pref corruption, there shouldn't be any pref update. EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_FALSE(MainThreadHasPendingTask()); + EXPECT_EQ(0u, GetPendingMainThreadTaskCount()); // Schedule one more cache update. The task should be successfully scheduled // on the task runner. @@ -1242,7 +1242,7 @@ TEST_P(HttpServerPropertiesManagerTest, } TEST_P(HttpServerPropertiesManagerTest, AddToAlternativeServiceMap) { - std::unique_ptr<base::Value> server_value = base::JSONReader::Read( + std::unique_ptr<base::Value> server_value = base::JSONReader::ReadDeprecated( "{\"alternative_service\":[{\"port\":443,\"protocol_str\":\"h2\"}," "{\"port\":123,\"protocol_str\":\"quic\"," "\"expiration\":\"9223372036854775807\"},{\"host\":\"example.org\"," @@ -1294,7 +1294,7 @@ TEST_P(HttpServerPropertiesManagerTest, AddToAlternativeServiceMap) { // Regression test for https://crbug.com/615497. TEST_P(HttpServerPropertiesManagerTest, DoNotLoadAltSvcForInsecureOrigins) { - std::unique_ptr<base::Value> server_value = base::JSONReader::Read( + std::unique_ptr<base::Value> server_value = base::JSONReader::ReadDeprecated( "{\"alternative_service\":[{\"port\":443,\"protocol_str\":\"h2\"," "\"expiration\":\"9223372036854775807\"}]}"); ASSERT_TRUE(server_value); @@ -1395,7 +1395,7 @@ TEST_P(HttpServerPropertiesManagerTest, DoNotLoadExpiredAlternativeService) { base::Time time_one_day_ago = base::Time::Now() - base::TimeDelta::FromDays(1); expired_dict->SetString( - "expiration", base::Int64ToString(time_one_day_ago.ToInternalValue())); + "expiration", base::NumberToString(time_one_day_ago.ToInternalValue())); alternative_service_list->Append(std::move(expired_dict)); auto valid_dict = std::make_unique<base::DictionaryValue>(); @@ -1403,7 +1403,7 @@ TEST_P(HttpServerPropertiesManagerTest, DoNotLoadExpiredAlternativeService) { valid_dict->SetString("host", "valid.example.com"); valid_dict->SetInteger("port", 443); valid_dict->SetString( - "expiration", base::Int64ToString(one_day_from_now_.ToInternalValue())); + "expiration", base::NumberToString(one_day_from_now_.ToInternalValue())); alternative_service_list->Append(std::move(valid_dict)); base::DictionaryValue server_pref_dict; @@ -1448,7 +1448,7 @@ TEST_P(HttpServerPropertiesManagerTest, PersistAdvertisedVersionsToPref) { base::Time expiration1; ASSERT_TRUE(base::Time::FromUTCString("2036-12-01 10:00:00", &expiration1)); quic::QuicTransportVersionVector advertised_versions = { - quic::QUIC_VERSION_44, quic::QUIC_VERSION_35}; + quic::QUIC_VERSION_44, quic::QUIC_VERSION_39}; alternative_service_info_vector.push_back( AlternativeServiceInfo::CreateQuicAlternativeServiceInfo( quic_alternative_service1, expiration1, advertised_versions)); @@ -1487,7 +1487,7 @@ TEST_P(HttpServerPropertiesManagerTest, PersistAdvertisedVersionsToPref) { // Update Prefs. EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -1496,7 +1496,7 @@ TEST_P(HttpServerPropertiesManagerTest, PersistAdvertisedVersionsToPref) { "{\"quic_servers\":{\"https://mail.google.com:80\":{" "\"server_info\":\"quic_server_info1\"}},\"servers\":[" "{\"https://www.google.com:80\":{\"alternative_service\":[{" - "\"advertised_versions\":[35,44],\"expiration\":\"13756212000000000\"," + "\"advertised_versions\":[39,44],\"expiration\":\"13756212000000000\"," "\"port\":443,\"protocol_str\":\"quic\"},{\"advertised_versions\":[]," "\"expiration\":\"13758804000000000\",\"host\":\"www.google.com\"," "\"port\":1234,\"protocol_str\":\"h2\"}]}}," @@ -1515,12 +1515,12 @@ TEST_P(HttpServerPropertiesManagerTest, PersistAdvertisedVersionsToPref) { } TEST_P(HttpServerPropertiesManagerTest, ReadAdvertisedVersionsFromPref) { - std::unique_ptr<base::Value> server_value = base::JSONReader::Read( + std::unique_ptr<base::Value> server_value = base::JSONReader::ReadDeprecated( "{\"alternative_service\":[" "{\"port\":443,\"protocol_str\":\"quic\"}," "{\"port\":123,\"protocol_str\":\"quic\"," "\"expiration\":\"9223372036854775807\"," - "\"advertised_versions\":[44,35]}]}"); + "\"advertised_versions\":[44,39]}]}"); ASSERT_TRUE(server_value); base::DictionaryValue* server_dict; ASSERT_TRUE(server_value->GetAsDictionary(&server_dict)); @@ -1557,7 +1557,7 @@ TEST_P(HttpServerPropertiesManagerTest, ReadAdvertisedVersionsFromPref) { const quic::QuicTransportVersionVector loaded_advertised_versions = alternative_service_info_vector[1].advertised_versions(); EXPECT_EQ(2u, loaded_advertised_versions.size()); - EXPECT_EQ(quic::QUIC_VERSION_35, loaded_advertised_versions[0]); + EXPECT_EQ(quic::QUIC_VERSION_39, loaded_advertised_versions[0]); EXPECT_EQ(quic::QUIC_VERSION_44, loaded_advertised_versions[1]); } @@ -1590,7 +1590,7 @@ TEST_P(HttpServerPropertiesManagerTest, // Update Prefs. EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -1616,7 +1616,7 @@ TEST_P(HttpServerPropertiesManagerTest, AlternativeServiceInfoVector alternative_service_info_vector_2; // Quic alternative service set with two advertised QUIC versions. quic::QuicTransportVersionVector advertised_versions = { - quic::QUIC_VERSION_44, quic::QUIC_VERSION_35}; + quic::QUIC_VERSION_44, quic::QUIC_VERSION_39}; alternative_service_info_vector_2.push_back( AlternativeServiceInfo::CreateQuicAlternativeServiceInfo( quic_alternative_service1, expiration1, advertised_versions)); @@ -1625,7 +1625,7 @@ TEST_P(HttpServerPropertiesManagerTest, // Update Prefs. EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardUntilNoTasksRemain(); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); @@ -1634,7 +1634,7 @@ TEST_P(HttpServerPropertiesManagerTest, "{\"quic_servers\":{\"https://mail.google.com:80\":" "{\"server_info\":\"quic_server_info1\"}},\"servers\":[" "{\"https://www.google.com:80\":" - "{\"alternative_service\":[{\"advertised_versions\":[35,44]," + "{\"alternative_service\":[{\"advertised_versions\":[39,44]," "\"expiration\":\"13756212000000000\",\"port\":443," "\"protocol_str\":\"quic\"}]}}],\"supports_quic\":" "{\"address\":\"127.0.0.1\",\"used_quic\":true},\"version\":5}"; @@ -1646,7 +1646,7 @@ TEST_P(HttpServerPropertiesManagerTest, AlternativeServiceInfoVector alternative_service_info_vector_3; // A same set of QUIC versions but listed in a different order. quic::QuicTransportVersionVector advertised_versions_2 = { - quic::QUIC_VERSION_35, quic::QUIC_VERSION_44}; + quic::QUIC_VERSION_39, quic::QUIC_VERSION_44}; alternative_service_info_vector_3.push_back( AlternativeServiceInfo::CreateQuicAlternativeServiceInfo( quic_alternative_service1, expiration1, advertised_versions_2)); @@ -1654,7 +1654,7 @@ TEST_P(HttpServerPropertiesManagerTest, server_www, alternative_service_info_vector_3)); // No Prefs update. - EXPECT_FALSE(MainThreadHasPendingTask()); + EXPECT_EQ(0u, GetPendingMainThreadTaskCount()); EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); } @@ -1672,11 +1672,11 @@ TEST_P(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) { cached_recently_broken_service); EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); // Run the prefs update task but not the expiration task for // |cached_broken_service|. FastForwardBy(HttpServerPropertiesManager::GetUpdatePrefsDelayForTesting()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates()); // Load the |pref_delegate_| with some JSON to verify updating the cache from @@ -1684,9 +1684,9 @@ TEST_P(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) { // "cached_broken", the expiration time will be one day from now. std::string expiration_str = - base::Int64ToString(static_cast<int64_t>(one_day_from_now_.ToTimeT())); + base::NumberToString(static_cast<int64_t>(one_day_from_now_.ToTimeT())); - std::unique_ptr<base::Value> server_value = base::JSONReader::Read( + std::unique_ptr<base::Value> server_value = base::JSONReader::ReadDeprecated( "{" "\"broken_alternative_services\":[" "{\"broken_until\":\"" + @@ -1730,11 +1730,11 @@ TEST_P(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) { pref_delegate_->SetPrefs(*server_dict); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); // Run the cache update task but not the expiration task for // |cached_broken_service|. FastForwardBy(NextMainThreadPendingTaskDelay()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); // // Verify alternative service info for https://www.google.com @@ -1751,7 +1751,7 @@ TEST_P(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) { EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service().port); EXPECT_EQ( "13756212000000000", - base::Int64ToString( + base::NumberToString( alternative_service_info_vector[0].expiration().ToInternalValue())); EXPECT_EQ(kProtoHTTP2, @@ -1762,7 +1762,7 @@ TEST_P(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) { alternative_service_info_vector[1].alternative_service().port); EXPECT_EQ( "13758804000000000", - base::Int64ToString( + base::NumberToString( alternative_service_info_vector[1].expiration().ToInternalValue())); // @@ -1780,7 +1780,7 @@ TEST_P(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) { EXPECT_EQ(444, alternative_service_info_vector[0].alternative_service().port); EXPECT_EQ( "9223372036854775807", - base::Int64ToString( + base::NumberToString( alternative_service_info_vector[0].expiration().ToInternalValue())); // @@ -1848,7 +1848,7 @@ TEST_P(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) { http_server_props_manager_->MarkAlternativeServiceBroken( prefs_broken_service); EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates()); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardBy(base::TimeDelta::FromMinutes(10) - base::TimeDelta::FromInternalValue(1)); EXPECT_TRUE(http_server_props_manager_->IsAlternativeServiceBroken( @@ -1860,7 +1860,7 @@ TEST_P(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) { // when marked broken. http_server_props_manager_->MarkAlternativeServiceBroken( cached_recently_broken_service); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardBy(base::TimeDelta::FromMinutes(40) - base::TimeDelta::FromInternalValue(1)); EXPECT_TRUE(http_server_props_manager_->IsAlternativeServiceBroken( @@ -1872,7 +1872,7 @@ TEST_P(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) { // marked broken. http_server_props_manager_->MarkAlternativeServiceBroken( cached_broken_service); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardBy(base::TimeDelta::FromMinutes(20) - base::TimeDelta::FromInternalValue(1)); EXPECT_TRUE(http_server_props_manager_->IsAlternativeServiceBroken( @@ -1884,7 +1884,7 @@ TEST_P(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) { // marked broken. http_server_props_manager_->MarkAlternativeServiceBroken( cached_broken_service2); - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); FastForwardBy(base::TimeDelta::FromMinutes(10) - base::TimeDelta::FromInternalValue(1)); EXPECT_TRUE(http_server_props_manager_->IsAlternativeServiceBroken( diff --git a/chromium/net/http/http_stream_factory_job.cc b/chromium/net/http/http_stream_factory_job.cc index 8c4eb8ec46d..8de407ea25d 100644 --- a/chromium/net/http/http_stream_factory_job.cc +++ b/chromium/net/http/http_stream_factory_job.cc @@ -30,10 +30,10 @@ #include "net/http/http_basic_stream.h" #include "net/http/http_network_session.h" #include "net/http/http_proxy_client_socket.h" -#include "net/http/http_proxy_client_socket_pool.h" #include "net/http/http_request_info.h" #include "net/http/http_server_properties.h" #include "net/http/http_stream_factory.h" +#include "net/http/proxy_connect_redirect_http_stream.h" #include "net/http/proxy_fallback.h" #include "net/log/net_log.h" #include "net/log/net_log_capture_mode.h" @@ -43,11 +43,8 @@ #include "net/quic/bidirectional_stream_quic_impl.h" #include "net/quic/quic_http_stream.h" #include "net/socket/client_socket_handle.h" -#include "net/socket/client_socket_pool.h" #include "net/socket/client_socket_pool_manager.h" -#include "net/socket/socks_client_socket_pool.h" #include "net/socket/ssl_client_socket.h" -#include "net/socket/ssl_client_socket_pool.h" #include "net/socket/stream_socket.h" #include "net/spdy/bidirectional_stream_spdy_impl.h" #include "net/spdy/http2_push_promise_index.h" @@ -313,9 +310,9 @@ int HttpStreamFactory::Job::Preconnect(int num_streams) { int HttpStreamFactory::Job::RestartTunnelWithProxyAuth() { DCHECK(establishing_tunnel_); - next_state_ = STATE_RESTART_TUNNEL_AUTH; - stream_.reset(); - RunLoop(OK); + DCHECK(restart_with_auth_callback_); + + std::move(restart_with_auth_callback_).Run(); return ERR_IO_PENDING; } @@ -516,8 +513,13 @@ void HttpStreamFactory::Job::OnCertificateErrorCallback( void HttpStreamFactory::Job::OnNeedsProxyAuthCallback( const HttpResponseInfo& response, - HttpAuthController* auth_controller) { + HttpAuthController* auth_controller, + base::OnceClosure restart_with_auth_callback) { DCHECK_NE(job_type_, PRECONNECT); + DCHECK(establishing_tunnel_); + DCHECK(!restart_with_auth_callback_); + + restart_with_auth_callback_ = std::move(restart_with_auth_callback); delegate_->OnNeedsProxyAuth(this, response, server_ssl_config_, proxy_info_, auth_controller); @@ -586,8 +588,9 @@ void HttpStreamFactory::Job::RunLoop(int result) { if (job_type_ == PRECONNECT) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&HttpStreamFactory::Job::OnPreconnectsComplete, - ptr_factory_.GetWeakPtr())); + FROM_HERE, + base::BindOnce(&HttpStreamFactory::Job::OnPreconnectsComplete, + ptr_factory_.GetWeakPtr())); return; } @@ -599,40 +602,16 @@ void HttpStreamFactory::Job::RunLoop(int result) { next_state_ = STATE_WAITING_USER_ACTION; base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&HttpStreamFactory::Job::OnCertificateErrorCallback, - ptr_factory_.GetWeakPtr(), result, ssl_info)); + base::BindOnce(&HttpStreamFactory::Job::OnCertificateErrorCallback, + ptr_factory_.GetWeakPtr(), result, ssl_info)); return; } switch (result) { - case ERR_PROXY_AUTH_REQUESTED: { - UMA_HISTOGRAM_BOOLEAN("Net.ProxyAuthRequested.HasConnection", - connection_.get() != NULL); - if (!connection_.get()) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(&Job::OnStreamFailedCallback, ptr_factory_.GetWeakPtr(), - ERR_PROXY_AUTH_REQUESTED_WITH_NO_CONNECTION)); - return; - } - CHECK(connection_->socket()); - CHECK(establishing_tunnel_); - - next_state_ = STATE_WAITING_USER_ACTION; - ProxyClientSocket* proxy_socket = - static_cast<ProxyClientSocket*>(connection_->socket()); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(&Job::OnNeedsProxyAuthCallback, ptr_factory_.GetWeakPtr(), - *proxy_socket->GetConnectResponseInfo(), - base::RetainedRef(proxy_socket->GetAuthController()))); - return; - } - case ERR_SSL_CLIENT_AUTH_CERT_NEEDED: base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind( + base::BindOnce( &Job::OnNeedsClientAuthCallback, ptr_factory_.GetWeakPtr(), base::RetainedRef( connection_->ssl_error_response_info().cert_request_info))); @@ -640,18 +619,27 @@ void HttpStreamFactory::Job::RunLoop(int result) { case ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT: { DCHECK(connection_.get()); - DCHECK(connection_->socket()); DCHECK(establishing_tunnel_); + LoadTimingInfo load_timing_info; + bool have_load_timing_info = connection_->GetLoadTimingInfo( + connection_->is_reused(), &load_timing_info); + + std::unique_ptr<StreamSocket> socket = + connection_->release_pending_http_proxy_socket(); + DCHECK(socket); + + connection_.reset(); ProxyClientSocket* proxy_socket = - static_cast<ProxyClientSocket*>(connection_->socket()); + static_cast<ProxyClientSocket*>(socket.get()); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce( &Job::OnHttpsProxyTunnelResponseRedirectCallback, ptr_factory_.GetWeakPtr(), *proxy_socket->GetConnectResponseInfo(), - base::Passed(proxy_socket->CreateConnectResponseStream()))); + std::make_unique<ProxyConnectRedirectHttpStream>( + have_load_timing_info ? &load_timing_info : nullptr))); return; } @@ -659,36 +647,37 @@ void HttpStreamFactory::Job::RunLoop(int result) { next_state_ = STATE_DONE; if (new_spdy_session_.get()) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&Job::OnNewSpdySessionReadyCallback, - ptr_factory_.GetWeakPtr())); + FROM_HERE, base::BindOnce(&Job::OnNewSpdySessionReadyCallback, + ptr_factory_.GetWeakPtr())); } else if (is_websocket_) { DCHECK(websocket_stream_); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback, - ptr_factory_.GetWeakPtr())); + FROM_HERE, + base::BindOnce(&Job::OnWebSocketHandshakeStreamReadyCallback, + ptr_factory_.GetWeakPtr())); } else if (stream_type_ == HttpStreamRequest::BIDIRECTIONAL_STREAM) { if (!bidirectional_stream_impl_) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&Job::OnStreamFailedCallback, - ptr_factory_.GetWeakPtr(), ERR_FAILED)); + FROM_HERE, base::BindOnce(&Job::OnStreamFailedCallback, + ptr_factory_.GetWeakPtr(), ERR_FAILED)); } else { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&Job::OnBidirectionalStreamImplReadyCallback, - ptr_factory_.GetWeakPtr())); + base::BindOnce(&Job::OnBidirectionalStreamImplReadyCallback, + ptr_factory_.GetWeakPtr())); } } else { DCHECK(stream_.get()); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); + FROM_HERE, base::BindOnce(&Job::OnStreamReadyCallback, + ptr_factory_.GetWeakPtr())); } return; default: base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&Job::OnStreamFailedCallback, - ptr_factory_.GetWeakPtr(), result)); + FROM_HERE, base::BindOnce(&Job::OnStreamFailedCallback, + ptr_factory_.GetWeakPtr(), result)); return; } } @@ -725,13 +714,6 @@ int HttpStreamFactory::Job::DoLoop(int result) { case STATE_WAITING_USER_ACTION: rv = DoWaitingUserAction(rv); break; - case STATE_RESTART_TUNNEL_AUTH: - DCHECK_EQ(OK, rv); - rv = DoRestartTunnelAuth(); - break; - case STATE_RESTART_TUNNEL_AUTH_COMPLETE: - rv = DoRestartTunnelAuthComplete(rv); - break; case STATE_CREATE_STREAM: DCHECK_EQ(OK, rv); rv = DoCreateStream(); @@ -892,7 +874,7 @@ int HttpStreamFactory::Job::DoInitConnectionImpl() { GURL::Replacements replacements; replacements.SetSchemeStr(url::kHttpsScheme); replacements.SetHostStr(destination.host()); - const std::string new_port = base::UintToString(destination.port()); + const std::string new_port = base::NumberToString(destination.port()); replacements.SetPortStr(new_port); replacements.ClearUsername(); replacements.ClearPassword(); @@ -986,6 +968,10 @@ int HttpStreamFactory::Job::DoInitConnectionImpl() { spdy_session_key_, enable_ip_based_pooling_, try_websocket_over_http2_) : OnHostResolutionCallback(); + + ClientSocketPool::ProxyAuthCallback proxy_auth_callback = + base::BindRepeating(&HttpStreamFactory::Job::OnNeedsProxyAuthCallback, + base::Unretained(this)); if (is_websocket_) { DCHECK(request_info_.socket_tag == SocketTag()); SSLConfig websocket_server_ssl_config = server_ssl_config_; @@ -995,7 +981,7 @@ int HttpStreamFactory::Job::DoInitConnectionImpl() { request_info_.load_flags, priority_, session_, proxy_info_, websocket_server_ssl_config, proxy_ssl_config_, request_info_.privacy_mode, net_log_, connection_.get(), - resolution_callback, io_callback_); + resolution_callback, io_callback_, proxy_auth_callback); } return InitSocketHandleForHttpRequest( @@ -1003,7 +989,7 @@ int HttpStreamFactory::Job::DoInitConnectionImpl() { request_info_.load_flags, priority_, session_, proxy_info_, quic_version_, server_ssl_config_, proxy_ssl_config_, request_info_.privacy_mode, request_info_.socket_tag, net_log_, connection_.get(), - resolution_callback, io_callback_); + resolution_callback, io_callback_, proxy_auth_callback); } void HttpStreamFactory::Job::OnQuicHostResolution(int result) { @@ -1089,16 +1075,8 @@ int HttpStreamFactory::Job::DoInitConnectionComplete(int result) { } } - if (result == ERR_PROXY_AUTH_REQUESTED || - result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT) { + if (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 - // puts the in progress HttpProxy socket into |connection_| in order to - // complete the auth (or read the response body). The tunnel restart code - // is careful to remove it before returning control to the rest of this - // class. - connection_ = connection_->release_pending_http_proxy_connection(); return result; } @@ -1276,7 +1254,7 @@ int HttpStreamFactory::Job::DoCreateStream() { !spdy_session_direct_ && proxy_info_.proxy_server().is_trusted_proxy(); base::WeakPtr<SpdySession> spdy_session = - session_->spdy_session_pool()->CreateAvailableSessionFromSocket( + session_->spdy_session_pool()->CreateAvailableSessionFromSocketHandle( spdy_session_key_, is_trusted_proxy, std::move(connection_), net_log_); @@ -1314,35 +1292,6 @@ int HttpStreamFactory::Job::DoCreateStreamComplete(int result) { return OK; } -int HttpStreamFactory::Job::DoRestartTunnelAuth() { - next_state_ = STATE_RESTART_TUNNEL_AUTH_COMPLETE; - ProxyClientSocket* proxy_socket = - static_cast<ProxyClientSocket*>(connection_->socket()); - return proxy_socket->RestartWithAuth(io_callback_); -} - -int HttpStreamFactory::Job::DoRestartTunnelAuthComplete(int result) { - if (result == ERR_PROXY_AUTH_REQUESTED) - return result; - - if (result == OK || result == ERR_SPDY_SESSION_ALREADY_EXISTS) { - // Now that we've got the HttpProxyClientSocket connected. We have - // to release it as an idle socket into the pool and start the connection - // process from the beginning. Trying to pass it in with the - // SSLSocketParams might cause a deadlock since params are dispatched - // interchangeably. This request won't necessarily get this http proxy - // socket, but there will be forward progress. - // - // Alernatively, if there's an existing H2 session that can be reused, - // also go back to the init connection state to reuse it. - establishing_tunnel_ = false; - ReturnToStateInitConnection(false /* do not close connection */); - return OK; - } - - return ReconsiderProxyAfterError(result); -} - void HttpStreamFactory::Job::ReturnToStateInitConnection( bool close_connection) { if (close_connection && connection_->socket()) diff --git a/chromium/net/http/http_stream_factory_job.h b/chromium/net/http/http_stream_factory_job.h index 7dc0399a4aa..2d48d484187 100644 --- a/chromium/net/http/http_stream_factory_job.h +++ b/chromium/net/http/http_stream_factory_job.h @@ -26,6 +26,7 @@ #include "net/proxy_resolution/proxy_resolution_service.h" #include "net/quic/quic_stream_factory.h" #include "net/socket/client_socket_handle.h" +#include "net/socket/client_socket_pool.h" #include "net/socket/client_socket_pool_manager.h" #include "net/socket/next_proto.h" #include "net/socket/ssl_client_socket.h" @@ -280,8 +281,6 @@ class HttpStreamFactory::Job { STATE_INIT_CONNECTION, STATE_INIT_CONNECTION_COMPLETE, STATE_WAITING_USER_ACTION, - STATE_RESTART_TUNNEL_AUTH, - STATE_RESTART_TUNNEL_AUTH_COMPLETE, STATE_CREATE_STREAM, STATE_CREATE_STREAM_COMPLETE, STATE_DRAIN_BODY_FOR_AUTH_RESTART, @@ -300,7 +299,8 @@ class HttpStreamFactory::Job { void OnStreamFailedCallback(int result); void OnCertificateErrorCallback(int result, const SSLInfo& ssl_info); void OnNeedsProxyAuthCallback(const HttpResponseInfo& response_info, - HttpAuthController* auth_controller); + HttpAuthController* auth_controller, + base::OnceClosure restart_with_auth_callback); void OnNeedsClientAuthCallback(SSLCertRequestInfo* cert_info); void OnHttpsProxyTunnelResponseRedirectCallback( const HttpResponseInfo& response_info, @@ -336,8 +336,6 @@ class HttpStreamFactory::Job { int DoWaitingUserAction(int result); int DoCreateStream(); int DoCreateStreamComplete(int result); - int DoRestartTunnelAuth(); - int DoRestartTunnelAuthComplete(int result); void ResumeInitConnection(); // Creates a SpdyHttpStream or a BidirectionalStreamImpl from the given values @@ -519,6 +517,8 @@ class HttpStreamFactory::Job { // Whether Job has continued to DoInitConnection(). bool init_connection_already_resumed_; + base::OnceClosure restart_with_auth_callback_; + NetErrorDetails net_error_details_; base::WeakPtrFactory<Job> ptr_factory_; diff --git a/chromium/net/http/http_stream_factory_job_controller.cc b/chromium/net/http/http_stream_factory_job_controller.cc index c76c66df273..7c53ba12c9f 100644 --- a/chromium/net/http/http_stream_factory_job_controller.cc +++ b/chromium/net/http/http_stream_factory_job_controller.cc @@ -7,6 +7,7 @@ #include <string> #include <utility> +#include "base/bind.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" @@ -735,8 +736,8 @@ void HttpStreamFactory::JobController::RunLoop(int result) { DCHECK(!alternative_job_); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&HttpStreamFactory::JobController::NotifyRequestFailed, - ptr_factory_.GetWeakPtr(), rv)); + base::BindOnce(&HttpStreamFactory::JobController::NotifyRequestFailed, + ptr_factory_.GetWeakPtr(), rv)); } } @@ -1088,7 +1089,7 @@ GURL HttpStreamFactory::JobController::ApplyHostMappingRules( HostPortPair* endpoint) { if (session_->params().host_mapping_rules.RewriteHost(endpoint)) { url::Replacements<char> replacements; - const std::string port_str = base::UintToString(endpoint->port()); + const std::string port_str = base::NumberToString(endpoint->port()); replacements.SetPort(port_str.c_str(), url::Component(0, port_str.size())); replacements.SetHost(endpoint->host().c_str(), url::Component(0, endpoint->host().size())); diff --git a/chromium/net/http/http_stream_factory_job_controller_unittest.cc b/chromium/net/http/http_stream_factory_job_controller_unittest.cc index 26cb63ba12c..7741fa00951 100644 --- a/chromium/net/http/http_stream_factory_job_controller_unittest.cc +++ b/chromium/net/http/http_stream_factory_job_controller_unittest.cc @@ -95,38 +95,6 @@ class FailingProxyResolverFactory : public ProxyResolverFactory { } }; -class FailingHostResolver : public MockHostResolverBase { - public: - FailingHostResolver() : MockHostResolverBase(false /*use_caching*/) {} - ~FailingHostResolver() override = default; - - int Resolve(const RequestInfo& info, - RequestPriority priority, - AddressList* addresses, - CompletionOnceCallback callback, - std::unique_ptr<Request>* out_req, - const NetLogWithSource& net_log) override { - return ERR_NAME_NOT_RESOLVED; - } -}; - -// TODO(xunjieli): This should just use HangingHostResolver from -// mock_host_resolver.h -class HangingResolver : public MockHostResolverBase { - public: - HangingResolver() : MockHostResolverBase(false /*use_caching*/) {} - ~HangingResolver() override = default; - - int Resolve(const RequestInfo& info, - RequestPriority priority, - AddressList* addresses, - CompletionOnceCallback callback, - std::unique_ptr<Request>* out_req, - const NetLogWithSource& net_log) override { - return ERR_IO_PENDING; - } -}; - // A mock HttpServerProperties that always returns false for IsInitialized(). class MockHttpServerProperties : public HttpServerPropertiesImpl { public: @@ -499,7 +467,7 @@ class JobControllerReconsiderProxyAfterErrorTest HttpStreamFactory::JobFactory default_job_factory_; }; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( /* no prefix */, JobControllerReconsiderProxyAfterErrorTest, ::testing::Combine(::testing::Bool(), @@ -1740,7 +1708,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, HostResolutionHang) { session_deps_.host_resolver->ResolveAllPending(); // Task to resume main job in 15 microseconds should be posted. - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); FastForwardBy(base::TimeDelta::FromMicroseconds(14)); EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); @@ -1806,7 +1774,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, DelayedTCP) { EXPECT_FALSE(JobControllerPeer::main_job_is_resumed(job_controller_)); // Task to resume main job in 15us should be posted. - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); FastForwardBy(base::TimeDelta::FromMicroseconds(14)); EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); @@ -1832,7 +1800,8 @@ TEST_F(HttpStreamFactoryJobControllerTest, ResumeMainJobLaterCanceled) { session_deps_.proxy_resolution_service = std::move(proxy_resolution_service); // Using hanging resolver will cause the alternative job to hang indefinitely. - session_deps_.host_resolver = std::make_unique<HangingResolver>(); + session_deps_.alternate_host_resolver = + std::make_unique<HangingHostResolver>(); HttpRequestInfo request_info; request_info.method = "GET"; @@ -1944,7 +1913,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, DelayedTCPWithLargeSrtt) { EXPECT_FALSE(JobControllerPeer::main_job_is_resumed(job_controller_)); // Task to resume main job in 3 seconds should be posted. - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); FastForwardBy(kMaxDelayTimeForMainJob - base::TimeDelta::FromMicroseconds(1)); EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); @@ -2004,7 +1973,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, EXPECT_FALSE(JobControllerPeer::main_job_is_resumed(job_controller_)); // Task to resume main job in 15us should be posted. - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); FastForwardBy(base::TimeDelta::FromMicroseconds(1)); @@ -2021,7 +1990,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, // Verify there is another task to resume main job with delay but should // not call Resume() on the main job as main job has been resumed. - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); FastForwardBy(base::TimeDelta::FromMicroseconds(15)); @@ -2032,7 +2001,8 @@ TEST_F(HttpStreamFactoryJobControllerTest, // scheme is HTTPS. TEST_F(HttpStreamFactoryJobControllerTest, HttpsURL) { // Using hanging resolver will cause the alternative job to hang indefinitely. - session_deps_.host_resolver = std::make_unique<HangingResolver>(); + session_deps_.alternate_host_resolver = + std::make_unique<HangingHostResolver>(); HttpRequestInfo request_info; request_info.method = "GET"; @@ -2055,7 +2025,8 @@ TEST_F(HttpStreamFactoryJobControllerTest, HttpsURL) { // does not fetch the resource through a proxy. TEST_F(HttpStreamFactoryJobControllerTest, HttpURLWithNoProxy) { // Using hanging resolver will cause the alternative job to hang indefinitely. - session_deps_.host_resolver = std::make_unique<HangingResolver>(); + session_deps_.alternate_host_resolver = + std::make_unique<HangingHostResolver>(); HttpRequestInfo request_info; request_info.method = "GET"; @@ -2123,7 +2094,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, DelayedTCPAlternativeProxy) { EXPECT_FALSE(JobControllerPeer::main_job_is_resumed(job_controller_)); // Task to resume main job in 15us should be posted. - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_NE(0u, GetPendingMainThreadTaskCount()); EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); FastForwardBy(base::TimeDelta::FromMicroseconds(14)); EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); @@ -2481,7 +2452,7 @@ TEST_F(JobControllerLimitMultipleH2Requests, MultipleRequestsFirstRequestHang) { EXPECT_CALL(*request_delegates[i].get(), OnStreamReadyImpl(_, _, _)); } - EXPECT_TRUE(MainThreadHasPendingTask()); + EXPECT_GT(GetPendingMainThreadTaskCount(), 0u); FastForwardBy(base::TimeDelta::FromMilliseconds( HttpStreamFactory::Job::kHTTP2ThrottleMs)); base::RunLoop().RunUntilIdle(); @@ -2723,7 +2694,7 @@ class HttpStreamFactoryJobControllerMisdirectedRequestRetry : public HttpStreamFactoryJobControllerTest, public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {}; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( /* no prefix */, HttpStreamFactoryJobControllerMisdirectedRequestRetry, ::testing::Combine(::testing::Bool(), ::testing::Bool())); @@ -2814,7 +2785,7 @@ class HttpStreamFactoryJobControllerPreconnectTest HttpRequestInfo request_info_; }; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( /* no prefix */, HttpStreamFactoryJobControllerPreconnectTest, ::testing::Bool()); diff --git a/chromium/net/http/http_stream_factory_unittest.cc b/chromium/net/http/http_stream_factory_unittest.cc index 6a37330b031..716137431c8 100644 --- a/chromium/net/http/http_stream_factory_unittest.cc +++ b/chromium/net/http/http_stream_factory_unittest.cc @@ -34,6 +34,7 @@ #include "net/http/http_network_session.h" #include "net/http/http_network_session_peer.h" #include "net/http/http_network_transaction.h" +#include "net/http/http_proxy_connect_job.h" #include "net/http/http_request_info.h" #include "net/http/http_server_properties.h" #include "net/http/http_server_properties_impl.h" @@ -51,6 +52,8 @@ #include "net/socket/next_proto.h" #include "net/socket/socket_tag.h" #include "net/socket/socket_test_util.h" +#include "net/socket/socks_connect_job.h" +#include "net/socket/ssl_connect_job.h" #include "net/socket/transport_connect_job.h" #include "net/spdy/spdy_session.h" #include "net/spdy/spdy_session_pool.h" @@ -382,6 +385,12 @@ void PreconnectHelper(const TestCase& test, HttpNetworkSession* session) { PreconnectHelperForURL(test.num_streams, url, session); } +std::string GetGroupName(const TestCase& test) { + if (test.ssl) + return "ssl/www.google.com:443"; + return "www.google.com:80"; +} + template <typename ParentPool> class CapturePreconnectsSocketPool : public ParentPool { public: @@ -392,18 +401,24 @@ class CapturePreconnectsSocketPool : public ParentPool { CTPolicyEnforcer* ct_policy_enforcer); int last_num_streams() const { return last_num_streams_; } + const std::string& last_group_name() const { return last_group_name_; } + + // Resets |last_num_streams_| and |last_group_name_| default values. + void reset() { + last_num_streams_ = -1; + last_group_name_.clear(); + } - // Resets |last_num_streams_| to its default value. - void reset_last_num_streams() { last_num_streams_ = -1; } - - int RequestSocket(const std::string& group_name, - const void* socket_params, - RequestPriority priority, - const SocketTag& socket_tag, - ClientSocketPool::RespectLimits respect_limits, - ClientSocketHandle* handle, - CompletionOnceCallback callback, - const NetLogWithSource& net_log) override { + int RequestSocket( + const std::string& group_name, + const void* socket_params, + RequestPriority priority, + const SocketTag& socket_tag, + ClientSocketPool::RespectLimits respect_limits, + ClientSocketHandle* handle, + CompletionOnceCallback callback, + const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback, + const NetLogWithSource& net_log) override { ADD_FAILURE(); return ERR_UNEXPECTED; } @@ -413,6 +428,7 @@ class CapturePreconnectsSocketPool : public ParentPool { int num_sockets, const NetLogWithSource& net_log) override { last_num_streams_ = num_sockets; + last_group_name_ = group_name; } void CancelRequest(const std::string& group_name, @@ -429,7 +445,7 @@ class CapturePreconnectsSocketPool : public ParentPool { ADD_FAILURE(); return 0; } - int IdleSocketCountInGroup(const std::string& group_name) const override { + size_t IdleSocketCountInGroup(const std::string& group_name) const override { ADD_FAILURE(); return 0; } @@ -441,16 +457,11 @@ class CapturePreconnectsSocketPool : public ParentPool { private: int last_num_streams_; + std::string last_group_name_; }; typedef CapturePreconnectsSocketPool<TransportClientSocketPool> CapturePreconnectsTransportSocketPool; -typedef CapturePreconnectsSocketPool<HttpProxyClientSocketPool> - CapturePreconnectsHttpProxySocketPool; -typedef CapturePreconnectsSocketPool<SOCKSClientSocketPool> - CapturePreconnectsSOCKSSocketPool; -typedef CapturePreconnectsSocketPool<SSLClientSocketPool> - CapturePreconnectsSSLSocketPool; template <typename ParentPool> CapturePreconnectsSocketPool<ParentPool>::CapturePreconnectsSocketPool( @@ -459,47 +470,23 @@ CapturePreconnectsSocketPool<ParentPool>::CapturePreconnectsSocketPool( TransportSecurityState*, CTVerifier*, CTPolicyEnforcer*) - : ParentPool(0, 0, host_resolver, nullptr, nullptr, nullptr), - last_num_streams_(-1) {} - -template <> -CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool( - HostResolver*, - CertVerifier*, - TransportSecurityState*, - CTVerifier*, - CTPolicyEnforcer*) - : HttpProxyClientSocketPool(0, - 0, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr), - last_num_streams_(-1) {} - -template <> -CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool( - HostResolver* /* host_resolver */, - CertVerifier* cert_verifier, - TransportSecurityState* transport_security_state, - CTVerifier* cert_transparency_verifier, - CTPolicyEnforcer* ct_policy_enforcer) - : SSLClientSocketPool(0, - 0, - cert_verifier, - nullptr, // channel_id_store - transport_security_state, - cert_transparency_verifier, - ct_policy_enforcer, - std::string(), // ssl_session_cache_shard - nullptr, // deterministic_socket_factory - nullptr, // transport_socket_pool - nullptr, // socks_pool - nullptr, // http_proxy_pool - nullptr, // ssl_config_service - nullptr, // network_quality_estimator - nullptr), // net_log + : ParentPool(0, + 0, + base::TimeDelta(), + nullptr /* socket_factory */, + host_resolver, + nullptr /* proxy_delegate */, + nullptr /* cert_verifier */, + nullptr /* channel_id_server */, + nullptr /* transport_security_state */, + nullptr /* cert_transparency_verifier */, + nullptr /* ct_policy_enforcer */, + nullptr /* ssl_client_session_cache */, + nullptr /* ssl_client_session_cache_privacy_mode */, + nullptr /* ssl_config_service */, + nullptr /* socket_performance_watcher_factory */, + nullptr /* network_quality_estimator */, + nullptr /* netlog */), last_num_streams_(-1) {} using HttpStreamFactoryTest = TestWithScopedTaskEnvironment; @@ -511,27 +498,23 @@ TEST_F(HttpStreamFactoryTest, PreconnectDirect) { std::unique_ptr<HttpNetworkSession> session( SpdySessionDependencies::SpdyCreateSession(&session_deps)); HttpNetworkSessionPeer peer(session.get()); + std::unique_ptr<CapturePreconnectsTransportSocketPool> + owned_transport_conn_pool = + std::make_unique<CapturePreconnectsTransportSocketPool>( + session_deps.host_resolver.get(), + session_deps.cert_verifier.get(), + session_deps.transport_security_state.get(), + session_deps.cert_transparency_verifier.get(), + session_deps.ct_policy_enforcer.get()); CapturePreconnectsTransportSocketPool* transport_conn_pool = - new CapturePreconnectsTransportSocketPool( - session_deps.host_resolver.get(), session_deps.cert_verifier.get(), - session_deps.transport_security_state.get(), - session_deps.cert_transparency_verifier.get(), - session_deps.ct_policy_enforcer.get()); - CapturePreconnectsSSLSocketPool* ssl_conn_pool = - new CapturePreconnectsSSLSocketPool( - session_deps.host_resolver.get(), session_deps.cert_verifier.get(), - session_deps.transport_security_state.get(), - session_deps.cert_transparency_verifier.get(), - session_deps.ct_policy_enforcer.get()); + owned_transport_conn_pool.get(); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetTransportSocketPool(transport_conn_pool); - mock_pool_manager->SetSSLSocketPool(ssl_conn_pool); + mock_pool_manager->SetSocketPool(ProxyServer::Direct(), + std::move(owned_transport_conn_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); PreconnectHelper(kTests[i], session.get()); - if (kTests[i].ssl) - EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); - else - EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams()); + EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams()); + EXPECT_EQ(GetGroupName(kTests[i]), transport_conn_pool->last_group_name()); } } @@ -544,29 +527,20 @@ TEST_F(HttpStreamFactoryTest, PreconnectHttpProxy) { HttpNetworkSessionPeer peer(session.get()); ProxyServer proxy_server(ProxyServer::SCHEME_HTTP, HostPortPair("http_proxy", 80)); - CapturePreconnectsHttpProxySocketPool* http_proxy_pool = - new CapturePreconnectsHttpProxySocketPool( - session_deps.host_resolver.get(), session_deps.cert_verifier.get(), - session_deps.transport_security_state.get(), - session_deps.cert_transparency_verifier.get(), - session_deps.ct_policy_enforcer.get()); - CapturePreconnectsSSLSocketPool* ssl_conn_pool = - new CapturePreconnectsSSLSocketPool( + CapturePreconnectsTransportSocketPool* http_proxy_pool = + new CapturePreconnectsTransportSocketPool( session_deps.host_resolver.get(), session_deps.cert_verifier.get(), session_deps.transport_security_state.get(), session_deps.cert_transparency_verifier.get(), session_deps.ct_policy_enforcer.get()); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetSocketPoolForHTTPProxy( - proxy_server, base::WrapUnique(http_proxy_pool)); - mock_pool_manager->SetSocketPoolForSSLWithProxy( - proxy_server, base::WrapUnique(ssl_conn_pool)); + mock_pool_manager->SetSocketPool(proxy_server, + base::WrapUnique(http_proxy_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); PreconnectHelper(kTests[i], session.get()); - if (kTests[i].ssl) - EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); - else - EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams()); + EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams()); + EXPECT_EQ("http_proxy/" + GetGroupName(kTests[i]), + http_proxy_pool->last_group_name()); } } @@ -579,29 +553,20 @@ TEST_F(HttpStreamFactoryTest, PreconnectSocksProxy) { HttpNetworkSessionPeer peer(session.get()); ProxyServer proxy_server(ProxyServer::SCHEME_SOCKS4, HostPortPair("socks_proxy", 1080)); - CapturePreconnectsSOCKSSocketPool* socks_proxy_pool = - new CapturePreconnectsSOCKSSocketPool( - session_deps.host_resolver.get(), session_deps.cert_verifier.get(), - session_deps.transport_security_state.get(), - session_deps.cert_transparency_verifier.get(), - session_deps.ct_policy_enforcer.get()); - CapturePreconnectsSSLSocketPool* ssl_conn_pool = - new CapturePreconnectsSSLSocketPool( + CapturePreconnectsTransportSocketPool* socks_proxy_pool = + new CapturePreconnectsTransportSocketPool( session_deps.host_resolver.get(), session_deps.cert_verifier.get(), session_deps.transport_security_state.get(), session_deps.cert_transparency_verifier.get(), session_deps.ct_policy_enforcer.get()); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetSocketPoolForSOCKSProxy( - proxy_server, base::WrapUnique(socks_proxy_pool)); - mock_pool_manager->SetSocketPoolForSSLWithProxy( - proxy_server, base::WrapUnique(ssl_conn_pool)); + mock_pool_manager->SetSocketPool(proxy_server, + base::WrapUnique(socks_proxy_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); PreconnectHelper(kTests[i], session.get()); - if (kTests[i].ssl) - EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); - else - EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams()); + EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams()); + EXPECT_EQ("socks4/" + GetGroupName(kTests[i]), + socks_proxy_pool->last_group_name()); } } @@ -620,27 +585,25 @@ TEST_F(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) { SpdySessionKey::IsProxySession::kFalse, SocketTag()); ignore_result(CreateFakeSpdySession(session->spdy_session_pool(), key)); + std::unique_ptr<CapturePreconnectsTransportSocketPool> + owned_transport_conn_pool = + std::make_unique<CapturePreconnectsTransportSocketPool>( + session_deps.host_resolver.get(), + session_deps.cert_verifier.get(), + session_deps.transport_security_state.get(), + session_deps.cert_transparency_verifier.get(), + session_deps.ct_policy_enforcer.get()); CapturePreconnectsTransportSocketPool* transport_conn_pool = - new CapturePreconnectsTransportSocketPool( - session_deps.host_resolver.get(), session_deps.cert_verifier.get(), - session_deps.transport_security_state.get(), - session_deps.cert_transparency_verifier.get(), - session_deps.ct_policy_enforcer.get()); - CapturePreconnectsSSLSocketPool* ssl_conn_pool = - new CapturePreconnectsSSLSocketPool( - session_deps.host_resolver.get(), session_deps.cert_verifier.get(), - session_deps.transport_security_state.get(), - session_deps.cert_transparency_verifier.get(), - session_deps.ct_policy_enforcer.get()); + owned_transport_conn_pool.get(); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetTransportSocketPool(transport_conn_pool); - mock_pool_manager->SetSSLSocketPool(ssl_conn_pool); + mock_pool_manager->SetSocketPool(ProxyServer::Direct(), + std::move(owned_transport_conn_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); PreconnectHelper(kTests[i], session.get()); // We shouldn't be preconnecting if we have an existing session, which is // the case for https://www.google.com. if (kTests[i].ssl) - EXPECT_EQ(-1, ssl_conn_pool->last_num_streams()); + EXPECT_EQ(-1, transport_conn_pool->last_num_streams()); else EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams()); } @@ -655,14 +618,19 @@ TEST_F(HttpStreamFactoryTest, PreconnectUnsafePort) { std::unique_ptr<HttpNetworkSession> session( SpdySessionDependencies::SpdyCreateSession(&session_deps)); HttpNetworkSessionPeer peer(session.get()); + std::unique_ptr<CapturePreconnectsTransportSocketPool> + owned_transport_conn_pool = + std::make_unique<CapturePreconnectsTransportSocketPool>( + session_deps.host_resolver.get(), + session_deps.cert_verifier.get(), + session_deps.transport_security_state.get(), + session_deps.cert_transparency_verifier.get(), + session_deps.ct_policy_enforcer.get()); CapturePreconnectsTransportSocketPool* transport_conn_pool = - new CapturePreconnectsTransportSocketPool( - session_deps.host_resolver.get(), session_deps.cert_verifier.get(), - session_deps.transport_security_state.get(), - session_deps.cert_transparency_verifier.get(), - session_deps.ct_policy_enforcer.get()); + owned_transport_conn_pool.get(); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetTransportSocketPool(transport_conn_pool); + mock_pool_manager->SetSocketPool(ProxyServer::Direct(), + std::move(owned_transport_conn_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get()); @@ -1208,26 +1176,18 @@ TEST_F(HttpStreamFactoryTest, UsePreConnectIfNoZeroRTT) { HttpNetworkSessionPeer peer(session.get()); ProxyServer proxy_server(ProxyServer::SCHEME_HTTP, HostPortPair("http_proxy", 80)); - CapturePreconnectsHttpProxySocketPool* http_proxy_pool = - new CapturePreconnectsHttpProxySocketPool( - session_deps.host_resolver.get(), session_deps.cert_verifier.get(), - session_deps.transport_security_state.get(), - session_deps.cert_transparency_verifier.get(), - session_deps.ct_policy_enforcer.get()); - CapturePreconnectsSSLSocketPool* ssl_conn_pool = - new CapturePreconnectsSSLSocketPool( + CapturePreconnectsTransportSocketPool* http_proxy_pool = + new CapturePreconnectsTransportSocketPool( session_deps.host_resolver.get(), session_deps.cert_verifier.get(), session_deps.transport_security_state.get(), session_deps.cert_transparency_verifier.get(), session_deps.ct_policy_enforcer.get()); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetSocketPoolForHTTPProxy( - proxy_server, base::WrapUnique(http_proxy_pool)); - mock_pool_manager->SetSocketPoolForSSLWithProxy( - proxy_server, base::WrapUnique(ssl_conn_pool)); + mock_pool_manager->SetSocketPool(proxy_server, + base::WrapUnique(http_proxy_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); PreconnectHelperForURL(num_streams, url, session.get()); - EXPECT_EQ(num_streams, ssl_conn_pool->last_num_streams()); + EXPECT_EQ(num_streams, http_proxy_pool->last_num_streams()); } } @@ -1268,15 +1228,8 @@ TEST_F(HttpStreamFactoryTest, OnlyOnePreconnectToProxyServer) { for (int preconnect_request = 0; preconnect_request < 2; ++preconnect_request) { - CapturePreconnectsHttpProxySocketPool* http_proxy_pool = - new CapturePreconnectsHttpProxySocketPool( - session_deps.host_resolver.get(), - session_deps.cert_verifier.get(), - session_deps.transport_security_state.get(), - session_deps.cert_transparency_verifier.get(), - session_deps.ct_policy_enforcer.get()); - CapturePreconnectsSSLSocketPool* ssl_conn_pool = - new CapturePreconnectsSSLSocketPool( + CapturePreconnectsTransportSocketPool* http_proxy_pool = + new CapturePreconnectsTransportSocketPool( session_deps.host_resolver.get(), session_deps.cert_verifier.get(), session_deps.transport_security_state.get(), @@ -1285,10 +1238,8 @@ TEST_F(HttpStreamFactoryTest, OnlyOnePreconnectToProxyServer) { auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetSocketPoolForHTTPProxy( - proxy_server, base::WrapUnique(http_proxy_pool)); - mock_pool_manager->SetSocketPoolForSSLWithProxy( - proxy_server, base::WrapUnique(ssl_conn_pool)); + mock_pool_manager->SetSocketPool(proxy_server, + base::WrapUnique(http_proxy_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); HttpRequestInfo request; @@ -1302,13 +1253,11 @@ TEST_F(HttpStreamFactoryTest, OnlyOnePreconnectToProxyServer) { // First preconnect job should succeed. session->http_stream_factory()->PreconnectStreams(num_streams, request); - EXPECT_EQ(-1, ssl_conn_pool->last_num_streams()); EXPECT_EQ(num_streams, http_proxy_pool->last_num_streams()); } else { // Second preconnect job should not succeed. session->http_stream_factory()->PreconnectStreams(num_streams, request); - EXPECT_EQ(-1, ssl_conn_pool->last_num_streams()); if (set_http_server_properties) { EXPECT_EQ(-1, http_proxy_pool->last_num_streams()); } else { @@ -1362,24 +1311,16 @@ TEST_F(HttpStreamFactoryTest, ProxyServerPreconnectDifferentPrivacyModes) { ProxyServer proxy_server(ProxyServer::SCHEME_HTTPS, HostPortPair("myproxy.org", 443)); - CapturePreconnectsHttpProxySocketPool* http_proxy_pool = - new CapturePreconnectsHttpProxySocketPool( - session_deps.host_resolver.get(), session_deps.cert_verifier.get(), - session_deps.transport_security_state.get(), - session_deps.cert_transparency_verifier.get(), - session_deps.ct_policy_enforcer.get()); - CapturePreconnectsSSLSocketPool* ssl_conn_pool = - new CapturePreconnectsSSLSocketPool( + CapturePreconnectsTransportSocketPool* http_proxy_pool = + new CapturePreconnectsTransportSocketPool( session_deps.host_resolver.get(), session_deps.cert_verifier.get(), session_deps.transport_security_state.get(), session_deps.cert_transparency_verifier.get(), session_deps.ct_policy_enforcer.get()); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetSocketPoolForHTTPProxy( - proxy_server, base::WrapUnique(http_proxy_pool)); - mock_pool_manager->SetSocketPoolForSSLWithProxy( - proxy_server, base::WrapUnique(ssl_conn_pool)); + mock_pool_manager->SetSocketPool(proxy_server, + base::WrapUnique(http_proxy_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); HttpRequestInfo request_privacy_mode_disabled; @@ -1392,14 +1333,12 @@ TEST_F(HttpStreamFactoryTest, ProxyServerPreconnectDifferentPrivacyModes) { // First preconnect job should succeed. session->http_stream_factory()->PreconnectStreams( num_streams, request_privacy_mode_disabled); - EXPECT_EQ(-1, ssl_conn_pool->last_num_streams()); EXPECT_EQ(num_streams, http_proxy_pool->last_num_streams()); - http_proxy_pool->reset_last_num_streams(); + http_proxy_pool->reset(); // Second preconnect job with same privacy mode should not succeed. session->http_stream_factory()->PreconnectStreams( num_streams + 1, request_privacy_mode_disabled); - EXPECT_EQ(-1, ssl_conn_pool->last_num_streams()); EXPECT_EQ(-1, http_proxy_pool->last_num_streams()); // Next request with a different privacy mode should succeed. @@ -1414,7 +1353,6 @@ TEST_F(HttpStreamFactoryTest, ProxyServerPreconnectDifferentPrivacyModes) { // Request with a different privacy mode should succeed. session->http_stream_factory()->PreconnectStreams( num_streams, request_privacy_mode_enabled); - EXPECT_EQ(-1, ssl_conn_pool->last_num_streams()); EXPECT_EQ(num_streams, http_proxy_pool->last_num_streams()); } @@ -1468,8 +1406,7 @@ namespace { // Return count of distinct groups in given socket pool. int GetSocketPoolGroupCount(ClientSocketPool* pool) { int count = 0; - std::unique_ptr<base::DictionaryValue> dict( - pool->GetInfoAsValue("", "", false)); + std::unique_ptr<base::DictionaryValue> dict(pool->GetInfoAsValue("", "")); EXPECT_TRUE(dict != nullptr); base::DictionaryValue* groups = nullptr; if (dict->GetDictionary("groups", &groups) && (groups != nullptr)) { @@ -1491,8 +1428,7 @@ int GetSpdySessionCount(HttpNetworkSession* session) { // Return count of sockets handed out by a given socket pool. int GetHandedOutSocketCount(ClientSocketPool* pool) { int count = 0; - std::unique_ptr<base::DictionaryValue> dict( - pool->GetInfoAsValue("", "", false)); + std::unique_ptr<base::DictionaryValue> dict(pool->GetInfoAsValue("", "")); EXPECT_TRUE(dict != nullptr); if (!dict->GetInteger("handed_out_socket_count", &count)) return -1; @@ -1535,8 +1471,8 @@ TEST_F(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) { std::unique_ptr<HttpNetworkSession> session( SpdySessionDependencies::SpdyCreateSession(&session_deps)); - SSLClientSocketPool* ssl_pool = - session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL); + TransportClientSocketPool* ssl_pool = session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()); EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0); @@ -1641,14 +1577,9 @@ TEST_F(HttpStreamFactoryTest, RequestHttpStream) { EXPECT_TRUE(nullptr == waiter.websocket_stream()); EXPECT_EQ(0, GetSpdySessionCount(session.get())); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ( + 1, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); EXPECT_TRUE(waiter.used_proxy_info().is_direct()); } @@ -1741,14 +1672,9 @@ TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverSSL) { EXPECT_TRUE(nullptr == waiter.websocket_stream()); EXPECT_EQ(0, GetSpdySessionCount(session.get())); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ( + 1, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); EXPECT_TRUE(waiter.used_proxy_info().is_direct()); } @@ -1785,31 +1711,18 @@ TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverProxy) { EXPECT_TRUE(nullptr == waiter.websocket_stream()); EXPECT_EQ(0, GetSpdySessionCount(session.get())); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPLikeProxy( - HttpNetworkSession::NORMAL_SOCKET_POOL, - ProxyServer(ProxyServer::SCHEME_HTTP, - HostPortPair("myproxy", 8888))))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPLikeProxy( - HttpNetworkSession::NORMAL_SOCKET_POOL, - ProxyServer(ProxyServer::SCHEME_HTTPS, - HostPortPair("myproxy", 8888))))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( + EXPECT_EQ( + 0, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); + EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 8888))))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( + EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("myproxy", 8888))))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPLikeProxy( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL, - ProxyServer(ProxyServer::SCHEME_HTTP, - HostPortPair("myproxy", 8888))))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( + EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPool( HttpNetworkSession::WEBSOCKET_SOCKET_POOL, ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 8888))))); @@ -1855,7 +1768,7 @@ TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverProxyWithPreconnects) { ++preconnect_request) { session->http_stream_factory()->PreconnectStreams(1, request_info); base::RunLoop().RunUntilIdle(); - while (GetSocketPoolGroupCount(session->GetSocketPoolForHTTPLikeProxy( + while (GetSocketPoolGroupCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("myproxy.org", 443)))) == 0) { @@ -1880,7 +1793,7 @@ TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverProxyWithPreconnects) { ASSERT_TRUE(nullptr != waiter.stream()); EXPECT_TRUE(nullptr == waiter.websocket_stream()); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPLikeProxy( + EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("myproxy.org", 443))))); @@ -1890,7 +1803,7 @@ TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverProxyWithPreconnects) { ++preconnect_request) { session->http_stream_factory()->PreconnectStreams(1, request_info); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPLikeProxy( + EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("myproxy.org", 443))))); @@ -1935,12 +1848,9 @@ TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) { ASSERT_TRUE(nullptr != waiter.websocket_stream()); EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic, waiter.websocket_stream()->type()); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ( + 0, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); EXPECT_TRUE(waiter.used_proxy_info().is_direct()); } @@ -1982,12 +1892,9 @@ TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) { ASSERT_TRUE(nullptr != waiter.websocket_stream()); EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic, waiter.websocket_stream()->type()); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ( + 0, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); EXPECT_TRUE(waiter.used_proxy_info().is_direct()); } @@ -2027,23 +1934,14 @@ TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) { ASSERT_TRUE(nullptr != waiter.websocket_stream()); EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic, waiter.websocket_stream()->type()); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPLikeProxy( - HttpNetworkSession::NORMAL_SOCKET_POOL, - ProxyServer(ProxyServer::SCHEME_HTTP, - HostPortPair("myproxy", 8888))))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( - HttpNetworkSession::NORMAL_SOCKET_POOL, - ProxyServer(ProxyServer::SCHEME_HTTP, - HostPortPair("myproxy", 8888))))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPLikeProxy( + EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPool( HttpNetworkSession::WEBSOCKET_SOCKET_POOL, + ProxyServer::Direct()))); + EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 8888))))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( + EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPool( HttpNetworkSession::WEBSOCKET_SOCKET_POOL, ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 8888))))); @@ -2088,14 +1986,9 @@ TEST_F(HttpStreamFactoryTest, RequestSpdyHttpStreamHttpsURL) { ASSERT_TRUE(nullptr != waiter.stream()); EXPECT_EQ(1, GetSpdySessionCount(session.get())); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ( + 1, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); EXPECT_TRUE(waiter.used_proxy_info().is_direct()); } @@ -2147,14 +2040,9 @@ TEST_F(HttpStreamFactoryTest, RequestSpdyHttpStreamHttpURL) { ASSERT_TRUE(nullptr != waiter.stream()); EXPECT_EQ(1, GetSpdySessionCount(session.get())); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ( + 0, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); EXPECT_FALSE(waiter.used_proxy_info().is_direct()); EXPECT_TRUE(http_server_properties->GetSupportsSpdy(scheme_host_port)); } @@ -2199,9 +2087,13 @@ TEST_F(HttpStreamFactoryTest, NewSpdySessionCloseIdleH2Sockets) { ssl_config, PRIVACY_MODE_DISABLED)); std::string group_name = "ssl/" + host_port_pair.ToString(); int rv = connection->Init( - group_name, ssl_params, MEDIUM, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL), + group_name, + TransportClientSocketPool::SocketParams::CreateFromSSLSocketParams( + ssl_params), + MEDIUM, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + session->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL, + ProxyServer::Direct()), NetLogWithSource()); rv = callback.GetResult(rv); handles.push_back(std::move(connection)); @@ -2210,7 +2102,9 @@ TEST_F(HttpStreamFactoryTest, NewSpdySessionCloseIdleH2Sockets) { // Releases handles now, and these sockets should go into the socket pool. handles.clear(); EXPECT_EQ(kNumIdleSockets, - session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL) + session + ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL, + ProxyServer::Direct()) ->IdleSocketCount()); // Request two streams at once and make sure they use the same connection. @@ -2243,7 +2137,9 @@ TEST_F(HttpStreamFactoryTest, NewSpdySessionCloseIdleH2Sockets) { ASSERT_NE(waiter1.stream(), waiter2.stream()); // Establishing the SpdySession will close idle H2 sockets. - EXPECT_EQ(0, session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL) + EXPECT_EQ(0, session + ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL, + ProxyServer::Direct()) ->IdleSocketCount()); EXPECT_EQ(1, GetSpdySessionCount(session.get())); } @@ -2304,7 +2200,9 @@ TEST_F(HttpStreamFactoryTest, TwoSpdyConnects) { ASSERT_NE(waiter1.stream(), waiter2.stream()); // Establishing the SpdySession will close the extra H2 socket. - EXPECT_EQ(0, session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL) + EXPECT_EQ(0, session + ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL, + ProxyServer::Direct()) ->IdleSocketCount()); EXPECT_EQ(1, GetSpdySessionCount(session.get())); EXPECT_TRUE(data0.AllReadDataConsumed()); @@ -2347,14 +2245,9 @@ TEST_F(HttpStreamFactoryTest, RequestBidirectionalStreamImpl) { EXPECT_FALSE(waiter.websocket_stream()); ASSERT_FALSE(waiter.stream()); ASSERT_TRUE(waiter.bidirectional_stream_impl()); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ( + 1, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); EXPECT_TRUE(waiter.used_proxy_info().is_direct()); } @@ -2478,7 +2371,7 @@ class HttpStreamFactoryBidirectionalQuicTest HttpNetworkSession::Params params_; }; -INSTANTIATE_TEST_CASE_P( +INSTANTIATE_TEST_SUITE_P( VersionIncludeStreamDependencySequence, HttpStreamFactoryBidirectionalQuicTest, ::testing::Combine( @@ -2561,14 +2454,9 @@ TEST_P(HttpStreamFactoryBidirectionalQuicTest, EXPECT_THAT(stream_impl->ReadData(buffer.get(), 1), IsOk()); EXPECT_EQ(kProtoQUIC, stream_impl->GetProtocol()); EXPECT_EQ("200", delegate.response_headers().find(":status")->second); - EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ( + 0, GetSocketPoolGroupCount(session()->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); EXPECT_TRUE(waiter.used_proxy_info().is_direct()); } @@ -2696,14 +2584,9 @@ TEST_P(HttpStreamFactoryBidirectionalQuicTest, EXPECT_EQ(kProtoQUIC, stream_impl->GetProtocol()); EXPECT_EQ("200", delegate.response_headers().find(":status")->second); // There is no Http2 socket pool. - EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ( + 0, GetSocketPoolGroupCount(session()->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); EXPECT_TRUE(waiter.used_proxy_info().is_direct()); } @@ -2746,14 +2629,9 @@ TEST_F(HttpStreamFactoryTest, RequestBidirectionalStreamImplFailure) { EXPECT_FALSE(waiter.websocket_stream()); ASSERT_FALSE(waiter.stream()); ASSERT_FALSE(waiter.bidirectional_stream_impl()); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ( + 1, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); } #if defined(OS_ANDROID) @@ -2821,18 +2699,12 @@ TEST_F(HttpStreamFactoryTest, Tag) { ASSERT_TRUE(nullptr != waiter1.stream()); EXPECT_EQ(1, GetSpdySessionCount(session.get())); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(1, GetHandedOutSocketCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetHandedOutSocketCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ( + 1, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); + EXPECT_EQ( + 1, GetHandedOutSocketCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify socket tagged appropriately. EXPECT_TRUE(tag1 == socket_factory->GetLastProducedTCPSocket()->tag()); EXPECT_TRUE( @@ -2852,18 +2724,12 @@ TEST_F(HttpStreamFactoryTest, Tag) { ASSERT_TRUE(nullptr != waiter2.stream()); EXPECT_EQ(2, GetSpdySessionCount(session.get())); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(2, GetHandedOutSocketCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(2, GetHandedOutSocketCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ( + 1, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); + EXPECT_EQ( + 2, GetHandedOutSocketCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify socket tagged appropriately. EXPECT_TRUE(tag2 == socket_factory->GetLastProducedTCPSocket()->tag()); EXPECT_TRUE( @@ -2883,18 +2749,12 @@ TEST_F(HttpStreamFactoryTest, Tag) { ASSERT_TRUE(nullptr != waiter3.stream()); EXPECT_EQ(2, GetSpdySessionCount(session.get())); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(2, GetHandedOutSocketCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(2, GetHandedOutSocketCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ( + 1, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); + EXPECT_EQ( + 2, GetHandedOutSocketCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); } // Verify HttpStreamFactory::Job passes socket tag along properly to QUIC @@ -3099,18 +2959,12 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTag) { ASSERT_TRUE(waiter1.stream()); EXPECT_EQ(1, GetSpdySessionCount(session.get())); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(1, GetHandedOutSocketCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetHandedOutSocketCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ( + 1, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); + EXPECT_EQ( + 1, GetHandedOutSocketCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify socket tagged appropriately. MockTaggingStreamSocket* socket = socket_factory->GetLastProducedTCPSocket(); EXPECT_TRUE(tag1 == socket->tag()); @@ -3129,18 +2983,12 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTag) { ASSERT_TRUE(waiter2.stream()); // Verify still have just one session. EXPECT_EQ(1, GetSpdySessionCount(session.get())); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(1, GetHandedOutSocketCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetHandedOutSocketCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ( + 1, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); + EXPECT_EQ( + 1, GetHandedOutSocketCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify no new sockets created. EXPECT_EQ(socket, socket_factory->GetLastProducedTCPSocket()); // Verify socket tag changed. @@ -3169,18 +3017,12 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTag) { ASSERT_TRUE(waiter3.stream()); // Verify still have just one session. EXPECT_EQ(1, GetSpdySessionCount(session.get())); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(1, GetHandedOutSocketCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetHandedOutSocketCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ( + 1, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); + EXPECT_EQ( + 1, GetHandedOutSocketCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify no new sockets created. EXPECT_EQ(socket, socket_factory->GetLastProducedTCPSocket()); // Verify socket tag changed. @@ -3209,18 +3051,12 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTag) { ASSERT_TRUE(waiter4.stream()); // Verify we now have two sessions. EXPECT_EQ(2, GetSpdySessionCount(session.get())); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(2, GetHandedOutSocketCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(2, GetHandedOutSocketCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ( + 1, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); + EXPECT_EQ( + 2, GetHandedOutSocketCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify a new socket was created. MockTaggingStreamSocket* socket2 = socket_factory->GetLastProducedTCPSocket(); EXPECT_NE(socket, socket2); @@ -3303,18 +3139,12 @@ TEST_F(HttpStreamFactoryTest, MultiIPAliases) { // Verify just one session created. EXPECT_EQ(1, GetSpdySessionCount(session.get())); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(1, GetHandedOutSocketCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(1, GetHandedOutSocketCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ( + 1, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); + EXPECT_EQ( + 1, GetHandedOutSocketCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Open another session to same IP but with different privacy mode. StreamRequestWaiter waiter2; @@ -3330,18 +3160,12 @@ TEST_F(HttpStreamFactoryTest, MultiIPAliases) { // Verify two sessions are now open. EXPECT_EQ(2, GetSpdySessionCount(session.get())); - EXPECT_EQ(2, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(2, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(2, GetHandedOutSocketCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(2, GetHandedOutSocketCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ( + 2, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); + EXPECT_EQ( + 2, GetHandedOutSocketCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Open a third session that IP aliases first session. StreamRequestWaiter waiter3; @@ -3360,18 +3184,12 @@ TEST_F(HttpStreamFactoryTest, MultiIPAliases) { // created. This will fail unless the session pool supports multiple // sessions aliasing a single IP. EXPECT_EQ(2, GetSpdySessionCount(session.get())); - EXPECT_EQ(2, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(2, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(2, GetHandedOutSocketCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(2, GetHandedOutSocketCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ( + 2, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); + EXPECT_EQ( + 2, GetHandedOutSocketCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Open a fourth session that IP aliases the second session. StreamRequestWaiter waiter4; @@ -3389,18 +3207,12 @@ TEST_F(HttpStreamFactoryTest, MultiIPAliases) { // Verify the session pool reused the second session. This will fail unless // the session pool supports multiple sessions aliasing a single IP. EXPECT_EQ(2, GetSpdySessionCount(session.get())); - EXPECT_EQ(2, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(2, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( - HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); - EXPECT_EQ(2, GetHandedOutSocketCount(session->GetTransportSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); - EXPECT_EQ(2, GetHandedOutSocketCount(session->GetSSLSocketPool( - HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ( + 2, GetSocketPoolGroupCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); + EXPECT_EQ( + 2, GetHandedOutSocketCount(session->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); } } // namespace diff --git a/chromium/net/http/http_stream_parser.cc b/chromium/net/http/http_stream_parser.cc index 30bba23be67..19eaa7e12da 100644 --- a/chromium/net/http/http_stream_parser.cc +++ b/chromium/net/http/http_stream_parser.cc @@ -21,10 +21,13 @@ #include "net/http/http_request_headers.h" #include "net/http/http_request_info.h" #include "net/http/http_response_headers.h" +#include "net/http/http_response_info.h" #include "net/http/http_util.h" #include "net/log/net_log_event_type.h" -#include "net/socket/client_socket_handle.h" #include "net/socket/ssl_client_socket.h" +#include "net/socket/stream_socket.h" +#include "net/ssl/ssl_cert_request_info.h" +#include "net/ssl/ssl_info.h" #include "url/url_canon.h" namespace net { @@ -184,7 +187,8 @@ class HttpStreamParser::SeekableIOBuffer : public IOBuffer { // 2 CRLFs + max of 8 hex chars. const size_t HttpStreamParser::kChunkHeaderFooterSize = 12; -HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection, +HttpStreamParser::HttpStreamParser(StreamSocket* stream_socket, + bool connection_is_reused, const HttpRequestInfo* request, GrowableIOBuffer* read_buffer, const NetLogWithSource& net_log) @@ -195,7 +199,7 @@ HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection, http_09_on_non_default_ports_enabled_(false), read_buf_(read_buffer), read_buf_unused_offset_(0), - response_header_start_offset_(-1), + response_header_start_offset_(std::string::npos), received_bytes_(0), sent_bytes_(0), response_(nullptr), @@ -204,13 +208,12 @@ HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection, response_body_read_(0), user_read_buf_(nullptr), user_read_buf_len_(0), - connection_(connection), + stream_socket_(stream_socket), + connection_is_reused_(connection_is_reused), net_log_(net_log), sent_last_chunk_(false), upload_error_(OK), weak_ptr_factory_(this) { - CHECK(connection_) << "ClientSocketHandle passed to HttpStreamParser must " - "not be NULL. See crbug.com/790776"; io_callback_ = base::BindRepeating(&HttpStreamParser::OnIOComplete, weak_ptr_factory_.GetWeakPtr()); } @@ -239,10 +242,10 @@ int HttpStreamParser::SendRequest( // Put the peer's IP address and port into the response. IPEndPoint ip_endpoint; - int result = connection_->socket()->GetPeerAddress(&ip_endpoint); + int result = stream_socket_->GetPeerAddress(&ip_endpoint); if (result != OK) return result; - response_->socket_address = HostPortPair::FromIPEndPoint(ip_endpoint); + response_->remote_endpoint = ip_endpoint; std::string request = request_line + headers.ToString(); request_headers_length_ = request.size(); @@ -347,12 +350,6 @@ int HttpStreamParser::ReadResponseHeaders(CompletionOnceCallback callback) { return result > 0 ? OK : result; } -void HttpStreamParser::Close(bool not_reusable) { - if (not_reusable && connection_->socket()) - connection_->socket()->Disconnect(); - connection_->Reset(); -} - int HttpStreamParser::ReadResponseBody(IOBuffer* buf, int buf_len, CompletionOnceCallback callback) { @@ -464,7 +461,7 @@ int HttpStreamParser::DoSendHeaders() { response_->request_time = base::Time::Now(); io_state_ = STATE_SEND_HEADERS_COMPLETE; - return connection_->socket()->Write( + return stream_socket_->Write( request_headers_.get(), bytes_remaining, io_callback_, NetworkTrafficAnnotationTag(traffic_annotation_)); } @@ -513,7 +510,7 @@ int HttpStreamParser::DoSendHeadersComplete(int result) { int HttpStreamParser::DoSendBody() { if (request_body_send_buf_->BytesRemaining() > 0) { io_state_ = STATE_SEND_BODY_COMPLETE; - return connection_->socket()->Write( + return stream_socket_->Write( request_body_send_buf_.get(), request_body_send_buf_->BytesRemaining(), io_callback_, NetworkTrafficAnnotationTag(traffic_annotation_)); } @@ -608,8 +605,8 @@ int HttpStreamParser::DoReadHeaders() { // See if the user is passing in an IOBuffer with a NULL |data_|. CHECK(read_buf_->data()); - return connection_->socket() - ->Read(read_buf_.get(), read_buf_->RemainingCapacity(), io_callback_); + return stream_socket_->Read(read_buf_.get(), read_buf_->RemainingCapacity(), + io_callback_); } int HttpStreamParser::DoReadHeadersComplete(int result) { @@ -694,8 +691,8 @@ int HttpStreamParser::DoReadBody() { return 0; DCHECK_EQ(0, read_buf_->offset()); - return connection_->socket() - ->Read(user_read_buf_.get(), user_read_buf_len_, io_callback_); + return stream_socket_->Read(user_read_buf_.get(), user_read_buf_len_, + io_callback_); } int HttpStreamParser::DoReadBodyComplete(int result) { @@ -815,7 +812,7 @@ int HttpStreamParser::HandleReadHeaderResult(int result) { // on the original connection close error, as rather than being an // empty HTTP/0.9 response it's much more likely the server closed the // socket before it received the request. - if (!connection_->is_reused()) + if (!connection_is_reused_) return ERR_EMPTY_RESPONSE; return result; } @@ -823,12 +820,12 @@ int HttpStreamParser::HandleReadHeaderResult(int result) { // Accepting truncated headers over HTTPS is a potential security // vulnerability, so just return an error in that case. // - // If response_header_start_offset_ is -1, this may be a < 8 byte HTTP/0.9 - // response. However, accepting such a response over HTTPS would allow a - // MITM to truncate an HTTP/1.x status line to look like a short HTTP/0.9 - // response if the peer put a record boundary at the first 8 bytes. To - // ensure that all response headers received over HTTPS are pristine, treat - // such responses as errors. + // If response_header_start_offset_ is std::string::npos, this may be a < 8 + // byte HTTP/0.9 response. However, accepting such a response over HTTPS + // would allow a MITM to truncate an HTTP/1.x status line to look like a + // short HTTP/0.9 response if the peer put a record boundary at the first 8 + // bytes. To ensure that all response headers received over HTTPS are + // pristine, treat such responses as errors. // // TODO(mmenke): Returning ERR_RESPONSE_HEADERS_TRUNCATED when a response // looks like an HTTP/0.9 response is weird. Should either come up with @@ -841,7 +838,7 @@ int HttpStreamParser::HandleReadHeaderResult(int result) { // Parse things as well as we can and let the caller decide what to do. int end_offset; - if (response_header_start_offset_ >= 0) { + if (response_header_start_offset_ != std::string::npos) { // The response looks to be a truncated set of HTTP headers. io_state_ = STATE_READ_BODY_COMPLETE; end_offset = read_buf_->offset(); @@ -913,7 +910,7 @@ int HttpStreamParser::HandleReadHeaderResult(int result) { // request so we return OK here, which lets the caller inspect the // response and reject it in the event that we're setting up a CONNECT // tunnel. - response_header_start_offset_ = -1; + response_header_start_offset_ = std::string::npos; response_body_length_ = -1; // Now waiting for the second set of headers to be read. } else { @@ -938,23 +935,25 @@ int HttpStreamParser::HandleReadHeaderResult(int result) { int HttpStreamParser::FindAndParseResponseHeaders(int new_bytes) { DCHECK_GT(new_bytes, 0); DCHECK_EQ(0, read_buf_unused_offset_); - int end_offset = -1; + size_t end_offset = std::string::npos; // Look for the start of the status line, if it hasn't been found yet. - if (response_header_start_offset_ < 0) { + if (response_header_start_offset_ == std::string::npos) { response_header_start_offset_ = HttpUtil::LocateStartOfStatusLine( read_buf_->StartOfBuffer(), read_buf_->offset()); } - if (response_header_start_offset_ >= 0) { + if (response_header_start_offset_ != std::string::npos) { // LocateEndOfHeaders looks for two line breaks in a row (With or without // carriage returns). So the end of the headers includes at most the last 3 // bytes of the buffer from the past read. This optimization avoids O(n^2) // performance in the case each read only returns a couple bytes. It's not // too important in production, but for fuzzers with memory instrumentation, // it's needed to avoid timing out. - int search_start = std::max(response_header_start_offset_, - read_buf_->offset() - new_bytes - 3); + size_t lower_bound = + (base::ClampedNumeric<size_t>(read_buf_->offset()) - new_bytes - 3) + .RawValue(); + size_t search_start = std::max(response_header_start_offset_, lower_bound); end_offset = HttpUtil::LocateEndOfHeaders( read_buf_->StartOfBuffer(), read_buf_->offset(), search_start); } else if (read_buf_->offset() >= 8) { @@ -963,7 +962,7 @@ int HttpStreamParser::FindAndParseResponseHeaders(int new_bytes) { end_offset = 0; } - if (end_offset == -1) + if (end_offset == std::string::npos) return -1; int rv = ParseResponseHeaders(end_offset); @@ -976,7 +975,7 @@ int HttpStreamParser::ParseResponseHeaders(int end_offset) { scoped_refptr<HttpResponseHeaders> headers; DCHECK_EQ(0, read_buf_unused_offset_); - if (response_header_start_offset_ >= 0) { + if (response_header_start_offset_ != std::string::npos) { received_bytes_ += end_offset; headers = HttpResponseHeaders::TryToCreate( base::StringPiece(read_buf_->StartOfBuffer(), end_offset)); @@ -1103,16 +1102,6 @@ bool HttpStreamParser::IsMoreDataBuffered() const { return read_buf_->offset() > read_buf_unused_offset_; } -bool HttpStreamParser::IsConnectionReused() const { - ClientSocketHandle::SocketReuseType reuse_type = connection_->reuse_type(); - return connection_->is_reused() || - reuse_type == ClientSocketHandle::UNUSED_IDLE; -} - -void HttpStreamParser::SetConnectionReused() { - connection_->set_reuse_type(ClientSocketHandle::REUSED_IDLE); -} - bool HttpStreamParser::CanReuseConnection() const { if (!CanFindEndOfResponse()) return false; @@ -1130,20 +1119,21 @@ bool HttpStreamParser::CanReuseConnection() const { if (IsResponseBodyComplete() && IsMoreDataBuffered()) return false; - return connection_->socket() && connection_->socket()->IsConnected(); + return stream_socket_->IsConnected(); } void HttpStreamParser::GetSSLInfo(SSLInfo* ssl_info) { - if (request_->url.SchemeIsCryptographic() && connection_->socket()) { - connection_->socket()->GetSSLInfo(ssl_info); + if (!request_->url.SchemeIsCryptographic() || + !stream_socket_->GetSSLInfo(ssl_info)) { + ssl_info->Reset(); } } void HttpStreamParser::GetSSLCertRequestInfo( SSLCertRequestInfo* cert_request_info) { - if (request_->url.SchemeIsCryptographic() && connection_->socket()) { - connection_->socket()->GetSSLCertRequestInfo(cert_request_info); - } + cert_request_info->Reset(); + if (request_->url.SchemeIsCryptographic()) + stream_socket_->GetSSLCertRequestInfo(cert_request_info); } int HttpStreamParser::EncodeChunk(const base::StringPiece& payload, diff --git a/chromium/net/http/http_stream_parser.h b/chromium/net/http/http_stream_parser.h index ce587534fc2..c09a709e0e1 100644 --- a/chromium/net/http/http_stream_parser.h +++ b/chromium/net/http/http_stream_parser.h @@ -25,7 +25,6 @@ namespace net { -class ClientSocketHandle; class DrainableIOBuffer; class GrowableIOBuffer; class HttpChunkedDecoder; @@ -35,16 +34,24 @@ class HttpResponseInfo; class IOBuffer; class SSLCertRequestInfo; class SSLInfo; +class StreamSocket; class UploadDataStream; class NET_EXPORT_PRIVATE HttpStreamParser { public: + // |connection_is_reused| must be |true| if |stream_socket| has previously + // been used successfully for an HTTP/1.x request. + // // Any data in |read_buffer| will be used before reading from the socket // and any data left over after parsing the stream will be put into // |read_buffer|. The left over data will start at offset 0 and the // buffer's offset will be set to the first free byte. |read_buffer| may // have its capacity changed. - HttpStreamParser(ClientSocketHandle* connection, + // + // It is not safe to call into the HttpStreamParser after destroying the + // |stream_socket|. + HttpStreamParser(StreamSocket* stream_socket, + bool connection_is_reused, const HttpRequestInfo* request, GrowableIOBuffer* read_buffer, const NetLogWithSource& net_log); @@ -72,18 +79,12 @@ class NET_EXPORT_PRIVATE HttpStreamParser { int buf_len, CompletionOnceCallback callback); - void Close(bool not_reusable); - bool IsResponseBodyComplete() const; bool CanFindEndOfResponse() const; bool IsMoreDataBuffered() const; - bool IsConnectionReused() const; - - void SetConnectionReused(); - // Returns true if the underlying connection can be reused. // The connection can be reused if: // * It's still connected. @@ -227,8 +228,8 @@ class NET_EXPORT_PRIVATE HttpStreamParser { int read_buf_unused_offset_; // The amount beyond |read_buf_unused_offset_| where the status line starts; - // -1 if not found yet. - int response_header_start_offset_; + // std::string::npos if not found yet. + size_t response_header_start_offset_; // The amount of received data. If connection is reused then intermediate // value may be bigger than final. @@ -269,8 +270,14 @@ class NET_EXPORT_PRIVATE HttpStreamParser { // complete or there was an error CompletionOnceCallback callback_; - // The underlying socket. - ClientSocketHandle* const connection_; + // The underlying socket, owned by the caller. The HttpStreamParser must be + // destroyed before the caller destroys the socket, or relinquishes ownership + // of it. + StreamSocket* const stream_socket_; + + // Whether the socket has already been used. Only used in HTTP/0.9 detection + // logic. + const bool connection_is_reused_; NetLogWithSource net_log_; diff --git a/chromium/net/http/http_stream_parser_fuzzer.cc b/chromium/net/http/http_stream_parser_fuzzer.cc index 0e6fe6c7927..1cfcb27087a 100644 --- a/chromium/net/http/http_stream_parser_fuzzer.cc +++ b/chromium/net/http/http_stream_parser_fuzzer.cc @@ -23,7 +23,6 @@ #include "net/http/http_request_info.h" #include "net/http/http_response_info.h" #include "net/log/test_net_log.h" -#include "net/socket/client_socket_handle.h" #include "net/socket/fuzzed_socket.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "url/gurl.h" @@ -35,12 +34,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { net::TestCompletionCallback callback; net::BoundTestNetLog bound_test_net_log; base::FuzzedDataProvider data_provider(data, size); - std::unique_ptr<net::FuzzedSocket> fuzzed_socket(new net::FuzzedSocket( - &data_provider, bound_test_net_log.bound().net_log())); - CHECK_EQ(net::OK, fuzzed_socket->Connect(callback.callback())); - - net::ClientSocketHandle socket_handle; - socket_handle.SetSocket(std::move(fuzzed_socket)); + net::FuzzedSocket fuzzed_socket(&data_provider, + bound_test_net_log.bound().net_log()); + CHECK_EQ(net::OK, fuzzed_socket.Connect(callback.callback())); net::HttpRequestInfo request_info; request_info.method = "GET"; @@ -50,7 +46,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { base::MakeRefCounted<net::GrowableIOBuffer>(); // Use a NetLog that listens to events, to get coverage of logging // callbacks. - net::HttpStreamParser parser(&socket_handle, &request_info, read_buffer.get(), + net::HttpStreamParser parser(&fuzzed_socket, false /* is_reused */, + &request_info, read_buffer.get(), bound_test_net_log.bound()); net::HttpResponseInfo response_info; diff --git a/chromium/net/http/http_stream_parser_unittest.cc b/chromium/net/http/http_stream_parser_unittest.cc index 658cda07a15..1125d556619 100644 --- a/chromium/net/http/http_stream_parser_unittest.cc +++ b/chromium/net/http/http_stream_parser_unittest.cc @@ -11,6 +11,7 @@ #include <utility> #include <vector> +#include "base/bind.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" @@ -31,8 +32,8 @@ #include "net/http/http_request_info.h" #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" -#include "net/socket/client_socket_handle.h" #include "net/socket/socket_test_util.h" +#include "net/socket/stream_socket.h" #include "net/test/gtest_util.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gmock/include/gmock/gmock.h" @@ -53,8 +54,7 @@ const size_t kMaxPayloadSize = // Helper method to create a connected ClientSocketHandle using |data|. // Modifies |data|. -std::unique_ptr<ClientSocketHandle> CreateConnectedSocketHandle( - SequencedSocketData* data) { +std::unique_ptr<StreamSocket> CreateConnectedSocket(SequencedSocketData* data) { data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); std::unique_ptr<MockTCPClientSocket> socket( @@ -63,9 +63,7 @@ std::unique_ptr<ClientSocketHandle> CreateConnectedSocketHandle( TestCompletionCallback callback; EXPECT_THAT(socket->Connect(callback.callback()), IsOk()); - std::unique_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle); - socket_handle->SetSocket(std::move(socket)); - return socket_handle; + return socket; } class ReadErrorUploadDataStream : public UploadDataStream { @@ -84,8 +82,8 @@ class ReadErrorUploadDataStream : public UploadDataStream { int ReadInternal(IOBuffer* buf, int buf_len) override { if (async_ == FailureMode::ASYNC) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&ReadErrorUploadDataStream::CompleteRead, - weak_factory_.GetWeakPtr())); + FROM_HERE, base::BindOnce(&ReadErrorUploadDataStream::CompleteRead, + weak_factory_.GetWeakPtr())); return ERR_IO_PENDING; } return ERR_FAILED; @@ -107,8 +105,7 @@ TEST(HttpStreamParser, DataReadErrorSynchronous) { }; SequencedSocketData data(base::span<MockRead>(), writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); ReadErrorUploadDataStream upload_data_stream( ReadErrorUploadDataStream::FailureMode::SYNC); @@ -134,8 +131,8 @@ TEST(HttpStreamParser, DataReadErrorSynchronous) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, &request, + read_buffer.get(), NetLogWithSource()); HttpRequestHeaders headers; headers.SetHeader("Content-Length", "12"); @@ -163,8 +160,7 @@ TEST(HttpStreamParser, DataReadErrorAsynchronous) { }; SequencedSocketData data(base::span<MockRead>(), writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); ReadErrorUploadDataStream upload_data_stream( ReadErrorUploadDataStream::FailureMode::ASYNC); @@ -179,8 +175,8 @@ TEST(HttpStreamParser, DataReadErrorAsynchronous) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, &request, + read_buffer.get(), NetLogWithSource()); HttpRequestHeaders headers; headers.SetHeader("Content-Length", "12"); @@ -211,8 +207,8 @@ class InitAsyncUploadDataStream : public ChunkedUploadDataStream { int InitInternal(const NetLogWithSource& net_log) override { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&InitAsyncUploadDataStream::CompleteInit, - weak_factory_.GetWeakPtr())); + FROM_HERE, base::BindOnce(&InitAsyncUploadDataStream::CompleteInit, + weak_factory_.GetWeakPtr())); return ERR_IO_PENDING; } @@ -254,13 +250,12 @@ TEST(HttpStreamParser, InitAsynchronousUploadDataStream) { }; SequencedSocketData data(base::span<MockRead>(), writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, &request, + read_buffer.get(), NetLogWithSource()); HttpRequestHeaders headers; headers.SetHeader("Transfer-Encoding", "chunked"); @@ -440,8 +435,7 @@ TEST(HttpStreamParser, SentBytesNoHeaders) { }; SequencedSocketData data(base::span<MockRead>(), writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); HttpRequestInfo request; request.method = "GET"; @@ -449,8 +443,8 @@ TEST(HttpStreamParser, SentBytesNoHeaders) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, &request, + read_buffer.get(), NetLogWithSource()); HttpResponseInfo response; TestCompletionCallback callback; @@ -470,8 +464,7 @@ TEST(HttpStreamParser, SentBytesWithHeaders) { }; SequencedSocketData data(base::span<MockRead>(), writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); HttpRequestInfo request; request.method = "GET"; @@ -479,8 +472,8 @@ TEST(HttpStreamParser, SentBytesWithHeaders) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, &request, + read_buffer.get(), NetLogWithSource()); HttpRequestHeaders headers; headers.SetHeader("Host", "localhost"); @@ -503,8 +496,7 @@ TEST(HttpStreamParser, SentBytesWithHeadersMultiWrite) { }; SequencedSocketData data(base::span<MockRead>(), writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); HttpRequestInfo request; request.method = "GET"; @@ -512,8 +504,8 @@ TEST(HttpStreamParser, SentBytesWithHeadersMultiWrite) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, &request, + read_buffer.get(), NetLogWithSource()); HttpRequestHeaders headers; headers.SetHeader("Host", "localhost"); @@ -537,8 +529,7 @@ TEST(HttpStreamParser, SentBytesWithErrorWritingHeaders) { }; SequencedSocketData data(base::span<MockRead>(), writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); HttpRequestInfo request; request.method = "GET"; @@ -546,8 +537,8 @@ TEST(HttpStreamParser, SentBytesWithErrorWritingHeaders) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, &request, + read_buffer.get(), NetLogWithSource()); HttpRequestHeaders headers; headers.SetHeader("Host", "localhost"); @@ -571,8 +562,7 @@ TEST(HttpStreamParser, SentBytesPost) { }; SequencedSocketData data(base::span<MockRead>(), writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); std::vector<std::unique_ptr<UploadElementReader>> element_readers; element_readers.push_back( @@ -589,8 +579,8 @@ TEST(HttpStreamParser, SentBytesPost) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, &request, + read_buffer.get(), NetLogWithSource()); HttpRequestHeaders headers; headers.SetHeader("Content-Length", "12"); @@ -621,8 +611,7 @@ TEST(HttpStreamParser, SentBytesChunkedPostError) { }; SequencedSocketData data(base::span<MockRead>(), writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); ChunkedUploadDataStream upload_data_stream(0); ASSERT_THAT(upload_data_stream.Init(TestCompletionCallback().callback(), @@ -636,8 +625,8 @@ TEST(HttpStreamParser, SentBytesChunkedPostError) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, &request, + read_buffer.get(), NetLogWithSource()); HttpRequestHeaders headers; headers.SetHeader("Transfer-Encoding", "chunked"); @@ -696,8 +685,7 @@ TEST(HttpStreamParser, AsyncSingleChunkAndAsyncSocket) { IsOk()); SequencedSocketData data(reads, writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); HttpRequestInfo request_info; request_info.method = "GET"; @@ -706,8 +694,8 @@ TEST(HttpStreamParser, AsyncSingleChunkAndAsyncSocket) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, + &request_info, read_buffer.get(), NetLogWithSource()); HttpRequestHeaders request_headers; request_headers.SetHeader("Transfer-Encoding", "chunked"); @@ -781,8 +769,7 @@ TEST(HttpStreamParser, SyncSingleChunkAndAsyncSocket) { upload_stream.AppendData(kChunk, base::size(kChunk) - 1, true); SequencedSocketData data(reads, writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); HttpRequestInfo request_info; request_info.method = "GET"; @@ -791,8 +778,8 @@ TEST(HttpStreamParser, SyncSingleChunkAndAsyncSocket) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, + &request_info, read_buffer.get(), NetLogWithSource()); HttpRequestHeaders request_headers; request_headers.SetHeader("Transfer-Encoding", "chunked"); @@ -866,8 +853,7 @@ TEST(HttpStreamParser, AsyncChunkAndAsyncSocketWithMultipleChunks) { IsOk()); SequencedSocketData data(reads, writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); HttpRequestInfo request_info; request_info.method = "GET"; @@ -876,8 +862,8 @@ TEST(HttpStreamParser, AsyncChunkAndAsyncSocketWithMultipleChunks) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, + &request_info, read_buffer.get(), NetLogWithSource()); HttpRequestHeaders request_headers; request_headers.SetHeader("Transfer-Encoding", "chunked"); @@ -955,8 +941,7 @@ TEST(HttpStreamParser, AsyncEmptyChunkedUpload) { IsOk()); SequencedSocketData data(reads, writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); HttpRequestInfo request_info; request_info.method = "GET"; @@ -965,8 +950,8 @@ TEST(HttpStreamParser, AsyncEmptyChunkedUpload) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, + &request_info, read_buffer.get(), NetLogWithSource()); HttpRequestHeaders request_headers; request_headers.SetHeader("Transfer-Encoding", "chunked"); @@ -1035,8 +1020,7 @@ TEST(HttpStreamParser, SyncEmptyChunkedUpload) { upload_stream.AppendData(nullptr, 0, true); SequencedSocketData data(reads, writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); HttpRequestInfo request_info; request_info.method = "GET"; @@ -1045,8 +1029,8 @@ TEST(HttpStreamParser, SyncEmptyChunkedUpload) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, + &request_info, read_buffer.get(), NetLogWithSource()); HttpRequestHeaders request_headers; request_headers.SetHeader("Transfer-Encoding", "chunked"); @@ -1136,8 +1120,7 @@ TEST(HttpStreamParser, TruncatedHeaders) { for (size_t i = 0; i < base::size(reads); i++) { SCOPED_TRACE(i); SequencedSocketData data(reads[i], writes); - std::unique_ptr<ClientSocketHandle> socket_handle( - CreateConnectedSocketHandle(&data)); + std::unique_ptr<StreamSocket> stream_socket(CreateConnectedSocket(&data)); HttpRequestInfo request_info; request_info.method = "GET"; @@ -1150,8 +1133,9 @@ TEST(HttpStreamParser, TruncatedHeaders) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request_info, - read_buffer.get(), NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, + &request_info, read_buffer.get(), + NetLogWithSource()); HttpRequestHeaders request_headers; HttpResponseInfo response_info; @@ -1198,8 +1182,7 @@ TEST(HttpStreamParser, WebSocket101Response) { }; SequencedSocketData data(reads, writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); HttpRequestInfo request_info; request_info.method = "GET"; @@ -1208,8 +1191,8 @@ TEST(HttpStreamParser, WebSocket101Response) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), &request_info, read_buffer.get(), - NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, + &request_info, read_buffer.get(), NetLogWithSource()); HttpRequestHeaders request_headers; HttpResponseInfo response_info; @@ -1276,13 +1259,14 @@ class SimpleGetRunner { reads_.push_back(MockRead(SYNCHRONOUS, 0, sequence_number_++)); // EOF data_.reset(new SequencedSocketData(reads_, writes_)); - socket_handle_ = CreateConnectedSocketHandle(data_.get()); + stream_socket_ = CreateConnectedSocket(data_.get()); request_info_.method = "GET"; request_info_.url = url_; request_info_.load_flags = LOAD_NORMAL; - parser_.reset(new HttpStreamParser(socket_handle_.get(), &request_info_, + parser_.reset(new HttpStreamParser(stream_socket_.get(), + false /* is_reused */, &request_info_, read_buffer(), NetLogWithSource())); parser_->set_http_09_on_non_default_ports_enabled( @@ -1331,7 +1315,7 @@ class SimpleGetRunner { scoped_refptr<GrowableIOBuffer> read_buffer_; std::vector<MockRead> reads_; std::vector<MockWrite> writes_; - std::unique_ptr<ClientSocketHandle> socket_handle_; + std::unique_ptr<StreamSocket> stream_socket_; std::unique_ptr<SequencedSocketData> data_; std::unique_ptr<HttpStreamParser> parser_; int sequence_number_; @@ -1743,8 +1727,7 @@ TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) { }; SequencedSocketData data(reads, writes); - std::unique_ptr<ClientSocketHandle> socket_handle = - CreateConnectedSocketHandle(&data); + std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); std::unique_ptr<HttpRequestInfo> request_info(new HttpRequestInfo()); request_info->method = "GET"; @@ -1752,8 +1735,9 @@ TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) { scoped_refptr<GrowableIOBuffer> read_buffer = base::MakeRefCounted<GrowableIOBuffer>(); - HttpStreamParser parser(socket_handle.get(), request_info.get(), - read_buffer.get(), NetLogWithSource()); + HttpStreamParser parser(stream_socket.get(), false /* is_reused */, + request_info.get(), read_buffer.get(), + NetLogWithSource()); std::unique_ptr<HttpRequestHeaders> request_headers(new HttpRequestHeaders()); std::unique_ptr<HttpResponseInfo> response_info(new HttpResponseInfo()); diff --git a/chromium/net/http/http_util.cc b/chromium/net/http/http_util.cc index 23b71d0f5eb..6d9c6e63e6f 100644 --- a/chromium/net/http/http_util.cc +++ b/chromium/net/http/http_util.cc @@ -641,27 +641,27 @@ std::string HttpUtil::Quote(const std::string& str) { // Find the "http" substring in a status line. This allows for // some slop at the start. If the "http" string could not be found -// then returns -1. +// then returns std::string::npos. // static -int HttpUtil::LocateStartOfStatusLine(const char* buf, int buf_len) { - const int slop = 4; - const int http_len = 4; +size_t HttpUtil::LocateStartOfStatusLine(const char* buf, size_t buf_len) { + const size_t slop = 4; + const size_t http_len = 4; if (buf_len >= http_len) { - int i_max = std::min(buf_len - http_len, slop); - for (int i = 0; i <= i_max; ++i) { + size_t i_max = std::min(buf_len - http_len, slop); + for (size_t i = 0; i <= i_max; ++i) { if (base::LowerCaseEqualsASCII(base::StringPiece(buf + i, http_len), "http")) return i; } } - return -1; // Not found + return std::string::npos; // Not found } -static int LocateEndOfHeadersHelper(const char* buf, - int buf_len, - int i, - bool accept_empty_header_list) { +static size_t LocateEndOfHeadersHelper(const char* buf, + size_t buf_len, + size_t i, + bool accept_empty_header_list) { char last_c = '\0'; bool was_lf = false; if (accept_empty_header_list) { @@ -682,16 +682,16 @@ static int LocateEndOfHeadersHelper(const char* buf, } last_c = c; } - return -1; + return std::string::npos; } -int HttpUtil::LocateEndOfAdditionalHeaders(const char* buf, - int buf_len, - int i) { +size_t HttpUtil::LocateEndOfAdditionalHeaders(const char* buf, + size_t buf_len, + size_t i) { return LocateEndOfHeadersHelper(buf, buf_len, i, true); } -int HttpUtil::LocateEndOfHeaders(const char* buf, int buf_len, int i) { +size_t HttpUtil::LocateEndOfHeaders(const char* buf, size_t buf_len, size_t i) { return LocateEndOfHeadersHelper(buf, buf_len, i, false); } @@ -738,7 +738,7 @@ static const char* FindFirstNonLWS(const char* begin, const char* end) { } std::string HttpUtil::AssembleRawHeaders(const char* input_begin, - int input_len) { + size_t input_len) { std::string raw_headers; raw_headers.reserve(input_len); @@ -746,8 +746,8 @@ std::string HttpUtil::AssembleRawHeaders(const char* input_begin, // Skip any leading slop, since the consumers of this output // (HttpResponseHeaders) don't deal with it. - int status_begin_offset = LocateStartOfStatusLine(input_begin, input_len); - if (status_begin_offset != -1) + size_t status_begin_offset = LocateStartOfStatusLine(input_begin, input_len); + if (status_begin_offset != std::string::npos) input_begin += status_begin_offset; // Copy the status line. @@ -817,8 +817,8 @@ std::string HttpUtil::ExpandLanguageList(const std::string& language_prefs) { AcceptLanguageBuilder builder; - const int size = languages.size(); - for (int i = 0; i < size; ++i) { + const size_t size = languages.size(); + for (size_t i = 0; i < size; ++i) { const std::string& language = languages[i]; builder.AddLanguageCode(language); @@ -827,7 +827,7 @@ std::string HttpUtil::ExpandLanguageList(const std::string& language_prefs) { // Look ahead and add the base language if the next language is not part // of the same family. - const int j = i + 1; + const size_t j = i + 1; if (j >= size || GetBaseLanguageCode(languages[j]) != base_language) { builder.AddLanguageCode(base_language); } diff --git a/chromium/net/http/http_util.h b/chromium/net/http/http_util.h index cf007043ab4..c757bf18cb5 100644 --- a/chromium/net/http/http_util.h +++ b/chromium/net/http/http_util.h @@ -161,27 +161,29 @@ class NET_EXPORT HttpUtil { // The reverse of Unquote() -- escapes and surrounds with " static std::string Quote(const std::string& str); - // Returns the start of the status line, or -1 if no status line was found. - // This allows for 4 bytes of junk to precede the status line (which is what - // mozilla does too). - static int LocateStartOfStatusLine(const char* buf, int buf_len); - - // Returns index beyond the end-of-headers marker or -1 if not found. RFC - // 2616 defines the end-of-headers marker as a double CRLF; however, some - // servers only send back LFs (e.g., Unix-based CGI scripts written using the - // ASIS Apache module). This function therefore accepts the pattern LF[CR]LF - // as end-of-headers (just like Mozilla). The first line of |buf| is - // considered the status line, even if empty. - // The parameter |i| is the offset within |buf| to begin searching from. - static int LocateEndOfHeaders(const char* buf, int buf_len, int i = 0); + // Returns the start of the status line, or std::string::npos if no status + // line was found. This allows for 4 bytes of junk to precede the status line + // (which is what Mozilla does too). + static size_t LocateStartOfStatusLine(const char* buf, size_t buf_len); + + // Returns index beyond the end-of-headers marker or std::string::npos if not + // found. RFC 2616 defines the end-of-headers marker as a double CRLF; + // however, some servers only send back LFs (e.g., Unix-based CGI scripts + // written using the ASIS Apache module). This function therefore accepts the + // pattern LF[CR]LF as end-of-headers (just like Mozilla). The first line of + // |buf| is considered the status line, even if empty. The parameter |i| is + // the offset within |buf| to begin searching from. + static size_t LocateEndOfHeaders(const char* buf, + size_t buf_len, + size_t i = 0); // Same as |LocateEndOfHeaders|, but does not expect a status line, so can be // used on multi-part responses or HTTP/1.x trailers. As a result, if |buf| // starts with a single [CR]LF, it is considered an empty header list, as // opposed to an empty status line above a header list. - static int LocateEndOfAdditionalHeaders(const char* buf, - int buf_len, - int i = 0); + static size_t LocateEndOfAdditionalHeaders(const char* buf, + size_t buf_len, + size_t i = 0); // Assemble "raw headers" in the format required by HttpResponseHeaders. // This involves normalizing line terminators, converting [CR]LF to \0 and @@ -194,7 +196,7 @@ class NET_EXPORT HttpUtil { // // TODO(crbug.com/671799): Should remove or internalize this to // HttpResponseHeaders. - static std::string AssembleRawHeaders(const char* buf, int buf_len); + static std::string AssembleRawHeaders(const char* buf, size_t buf_len); // Converts assembled "raw headers" back to the HTTP response format. That is // convert each \0 occurence to CRLF. This is used by DevTools. diff --git a/chromium/net/http/http_util_unittest.cc b/chromium/net/http/http_util_unittest.cc index 7883b3e4b4b..0ddf34df2b4 100644 --- a/chromium/net/http/http_util_unittest.cc +++ b/chromium/net/http/http_util_unittest.cc @@ -327,12 +327,12 @@ TEST(HttpUtilTest, Quote) { TEST(HttpUtilTest, LocateEndOfHeaders) { struct { const char* const input; - int expected_result; + size_t expected_result; } tests[] = { - {"\r\n", -1}, - {"\n", -1}, - {"\r", -1}, - {"foo", -1}, + {"\r\n", std::string::npos}, + {"\n", std::string::npos}, + {"\r", std::string::npos}, + {"foo", std::string::npos}, {"\r\n\r\n", 4}, {"foo\r\nbar\r\n\r\n", 12}, {"foo\nbar\n\n", 9}, @@ -342,8 +342,8 @@ TEST(HttpUtilTest, LocateEndOfHeaders) { {"foo\nbar\r\n\njunk", 10}, }; for (size_t i = 0; i < base::size(tests); ++i) { - int input_len = static_cast<int>(strlen(tests[i].input)); - int eoh = HttpUtil::LocateEndOfHeaders(tests[i].input, input_len); + size_t input_len = strlen(tests[i].input); + size_t eoh = HttpUtil::LocateEndOfHeaders(tests[i].input, input_len); EXPECT_EQ(tests[i].expected_result, eoh); } } @@ -351,12 +351,12 @@ TEST(HttpUtilTest, LocateEndOfHeaders) { TEST(HttpUtilTest, LocateEndOfAdditionalHeaders) { struct { const char* const input; - int expected_result; + size_t expected_result; } tests[] = { {"\r\n", 2}, {"\n", 1}, - {"\r", -1}, - {"foo", -1}, + {"\r", std::string::npos}, + {"foo", std::string::npos}, {"\r\n\r\n", 2}, {"foo\r\nbar\r\n\r\n", 12}, {"foo\nbar\n\n", 9}, @@ -366,8 +366,9 @@ TEST(HttpUtilTest, LocateEndOfAdditionalHeaders) { {"foo\nbar\r\n\njunk", 10}, }; for (size_t i = 0; i < base::size(tests); ++i) { - int input_len = static_cast<int>(strlen(tests[i].input)); - int eoh = HttpUtil::LocateEndOfAdditionalHeaders(tests[i].input, input_len); + size_t input_len = strlen(tests[i].input); + size_t eoh = + HttpUtil::LocateEndOfAdditionalHeaders(tests[i].input, input_len); EXPECT_EQ(tests[i].expected_result, eoh); } } diff --git a/chromium/net/http/mock_allow_http_auth_preferences.cc b/chromium/net/http/mock_allow_http_auth_preferences.cc index 12ccfe2e3be..688f10e45ce 100644 --- a/chromium/net/http/mock_allow_http_auth_preferences.cc +++ b/chromium/net/http/mock_allow_http_auth_preferences.cc @@ -16,8 +16,9 @@ bool MockAllowHttpAuthPreferences::CanUseDefaultCredentials( return true; } -bool MockAllowHttpAuthPreferences::CanDelegate(const GURL& auth_origin) const { - return true; +HttpAuth::DelegationType MockAllowHttpAuthPreferences::GetDelegationType( + const GURL& auth_origin) const { + return HttpAuth::DelegationType::kUnconstrained; } } // namespace net diff --git a/chromium/net/http/mock_allow_http_auth_preferences.h b/chromium/net/http/mock_allow_http_auth_preferences.h index 3b51d7a0d63..c00a8d2adb3 100644 --- a/chromium/net/http/mock_allow_http_auth_preferences.h +++ b/chromium/net/http/mock_allow_http_auth_preferences.h @@ -18,7 +18,8 @@ class MockAllowHttpAuthPreferences : public HttpAuthPreferences { ~MockAllowHttpAuthPreferences() override; bool CanUseDefaultCredentials(const GURL& auth_origin) const override; - bool CanDelegate(const GURL& auth_origin) const override; + HttpAuth::DelegationType GetDelegationType( + const GURL& auth_origin) const override; private: DISALLOW_COPY_AND_ASSIGN(MockAllowHttpAuthPreferences); diff --git a/chromium/net/http/mock_http_cache.cc b/chromium/net/http/mock_http_cache.cc index 3ae150b10fd..355b20601e6 100644 --- a/chromium/net/http/mock_http_cache.cc +++ b/chromium/net/http/mock_http_cache.cc @@ -414,6 +414,7 @@ MockDiskCache::MockDiskCache() double_create_check_(true), fail_sparse_requests_(false), support_in_memory_entry_data_(true), + force_fail_callback_later_(false), defer_op_(MockDiskEntry::DEFER_NONE), resume_return_code_(0) {} @@ -429,11 +430,51 @@ int32_t MockDiskCache::GetEntryCount() const { return static_cast<int32_t>(entries_.size()); } +net::Error MockDiskCache::OpenOrCreateEntry( + const std::string& key, + net::RequestPriority request_priority, + disk_cache::EntryWithOpened* entry_struct, + CompletionOnceCallback callback) { + DCHECK(!callback.is_null()); + base::RepeatingCallback<void(int)> copyable_callback; + if (callback) + copyable_callback = base::AdaptCallbackForRepeating(std::move(callback)); + + if (force_fail_callback_later_) { + CallbackLater(copyable_callback, ERR_CACHE_OPEN_OR_CREATE_FAILURE); + return ERR_IO_PENDING; + } + + if (fail_requests_) + return ERR_CACHE_OPEN_OR_CREATE_FAILURE; + + disk_cache::Entry** entry = &(entry_struct->entry); + + // First try opening the entry. + entry_struct->opened = true; + net::Error rv = OpenEntry(key, request_priority, entry, copyable_callback); + if (rv == OK || rv == ERR_IO_PENDING) + return rv; + + // Unable to open, try creating the entry. + entry_struct->opened = false; + rv = CreateEntry(key, request_priority, entry, copyable_callback); + if (rv == OK || rv == ERR_IO_PENDING) + return rv; + + return ERR_CACHE_OPEN_OR_CREATE_FAILURE; +} + net::Error MockDiskCache::OpenEntry(const std::string& key, net::RequestPriority request_priority, disk_cache::Entry** entry, CompletionOnceCallback callback) { DCHECK(!callback.is_null()); + if (force_fail_callback_later_) { + CallbackLater(std::move(callback), ERR_CACHE_OPEN_FAILURE); + return ERR_IO_PENDING; + } + if (fail_requests_) return ERR_CACHE_OPEN_FAILURE; @@ -471,6 +512,11 @@ net::Error MockDiskCache::CreateEntry(const std::string& key, disk_cache::Entry** entry, CompletionOnceCallback callback) { DCHECK(!callback.is_null()); + if (force_fail_callback_later_) { + CallbackLater(std::move(callback), ERR_CACHE_CREATE_FAILURE); + return ERR_IO_PENDING; + } + if (fail_requests_) return ERR_CACHE_CREATE_FAILURE; @@ -525,6 +571,14 @@ net::Error MockDiskCache::DoomEntry(const std::string& key, net::RequestPriority request_priority, CompletionOnceCallback callback) { DCHECK(!callback.is_null()); + if (force_fail_callback_later_) { + CallbackLater(std::move(callback), ERR_CACHE_DOOM_FAILURE); + return ERR_IO_PENDING; + } + + if (fail_requests_) + return ERR_CACHE_DOOM_FAILURE; + auto it = entries_.find(key); if (it != entries_.end()) { it->second->Release(); diff --git a/chromium/net/http/mock_http_cache.h b/chromium/net/http/mock_http_cache.h index 887f45fffec..c4d026df7ec 100644 --- a/chromium/net/http/mock_http_cache.h +++ b/chromium/net/http/mock_http_cache.h @@ -153,6 +153,10 @@ class MockDiskCache : public disk_cache::Backend { CacheType GetCacheType() const override; int32_t GetEntryCount() const override; + net::Error OpenOrCreateEntry(const std::string& key, + net::RequestPriority request_priority, + disk_cache::EntryWithOpened* entry_struct, + CompletionOnceCallback callback) override; net::Error OpenEntry(const std::string& key, net::RequestPriority request_priority, disk_cache::Entry** entry, @@ -191,8 +195,8 @@ class MockDiskCache : public disk_cache::Backend { // Returns number of doomed entries. int doomed_count() const { return doomed_count_; } - // Fail any subsequent CreateEntry and OpenEntry. - void set_fail_requests() { fail_requests_ = true; } + // Fail any subsequent CreateEntry, OpenEntry, and DoomEntry + void set_fail_requests(bool value) { fail_requests_ = value; } // Return entries that fail some of their requests. void set_soft_failures(bool value) { soft_failures_ = value; } @@ -212,6 +216,12 @@ class MockDiskCache : public disk_cache::Backend { support_in_memory_entry_data_ = value; } + // OpenEntry, CreateEntry, and DoomEntry immediately return with + // ERR_IO_PENDING and will callback some time later with an error. + void set_force_fail_callback_later(bool value) { + force_fail_callback_later_ = value; + } + // Makes all requests for data ranges to fail as not implemented. void set_fail_sparse_requests() { fail_sparse_requests_ = true; } @@ -256,6 +266,7 @@ class MockDiskCache : public disk_cache::Backend { bool double_create_check_; bool fail_sparse_requests_; bool support_in_memory_entry_data_; + bool force_fail_callback_later_; // Used for pause and restart. MockDiskEntry::DeferOp defer_op_; diff --git a/chromium/net/http/proxy_client_socket.h b/chromium/net/http/proxy_client_socket.h index 1d3f2a8fef7..0a34d871190 100644 --- a/chromium/net/http/proxy_client_socket.h +++ b/chromium/net/http/proxy_client_socket.h @@ -19,7 +19,6 @@ namespace net { class HostPortPair; class HttpAuthController; -class HttpStream; class HttpResponseInfo; class HttpRequestHeaders; class HttpAuthController; @@ -34,10 +33,6 @@ class NET_EXPORT_PRIVATE ProxyClientSocket : public StreamSocket { // the response to the CONNECT request. virtual const HttpResponseInfo* GetConnectResponseInfo() const = 0; - // Transfers ownership of a newly created HttpStream to the caller - // which can be used to read the response body. - virtual std::unique_ptr<HttpStream> CreateConnectResponseStream() = 0; - // Returns the HttpAuthController which can be used // to interact with an HTTP Proxy Authorization Required (407) request. virtual const scoped_refptr<HttpAuthController>& GetAuthController() const diff --git a/chromium/net/http/transport_security_persister.cc b/chromium/net/http/transport_security_persister.cc index 74c7c93ac1e..ee788d81c66 100644 --- a/chromium/net/http/transport_security_persister.cc +++ b/chromium/net/http/transport_security_persister.cc @@ -292,7 +292,8 @@ bool TransportSecurityPersister::LoadEntries(const std::string& serialized, bool TransportSecurityPersister::Deserialize(const std::string& serialized, bool* dirty, TransportSecurityState* state) { - std::unique_ptr<base::Value> value = base::JSONReader::Read(serialized); + std::unique_ptr<base::Value> value = + base::JSONReader::ReadDeprecated(serialized); base::DictionaryValue* dict_value = NULL; if (!value.get() || !value->GetAsDictionary(&dict_value)) return false; diff --git a/chromium/net/http/transport_security_state.cc b/chromium/net/http/transport_security_state.cc index fe433909de1..b7a2bca7bf4 100644 --- a/chromium/net/http/transport_security_state.cc +++ b/chromium/net/http/transport_security_state.cc @@ -9,6 +9,7 @@ #include <vector> #include "base/base64.h" +#include "base/bind.h" #include "base/build_time.h" #include "base/containers/span.h" #include "base/json/json_writer.h" diff --git a/chromium/net/http/transport_security_state.h b/chromium/net/http/transport_security_state.h index 5e772fd78b5..48ccb74e2e1 100644 --- a/chromium/net/http/transport_security_state.h +++ b/chromium/net/http/transport_security_state.h @@ -28,7 +28,7 @@ namespace net { namespace ct { enum class CTPolicyCompliance; -}; +} class HostPortPair; class SSLInfo; diff --git a/chromium/net/http/transport_security_state_static.json b/chromium/net/http/transport_security_state_static.json index 8e37704a27d..51ac1ced6db 100644 --- a/chromium/net/http/transport_security_state_static.json +++ b/chromium/net/http/transport_security_state_static.json @@ -227,21 +227,6 @@ ] }, { - "name": "ncsccs", - "static_spki_hashes": [ - "LetsEncryptAuthorityPrimary_X1_X3", - "LetsEncryptAuthorityBackup_X2_X4", - "DigiCertGlobalRoot", - "DigiCertEVRoot", - "DigiCertAssuredIDRoot", - "AddTrustExternalCARoot", - "BaltimoreCyberTrustRoot", - "COMODORSACertificationAuthority", - "COMODOECCCertificationAuthority" - ], - "report_uri": "https://log.ncsccs.com/report/hpkp" - }, - { "name": "tumblr", "static_spki_hashes": [ "DigiCertEVRoot", @@ -818,9 +803,6 @@ { "name": "www.irccloud.com", "policy": "custom", "mode": "force-https" }, { "name": "alpha.irccloud.com", "policy": "custom", "mode": "force-https" }, { "name": "neonisi.com", "policy": "custom", "mode": "force-https" }, - { "name": "intercom.io", "policy": "custom", "mode": "force-https" }, - { "name": "api.intercom.io", "policy": "custom", "mode": "force-https" }, - { "name": "www.intercom.io", "policy": "custom", "mode": "force-https" }, { "name": "www.makeyourlaws.org", "policy": "custom", "mode": "force-https" }, { "name": "surfeasy.com", "policy": "custom", "mode": "force-https" }, { "name": "www.surfeasy.com", "policy": "custom", "mode": "force-https" }, @@ -4763,7 +4745,6 @@ { "name": "sumoscout.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sweetstreats.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sykepleien.no", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "synchtu.be", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tacticalsquare.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tazj.in", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tdelmas.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -5033,7 +5014,6 @@ { "name": "ys-shop.biz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "zooparadies.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "0paste.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "1km.ro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "2nerds1bit.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "403.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "acr.im", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -5241,7 +5221,6 @@ { "name": "maxwell-english.co.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mazz-tech.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mcc.re", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "mcgarderen.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mcpart.land", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "medirich.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "medo64.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -6818,7 +6797,6 @@ { "name": "tonage.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "toncusters.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "toomanypillows.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "tooolroc.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "topmarine.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tosteberg.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "toucedo.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -7313,7 +7291,6 @@ { "name": "mommelonline.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "monix.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "moonloupe.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "morganino.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "morningcalculation.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "moy-gorod.od.ua", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "msmails.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -7534,7 +7511,6 @@ { "name": "ts2.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ulmo.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "umidev.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "undernet.uy", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "upboard.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ur-lauber.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "usakitchensandflooring.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -8161,7 +8137,6 @@ { "name": "imusic.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "indusfastremit-us.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "indusfastremit.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "insighti.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "insighti.sk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "iprice.co.id", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "iprice.hk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -8240,7 +8215,6 @@ { "name": "mmonit.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mobal.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "monobank.no", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "morganino.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "moveek.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "movember.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mtg-tutor.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -8302,7 +8276,6 @@ { "name": "peoplesbankal.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pepperworldhotshop.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pethub.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "pharmgkb.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "philadelphia.com.mx", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "picoauto.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "picotech.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11279,13 +11252,11 @@ { "name": "bacontreeconsulting.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "azino777.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "badoo.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "azazy.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ballmerpeak.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bandb.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bangzafran.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "barrett.ag", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "baffinlee.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "bcswampcabins.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bancoctt.pt", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bcchack.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "barbate.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11322,17 +11293,13 @@ { "name": "booked.holiday", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bourasse.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bodrumfarm.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "boris64.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "boxing-austria.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "btio.pw", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "btcontract.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "brilliantbuilders.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "brigidaarie.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "bubulazy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "bubulazi.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "brefy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "boxpirates.to", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "businessloanconnection.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "budaev-shop.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "buhler.pro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "callhub.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11403,7 +11370,6 @@ { "name": "convergemagazine.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "creativeartifice.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cookiesoft.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "computersystems.guru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "comotalk.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "crumbcontrol.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "crtvmgmt.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11417,7 +11383,6 @@ { "name": "cross-view.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cuonic.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cup.al", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "danielheal.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "creativephysics.ml", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "dad256.tk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cujba.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11493,7 +11458,6 @@ { "name": "eintageinzug.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "elaintehtaat.fi", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "elemprendedor.com.ve", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "eit-web.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "elonbase.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "emi-air-comprime.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "endlessdiy.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11548,7 +11512,6 @@ { "name": "foreveralone.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "fourchin.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "flexapplications.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "forschbach-janssen.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "frickenate.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "fumiware.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "freebus.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11681,7 +11644,6 @@ { "name": "ivi.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "jan-cermak.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "jimgao.tk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "itcko.sk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "joedavison.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "joshuarogers.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "jetsetpay.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11883,7 +11845,6 @@ { "name": "newtonhaus.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "nicocourts.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "nikksno.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "niagaraschoice.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "nitropur.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "nicolasklotz.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "nicolasbettag.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11908,7 +11869,6 @@ { "name": "oh14.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ojls.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ons.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "onlinebizdirect.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "onearth.one", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "onarto.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "newline.online", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11934,7 +11894,6 @@ { "name": "overalglas.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "opensourcehouse.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "oxynux.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "partnercardservices.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "papa-webzeit.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pastenib.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "penguinclientsystem.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11946,7 +11905,6 @@ { "name": "phantasie.cc", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "perroud.pro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "perthdevicelab.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "pgpmail.cc", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "peterfolta.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pfolta.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "performancesantafe.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -11993,7 +11951,6 @@ { "name": "psncardplus.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "quail.solutions", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "radar.sx", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "r0uzic.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "qkka.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "psncardplus.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "qldformulaford.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -12011,12 +11968,10 @@ { "name": "refreshingserum.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ray-works.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "rayworks.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "recepty.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "refill-roboter.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "redra.ws", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "relayawards.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "rem.pe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "remitatm.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "res-rheingau.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "regionalcoalition.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "rentacarcluj.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -12032,7 +11987,6 @@ { "name": "rhapsodhy.hu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "rochman.id", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "rointe.online", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "rotozen.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "royalhop.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "rokort.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "rogue-e.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -12045,19 +11999,12 @@ { "name": "runawebinar.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "rr105.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "samraskauskas.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "s-mdb.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "saraleebread.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "sagsmarseille.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sagedocumentmanager.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "sanissimo.com.mx", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ruh-veit.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "saleslift.pl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "saba-piserver.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sangwon.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "saml-gateway.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "sandobygg.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "sandogruppen.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "saro.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sbirecruitment.co.in", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sansemea.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "samsen.club", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -12148,7 +12095,6 @@ { "name": "stigroom.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "studiozelden.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "svatba-frantovi.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "sumoatm.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tails.com.ar", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sv-turm-hohenlimburg.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "taravancil.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -13002,7 +12948,6 @@ { "name": "tocaro.im", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "toursandtransfers.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tracetracker.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "transport.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "trefpuntdemeent.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tronatic-studio.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tsaro.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -16332,7 +16277,6 @@ { "name": "tetrarch.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "studio-panic.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sudaraka.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "teamx-gaming.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "teamtrack.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "solariiknight.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "techace.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -16577,7 +16521,6 @@ { "name": "xn--werner-schffer-fib.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ylinternal.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "yourgame.co.il", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "xyndrac.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ytuquelees.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "youlend.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "vanderziel.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -16859,7 +16802,6 @@ { "name": "davidnadaski.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "customshort.link", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cultureroll.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "crediteo.pl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "curveprotect.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "devafterdark.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "customfilmworks.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -17956,7 +17898,6 @@ { "name": "yuzu.tk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "zlc1994.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "woufbox.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "zenycosta.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "worldsbeststory.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "yantrasthal.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "zefiris.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -18223,7 +18164,6 @@ { "name": "brooklynrealestateblog.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "benjamin-suess.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "btorrent.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "branw.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "berlin.dating", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "black-octopus.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bonqoeur.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -18724,7 +18664,6 @@ { "name": "europapier.rs", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "europapier.ba", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "europapier.hu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "francisli.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "foxterrier.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "feld.saarland", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "foo.fo", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -19433,7 +19372,6 @@ { "name": "mysqldump-secure.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "nadyaolcer.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "namereel.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "n-un.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "myepass.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "neatous.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mydebian.in.ua", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -19569,7 +19507,6 @@ { "name": "participatorybudgeting.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "paio2.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "piratesforums.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "pitchpinecapital.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "paulswartz.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "paypod.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "orro.ro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -19677,7 +19614,6 @@ { "name": "rc-offi.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "remedica.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "professors.ee", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "puurwonengeldrop.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pruikshop.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "robototes.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "questionable.host", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -20437,7 +20373,6 @@ { "name": "a-little-linux-box.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "8ackprotect.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "alicialab.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "adamek.online", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "4u2ore.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "akalashnikov.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "advokat-romanov.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -20853,7 +20788,6 @@ { "name": "crashsec.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "commoncode.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "childrendeservebetter.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "comfintouch.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "citylights.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cinq-elements.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cpy.pt", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -21017,7 +20951,6 @@ { "name": "csgoshifter.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "demarle.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "dracisvet.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "earvinkayonga.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "educationevolving.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "dprb.biz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "doli.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -21074,7 +21007,6 @@ { "name": "dungeon-bbs.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "elektro-woerdehoff.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "energyled.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "enginsight.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ericjohnltd.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "erwinvanlonden.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "erinn.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -21228,7 +21160,6 @@ { "name": "funideas.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "froggitt.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "fritteli.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "freend.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "furnfurs.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "freebetoffers.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "fstfy.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -21374,7 +21305,6 @@ { "name": "greatsong.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "helpmij.cf", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "holoxplor.space", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "harschnitz.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "haus-garten-test.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "hardyboyplant.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "heckelektro.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -22230,7 +22160,6 @@ { "name": "projectnom.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "queryplayground.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "project-rune.tech", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "oblast45.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mrning.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pollet-ghys.be", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "quantumwebs.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -22260,7 +22189,6 @@ { "name": "rbti.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "recreation.gov", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "pfeuffer-elektro.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "proteinnuts.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ps4all.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "rachelreagan.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "qrpth.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -22666,7 +22594,6 @@ { "name": "t4x.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "thailandpropertylisting.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tacklog.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "tepitus.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "thewp.pro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "teknotes.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "technotonic.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -23113,7 +23040,6 @@ { "name": "aux-arts-de-la-table.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "avticket.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bacimg.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "backgroundchecks.online", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "badseacoffee.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bagiobella.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bakkerinjebuurt.be", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -23600,7 +23526,6 @@ { "name": "lickthesalt.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "lihaul.dnsalias.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "lily-bearing.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "lindy.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "litcomphonors.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "litemind.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "lithan.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -25065,7 +24990,6 @@ { "name": "deepvision.com.ua", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "defrax.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "defrax.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "deftek.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "deftnerd.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "degen-elektrotechnik.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "deinewebsite.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -25271,7 +25195,6 @@ { "name": "equalcloud.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "equipedefrance.tv", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "er.tl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "erikwalther.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "erinaceinae.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "eriser.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "erotic4me.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -26510,7 +26433,6 @@ { "name": "mstdn.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mstdn.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mstdn.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "mstdn.onl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mtb.wtf", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mtd.ovh", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "mtdn.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -26788,7 +26710,6 @@ { "name": "panpsychist.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "panzer72.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "papakatsu-life.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "paperhaven.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "parachute70.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "paradise-engineer.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "paradise-engineers.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -28526,7 +28447,6 @@ { "name": "bentphotos.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "biaggeo.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "arfad.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "beyond-infinity.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "beraru.tk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "birdbrowser.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "bestwarezone.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -28893,7 +28813,6 @@ { "name": "crunchy.rocks", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "congobunkering.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "cuongthach.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "crows.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "currynissanmaparts.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "customwritingservice.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "chasafilli.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -29097,7 +29016,6 @@ { "name": "dugnet.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "dugnet.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "dontpayfull.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "dugnet.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "droidim.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "dugnet.tech", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "dr-becarelli-philippe.chirurgiens-dentistes.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -29545,7 +29463,6 @@ { "name": "geneve-naturisme.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "gilmoreid.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "govtjobs.blog", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "grandefratellonews.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "gmx.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "gmx.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "groentefruitzeep.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -29586,7 +29503,6 @@ { "name": "gritte.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "haze.sucks", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "goatcloud.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "grmp.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "greggsfoundation.org.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "gloomyspark.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "gugert.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -29962,7 +29878,6 @@ { "name": "kissgyms.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "kosaki.moe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "kevyn.lu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "kanzlei-wirtschaftsrecht.berlin", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "kogak.ninja", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "katata-kango.ac.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "konosuke.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -31558,7 +31473,6 @@ { "name": "tsumi.moe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "travel-to-nature.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "tradietrove.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "tniad.mil.id", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "trekfriend.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "troedelhannes.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "thelostyankee.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -34201,7 +34115,6 @@ { "name": "xsstime.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "xn--cckvb1cwa0c5br5e2d2711k.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "yu.vc", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "yunzhan.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ying299.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "zeloz.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ying299.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -34490,7 +34403,6 @@ { "name": "apn-dz.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "aquarium-supplement.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "arcenergy.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "arcobalabs.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "arian.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "artsinthevalley.net.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "atlantahairsurgeon.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -35072,7 +34984,6 @@ { "name": "highlatitudestravel.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "hill.selfip.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "hippo.ge", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "hlacosedora.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "hoast.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "hoflerlawfirm.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "holistichealer.in", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -35177,7 +35088,6 @@ { "name": "magnoliastrong.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "makemejob.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "marti201.ga", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "marykatrinaphotography.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "matomeathena.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "matthewtester.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "maxhorvath.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -35611,7 +35521,6 @@ { "name": "mysize-condooms.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "nabaleka.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "naturalspacesdomes.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "newbietech.cn", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "nextrobotics.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "novelabs.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "o-sp.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -35628,7 +35537,6 @@ { "name": "resoundpro.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "risiinfo.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "royalcitytaxi.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "royalcitytaxi.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sahb.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "samaritainsmeyrin.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sat7a-riyadh.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -35946,7 +35854,6 @@ { "name": "chocolatier-tristan.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "chowii.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "christian-liebel.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "christiancleva.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "christianfaq.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "christopher-simon.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "chupadelfrasco.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -36075,7 +35982,6 @@ { "name": "domengrad.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "domian.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "dominik-schlueter.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "donnoval.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "donpaginasweb.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "donzool.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "doopdidoop.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -36115,7 +36021,6 @@ { "name": "edenvalerubbleremovals.co.za", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "edhesive.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "edstep.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "eggert.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ejusu.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ekobudisantoso.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "eldrid.ge", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -36984,7 +36889,6 @@ { "name": "rwky.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "ryzhov.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sabine-forschbach.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "sabineforschbach.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "saclier.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "sacred-knights.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "saint-astier-triathlon.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -37570,7 +37474,6 @@ { "name": "datenschutzhelden.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "dekasiba.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "dellipaoli.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, - { "name": "dentfix.ro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "depotsquarekerrville.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "depthe.gr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, { "name": "di2pra.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true }, @@ -38976,7 +38879,6 @@ { "name": "leveluprails.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lidel.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lifemarque.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "lifeventure.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lignemalin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lilysbouncycastles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "limberg.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -39095,7 +38997,6 @@ { "name": "multikalender.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "muusika.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mvandek.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "mxlife.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "myjumparoo.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mymun.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "myowndisk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -39906,7 +39807,6 @@ { "name": "fashion24.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "feuerwehr-heiligenberg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fialat.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "figinstitute.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "finch.am", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "findthere.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fireworksshowvr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -40117,7 +40017,6 @@ { "name": "monkeytek.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "moonkin.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "moorewelliver.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "moppy.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "morespacestorage.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "moshwire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mp3donusturucu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -40837,7 +40736,6 @@ { "name": "salearnership.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sanitairwinkel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sauenytt.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "saumon.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "schwedenhaus.ag", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "scifi.fyi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "scimage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -41402,7 +41300,6 @@ { "name": "robotattack.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rockthebabybump.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rubenkruisselbrink.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "ruri.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rybox.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "safeinfra.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "safesecret.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -42553,7 +42450,6 @@ { "name": "hf-tekst.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hf51.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hibari.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "hideout.agency", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hightechgadgets.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hipnoseinstitute.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hireprofs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -42719,7 +42615,6 @@ { "name": "konventa.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kopio.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kopjethee.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "koppelvlak.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "korben.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kotly-marten.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kouten-jp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -44099,7 +43994,6 @@ { "name": "latable-bowling-vire.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "latiendadelbebefeliz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "latintoy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "launayflorian.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "leadinfo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "led-tl-wereld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ledscontato.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -44314,7 +44208,6 @@ { "name": "rogoff.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "roka9.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "roksolana.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "roof.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "room-composite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rossclark.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rotek.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -45208,7 +45101,6 @@ { "name": "serviziourgente.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sestra.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "shadowsocks.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "shafou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "shakerwebdesign.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "shankangke.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "shippingbo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -46175,7 +46067,6 @@ { "name": "wpsec.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wristreview.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wrp-timber-mouldings.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "wtwk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "wyo.cam", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "x-one.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "xia.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -47413,7 +47304,6 @@ { "name": "mapeo.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "marclay.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mariereichl.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "marketinggenerators.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "marshallwilson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mateuszpilszek.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mattatoio.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -47972,7 +47862,6 @@ { "name": "faraonplay8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "favirei.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "feelmom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "feuerwehr-offenbach-bieber.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fibretv.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "fibretv.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "files.from-me.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -49481,7 +49370,6 @@ { "name": "kolcsey.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kotonoha.cafe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kovuthehusky.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "kryha.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ksk-agentur.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kuops.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lacetsfun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -50335,7 +50223,6 @@ { "name": "lunanova.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "luteijn.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "luteijn.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "mailum.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "makera.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "maketheneighborsjealous.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "malscan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -52247,7 +52134,6 @@ { "name": "portugal-a-programar.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pour-la-culture-aulnay.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "pouwels-oss.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "prettynode.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "priorityelectric-agourahills.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "priorityelectric-calabasas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "priorityelectric-camarillo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -52300,7 +52186,6 @@ { "name": "sadev.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sadou.kyoto.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "safepay.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "samip.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sanantoniolocksmithinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "santensautomatics.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sap-inc.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -52637,7 +52522,6 @@ { "name": "hansen-kronshagen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hearty.ooo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "henchman.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "hex.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hikarukujo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hilde.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hildegardis-schule.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -53421,7 +53305,6 @@ { "name": "nakitbonus2.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nansa.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "narardetval.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "narduin.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "nature-shots.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "natureword.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ncdc.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -53563,7 +53446,6 @@ { "name": "smart-media-gmbh.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smartwoodczech.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smcbox.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "smith.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smplr.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sms.storage", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "snowyluma.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -54023,7 +53905,6 @@ { "name": "romatrip.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ronniegane.kiwi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rossmacphee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "rustralasia.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "saastopankki.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sac-shop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sacrome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -54529,7 +54410,6 @@ { "name": "electricfencingballito.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "elektro-doerr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "eluvio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "elvn.tokyo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "embudospro.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ememsei.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "emvoice.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -55184,7 +55064,6 @@ { "name": "sistemlash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "skincare-note.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sky-universe.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "skyem.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "sleeps.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "slim-slender.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "smakassen.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -55737,7 +55616,6 @@ { "name": "kersmexico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "keyhomechecker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kinnettmemorial.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "kirito.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kiwi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kloudboy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "krazyboi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -57963,7 +57841,6 @@ { "name": "graphic-schools.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "greatskillchecks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "greenwaylog.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "groundlevelup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gtxbbs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "gustom.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "hakkasangroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -58150,7 +58027,6 @@ { "name": "media-service.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "mediarithmics.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "medical-assistant-colleges.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "medik8.com.cy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "meditadvisors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "meesteresmisty.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "meps.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -61044,7 +60920,6 @@ { "name": "cnnet.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cobaltis.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "code-vikings.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "codebreaking.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "codehz.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "codersatlas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "coldcardwallet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -61481,7 +61356,6 @@ { "name": "irish.radio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "irishradioplayer.radio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "irkfap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "isaac.world", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "isbaseballstillon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "isg-tech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "isolta.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -62262,7 +62136,6 @@ { "name": "toutelathailande.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tower.land", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "toycu.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "toysale.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "trackfeed.tokyo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "tradlost-natverk.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "trafficmgr.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -62686,7 +62559,6 @@ { "name": "qkzy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "qlcvea.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "qpcna.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "qtap.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "quadra.srl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "rachurch.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "radiobox.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -62815,7 +62687,6 @@ { "name": "w88info.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "w88xinxi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "webhost.guide", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "webpulser.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "webwelearn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "welovemaira.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "werbe-markt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -63024,7 +62895,6 @@ { "name": "correcthorse.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "country-creativ.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ctr.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "cybergates.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "cyberlegal.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "dailyroverr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "danieln.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -63888,7 +63758,6 @@ { "name": "bani99.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bankanswers.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bariumoxide.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "batkave.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "baumkuchen-aus-dresden.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "baza-gai.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "bbsec.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -65330,7 +65199,6 @@ { "name": "kiwihub.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "klautshop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kongress-hostessen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "kupiclub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kupleno.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "lado.ltd", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "ladotech.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -65662,7 +65530,6 @@ { "name": "ji0vwl.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "joona.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "justinfreid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, - { "name": "kairostecnologia.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "katyusha.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "keian.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "kiknudes.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, @@ -65877,6 +65744,2501 @@ { "name": "zstu.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zumub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, { "name": "zzbnet.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "021002.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "077768.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "081115.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "0x41.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "161263.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "162361.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "177603.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1android.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1gp.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1zombie.team", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "22delta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "411quest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "4hmediaproductions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "62314.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "662607.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "6bwcp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "8212p.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "877027.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "908.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "929349.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "9hosts.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "a-pro-pos.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acchicocchi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ace-aegon.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acg1080.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adnmb1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aimd.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alhost.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alloutofgum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "allrad-buck.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "almamet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alonas.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "americanindiancoc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ames.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amj74-informatique.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amyria.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "android-tv.3utilities.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "androzoom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "appspace.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arslankaynakmetal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "asmeets.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "auto1.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "autolawetawroclaw.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "avtek.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aylavblog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bagwrap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "banderasdelmundo.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "barneveldcentrum.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "basics.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bawbby.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bazinga-events.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bcubic.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bebeautiful.business", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "beherit.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestlooperpedalsguide.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bezlampowe.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bitcert.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blackmagicshaman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blogit.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "briograce.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "buck-hydro.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "burakogun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "burakogun.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "burakogun.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "burakogun.net.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "burakogun.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "burzum.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cabanactf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "camping-le-pasquier.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "canopy.ninja", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "casinoportugal.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cclasabana.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "charlylou.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chemco.mu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ciclista.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "citywidealarms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clo.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cloud255.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "codeandsupply.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coincircle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coisabakana.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "colcomm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coldiario.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "comoaliviareldolor.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cooksecuritygroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "creativ-impuls-dekorateurin-muenchen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crismatthews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crypkit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cslaboralistas.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cuegee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cumtd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "d4fx.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dadadani.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "danads.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dapianw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dare.deals", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "darf.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dead-letter.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "decorumcomics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deepspace4.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deplorablesdaily.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "depositart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "derekbooth.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "developer.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dickord.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dictionarypro.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "directoriostelefonicos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "divineglowinghealth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "donetsk24.su", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dotesports.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dpsg-hohenlinden.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drros.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dubstep.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e-webos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eallion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eblog.ink", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "educacionvirtual.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "educateyourskin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ekaplast.com.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ekouniejow.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "electricgatemotorglenvista.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eosolutions.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "esteladigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estraks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "estudiaryaprenderingles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "excaliburtitle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "excess-baggage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eyemagic.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "facingbipolar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fantasysportsnews.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "farleybrass.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fb-feed.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "feross.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "festicle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "filehash.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fili.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "firefense.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fletcherdigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flexbuildingsystems.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flowersquito.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fonzone.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foreverclean.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "forself.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "freertomorrow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "friedzombie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "frsnpwr.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fruityfitness.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gakdigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gamerwares.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "garbagedisposalguides.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gestsal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "giftlist.guru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gpyy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "groundmc.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gurunpa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gyume.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "h33t.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "harelmallac.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "harelmallacglobal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hartkampforkids.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hawawa.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healthyrecharge.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "heikohessenkemper.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "helpwithinsomnia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hokung.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hostco.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hsg-kreuzberg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hugonote.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "icdp.org.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ictussistemas.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iinf.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iiyama-bg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ilmainensanakirja.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "indigolawnscape.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "innovere.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "instafuckfriend.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "instahub.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "institutomaritimocolombiano.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "internationalstudentassociation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ishland.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "isif-ostewg.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "islamicmarkets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "j0e.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jamestmartin.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jerrysretailstores.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jix.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "joyfulhealthyeats.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "julestern.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jwhite.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kalashcards.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "keeckee.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "keeckee.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kiasystems.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kileahh.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "klop.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "komp247.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kosmos.org.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lares.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "launcher-minecraft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leafland.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "left-baggage.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "legabot.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leszonderstress.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "linasjourney.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "linkst.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "linkyou.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lippu1.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lisahh-jayne.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "living-with-outlook-2010.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "localegroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ltlec.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ltlec.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ltmw.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "m2tm.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mailhardener.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mainhattan-handwerker.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "malibumodas.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mantuo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "manwish.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "maorx.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "markhoodwrites.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "marron-dietrecipe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "masterpassword.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "matematyka.wiki", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "matteobrenci.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "matthi3u.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mcfi.mu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "melodict.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mentecuriosa.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "michilaw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mindmax.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mionerve.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mionerve.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "misterseguros.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mmgal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mostcomfortableworkboots.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "motogb.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "motospaya.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mralonas.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mrdatenschutz.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mte.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mukyu.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "murphycraftbeerfest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mvbug.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mycreditunion.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mypt3.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nailsart.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nan.ge", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "napkins-wholesale.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "napkins-wholesale.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "napkins-wholesale.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "napkins-wholesale.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "napkins-wholesale.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "napkins-wholesale.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nasosvdom.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nauris.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ncua.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nebras.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "networkhane.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "new-vip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "newfoundland-labradorflora.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nextcloud-miyamoto.spdns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nilgirispice.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nonx.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nook.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "northebridge.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "novengi.mu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "noxx.global", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "obec-krakovany.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "olandiz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "olivemultispecialist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ordbokpro.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "outdoorchoose.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "outdoorhole.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oxz.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "p5on.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paya.cat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paydigital.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "perevedi.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pglaum.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pharmaquality.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "phrazor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pinkmango.travel", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pixeoapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "platinapump.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "podipod.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "postandfly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "powersergdatasystems.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "powersergdynamic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "projectmakeit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "promuovi.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "proximoconcurso.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ptasiepodroze.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qklshequ.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qxzgssr.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rbuddenhagen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reby.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "redmangallpsychologists.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "revivalsstores.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "richbutler.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "riddler.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ristisanat.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "robgorman.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ruhnke.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rvsuitlaatdelen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saatchiart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sabbottlabs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "safungerar.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scevity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "searchpartners.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "securevideo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seemomclick.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seht.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sektor.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "selber-coden.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sendingbee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "senorporno.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "senseict.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "servetten-groothandel.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "servietten-grosshandel.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "servietten-grosshandel.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "servietten-grosshandel.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "servietten-grosshandel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "serviettes-et-plus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "servilletas-de-papel.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "servilletas-de-papel.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "serwetki-papierowe.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shavit.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shdsub.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shiny.gift", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shippinglabel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shopdongho.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sietejefes.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "simulping.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sirihouse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skillside.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skinandglamour.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skinwhiteningoptions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skorpil.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smaltimentoamianto.campania.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smartphone-pliable.wtf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "snwsjz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "socialmedia-manager.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sonaraamat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "southwesteventhire.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sozialstation-ritterhude.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spalnobelyo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spanch.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stgabrielavondalepa.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stoerevrouwensporten.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stretchmarkdestroyer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "studio-n.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suchem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "superenduro.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suppwatch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "svenrath.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sweetenedcondensed.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "systemctl.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tandartszilverschoon.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tease.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "techlr.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tedxyalesecondaryschool.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "telsu.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "testeri.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thea-team.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thealonas.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theappliancedepot.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thecandyjam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thedermreport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thefriedzombie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theseoplatform.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thesetwohands864.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thoxyn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tomorrowmuseum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "topyachts.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tovaglioli-di-carta.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tql.plus", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tracker.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tradexport.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tradexport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "transferbags.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trinitycorporateservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "troxal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "truecosmeticbeauty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trustees.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tryplo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tryplo.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tryplo.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tryplo.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "turingmind.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tusmedicamentos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "twoleftsticks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "u-chan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "u29dc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uitvaartvrouwenfriesland.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ukrn.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ummati.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unicmotos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unkn0wncat.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "upcloud.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uscis.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "valimised.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "valuehost.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "veggiesecret.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "velassoltas.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vexsoluciones.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "virtualizy.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vista-research-group.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "viviendy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "w3n14izy.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "weymouthslowik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wijnimportjanssen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "witch-spells.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wordnietvindbaar.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "worldsy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wsp-center.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ww-design.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wzilverschoon.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xavierdmello.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xgwap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xi.ht", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn-----6kcbjcgl1atjj7aadbkxfxfe7a9yia.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--12c3bpr6bsv7c.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--3st814ec8r.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--3stv82k.hk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--3stv82k.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--bersetzung-8db.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--durhre-yxa.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yachtlettering.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yateshomesales.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yesornut.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yuhindo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zadania.wiki", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zeno-dev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zhang.ge", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zhina.wiki", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zistemo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zxssl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1236.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "162632.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1plus-agency.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3d1t0r4.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3xm.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "42l.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "4o5.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "4x4-27mc.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "4x4coatingen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "7milesglobal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "80bin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ac-elektro.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "accessgaragedoors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acinq.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "admind.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adv.cr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adventurecreators.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "airport-charlotte.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aivan.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amir-heinisch.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "andrewtasso.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "apviz.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "archivium.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ardadanal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arnaudlanna.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "asylbarn.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aulica-conseil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "avelinodiaz.gal", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "baileybae.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bee-removal-dublin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "benediktgeissler.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bereginy.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bettercareclinic.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bhserralheria.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "biomathalliance.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bjoe2k4.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blopezabogado.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bluicraft.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bluinet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bodemplaten4x4.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "boutoncoupdepoing.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bryantzheng.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bt780.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "budolangnau.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bytegoing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "caffeinefiend.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "camshowdir.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "camshowhub.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "camshowstorage.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "camshowverse.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "car-insurance-quotes.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cardioc.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "casjenprome.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chainels.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chateroids.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cheem.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chimho.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cinicloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ciniticket.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cloneuniverse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cna5.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coffeist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "complexorganization.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "continuumrecoverycenter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "contunda.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "conxcon.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crimbotrees.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cristoraciones.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cxfinancia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cyberdean.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "d9c.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "damianus.hr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dashdrive.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "data.bayern", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dermopigmentista.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diethood.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "distinctdesign2009.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diysec.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dizzie.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dizzieforums.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dnastatic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "doc.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "doeren.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dommelschbierfusten.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "domop.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "domop.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "domovitae.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "domovitae.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "donation.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dormkitty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "draadloos-besturen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drphillipsmwc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drumlines.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "duesterhus.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "edas.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "edv-ringhofer.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ekeblock.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ekpj.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elitepaintingsa.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elon-musk.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "emergeandsee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "energysolutionstech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "esu.wiki", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "etnoria.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "evoting-test.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "farvisun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "feestbierfusten.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "firstnetworksouth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "firstsecurity.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foroaranda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foxbnc.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foyer-laique-segre.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "frankfurt-coworking.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "frietzombie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "funkfernbedienung-industrie.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "funknotaus.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "galvingao.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gitecolombedesbois.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "githubapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "goeb.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "goeb.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gooroosmarketplace.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "grid.studio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hammerpondkennels.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "handicaps-ensemble.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hansgoes.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hansminten.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hauora.fyi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "healike.hk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hemkoll.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "heretic-guild.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hguandl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "historiasdepueblo.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hktech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homeland.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hoxo.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hrebecek.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iinix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ikparis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "industrial-remote-control.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "infoteka.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "infravoce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "intellihr.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "isdr-bukavu.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jaamaa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "janz.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jcvidroseespelhos.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jeremy.codes", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "joelving.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jogjacar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jungidee.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "junta.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "juyunce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kappharn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "karenwillisholmes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "khg-orchester.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kibbesfusion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kindesfreude.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kolektivbrand.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "krrn.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kt3i.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kys.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "laceysfarm.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lagranmoon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leaseourthings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "legoutcheznous.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "legyenkianegykereked.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leignier.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lenostech.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lepourquoiducomment.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "les-explos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "letsprint3d.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "liaronce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lieren4x4.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "life29.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lifewithdyna.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "littlebirds.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lkbk.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loca-voiture.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "locald.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loqyu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lovebeingsexy.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lowbidders.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lucid-reality.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "luda.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ludum-polus.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "luxecalendar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "machcz.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "malkoun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mandiblackburnphoto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mathes.berlin", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "medsblalabs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "meidev.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "melefo.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "minapin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "minhyukpark.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "miniaturepets.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mirrordream.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mobl.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moego.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moki.org.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "monerogamez.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "monitoringd.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mozilla-hispano.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mpu-ibbi.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mrhee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "muffs.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mussalains.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mxdvl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mycamshowhub.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mystagic.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "neat-patch.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "neckbeard.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nelflex.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "neosey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "neppglobal.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "newflavor.design", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nishimebistro.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nothingprivate.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nowarning.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ntcp.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "okada-touki.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "opinio.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "opus-consulting.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "overnightglasses.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pandaltd.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "parnizaziteksasko.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "patrol-x.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "payments.gy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pc-warriors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pc28yc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pcmobile.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "petaouchnok.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "petrsvec.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "phils1990.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "phographer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "plantdaddie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "practixdevelopment.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "praderarestaurant.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "prajwal-koirala.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "praxistipp24.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "premierdisco.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "premiermaldives.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "puertasautomaticasgi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "quaxio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "queropescar.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "radiocommande-industrielle.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rajastore.ma", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ranasinha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ravenrockrp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reactivemarkets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reformation.financial", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reitstall-goettingen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "relvan.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "remeb.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "remedyrecoverymat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "riskcategory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ristorantesamarkand.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "robertsonsalts.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "robsalmon.me.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rp2018.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "s92.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "s92.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "safetyrange.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sajjadzaidi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saksonski-szlak-parowozow.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sancdz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sandrabernardo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scalpel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "schoenstatt-fathers.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sestolab.pp.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sharecrypted.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shelike.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shellcode.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shimonfly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shiqi.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shiqi1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoes-mori.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sich-fight.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sigcafe.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "simonmanuel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sipyuru.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sistemhane.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sitanleta.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sloanrealtygroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "socialtraderpartner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sofgen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sos.vg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sos.yt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "speeder.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "speeders.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spirit-of-sahara.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ssld.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "steam-route-saxony.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sticky.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stmarkcharlotte.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stoneproperty.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stopoverconnections.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stopthinkconnect.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suncity288.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suncity818.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "surmountsoft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sweetbabyjesus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "symposium.beer", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "teamtmgb.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "techgadgetry.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tekanswer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "termee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tessierashpool.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "texasabrasiveblasting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tharuka-app.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tharuka.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tharuka.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thebiggive.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thehardylawfirm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theshots.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thetassos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tinapoethe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tipocloud.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "travelmexico42.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trueseeing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tubebegana.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "twmartin.codes", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tziyona.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uns.ac.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unti.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unusedrooms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vairuok.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "verlagdrkovac.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "view-page-source.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vincent-haupert.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vitlproducts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vnctdj.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vsoy.co.th", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vvave.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "waterseal.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wayuanma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wbinnssmith.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webetnet.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webgeneric.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webgeneric.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webgeneric.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webhopp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webstaff.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webtoro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "weedelec.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "weeka.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "weknowhowtodoit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "weltderangebote.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "whatsapp.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wyatttauber.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xgadget.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xms66.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--12cg9bnm5ci2ag9hbcs17a.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--pn1am9c.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yogaemmental.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "youhabitat.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yourpersonalfrance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ypfr.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yunsoupian.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yuucchi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zeit.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zstgmnachod.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "intercom.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "06804.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "100k.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "136824.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "161233.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "182162.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "191090.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "19qq.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1hc.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1v9.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "22d.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "321132.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "338393.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3gdh.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "502312.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "621162.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "622812.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "668825.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "676812.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "709129.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "721172.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "797715.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "877791.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "8821ks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "8889ks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "8898ks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "998081.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abjay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "accreditamento.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "accrosoft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "achat-volets-roulants.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "addistribution.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "agenciamseo.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ak47-miyamoto.spdns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alabordage.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alfredapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "altijdleroy.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "altijdleroy.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amleather.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "anarajaoui.ma", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aoe9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aptumseguros.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arabhardware.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arcobalabs.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "artacadia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "asemanhotel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "astropaykasa.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "atinylittle.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aviationweather.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "avnavi.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bagnichimici.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "banland.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "baranhotel.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "barcelonapremium.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "barcelonapremiummini.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "belle-lingerie.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "beratungswelt.dvag", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bestinsider.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bgbaby.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bintangpiaggi.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blackhawktreeinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bomboniere.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "boosman.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "boosmanpoolservice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bpreguica.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bpvboekje.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "br-miyamoto.spdns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "buerger-lenke.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cacd.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "calzadonline1-latam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "calzadonline1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cambuslangharriers.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cannaffiliate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "carlocksmithcarrollton.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "carplus.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "casaamor.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "castellannenberg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "castlemail.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cchen.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "centrepointorguk-dev.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cert.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "challengeclothing.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "checkmyhttps.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chrissmiley.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "civey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "claudiolemos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clav1d.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cloud10.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cluj.help", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coeus.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coker.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "collegesecretary.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "continental-zermatt.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "contourheating.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "controllertech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cookiee.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cradle.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crowdspire.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "current-usa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cyberdiscoverycommunity.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cyraus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "davethom.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "denkeandersblog.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "derpy.pp.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "desentupidorapernambucana.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diabetesblog.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "doggo.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "domop.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "doughseeker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "downtownstevenspoint.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dreamboxpro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drewzar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dsmnet.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dstvinstallglenvista.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dstvinstalljohannesburg.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eenvren.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eenvxing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "effer.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eftopia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ehcommerce.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elejordemarketingconsultancy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elib.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "emo-poris.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "empregosrj.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enbulleiugnen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "energygenie.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enforcement-trends-dev.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enforcement-trends-test.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enforcement-trends.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "engrish.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enlightenedmind.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "enxadahost.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "erik-stomp.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "erikatanithphotography.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escortlistings.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escortlistings.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escortlistings.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escortlistings.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escortlistings.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "est-it.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "esthernariyoshi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "etwalldentalpractice.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "everlastingoak.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "expertnews.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "expressglobal.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fabrykowski.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "factorit.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fashiontrendsetter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "firemist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fitrate.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fizzgi.gs", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foodlist.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "freebsdbrasil.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "freespot.mobi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "friedstechnology.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "friedstechnology.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "friedstechnology.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "friedzombie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "friedzombie.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fskounoike.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fuciam.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fukata.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fun-fan.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "funkazoid-radio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gaddini.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gajowniczek.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gamerepublic.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "geekyquiz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gornergrat-kulm.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "govsurvey.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "grazitti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haaksmadehaanuitvaart.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haarigerrattenarsch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hagskold.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hansgoes.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hansgoesit.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "happychat.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "harrisconsulting.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "herba-belgie.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homecompost.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "horgenberg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hummingbird.services", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "huoqibaike.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hydradigital.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hypothesis.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iamlife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibcl.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibericarbenet.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibericarcuzco.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibericarcuzcomini.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ijinus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "imaginationpathway.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "impossible.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "impossible.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "impossiblefitness.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "impossiblehq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "impossiblenutrition.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "impossiblex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "impresadipulizia.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "imprezzor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "infomasx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "inscribe.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "internetnz.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "intranet.dvag", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "intres.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "inyourowntime.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "inyourowntime.zone", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iondrey.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "istitutoricci.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "j605.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jackjack.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jpph.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "julian-post.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "k0.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kagucho.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kb3030.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kdcp.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "keepleft.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kevertje.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "keysofart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "khojirdesign.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "khorne.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kidsdaysout.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kordamed.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kpopsource.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ks626.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "la-laitonnerie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lawlessenglish.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lawlessfrench.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lawlessspanish.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lecannabiste.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ledwereld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lenalio.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "letshome.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lmsuitespagna.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lockoutgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loliblogs.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loliblogs.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loliblogs.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loliblogs.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lolifamily.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lolifamily.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lolifamily.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lolifamily.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lq.hr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ltlec.services", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "luv.asn.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mahler.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mailman.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "margatroid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "markf.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mascotarios.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "massage-well.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mdi-wolfsburg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mediafart.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "meineit.dvag", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mengliangyun.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "merloaded.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "miaomiao.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "michalinastrzyz.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mihijoesdislexico.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mikeandersondj.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "miniverse.social", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mivzakim.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mivzakim.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mivzakim.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mivzakim.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mivzakim.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mochizuki.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mocking-bird.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moesif.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mopxing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "motmplus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "movewellapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mujemail.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mystia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "netsecma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "networkofarts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "newdimensioninterlock.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "newspiritfilms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nextiva.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nextos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nicholasruddick.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nootroic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "noteboat.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nsoft.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "obzoroff.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "octomist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "olgcc.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "olofsson.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onestop-study.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onlylibya.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onore.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "openresearch.amsterdam", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "opt.ninja", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "orchids.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "our-box.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paleo.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paleodietfoodlist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paleodietrecipes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paleorecipepro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "paleoso.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "payment-express.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pgwap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "playmei.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pourmoi.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "princefamilylaw.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "privateservice.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "propshub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "prostoporno.video", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ptrt.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pulseroot.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "quarticon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qxzg.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "raccoon.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reissnehme.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rentta.fashion", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "resepi.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rhycloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rhymc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "riffelhaus.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "riptoforex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "robin.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rsarchive.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rsarchive.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ruimarques.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "s92.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "said.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saitoh-atsuko.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "samalderson.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sarella.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "savantic.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saveonkitchens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sbblog.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sdrive-gutachter.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sensor-dream.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "septs.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sharks.football", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shcode.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shoppingandreviews.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sht.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sia.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "signaconsultoria.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skux.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sl-informatique.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "slepsluzbabeograd.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "slobrowink.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "soumya.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spanishfox.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "speeders.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spikar.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "srpx.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "startablog.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "startmail.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stavnager.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stdemianabookstore.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "studiodentisticomasi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "surefleet.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "swi.sytes.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "takipone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tech-ninja.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "teetje-doko.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "telemessage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "terrorismattacks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "terrybutler.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "textbrawlers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tgbabyzoo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thconsulting.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thebiglaskowski.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theboss.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thefamilygarrison.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thefriedzombie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thefriedzombie.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thenine.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thepeoplesdata.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thepeoplesdata.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thisistranquility.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thumbsupcandy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "timetastic.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "titanplumbingservices.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "topstore.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "traha.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tulsaworkshop.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tupass.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tw-hosting.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tyroremotes.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uberactivist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ultimatepaleoguide.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ungelektro.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vacancyfiller.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "venten.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vernis-marins.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vinciladislessia.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "virgiliocervantes.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "visionduweb.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "visualgnome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "volubilisplus.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wageverify.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webhosting4u.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "websize.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "weissborn.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "westondenning.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "whitehouse.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wildcardcorp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wildcardfederal.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wugniu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xrbox.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yachting-home.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yakmail.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yangruixin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yiff.forsale", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yourantiquarian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yuncaioo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zermatterhof.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zwergenfeste.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "087010.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "098955.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "0akarma.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "10giant.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "130497.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "133846.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "158306.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "159ks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "162263.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "163132.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "188198.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "1db77.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "22txc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "26004.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "2melo.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "376557.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "377813.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "555w.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "617020.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "6hzx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "701605.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "85383838.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "88881.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "8balls.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "939394.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "a-bm.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aaronfurtado.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "acefreightco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adamgibbins.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adc64.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "administratiekantoorblom.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adrianobarbosa.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "albilaga.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "allseasonswaterproofing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "angeletakis.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "anthonyellis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "apdfawl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arjan.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arjansteevels.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "artozoul.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ascpaphilatelie.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "asilo.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "augenlaser-chemnitz.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "augenlaser-dresden.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "augenlasercenter-dresden.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "augenlaserzentrum-dresden.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "augenlaserzentrum-dresden.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "autobella-hurtownia.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "autosaan.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aveclunettesoleil.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "baleen.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "balmeo.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "barsgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "beckyhirstconsulting.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bentinata.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bighouse-events.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bjoernengel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bjoernengel.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bluemarmalade.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bwhbwh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bwhbwh.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cakirlarshipyard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "camelliaflowers.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "camping-landes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "campsoulfestival.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "canalecontracting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "capbig.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "catherinesofpartick.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cdkeyprices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "celestebonito.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ceramica.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chaizhikang.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chargersdirect.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chordify.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chrisspencermusic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "citizensgbr.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "classic-yacht-charters.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cna5.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cockedey.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "comoculosdesol.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "conocchialidasole.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "conquer-addiction.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coorpintr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "corl3ss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "costruzioni.milano.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "csirt.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cubaal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "custodian.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cycledownunder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cynicaloptimist.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daddyfinger.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dan-nixon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daniel-milnes.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daniel.domains", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daop.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "datagir.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deals.ms", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "degit.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "demoakasafe2.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "desireeburch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dieradvies.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dilberkebab.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dobre-programy.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dobreprogramy.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "domy-drewniane-kanadyjskie.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "doortim.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dp2.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drake.partners", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "draycotthotel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "edusitios.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eliaswendt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eliaswendt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "emilypennock.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "empatico.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escapeforyou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escaperoomdoctor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escaperoomservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escaperoomsolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escapessolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escortlistings.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "escortlistingsuk.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "esd.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "esigtorg.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "esmincg2t1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "etduvindemoselle.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eventsframe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "evitacion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "executiveresolutions.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "f1nal-lap.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "factory-f.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "femaex.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "feministwiki.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ferriswheelofficial.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "flcatering.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fleet-group.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fleet-search.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "francis.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ga-2.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "galeriajardim.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "garcia-franco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gifino.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gladysstrickland.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gregory-thibault.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "guiaextra.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "guidesacademe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "guohuageng.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gwynfryncottages.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hackadena.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hanjuapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "helensmithpr.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "help207.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "helsenorge.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "heritagecoffee.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "herzwacht.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hhuitvaart.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hokusya.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "holland-sailing.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hotwifer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "how-old.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hsturan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hulaginswoodworking.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "i2verify.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibericarempresas.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibericarformula.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibericargestoso.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibericarmotors.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibkvkk.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iknet.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "imgal.vin", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "innovamag.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "inqorp.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "integrityglobal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "interparcel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iszy.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "it-inside.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ja-zur-gs.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jadehotel.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jakobdenlinger.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jd777.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jeerbl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jesiensredniowiecza.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jmwap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jobbuddy.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jpoirierlavoie.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kappie.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kapsalonlinds.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "keez.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kidsdinefree.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kidspaper.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "killme.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kiot.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kita-sun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "klempin.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "korbel-loziska.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kucloud.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kultsar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kunsthandel-augustus-rex.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "l66.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lafantasticatravel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lcx.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lescrapdesfilles.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "liangxingai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lm228.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lm338.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loic.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "londonpropertymatch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "longma168.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loremipsum.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "luchthavenmaastricht.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lucky28.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lxai.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "machidaclip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "madamegarage.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "maiti.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "makejusticework.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mann-und-maeuse.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "manuscripteditorial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "margaux-perrin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "markvanacker.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "matex-tokyo.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "matipl.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mcblain.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mczo.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "megaxchange.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "merzai.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "michalklabnik.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "michelletmc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "midamericapiering.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "miele-katerini.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mikeklidjian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "misakastudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mitsonnenbrillen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mmsmotor.com.hk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "monetki.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "monsterandfox.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mopliangxing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mrcrowley217.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mtludlow.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mugen.technology", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "multiclinicacardio.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nateandxtina.wedding", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nerdswithknives.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "next-idea.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "niumactive.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nobilefoods.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "noleggioimbarcazioni.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "noob-rp.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "norfolkgardencare.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "noteshare.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nyconcretelifting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "obrobka-zdjec.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "odeonentertainment.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ohentpay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ohm.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oleam.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "olmmcc.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onemeter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onoranzefunebri.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "op3racional.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "opcionpublicitaria.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "orcawiki.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oscarproductions.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "osuszanie-krakow.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "osuszanie-radom.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "osuszanie-warszawa.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ovisy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pageboard.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pat-edu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pcunderground.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pensiunea-paco.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pestcontrol.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "phoenixnest.ltd", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "photosafaribg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "physik.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pinkoi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pintiaux.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "plaza.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "plevenlab.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "poshbeyond.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pr3-space-staging.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pr3.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "proxybay.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "przerabianiezdjec.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "publisherservices.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "q1000.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qualitywaterproofing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ranobe.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rapidminer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rawcode.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rawpearls.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rdactive.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rdactive.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ready4bf.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "regeneracjalamp.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "regenpod.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "repsltd.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rgz.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rickmakes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rides-japan.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rjan.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "robison.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "robisonweb.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rochesterglobal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "roosta.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rossfrance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rrssww.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ruthbarrettmusic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "s-yuz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sainformatica.com.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sannefoltz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sargeson.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sarny.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saronikos.city", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sattamatka420.mobi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saunafahrten.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "searx.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "securetasks.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seekersmart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "semao.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sengoku-okayama.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seniorhost.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sensory-brands.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seo-website.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sessile-oak.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sex5.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sheepproductions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shellta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "simulise.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sipyuru.lk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sklepvoip.tel", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skremovals.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smits.frl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "somethingsomething.work", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sophiahatstudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sopra.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "speakersbusiness.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spotsee.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spt.tf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "staffhunt.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "star-darom.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stevehaid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stevereedmp.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stockholmpride.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "storytellingforbusiness.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "strategos.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "streathamfoodfestival.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sun1338.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sunnibangla.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "svpoa.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sw-machines.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "t-pc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tapety-na-pulpit.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tasarimgazetesi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "taxationweb.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "taxi-legroux.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "techcenturion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "temtekco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theaccountingcompanyleeds.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thedword.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tifaware.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tim-demisch.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tkcafe.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "totalpackers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trastornolimite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "travisec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trit.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trosell.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ub889.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uitvaartzorg-heerenveen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uitvaartzorgzuidwestfriesland.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uleenucks.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ulotnefoto.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "um-sachsen-pictures.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unblocked.cx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unblocked.llc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "univate.berlin", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "urbanxhome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "usamdt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uvx.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uyku-apnesi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vanwoensel.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vczk.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "veply.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vernontechnology.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "villagecardshop.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ville-aime.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vinkt.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wangqr.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wanmen.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wardslager.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webleedpixels.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "weblegion.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webmaster-infographiste-lyon.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "websa.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "weidehelp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "westthorntonlabour.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "widely.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wigelsworth.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "withsunglasses.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "woodwormtreatment.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "workathomenoscams.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wxw.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yanwei.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "youlikehookups.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "youliketwinks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yuyantang.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zbtcmu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zeadaniel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zerocz.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zhimingwang.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "03012.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "03018.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "035711630.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "04dco.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "0736ks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "08845.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "095598.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "13214.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "132301.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "17kpw.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "288game.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "303312.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "338sa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "377625.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "377632.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "377817.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "378553.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "4553.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "518.com.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "69games.xxx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "6dec.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "756337.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "787637.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "901543.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "984.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "998sa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "999salon.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "999salon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "99spokes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ab288.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ab2888.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ab28s.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adviserplus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alighierirescaldina.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "all878.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "allbetgame.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "allbetgaming.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "allcinema.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "altered.si", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alxlegal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amal2019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "anarchistos.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aprendiendoforexhoy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arshell.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "arthuryidi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "artistedeparis.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "artiwear.com.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ashtonc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "autorepairseattle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ayumix3.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aznews.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "azurlane.cool", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "b-dd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bancomap.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "beaker.coffee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "beeswarmrehoming.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bernar.do", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bernyweb.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "besuccessful.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bi1gif.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bierwebshop.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bionima.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bitcoincasinos.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blblblblbl.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blogcast.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bnck.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bonus.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bookofdenim.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "borysenko.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "brainyapp.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bravor.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "breizh.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bugu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "buycoins.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "byte.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bytenoc.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cadmanlaw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cafejulian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "calypsohost.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cameroonlounge.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "camisetasmalwee.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "campusfit.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cartelloni.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "castlepointanime.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "catbox.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cb1388.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cb1588.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "centermk.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cfc-swc.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "charset.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "checktechnology.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chefz.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chengarda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chrono-ski-aravis.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cichol.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "classical-guitar-school.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clevvi.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clich.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coinsmat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coinsz.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coldlasers.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "collegesecretary.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "colors3d.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "comidina.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "comiteexpertes.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "communalconsulting.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "consulting-cloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "coriolis.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cramersoft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dansedesalonsaintave.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dat4u.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daveedave.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dayofthegirl.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "daywalkers-photography.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dec6.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "defendersz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "degoticapunk.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deviajesturismo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "devtoys.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dimagrimentoincorso.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "doggo.dance", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "download.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drgiyaseddin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dronesz.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dutchsailors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ealadel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "earfolds.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ecomia.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eges.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eightysoft.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elaboratefiction.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elburgozagalicos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elevationcreative.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "elevationfilms.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "endviolence.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "entravex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "epaslaugos.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "epitome.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "epitome.games", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "esdvfootloose.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "esim.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "esport-agency.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "euroroad17.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "expertpanel.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "exvs.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eythorsson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "facesdr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "faggut.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fanzhencha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fastconv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fboerman.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fcbarcelona.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fdpbrig.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "feat.agency", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "feeg-wage.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "feg-wge.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fegc-wgec.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "felixklein.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "femmes-women.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "femmes.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fflone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "financialfreedomaus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "finilaviolence.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fitnessunder50.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fleetyards.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fmbilder.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "foliumbiosciences.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fosgreece.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fromthemonks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fundavi.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fztopsec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gamenauta.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gameres.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gaycamvids.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "getintopc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "giemall.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "globalinvestigations.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gmuh.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gr8engineer2b.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "handyklinik.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haorenka.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "headforcloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hell.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hicts.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hinaryazan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hitechgr.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hoberg.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "homelab.farm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "horoca.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hotcamvids.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hothiphopmusic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hugh-dancy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "humio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hvenetworks.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hysolate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibericarmotorsmalaga.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibericarmovilcentro.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibericarmovilsur.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibericarreicomsa.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ibericartechnik.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "icci.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "icelandicasian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "icnc.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "idbs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "impactingsports.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "infraredradiant.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iningrui.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "insegne.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "instagib.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iondrey.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iondrey.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iondrey.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iondrey.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iwd.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "izolpoznan.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jayharkess.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jif.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jingyunbank.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jomibe.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jonasberger.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "journeedesfilles.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jsk26.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "json.download", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jsproxy.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "juergmeier.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "justmade.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kaihub.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kaisab.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kaktuskola.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "karrot.world", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kastgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kb5151.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "keevault.pm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kevincramer.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kevindavid.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "keywalker.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kfz-service-wachtmann.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kindconcentrates.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kitpartners.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kjmedia.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kk.sb", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kolibrisolutions.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kometia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "laan247.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lachlanallison.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "landoncreekapartments.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "laresistencia.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lartduportrait.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "laurencball.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "letsflyinto.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leuchtmann.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lffweb.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "libravatar.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "libre-innovation.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lifeslonglist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lincolnboolefoundation.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "liturgical.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "live8811.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "live8899.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "live8899.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "live8899.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "live9922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lm1628.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lm228.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lm338.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "longma168.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "m12uno.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "madpsy.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "madridagency.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "maikoloc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "malacat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "martinbaileyphotography.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "matiaskorhonen.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mcblain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "medeurope.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "media101.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "medicine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "medicsz.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mele.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mhf.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mining.diamonds", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mns.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mns.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "momove.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "monopoly-one.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "monwarez.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moseracctg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "multimed-solutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "muszic.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mycaelis.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "myconf.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "myhostvm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mytime.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "namu.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ndx.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nekorektni.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "netzklad.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "newburghhistoryblog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "newflora.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "noradevot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "noseastumismo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nt-catala.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nuipogoda.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "objetperso.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ochrebridge.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "offtopica.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oleron.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onlinesystem.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "opinionitech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oppress.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ortizmario.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "osez-l-odyssee.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "osmani-gebaeudereinigung.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pbz.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pcsremodel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pen-sec.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pfssales.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pictoriastudios.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pk8k.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "poetry.ge", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pogotowiekomputeroweolsztyn.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "polarfisk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pommetelecom.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "porcore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "profilib.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "prosperity-textile.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pteceng.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "purplscientific.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qacademy.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qualpay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "quantifiedcommerce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ragu.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ralvke.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rap4ever.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "raspberrypi.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ratelimited.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ravencoin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ravencoin.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "raysei.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rdcdesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rdfencingandgates.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "realcolors.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "retefrati.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "retropack.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "richlj.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "richlj.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "richtoinfinity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "riight.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "romaindepeigne.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rootsh3ll.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rssnews.world", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "s1128.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sac.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "saytu.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "schoenstatt-fathers.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "schoolarchive.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scity88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scottspainting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "searchmore.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "searx.run", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "securemind.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sellcoins.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "semakincantik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "serban.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sewatec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sexedquickies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sexedrescue.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "shadowsocks.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sheaspire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "siwyd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sketch.jpn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skorovsud.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skylarker.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sliptrickrecords.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smrtrpck.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "softlan.com.py", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "solomonsklash.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "soulcasa.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "splorge.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spotty.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spumanti.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "starryvoid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "steamosaic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stefanfriedli.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stopmodacruel.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stucki-bagger.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sun1218.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sun1245.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sun1345.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sun1378.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sun668.asia", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sun668.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sunbingchen.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suncity288.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suncity8118.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suncity8118.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suncity818.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suncity818.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suncity8338.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suncity8338.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suncity858.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suncity858.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suncity8668.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suncity8998.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "surfpacific.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "suzaku.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "swc-cfc.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "swingtimeinthegardens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "swissmadesecurity.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tagderinspiration.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "takeomi.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tcksolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tdr.today", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "teetoptens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "textpattern.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "the-archimedeans.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thechargertimes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theclinician.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theobora.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theologyz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thomas717.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thomascauquil.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "totalclean.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "toxoproject.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trekking-friends.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tsueri.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tvdates.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tycyc88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uastrategy.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uberi.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uberifix.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unblocked.pet", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "universe.horse", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unpaismejor.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uranius.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "utahhydrographics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "uten.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "varmepumpe-guide.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vbsoft.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "verasani.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vextraz.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vim.ge", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vinosalmundo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vivemedialab.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "voceempaz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vrcinvestigations.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wage-feeg.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wallis-inside.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wallpapers-free.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "waterproofingahmedabad.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webhotelsoversigt.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "websitesolutionsmedia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wellspringsga.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "westlahair.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "westlife.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wge-feg.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wgec-fegc.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "whitepack.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "whizdomcenter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "whm.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "whtcsj.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "women-femmes.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "women.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xm.digital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--6oqx6c301allufxcm23a7sm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--erban-e9b.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--u8jvc1drbz972aywbk0by95ffo1aqm1c.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--underux-0za.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xoh.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yezishurb.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yicivideo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "young-brahmousin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "yuvaindia.co.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zeiw.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zhl123.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zinglix.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zocial.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zoptiks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "0xff.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "12gotovo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "361171.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "361173.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "367553.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "367556.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "387763.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "3ve.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "638566.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "666618.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "7f.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "809088.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "abelsflooringandtile.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ada.eco", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "adoll.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "afinterio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "africankitchen.gallery", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "afrishade.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "akrep.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "albareport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alexlambertz.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "algebra-quiz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "allesovertech.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "alloutsec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "am8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amanet.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ameliemarieintokyo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "amendoeiraresort.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "anaisfae.art", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "andrewlarson.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "anvorte.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "anyad.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "appspacestatic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "appspaceusercontent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aquafc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "argentinatrabaja.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aubreysnider.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "autismewoerden.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "automagischeberegening.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "axel-voss.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "axelvoss.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ayumi.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "aztummytuck.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "baitap.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "belfordroxo.net.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bellmangesellschaft.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bespokebathrooms.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bezahlbare-praemien.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bigpicture-learning.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bim.physio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bimibroccoli.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bimibroccoli.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bimibroccoli.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bimibrokkoli.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "binary.house", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blechbuexn.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blockclique.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "blogpronto.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bnusd.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bobbyhensley.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bol.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "booktoan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "botmastery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bovworkplacepensions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "boxlink.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bridesmagazine.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "bsgcredit.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "butts-are.cool", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cadmanlaw.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cafeey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cansworld.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "carbon.coop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cardano.eco", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "caroleblouin.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "carolineeball.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "casian.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "catenariadiscos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cceputnam360.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chat-love.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "chriscutts.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cistitguru.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "clearview-creative.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cloudsprt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "club-jose.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cnnet.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "colloquy.mobi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "comptablevilledequebec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "con-con.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "conversiepartners.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cowsay.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "creamsoft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crowleymarine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "cryptoholic.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "crys.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "csgf.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "customwebsitesplus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "da-sh.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "damtosfoods.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "deathberry.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diagnoseo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diagnoseo.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "diagnoseo.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "die-machons.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "digitise.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "distracteddriving.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "doda.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "dollchan.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "doubledash.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drbresnick.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drdegenhart.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "drdenisvincenzi.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e3leading.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e3leading.solutions", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e3leadingsolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e3learning.institute", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "e3li.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eco-solu.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "embodiaacademy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "embodiaapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eooe.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "erikapsicologia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eurekz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "euro-construction.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "europareise2010.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "eventservicestockholm.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "evlann.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "extmatrix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fabianegli.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fastserv.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "felixkaaman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "festx.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fikriwildannugraha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fiskelures.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fleischmann.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fleursdujour.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "florlola.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "frontletter.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fuckz.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "furry.cool", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "fzdm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "galighticus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gelpinhos.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "georgeblack.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "giardiniere.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gloucestershiregospelpartnership.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "golkala.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "grabadolasermonterrey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "greenponik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gunz.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "gyoza.beer", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "haju.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hamikala.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hatcher.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hauntedfieldsofglory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hellenicmusicacademy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hikawa.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hillier-swift.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hitrost.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hoctracnghiem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "honglitrading.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hybrydowe-samochody.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "hypnovir.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iautodily.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "iboy1069.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "icanhazpass.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ifma.edu.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ihorizon.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "infodesigners.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "inlinea.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "inteli.com.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "interssl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "inzernettechnologies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "isabelmurillo-ordonez.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "islightdown.today", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "istitutovivaldi.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "izt.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "izttech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jacksball.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "james.guru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jamestmart.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "javelin.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "javhdmovies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "johnball.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "johndball.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "jomagus.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "journeyof1000hops.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kaffau.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kaidoblogi.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kaizencraft.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kakacon.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kassa.expert", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kenshobox.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kep-sbt.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kepsbt.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kodamail.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "krsaustralia.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kulinaristi.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "kysil.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "l0v0l.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lambertz.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lapatio.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lauraohagan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "laurineprice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lawabidingcactus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "leiyinan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lepartiecomemoracoes.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "librofilia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "limingheike.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "link9.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "loshogares.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "lvcshu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "machon.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "magicsms.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "makropa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mara-martinez.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "marcobicca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mauracher.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mcjackk77.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mdtorelli.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "meidens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mikegao.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mikegao.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "miramar.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mizar.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mizternational.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moarcookies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "moeloli.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "monarcjuexpo.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mosboutique.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mrjbanksy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mrmanner.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "muzykanawesele.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mvwoensei.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mwlcouriers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "myconan.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "myedumundo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "myndcoins.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "mysticconsult.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "namu.games", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nanisiyou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nasserver-test.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "natehobi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ncpimd001.spdns.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nectir-staging.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nectir.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nemausus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nengzhen.com.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "net-combo-ja.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "netframe.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nextcom.digital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nichi.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nietmvwoensel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nippangift.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nipplefucking.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "noclegiwchecinach.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "norml.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "notariusz-bialystok.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "novaiguacu.net.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nsamail.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nullchan.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "nx42.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oahpmdata.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "obscureware.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "octava.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oes.org.gt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "omskrock.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "oneindex.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onlinevisa.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "onvisible.website", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "openconf.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "opencpes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "opencpes.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "opencpes.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pacchioni.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "palebluedot.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "papiweb.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "parkinsplasticsurgery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "partnertaxhub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pastebin.run", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "peev.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "peterkrivanek.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "picom365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pierreyvesdick.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pig.name", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pilvi.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pinup-app.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "plaque-immatriculation-auto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "pointmaquininha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "q01.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qiuby.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ql.tc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qoacher.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qqiao.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "qualitylogoproducts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "raeder-test.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "razvodguru.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "reactivelambda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "realgear.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rebelko.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "redgravity.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rentaways.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "residentialmortgageholdings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ribtours.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rizonrice.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rockmyshoes.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rosenheim-wladiwostok.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rprevost.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "rsearch.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ruffinstorage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "runningrabb.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ryanparman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "safercar.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sailbookers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sanqinyinshi.com.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "satserwis.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "scheldestromen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seewang.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "seidel-immobilienberatung.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "serverhunter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sextop1.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sgdementia.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sharerotic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sherpa.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "simpele-recepten.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "simply.black", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sincordones.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "siselectrom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skipton.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "skullnet.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smallbytedesign.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smartlybuy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "smilesatlakewood.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "spsidahoinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "squeakie.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stagend.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "stralingsonzin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "sustainabilitysociety.hk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "taiklus.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tankionlinenow.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "techmerch.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "techsocial.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "teraservice.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "theafleo.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "thepickledhedgehog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tnonline.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "todasaslojas.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tor.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tranquillapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trindonball.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "trk1234.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "truckers-auction.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tsriggingequipment.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "turnout.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "tvteam.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "twwd.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ugy.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ukne.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "unknown.kyoto", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vdio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "venzagroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "veronicaphotography.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vesaviljanen.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vetpraxis.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vifsoft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "viku.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "vuasinhly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "washoedems.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "watchcow.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wb2288.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "webandsun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "well-around-the-world.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "westcoastheatingair.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "weyhmueller.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wifimb.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wingsofacow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wowgenial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "wyczaruj.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--95q32l0t6b9cb17l.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--anyd-7na.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--e1tvpw18d.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--int-ru8ea.xn--6qq986b3xl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--kkcon-fwab.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xn--l8jydta9i239uzq6aqz9a.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xtremeperformance.co.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "xtri.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "ys6888.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zahnarzt-drvogel-rosenheim.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zahnarzt-drvogel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zylai.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, + { "name": "zzpwoerden.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true }, // END OF 1-YEAR BULK HSTS ENTRIES // Only eTLD+1 domains can be submitted automatically to hstspreload.org, @@ -65949,12 +68311,16 @@ { "name": "www.techrepublic.com", "policy": "custom", "mode": "force-https", "include_subdomains": true }, { "name": "aka.ms", "policy": "custom", "mode": "force-https", "include_subdomains": true }, { "name": "go.microsoft.com", "policy": "custom", "mode": "force-https", "include_subdomains": true }, - { "name": "typewritten.net", "policy": "custom", "mode": "force-https", "include_subdomains": true }, { "name": "airbnb.com", "policy": "custom", "mode": "force-https", "include_subdomains": true }, { "name": "airbnb.tools", "policy": "custom", "mode": "force-https", "include_subdomains": true }, { "name": "account.bbc.com", "policy": "custom", "mode": "force-https", "include_subdomains": true }, { "name": "session.bbc.com", "policy": "custom", "mode": "force-https", "include_subdomains": true }, { "name": "session.bbc.co.uk", "policy": "custom", "mode": "force-https", "include_subdomains": true }, + { "name": "bank.barclays.co.uk", "policy": "custom", "mode": "force-https", "include_subdomains": true }, + // Burton domains (contact: burton at typewritten.net) + { "name": "typewritten.net", "policy": "custom", "mode": "force-https", "include_subdomains": true }, + { "name": "codebreaking.org", "policy": "custom", "mode": "force-https", "include_subdomains": true }, + { "name": "calculates.org", "policy": "custom", "mode": "force-https", "include_subdomains": true }, // IP Address { "name": "1.0.0.1", "policy": "custom", "mode": "force-https", "include_subdomains": false }, // No subdomains @@ -65964,10 +68330,9 @@ { "name": "ft.com", "policy": "custom", "mode": "force-https", "include_subdomains": false }, { "name": "www.ft.com", "policy": "custom", "mode": "force-https", "include_subdomains": true }, { "name": "va.gov", "policy": "custom", "mode": "force-https", "include_subdomains": false }, + { "name": "gov.uk", "policy": "custom", "mode": "force-https", "include_subdomains": false }, // HPKP { "name": "swehack.org", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "swehackCom" }, - { "name": "ncsccs.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "ncsccs" }, - { "name": "themathematician.uk", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "ncsccs" }, // TODO(elawrence): hstspreload.org can't scan IPv6-only sites due to Google // Cloud limitations. Move these entries to the bulk entries once they can // be handled automatically: github.com/chromium/hstspreload.org/issues/43 @@ -66054,13 +68419,6 @@ "mode": "force-https", "include_subdomains": true }, { - "name": "0.me.uk", - "policy": "custom", - "mode": "force-https", "include_subdomains": true, "pins": "ncsccs", - "expect_ct": true, - "expect_ct_report_uri": "https://log.ncsccs.com/report/expectct" - }, - { "name": "photistic.org", "policy": "custom", "mode": "force-https", "include_subdomains": true @@ -66079,13 +68437,6 @@ "expect_ct_report_uri": "https://history.report-uri.com/r/d/ct/reportOnly" }, { - "name": "sirburton.com", - "policy": "custom", - "mode": "force-https", "include_subdomains": true, "pins": "ncsccs", - "expect_ct": true, - "expect_ct_report_uri": "https://log.ncsccs.com/report/expectct" - }, - { "name": "cortis-consulting.ch", "policy": "custom", "mode": "force-https", "include_subdomains": true @@ -66215,6 +68566,36 @@ { "name": "tnwioa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, { "name": "toddmissiontx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, { "name": "townofruthnc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "tnrealid.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cityofmadera.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "jeffersonkyattorney.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "pittmancentertn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "usdoscloud.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "redmondoregon.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "widoj.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "banningca.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ocwr.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cwr.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "sheriffmiamicountyks.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "calcasieuparish.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ncmedicaidplans.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ncmedicaidplan.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "gibraltarwi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "burgawnc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "charlottecountyva.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "joliet.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "deperewi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "genevacountyal.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "myfloridacfo.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mccurtainems.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "america250.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "usa250.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ussemiquincentennial.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "arkadelphia.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cityofarcolatx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "tnosha.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "dpucarriersma.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mainelosap.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, { "name": "bmoattachments.org", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, // END OF ETLD-OWNER REQUESTED ENTRIES diff --git a/chromium/net/http/transport_security_state_static.pins b/chromium/net/http/transport_security_state_static.pins index 9f41460cd6e..f199694822f 100644 --- a/chromium/net/http/transport_security_state_static.pins +++ b/chromium/net/http/transport_security_state_static.pins @@ -1724,62 +1724,6 @@ lBlGGSW4gNfL1IYoakRwJiNiqZ+Gb7+6kHDSVneFeO/qJakXzlByjAA6quPbYzSf +AZxAeKCINT+b72x -----END CERTIFICATE----- -# https://support.comodo.com/index.php?/Knowledgebase/Article/View/969/108/root-comodo-rsa-certification-authority-sha-2 -COMODORSACertificationAuthority ------BEGIN CERTIFICATE----- -MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB -hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV -BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT -EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR -6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X -pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC -9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV -/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf -Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z -+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w -qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah -SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC -u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf -Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq -crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E -FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB -/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl -wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM -4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV -2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna -FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ -CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK -boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke -jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL -S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb -QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl -0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB -NVOFBkpdn627G190 ------END CERTIFICATE----- - -# https://bugzilla.mozilla.org/show_bug.cgi?id=421946 -COMODOECCCertificationAuthority ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT -IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw -MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy -ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N -T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR -FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J -cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW -BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm -fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv -GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- - # From https://crbug.com/745781#c7 TumblrBackup -----BEGIN PUBLIC KEY----- diff --git a/chromium/net/http/transport_security_state_unittest.cc b/chromium/net/http/transport_security_state_unittest.cc index 8822b6c9cce..e8f1caedbe7 100644 --- a/chromium/net/http/transport_security_state_unittest.cc +++ b/chromium/net/http/transport_security_state_unittest.cc @@ -239,7 +239,7 @@ void CheckHPKPReport( const scoped_refptr<X509Certificate>& served_certificate_chain, const scoped_refptr<X509Certificate>& validated_certificate_chain, const HashValueVector& known_pins) { - std::unique_ptr<base::Value> value(base::JSONReader::Read(report)); + std::unique_ptr<base::Value> value(base::JSONReader::ReadDeprecated(report)); ASSERT_TRUE(value); ASSERT_TRUE(value->is_dict()); diff --git a/chromium/net/http/url_security_manager_win.cc b/chromium/net/http/url_security_manager_win.cc index cafdba41f98..97fd9e1988d 100644 --- a/chromium/net/http/url_security_manager_win.cc +++ b/chromium/net/http/url_security_manager_win.cc @@ -55,11 +55,9 @@ bool URLSecurityManagerWin::CanUseDefaultCredentials( base::string16 url16 = base::ASCIIToUTF16(auth_origin.spec()); DWORD policy = 0; HRESULT hr; - hr = security_manager_->ProcessUrlAction(url16.c_str(), - URLACTION_CREDENTIALS_USE, - reinterpret_cast<BYTE*>(&policy), - sizeof(policy), NULL, 0, - PUAF_NOUI, 0); + hr = security_manager_->ProcessUrlAction( + base::as_wcstr(url16), URLACTION_CREDENTIALS_USE, + reinterpret_cast<BYTE*>(&policy), sizeof(policy), NULL, 0, PUAF_NOUI, 0); if (FAILED(hr)) { LOG(ERROR) << "IInternetSecurityManager::ProcessUrlAction failed: " << hr; return false; @@ -83,7 +81,7 @@ bool URLSecurityManagerWin::CanUseDefaultCredentials( // URLZONE_INTERNET 3 // URLZONE_UNTRUSTED 4 DWORD zone = 0; - hr = security_manager_->MapUrlToZone(url16.c_str(), &zone, 0); + hr = security_manager_->MapUrlToZone(base::as_wcstr(url16), &zone, 0); if (FAILED(hr)) { LOG(ERROR) << "IInternetSecurityManager::MapUrlToZone failed: " << hr; return false; |