blob: c452b88ce207601f05230c73255a0cee3c74e7d5 [file] [log] [blame]
/*
* Copyright 2012 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: jud@google.com (Jud Porter)
#include "net/instaweb/rewriter/public/beacon_critical_images_finder.h"
#include "base/logging.h"
#include "net/instaweb/rewriter/critical_images.pb.h"
#include "net/instaweb/rewriter/critical_keys.pb.h"
#include "net/instaweb/rewriter/public/critical_finder_support_util.h"
#include "net/instaweb/rewriter/public/property_cache_util.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_driver_factory.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "net/instaweb/util/public/fallback_property_page.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/statistics.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_hash.h"
#include "pagespeed/kernel/base/timer.h"
namespace net_instaweb {
BeaconCriticalImagesFinder::BeaconCriticalImagesFinder(
const PropertyCache::Cohort* cohort, NonceGenerator* nonce_generator,
Statistics* stats)
: CriticalImagesFinder(cohort, stats), nonce_generator_(nonce_generator) {}
BeaconCriticalImagesFinder::~BeaconCriticalImagesFinder() {
}
bool BeaconCriticalImagesFinder::UpdateCriticalImagesCacheEntry(
const StringSet* html_critical_images_set,
const StringSet* css_critical_images_set,
const RenderedImages* rendered_images_set,
const StringPiece& nonce,
const PropertyCache::Cohort* cohort,
AbstractPropertyPage* page, Timer* timer) {
DCHECK(cohort != NULL);
DCHECK(page != NULL);
PropertyValue* property_value =
page->GetProperty(cohort, kCriticalImagesPropertyName);
if (property_value == NULL) {
return false;
}
CriticalImages critical_images;
if (!PopulateCriticalImagesFromPropertyValue(
property_value, &critical_images)) {
return false;
}
if (!ValidateAndExpireNonce(
timer->NowMs(), nonce,
critical_images.mutable_html_critical_image_support())) {
return false;
}
return CriticalImagesFinder::UpdateAndWriteBackCriticalImagesCacheEntry(
html_critical_images_set, css_critical_images_set, rendered_images_set,
kBeaconImageSupportInterval, cohort, page, &critical_images);
}
GoogleString BeaconCriticalImagesFinder::GetKeyForUrl(StringPiece url) {
unsigned int hash_val =
HashString<CasePreserve, unsigned int>(url.data(), url.size());
return UintToString(hash_val);
}
CriticalImagesFinder::Availability BeaconCriticalImagesFinder::Available(
RewriteDriver* driver) {
if (driver->options()->critical_images_beacon_enabled() &&
driver->server_context()->factory()->UseBeaconResultsInFilters()) {
return CriticalImagesFinder::Available(driver);
} else {
return CriticalImagesFinder::kDisabled;
}
}
bool BeaconCriticalImagesFinder::ShouldBeacon(RewriteDriver* driver) {
UpdateCriticalImagesSetInDriver(driver);
int64 next_beacon_timestamp_ms = 0;
CriticalImagesInfo* critical_images = driver->critical_images_info();
DCHECK(critical_images != NULL)
<< "UpdateCriticalImagesSetInDriver must be called before ShouldBeacon";
if (critical_images != NULL) {
const CriticalImages& proto = critical_images->proto;
if (proto.has_html_critical_image_support()) {
next_beacon_timestamp_ms =
proto.html_critical_image_support().next_beacon_timestamp_ms();
}
}
return net_instaweb::ShouldBeacon(next_beacon_timestamp_ms, *driver);
}
BeaconMetadata BeaconCriticalImagesFinder::PrepareForBeaconInsertion(
RewriteDriver* driver) {
BeaconMetadata metadata;
UpdateCriticalImagesSetInDriver(driver);
CriticalImages& proto = driver->critical_images_info()->proto;
// We store the metadata about last beacon time and nonce generation in the
// html_critical_image_support field of the CriticalImages proto.
net_instaweb::PrepareForBeaconInsertionHelper(
proto.mutable_html_critical_image_support(), nonce_generator_, driver,
true /* using_candidate_key_detection */, &metadata);
if (metadata.status != kDoNotBeacon) {
UpdateInPropertyCache(proto, cohort(), kCriticalImagesPropertyName,
true /* write_cohort */,
driver->fallback_property_page());
}
return metadata;
}
void BeaconCriticalImagesFinder::UpdateCandidateImagesForBeaconing(
const StringSet& images, RewriteDriver* driver, bool beaconing) {
UpdateCriticalImagesSetInDriver(driver);
CriticalImages& proto = driver->critical_images_info()->proto;
if (::net_instaweb::UpdateCandidateKeys(
images, proto.mutable_html_critical_image_support(), !beaconing)) {
UpdateInPropertyCache(proto, cohort(), kCriticalImagesPropertyName,
true /* write_cohort */,
driver->fallback_property_page());
}
}
} // namespace net_instaweb