Create a URLRequestJobFactory to replace the URLRequest globals.
URLRequest::Interceptor and URLRequest::ProtocolFactory are globally registered. This causes a variety of problems. This provides a method for replacing them.
It used to be the case that we used net::URLRequest::IsHandledProtocol()/net::URLRequest::IsHandledURL() to see if the request would be handled by Chrome, or deferred to an external protocol handler. This required that URLRequest be aware of all protocol handlers.
We instead provide ProfileIOData::IsHandledProtocol(), which checks to see if there are any Chrome registered protocol handlers, and if not, checks the default ones in net::URLRequest.
Note this doesn't work for custom handlers (registerProtocolHandler) because they are dynamic and profile-specific. We would have to add a member function to ProfileIOData and not use a global. This is problematic since we check ProfileIOData::IsHandledProtocol in the RenderViewContextMenu, which runs on the UI thread, whereas ProfileIOData lives on the IO thread. RenderViewContextMenu is using also using it synchronously, which makes it a pain to support.
So, we don't support custom handlers in ProfileIOData::IsHandledProtocol(). This means that "save as" won't work for custom handlers. Seems ok for now.
This also fixes the multiprofile/incognito bugs where if a profile registers a custom handler, and then a different profile / an incognito profile registers the same custom handler and then unregisters it, which globally unregisters it, so the original profile is now broken. By removing the use of the globals, we fix this.
Also fixes a bunch of style guide violations in the ProtocolHandler/ProtocolHandlerRegistry code.
This changelist replaces two existing URLRequest::ProtocolFactory uses: chrome-extension/user-script and custom handlers.
Also improve the tests in ResourceDispatcherHost so we don't have to do as many NULL checks. Change the MockResourceContext to create a TestURLRequestContext.
BUG=81979
TEST=none
Review URL: http://codereview.chromium.org/6960006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85376 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/autocomplete/autocomplete.cc b/chrome/browser/autocomplete/autocomplete.cc
index 2de0cfea..5d241dc 100644
--- a/chrome/browser/autocomplete/autocomplete.cc
+++ b/chrome/browser/autocomplete/autocomplete.cc
@@ -27,6 +27,7 @@
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_io_data.h"
#include "chrome/browser/ui/webui/history_ui.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
@@ -159,7 +160,7 @@
!LowerCaseEqualsASCII(parsed_scheme, chrome::kHttpScheme) &&
!LowerCaseEqualsASCII(parsed_scheme, chrome::kHttpsScheme)) {
// See if we know how to handle the URL internally.
- if (net::URLRequest::IsHandledProtocol(UTF16ToASCII(parsed_scheme)))
+ if (ProfileIOData::IsHandledProtocol(UTF16ToASCII(parsed_scheme)))
return URL;
// There are also some schemes that we convert to other things before they
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index f80a813..f71ab40 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -1690,10 +1690,7 @@
// Configure modules that need access to resources.
net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
- // Register our global network handler for chrome:// and
- // chrome-extension:// URLs.
ChromeURLDataManagerBackend::Register();
- RegisterExtensionProtocols();
RegisterMetadataURLRequestHandler();
RegisterBlobURLRequestJobFactory();
RegisterFileSystemURLRequestJobFactory();
diff --git a/chrome/browser/custom_handlers/protocol_handler.cc b/chrome/browser/custom_handlers/protocol_handler.cc
index e9ed3cb..1b2bec1 100644
--- a/chrome/browser/custom_handlers/protocol_handler.cc
+++ b/chrome/browser/custom_handlers/protocol_handler.cc
@@ -11,34 +11,36 @@
ProtocolHandler::ProtocolHandler(const std::string& protocol,
const GURL& url,
const string16& title)
- : protocol_(protocol),
- url_(url),
- title_(title) {
+ : protocol_(protocol),
+ url_(url),
+ title_(title) {
}
ProtocolHandler ProtocolHandler::CreateProtocolHandler(
const std::string& protocol,
const GURL& url,
const string16& title) {
- std::string lower_protocol(protocol);
- lower_protocol = StringToLowerASCII(protocol);
+ std::string lower_protocol = StringToLowerASCII(protocol);
return ProtocolHandler(lower_protocol, url, title);
}
ProtocolHandler::ProtocolHandler() {
}
-const ProtocolHandler ProtocolHandler::kEmpty;
-
bool ProtocolHandler::IsValidDict(const DictionaryValue* value) {
return value->HasKey("protocol") && value->HasKey("url") &&
value->HasKey("title");
}
+const ProtocolHandler& ProtocolHandler::EmptyProtocolHandler() {
+ static const ProtocolHandler* const kEmpty = new ProtocolHandler();
+ return *kEmpty;
+}
+
ProtocolHandler ProtocolHandler::CreateProtocolHandler(
const DictionaryValue* value) {
if (!IsValidDict(value)) {
- return kEmpty;
+ return EmptyProtocolHandler();
}
std::string protocol, url;
string16 title;
@@ -48,14 +50,14 @@
return ProtocolHandler::CreateProtocolHandler(protocol, GURL(url), title);
}
-GURL ProtocolHandler::TranslateUrl(const GURL& url) {
+GURL ProtocolHandler::TranslateUrl(const GURL& url) const {
std::string translatedUrlSpec(url_.spec());
ReplaceSubstringsAfterOffset(&translatedUrlSpec, 0, "%s",
EscapeQueryParamValue(url.spec(), true));
return GURL(translatedUrlSpec);
}
-DictionaryValue* ProtocolHandler::Encode() {
+DictionaryValue* ProtocolHandler::Encode() const {
DictionaryValue* d = new DictionaryValue();
d->Set("protocol", Value::CreateStringValue(protocol_));
d->Set("url", Value::CreateStringValue(url_.spec()));
@@ -63,9 +65,8 @@
return d;
}
-bool ProtocolHandler::operator==(const ProtocolHandler &other) const {
+bool ProtocolHandler::operator==(const ProtocolHandler& other) const {
return protocol_ == other.protocol_ &&
url_ == other.url_ &&
title_ == other.title_;
}
-
diff --git a/chrome/browser/custom_handlers/protocol_handler.h b/chrome/browser/custom_handlers/protocol_handler.h
index 36387b5..e145222 100644
--- a/chrome/browser/custom_handlers/protocol_handler.h
+++ b/chrome/browser/custom_handlers/protocol_handler.h
@@ -29,23 +29,21 @@
static bool IsValidDict(const DictionaryValue* value);
// Canonical empty ProtocolHandler.
- static const ProtocolHandler kEmpty;
-
- explicit ProtocolHandler();
+ static const ProtocolHandler& EmptyProtocolHandler();
// Interpolates the given URL into the URL template of this handler.
- GURL TranslateUrl(const GURL& url);
+ GURL TranslateUrl(const GURL& url) const;
// Encodes this protocol handler as a DictionaryValue. The caller is
// responsible for deleting the returned value.
- DictionaryValue* Encode();
+ DictionaryValue* Encode() const;
- std::string protocol() const { return protocol_; }
- GURL url() const { return url_;}
- string16 title() const { return title_; }
+ const std::string& protocol() const { return protocol_; }
+ const GURL& url() const { return url_;}
+ const string16& title() const { return title_; }
bool IsEmpty() const {
- return protocol_ == "";
+ return protocol_.empty();
}
bool operator==(const ProtocolHandler &other) const;
@@ -54,10 +52,11 @@
ProtocolHandler(const std::string& protocol,
const GURL& url,
const string16& title);
+ ProtocolHandler();
+
std::string protocol_;
GURL url_;
string16 title_;
};
#endif // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_H_
-
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc
index 7edb280..b4991e2 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -4,11 +4,14 @@
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
+#include <utility>
+
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/custom_handlers/protocol_handler.h"
#include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/profiles/profile_io_data.h"
#include "chrome/common/pref_names.h"
#include "content/browser/child_process_security_policy.h"
#include "net/base/network_delegate.h"
@@ -19,16 +22,16 @@
ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile,
Delegate* delegate)
- : profile_(profile),
- delegate_(delegate),
- enabled_(true) {
+ : profile_(profile),
+ delegate_(delegate),
+ enabled_(true) {
}
ProtocolHandlerRegistry::~ProtocolHandlerRegistry() {
}
-ProtocolHandlerList& ProtocolHandlerRegistry::GetHandlerListFor(
- const std::string& scheme) {
+ProtocolHandlerRegistry::ProtocolHandlerList&
+ProtocolHandlerRegistry::GetHandlerListFor(const std::string& scheme) {
ProtocolHandlerMultiMap::iterator p = protocol_handlers_.find(scheme);
if (p == protocol_handlers_.end()) {
protocol_handlers_[scheme] = ProtocolHandlerList();
@@ -60,7 +63,7 @@
}
enabled_ = true;
for (ProtocolHandlerMultiMap::const_iterator p = protocol_handlers_.begin();
- p != protocol_handlers_.end(); p++) {
+ p != protocol_handlers_.end(); ++p) {
delegate_->RegisterExternalHandler(p->first);
}
}
@@ -71,13 +74,13 @@
}
enabled_ = false;
for (ProtocolHandlerMultiMap::const_iterator p = protocol_handlers_.begin();
- p != protocol_handlers_.end(); p++) {
+ p != protocol_handlers_.end(); ++p) {
delegate_->DeregisterExternalHandler(p->first);
}
}
std::vector<const DictionaryValue*>
-ProtocolHandlerRegistry::GetHandlersFromPref(const char* pref_name) {
+ProtocolHandlerRegistry::GetHandlersFromPref(const char* pref_name) const {
std::vector<const DictionaryValue*> result;
PrefService* prefs = profile_->GetPrefs();
if (!prefs->HasPrefPath(pref_name)) {
@@ -86,7 +89,7 @@
const ListValue* handlers = prefs->GetList(pref_name);
if (handlers) {
- for (size_t i = 0; i < handlers->GetSize(); i++) {
+ for (size_t i = 0; i < handlers->GetSize(); ++i) {
DictionaryValue* dict;
handlers->GetDictionary(i, &dict);
if (ProtocolHandler::IsValidDict(dict)) {
@@ -107,7 +110,7 @@
GetHandlersFromPref(prefs::kRegisteredProtocolHandlers);
for (std::vector<const DictionaryValue*>::const_iterator p =
registered_handlers.begin();
- p != registered_handlers.end(); p++) {
+ p != registered_handlers.end(); ++p) {
ProtocolHandler handler = ProtocolHandler::CreateProtocolHandler(*p);
RegisterProtocolHandler(handler);
bool is_default = false;
@@ -118,8 +121,8 @@
std::vector<const DictionaryValue*> ignored_handlers =
GetHandlersFromPref(prefs::kIgnoredProtocolHandlers);
for (std::vector<const DictionaryValue*>::const_iterator p =
- ignored_handlers.begin();
- p != ignored_handlers.end(); p++) {
+ ignored_handlers.begin();
+ p != ignored_handlers.end(); ++p) {
IgnoreProtocolHandler(ProtocolHandler::CreateProtocolHandler(*p));
}
is_loading_ = false;
@@ -157,7 +160,7 @@
void ProtocolHandlerRegistry::GetHandledProtocols(
std::vector<std::string>* output) const {
ProtocolHandlerMultiMap::const_iterator p;
- for (p = protocol_handlers_.begin(); p != protocol_handlers_.end(); p++) {
+ for (p = protocol_handlers_.begin(); p != protocol_handlers_.end(); ++p) {
output->push_back(p->first);
}
}
@@ -165,7 +168,7 @@
void ProtocolHandlerRegistry::RemoveIgnoredHandler(
const ProtocolHandler& handler) {
for (ProtocolHandlerList::iterator p = ignored_protocol_handlers_.begin();
- p != ignored_protocol_handlers_.end(); p++) {
+ p != ignored_protocol_handlers_.end(); ++p) {
if (handler == *p) {
ignored_protocol_handlers_.erase(p);
break;
@@ -181,7 +184,7 @@
bool ProtocolHandlerRegistry::IsIgnored(const ProtocolHandler& handler) const {
ProtocolHandlerList::const_iterator i;
for (i = ignored_protocol_handlers_.begin();
- i != ignored_protocol_handlers_.end(); i++) {
+ i != ignored_protocol_handlers_.end(); ++i) {
if (*i == handler) {
return true;
}
@@ -202,17 +205,12 @@
handlers.erase(p);
}
- if (default_handlers_[handler.protocol()] == handler) {
- default_handlers_.erase(handler.protocol());
+ ProtocolHandlerMap::iterator it = default_handlers_.find(handler.protocol());
+ if (it != default_handlers_.end() && it->second == handler) {
+ default_handlers_.erase(it);
}
}
-net::URLRequestJob* ProtocolHandlerRegistry::Factory(net::URLRequest* request,
- const std::string& scheme) {
- return request->context()->network_delegate()->MaybeCreateURLRequestJob(
- request);
-}
-
net::URLRequestJob* ProtocolHandlerRegistry::MaybeCreateJob(
net::URLRequest* request) const {
ProtocolHandler handler = GetHandlerFor(request->url().scheme());
@@ -234,9 +232,9 @@
ListValue* protocol_handlers = new ListValue();
for (ProtocolHandlerMultiMap::iterator i = protocol_handlers_.begin();
- i != protocol_handlers_.end(); ++i) {
+ i != protocol_handlers_.end(); ++i) {
for (ProtocolHandlerList::iterator j = i->second.begin();
- j != i->second.end(); j++) {
+ j != i->second.end(); ++j) {
DictionaryValue* encoded = j->Encode();
if (IsDefault(*j)) {
encoded->Set("default", Value::CreateBooleanValue(true));
@@ -251,7 +249,7 @@
ListValue* handlers = new ListValue();
for (ProtocolHandlerList::iterator i = ignored_protocol_handlers_.begin();
- i != ignored_protocol_handlers_.end(); ++i) {
+ i != ignored_protocol_handlers_.end(); ++i) {
handlers->Append(i->Encode());
}
return handlers;
@@ -273,17 +271,18 @@
Save();
}
-void ProtocolHandlerRegistry::RegisterPrefs(PrefService* prefService) {
- prefService->RegisterListPref(prefs::kRegisteredProtocolHandlers,
- PrefService::UNSYNCABLE_PREF);
- prefService->RegisterListPref(prefs::kIgnoredProtocolHandlers,
- PrefService::UNSYNCABLE_PREF);
- prefService->RegisterBooleanPref(prefs::kCustomHandlersEnabled, true,
- PrefService::UNSYNCABLE_PREF);
+void ProtocolHandlerRegistry::RegisterPrefs(PrefService* pref_service) {
+ pref_service->RegisterListPref(prefs::kRegisteredProtocolHandlers,
+ PrefService::UNSYNCABLE_PREF);
+ pref_service->RegisterListPref(prefs::kIgnoredProtocolHandlers,
+ PrefService::UNSYNCABLE_PREF);
+ pref_service->RegisterBooleanPref(prefs::kCustomHandlersEnabled, true,
+ PrefService::UNSYNCABLE_PREF);
}
void ProtocolHandlerRegistry::SetDefault(const ProtocolHandler& handler) {
- default_handlers_[handler.protocol()] = handler;
+ default_handlers_.erase(handler.protocol());
+ default_handlers_.insert(std::make_pair(handler.protocol(), handler));
Save();
}
@@ -307,7 +306,7 @@
if (q != protocol_handlers_.end() && q->second.size() == 1) {
return q->second[0];
}
- return ProtocolHandler::kEmpty;
+ return ProtocolHandler::EmptyProtocolHandler();
}
bool ProtocolHandlerRegistry::HasDefault(
@@ -331,16 +330,13 @@
if (!policy->IsWebSafeScheme(protocol)) {
policy->RegisterWebSafeScheme(protocol);
}
- net::URLRequest::RegisterProtocolFactory(protocol,
- &ProtocolHandlerRegistry::Factory);
}
void ProtocolHandlerRegistry::Delegate::DeregisterExternalHandler(
const std::string& protocol) {
- net::URLRequest::RegisterProtocolFactory(protocol, NULL);
}
bool ProtocolHandlerRegistry::Delegate::IsExternalHandlerRegistered(
const std::string& protocol) {
- return net::URLRequest::IsHandledProtocol(protocol);
+ return ProfileIOData::IsHandledProtocol(protocol);
}
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.h b/chrome/browser/custom_handlers/protocol_handler_registry.h
index 8ce29eed..eaeb0c6 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.h
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.h
@@ -18,10 +18,6 @@
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"
-typedef std::map<std::string, ProtocolHandler> ProtocolHandlerMap;
-typedef std::vector<ProtocolHandler> ProtocolHandlerList;
-typedef std::map<std::string, ProtocolHandlerList> ProtocolHandlerMultiMap;
-
// This is where handlers for protocols registered with
// navigator.registerProtocolHandler() are registered. Each Profile owns an
// instance of this class, which is initialized on browser start through
@@ -31,7 +27,16 @@
class ProtocolHandlerRegistry
: public base::RefCountedThreadSafe<ProtocolHandlerRegistry> {
public:
- class Delegate;
+ // TODO(koz): Refactor this to eliminate the unnecessary virtuals. All that
+ // should be needed is a way to ensure that the list of websafe protocols is
+ // updated.
+ class Delegate {
+ public:
+ virtual ~Delegate();
+ virtual void RegisterExternalHandler(const std::string& protocol);
+ virtual void DeregisterExternalHandler(const std::string& protocol);
+ virtual bool IsExternalHandlerRegistered(const std::string& protocol);
+ };
ProtocolHandlerRegistry(Profile* profile, Delegate* delegate);
~ProtocolHandlerRegistry();
@@ -94,11 +99,6 @@
// Causes the given protocol handler to not be ignored anymore.
void RemoveIgnoredHandler(const ProtocolHandler& handler);
- // URLRequestFactory for use with URLRequest::RegisterProtocolFactory().
- // Redirects any URLRequests for which there is a matching protocol handler.
- static net::URLRequestJob* Factory(net::URLRequest* request,
- const std::string& scheme);
-
// Registers the preferences that we store registered protocol handlers in.
static void RegisterPrefs(PrefService* prefService);
@@ -114,20 +114,15 @@
// will not handle requests.
void Disable();
- bool enabled() { return enabled_; }
-
- class Delegate {
- public:
- virtual ~Delegate();
- virtual void RegisterExternalHandler(const std::string& protocol);
- virtual void DeregisterExternalHandler(const std::string& protocol);
- virtual bool IsExternalHandlerRegistered(const std::string& protocol);
- };
+ bool enabled() const { return enabled_; }
private:
-
friend class base::RefCountedThreadSafe<ProtocolHandlerRegistry>;
+ typedef std::map<std::string, ProtocolHandler> ProtocolHandlerMap;
+ typedef std::vector<ProtocolHandler> ProtocolHandlerList;
+ typedef std::map<std::string, ProtocolHandlerList> ProtocolHandlerMultiMap;
+
// Returns a JSON list of protocol handlers. The caller is responsible for
// deleting this Value.
Value* EncodeRegisteredHandlers();
@@ -142,7 +137,7 @@
// Get the DictionaryValues stored under the given pref name that are valid
// ProtocolHandler values.
std::vector<const DictionaryValue*> GetHandlersFromPref(
- const char* pref_name);
+ const char* pref_name) const;
// Ignores future requests to register the given protocol handler.
void IgnoreProtocolHandler(const ProtocolHandler& handler);
@@ -180,4 +175,3 @@
DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry);
};
#endif // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_
-
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
index 982d4517..5613be7 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
@@ -42,7 +42,10 @@
class ProtocolHandlerRegistryTest : public testing::Test {
- public:
+ protected:
+ ProtocolHandlerRegistryTest()
+ : test_protocol_handler_(CreateProtocolHandler("test", "test")) {}
+
FakeDelegate* delegate() const { return delegate_; }
TestingProfile* profile() const { return profile_.get(); }
PrefService* pref_service() const { return profile_->GetPrefs(); }
@@ -70,9 +73,7 @@
registry_->Load();
}
- private:
virtual void SetUp() {
- test_protocol_handler_ = CreateProtocolHandler("test", "test");
profile_.reset(new TestingProfile());
profile_->SetPrefService(new TestingPrefService());
delegate_ = new FakeDelegate();
diff --git a/chrome/browser/extensions/extension_protocols.cc b/chrome/browser/extensions/extension_protocols.cc
index 10bc072..d7eac2f8 100644
--- a/chrome/browser/extensions/extension_protocols.cc
+++ b/chrome/browser/extensions/extension_protocols.cc
@@ -119,8 +119,8 @@
// TODO(aa): This should be moved into ExtensionResourceRequestPolicy, but we
// first need to find a way to get CanLoadInIncognito state into the renderers.
bool AllowExtensionResourceLoad(net::URLRequest* request,
- ChromeURLRequestContext* context,
- const std::string& scheme) {
+ bool is_incognito,
+ ExtensionInfoMap* extension_info_map) {
const ResourceDispatcherHostRequestInfo* info =
ResourceDispatcherHost::InfoForRequest(request);
@@ -135,10 +135,9 @@
// Don't allow toplevel navigations to extension resources in incognito mode.
// This is because an extension must run in a single process, and an
// incognito tab prevents that.
- if (context->is_incognito() &&
+ if (is_incognito &&
info->resource_type() == ResourceType::MAIN_FRAME &&
- !context->extension_info_map()->
- ExtensionCanLoadInIncognito(request->url().host())) {
+ !extension_info_map->ExtensionCanLoadInIncognito(request->url().host())) {
LOG(ERROR) << "Denying load of " << request->url().spec() << " from "
<< "incognito tab.";
return false;
@@ -147,29 +146,42 @@
return true;
}
-} // namespace
+class ExtensionProtocolHandler
+ : public net::URLRequestJobFactory::ProtocolHandler {
+ public:
+ ExtensionProtocolHandler(bool is_incognito,
+ ExtensionInfoMap* extension_info_map)
+ : is_incognito_(is_incognito),
+ extension_info_map_(extension_info_map) {}
-// Factory registered with net::URLRequest to create URLRequestJobs for
-// extension:// URLs.
-static net::URLRequestJob* CreateExtensionURLRequestJob(
- net::URLRequest* request,
- const std::string& scheme) {
- ChromeURLRequestContext* context =
- static_cast<ChromeURLRequestContext*>(request->context());
+ virtual ~ExtensionProtocolHandler() {}
+ virtual net::URLRequestJob* MaybeCreateJob(
+ net::URLRequest* request) const OVERRIDE;
+
+ private:
+ const bool is_incognito_;
+ ExtensionInfoMap* const extension_info_map_;
+ DISALLOW_COPY_AND_ASSIGN(ExtensionProtocolHandler);
+};
+
+// Creates URLRequestJobs for extension:// URLs.
+net::URLRequestJob*
+ExtensionProtocolHandler::MaybeCreateJob(net::URLRequest* request) const {
// TODO(mpcomplete): better error code.
- if (!AllowExtensionResourceLoad(request, context, scheme)) {
+ if (!AllowExtensionResourceLoad(
+ request, is_incognito_, extension_info_map_)) {
LOG(ERROR) << "disallowed in extension protocols";
return new net::URLRequestErrorJob(request, net::ERR_ADDRESS_UNREACHABLE);
}
// chrome-extension://extension-id/resource/path.js
const std::string& extension_id = request->url().host();
- FilePath directory_path = context->extension_info_map()->
+ FilePath directory_path = extension_info_map_->
GetPathForExtension(extension_id);
if (directory_path.value().empty()) {
- if (context->extension_info_map()->URLIsForExtensionIcon(request->url()))
- directory_path = context->extension_info_map()->
+ if (extension_info_map_->URLIsForExtensionIcon(request->url()))
+ directory_path = extension_info_map_->
GetPathForDisabledExtension(extension_id);
if (directory_path.value().empty()) {
LOG(WARNING) << "Failed to GetPathForExtension: " << extension_id;
@@ -177,7 +189,7 @@
}
}
- const std::string& content_security_policy = context->extension_info_map()->
+ const std::string& content_security_policy = extension_info_map_->
GetContentSecurityPolicyForExtension(extension_id);
FilePath resources_path;
@@ -221,26 +233,47 @@
content_security_policy);
}
+class UserScriptProtocolHandler
+ : public net::URLRequestJobFactory::ProtocolHandler {
+ public:
+ UserScriptProtocolHandler(const FilePath& user_script_dir_path,
+ ExtensionInfoMap* extension_info_map)
+ : user_script_dir_path_(user_script_dir_path),
+ extension_info_map_(extension_info_map) {}
+
+ virtual ~UserScriptProtocolHandler() {}
+
+ virtual net::URLRequestJob* MaybeCreateJob(
+ net::URLRequest* request) const OVERRIDE;
+
+ private:
+ const FilePath user_script_dir_path_;
+ ExtensionInfoMap* const extension_info_map_;
+};
+
// Factory registered with net::URLRequest to create URLRequestJobs for
// chrome-user-script:/ URLs.
-static net::URLRequestJob* CreateUserScriptURLRequestJob(
- net::URLRequest* request,
- const std::string& scheme) {
- ChromeURLRequestContext* context =
- static_cast<ChromeURLRequestContext*>(request->context());
-
+net::URLRequestJob* UserScriptProtocolHandler::MaybeCreateJob(
+ net::URLRequest* request) const {
// chrome-user-script:/user-script-name.user.js
- FilePath directory_path = context->user_script_dir_path();
-
- ExtensionResource resource(request->url().host(), directory_path,
+ ExtensionResource resource(
+ request->url().host(), user_script_dir_path_,
extension_file_util::ExtensionURLToRelativeFilePath(request->url()));
return new net::URLRequestFileJob(request, resource.GetFilePath());
}
-void RegisterExtensionProtocols() {
- net::URLRequest::RegisterProtocolFactory(chrome::kExtensionScheme,
- &CreateExtensionURLRequestJob);
- net::URLRequest::RegisterProtocolFactory(chrome::kUserScriptScheme,
- &CreateUserScriptURLRequestJob);
+} // namespace
+
+net::URLRequestJobFactory::ProtocolHandler* CreateExtensionProtocolHandler(
+ bool is_incognito,
+ ExtensionInfoMap* extension_info_map) {
+ return new ExtensionProtocolHandler(is_incognito, extension_info_map);
+}
+
+net::URLRequestJobFactory::ProtocolHandler* CreateUserScriptProtocolHandler(
+ const FilePath& user_script_dir_path,
+ ExtensionInfoMap* extension_info_map) {
+ return new UserScriptProtocolHandler(
+ user_script_dir_path, extension_info_map);
}
diff --git a/chrome/browser/extensions/extension_protocols.h b/chrome/browser/extensions/extension_protocols.h
index b8bc4f1..06ff2de 100644
--- a/chrome/browser/extensions/extension_protocols.h
+++ b/chrome/browser/extensions/extension_protocols.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,7 +6,19 @@
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_PROTOCOLS_H_
#pragma once
-// Registers support for the extension URL scheme.
-void RegisterExtensionProtocols();
+#include "net/url_request/url_request_job_factory.h"
+
+class ExtensionInfoMap;
+class FilePath;
+
+// Creates the handlers for the chrome-extension:// scheme.
+net::URLRequestJobFactory::ProtocolHandler* CreateExtensionProtocolHandler(
+ bool is_incognito,
+ ExtensionInfoMap* extension_info_map);
+
+// Creates the handlers for the chrome-user-script:// scheme.
+net::URLRequestJobFactory::ProtocolHandler* CreateUserScriptProtocolHandler(
+ const FilePath& user_script_dir_path,
+ ExtensionInfoMap* extension_info_map);
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_PROTOCOLS_H_
diff --git a/chrome/browser/extensions/extension_webrequest_api_unittest.cc b/chrome/browser/extensions/extension_webrequest_api_unittest.cc
index 5207079..e2ace67 100644
--- a/chrome/browser/extensions/extension_webrequest_api_unittest.cc
+++ b/chrome/browser/extensions/extension_webrequest_api_unittest.cc
@@ -71,7 +71,7 @@
prefs::kEnableReferrers, profile_.GetTestingPrefService(), NULL);
network_delegate_.reset(new ChromeNetworkDelegate(
event_router_.get(), profile_.GetRuntimeId(),
- &enable_referrers_, NULL));
+ &enable_referrers_));
context_ = new TestURLRequestContext();
context_->set_network_delegate(network_delegate_.get());
}
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 0bc6ee8..8aa6e01e 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -419,8 +419,7 @@
globals_->system_network_delegate.reset(new ChromeNetworkDelegate(
extension_event_router_forwarder_,
Profile::kInvalidProfileId,
- &system_enable_referrers_,
- NULL));
+ &system_enable_referrers_));
globals_->host_resolver.reset(
CreateGlobalHostResolver(net_log_));
globals_->cert_verifier.reset(new net::CertVerifier);
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc
index ee3afad..e2238282 100644
--- a/chrome/browser/net/chrome_network_delegate.cc
+++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -5,7 +5,6 @@
#include "chrome/browser/net/chrome_network_delegate.h"
#include "base/logging.h"
-#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
#include "chrome/browser/extensions/extension_event_router_forwarder.h"
#include "chrome/browser/extensions/extension_proxy_api.h"
#include "chrome/browser/extensions/extension_webrequest_api.h"
@@ -41,12 +40,10 @@
ChromeNetworkDelegate::ChromeNetworkDelegate(
ExtensionEventRouterForwarder* event_router,
ProfileId profile_id,
- BooleanPrefMember* enable_referrers,
- ProtocolHandlerRegistry* protocol_handler_registry)
+ BooleanPrefMember* enable_referrers)
: event_router_(event_router),
profile_id_(profile_id),
- enable_referrers_(enable_referrers),
- protocol_handler_registry_(protocol_handler_registry) {
+ enable_referrers_(enable_referrers) {
DCHECK(event_router);
DCHECK(enable_referrers);
}
@@ -127,13 +124,6 @@
profile_id_, request_id);
}
-net::URLRequestJob* ChromeNetworkDelegate::OnMaybeCreateURLRequestJob(
- net::URLRequest* request) {
- if (!protocol_handler_registry_)
- return NULL;
- return protocol_handler_registry_->MaybeCreateJob(request);
-}
-
void ChromeNetworkDelegate::OnPACScriptError(int line_number,
const string16& error) {
ExtensionProxyEventRouter::GetInstance()->OnPACScriptError(
diff --git a/chrome/browser/net/chrome_network_delegate.h b/chrome/browser/net/chrome_network_delegate.h
index aa556de..ad6fd3c 100644
--- a/chrome/browser/net/chrome_network_delegate.h
+++ b/chrome/browser/net/chrome_network_delegate.h
@@ -7,13 +7,13 @@
#pragma once
#include "base/basictypes.h"
+#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/profiles/profile.h"
#include "net/base/network_delegate.h"
class ExtensionEventRouterForwarder;
template<class T> class PrefMember;
-class ProtocolHandlerRegistry;
typedef PrefMember<bool> BooleanPrefMember;
@@ -29,22 +29,22 @@
ChromeNetworkDelegate(
ExtensionEventRouterForwarder* event_router,
ProfileId profile_id,
- BooleanPrefMember* enable_referrers,
- ProtocolHandlerRegistry* protocol_handler_registry);
+ BooleanPrefMember* enable_referrers);
virtual ~ChromeNetworkDelegate();
// Binds |enable_referrers| to |pref_service| and moves it to the IO thread.
// This method should be called on the UI thread.
static void InitializeReferrersEnabled(BooleanPrefMember* enable_referrers,
PrefService* pref_service);
+
private:
// NetworkDelegate methods:
virtual int OnBeforeURLRequest(net::URLRequest* request,
net::CompletionCallback* callback,
- GURL* new_url);
+ GURL* new_url) OVERRIDE;
virtual int OnBeforeSendHeaders(uint64 request_id,
net::CompletionCallback* callback,
- net::HttpRequestHeaders* headers);
+ net::HttpRequestHeaders* headers) OVERRIDE;
virtual void OnRequestSent(uint64 request_id,
const net::HostPortPair& socket_address,
const net::HttpRequestHeaders& headers);
@@ -54,8 +54,6 @@
virtual void OnCompleted(net::URLRequest* request);
virtual void OnURLRequestDestroyed(net::URLRequest* request);
virtual void OnHttpTransactionDestroyed(uint64 request_id);
- virtual net::URLRequestJob* OnMaybeCreateURLRequestJob(
- net::URLRequest* request);
virtual void OnPACScriptError(int line_number, const string16& error);
scoped_refptr<ExtensionEventRouterForwarder> event_router_;
@@ -63,7 +61,7 @@
// Weak, owned by our owner.
BooleanPrefMember* enable_referrers_;
- scoped_refptr<ProtocolHandlerRegistry> protocol_handler_registry_;
+
DISALLOW_COPY_AND_ASSIGN(ChromeNetworkDelegate);
};
diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc
index 644dbfe1..1d100608 100644
--- a/chrome/browser/profiles/off_the_record_profile_io_data.cc
+++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc
@@ -178,6 +178,9 @@
main_context->set_http_transaction_factory(cache);
main_context->set_ftp_transaction_factory(
new net::FtpNetworkLayer(main_context->host_resolver()));
+
+ main_context->set_job_factory(job_factory());
+ extensions_context->set_job_factory(job_factory());
}
scoped_refptr<ProfileIOData::RequestContext>
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index 33bd8b8..a1afa801 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -272,8 +272,7 @@
main_context->set_cookie_store(cookie_store);
media_request_context_->set_cookie_store(cookie_store);
- extensions_context->set_cookie_store(
- extensions_cookie_store);
+ extensions_context->set_cookie_store(extensions_cookie_store);
main_http_factory_.reset(main_cache);
media_http_factory_.reset(media_cache);
@@ -283,6 +282,10 @@
main_context->set_ftp_transaction_factory(
new net::FtpNetworkLayer(io_thread_globals->host_resolver.get()));
+ main_context->set_job_factory(job_factory());
+ media_request_context_->set_job_factory(job_factory());
+ extensions_context->set_job_factory(job_factory());
+
lazy_params_.reset();
}
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index c34684d..49bc4867 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
+#include "chrome/browser/extensions/extension_protocols.h"
#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/io_thread.h"
#include "chrome/browser/net/chrome_cookie_notification_details.h"
@@ -28,6 +29,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
#include "content/browser/browser_thread.h"
#include "content/browser/host_zoom_map.h"
#include "content/browser/resource_context.h"
@@ -36,6 +38,7 @@
#include "net/proxy/proxy_config_service_fixed.h"
#include "net/proxy/proxy_script_fetcher_impl.h"
#include "net/proxy/proxy_service.h"
+#include "net/url_request/url_request.h"
#include "webkit/database/database_tracker.h"
#include "webkit/quota/quota_manager.h"
@@ -129,6 +132,38 @@
scoped_refptr<ProfileGetter> profile_getter_;
};
+class ProtocolHandlerRegistryInterceptor
+ : public net::URLRequestJobFactory::Interceptor {
+ public:
+ explicit ProtocolHandlerRegistryInterceptor(
+ ProtocolHandlerRegistry* protocol_handler_registry)
+ : protocol_handler_registry_(protocol_handler_registry) {
+ DCHECK(protocol_handler_registry_);
+ }
+
+ virtual ~ProtocolHandlerRegistryInterceptor() {}
+
+ virtual net::URLRequestJob* MaybeIntercept(
+ net::URLRequest* request) const OVERRIDE {
+ return protocol_handler_registry_->MaybeCreateJob(request);
+ }
+
+ virtual net::URLRequestJob* MaybeInterceptRedirect(
+ const GURL& url, net::URLRequest* request) const OVERRIDE {
+ return NULL;
+ }
+
+ virtual net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request) const OVERRIDE {
+ return NULL;
+ }
+
+ private:
+ const scoped_refptr<ProtocolHandlerRegistry> protocol_handler_registry_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistryInterceptor);
+};
+
} // namespace
void ProfileIOData::InitializeProfileParams(Profile* profile) {
@@ -221,6 +256,29 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
}
+// static
+bool ProfileIOData::IsHandledProtocol(const std::string& scheme) {
+ DCHECK_EQ(scheme, StringToLowerASCII(scheme));
+ static const char* const kProtocolList[] = {
+ chrome::kExtensionScheme,
+ chrome::kUserScriptScheme,
+ };
+ for (size_t i = 0; i < arraysize(kProtocolList); ++i) {
+ if (scheme == kProtocolList[i])
+ return true;
+ }
+ return net::URLRequest::IsHandledProtocol(scheme);
+}
+
+bool ProfileIOData::IsHandledURL(const GURL& url) {
+ if (!url.is_valid()) {
+ // We handle error cases.
+ return true;
+ }
+
+ return IsHandledProtocol(url.scheme());
+}
+
scoped_refptr<ChromeURLRequestContext>
ProfileIOData::GetMainRequestContext() const {
LazyInitialize();
@@ -298,8 +356,7 @@
network_delegate_.reset(new ChromeNetworkDelegate(
io_thread_globals->extension_event_router_forwarder.get(),
profile_params_->profile_id,
- &enable_referrers_,
- profile_params_->protocol_handler_registry));
+ &enable_referrers_));
dns_cert_checker_.reset(
CreateDnsCertProvenanceChecker(io_thread_globals->dnsrr_resolver.get(),
@@ -312,6 +369,25 @@
profile_params_->proxy_config_service.release(),
command_line));
+ // NOTE(willchan): Keep these protocol handlers in sync with
+ // ProfileIOData::IsHandledProtocol().
+ job_factory_.reset(new net::URLRequestJobFactory);
+ if (profile_params_->protocol_handler_registry) {
+ job_factory_->AddInterceptor(
+ new ProtocolHandlerRegistryInterceptor(
+ profile_params_->protocol_handler_registry));
+ }
+ bool set_protocol = job_factory_->SetProtocolHandler(
+ chrome::kExtensionScheme,
+ CreateExtensionProtocolHandler(profile_params_->is_incognito,
+ profile_params_->extension_info_map));
+ DCHECK(set_protocol);
+ set_protocol = job_factory_->SetProtocolHandler(
+ chrome::kUserScriptScheme,
+ CreateUserScriptProtocolHandler(profile_params_->user_script_dir_path,
+ profile_params_->extension_info_map));
+ DCHECK(set_protocol);
+
// Take ownership over these parameters.
database_tracker_ = profile_params_->database_tracker;
appcache_service_ = profile_params_->appcache_service;
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h
index ba33f3c8..cfa0bfe 100644
--- a/chrome/browser/profiles/profile_io_data.h
+++ b/chrome/browser/profiles/profile_io_data.h
@@ -64,6 +64,14 @@
// accessor.
class ProfileIOData : public base::RefCountedThreadSafe<ProfileIOData> {
public:
+ // Returns true if |scheme| is handled in Chrome, or by default handlers in
+ // net::URLRequest.
+ static bool IsHandledProtocol(const std::string& scheme);
+
+ // Returns true if |url| is handled in Chrome, or by default handlers in
+ // net::URLRequest.
+ static bool IsHandledURL(const GURL& url);
+
// These should only be called at most once each. Ownership is reversed when
// they get called, from ProfileIOData owning ChromeURLRequestContext to vice
// versa.
@@ -162,6 +170,10 @@
return proxy_service_.get();
}
+ net::URLRequestJobFactory* job_factory() const {
+ return job_factory_.get();
+ }
+
ChromeURLRequestContext* main_request_context() const {
return main_request_context_;
}
@@ -219,6 +231,7 @@
mutable scoped_ptr<net::NetworkDelegate> network_delegate_;
mutable scoped_ptr<net::DnsCertProvenanceChecker> dns_cert_checker_;
mutable scoped_ptr<net::ProxyService> proxy_service_;
+ mutable scoped_ptr<net::URLRequestJobFactory> job_factory_;
// Pointed to by ResourceContext.
mutable scoped_refptr<webkit_database::DatabaseTracker> database_tracker_;
diff --git a/chrome/browser/safe_browsing/malware_details_unittest.cc b/chrome/browser/safe_browsing/malware_details_unittest.cc
index faca178..cc98020 100644
--- a/chrome/browser/safe_browsing/malware_details_unittest.cc
+++ b/chrome/browser/safe_browsing/malware_details_unittest.cc
@@ -100,11 +100,12 @@
entry->Close();
}
-void FillCache(net::URLRequestContext* context) {
+void FillCache(net::URLRequestContextGetter* context_getter) {
TestCompletionCallback cb;
disk_cache::Backend* cache;
int rv =
- context->http_transaction_factory()->GetCache()->GetBackend(&cache, &cb);
+ context_getter->GetURLRequestContext()->http_transaction_factory()->
+ GetCache()-> GetBackend(&cache, &cb);
ASSERT_EQ(net::OK, cb.GetResult(rv));
std::string empty;
@@ -497,10 +498,13 @@
profile()->CreateRequestContext();
scoped_refptr<MalwareDetailsWrap> report = new MalwareDetailsWrap(
- sb_service_.get(), contents(), resource
- , profile()->GetRequestContext());
+ sb_service_.get(), contents(), resource, profile()->GetRequestContext());
- FillCache(profile()->GetRequestContext()->GetURLRequestContext());
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableFunction(
+ &FillCache,
+ make_scoped_refptr(profile()->GetRequestContext())));
// The cache collection starts after the IPC from the DOM is fired.
std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node> params;
diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc
index 191d5640..d7d5633 100644
--- a/chrome/browser/tab_contents/render_view_context_menu.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu.cc
@@ -33,6 +33,7 @@
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/printing/print_preview_tab_controller.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_io_data.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "chrome/browser/spellcheck_host.h"
@@ -57,7 +58,6 @@
#include "content/common/content_restriction.h"
#include "grit/generated_resources.h"
#include "net/base/escape.h"
-#include "net/url_request/url_request.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerAction.h"
#include "ui/base/l10n/l10n_util.h"
@@ -945,7 +945,7 @@
return false;
return params_.link_url.is_valid() &&
- net::URLRequest::IsHandledURL(params_.link_url);
+ ProfileIOData::IsHandledProtocol(params_.link_url.scheme());
}
case IDC_CONTENT_CONTEXT_SAVEIMAGEAS: {
@@ -956,7 +956,7 @@
return false;
return params_.src_url.is_valid() &&
- net::URLRequest::IsHandledURL(params_.src_url);
+ ProfileIOData::IsHandledProtocol(params_.src_url.scheme());
}
case IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB:
@@ -1007,7 +1007,7 @@
return (params_.media_flags &
WebContextMenuData::MediaCanSave) &&
params_.src_url.is_valid() &&
- net::URLRequest::IsHandledURL(params_.src_url);
+ ProfileIOData::IsHandledProtocol(params_.src_url.scheme());
}
case IDC_CONTENT_CONTEXT_OPENAVNEWTAB:
diff --git a/chrome/browser/ui/browser_init.cc b/chrome/browser/ui/browser_init.cc
index 3a72032e..9ae505f 100644
--- a/chrome/browser/ui/browser_init.cc
+++ b/chrome/browser/ui/browser_init.cc
@@ -36,6 +36,7 @@
#include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h"
#include "chrome/browser/printing/print_dialog_cloud.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_io_data.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "chrome/browser/sessions/session_restore.h"
@@ -70,7 +71,6 @@
#include "grit/theme_resources.h"
#include "grit/theme_resources_standard.h"
#include "net/base/net_util.h"
-#include "net/url_request/url_request.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "webkit/glue/webkit_glue.h"
@@ -991,7 +991,8 @@
// This avoids us getting into an infinite loop asking ourselves to open
// a URL, should the handler be (incorrectly) configured to be us. Anyone
// asking us to open such a URL should really ask the handler directly.
- if (!process_startup && !net::URLRequest::IsHandledURL(tabs[i].url))
+ if (!process_startup &&
+ !ProfileIOData::IsHandledURL(tabs[i].url))
continue;
int add_types = first_tab ? TabStripModel::ADD_ACTIVE :