Home | History | Annotate | Download | only in custom_handlers
      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 
     18 ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile)
     19   :profile_(profile) {
     20 }
     21 
     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 
     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 
     51 void ProtocolHandlerRegistry::RegisterHandlerFromValue(
     52     const DictionaryValue* value) {
     53   ProtocolHandler* handler = ProtocolHandler::CreateProtocolHandler(value);
     54   if (handler) {
     55     RegisterProtocolHandler(handler);
     56   }
     57 }
     58 
     59 void ProtocolHandlerRegistry::Save() {
     60   scoped_ptr<Value> value(Encode());
     61   profile_->GetPrefs()->Set(prefs::kRegisteredProtocolHandlers, *value);
     62   profile_->GetPrefs()->ScheduleSavePersistentPrefs();
     63 }
     64 
     65 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 
     71 bool ProtocolHandlerRegistry::CanSchemeBeOverridden(
     72     const std::string& scheme) const {
     73   return GetHandlerFor(scheme) != NULL ||
     74     !net::URLRequest::IsHandledProtocol(scheme);
     75 }
     76 
     77 bool ProtocolHandlerRegistry::IsAlreadyRegistered(
     78     const ProtocolHandler* handler) const {
     79   ProtocolHandler* currentHandler = GetHandlerFor(handler->protocol());
     80   return currentHandler && *currentHandler == *handler;
     81 }
     82 
     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 
     90 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 
    107 ProtocolHandlerRegistry::~ProtocolHandlerRegistry() {}
    108 
    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 
    119 void ProtocolHandlerRegistry::OnAcceptRegisterProtocolHandler(
    120     ProtocolHandler* handler) {
    121   RegisterProtocolHandler(handler);
    122   Save();
    123 }
    124 
    125 void ProtocolHandlerRegistry::OnDenyRegisterProtocolHandler(
    126     ProtocolHandler* handler) {
    127 }
    128 
    129 void ProtocolHandlerRegistry::RegisterPrefs(PrefService* prefService) {
    130   prefService->RegisterListPref(prefs::kRegisteredProtocolHandlers);
    131 }
    132