| /* |
| * Copyright 2010 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| // Author: jmarantz@google.com (Joshua Marantz) |
| |
| #include "net/instaweb/rewriter/public/domain_lawyer.h" |
| |
| #include "pagespeed/kernel/base/gtest.h" |
| #include "pagespeed/kernel/base/mock_message_handler.h" |
| #include "pagespeed/kernel/base/null_mutex.h" |
| #include "pagespeed/kernel/base/string.h" |
| #include "pagespeed/kernel/base/string_util.h" |
| #include "pagespeed/kernel/http/google_url.h" |
| |
| namespace { |
| |
| const char kResourceUrl[] = "styles/style.css?appearance=reader"; |
| const char kCdnPrefix[] = "http://graphics8.nytimes.com/"; |
| const char kRequestDomain[] = "http://www.nytimes.com/"; |
| const char kRequestDomainPort[] = "http://www.nytimes.com:8080/"; |
| |
| } // namespace |
| |
| namespace net_instaweb { |
| |
| class DomainLawyerTest : public testing::Test { |
| protected: |
| DomainLawyerTest() |
| : orig_request_("http://www.nytimes.com/index.html"), |
| port_request_("http://www.nytimes.com:8080/index.html"), |
| https_request_("https://www.nytimes.com/index.html"), |
| message_handler_(new NullMutex) { |
| domain_lawyer_with_all_domains_authorized_.AddDomain( |
| "*", &message_handler_); |
| } |
| |
| // Syntactic sugar to map a request. |
| bool MapRequest(const GoogleUrl& original_request, |
| const StringPiece& resource_url, |
| GoogleString* mapped_domain_name) { |
| GoogleUrl resolved_request; |
| return MapRequest(original_request, resource_url, mapped_domain_name, |
| &resolved_request); |
| } |
| |
| // Syntactic sugar to map a request. |
| bool MapRequest(const GoogleUrl& original_request, |
| const StringPiece& resource_url, |
| GoogleString* mapped_domain_name, |
| GoogleUrl* resolved_request) { |
| return domain_lawyer_.MapRequestToDomain( |
| original_request, resource_url, mapped_domain_name, resolved_request, |
| &message_handler_); |
| } |
| |
| bool MapOrigin(const StringPiece& in, GoogleString* out) { |
| bool is_proxy = true; |
| out->clear(); |
| GoogleString host_header; |
| return domain_lawyer_.MapOrigin(in, out, &host_header, |
| &is_proxy) && !is_proxy; |
| } |
| |
| bool MapOriginAndHost(const StringPiece& in, GoogleString* origin, |
| GoogleString* host_header) { |
| bool is_proxy = true; |
| origin->clear(); |
| host_header->clear(); |
| return domain_lawyer_.MapOrigin(in, origin, host_header, |
| &is_proxy) && !is_proxy; |
| } |
| |
| bool MapProxy(const StringPiece& in, GoogleString* out) { |
| bool is_proxy = false; |
| out->clear(); |
| GoogleString host_header; |
| return domain_lawyer_.MapOrigin(in, out, &host_header, &is_proxy) && |
| is_proxy; |
| } |
| |
| bool AddOriginDomainMapping(const StringPiece& dest, const StringPiece& src) { |
| return domain_lawyer_.AddOriginDomainMapping(dest, src, "", |
| &message_handler_); |
| } |
| |
| bool AddRewriteDomainMapping(const StringPiece& dest, |
| const StringPiece& src) { |
| return domain_lawyer_.AddRewriteDomainMapping(dest, src, &message_handler_); |
| } |
| |
| bool AddShard(const StringPiece& domain, const StringPiece& shards) { |
| return domain_lawyer_.AddShard(domain, shards, &message_handler_); |
| } |
| |
| bool WillDomainChange(StringPiece url) { |
| GoogleUrl gurl(domain_lawyer_.NormalizeDomainName(url)); |
| return domain_lawyer_.WillDomainChange(gurl); |
| } |
| |
| bool IsDomainAuthorized(const GoogleUrl& context_gurl, StringPiece url) { |
| GoogleUrl gurl(url); |
| return domain_lawyer_.IsDomainAuthorized(context_gurl, gurl); |
| } |
| |
| GoogleUrl orig_request_; |
| GoogleUrl port_request_; |
| GoogleUrl https_request_; |
| DomainLawyer domain_lawyer_; |
| DomainLawyer domain_lawyer_with_all_domains_authorized_; |
| MockMessageHandler message_handler_; |
| }; |
| |
| TEST_F(DomainLawyerTest, RelativeDomain) { |
| GoogleString mapped_domain_name; |
| ASSERT_TRUE(MapRequest(orig_request_, kResourceUrl, &mapped_domain_name)); |
| EXPECT_STREQ(kRequestDomain, mapped_domain_name); |
| EXPECT_FALSE(domain_lawyer_.can_rewrite_domains()); |
| } |
| |
| TEST_F(DomainLawyerTest, AbsoluteDomain) { |
| GoogleString mapped_domain_name; |
| ASSERT_TRUE(MapRequest(orig_request_, StrCat(kRequestDomain, kResourceUrl), |
| &mapped_domain_name)); |
| EXPECT_STREQ(kRequestDomain, mapped_domain_name); |
| EXPECT_FALSE(domain_lawyer_.can_rewrite_domains()); |
| } |
| |
| TEST_F(DomainLawyerTest, ExternalDomainNotDeclared) { |
| GoogleString mapped_domain_name; |
| EXPECT_FALSE(MapRequest( |
| orig_request_, StrCat(kCdnPrefix, kResourceUrl), &mapped_domain_name)); |
| } |
| |
| TEST_F(DomainLawyerTest, ExternalDomainDeclared) { |
| StringPiece cdn_domain(kCdnPrefix, STATIC_STRLEN(kCdnPrefix)); |
| |
| // Any domain is authorized with respect to an HTML from the same domain. |
| EXPECT_TRUE(IsDomainAuthorized(orig_request_, orig_request_.Origin())); |
| |
| // But to pull in a resource from another domain, we must first authorize it. |
| EXPECT_FALSE(IsDomainAuthorized(orig_request_, cdn_domain)); |
| ASSERT_TRUE(domain_lawyer_.AddDomain(cdn_domain, &message_handler_)); |
| EXPECT_TRUE(IsDomainAuthorized(orig_request_, cdn_domain)); |
| GoogleString mapped_domain_name; |
| ASSERT_TRUE(MapRequest( |
| orig_request_, StrCat(kCdnPrefix, kResourceUrl), &mapped_domain_name)); |
| EXPECT_STREQ(cdn_domain, mapped_domain_name); |
| |
| // Make sure that we do not allow requests when the port is present; we've |
| // only authorized origin "http://www.nytimes.com/", |
| // not "http://www.nytimes.com:8080/". |
| // The '-1' below is to strip the trailing slash. |
| GoogleString orig_cdn_domain(kCdnPrefix, STATIC_STRLEN(kCdnPrefix) - 1); |
| GoogleString port_cdn_domain(cdn_domain.data(), cdn_domain.size() - 1); |
| port_cdn_domain += ":8080/"; |
| EXPECT_FALSE(MapRequest( |
| orig_request_, StrCat(port_cdn_domain, "/", kResourceUrl), |
| &mapped_domain_name)); |
| EXPECT_FALSE(domain_lawyer_.DoDomainsServeSameContent( |
| port_cdn_domain, cdn_domain)); |
| } |
| |
| TEST_F(DomainLawyerTest, ExternalUpperCaseDomainDeclared) { |
| GoogleString cdn_domain(kCdnPrefix, STATIC_STRLEN(kCdnPrefix)); |
| UpperString(&cdn_domain); // will get normalized in AddDomain. |
| ASSERT_TRUE(domain_lawyer_.AddDomain(cdn_domain, &message_handler_)); |
| GoogleString mapped_domain_name; |
| ASSERT_TRUE(MapRequest( |
| orig_request_, StrCat(kCdnPrefix, kResourceUrl), &mapped_domain_name)); |
| LowerString(&cdn_domain); |
| EXPECT_STREQ(cdn_domain, mapped_domain_name); |
| |
| // Make sure that we do not allow requests when the port is present; we've |
| // only authorized origin "http://www.nytimes.com/", |
| // not "http://www.nytimes.com:8080/". |
| // The '-1' below is to strip the trailing slash. |
| GoogleString orig_cdn_domain(kCdnPrefix, STATIC_STRLEN(kCdnPrefix) - 1); |
| GoogleString port_cdn_domain(cdn_domain.data(), cdn_domain.size() - 1); |
| port_cdn_domain += ":8080/"; |
| EXPECT_FALSE(MapRequest( |
| orig_request_, StrCat(port_cdn_domain, "/", kResourceUrl), |
| &mapped_domain_name)); |
| } |
| |
| TEST_F(DomainLawyerTest, MixedCasePath) { |
| GoogleUrl context_gurl("http://origin.com/index.html"); |
| ASSERT_TRUE(domain_lawyer_.AddDomain("EXAMPLE.com/HI/lo", &message_handler_)); |
| EXPECT_TRUE(IsDomainAuthorized(context_gurl, |
| "http://example.com/HI/lo/file")); |
| EXPECT_FALSE(IsDomainAuthorized(context_gurl, |
| "http://example.com/hi/lo/file")); |
| EXPECT_FALSE(IsDomainAuthorized(context_gurl, |
| "https://example.com/HI/lo/file")); |
| } |
| |
| TEST_F(DomainLawyerTest, RedundantPortsOnDeclaration) { |
| GoogleUrl context_gurl("http://origin.com/index.html"); |
| ASSERT_TRUE(domain_lawyer_.AddDomain("http://a.com:80", &message_handler_)); |
| ASSERT_TRUE(domain_lawyer_.AddDomain("https://b.com:443", &message_handler_)); |
| EXPECT_TRUE(IsDomainAuthorized(context_gurl, "http://a.com/file")); |
| EXPECT_TRUE(IsDomainAuthorized(context_gurl, "https://b.com/file")); |
| EXPECT_FALSE(IsDomainAuthorized(context_gurl, "http://b.com/file")); |
| EXPECT_FALSE(IsDomainAuthorized(context_gurl, "https://a.com/file")); |
| } |
| |
| TEST_F(DomainLawyerTest, RedundantPortsOnTest) { |
| GoogleUrl context_gurl("http://origin.com/index.html"); |
| ASSERT_TRUE(domain_lawyer_.AddDomain("http://a.com", &message_handler_)); |
| ASSERT_TRUE(domain_lawyer_.AddDomain("https://b.com", &message_handler_)); |
| EXPECT_TRUE(IsDomainAuthorized(context_gurl, "http://a.com:80/file")); |
| EXPECT_TRUE(IsDomainAuthorized(context_gurl, "https://b.com:443/file")); |
| EXPECT_FALSE(IsDomainAuthorized(context_gurl, "http://a.com:443/file")); |
| EXPECT_FALSE(IsDomainAuthorized(context_gurl, "http://b.com:443/file")); |
| EXPECT_FALSE(IsDomainAuthorized(context_gurl, "http://b.com:80/file")); |
| EXPECT_FALSE(IsDomainAuthorized(context_gurl, "https://a.com:443/file")); |
| EXPECT_FALSE(IsDomainAuthorized(context_gurl, "https://a.com:80/file")); |
| EXPECT_FALSE(IsDomainAuthorized(context_gurl, "https://b.com:80/file")); |
| } |
| |
| TEST_F(DomainLawyerTest, ExternalDomainDeclaredWithoutScheme) { |
| StringPiece cdn_domain(kCdnPrefix, STATIC_STRLEN(kCdnPrefix)); |
| ASSERT_TRUE(domain_lawyer_.AddDomain(kCdnPrefix + strlen("http://"), |
| &message_handler_)); |
| GoogleString mapped_domain_name; |
| ASSERT_TRUE(MapRequest( |
| orig_request_, StrCat(kCdnPrefix, kResourceUrl), &mapped_domain_name)); |
| EXPECT_STREQ(cdn_domain, mapped_domain_name); |
| } |
| |
| TEST_F(DomainLawyerTest, ExternalDomainDeclaredWithoutTrailingSlash) { |
| StringPiece cdn_domain(kCdnPrefix, STATIC_STRLEN(kCdnPrefix)); |
| // The '-1' below is to strip the trailing slash. |
| StringPiece cdn_domain_no_slash(kCdnPrefix, STATIC_STRLEN(kCdnPrefix) - 1); |
| ASSERT_TRUE(domain_lawyer_.AddDomain(cdn_domain_no_slash, &message_handler_)); |
| GoogleString mapped_domain_name; |
| ASSERT_TRUE(MapRequest( |
| orig_request_, StrCat(kCdnPrefix, kResourceUrl), &mapped_domain_name)); |
| EXPECT_STREQ(cdn_domain, mapped_domain_name); |
| } |
| |
| TEST_F(DomainLawyerTest, WildcardDomainDeclared) { |
| StringPiece cdn_domain(kCdnPrefix, STATIC_STRLEN(kCdnPrefix)); |
| ASSERT_TRUE(domain_lawyer_.AddDomain("*.nytimes.com", &message_handler_)); |
| GoogleString mapped_domain_name; |
| ASSERT_TRUE(MapRequest( |
| orig_request_, StrCat(kCdnPrefix, kResourceUrl), &mapped_domain_name)); |
| EXPECT_STREQ(cdn_domain, mapped_domain_name); |
| } |
| |
| TEST_F(DomainLawyerTest, RelativeDomainPort) { |
| GoogleString mapped_domain_name; |
| ASSERT_TRUE(MapRequest(port_request_, kResourceUrl, &mapped_domain_name)); |
| EXPECT_STREQ(kRequestDomainPort, mapped_domain_name); |
| } |
| |
| TEST_F(DomainLawyerTest, AbsoluteDomainPort) { |
| GoogleString mapped_domain_name; |
| ASSERT_TRUE(MapRequest( |
| port_request_, StrCat(kRequestDomainPort, kResourceUrl), |
| &mapped_domain_name)); |
| EXPECT_STREQ(kRequestDomainPort, mapped_domain_name); |
| } |
| |
| TEST_F(DomainLawyerTest, PortExternalDomainNotDeclared) { |
| GoogleString mapped_domain_name; |
| EXPECT_FALSE(MapRequest( |
| port_request_, StrCat(kCdnPrefix, kResourceUrl), &mapped_domain_name)); |
| } |
| |
| TEST_F(DomainLawyerTest, PortExternalDomainDeclared) { |
| GoogleString port_cdn_domain(kCdnPrefix, STATIC_STRLEN(kCdnPrefix) - 1); |
| port_cdn_domain += ":8080/"; |
| ASSERT_TRUE(domain_lawyer_.AddDomain(port_cdn_domain, &message_handler_)); |
| GoogleString mapped_domain_name; |
| ASSERT_TRUE(MapRequest( |
| port_request_, StrCat(port_cdn_domain, kResourceUrl), |
| &mapped_domain_name)); |
| EXPECT_STREQ(port_cdn_domain, mapped_domain_name); |
| |
| // Make sure that we do not allow requests when the port is missing; we've |
| // only authorized origin "http://www.nytimes.com:8080/", |
| // not "http://www.nytimes.com:8080". |
| GoogleString orig_cdn_domain(kCdnPrefix, STATIC_STRLEN(kCdnPrefix) - 1); |
| orig_cdn_domain += "/"; |
| EXPECT_FALSE(MapRequest(port_request_, StrCat(orig_cdn_domain, kResourceUrl), |
| &mapped_domain_name)); |
| } |
| |
| TEST_F(DomainLawyerTest, PortWildcardDomainDeclared) { |
| GoogleString port_cdn_domain(kCdnPrefix, STATIC_STRLEN(kCdnPrefix) - 1); |
| port_cdn_domain += ":8080/"; |
| ASSERT_TRUE(domain_lawyer_.AddDomain("*.nytimes.com:*", &message_handler_)); |
| GoogleString mapped_domain_name; |
| ASSERT_TRUE(MapRequest(port_request_, StrCat(port_cdn_domain, kResourceUrl), |
| &mapped_domain_name)); |
| EXPECT_STREQ(port_cdn_domain, mapped_domain_name); |
| } |
| |
| TEST_F(DomainLawyerTest, HttpsDomain) { |
| ASSERT_TRUE(domain_lawyer_.AddDomain("https://nytimes.com", |
| &message_handler_)); |
| } |
| |
| TEST_F(DomainLawyerTest, ResourceFromHttpsPage) { |
| ASSERT_TRUE(domain_lawyer_.AddDomain("www.nytimes.com", &message_handler_)); |
| GoogleString mapped_domain_name; |
| |
| // We now handle requests for https, though subsequent fetching might fail. |
| ASSERT_TRUE(MapRequest(https_request_, kResourceUrl, &mapped_domain_name)); |
| ASSERT_TRUE(MapRequest(https_request_, StrCat(kRequestDomain, kResourceUrl), |
| &mapped_domain_name)); |
| } |
| |
| TEST_F(DomainLawyerTest, MapHttpsAcrossHosts) { |
| ASSERT_TRUE(AddOriginDomainMapping("http://insecure.nytimes.com", |
| "https://secure.nytimes.com")); |
| ASSERT_TRUE(AddOriginDomainMapping("https://secure.nytimes.com", |
| "http://insecure.nytimes.com")); |
| GoogleString mapped; |
| ASSERT_TRUE(MapOrigin( |
| "https://secure.nytimes.com/css/stylesheet.css", &mapped)); |
| EXPECT_STREQ("http://insecure.nytimes.com/css/stylesheet.css", mapped); |
| ASSERT_TRUE(MapOrigin( |
| "http://insecure.nytimes.com/css/stylesheet.css", &mapped)); |
| EXPECT_EQ("https://secure.nytimes.com/css/stylesheet.css", mapped); |
| } |
| |
| TEST_F(DomainLawyerTest, MapHttpsAcrossSchemes) { |
| ASSERT_TRUE(AddOriginDomainMapping("http://nytimes.com", |
| "https://nytimes.com")); |
| ASSERT_TRUE(AddOriginDomainMapping("https://nytimes.com", |
| "http://nytimes.com")); |
| GoogleString mapped; |
| ASSERT_TRUE(MapOrigin("https://nytimes.com/css/stylesheet.css", &mapped)); |
| EXPECT_STREQ("http://nytimes.com/css/stylesheet.css", mapped); |
| ASSERT_TRUE(MapOrigin("http://nytimes.com/css/stylesheet.css", &mapped)); |
| EXPECT_EQ("https://nytimes.com/css/stylesheet.css", mapped); |
| } |
| |
| TEST_F(DomainLawyerTest, MapHttpsAcrossPorts) { |
| ASSERT_TRUE(AddOriginDomainMapping("http://nytimes.com:8181", |
| "https://nytimes.com")); |
| GoogleString mapped; |
| ASSERT_TRUE(MapOrigin("https://nytimes.com/css/stylesheet.css", &mapped)); |
| EXPECT_STREQ("http://nytimes.com:8181/css/stylesheet.css", mapped); |
| } |
| |
| TEST_F(DomainLawyerTest, MapHttpsAcrossSchemesAndPorts) { |
| ASSERT_TRUE(AddOriginDomainMapping("http://localhost:8080", |
| "https://nytimes.com:8443")); |
| GoogleString mapped; |
| ASSERT_TRUE(MapOrigin( |
| "https://nytimes.com:8443/css/stylesheet.css", &mapped)); |
| EXPECT_STREQ("http://localhost:8080/css/stylesheet.css", mapped); |
| } |
| |
| TEST_F(DomainLawyerTest, AddTwoProtocolDomainMapping) { |
| ASSERT_TRUE(domain_lawyer_.AddTwoProtocolOriginDomainMapping( |
| "ref.nytimes.com", "www.nytimes.com", "", &message_handler_)); |
| // This will rewrite domains of fetches, but not change urls in page: |
| EXPECT_FALSE(domain_lawyer_.can_rewrite_domains()); |
| GoogleString mapped; |
| GoogleString host_header; |
| ASSERT_TRUE(MapOriginAndHost( |
| "http://www.nytimes.com/index.html", &mapped, &host_header)); |
| EXPECT_STREQ("http://ref.nytimes.com/index.html", mapped); |
| EXPECT_STREQ("www.nytimes.com", host_header); |
| ASSERT_TRUE(MapOriginAndHost( |
| "https://www.nytimes.com/index.html", &mapped, &host_header)); |
| EXPECT_STREQ("https://ref.nytimes.com/index.html", mapped); |
| EXPECT_STREQ("www.nytimes.com", host_header); |
| } |
| |
| TEST_F(DomainLawyerTest, AddTwoProtocolDomainMappingWithRefPort) { |
| ASSERT_TRUE(domain_lawyer_.AddTwoProtocolOriginDomainMapping( |
| "ref.nytimes.com:8089", "www.nytimes.com", "", &message_handler_)); |
| // This will rewrite domains of fetches, but not change urls in page: |
| EXPECT_FALSE(domain_lawyer_.can_rewrite_domains()); |
| GoogleString mapped; |
| GoogleString host_header; |
| ASSERT_TRUE(MapOriginAndHost( |
| "http://www.nytimes.com/index.html", &mapped, &host_header)); |
| EXPECT_STREQ("http://ref.nytimes.com:8089/index.html", mapped); |
| EXPECT_STREQ("www.nytimes.com", host_header); |
| ASSERT_TRUE(MapOriginAndHost( |
| "https://www.nytimes.com/index.html", &mapped, &host_header)); |
| EXPECT_STREQ("https://ref.nytimes.com:8089/index.html", mapped); |
| EXPECT_STREQ("www.nytimes.com", host_header); |
| } |
| |
| TEST_F(DomainLawyerTest, AddTwoProtocolDomainMappingWithServingPort) { |
| ASSERT_TRUE(domain_lawyer_.AddTwoProtocolOriginDomainMapping( |
| "ref.nytimes.com", "www.nytimes.com:8080", "", &message_handler_)); |
| // This will rewrite domains of fetches, but not change urls in page: |
| EXPECT_FALSE(domain_lawyer_.can_rewrite_domains()); |
| GoogleString mapped; |
| GoogleString host_header; |
| ASSERT_TRUE(MapOriginAndHost( |
| "http://www.nytimes.com:8080/index.html", &mapped, &host_header)); |
| EXPECT_STREQ("http://ref.nytimes.com/index.html", mapped); |
| EXPECT_STREQ("www.nytimes.com:8080", host_header); |
| ASSERT_TRUE(MapOriginAndHost( |
| "http://www.nytimes.com/index.html", &mapped, &host_header)); |
| EXPECT_STREQ("http://www.nytimes.com/index.html", mapped); |
| EXPECT_STREQ("www.nytimes.com", host_header); |
| ASSERT_TRUE(MapOriginAndHost( |
| "https://www.nytimes.com:8080/index.html", &mapped, &host_header)); |
| EXPECT_STREQ("https://ref.nytimes.com/index.html", mapped); |
| EXPECT_STREQ("www.nytimes.com:8080", host_header); |
| ASSERT_TRUE(MapOriginAndHost( |
| "https://www.nytimes.com/index.html", &mapped, &host_header)); |
| EXPECT_STREQ("https://www.nytimes.com/index.html", mapped); |
| EXPECT_STREQ("www.nytimes.com", host_header); |
| } |
| |
| TEST_F(DomainLawyerTest, AddTwoProtocolDomainMappingWithBothPorts) { |
| ASSERT_TRUE(domain_lawyer_.AddTwoProtocolOriginDomainMapping( |
| "ref.nytimes.com:9999", "www.nytimes.com:8080", "", &message_handler_)); |
| // This will rewrite domains of fetches, but not change urls in page: |
| EXPECT_FALSE(domain_lawyer_.can_rewrite_domains()); |
| GoogleString mapped; |
| GoogleString host_header; |
| ASSERT_TRUE(MapOriginAndHost( |
| "http://www.nytimes.com:8080/index.html", &mapped, &host_header)); |
| EXPECT_STREQ("http://ref.nytimes.com:9999/index.html", mapped); |
| EXPECT_STREQ("www.nytimes.com:8080", host_header); |
| ASSERT_TRUE(MapOriginAndHost( |
| "https://www.nytimes.com:8080/index.html", &mapped, &host_header)); |
| EXPECT_STREQ("https://ref.nytimes.com:9999/index.html", mapped); |
| EXPECT_STREQ("www.nytimes.com:8080", host_header); |
| } |
| |
| TEST_F(DomainLawyerTest, AddTwoProtocolDomainMappingWithHostHeader) { |
| ASSERT_TRUE(domain_lawyer_.AddTwoProtocolOriginDomainMapping( |
| "ref.nytimes.com", "www.nytimes.com", "host.nytimes.com", |
| &message_handler_)); |
| // This will rewrite domains of fetches, but not change urls in page: |
| EXPECT_FALSE(domain_lawyer_.can_rewrite_domains()); |
| GoogleString mapped; |
| GoogleString host_header; |
| ASSERT_TRUE(MapOriginAndHost( |
| "http://www.nytimes.com/index.html", &mapped, &host_header)); |
| EXPECT_STREQ("http://ref.nytimes.com/index.html", mapped); |
| EXPECT_STREQ("host.nytimes.com", host_header); |
| ASSERT_TRUE(MapOriginAndHost( |
| "https://www.nytimes.com/index.html", &mapped, &host_header)); |
| EXPECT_STREQ("https://ref.nytimes.com/index.html", mapped); |
| EXPECT_STREQ("host.nytimes.com", host_header); |
| } |
| |
| TEST_F(DomainLawyerTest, MapOriginExplicitHost) { |
| ASSERT_TRUE(domain_lawyer_.AddOriginDomainMapping("origin", "*domain", "host", |
| &message_handler_)); |
| bool is_proxy = true; |
| GoogleString out; |
| GoogleString host; |
| ASSERT_TRUE(domain_lawyer_.MapOrigin("http://www.domain/foo.css", |
| &out, &host, &is_proxy)); |
| EXPECT_STREQ("http://origin/foo.css", out); |
| EXPECT_STREQ("host", host); |
| EXPECT_FALSE(is_proxy); |
| } |
| |
| TEST_F(DomainLawyerTest, MapOriginWithoutExplicitHost) { |
| ASSERT_TRUE(domain_lawyer_.AddOriginDomainMapping("origin", "*domain", |
| "" /* host_header */, |
| &message_handler_)); |
| bool is_proxy = true; |
| GoogleString out; |
| GoogleString host; |
| ASSERT_TRUE(domain_lawyer_.MapOrigin("http://www.domain/foo.css", |
| &out, &host, &is_proxy)); |
| EXPECT_STREQ("http://origin/foo.css", out); |
| EXPECT_STREQ("www.domain", host); |
| EXPECT_FALSE(is_proxy); |
| } |
| |
| TEST_F(DomainLawyerTest, RewriteHttpsAcrossHosts) { |
| ASSERT_TRUE(AddRewriteDomainMapping("http://insecure.nytimes.com", |
| "https://secure.nytimes.com")); |
| EXPECT_TRUE(domain_lawyer_.DoDomainsServeSameContent( |
| "insecure.nytimes.com", "https://secure.nytimes.com")); |
| EXPECT_TRUE(domain_lawyer_.can_rewrite_domains()); |
| GoogleString mapped_domain_name; |
| GoogleUrl insecure_gurl("http://insecure.nytimes.com/index.html"); |
| ASSERT_TRUE(MapRequest(insecure_gurl, |
| "https://secure.nytimes.com/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://insecure.nytimes.com/", mapped_domain_name); |
| // Succeeds because http://insecure... is authorized and matches the request. |
| GoogleUrl https_gurl("https://secure.nytimes.com/index.html"); |
| ASSERT_TRUE(MapRequest(https_gurl, |
| "http://insecure.nytimes.com/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://insecure.nytimes.com/", mapped_domain_name); |
| // Succeeds because https://secure... maps to http://insecure... |
| ASSERT_TRUE(MapRequest(https_gurl, |
| "https://secure.nytimes.com/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://insecure.nytimes.com/", mapped_domain_name); |
| } |
| |
| TEST_F(DomainLawyerTest, RewriteHttpsAcrossPorts) { |
| ASSERT_TRUE(AddRewriteDomainMapping("http://nytimes.com:8181", |
| "https://nytimes.com")); |
| EXPECT_TRUE(domain_lawyer_.can_rewrite_domains()); |
| GoogleString mapped_domain_name; |
| // Succeeds because we map it as specified above. |
| GoogleUrl nyt_gurl("http://nytimes.com/index.html"); |
| ASSERT_TRUE(MapRequest(nyt_gurl, "https://nytimes.com/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://nytimes.com:8181/", mapped_domain_name); |
| // Fails because http://nytimes/ is not authorized. |
| GoogleUrl nyt_https("https://nytimes.com/index.html"); |
| ASSERT_FALSE(MapRequest(nyt_https, |
| "http://nytimes.com/css/stylesheet.css", |
| &mapped_domain_name)); |
| // Succeeds because http://nytimes:8181/ is authorized & matches the request. |
| ASSERT_TRUE(MapRequest(nyt_https, |
| "http://nytimes.com:8181/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://nytimes.com:8181/", mapped_domain_name); |
| // Succeeds because https://nytimes/ maps to http://nytimes:8181/. |
| ASSERT_TRUE(MapRequest(nyt_https, |
| "https://nytimes.com/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://nytimes.com:8181/", mapped_domain_name); |
| } |
| |
| TEST_F(DomainLawyerTest, RewriteHttpsAcrossSchemes) { |
| ASSERT_TRUE(AddRewriteDomainMapping("http://nytimes.com", |
| "https://nytimes.com")); |
| EXPECT_TRUE(domain_lawyer_.can_rewrite_domains()); |
| GoogleString mapped_domain_name; |
| GoogleUrl nyt_http("http://nytimes.com/index.html"); |
| ASSERT_TRUE(MapRequest(nyt_http, |
| "https://nytimes.com/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://nytimes.com/", mapped_domain_name); |
| // Succeeds because http://nytimes/ is authorized and matches the request. |
| GoogleUrl nyt_https("https://nytimes.com/index.html"); |
| ASSERT_TRUE(MapRequest(nyt_https, |
| "http://nytimes.com/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://nytimes.com/", mapped_domain_name); |
| // Succeeds because https://nytimes/ maps to http://nytimes/. |
| ASSERT_TRUE(MapRequest(nyt_https, |
| "https://nytimes.com/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://nytimes.com/", mapped_domain_name); |
| } |
| |
| TEST_F(DomainLawyerTest, RewriteHttpsAcrossSchemesAndPorts) { |
| ASSERT_TRUE(AddRewriteDomainMapping("http://localhost:8080", |
| "https://nytimes.com:8443")); |
| EXPECT_TRUE(domain_lawyer_.can_rewrite_domains()); |
| GoogleString mapped_domain_name; |
| GoogleUrl local_8080("http://localhost:8080/index.html"); |
| ASSERT_TRUE(MapRequest(local_8080, |
| "https://nytimes.com:8443/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://localhost:8080/", mapped_domain_name); |
| // Succeeds b/c http://localhost:8080/ is authorized and matches the request. |
| GoogleUrl https_nyt_8443("https://nytimes.com:8443/index.html"); |
| ASSERT_TRUE(MapRequest(https_nyt_8443, |
| "http://localhost:8080/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://localhost:8080/", mapped_domain_name); |
| // Succeeds because https://nytimes:8443/ maps to http://localhost:8080/. |
| ASSERT_TRUE(MapRequest(https_nyt_8443, |
| "https://nytimes.com:8443/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://localhost:8080/", mapped_domain_name); |
| // Relative path also succeeds. |
| ASSERT_TRUE(MapRequest(https_nyt_8443, "css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://localhost:8080/", mapped_domain_name); |
| } |
| |
| TEST_F(DomainLawyerTest, RewriteHttpsToHttps) { |
| ASSERT_TRUE(AddRewriteDomainMapping("https://localhost:8443", |
| "https://nytimes.com:8443")); |
| EXPECT_TRUE(domain_lawyer_.can_rewrite_domains()); |
| GoogleString mapped_domain_name; |
| GoogleUrl local_8443("https://localhost:8443/index.html"); |
| ASSERT_TRUE(MapRequest(local_8443, |
| "https://nytimes.com:8443/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("https://localhost:8443/", mapped_domain_name); |
| // Succeeds b/c https://localhost:8443/ is authorized and matches the request. |
| GoogleUrl https_nyt_8443("https://nytimes.com:8443/index.html"); |
| ASSERT_TRUE(MapRequest(https_nyt_8443, |
| "https://localhost:8443/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("https://localhost:8443/", mapped_domain_name); |
| // Succeeds because https://nytimes:8443/ maps to https://localhost:8443/. |
| ASSERT_TRUE(MapRequest(https_nyt_8443, |
| "https://nytimes.com:8443/css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("https://localhost:8443/", mapped_domain_name); |
| // Relative path also succeeds. |
| ASSERT_TRUE(MapRequest(https_nyt_8443, "css/stylesheet.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("https://localhost:8443/", mapped_domain_name); |
| } |
| |
| TEST_F(DomainLawyerTest, AddTwoProtocolRewriteDomainMapping) { |
| ASSERT_TRUE(domain_lawyer_.AddTwoProtocolRewriteDomainMapping( |
| "www.nytimes.com", "ref.nytimes.com", &message_handler_)); |
| EXPECT_TRUE(domain_lawyer_.can_rewrite_domains()); |
| GoogleString mapped_domain; |
| GoogleUrl containing_page_http("http://www.nytimes.com/index.html"); |
| GoogleUrl containing_page_https("https://www.nytimes.com/index.html"); |
| // http page asks for http stylesheet. |
| ASSERT_TRUE(MapRequest( |
| containing_page_http, |
| "http://ref.nytimes.com/css/stylesheet.css", &mapped_domain)); |
| EXPECT_STREQ("http://www.nytimes.com/", mapped_domain); |
| // http page asks for an https stylesheet. Should still re-map. |
| ASSERT_TRUE(MapRequest( |
| containing_page_http, |
| "https://ref.nytimes.com/css/stylesheet.css", &mapped_domain)); |
| EXPECT_STREQ("https://www.nytimes.com/", mapped_domain); |
| // https page asks for an https stylesheet. |
| ASSERT_TRUE(MapRequest( |
| containing_page_https, |
| "https://ref.nytimes.com/css/stylesheet.css", &mapped_domain)); |
| EXPECT_STREQ("https://www.nytimes.com/", mapped_domain); |
| // https page asks for an http stylesheet. It shouldn't be doing that, but we |
| // preserve the bad behavior so the user realizes something fishy could |
| // happen. |
| ASSERT_TRUE(MapRequest( |
| containing_page_https, |
| "http://ref.nytimes.com/css/stylesheet.css", &mapped_domain)); |
| EXPECT_STREQ("http://www.nytimes.com/", mapped_domain); |
| } |
| |
| TEST_F(DomainLawyerTest, FindDomainsRewrittenTo) { |
| // No mapping. |
| ConstStringStarVector from_domains; |
| GoogleUrl gurl("http://www1.example.com/"); |
| domain_lawyer_.FindDomainsRewrittenTo(gurl, &from_domains); |
| EXPECT_EQ(0, from_domains.size()); |
| |
| // Add mapping. |
| ASSERT_TRUE(domain_lawyer_.AddTwoProtocolRewriteDomainMapping( |
| "www1.example.com", "www.example.com", &message_handler_)); |
| ASSERT_TRUE(domain_lawyer_.AddTwoProtocolRewriteDomainMapping( |
| "www1.example.com", "xyz.example.com", &message_handler_)); |
| |
| domain_lawyer_.FindDomainsRewrittenTo(gurl, &from_domains); |
| ASSERT_EQ(2, from_domains.size()); |
| EXPECT_STREQ("http://www.example.com/", *(from_domains[0])); |
| EXPECT_STREQ("http://xyz.example.com/", *(from_domains[1])); |
| } |
| |
| TEST_F(DomainLawyerTest, AddDomainRedundantly) { |
| ASSERT_TRUE(domain_lawyer_.AddDomain("www.nytimes.com", &message_handler_)); |
| ASSERT_FALSE(domain_lawyer_.AddDomain("www.nytimes.com", &message_handler_)); |
| ASSERT_TRUE(domain_lawyer_.AddDomain("*", &message_handler_)); |
| ASSERT_FALSE(domain_lawyer_.AddDomain("*", &message_handler_)); |
| } |
| |
| TEST_F(DomainLawyerTest, VerifyPortIsDistinct1) { |
| ASSERT_TRUE(domain_lawyer_.AddDomain("www.example.com", &message_handler_)); |
| GoogleString mapped_domain_name; |
| GoogleUrl context_gurl("http://www.other.com/index.html"); |
| EXPECT_FALSE(MapRequest( |
| context_gurl, |
| "http://www.example.com:81/styles.css", |
| &mapped_domain_name)); |
| } |
| |
| TEST_F(DomainLawyerTest, VerifyPortIsDistinct2) { |
| ASSERT_TRUE( |
| domain_lawyer_.AddDomain("www.example.com:81", &message_handler_)); |
| GoogleString mapped_domain_name; |
| GoogleUrl context_gurl("http://www.other.com/index.html"); |
| EXPECT_FALSE(MapRequest( |
| context_gurl, |
| "http://www.example.com/styles.css", |
| &mapped_domain_name)); |
| } |
| |
| TEST_F(DomainLawyerTest, VerifyWildcardedPortSpec) { |
| ASSERT_TRUE(domain_lawyer_.AddDomain("www.example.com*", &message_handler_)); |
| GoogleUrl context_gurl("http://www.origin.com/index.html"); |
| GoogleString mapped_domain_name; |
| EXPECT_TRUE(MapRequest( |
| context_gurl, |
| "http://www.example.com/styles.css", |
| &mapped_domain_name)); |
| EXPECT_TRUE(MapRequest( |
| context_gurl, |
| "http://www.example.com:81/styles.css", |
| &mapped_domain_name)); |
| } |
| |
| TEST_F(DomainLawyerTest, MapRewriteDomain) { |
| GoogleUrl context_gurl("http://www.origin.com/index.html"); |
| ASSERT_TRUE(domain_lawyer_.AddDomain("http://cdn.com/", &message_handler_)); |
| ASSERT_TRUE(domain_lawyer_.AddDomain("http://origin.com/", |
| &message_handler_)); |
| EXPECT_FALSE(domain_lawyer_.DoDomainsServeSameContent( |
| "cdn.com", "origin.com")); |
| ASSERT_TRUE(AddRewriteDomainMapping("http://cdn.com", "http://origin.com")); |
| EXPECT_TRUE(domain_lawyer_.DoDomainsServeSameContent( |
| "cdn.com", "origin.com")); |
| EXPECT_TRUE(domain_lawyer_.can_rewrite_domains()); |
| // First try the mapping from "origin.com" to "cdn.com". |
| GoogleString mapped_domain_name; |
| ASSERT_TRUE(MapRequest( |
| context_gurl, |
| "http://origin.com/styles/blue.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://cdn.com/", mapped_domain_name); |
| |
| // But a relative reference will not map because we mapped "origin.com", |
| // not "www.origin.com". |
| ASSERT_TRUE(MapRequest( |
| context_gurl, |
| "styles/blue.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://www.origin.com/", mapped_domain_name); |
| |
| // Now add the mapping from "www". |
| ASSERT_TRUE(AddRewriteDomainMapping("http://cdn.com", |
| "http://www.origin.com")); |
| ASSERT_TRUE(MapRequest( |
| context_gurl, |
| "styles/blue.css", |
| &mapped_domain_name)); |
| EXPECT_STREQ("http://cdn.com/", mapped_domain_name); |
| } |
| |
| TEST_F(DomainLawyerTest, MapRewriteDomainAndPath) { |
| GoogleUrl context_gurl("http://www.origin.com/index.html"); |
| ASSERT_TRUE(domain_lawyer_.AddDomain("http://cdn.com/origin/", |
| &message_handler_)); |
| ASSERT_TRUE(domain_lawyer_.AddDomain("http://origin.com/", |
| &message_handler_)); |
| ASSERT_TRUE(AddRewriteDomainMapping("http://cdn.com/origin", |
| "http://origin.com")); |
| EXPECT_TRUE(domain_lawyer_.can_rewrite_domains()); |
| // First try the mapping from "origin.com" to "cdn.com/origin". |
| GoogleUrl resolved_request; |
| GoogleString mapped_domain_name; |
| ASSERT_TRUE(MapRequest( |
| context_gurl, |
| "http://origin.com/styles/blue.css", |
| &mapped_domain_name, |
| &resolved_request)); |
| EXPECT_STREQ("http://cdn.com/origin/", mapped_domain_name); |
| EXPECT_STREQ("http://cdn.com/origin/styles/blue.css", |
| resolved_request.Spec()); |
| |
| // But a relative reference will not map because we mapped "origin.com", |
| // not "www.origin.com". |
| ASSERT_TRUE(MapRequest( |
| context_gurl, |
| "styles/blue.css", |
| &mapped_domain_name, |
| &resolved_request)); |
| EXPECT_STREQ("http://www.origin.com/", mapped_domain_name); |
| EXPECT_STREQ("http://www.origin.com/styles/blue.css", |
| resolved_request.Spec()); |
| |
| // Now add the mapping from "www". |
| ASSERT_TRUE(AddRewriteDomainMapping("http://cdn.com/origin", |
| "http://www.origin.com")); |
| ASSERT_TRUE(MapRequest( |
| context_gurl, |
| "styles/blue.css", |
| &mapped_domain_name, |
| &resolved_request)); |
| EXPECT_STREQ("http://cdn.com/origin/", mapped_domain_name); |
| EXPECT_STREQ("http://cdn.com/origin/styles/blue.css", |
| resolved_request.Spec()); |
| } |
| |
| TEST_F(DomainLawyerTest, RewriteWithPath) { |
| GoogleUrl context_gurl("http://example.com/index.html"); |
| ASSERT_TRUE(AddRewriteDomainMapping( |
| "http://example.com/static/images/", "http://static.com/images/")); |
| GoogleString mapped_domain_name; |
| GoogleUrl resolved_request; |
| ASSERT_TRUE(MapRequest(context_gurl, |
| "http://static.com/images/teapot.png", |
| &mapped_domain_name, &resolved_request)); |
| EXPECT_STREQ("http://example.com/static/images/", mapped_domain_name); |
| EXPECT_STREQ("http://example.com/static/images/teapot.png", |
| resolved_request.Spec()); |
| } |
| |
| TEST_F(DomainLawyerTest, OriginWithPath) { |
| ASSERT_TRUE(AddOriginDomainMapping( |
| "http://origin.com/subdir/", "http://external.com")); |
| GoogleString origin_url; |
| ASSERT_TRUE(MapOrigin("http://external.com/styles/main.css", &origin_url)); |
| EXPECT_STREQ("http://origin.com/subdir/styles/main.css", origin_url); |
| } |
| |
| TEST_F(DomainLawyerTest, OriginWithPathOnSource) { |
| ASSERT_TRUE(AddOriginDomainMapping( |
| "http://origin.com/subdir/", "http://external.com/path")); |
| GoogleString origin_url; |
| ASSERT_TRUE(MapOrigin("http://external.com/path/styles/main.css", |
| &origin_url)); |
| EXPECT_STREQ("http://origin.com/subdir/styles/main.css", origin_url); |
| } |
| |
| TEST_F(DomainLawyerTest, OriginAndExternWithPaths) { |
| ASSERT_TRUE(AddOriginDomainMapping( |
| "http://origin.com/subdir/", "http://external.com/static/")); |
| GoogleString origin_url; |
| ASSERT_TRUE(MapOrigin("http://external.com/static/styles/main.css", |
| &origin_url)); |
| EXPECT_STREQ("http://origin.com/subdir/styles/main.css", origin_url); |
| } |
| |
| TEST_F(DomainLawyerTest, OriginAndExternWithMultipleMatches) { |
| domain_lawyer_.AddDomain("http://origin.com", &message_handler_); |
| domain_lawyer_.AddDomain("http://origin.com/a/b", &message_handler_); |
| domain_lawyer_.AddDomain("http://external.com", &message_handler_); |
| ASSERT_TRUE(AddOriginDomainMapping( |
| "http://origin.com/a/", "http://external.com/static/")); |
| |
| GoogleString origin_url; |
| ASSERT_TRUE(MapOrigin("http://external.com/static/styles/main.css", |
| &origin_url)); |
| EXPECT_STREQ("http://origin.com/a/styles/main.css", origin_url); |
| |
| // No mappings should occur on a top level page on external.com, |
| // since our directive should apply only to external.com/static. |
| const char kTopLevelExternalPage[] = "http://external.com/index.html"; |
| origin_url.clear(); |
| ASSERT_TRUE(MapOrigin(kTopLevelExternalPage, &origin_url)); |
| EXPECT_STREQ(kTopLevelExternalPage, origin_url); |
| } |
| |
| TEST_F(DomainLawyerTest, RootDomainOfProxySourceNotAuthorized) { |
| ASSERT_TRUE(AddOriginDomainMapping( |
| "http://origin.com/a/", "http://external.com/static/")); |
| GoogleUrl context_gurl("http://origin.com/index.html"); |
| GoogleUrl external_domain("http://external.com"); |
| |
| // It is not OK to rewrite content on external.com. |
| EXPECT_FALSE(domain_lawyer_.IsDomainAuthorized(context_gurl, |
| external_domain)); |
| EXPECT_TRUE( |
| domain_lawyer_with_all_domains_authorized_.IsDomainAuthorized( |
| context_gurl, external_domain)); |
| |
| // But it *is* OK to rewrite content on external.com/static. |
| external_domain.Reset("http://external.com/static/"); |
| EXPECT_TRUE(domain_lawyer_.IsDomainAuthorized(context_gurl, |
| external_domain)); |
| } |
| |
| TEST_F(DomainLawyerTest, OriginAndExternWithMultipleMatchesDoubleSlash) { |
| domain_lawyer_.AddDomain("http://origin.com", &message_handler_); |
| domain_lawyer_.AddDomain("http://external.com", &message_handler_); |
| ASSERT_TRUE(AddOriginDomainMapping( |
| "http://origin.com/subdir/", "http://external.com/static/")); |
| |
| GoogleString origin_url; |
| ASSERT_TRUE(MapOrigin("http://external.com/static/styles//main.css", |
| &origin_url)); |
| EXPECT_STREQ("http://origin.com/subdir/styles//main.css", origin_url); |
| } |
| |
| TEST_F(DomainLawyerTest, MapOriginDomain) { |
| ASSERT_TRUE(AddOriginDomainMapping( |
| "http://localhost:8080", "http://origin.com:8080")); |
| GoogleString mapped; |
| ASSERT_TRUE(MapOrigin("http://origin.com:8080/a/b/c?d=f", |
| &mapped)); |
| EXPECT_STREQ("http://localhost:8080/a/b/c?d=f", mapped); |
| |
| // The origin domain, which might be, say, 'localhost', is not necessarily |
| // authorized as a domain for input resources. |
| GoogleUrl gurl("http://origin.com:8080/index.html"); |
| EXPECT_FALSE(MapRequest(gurl, "http://localhost:8080/blue.css", &mapped)); |
| GoogleUrl page_url("http://origin.com:8080"); |
| EXPECT_FALSE(IsDomainAuthorized(page_url, "http://localhost:8080")); |
| |
| // Of course, if we were to explicitly authorize then it would be ok. |
| // First use a wildcard, which will not cover the ":8080", so the |
| // Map will still fail. |
| ASSERT_TRUE(domain_lawyer_.AddDomain("localhost*", &message_handler_)); |
| EXPECT_FALSE(MapRequest(gurl, "http://localhost:8080/blue.css", &mapped)); |
| |
| // Now, include the port explicitly, and the mapping will be allowed. |
| ASSERT_TRUE(domain_lawyer_.AddDomain("localhost:8080", &message_handler_)); |
| EXPECT_TRUE(MapRequest(gurl, "http://localhost:8080/blue.css", &mapped)); |
| } |
| |
| TEST_F(DomainLawyerTest, ProxyExternalResource) { |
| GoogleUrl context_gurl("http://origin.com/index.html"); |
| ASSERT_TRUE(domain_lawyer_.AddProxyDomainMapping( |
| "http://origin.com/external", "http://external.com/static", "", |
| &message_handler_)); |
| |
| // Map proxy_this.png to a subdirectory in origin.com. |
| GoogleUrl resolved_request; |
| GoogleString mapped_domain_name; |
| const char kUrlToProxy[] = "http://external.com/static/images/proxy_this.png"; |
| ASSERT_TRUE(MapRequest(context_gurl, kUrlToProxy, &mapped_domain_name, |
| &resolved_request)); |
| EXPECT_STREQ("http://origin.com/external/", mapped_domain_name); |
| EXPECT_STREQ("http://origin.com/external/images/proxy_this.png", |
| resolved_request.Spec()); |
| |
| // But when we fetch this resource, we won't find it in external.com so we |
| // must map it back to origin.com/static. |
| GoogleString origin_url; |
| ASSERT_TRUE(MapProxy(resolved_request.Spec(), &origin_url)); |
| EXPECT_EQ(kUrlToProxy, origin_url); |
| |
| // Just because we enabled proxying from external.com/static, doesn't mean |
| // we want to proxy from external.com/evil or external.com. |
| EXPECT_FALSE(MapRequest(context_gurl, "http://external.com/evil/gifar.gif", |
| &mapped_domain_name, &resolved_request)); |
| EXPECT_FALSE(MapRequest(context_gurl, "http://external.com/gifar.gif", |
| &mapped_domain_name, &resolved_request)); |
| } |
| |
| // Test a situation in which origin is proxied, optimized, and rewritten to a |
| // CDN. |
| TEST_F(DomainLawyerTest, ProxyExternalResourceToCDN) { |
| GoogleUrl context_gurl("http://proxy.com/index.html"); |
| ASSERT_TRUE(domain_lawyer_.AddProxyDomainMapping( |
| "http://proxy.com/external", // Proxies origin, optimizes. |
| "http://origin.com/static", // Origin server, potentially external. |
| "http://cdn.com/external", // CDN, caches responses. |
| &message_handler_)); |
| |
| GoogleUrl resolved_request; |
| GoogleString mapped_domain_name; |
| |
| // We should rewrite origin.com/static to cdn.com/external |
| const char kUrlToProxy[] = "http://origin.com/static/images/proxy_this.png"; |
| ASSERT_TRUE(MapRequest(context_gurl, kUrlToProxy, &mapped_domain_name, |
| &resolved_request)); |
| EXPECT_STREQ("http://cdn.com/external/images/proxy_this.png", |
| resolved_request.Spec()); |
| |
| // We should also rewrite proxy.com/external to cdn.com/external for looking |
| // up cached resources on proxy.com. |
| ASSERT_TRUE( |
| MapRequest(context_gurl, |
| "http://proxy.com/external/images/proxy_this.png", |
| &mapped_domain_name, |
| &resolved_request)); |
| EXPECT_STREQ("http://cdn.com/external/images/proxy_this.png", |
| resolved_request.Spec()); |
| |
| GoogleString external_url; |
| |
| // Map CDN domain to Origin |
| ASSERT_TRUE(MapProxy("http://cdn.com/external/images/proxy_this.png", |
| &external_url)); |
| EXPECT_EQ(kUrlToProxy, external_url); |
| |
| // Map Proxy domain to Origin |
| ASSERT_TRUE(MapProxy("http://proxy.com/external/images/proxy_this.png", |
| &external_url)); |
| EXPECT_EQ(kUrlToProxy, external_url); |
| |
| // Just because we enabled proxying from origin.com/static, doesn't mean |
| // we want to proxy from origin.com/evil or origin.com. |
| EXPECT_FALSE(MapRequest(context_gurl, "http://origin.com/evil/gifar.gif", |
| &mapped_domain_name, &resolved_request)); |
| EXPECT_FALSE(MapRequest(context_gurl, "http://origin.com/gifar.gif", |
| &mapped_domain_name, &resolved_request)); |
| |
| GoogleUrl proxy_url("http://proxy.com/external/a.b"); |
| EXPECT_TRUE(domain_lawyer_.IsProxyMapped(proxy_url)); |
| GoogleUrl non_proxy_url("http://proxy.com/a.b"); |
| EXPECT_FALSE(domain_lawyer_.IsProxyMapped(non_proxy_url)); |
| GoogleUrl origin_url("http://origin.com/static/a.b"); |
| EXPECT_FALSE(domain_lawyer_.IsProxyMapped(origin_url)); |
| GoogleUrl non_origin_url("http://origin.com/a.b"); |
| EXPECT_FALSE(domain_lawyer_.IsProxyMapped(non_origin_url)); |
| GoogleUrl cdn_url("http://cdn.com/external/a.b"); |
| EXPECT_TRUE(domain_lawyer_.IsProxyMapped(cdn_url)); |
| GoogleUrl non_cdn_url("http://cdn.com/a.b"); |
| EXPECT_FALSE(domain_lawyer_.IsProxyMapped(non_cdn_url)); |
| } |
| |
| TEST_F(DomainLawyerTest, ProxyExternalResourceFromHttps) { |
| GoogleUrl context_gurl("http://origin.com/index.html"); |
| ASSERT_TRUE(domain_lawyer_.AddProxyDomainMapping( |
| "http://origin.com/external", "https://external.com/static", NULL, |
| &message_handler_)); |
| |
| // Map proxy_this.png to a subdirectory in origin.com. |
| GoogleUrl resolved_request; |
| GoogleString mapped_domain_name; |
| const char kUrlToProxy[] = |
| "https://external.com/static/images/proxy_this.png"; |
| ASSERT_TRUE(MapRequest(context_gurl, kUrlToProxy, &mapped_domain_name, |
| &resolved_request)); |
| EXPECT_STREQ("http://origin.com/external/", mapped_domain_name); |
| EXPECT_STREQ("http://origin.com/external/images/proxy_this.png", |
| resolved_request.Spec()); |
| |
| // But when we fetch this resource, we won't find it in external.com so we |
| // must map it back to origin.com/static. |
| GoogleString origin_url; |
| ASSERT_TRUE(MapProxy(resolved_request.Spec(), &origin_url)); |
| EXPECT_EQ(kUrlToProxy, origin_url); |
| |
| // Just because we enabled proxying from external.com/static, doesn't mean |
| // we want to proxy from external.com/evil or external.com. |
| EXPECT_FALSE(MapRequest(context_gurl, "https://external.com/evil/gifar.gif", |
| &mapped_domain_name, &resolved_request)); |
| EXPECT_FALSE(MapRequest(context_gurl, "https://external.com/gifar.gif", |
| &mapped_domain_name, &resolved_request)); |
| } |
| |
| TEST_F(DomainLawyerTest, ProxyAmbiguous) { |
| GoogleUrl context_gurl("http://origin.com/index.html"); |
| ASSERT_TRUE(domain_lawyer_.AddProxyDomainMapping( |
| "http://proxy.com/origin", "http://origin.com", "", &message_handler_)); |
| |
| GoogleString out; |
| EXPECT_TRUE(MapProxy("http://proxy.com/origin/x", &out)); |
| EXPECT_STREQ("http://origin.com/x", out); |
| |
| // We don't allow proxy/proxy conflicts. |
| EXPECT_FALSE(domain_lawyer_.AddProxyDomainMapping( |
| "http://proxy.com/origin", "http://ambiguous.com", "", |
| &message_handler_)); |
| |
| EXPECT_TRUE(MapProxy("http://proxy.com/origin/x", &out)); |
| EXPECT_STREQ("http://origin.com/x", out); |
| |
| // We don't allow origin/proxy conflicts either. |
| EXPECT_FALSE(AddOriginDomainMapping( |
| "http://ambiguous.com", "http://proxy.com/origin")); |
| |
| EXPECT_TRUE(MapProxy("http://proxy.com/origin/x", &out)); |
| EXPECT_STREQ("http://origin.com/x", out); |
| |
| // But origin/origin conflicts are noisily ignored; second one wins. |
| EXPECT_TRUE(AddOriginDomainMapping("http://origin1.com", "http://x.com")); |
| EXPECT_TRUE(MapOrigin("http://x.com/y", &out)); |
| EXPECT_STREQ("http://origin1.com/y", out); |
| |
| EXPECT_TRUE(AddOriginDomainMapping("http://origin2.com", "http://x.com")); |
| EXPECT_TRUE(MapOrigin("http://x.com/y", &out)); |
| EXPECT_STREQ("http://origin2.com/y", out) << "second one wins."; |
| |
| // It is also a bad idea to map the same origin to two different proxies. |
| EXPECT_FALSE(domain_lawyer_.AddProxyDomainMapping( |
| "http://proxy2.com/origin", "http://origin.com", "", &message_handler_)); |
| } |
| |
| TEST_F(DomainLawyerTest, Merge) { |
| // Add some mappings for domain_lawywer_. |
| ASSERT_TRUE(domain_lawyer_.AddDomain("http://d1.com/", &message_handler_)); |
| ASSERT_TRUE(AddRewriteDomainMapping( |
| "http://cdn1.com", "http://www.o1.com")); |
| ASSERT_TRUE(AddOriginDomainMapping( |
| "http://localhost:8080", "http://o1.com:8080")); |
| ASSERT_TRUE(domain_lawyer_.AddProxyDomainMapping( |
| "http://proxy.com/origin", "http://origin.com", "", &message_handler_)); |
| |
| // We'll also a mapping that will conflict, and one that won't. |
| ASSERT_TRUE(AddOriginDomainMapping("http://dest1/", "http://common_src1")); |
| ASSERT_TRUE(AddOriginDomainMapping("http://dest2/", "http://common_src2")); |
| ASSERT_TRUE(AddShard("foo.com", "bar1.com,bar2.com")); |
| EXPECT_TRUE(domain_lawyer_.DoDomainsServeSameContent("foo.com", "bar1.com")); |
| EXPECT_TRUE(domain_lawyer_.DoDomainsServeSameContent("foo.com", "bar2.com")); |
| EXPECT_TRUE(domain_lawyer_.DoDomainsServeSameContent("bar1.com", "bar2.com")); |
| EXPECT_TRUE(domain_lawyer_.DoDomainsServeSameContent("bar1.com", "foo.com")); |
| EXPECT_TRUE(domain_lawyer_.DoDomainsServeSameContent("bar2.com", "foo.com")); |
| EXPECT_TRUE(domain_lawyer_.DoDomainsServeSameContent("bar2.com", "bar1.com")); |
| |
| GoogleString out; |
| EXPECT_TRUE(MapProxy("http://proxy.com/origin/x", &out)); |
| EXPECT_STREQ("http://origin.com/x", out); |
| |
| // Now add a similar set of mappings for another lawyer. |
| DomainLawyer merged; |
| ASSERT_TRUE(merged.AddDomain("http://d2.com/", &message_handler_)); |
| ASSERT_TRUE(merged.AddRewriteDomainMapping( |
| "http://cdn2.com", "http://www.o2.com", &message_handler_)); |
| ASSERT_TRUE(merged.AddOriginDomainMapping( |
| "http://localhost:8080", "http://o2.com:8080", "", &message_handler_)); |
| |
| // Here's a different mapping for the same source. |
| ASSERT_TRUE(merged.AddOriginDomainMapping( |
| "http://dest3/", "http://common_src1", "", &message_handler_)); |
| ASSERT_TRUE(domain_lawyer_.AddOriginDomainMapping( |
| "http://dest4/", "http://common_src3", "", &message_handler_)); |
| |
| merged.Merge(domain_lawyer_); |
| |
| // Now the tests for both domains should work post-merger. |
| |
| GoogleString mapped; |
| GoogleUrl resolved_request; |
| GoogleUrl o1_index_gurl("http://www.o1.com/index.html"); |
| ASSERT_TRUE(merged.MapRequestToDomain( |
| o1_index_gurl, |
| "styles/blue.css", &mapped, &resolved_request, &message_handler_)); |
| EXPECT_STREQ("http://cdn1.com/", mapped); |
| GoogleUrl o2_index_gurl("http://www.o2.com/index.html"); |
| ASSERT_TRUE(merged.MapRequestToDomain( |
| o2_index_gurl, |
| "styles/blue.css", &mapped, &resolved_request, &message_handler_)); |
| EXPECT_STREQ("http://cdn2.com/", mapped); |
| |
| bool is_proxy = true; |
| GoogleString host_header; |
| ASSERT_TRUE(merged.MapOrigin("http://o1.com:8080/a/b/c?d=f", &mapped, |
| &host_header, &is_proxy)); |
| EXPECT_STREQ("o1.com:8080", host_header); |
| host_header.clear(); |
| EXPECT_FALSE(is_proxy); |
| EXPECT_STREQ("http://localhost:8080/a/b/c?d=f", mapped); |
| ASSERT_TRUE(merged.MapOrigin("http://o2.com:8080/a/b/c?d=f", &mapped, |
| &host_header, &is_proxy)); |
| EXPECT_STREQ("o2.com:8080", host_header); |
| EXPECT_FALSE(is_proxy); |
| EXPECT_STREQ("http://localhost:8080/a/b/c?d=f", mapped); |
| |
| // The conflict will be silently resolved to prefer the mapping from |
| // the domain that got merged, which is domain_laywer_1, overriding |
| // what was previously in the target. |
| ASSERT_TRUE(merged.MapOrigin("http://common_src1", &mapped, &host_header, |
| &is_proxy)); |
| EXPECT_STREQ("http://dest1/", mapped); |
| EXPECT_STREQ("common_src1", host_header); |
| EXPECT_FALSE(is_proxy); |
| |
| // Now check the domains that were added. |
| ASSERT_TRUE(merged.MapOrigin("http://common_src2", &mapped, &host_header, |
| &is_proxy)); |
| EXPECT_STREQ("http://dest2/", mapped); |
| EXPECT_STREQ("common_src2", host_header); |
| EXPECT_FALSE(is_proxy); |
| |
| ASSERT_TRUE(merged.MapOrigin("http://common_src3", &mapped, &host_header, |
| &is_proxy)); |
| EXPECT_STREQ("http://dest4/", mapped); |
| EXPECT_STREQ("common_src3", host_header); |
| EXPECT_FALSE(is_proxy); |
| |
| GoogleString shard; |
| ASSERT_TRUE(merged.ShardDomain("http://foo.com/", 0, &shard)); |
| EXPECT_STREQ("http://bar1.com/", shard); |
| |
| EXPECT_TRUE(merged.DoDomainsServeSameContent("foo.com", "bar1.com")); |
| EXPECT_TRUE(merged.DoDomainsServeSameContent("foo.com", "bar2.com")); |
| EXPECT_TRUE(merged.DoDomainsServeSameContent("bar1.com", "bar2.com")); |
| EXPECT_TRUE(merged.DoDomainsServeSameContent("bar1.com", "foo.com")); |
| EXPECT_TRUE(merged.DoDomainsServeSameContent("bar2.com", "foo.com")); |
| EXPECT_TRUE(merged.DoDomainsServeSameContent("bar2.com", "bar1.com")); |
| |
| EXPECT_TRUE(merged.DoDomainsServeSameContent("cdn1.com", "www.o1.com")); |
| EXPECT_TRUE(merged.DoDomainsServeSameContent("cdn2.com", "www.o2.com")); |
| EXPECT_FALSE(merged.DoDomainsServeSameContent("cdn1.com", "cdn2.com")); |
| |
| // The proxy settings survive the merge. |
| mapped.clear(); |
| is_proxy = false; |
| EXPECT_TRUE(merged.MapOrigin("http://proxy.com/origin/x", &mapped, |
| &host_header, &is_proxy)); |
| EXPECT_TRUE(is_proxy); |
| EXPECT_STREQ("http://origin.com/x", mapped); |
| EXPECT_STREQ("proxy.com", host_header); |
| } |
| |
| TEST_F(DomainLawyerTest, AddMappingFailures) { |
| // Corner cases. |
| ASSERT_FALSE(AddRewriteDomainMapping("", "http://origin.com")); |
| ASSERT_FALSE(AddRewriteDomainMapping("http://cdn.com", "")); |
| ASSERT_FALSE(AddRewriteDomainMapping("http://cdn.com", ",")); |
| |
| // Ensure that we ignore a mapping of a domain to itself. |
| ASSERT_FALSE(AddRewriteDomainMapping("http://origin.com", |
| "http://origin.com")); |
| EXPECT_FALSE(domain_lawyer_.can_rewrite_domains()); |
| ASSERT_FALSE(AddRewriteDomainMapping("http://origin.com/newroot", |
| "http://origin.com")); |
| EXPECT_FALSE(domain_lawyer_.can_rewrite_domains()); |
| |
| ASSERT_FALSE(AddRewriteDomainMapping("http://origin.com", |
| "http://origin.com,")); |
| ASSERT_FALSE(AddRewriteDomainMapping("http://origin.com", |
| ",http://origin.com")); |
| ASSERT_FALSE(AddRewriteDomainMapping("http://origin.com/newroot", |
| "http://origin.com,")); |
| ASSERT_FALSE(AddRewriteDomainMapping("http://origin.com/newroot", |
| ",http://origin.com")); |
| |
| // You can never wildcard the target domains. |
| EXPECT_FALSE(AddRewriteDomainMapping("foo*.com", "bar.com")); |
| EXPECT_FALSE(AddOriginDomainMapping("foo*.com", "bar.com")); |
| EXPECT_FALSE(AddShard("foo*.com", "bar.com")); |
| |
| // You can use wildcard in source domains for Rewrite and Origin, but not |
| // Sharding. |
| EXPECT_TRUE(AddRewriteDomainMapping("foo.com", "bar*.com")); |
| EXPECT_TRUE(domain_lawyer_.AddOriginDomainMapping("foo.com", "bar*.com", |
| "", &message_handler_)); |
| EXPECT_FALSE(AddShard("foo.com", "bar*.com")); |
| |
| EXPECT_TRUE(AddShard("foo.com", "bar1.com,bar2.com")); |
| } |
| |
| TEST_F(DomainLawyerTest, Shard) { |
| EXPECT_FALSE(domain_lawyer_.can_rewrite_domains()); |
| ASSERT_TRUE(AddShard("foo.com", "bar1.com,bar2.com")); |
| EXPECT_TRUE(domain_lawyer_.can_rewrite_domains()); |
| GoogleString shard; |
| ASSERT_TRUE(domain_lawyer_.ShardDomain("http://foo.com/", 0, &shard)); |
| EXPECT_STREQ("http://bar1.com/", shard); |
| ASSERT_TRUE(domain_lawyer_.ShardDomain("http://foo.com/", 1, &shard)); |
| EXPECT_STREQ("http://bar2.com/", shard); |
| EXPECT_FALSE(domain_lawyer_.ShardDomain("http://other.com/", 0, &shard)); |
| } |
| |
| TEST_F(DomainLawyerTest, ShardHttps) { |
| EXPECT_FALSE(domain_lawyer_.can_rewrite_domains()); |
| ASSERT_TRUE(AddShard("https://foo.com", "https://bar1.com,https://bar2.com")); |
| EXPECT_TRUE(domain_lawyer_.can_rewrite_domains()); |
| GoogleString shard; |
| ASSERT_TRUE(domain_lawyer_.ShardDomain("https://foo.com/", 0, &shard)); |
| EXPECT_STREQ("https://bar1.com/", shard); |
| ASSERT_TRUE(domain_lawyer_.ShardDomain("https://foo.com/", 1, &shard)); |
| EXPECT_STREQ("https://bar2.com/", shard); |
| EXPECT_FALSE(domain_lawyer_.ShardDomain("https://other.com/", 0, &shard)); |
| } |
| |
| TEST_F(DomainLawyerTest, WillDomainChange) { |
| ASSERT_TRUE(AddShard("foo.com", "bar1.com,bar2.com")); |
| ASSERT_TRUE(AddRewriteDomainMapping("http://cdn.com", "http://origin.com")); |
| EXPECT_TRUE(WillDomainChange("http://foo.com/")); |
| EXPECT_TRUE(WillDomainChange("foo.com/")); |
| EXPECT_TRUE(WillDomainChange("http://foo.com")); |
| EXPECT_TRUE(WillDomainChange("foo.com")); |
| EXPECT_TRUE(WillDomainChange("http://origin.com/")); |
| EXPECT_TRUE(WillDomainChange("http://bar1.com/")); |
| EXPECT_TRUE(WillDomainChange("http://bar2.com/")); |
| EXPECT_FALSE(WillDomainChange("http://cdn.com/")); |
| EXPECT_FALSE(WillDomainChange("http://other_domain.com/")); |
| } |
| |
| TEST_F(DomainLawyerTest, WillDomainChangeSubdirectory) { |
| ASSERT_TRUE(AddRewriteDomainMapping("http://cdn.com", |
| "http://origin.com/subdir")); |
| EXPECT_FALSE(WillDomainChange("http://origin.com/")); |
| EXPECT_FALSE(WillDomainChange("http://origin.com/subdirx")); |
| EXPECT_TRUE(WillDomainChange("http://origin.com/subdir/x")); |
| } |
| |
| TEST_F(DomainLawyerTest, WillDomainChangeOnlyOneShard) { |
| ASSERT_TRUE(AddShard("foo.com", "bar1.com")); |
| ASSERT_TRUE(AddRewriteDomainMapping("http://cdn.com", "http://origin.com")); |
| EXPECT_TRUE(WillDomainChange("http://foo.com/")); |
| EXPECT_TRUE(WillDomainChange("foo.com/")); |
| EXPECT_TRUE(WillDomainChange("http://foo.com")); |
| EXPECT_TRUE(WillDomainChange("foo.com")); |
| EXPECT_TRUE(WillDomainChange("http://origin.com/")); |
| EXPECT_FALSE(WillDomainChange("http://bar1.com/")); |
| EXPECT_FALSE(WillDomainChange("http://cdn.com/")); |
| EXPECT_FALSE(WillDomainChange("http://other_domain.com/")); |
| } |
| |
| TEST_F(DomainLawyerTest, MapRewriteToOriginDomain) { |
| ASSERT_TRUE(AddRewriteDomainMapping("rewrite.com", "myhost.com")); |
| ASSERT_TRUE(AddOriginDomainMapping("localhost", "myhost.com")); |
| GoogleString mapped; |
| |
| // Check that we can warp all the way from the rewrite to localhost. |
| ASSERT_TRUE(MapOrigin("http://rewrite.com/a/b/c?d=f", &mapped)); |
| EXPECT_STREQ("http://localhost/a/b/c?d=f", mapped); |
| } |
| |
| TEST_F(DomainLawyerTest, MapShardToOriginDomain) { |
| ASSERT_TRUE(AddRewriteDomainMapping("cdn.myhost.com", "myhost.com")); |
| ASSERT_TRUE(AddOriginDomainMapping("localhost", "myhost.com")); |
| ASSERT_TRUE(AddShard("cdn.myhost.com", "s1.com,s2.com")); |
| GoogleString mapped; |
| |
| // Check that we can warp all the way from the cdn to localhost. |
| ASSERT_TRUE(MapOrigin("http://s1.com/a/b/c?d=f", &mapped)); |
| EXPECT_STREQ("http://localhost/a/b/c?d=f", mapped); |
| mapped.clear(); |
| ASSERT_TRUE(MapOrigin("http://s2.com/a/b/c?d=f", &mapped)); |
| EXPECT_STREQ("http://localhost/a/b/c?d=f", mapped); |
| } |
| |
| TEST_F(DomainLawyerTest, ConflictedOrigin1) { |
| ASSERT_TRUE(AddOriginDomainMapping( |
| "localhost", "myhost.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| |
| ASSERT_TRUE(AddOriginDomainMapping( |
| "other", "myhost.com")); |
| EXPECT_EQ(1, message_handler_.SeriousMessages()); |
| |
| // The second one will win. |
| GoogleString mapped; |
| ASSERT_TRUE(MapOrigin("http://myhost.com/x", &mapped)); |
| EXPECT_STREQ("http://other/x", mapped); |
| } |
| |
| TEST_F(DomainLawyerTest, NoConflictOnMerge1) { |
| ASSERT_TRUE(AddOriginDomainMapping("localhost", "myhost1.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| ASSERT_TRUE(AddOriginDomainMapping("localhost", "myhost2.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| |
| // We are rewriting multiple source domains to the same domain. Both |
| // source domains have the same origin mapping so there is no conflict |
| // message. |
| ASSERT_TRUE(AddRewriteDomainMapping("cdn.com", "myhost1.com,myhost2.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| |
| // Of course there's no conflict so it's obvious 'localhost' will win. Check. |
| GoogleString mapped; |
| ASSERT_TRUE(MapOrigin("http://myhost1.com/x", &mapped)); |
| EXPECT_STREQ("http://localhost/x", mapped); |
| ASSERT_TRUE(MapOrigin("http://myhost2.com/y", &mapped)); |
| EXPECT_STREQ("http://localhost/y", mapped); |
| ASSERT_TRUE(MapOrigin("http://cdn.com/z", &mapped)); |
| EXPECT_STREQ("http://localhost/z", mapped); |
| } |
| |
| TEST_F(DomainLawyerTest, ConflictedOrigin2) { |
| ASSERT_TRUE(AddOriginDomainMapping("origin1.com", "myhost1.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| ASSERT_TRUE(AddOriginDomainMapping("origin2.com", "myhost2.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| |
| // We are rewriting multiple source domains to the same domain. Both |
| // source domains have the *different* origin mappings so there will be a |
| // conflict message. |
| ASSERT_TRUE(AddRewriteDomainMapping("cdn.com", "myhost1.com,myhost2.com")); |
| EXPECT_EQ(1, message_handler_.SeriousMessages()); |
| |
| // The second mapping will win for the automatic propagation for "cdn.com". |
| GoogleString mapped; |
| ASSERT_TRUE(MapOrigin("http://cdn.com/x", &mapped)); |
| EXPECT_STREQ("http://origin2.com/x", mapped); |
| |
| // However, "myhost1.com"'s explicitly set origin will not be overridden. |
| ASSERT_TRUE(MapOrigin("http://myhost1.com/y", &mapped)); |
| EXPECT_STREQ("http://origin1.com/y", mapped); |
| } |
| |
| TEST_F(DomainLawyerTest, NoShardConflict) { |
| // We are origin-mapping multiple source domains to the same domain. |
| // Even though we've overspecified the origin domain in this graph, |
| // there are no conflict messages because the origins are the same. |
| ASSERT_TRUE(AddOriginDomainMapping("localhost", "myhost1.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| ASSERT_TRUE(AddOriginDomainMapping("localhost", "myhost2.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| ASSERT_TRUE(AddRewriteDomainMapping("cdn.com", "myhost1.com,myhost2.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| ASSERT_TRUE(AddShard("cdn.com", "s1.com,s2.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| |
| // Unambiguous mappings from either shard or rewrite domain. |
| GoogleString mapped; |
| ASSERT_TRUE(MapOrigin("http://cdn.com/x", &mapped)); |
| EXPECT_STREQ("http://localhost/x", mapped); |
| mapped.clear(); |
| ASSERT_TRUE(MapOrigin("http://s1.com/x", &mapped)); |
| EXPECT_STREQ("http://localhost/x", mapped); |
| mapped.clear(); |
| ASSERT_TRUE(MapOrigin("http://s2.com/x", &mapped)); |
| EXPECT_STREQ("http://localhost/x", mapped); |
| } |
| |
| TEST_F(DomainLawyerTest, NoShardConflictReverse) { |
| // This is the same exact test as NoShardConflict, but now we set up |
| // the shards first, then the rewrite domain, then the origin mappings. |
| ASSERT_TRUE(AddShard("cdn.com", "s1.com,s2.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| ASSERT_TRUE(AddRewriteDomainMapping("cdn.com", "myhost1.com,myhost2.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| ASSERT_TRUE(AddOriginDomainMapping("localhost", "myhost1.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| ASSERT_TRUE(AddOriginDomainMapping("localhost", "myhost2.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| |
| // Unambiguous mappings from either shard or rewrite domain. |
| GoogleString mapped; |
| ASSERT_TRUE(MapOrigin("http://cdn.com/x", &mapped)); |
| EXPECT_STREQ("http://localhost/x", mapped); |
| mapped.clear(); |
| ASSERT_TRUE(MapOrigin("http://s1.com/x", &mapped)); |
| EXPECT_STREQ("http://localhost/x", mapped); |
| mapped.clear(); |
| ASSERT_TRUE(MapOrigin("http://s2.com/x", &mapped)); |
| EXPECT_STREQ("http://localhost/x", mapped); |
| } |
| |
| TEST_F(DomainLawyerTest, NoShardConflictScramble) { |
| // Yet another copy of NoShardConflict, but do the rewrite-mapping last. |
| ASSERT_TRUE(AddShard("cdn.com", "s1.com,s2.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| ASSERT_TRUE(AddOriginDomainMapping("localhost", "myhost1.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| ASSERT_TRUE(AddOriginDomainMapping("localhost", "myhost2.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| ASSERT_TRUE(AddRewriteDomainMapping("cdn.com", "myhost1.com,myhost2.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| |
| // Unambiguous mappings from either shard or rewrite domain. |
| GoogleString mapped; |
| ASSERT_TRUE(MapOrigin("http://cdn.com/x", &mapped)); |
| EXPECT_STREQ("http://localhost/x", mapped); |
| mapped.clear(); |
| ASSERT_TRUE(MapOrigin("http://s1.com/x", &mapped)); |
| EXPECT_STREQ("http://localhost/x", mapped); |
| mapped.clear(); |
| ASSERT_TRUE(MapOrigin("http://s2.com/x", &mapped)); |
| EXPECT_STREQ("http://localhost/x", mapped); |
| } |
| |
| TEST_F(DomainLawyerTest, ShardConflict1) { |
| ASSERT_TRUE(AddShard("cdn1.com", "s1.com,s2.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| |
| ASSERT_FALSE(AddShard("cdn2.com", "s2.com,s3.com")); |
| EXPECT_EQ(1, message_handler_.SeriousMessages()); |
| } |
| |
| TEST_F(DomainLawyerTest, RewriteOriginCycle) { |
| ASSERT_TRUE(AddShard("b.com", "a.com")); |
| ASSERT_TRUE(AddRewriteDomainMapping("b.com", "a.com")); |
| // We now have "a.com" and "b.com" in a shard/rewrite cycle. That's |
| // ugly and we don't actually detect that because we don't have a |
| // graph traversal that can detect it until we start applying origin |
| // domains, which auto-propagate. |
| // |
| // We will have no serious errors reported until we create the |
| // conflict which will chase pointers in a cycle, which gets cut |
| // by breadcrumbing, but we wind up with 2 serious errors from |
| // one call. |
| |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| ASSERT_TRUE(AddOriginDomainMapping("origin1.com", "a.com")); |
| EXPECT_EQ(0, message_handler_.SeriousMessages()); |
| ASSERT_TRUE(AddOriginDomainMapping("origin2.com", "b.com")); |
| EXPECT_EQ(2, message_handler_.SeriousMessages()); |
| } |
| |
| TEST_F(DomainLawyerTest, WildcardOrder) { |
| ASSERT_TRUE(AddOriginDomainMapping("host1", "abc*.com")); |
| ASSERT_TRUE(AddOriginDomainMapping("host2", "*z.com")); |
| |
| GoogleString mapped; |
| ASSERT_TRUE(MapOrigin("http://abc.com/x", &mapped)); |
| EXPECT_STREQ("http://host1/x", mapped); |
| ASSERT_TRUE(MapOrigin("http://z.com/x", &mapped)); |
| EXPECT_STREQ("http://host2/x", mapped); |
| |
| // Define a second lawyer with definitions "*abc*.com" which should |
| // come after "abc*.com". |
| DomainLawyer second_lawyer, merged_lawyer; |
| ASSERT_TRUE(second_lawyer.AddOriginDomainMapping("host3", "*abc*.com", |
| "", &message_handler_)); |
| ASSERT_TRUE(second_lawyer.AddOriginDomainMapping( |
| "host1", "abc*.com", "", &message_handler_)); // duplicate entry. |
| merged_lawyer.Merge(domain_lawyer_); |
| merged_lawyer.Merge(second_lawyer); |
| EXPECT_EQ(3, merged_lawyer.num_wildcarded_domains()); |
| |
| // Hopefully we didn't bork the order of "abc* and "*". Note that just |
| // iterating over a std::set will yield the "*" first, as '*' is ascii |
| // 42 and 'a' is ascii 97, and the domain-map is over GoogleString. |
| bool is_proxy = true; |
| GoogleString host_header; |
| ASSERT_TRUE(merged_lawyer.MapOrigin("http://abc.com/x", &mapped, |
| &host_header, &is_proxy)); |
| EXPECT_STREQ("http://host1/x", mapped); |
| EXPECT_FALSE(is_proxy); |
| is_proxy = true; |
| ASSERT_TRUE(merged_lawyer.MapOrigin("http://xyz.com/x", &mapped, |
| &host_header, &is_proxy)); |
| EXPECT_STREQ("http://host2/x", mapped); |
| EXPECT_FALSE(is_proxy); |
| is_proxy = true; |
| ASSERT_TRUE(merged_lawyer.MapOrigin("http://xabc.com/x", &mapped, |
| &host_header, &is_proxy)); |
| EXPECT_STREQ("http://host3/x", mapped); |
| EXPECT_FALSE(is_proxy); |
| } |
| |
| TEST_F(DomainLawyerTest, ComputeSignatureTest) { |
| DomainLawyer first_lawyer, second_lawyer; |
| ASSERT_TRUE(first_lawyer.AddOriginDomainMapping("host1", "*abc*.com", "", |
| &message_handler_)); |
| ASSERT_TRUE(first_lawyer.AddOriginDomainMapping("host2", "*def*.com", "h2", |
| &message_handler_)); |
| |
| ASSERT_TRUE(second_lawyer.AddRewriteDomainMapping("cdn.com", |
| "myhost1.com,myhost2.com", |
| &message_handler_)); |
| EXPECT_STREQ("D:http://*abc*.com/__a_" "O:http://host1/_" |
| "-" |
| "D:http://*def*.com/__a_" "O:http://host2/_" |
| "-" |
| "D:http://host1/__n_" |
| "-" |
| "D:http://host2/__n_" "H:h2|" |
| "-", |
| first_lawyer.Signature()); |
| EXPECT_STREQ("D:http://cdn.com/__a_" |
| "-" |
| "D:http://myhost1.com/__a_" "R:http://cdn.com/_" |
| "-" |
| "D:http://myhost2.com/__a_" "R:http://cdn.com/_" |
| "-", |
| second_lawyer.Signature()); |
| |
| EXPECT_TRUE(first_lawyer.AddShard("domain1", "shard", &message_handler_)); |
| EXPECT_STREQ("D:http://*abc*.com/__a_" "O:http://host1/_" |
| "-" |
| "D:http://*def*.com/__a_" "O:http://host2/_" |
| "-" |
| "D:http://domain1/__a_" "S:http://shard/_" |
| "-" |
| "D:http://host1/__n_" |
| "-" |
| "D:http://host2/__n_" "H:h2|" |
| "-" |
| "D:http://shard/__a_" "R:http://domain1/_" |
| "-", |
| first_lawyer.Signature()); |
| } |
| |
| TEST_F(DomainLawyerTest, ToStringTest) { |
| DomainLawyer first_lawyer, second_lawyer; |
| EXPECT_TRUE(first_lawyer.AddDomain("static.example.com", &message_handler_)); |
| EXPECT_TRUE(first_lawyer.AddOriginDomainMapping("host1", "*abc*.com", "", |
| &message_handler_)); |
| EXPECT_STREQ( |
| "http://*abc*.com/ Auth OriginDomain:http://host1/\n" |
| "http://host1/\n" |
| "http://static.example.com/ Auth\n", |
| first_lawyer.ToString()); |
| |
| EXPECT_TRUE(second_lawyer.AddRewriteDomainMapping("myhost.cdn.com", |
| "myhost1.com,myhost2.com", |
| &message_handler_)); |
| EXPECT_TRUE( |
| second_lawyer.AddShard("domain1", "shard,shard2", &message_handler_)); |
| EXPECT_STREQ( |
| "http://domain1/ Auth Shards:{http://shard/, http://shard2/}\n" |
| "http://myhost.cdn.com/ Auth\n" |
| "http://myhost1.com/ Auth RewriteDomain:http://myhost.cdn.com/\n" |
| "http://myhost2.com/ Auth RewriteDomain:http://myhost.cdn.com/\n" |
| "http://shard/ Auth RewriteDomain:http://domain1/\n" |
| "http://shard2/ Auth RewriteDomain:http://domain1/\n", |
| second_lawyer.ToString()); |
| } |
| |
| TEST_F(DomainLawyerTest, IsOriginKnownTest) { |
| DomainLawyer lawyer; |
| lawyer.AddDomain("a.com", &message_handler_); |
| lawyer.AddDomain("a.com:42", &message_handler_); |
| lawyer.AddDomain("https://a.com:43", &message_handler_); |
| lawyer.AddRewriteDomainMapping("b.com", "c.com", &message_handler_); |
| lawyer.AddOriginDomainMapping("e.com", "d.com", "", &message_handler_); |
| lawyer.AddShard("f.com", "s1.f.com,s2.f.com", &message_handler_); |
| |
| GoogleUrl z_com("http://z.com"); |
| EXPECT_FALSE(lawyer.IsOriginKnown(z_com)); |
| |
| GoogleUrl a_com("http://a.com"); |
| EXPECT_TRUE(lawyer.IsOriginKnown(a_com)); |
| |
| GoogleUrl a_com_42("http://a.com:42/sardine"); |
| EXPECT_TRUE(lawyer.IsOriginKnown(a_com_42)); |
| |
| GoogleUrl a_com_43("http://a.com:43/bass"); |
| EXPECT_FALSE(lawyer.IsOriginKnown(a_com_43)); |
| |
| GoogleUrl s_a_com_43("https://a.com:43/bass"); |
| EXPECT_TRUE(lawyer.IsOriginKnown(s_a_com_43)); |
| |
| GoogleUrl s_a_com_44("https://a.com:44/bass"); |
| EXPECT_FALSE(lawyer.IsOriginKnown(s_a_com_44)); |
| |
| GoogleUrl b_com("http://b.com"); |
| EXPECT_TRUE(lawyer.IsOriginKnown(b_com)); |
| |
| GoogleUrl c_com("http://c.com"); |
| EXPECT_TRUE(lawyer.IsOriginKnown(c_com)); |
| |
| GoogleUrl d_com("http://d.com"); |
| EXPECT_TRUE(lawyer.IsOriginKnown(d_com)); |
| |
| GoogleUrl e_com("http://e.com"); |
| EXPECT_TRUE(lawyer.IsOriginKnown(e_com)); |
| |
| GoogleUrl f_com("http://f.com"); |
| EXPECT_TRUE(lawyer.IsOriginKnown(f_com)); |
| |
| GoogleUrl s1_f_com("http://s1.f.com"); |
| EXPECT_TRUE(lawyer.IsOriginKnown(s1_f_com)); |
| |
| GoogleUrl s2_f_com("http://s2.f.com"); |
| EXPECT_TRUE(lawyer.IsOriginKnown(s2_f_com)); |
| } |
| |
| TEST_F(DomainLawyerTest, NoAbsoluteUrlPath) { |
| DomainLawyer lawyer; |
| lawyer.AddOriginDomainMapping("b.com", "a.com", "", &message_handler_); |
| |
| GoogleUrl foo("http://a.com/foo"); |
| GoogleString out; |
| GoogleString host_header; |
| bool is_proxy = true; |
| EXPECT_TRUE(lawyer.MapOriginUrl(foo, &out, &host_header, &is_proxy)); |
| EXPECT_STREQ("http://b.com/foo", out); |
| EXPECT_FALSE(is_proxy); |
| |
| // Make sure we don't resolve the path: data:image/jpeg as an absolute URL. |
| GoogleUrl data("http://a.com/data:image/jpeg"); |
| out.clear(); |
| EXPECT_TRUE(lawyer.MapOriginUrl(data, &out, &host_header, &is_proxy)); |
| EXPECT_STREQ("http://b.com/data:image/jpeg", out); |
| EXPECT_FALSE(is_proxy); |
| } |
| |
| TEST_F(DomainLawyerTest, AboutBlank) { |
| DomainLawyer lawyer; |
| lawyer.AddOriginDomainMapping("b.com", "a.com", "", &message_handler_); |
| |
| GoogleUrl foo("about:blank"); |
| GoogleString out; |
| GoogleString host_header; |
| bool is_proxy = true; |
| EXPECT_FALSE(lawyer.MapOriginUrl(foo, &out, &host_header, &is_proxy)); |
| } |
| |
| TEST_F(DomainLawyerTest, StripProxySuffix) { |
| DomainLawyer lawyer; |
| GoogleUrl gurl("http://example.com.suffix/path"); |
| GoogleString host, url = gurl.Spec().as_string(); |
| EXPECT_FALSE(lawyer.can_rewrite_domains()); |
| EXPECT_FALSE(lawyer.StripProxySuffix(gurl, &url, &host)); |
| lawyer.set_proxy_suffix(".suffix"); |
| EXPECT_TRUE(lawyer.can_rewrite_domains()); |
| EXPECT_TRUE(lawyer.StripProxySuffix(gurl, &url, &host)); |
| EXPECT_STREQ("http://example.com/path", url); |
| EXPECT_STREQ("example.com", host); |
| |
| // The ':80' will get removed by GoogleUrl. |
| GoogleUrl http_gurl_80("http://example.com.suffix:80/path"); |
| url = http_gurl_80.Spec().as_string(); |
| host.clear(); |
| url.clear(); |
| EXPECT_TRUE(lawyer.StripProxySuffix(http_gurl_80, &url, &host)); |
| EXPECT_STREQ("http://example.com/path", url); |
| EXPECT_STREQ("example.com", host); |
| |
| // However an ':81' makes the proxy-suffix mismatch. |
| GoogleUrl http_gurl_81("http://example.com.suffix:81/path"); |
| url.clear(); |
| host.clear(); |
| EXPECT_FALSE(lawyer.StripProxySuffix(http_gurl_81, &url, &host)); |
| |
| // 443 on http. We need to understand why we see this in Apache slurping |
| // with a Firefox proxy, but punt for now. |
| GoogleUrl http_gurl_443("http://example.com.suffix:443/path"); |
| url.clear(); |
| host.clear(); |
| EXPECT_FALSE(lawyer.StripProxySuffix(http_gurl_443, &url, &host)); |
| |
| // 443 on https -- that should canonicalize out in GoogleUrl. |
| GoogleUrl https_gurl_443("https://example.com.suffix:443/path"); |
| url.clear(); |
| host.clear(); |
| EXPECT_TRUE(lawyer.StripProxySuffix(https_gurl_443, &url, &host)); |
| EXPECT_STREQ("https://example.com/path", url); |
| EXPECT_STREQ("example.com", host); |
| |
| GoogleUrl https_gurl("https://example.com.suffix/path"); |
| url.clear(); |
| host.clear(); |
| EXPECT_TRUE(lawyer.StripProxySuffix(https_gurl, &url, &host)); |
| EXPECT_STREQ("https://example.com/path", url); |
| EXPECT_STREQ("example.com", host); |
| } |
| |
| TEST_F(DomainLawyerTest, AddProxySuffix) { |
| DomainLawyer lawyer; |
| GoogleUrl base("http://www.example.com.suffix"); |
| lawyer.set_proxy_suffix(".suffix"); |
| EXPECT_TRUE(lawyer.can_rewrite_domains()); |
| |
| // No need to change relative URLs. |
| GoogleString url = "relative.html"; |
| EXPECT_FALSE(lawyer.AddProxySuffix(base, &url)); |
| |
| // An absolute reference to a new destination in the origin domain gets |
| // suffixed. |
| url = "http://www.example.com/absolute.html"; |
| EXPECT_TRUE(lawyer.AddProxySuffix(base, &url)); |
| EXPECT_STREQ("http://www.example.com.suffix/absolute.html", url); |
| |
| // It also works even if the reference is a domain that's related to the |
| // base, by consulting the known suffixes list via domain_registry. |
| url = "http://other.example.com/absolute.html"; |
| EXPECT_TRUE(lawyer.AddProxySuffix(base, &url)); |
| EXPECT_STREQ("http://other.example.com.suffix/absolute.html", url); |
| |
| // However a link to a completely unrelated domain is left unchanged. |
| url = "http://other.com/x.html"; |
| EXPECT_FALSE(lawyer.AddProxySuffix(base, &url)); |
| |
| // Link to same domain on HTTPS is also OK. |
| url = "https://www.example.com/absolute.html"; |
| EXPECT_TRUE(lawyer.AddProxySuffix(base, &url)); |
| EXPECT_STREQ("https://www.example.com.suffix/absolute.html", url); |
| } |
| |
| } // namespace net_instaweb |