| // 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/memory/scoped_ptr.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 "content/browser/child_process_security_policy.h" |
| #include "net/base/network_delegate.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::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()); |
| |
| if (!handler) { |
| return NULL; |
| } |
| |
| GURL translated_url(handler->TranslateUrl(request->url())); |
| |
| if (!translated_url.is_valid()) { |
| return NULL; |
| } |
| |
| return new net::URLRequestRedirectJob(request, translated_url); |
| } |
| |
| ProtocolHandlerRegistry::~ProtocolHandlerRegistry() {} |
| |
| 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); |
| } |