Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1788)

Unified Diff: chrome/browser/custom_handlers/protocol_handler_registry.cc

Issue 6410115: Adds navigator.registerProtocolHandler. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Sync'd, disallow non-same origin rph, adds hostname to the infobar. Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/custom_handlers/protocol_handler_registry.cc
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc
new file mode 100644
index 0000000000000000000000000000000000000000..cb0afcc888449c134c616188aa192890cb79c3d6
--- /dev/null
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -0,0 +1,129 @@
+// 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.
+
+#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
+
+#include "base/scoped_ptr.h"
+#include "chrome/browser/child_process_security_policy.h"
+#include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h"
+#include "chrome/browser/net/chrome_url_request_context.h"
+#include "chrome/common/pref_names.h"
+#include "net/url_request/url_request_redirect_job.h"
+
+
+// ProtocolHandlerRegistry -----------------------------------------------------
+
+ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile)
+ :profile_(profile) {
+}
+
+void ProtocolHandlerRegistry::RegisterProtocolHandler(
+ ProtocolHandler* handler) {
+ if (protocolHandlers_.find(handler->protocol()) == protocolHandlers_.end()) {
+ ChildProcessSecurityPolicy* policy =
+ ChildProcessSecurityPolicy::GetInstance();
+ if (!policy->IsWebSafeScheme(handler->protocol())) {
+ policy->RegisterWebSafeScheme(handler->protocol());
+ }
+ net::URLRequest::RegisterProtocolFactory(handler->protocol(),
+ &ProtocolHandlerRegistry::Factory);
+ }
+ protocolHandlers_[handler->protocol()] = handler;
+}
+
+void ProtocolHandlerRegistry::Load() {
+ PrefService* prefs = profile_->GetPrefs();
+ if (!prefs->HasPrefPath(prefs::kRegisteredProtocolHandlers)) {
+ return;
+ }
+ const ListValue* protocolHandlers =
+ prefs->GetList(prefs::kRegisteredProtocolHandlers);
+
+ for (size_t i = 0; i < protocolHandlers->GetSize(); i++) {
+ DictionaryValue* dict;
+ protocolHandlers->GetDictionary(i, &dict);
+ RegisterHandlerFromValue(dict);
+ }
+}
+
+void ProtocolHandlerRegistry::RegisterHandlerFromValue(
+ const DictionaryValue* value) {
+ ProtocolHandler* handler = ProtocolHandler::CreateProtocolHandler(value);
+ if (handler) {
+ RegisterProtocolHandler(handler);
+ }
+}
+
+void ProtocolHandlerRegistry::Save() {
+ scoped_ptr<Value> value(Encode());
+ profile_->GetPrefs()->Set(prefs::kRegisteredProtocolHandlers, *value);
+ profile_->GetPrefs()->ScheduleSavePersistentPrefs();
+}
+
+ProtocolHandler* ProtocolHandlerRegistry::GetHandlerFor(
+ const std::string& scheme) const {
+ ProtocolHandlerMap::const_iterator i = protocolHandlers_.find(scheme);
+ return i == protocolHandlers_.end() ? NULL : i->second;
+}
+
+bool ProtocolHandlerRegistry::CanSchemeBeOverridden(
+ const std::string& scheme) const {
+ return GetHandlerFor(scheme) != NULL ||
+ !net::URLRequest::IsHandledProtocol(scheme);
+}
+
+bool ProtocolHandlerRegistry::IsAlreadyRegistered(
+ const ProtocolHandler* handler) const {
+ ProtocolHandler* currentHandler = GetHandlerFor(handler->protocol());
+ return currentHandler && *currentHandler == *handler;
+}
+
+net::URLRequestJob* ProtocolHandlerRegistry::CreateJob(
+ net::URLRequest* request,
+ const std::string& scheme) const {
+ ProtocolHandler* handler = GetHandlerFor(scheme);
+
+ if (!handler) {
+ return NULL;
+ }
+
+ GURL translatedUrl(handler->TranslateUrl(request->url()));
+
+ if (!translatedUrl.is_valid()) {
+ return NULL;
+ }
+
+ return new net::URLRequestRedirectJob(request, translatedUrl);
+}
+
+net::URLRequestJob* ProtocolHandlerRegistry::Factory(net::URLRequest* request,
+ const std::string& scheme) {
+ ChromeURLRequestContext* context =
+ static_cast<ChromeURLRequestContext*>(request->context());
+ return context->protocol_handler_registry()->CreateJob(request, scheme);
+}
+
+Value* ProtocolHandlerRegistry::Encode() {
+ ListValue* protocolHandlers = new ListValue();
+
+ for (ProtocolHandlerMap::iterator i = protocolHandlers_.begin();
+ i != protocolHandlers_.end(); ++i) {
+ protocolHandlers->Append(i->second->Encode());
+ }
+ return protocolHandlers;
+}
+
+void ProtocolHandlerRegistry::OnAcceptRegisterProtocolHandler(
+ ProtocolHandler* handler) {
+ RegisterProtocolHandler(handler);
+ Save();
+}
+
+void ProtocolHandlerRegistry::OnDenyRegisterProtocolHandler(
+ ProtocolHandler* handler) {
+}
+
+void ProtocolHandlerRegistry::RegisterPrefs(PrefService* prefService) {
+ prefService->RegisterListPref(prefs::kRegisteredProtocolHandlers);
+}

Powered by Google App Engine
This is Rietveld 408576698