blob: 86b396179d0ca2ba8917d5bf0080675d04da82db [file] [log] [blame]
// Copyright 2013 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/request_properties.h"
#include "net/instaweb/http/public/log_record.h"
#include "net/instaweb/rewriter/public/device_properties.h"
#include "net/instaweb/rewriter/public/downstream_caching_directives.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/http/user_agent_matcher.h"
namespace net_instaweb {
RequestProperties::RequestProperties(UserAgentMatcher* matcher)
: device_properties_(new DeviceProperties(matcher)),
downstream_caching_directives_(new DownstreamCachingDirectives()),
supports_image_inlining_(kNotSet),
supports_js_defer_(kNotSet),
supports_lazyload_images_(kNotSet),
supports_webp_in_place_(kNotSet),
supports_webp_rewritten_urls_(kNotSet),
supports_webp_lossless_alpha_(kNotSet),
supports_webp_animated_(kNotSet) {
}
RequestProperties::~RequestProperties() {
}
void RequestProperties::SetUserAgent(StringPiece user_agent_string) {
device_properties_->SetUserAgent(user_agent_string);
}
void RequestProperties::ParseRequestHeaders(
const RequestHeaders& request_headers) {
device_properties_->ParseRequestHeaders(request_headers);
downstream_caching_directives_->ParseCapabilityListFromRequestHeaders(
request_headers);
}
bool RequestProperties::SupportsImageInlining() const {
if (supports_image_inlining_ == kNotSet) {
supports_image_inlining_ =
(downstream_caching_directives_->SupportsImageInlining() &&
device_properties_->SupportsImageInlining()) ?
kTrue :
kFalse;
}
return (supports_image_inlining_ == kTrue);
}
bool RequestProperties::SupportsLazyloadImages() const {
if (supports_lazyload_images_ == kNotSet) {
supports_lazyload_images_ =
(downstream_caching_directives_->SupportsLazyloadImages() &&
device_properties_->SupportsLazyloadImages()) ?
kTrue :
kFalse;
}
return (supports_lazyload_images_ == kTrue);
}
bool RequestProperties::SupportsCriticalCss() const {
return device_properties_->SupportsCriticalCss();
}
bool RequestProperties::AcceptsGzip() const {
return device_properties_->AcceptsGzip();
}
bool RequestProperties::SupportsCriticalCssBeacon() const {
// For bots, we don't allow instrumentation, but we do allow bots to use
// previous instrumentation results collected by non-bots to enable the
// prioritize_critical_css rewriter.
return SupportsCriticalCss() && !IsBot();
}
bool RequestProperties::SupportsCriticalImagesBeacon() const {
// For now this script has the same user agent requirements as image inlining,
// however that could change in the future if more advanced JS is used by the
// beacon.
return device_properties_->SupportsCriticalImagesBeacon();
}
// Note that the result of the function is cached as supports_js_defer_. This
// must be cleared before calling the function a second time with a different
// value for allow_mobile.
bool RequestProperties::SupportsJsDefer(bool allow_mobile) const {
if (supports_js_defer_ == kNotSet) {
supports_js_defer_ =
(downstream_caching_directives_->SupportsJsDefer() &&
device_properties_->SupportsJsDefer(allow_mobile)) ?
kTrue :
kFalse;
}
return (supports_js_defer_ == kTrue);
}
bool RequestProperties::SupportsWebpInPlace() const {
if (supports_webp_in_place_ == kNotSet) {
supports_webp_in_place_ =
(downstream_caching_directives_->SupportsWebp() &&
device_properties_->SupportsWebpInPlace()) ?
kTrue :
kFalse;
}
return (supports_webp_in_place_ == kTrue);
}
bool RequestProperties::SupportsWebpRewrittenUrls() const {
if (supports_webp_rewritten_urls_ == kNotSet) {
supports_webp_rewritten_urls_ =
(downstream_caching_directives_->SupportsWebp() &&
device_properties_->SupportsWebpRewrittenUrls()) ?
kTrue :
kFalse;
}
return (supports_webp_rewritten_urls_ == kTrue);
}
bool RequestProperties::SupportsWebpLosslessAlpha() const {
if (supports_webp_lossless_alpha_ == kNotSet) {
supports_webp_lossless_alpha_ =
(downstream_caching_directives_->SupportsWebpLosslessAlpha() &&
device_properties_->SupportsWebpLosslessAlpha()) ?
kTrue :
kFalse;
}
return (supports_webp_lossless_alpha_ == kTrue);
}
bool RequestProperties::SupportsWebpAnimated() const {
if (supports_webp_animated_ == kNotSet) {
supports_webp_animated_ =
(downstream_caching_directives_->SupportsWebpAnimated() &&
device_properties_->SupportsWebpAnimated()) ?
kTrue :
kFalse;
}
return (supports_webp_animated_ == kTrue);
}
bool RequestProperties::IsBot() const {
return device_properties_->IsBot();
}
bool RequestProperties::IsMobile() const {
return device_properties_->IsMobile();
}
bool RequestProperties::IsTablet() const {
return device_properties_->IsTablet();
}
bool RequestProperties::SupportsSplitHtml(bool allow_mobile) const {
return device_properties_->SupportsSplitHtml(allow_mobile);
}
bool RequestProperties::CanPreloadResources() const {
// TODO(anupama): Why do we not use a lazybool for this?
return device_properties_->CanPreloadResources();
}
UserAgentMatcher::DeviceType RequestProperties::GetDeviceType() const {
return device_properties_->GetDeviceType();
}
void RequestProperties::LogDeviceInfo(
AbstractLogRecord* log_record,
bool enable_aggressive_rewriters_for_mobile) {
log_record->LogDeviceInfo(
GetDeviceType(),
SupportsImageInlining(),
SupportsLazyloadImages(),
SupportsCriticalImagesBeacon(),
SupportsJsDefer(enable_aggressive_rewriters_for_mobile),
SupportsWebpInPlace(),
SupportsWebpRewrittenUrls(),
SupportsWebpLosslessAlpha(),
IsBot(),
SupportsSplitHtml(enable_aggressive_rewriters_for_mobile),
CanPreloadResources());
}
bool RequestProperties::ForbidWebpInlining() const {
return device_properties_->ForbidWebpInlining();
}
bool RequestProperties::RequestsSaveData() const {
return device_properties_->RequestsSaveData();
}
bool RequestProperties::HasViaHeader() const {
return device_properties_->HasViaHeader();
}
} // namespace net_instaweb