| /* |
| * Copyright 2013 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: pulkitg@google.com (Pulkit Goyal) |
| |
| #include "pagespeed/opt/http/fallback_property_page.h" |
| |
| #include "base/logging.h" |
| #include "pagespeed/kernel/http/google_url.h" |
| |
| namespace net_instaweb { |
| |
| namespace { |
| |
| const char kFallbackPageCacheKeyQuerySuffix[] = "@fallback"; |
| const char kFallbackPageCacheKeyBasePathSuffix[] = "#fallback"; |
| |
| } // namespace |
| |
| FallbackPropertyPage::FallbackPropertyPage( |
| PropertyPage* actual_property_page, |
| PropertyPage* property_page_with_fallback_values) |
| : actual_property_page_(actual_property_page), |
| property_page_with_fallback_values_(property_page_with_fallback_values) { |
| CHECK(actual_property_page != NULL); |
| } |
| |
| FallbackPropertyPage::~FallbackPropertyPage() { |
| } |
| |
| PropertyValue* FallbackPropertyPage::GetProperty( |
| const PropertyCache::Cohort* cohort, |
| const StringPiece& property_name) { |
| PropertyValue* value = actual_property_page_->GetProperty( |
| cohort, property_name); |
| if (value->has_value() || property_page_with_fallback_values_ == NULL) { |
| return value; |
| } |
| return property_page_with_fallback_values_->GetProperty( |
| cohort, property_name); |
| } |
| |
| PropertyValue* FallbackPropertyPage::GetFallbackProperty( |
| const PropertyCache::Cohort* cohort, |
| const StringPiece& property_name) { |
| if (property_page_with_fallback_values_ == NULL) { |
| return NULL; |
| } |
| return property_page_with_fallback_values_->GetProperty( |
| cohort, property_name); |
| } |
| |
| void FallbackPropertyPage::UpdateValue( |
| const PropertyCache::Cohort* cohort, const StringPiece& property_name, |
| const StringPiece& value) { |
| actual_property_page_->UpdateValue(cohort, property_name, value); |
| if (property_page_with_fallback_values_ != NULL) { |
| property_page_with_fallback_values_->UpdateValue( |
| cohort, property_name, value); |
| } |
| } |
| |
| void FallbackPropertyPage::WriteCohort( |
| const PropertyCache::Cohort* cohort) { |
| actual_property_page_->WriteCohort(cohort); |
| if (property_page_with_fallback_values_ != NULL) { |
| property_page_with_fallback_values_->WriteCohort(cohort); |
| } |
| } |
| |
| CacheInterface::KeyState FallbackPropertyPage::GetCacheState( |
| const PropertyCache::Cohort* cohort) { |
| return actual_property_page_->GetCacheState(cohort); |
| } |
| |
| CacheInterface::KeyState FallbackPropertyPage::GetFallbackCacheState( |
| const PropertyCache::Cohort* cohort) { |
| if (property_page_with_fallback_values_ == NULL) { |
| return CacheInterface::kNotFound; |
| } |
| return property_page_with_fallback_values_->GetCacheState(cohort); |
| } |
| |
| void FallbackPropertyPage::DeleteProperty(const PropertyCache::Cohort* cohort, |
| const StringPiece& property_name) { |
| actual_property_page_->DeleteProperty(cohort, property_name); |
| if (property_page_with_fallback_values_ != NULL) { |
| property_page_with_fallback_values_->DeleteProperty(cohort, property_name); |
| } |
| } |
| |
| GoogleString FallbackPropertyPage::GetFallbackPageUrl( |
| const GoogleUrl& request_url) { |
| GoogleString key; |
| GoogleString suffix; |
| if (request_url.has_query()) { |
| key = request_url.AllExceptQuery().as_string(); |
| suffix = kFallbackPageCacheKeyQuerySuffix; |
| } else { |
| GoogleString url(request_url.spec_c_str()); |
| int size = url.size(); |
| if (url[size - 1] == '/') { |
| // It's common for site admins to canonicalize urls by redirecting "/a/b" |
| // to "/a/b/". In order to more effectively share fallback properties, we |
| // strip the trailing '/' before dropping down a level. |
| url.resize(size - 1); |
| } |
| GoogleUrl gurl(url); |
| key = gurl.AllExceptLeaf().as_string(); |
| suffix = kFallbackPageCacheKeyBasePathSuffix; |
| } |
| return StrCat(key, suffix); |
| } |
| |
| bool FallbackPropertyPage::IsFallbackUrl(const GoogleString& url) { |
| return (url.find(kFallbackPageCacheKeyQuerySuffix) != GoogleString::npos || |
| url.find(kFallbackPageCacheKeyBasePathSuffix) != GoogleString::npos); |
| } |
| |
| } // namespace net_instaweb |