1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Use of this source code is governed by a BSD-style license that can be 3dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// found in the LICENSE file. 4dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/custom_handlers/protocol_handler_registry.h" 6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h" 9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/net/chrome_url_request_context.h" 10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/common/pref_names.h" 11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/child_process_security_policy.h" 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/network_delegate.h" 13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/url_request/url_request_redirect_job.h" 14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// ProtocolHandlerRegistry ----------------------------------------------------- 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 18dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile) 19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen :profile_(profile) { 20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ProtocolHandlerRegistry::RegisterProtocolHandler( 23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ProtocolHandler* handler) { 24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (protocolHandlers_.find(handler->protocol()) == protocolHandlers_.end()) { 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ChildProcessSecurityPolicy* policy = 26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ChildProcessSecurityPolicy::GetInstance(); 27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!policy->IsWebSafeScheme(handler->protocol())) { 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen policy->RegisterWebSafeScheme(handler->protocol()); 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen net::URLRequest::RegisterProtocolFactory(handler->protocol(), 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen &ProtocolHandlerRegistry::Factory); 32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen protocolHandlers_[handler->protocol()] = handler; 34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ProtocolHandlerRegistry::Load() { 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PrefService* prefs = profile_->GetPrefs(); 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!prefs->HasPrefPath(prefs::kRegisteredProtocolHandlers)) { 39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const ListValue* protocolHandlers = 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs->GetList(prefs::kRegisteredProtocolHandlers); 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (size_t i = 0; i < protocolHandlers->GetSize(); i++) { 45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DictionaryValue* dict; 46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen protocolHandlers->GetDictionary(i, &dict); 47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen RegisterHandlerFromValue(dict); 48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ProtocolHandlerRegistry::RegisterHandlerFromValue( 52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const DictionaryValue* value) { 53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ProtocolHandler* handler = ProtocolHandler::CreateProtocolHandler(value); 54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (handler) { 55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen RegisterProtocolHandler(handler); 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ProtocolHandlerRegistry::Save() { 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen scoped_ptr<Value> value(Encode()); 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen profile_->GetPrefs()->Set(prefs::kRegisteredProtocolHandlers, *value); 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen profile_->GetPrefs()->ScheduleSavePersistentPrefs(); 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 65dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenProtocolHandler* ProtocolHandlerRegistry::GetHandlerFor( 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const std::string& scheme) const { 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ProtocolHandlerMap::const_iterator i = protocolHandlers_.find(scheme); 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return i == protocolHandlers_.end() ? NULL : i->second; 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool ProtocolHandlerRegistry::CanSchemeBeOverridden( 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const std::string& scheme) const { 73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return GetHandlerFor(scheme) != NULL || 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen !net::URLRequest::IsHandledProtocol(scheme); 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool ProtocolHandlerRegistry::IsAlreadyRegistered( 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const ProtocolHandler* handler) const { 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ProtocolHandler* currentHandler = GetHandlerFor(handler->protocol()); 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return currentHandler && *currentHandler == *handler; 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennet::URLRequestJob* ProtocolHandlerRegistry::Factory(net::URLRequest* request, 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& scheme) { 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return request->context()->network_delegate()->MaybeCreateURLRequestJob( 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request); 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennet::URLRequestJob* ProtocolHandlerRegistry::MaybeCreateJob( 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net::URLRequest* request) const { 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProtocolHandler* handler = GetHandlerFor(request->url().scheme()); 93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!handler) { 95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return NULL; 96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL translated_url(handler->TranslateUrl(request->url())); 99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!translated_url.is_valid()) { 101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return NULL; 102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return new net::URLRequestRedirectJob(request, translated_url); 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 107dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenProtocolHandlerRegistry::~ProtocolHandlerRegistry() {} 108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 109dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenValue* ProtocolHandlerRegistry::Encode() { 110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ListValue* protocolHandlers = new ListValue(); 111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (ProtocolHandlerMap::iterator i = protocolHandlers_.begin(); 113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen i != protocolHandlers_.end(); ++i) { 114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen protocolHandlers->Append(i->second->Encode()); 115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return protocolHandlers; 117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ProtocolHandlerRegistry::OnAcceptRegisterProtocolHandler( 120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ProtocolHandler* handler) { 121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen RegisterProtocolHandler(handler); 122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Save(); 123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ProtocolHandlerRegistry::OnDenyRegisterProtocolHandler( 126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ProtocolHandler* handler) { 127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ProtocolHandlerRegistry::RegisterPrefs(PrefService* prefService) { 130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefService->RegisterListPref(prefs::kRegisteredProtocolHandlers); 131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 132