blob: 1f73f16d18fef3b2064cce4e7893c73071c4ddf0 [file] [log] [blame]
// Copyright 2015 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 "cobalt/loader/embedded_fetcher.h"
#include <algorithm>
#include "base/bind.h"
#include "base/callback.h"
#include "base/message_loop.h"
#include "base/stringprintf.h"
#include "cobalt/loader/embedded_resources.h" // Generated.
namespace cobalt {
namespace loader {
namespace {
bool EmbeddedURLToKey(const GURL& url, std::string* key) {
DCHECK(url.is_valid() && url.SchemeIs(kEmbeddedScheme));
*key = url.path();
DCHECK_EQ('/', (*key)[0]);
DCHECK_EQ('/', (*key)[1]);
(*key).erase(0, 2);
return !key->empty();
}
} // namespace
const char kEmbeddedScheme[] = "h5vcc-embedded";
EmbeddedFetcher::EmbeddedFetcher(const GURL& url,
const csp::SecurityCallback& security_callback,
Handler* handler, const Options& options)
: Fetcher(handler),
url_(url),
security_callback_(security_callback),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
// Embedded assets are available in-memory and can be loaded synchronously.
Fetch(options);
}
EmbeddedFetcher::~EmbeddedFetcher() {}
void EmbeddedFetcher::Fetch(const Options& options) {
if (!IsAllowedByCsp()) {
std::string msg(base::StringPrintf("URL %s rejected by security policy.",
url_.spec().c_str()));
handler()->OnError(this, msg);
return;
}
std::string key;
if (!EmbeddedURLToKey(url_, &key)) {
std::string msg(
base::StringPrintf("Invalid embedded URL: %s.", url_.spec().c_str()));
handler()->OnError(this, msg);
return;
}
GetEmbeddedData(key, options.start_offset, options.bytes_to_read);
}
void EmbeddedFetcher::GetEmbeddedData(const std::string& key,
int64 start_offset, int64 bytes_to_read) {
const char kDataNotFoundError[] = "Embedded data not found.";
GeneratedResourceMap resource_map;
LoaderEmbeddedResources::GenerateMap(resource_map);
if (resource_map.find(key) == resource_map.end()) {
handler()->OnError(this, kDataNotFoundError);
return;
}
FileContents file_contents = resource_map[key];
const char* data = reinterpret_cast<const char*>(file_contents.data);
size_t size = static_cast<size_t>(file_contents.size);
data += start_offset;
size = std::min(size, static_cast<size_t>(bytes_to_read));
handler()->OnReceived(this, data, size);
handler()->OnDone(this);
}
bool EmbeddedFetcher::IsAllowedByCsp() {
bool did_redirect = false;
if (security_callback_.is_null() ||
security_callback_.Run(url_, did_redirect)) {
return true;
} else {
return false;
}
}
} // namespace loader
} // namespace cobalt