b69b3c2793
in prep for change to make contents always be the extracted contents (ExtractUncompressedContents). refactor a ton of files to use the new definition.
141 lines
4.9 KiB
C++
141 lines
4.9 KiB
C++
/*
|
|
* 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: morlovich@google.com (Maksim Orlovich)
|
|
|
|
#include "net/instaweb/rewriter/public/inline_rewrite_context.h"
|
|
|
|
#include "base/logging.h"
|
|
#include "net/instaweb/rewriter/cached_result.pb.h"
|
|
#include "net/instaweb/rewriter/public/common_filter.h"
|
|
#include "net/instaweb/rewriter/public/output_resource_kind.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 "net/instaweb/rewriter/public/rewrite_result.h"
|
|
#include "net/instaweb/rewriter/public/server_context.h"
|
|
#include "pagespeed/kernel/base/string_util.h"
|
|
#include "pagespeed/kernel/html/html_element.h"
|
|
|
|
namespace net_instaweb {
|
|
|
|
InlineRewriteContext::InlineRewriteContext(CommonFilter* filter,
|
|
HtmlElement* element,
|
|
HtmlElement::Attribute* src)
|
|
: RewriteContext(filter->driver(), NULL, NULL),
|
|
filter_(filter),
|
|
element_(element),
|
|
src_(src) {
|
|
}
|
|
|
|
InlineRewriteContext::~InlineRewriteContext() {
|
|
}
|
|
|
|
bool InlineRewriteContext::StartInlining() {
|
|
RewriteDriver* driver = filter_->driver();
|
|
ResourcePtr input_resource;
|
|
const char* url = src_->DecodedValueOrNull();
|
|
if (url != NULL) {
|
|
bool is_authorized;
|
|
input_resource.reset(CreateResource(url, &is_authorized));
|
|
if (input_resource.get() != NULL) {
|
|
ResourceSlotPtr slot(driver->GetSlot(input_resource, element_, src_));
|
|
AddSlot(slot);
|
|
driver->InitiateRewrite(this);
|
|
return true;
|
|
}
|
|
if (!is_authorized) {
|
|
driver->InsertUnauthorizedDomainDebugComment(url, element_);
|
|
}
|
|
} else if (driver->DebugMode()) {
|
|
driver->InsertDebugComment("Following resource not rewritten because its "
|
|
"src attribute cannot be decoded", element_);
|
|
}
|
|
delete this;
|
|
return false;
|
|
}
|
|
|
|
ResourcePtr InlineRewriteContext::CreateResource(const char* url,
|
|
bool* is_authorized) {
|
|
return filter_->CreateInputResource(url, is_authorized);
|
|
}
|
|
|
|
bool InlineRewriteContext::Partition(OutputPartitions* partitions,
|
|
OutputResourceVector* outputs) {
|
|
CHECK_EQ(1, num_slots()) << "InlineRewriteContext only handles one slot";
|
|
ResourcePtr resource(slot(0)->resource());
|
|
|
|
// Always create someplace to store stuff, since we may need debug info.
|
|
CachedResult* partition = partitions->add_partition();
|
|
outputs->push_back(OutputResourcePtr(NULL));
|
|
|
|
bool ok = false;
|
|
GoogleString reason_for_failure;
|
|
if (!resource->IsSafeToRewrite(rewrite_uncacheable(), &reason_for_failure)) {
|
|
AddRecheckDependency();
|
|
} else {
|
|
resource->AddInputInfoToPartition(Resource::kOmitInputHash, 0, partition);
|
|
if (ShouldInline(resource, &reason_for_failure)) {
|
|
StringPiece contents = resource->ExtractUncompressedContents();
|
|
contents.CopyToString(partition->mutable_inlined_data());
|
|
ok = true;
|
|
}
|
|
}
|
|
|
|
if (!ok) {
|
|
partition->add_debug_message(reason_for_failure);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void InlineRewriteContext::Rewrite(int partition_index,
|
|
CachedResult* partition,
|
|
const OutputResourcePtr& output_resource) {
|
|
CHECK(output_resource.get() == NULL);
|
|
CHECK_EQ(0, partition_index);
|
|
|
|
// Mark slot as needing no further processing. Note that needs to be done
|
|
// before calling RewriteDone, as that may cause us to be deleted!
|
|
if (output_partition(0)->has_inlined_data()) {
|
|
slot(0)->set_disable_further_processing(true);
|
|
}
|
|
|
|
// We signal as rewrite failed, as we do not create an output resource.
|
|
RewriteDone(kRewriteFailed, 0);
|
|
}
|
|
|
|
void InlineRewriteContext::Render() {
|
|
if (num_output_partitions() == 1 &&
|
|
output_partition(0)->has_inlined_data() &&
|
|
!slot(0)->should_delete_element()) {
|
|
// We've decided to inline, and no one destroyed our element before us.
|
|
// Set disable_rendering = true because we will render directly here.
|
|
slot(0)->set_disable_rendering(true);
|
|
ResourceSlotPtr our_slot = slot(0);
|
|
RenderInline(
|
|
our_slot->resource(), output_partition(0)->inlined_data(), element_);
|
|
}
|
|
}
|
|
|
|
// We never create output resources, so methods related to them are stubbed.
|
|
OutputResourceKind InlineRewriteContext::kind() const {
|
|
LOG(FATAL);
|
|
return kRewrittenResource;
|
|
}
|
|
|
|
} // namespace net_instaweb
|