• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ProtocolHandlerRegistry(Profile * profile)18 ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile)
19   :profile_(profile) {
20 }
21 
RegisterProtocolHandler(ProtocolHandler * handler)22 void 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 
Load()36 void 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 
RegisterHandlerFromValue(const DictionaryValue * value)51 void ProtocolHandlerRegistry::RegisterHandlerFromValue(
52     const DictionaryValue* value) {
53   ProtocolHandler* handler = ProtocolHandler::CreateProtocolHandler(value);
54   if (handler) {
55     RegisterProtocolHandler(handler);
56   }
57 }
58 
Save()59 void ProtocolHandlerRegistry::Save() {
60   scoped_ptr<Value> value(Encode());
61   profile_->GetPrefs()->Set(prefs::kRegisteredProtocolHandlers, *value);
62   profile_->GetPrefs()->ScheduleSavePersistentPrefs();
63 }
64 
GetHandlerFor(const std::string & scheme) const65 ProtocolHandler* 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 
CanSchemeBeOverridden(const std::string & scheme) const71 bool ProtocolHandlerRegistry::CanSchemeBeOverridden(
72     const std::string& scheme) const {
73   return GetHandlerFor(scheme) != NULL ||
74     !net::URLRequest::IsHandledProtocol(scheme);
75 }
76 
IsAlreadyRegistered(const ProtocolHandler * handler) const77 bool ProtocolHandlerRegistry::IsAlreadyRegistered(
78     const ProtocolHandler* handler) const {
79   ProtocolHandler* currentHandler = GetHandlerFor(handler->protocol());
80   return currentHandler && *currentHandler == *handler;
81 }
82 
Factory(net::URLRequest * request,const std::string & scheme)83 net::URLRequestJob* ProtocolHandlerRegistry::Factory(net::URLRequest* request,
84     const std::string& scheme) {
85   return request->context()->network_delegate()->MaybeCreateURLRequestJob(
86       request);
87 }
88 
89 
MaybeCreateJob(net::URLRequest * request) const90 net::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 
~ProtocolHandlerRegistry()107 ProtocolHandlerRegistry::~ProtocolHandlerRegistry() {}
108 
Encode()109 Value* 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 
OnAcceptRegisterProtocolHandler(ProtocolHandler * handler)119 void ProtocolHandlerRegistry::OnAcceptRegisterProtocolHandler(
120     ProtocolHandler* handler) {
121   RegisterProtocolHandler(handler);
122   Save();
123 }
124 
OnDenyRegisterProtocolHandler(ProtocolHandler * handler)125 void ProtocolHandlerRegistry::OnDenyRegisterProtocolHandler(
126     ProtocolHandler* handler) {
127 }
128 
RegisterPrefs(PrefService * prefService)129 void ProtocolHandlerRegistry::RegisterPrefs(PrefService* prefService) {
130   prefService->RegisterListPref(prefs::kRegisteredProtocolHandlers);
131 }
132