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