blob: c4a2e20c2ebdb8d34f2b47d13332912589a19be6 [file] [log] [blame]
// Copyright 2010 Google Inc. All Rights Reserved.
//
// 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.
#include "net/instaweb/rewriter/public/device_properties.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/http/http_names.h"
#include "pagespeed/kernel/http/request_headers.h"
#include "pagespeed/kernel/http/user_agent_matcher.h"
#include "pagespeed/kernel/http/user_agent_matcher_test_base.h"
namespace net_instaweb {
class DevicePropertiesTest: public testing::Test {
protected:
DevicePropertiesTest()
: device_properties_(&user_agent_matcher_) { }
void ParseAndVerifySaveData(const char* header_value, bool expected_value) {
RequestHeaders headers;
if (header_value != NULL) {
headers.Add(HttpAttributes::kSaveData, header_value);
}
DeviceProperties device_properties(&user_agent_matcher_);
device_properties.ParseRequestHeaders(headers);
EXPECT_EQ(expected_value, device_properties.RequestsSaveData());
}
UserAgentMatcher user_agent_matcher_;
DeviceProperties device_properties_;
};
TEST_F(DevicePropertiesTest, WebpUserAgentIdentificationNoAccept) {
// NOTE: the purpose here is *not* to test user_agent_matcher's coverage of
// webp user agents, just to see that they're properly reflected in
// device_properties_.
//
// Note: these are all false due to the lack of accept:webp.
device_properties_.SetUserAgent(UserAgentMatcherTestBase::kIe7UserAgent);
EXPECT_FALSE(device_properties_.SupportsWebpInPlace());
EXPECT_FALSE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_FALSE(device_properties_.SupportsWebpLosslessAlpha());
device_properties_.SetUserAgent(UserAgentMatcherTestBase::kTestingWebp);
EXPECT_FALSE(device_properties_.SupportsWebpInPlace());
EXPECT_FALSE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_FALSE(device_properties_.SupportsWebpLosslessAlpha());
device_properties_.SetUserAgent(
UserAgentMatcherTestBase::kTestingWebpLosslessAlpha);
EXPECT_FALSE(device_properties_.SupportsWebpInPlace());
EXPECT_FALSE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_FALSE(device_properties_.SupportsWebpLosslessAlpha());
RequestHeaders headers;
headers.Add(HttpAttributes::kAccept, "image/webp");
device_properties_.ParseRequestHeaders(headers);
device_properties_.SetUserAgent(UserAgentMatcherTestBase::kTestingWebp);
EXPECT_TRUE(device_properties_.SupportsWebpInPlace());
EXPECT_TRUE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_FALSE(device_properties_.SupportsWebpLosslessAlpha());
device_properties_.SetUserAgent(
UserAgentMatcherTestBase::kTestingWebpLosslessAlpha);
EXPECT_TRUE(device_properties_.SupportsWebpInPlace());
EXPECT_TRUE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_TRUE(device_properties_.SupportsWebpLosslessAlpha());
}
// See https://code.google.com/p/modpagespeed/issues/detail?id=978
//
// Microsoft (v-evgena@microsoft.com and tobint@microsoft.com)
// suggests that they are planning to start masquerading IE11 on
// desktop as Chrome, and wants us not to send webp. They have not
// coughed up what the UA will actually be, however, so we can't do
// this with a blacklist yet.
TEST_F(DevicePropertiesTest, WebpRequireAcceptHeaderExceptAndroid) {
// Android Browser is OK -- we will serve it webp without an accept header.
// Mobile IE actually *does* masquerade as IE as of August 2014, but
// it's easy to avoid confusion because the UA includes 'Windows Phone'.
device_properties_.SetUserAgent(
UserAgentMatcherTestBase::kAndroidICSUserAgent);
EXPECT_FALSE(device_properties_.SupportsWebpInPlace());
EXPECT_TRUE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_FALSE(device_properties_.SupportsWebpLosslessAlpha());
device_properties_.SetUserAgent(
UserAgentMatcherTestBase::kWindowsPhoneUserAgent);
EXPECT_FALSE(device_properties_.SupportsWebpInPlace());
EXPECT_FALSE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_FALSE(device_properties_.SupportsWebpLosslessAlpha());
// However Chrome will generally send us an Accept:image/webp header, whereas
// other browsers such as (we think) IE11 in the future, will not send
// such Accept headers. Unfortunately, Chrome only started sending
// accept:image/webp at version 25, so version 18 will no longer get webp
// as of this change.
device_properties_.SetUserAgent(UserAgentMatcherTestBase::kChrome18UserAgent);
EXPECT_FALSE(device_properties_.SupportsWebpInPlace());
EXPECT_FALSE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_FALSE(device_properties_.SupportsWebpLosslessAlpha());
device_properties_.SetUserAgent(
UserAgentMatcherTestBase::kAndroidChrome21UserAgent);
EXPECT_FALSE(device_properties_.SupportsWebpInPlace());
EXPECT_FALSE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_FALSE(device_properties_.SupportsWebpLosslessAlpha());
device_properties_.SetUserAgent(
UserAgentMatcherTestBase::kCriOS48UserAgent);
EXPECT_FALSE(device_properties_.SupportsWebpInPlace());
EXPECT_FALSE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_FALSE(device_properties_.SupportsWebpLosslessAlpha());
// However, Chrome 25 and 37 will get webp due to the accept header.
RequestHeaders headers;
headers.Add(HttpAttributes::kAccept, "image/webp");
device_properties_.ParseRequestHeaders(headers);
device_properties_.SetUserAgent(UserAgentMatcherTestBase::kChrome37UserAgent);
EXPECT_TRUE(device_properties_.SupportsWebpInPlace());
EXPECT_TRUE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_TRUE(device_properties_.SupportsWebpLosslessAlpha());
device_properties_.SetUserAgent(
UserAgentMatcherTestBase::kOpera1110UserAgent);
EXPECT_TRUE(device_properties_.SupportsWebpInPlace());
EXPECT_TRUE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_FALSE(device_properties_.SupportsWebpLosslessAlpha());
device_properties_.SetUserAgent(
UserAgentMatcherTestBase::kCriOS48UserAgent);
EXPECT_TRUE(device_properties_.SupportsWebpInPlace());
EXPECT_TRUE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_TRUE(device_properties_.SupportsWebpLosslessAlpha());
}
TEST_F(DevicePropertiesTest, WebpUserAgentIdentificationAccept) {
RequestHeaders headers;
headers.Add(HttpAttributes::kAccept, "*/*");
headers.Add(HttpAttributes::kAccept, "image/webp");
headers.Add(HttpAttributes::kAccept, "text/html");
device_properties_.ParseRequestHeaders(headers);
device_properties_.SetUserAgent(UserAgentMatcherTestBase::kIe7UserAgent);
EXPECT_TRUE(device_properties_.SupportsWebpInPlace());
EXPECT_TRUE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_FALSE(device_properties_.SupportsWebpLosslessAlpha());
device_properties_.SetUserAgent(UserAgentMatcherTestBase::kTestingWebp);
EXPECT_TRUE(device_properties_.SupportsWebpInPlace());
EXPECT_TRUE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_FALSE(device_properties_.SupportsWebpLosslessAlpha());
device_properties_.SetUserAgent(
UserAgentMatcherTestBase::kTestingWebpLosslessAlpha);
EXPECT_TRUE(device_properties_.SupportsWebpInPlace());
EXPECT_TRUE(device_properties_.SupportsWebpRewrittenUrls());
EXPECT_TRUE(device_properties_.SupportsWebpLosslessAlpha());
}
TEST_F(DevicePropertiesTest, ProcessSaveDataHeader) {
ParseAndVerifySaveData("on", true);
ParseAndVerifySaveData("oN", true);
ParseAndVerifySaveData("ON", true);
ParseAndVerifySaveData(NULL, false);
ParseAndVerifySaveData("off", false);
ParseAndVerifySaveData("ofF", false);
ParseAndVerifySaveData("", false);
ParseAndVerifySaveData("garbage", false);
}
TEST_F(DevicePropertiesTest, ProcessViaHeader) {
RequestHeaders headers1;
DeviceProperties device_properties1(&user_agent_matcher_);
// This is to verify that unrelated headers don't set HasViaHeader().
headers1.Add(HttpAttributes::kAccept, "image/webp");
headers1.Add(HttpAttributes::kAccept, "text/html");
device_properties1.ParseRequestHeaders(headers1);
EXPECT_FALSE(device_properties1.HasViaHeader());
RequestHeaders headers2;
DeviceProperties device_properties2(&user_agent_matcher_);
headers2.Add(HttpAttributes::kVia,
"1.0 fred, 1.1 example.com (Apache/1.1)");
device_properties2.ParseRequestHeaders(headers2);
EXPECT_TRUE(device_properties2.HasViaHeader());
RequestHeaders headers3;
DeviceProperties device_properties3(&user_agent_matcher_);
headers3.Add(HttpAttributes::kVia, "");
device_properties3.ParseRequestHeaders(headers3);
EXPECT_TRUE(device_properties3.HasViaHeader());
}
} // namespace net_instaweb