Commit 8fb8eeb9 authored by michaeln@google.com's avatar michaeln@google.com

AppCacheExecutableHandlers - parse manifest file and store/retrieve the 'bit'...

AppCacheExecutableHandlers - parse manifest file and store/retrieve the 'bit' indicating executable.

BUG=101800

Review URL: https://codereview.chromium.org/13881003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@194642 0039d316-1c4b-4281-b951-d872f2087c98
parent 28e0a0e1
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "webkit/appcache/appcache_database.h" #include "webkit/appcache/appcache_database.h"
#include "base/auto_reset.h" #include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/file_util.h" #include "base/file_util.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
...@@ -15,6 +16,8 @@ ...@@ -15,6 +16,8 @@
#include "webkit/appcache/appcache_entry.h" #include "webkit/appcache/appcache_entry.h"
#include "webkit/appcache/appcache_histograms.h" #include "webkit/appcache/appcache_histograms.h"
namespace appcache {
// Schema ------------------------------------------------------------------- // Schema -------------------------------------------------------------------
namespace { namespace {
...@@ -167,13 +170,14 @@ bool CreateIndex(sql::Connection* db, const IndexInfo& info) { ...@@ -167,13 +170,14 @@ bool CreateIndex(sql::Connection* db, const IndexInfo& info) {
} }
std::string GetActiveExperimentFlags() { std::string GetActiveExperimentFlags() {
if (CommandLine::ForCurrentProcess()->HasSwitch(kEnableExecutableHandlers))
return std::string("executableHandlersEnabled");
return std::string(); return std::string();
} }
} // anon namespace } // anon namespace
// AppCacheDatabase ---------------------------------------------------------- // AppCacheDatabase ----------------------------------------------------------
namespace appcache {
AppCacheDatabase::GroupRecord::GroupRecord() AppCacheDatabase::GroupRecord::GroupRecord()
: group_id(0) { : group_id(0) {
...@@ -700,10 +704,19 @@ bool AppCacheDatabase::InsertNamespace( ...@@ -700,10 +704,19 @@ bool AppCacheDatabase::InsertNamespace(
" (cache_id, origin, type, namespace_url, target_url, is_pattern)" " (cache_id, origin, type, namespace_url, target_url, is_pattern)"
" VALUES (?, ?, ?, ?, ?, ?)"; " VALUES (?, ?, ?, ?, ?, ?)";
// Note: quick and dirty storage for the 'executable' bit w/o changing
// schemas, we use the high bit of 'type' field.
int type_with_executable_bit = record->namespace_.type;
if (record->namespace_.is_executable) {
type_with_executable_bit |= 0x8000000;
DCHECK(CommandLine::ForCurrentProcess()->HasSwitch(
kEnableExecutableHandlers));
}
sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
statement.BindInt64(0, record->cache_id); statement.BindInt64(0, record->cache_id);
statement.BindString(1, record->origin.spec()); statement.BindString(1, record->origin.spec());
statement.BindInt(2, record->namespace_.type); statement.BindInt(2, type_with_executable_bit);
statement.BindString(3, record->namespace_.namespace_url.spec()); statement.BindString(3, record->namespace_.namespace_url.spec());
statement.BindString(4, record->namespace_.target_url.spec()); statement.BindString(4, record->namespace_.target_url.spec());
statement.BindBool(5, record->namespace_.is_pattern); statement.BindBool(5, record->namespace_.is_pattern);
...@@ -947,10 +960,19 @@ void AppCacheDatabase::ReadNamespaceRecord( ...@@ -947,10 +960,19 @@ void AppCacheDatabase::ReadNamespaceRecord(
const sql::Statement* statement, NamespaceRecord* record) { const sql::Statement* statement, NamespaceRecord* record) {
record->cache_id = statement->ColumnInt64(0); record->cache_id = statement->ColumnInt64(0);
record->origin = GURL(statement->ColumnString(1)); record->origin = GURL(statement->ColumnString(1));
record->namespace_.type = static_cast<NamespaceType>(statement->ColumnInt(2)); int type_with_executable_bit = statement->ColumnInt(2);
record->namespace_.namespace_url = GURL(statement->ColumnString(3)); record->namespace_.namespace_url = GURL(statement->ColumnString(3));
record->namespace_.target_url = GURL(statement->ColumnString(4)); record->namespace_.target_url = GURL(statement->ColumnString(4));
record->namespace_.is_pattern = statement->ColumnBool(5); record->namespace_.is_pattern = statement->ColumnBool(5);
// Note: quick and dirty storage for the 'executable' bit w/o changing
// schemas, we use the high bit of 'type' field.
record->namespace_.type = static_cast<NamespaceType>
(type_with_executable_bit & 0x7ffffff);
record->namespace_.is_executable =
(type_with_executable_bit & 0x80000000) != 0;
DCHECK(!record->namespace_.is_executable ||
CommandLine::ForCurrentProcess()->HasSwitch(kEnableExecutableHandlers));
} }
void AppCacheDatabase::ReadOnlineWhiteListRecord( void AppCacheDatabase::ReadOnlineWhiteListRecord(
......
...@@ -24,6 +24,7 @@ class AppCacheEntry { ...@@ -24,6 +24,7 @@ class AppCacheEntry {
FOREIGN = 1 << 3, FOREIGN = 1 << 3,
FALLBACK = 1 << 4, FALLBACK = 1 << 4,
INTERCEPT = 1 << 5, INTERCEPT = 1 << 5,
EXECUTABLE = 1 << 6,
}; };
AppCacheEntry() AppCacheEntry()
...@@ -46,6 +47,7 @@ class AppCacheEntry { ...@@ -46,6 +47,7 @@ class AppCacheEntry {
bool IsForeign() const { return (types_ & FOREIGN) != 0; } bool IsForeign() const { return (types_ & FOREIGN) != 0; }
bool IsFallback() const { return (types_ & FALLBACK) != 0; } bool IsFallback() const { return (types_ & FALLBACK) != 0; }
bool IsIntercept() const { return (types_ & INTERCEPT) != 0; } bool IsIntercept() const { return (types_ & INTERCEPT) != 0; }
bool IsExecutable() const { return (types_ & EXECUTABLE) != 0; }
int64 response_id() const { return response_id_; } int64 response_id() const { return response_id_; }
void set_response_id(int64 id) { response_id_ = id; } void set_response_id(int64 id) { response_id_ = id; }
......
...@@ -30,6 +30,8 @@ const char kHttpsScheme[] = "https"; ...@@ -30,6 +30,8 @@ const char kHttpsScheme[] = "https";
const char kHttpGETMethod[] = "GET"; const char kHttpGETMethod[] = "GET";
const char kHttpHEADMethod[] = "HEAD"; const char kHttpHEADMethod[] = "HEAD";
const char kEnableExecutableHandlers[] = "enable-appcache-executable-handlers";
const base::FilePath::CharType kAppCacheDatabaseName[] = const base::FilePath::CharType kAppCacheDatabaseName[] =
FILE_PATH_LITERAL("Index"); FILE_PATH_LITERAL("Index");
...@@ -61,7 +63,8 @@ AppCacheResourceInfo::~AppCacheResourceInfo() { ...@@ -61,7 +63,8 @@ AppCacheResourceInfo::~AppCacheResourceInfo() {
Namespace::Namespace() Namespace::Namespace()
: type(FALLBACK_NAMESPACE), : type(FALLBACK_NAMESPACE),
is_pattern(false) { is_pattern(false),
is_executable(false) {
} }
Namespace::Namespace( Namespace::Namespace(
...@@ -69,7 +72,18 @@ Namespace::Namespace( ...@@ -69,7 +72,18 @@ Namespace::Namespace(
: type(type), : type(type),
namespace_url(url), namespace_url(url),
target_url(target), target_url(target),
is_pattern(is_pattern) { is_pattern(is_pattern),
is_executable(false) {
}
Namespace::Namespace(
NamespaceType type, const GURL& url, const GURL& target,
bool is_pattern, bool is_executable)
: type(type),
namespace_url(url),
target_url(target),
is_pattern(is_pattern),
is_executable(is_executable) {
} }
Namespace::~Namespace() { Namespace::~Namespace() {
......
...@@ -100,6 +100,8 @@ struct WEBKIT_STORAGE_EXPORT Namespace { ...@@ -100,6 +100,8 @@ struct WEBKIT_STORAGE_EXPORT Namespace {
Namespace(); // Type is set to FALLBACK_NAMESPACE by default. Namespace(); // Type is set to FALLBACK_NAMESPACE by default.
Namespace(NamespaceType type, const GURL& url, const GURL& target, Namespace(NamespaceType type, const GURL& url, const GURL& target,
bool is_pattern); bool is_pattern);
Namespace(NamespaceType type, const GURL& url, const GURL& target,
bool is_pattern, bool is_executable);
~Namespace(); ~Namespace();
bool IsMatch(const GURL& url) const; bool IsMatch(const GURL& url) const;
...@@ -108,6 +110,7 @@ struct WEBKIT_STORAGE_EXPORT Namespace { ...@@ -108,6 +110,7 @@ struct WEBKIT_STORAGE_EXPORT Namespace {
GURL namespace_url; GURL namespace_url;
GURL target_url; GURL target_url;
bool is_pattern; bool is_pattern;
bool is_executable;
}; };
typedef std::vector<Namespace> NamespaceVector; typedef std::vector<Namespace> NamespaceVector;
...@@ -171,6 +174,9 @@ extern const char kHttpsScheme[]; ...@@ -171,6 +174,9 @@ extern const char kHttpsScheme[];
extern const char kHttpGETMethod[]; extern const char kHttpGETMethod[];
extern const char kHttpHEADMethod[]; extern const char kHttpHEADMethod[];
// CommandLine flag to turn this experimental feature on.
extern const char kEnableExecutableHandlers[];
WEBKIT_STORAGE_EXPORT void AddSupportedScheme(const char* scheme); WEBKIT_STORAGE_EXPORT void AddSupportedScheme(const char* scheme);
bool IsSchemeSupported(const GURL& url); bool IsSchemeSupported(const GURL& url);
......
...@@ -892,7 +892,10 @@ void AppCacheUpdateJob::BuildUrlFileList(const Manifest& manifest) { ...@@ -892,7 +892,10 @@ void AppCacheUpdateJob::BuildUrlFileList(const Manifest& manifest) {
manifest.intercept_namespaces; manifest.intercept_namespaces;
for (std::vector<Namespace>::const_iterator it = intercepts.begin(); for (std::vector<Namespace>::const_iterator it = intercepts.begin();
it != intercepts.end(); ++it) { it != intercepts.end(); ++it) {
AddUrlToFileList(it->target_url, AppCacheEntry::INTERCEPT); int flags = AppCacheEntry::INTERCEPT;
if (it->is_executable)
flags |= AppCacheEntry::EXECUTABLE;
AddUrlToFileList(it->target_url, flags);
} }
const std::vector<Namespace>& fallbacks = const std::vector<Namespace>& fallbacks =
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/string_util.h" #include "base/string_util.h"
...@@ -104,6 +105,12 @@ void AppCacheURLRequestJob::BeginDelivery() { ...@@ -104,6 +105,12 @@ void AppCacheURLRequestJob::BeginDelivery() {
break; break;
case APPCACHED_DELIVERY: case APPCACHED_DELIVERY:
if (entry_.IsExecutable()) {
DCHECK(CommandLine::ForCurrentProcess()->HasSwitch(
kEnableExecutableHandlers));
// TODO(michaeln): do something different here with
// an AppCacheExecutableHandler.
}
AppCacheHistograms::AddAppCacheJobStartDelaySample( AppCacheHistograms::AddAppCacheJobStartDelaySample(
base::TimeTicks::Now() - start_time_tick_); base::TimeTicks::Now() - start_time_tick_);
request()->net_log().AddEvent( request()->net_log().AddEvent(
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "webkit/appcache/manifest_parser.h" #include "webkit/appcache/manifest_parser.h"
#include "base/command_line.h"
#include "base/i18n/icu_string_conversions.h" #include "base/i18n/icu_string_conversions.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
...@@ -60,7 +61,13 @@ enum Mode { ...@@ -60,7 +61,13 @@ enum Mode {
INTERCEPT, INTERCEPT,
FALLBACK, FALLBACK,
ONLINE_WHITELIST, ONLINE_WHITELIST,
UNKNOWN, UNKNOWN_MODE,
};
enum InterceptVerb {
RETURN,
EXECUTE,
UNKNOWN_VERB,
}; };
Manifest::Manifest() : online_whitelist_all(false) {} Manifest::Manifest() : online_whitelist_all(false) {}
...@@ -165,8 +172,8 @@ bool ParseManifest(const GURL& manifest_url, const char* data, int length, ...@@ -165,8 +172,8 @@ bool ParseManifest(const GURL& manifest_url, const char* data, int length,
} else if (line == L"CHROMIUM-INTERCEPT:") { } else if (line == L"CHROMIUM-INTERCEPT:") {
mode = INTERCEPT; mode = INTERCEPT;
} else if (*(line.end() - 1) == ':') { } else if (*(line.end() - 1) == ':') {
mode = UNKNOWN; mode = UNKNOWN_MODE;
} else if (mode == UNKNOWN) { } else if (mode == UNKNOWN_MODE) {
continue; continue;
} else if (line == L"*" && mode == ONLINE_WHITELIST) { } else if (line == L"*" && mode == ONLINE_WHITELIST) {
manifest.online_whitelist_all = true; manifest.online_whitelist_all = true;
...@@ -250,8 +257,16 @@ bool ParseManifest(const GURL& manifest_url, const char* data, int length, ...@@ -250,8 +257,16 @@ bool ParseManifest(const GURL& manifest_url, const char* data, int length,
++line_p; ++line_p;
// Look for a type value we understand, otherwise skip the line. // Look for a type value we understand, otherwise skip the line.
InterceptVerb verb = UNKNOWN_VERB;
std::wstring type(type_start, line_p - type_start); std::wstring type(type_start, line_p - type_start);
if (type != L"return") if (type == L"return") {
verb = RETURN;
} else if (type == L"execute" &&
CommandLine::ForCurrentProcess()->HasSwitch(
kEnableExecutableHandlers)) {
verb = EXECUTE;
}
if (verb == UNKNOWN_VERB)
continue; continue;
// Skip whitespace separating type from the target_url. // Skip whitespace separating type from the target_url.
...@@ -280,7 +295,7 @@ bool ParseManifest(const GURL& manifest_url, const char* data, int length, ...@@ -280,7 +295,7 @@ bool ParseManifest(const GURL& manifest_url, const char* data, int length,
bool is_pattern = HasPatternMatchingAnnotation(line_p, line_end); bool is_pattern = HasPatternMatchingAnnotation(line_p, line_end);
manifest.intercept_namespaces.push_back( manifest.intercept_namespaces.push_back(
Namespace(INTERCEPT_NAMESPACE, namespace_url, Namespace(INTERCEPT_NAMESPACE, namespace_url,
target_url, is_pattern)); target_url, is_pattern, verb == EXECUTE));
} else if (mode == FALLBACK) { } else if (mode == FALLBACK) {
const wchar_t* line_p = line.c_str(); const wchar_t* line_p = line.c_str();
const wchar_t* line_end = line_p + line.length(); const wchar_t* line_end = line_p + line.length();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment