blob: ac570ff55f00aad6347bdc99a50650e0e7dcac25 [file] [log] [blame]
/*
* Copyright 2011 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/single_rewrite_context.h"
#include "base/logging.h"
#include "net/instaweb/rewriter/cached_result.pb.h"
#include "net/instaweb/rewriter/public/output_resource.h"
#include "net/instaweb/rewriter/public/resource.h"
#include "net/instaweb/rewriter/public/resource_slot.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/http/http_names.h"
#include "pagespeed/kernel/http/google_url.h"
namespace net_instaweb {
SingleRewriteContext::SingleRewriteContext(RewriteDriver* driver,
RewriteContext* parent,
ResourceContext* resource_context)
: RewriteContext(driver, parent, resource_context) {
}
SingleRewriteContext::~SingleRewriteContext() {
}
bool SingleRewriteContext::Partition(OutputPartitions* partitions,
OutputResourceVector* outputs) {
bool ret = false;
if (num_slots() == 1) {
ret = true;
ResourcePtr resource(slot(0)->resource());
GoogleString unsafe_reason;
if (resource->IsSafeToRewrite(rewrite_uncacheable(), &unsafe_reason)) {
GoogleString failure_reason;
OutputResourcePtr output_resource(
Driver()->CreateOutputResourceFromResource(
id(), encoder(), resource_context(),
resource, kind(), &failure_reason));
if (output_resource.get() == NULL) {
partitions->add_debug_message(failure_reason);
} else {
CachedResult* partition = partitions->add_partition();
resource->AddInputInfoToPartition(Resource::kIncludeInputHash, 0,
partition);
output_resource->set_cached_result(partition);
outputs->push_back(output_resource);
}
} else {
partitions->add_debug_message(unsafe_reason);
}
}
return ret;
}
void SingleRewriteContext::Rewrite(int partition_index,
CachedResult* partition,
const OutputResourcePtr& output_resource) {
CHECK_EQ(0, partition_index);
ResourcePtr resource(slot(0)->resource());
CHECK(resource.get() != NULL);
CHECK(resource->loaded());
CHECK(resource->HttpStatusOk());
if (output_resource.get() != NULL) {
DCHECK_EQ(output_resource->cached_result(), partition);
}
RewriteSingle(resource, output_resource);
}
void SingleRewriteContext::AddLinkRelCanonical(
const ResourcePtr& input, const OutputResourcePtr& output) {
// It's unclear what we should do in case of complex domain mapping
// configurations, so we simply avoid adding a header in that case.
//
// Also note that we may see both the original and rewritten URLs,
// depending on whether we're handling the HTML or the resource fetch.
const DomainLawyer* domain_lawyer = Options()->domain_lawyer();
GoogleUrl input_gurl(input->url());
if (domain_lawyer->WillDomainChange(input_gurl)) {
return;
}
ConstStringStarVector rewritten_to;
domain_lawyer->FindDomainsRewrittenTo(input_gurl, &rewritten_to);
if (!rewritten_to.empty()) {
return;
}
output->response_headers()->Add(
HttpAttributes::kLink, RelCanonicalHeaderValue(input->url()));
}
GoogleString SingleRewriteContext::RelCanonicalHeaderValue(StringPiece url) {
return StrCat("<", GoogleUrl::Sanitize(url), ">; rel=\"canonical\"");
}
} // namespace net_instaweb