Index: chrome/browser/custom_handlers/protocol_handler_registry.cc |
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1927d417755af12d38af5ab0995705fb49a1f22e |
--- /dev/null |
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc |
@@ -0,0 +1,145 @@ |
+#include "base/string_util.h" |
+#include "chrome/browser/custom_handlers/protocol_handler_registry.h" |
+#include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h" |
+#include "chrome/browser/child_process_security_policy.h" |
+#include "chrome/browser/net/chrome_url_request_context.h" |
+#include "chrome/common/pref_names.h" |
+#include "net/url_request/url_request_redirect_job.h" |
+#include "stdio.h" |
+#include <iostream> |
+ |
+// ProtocolHandler ------------------------------------------------------------- |
+ |
+ProtocolHandler::ProtocolHandler(const std::string& protocol, const std::string& url, const std::string& title) |
+ :protocol_(protocol), |
+ url_(url), |
+ title_(title) { |
+} |
+ |
+ProtocolHandler* ProtocolHandler::CreateProtocolHandler( |
+ const std::string& protocol, const std::string& url, |
+ const std::string& title) { |
+ // FIXME(koz) Check for bad protocol and url here. |
tony
2011/02/07 20:51:45
TODO(koz) is more common in chromium code.
koz (OOO until 15th September)
2011/02/13 22:33:48
Done.
|
+ std::string lowerProtocol(protocol); |
tony
2011/02/07 20:51:45
Nit: lower_protocol
koz (OOO until 15th September)
2011/02/13 22:33:48
Done.
|
+ lowerProtocol = StringToLowerASCII(protocol); |
+ std::cout << "from " << protocol << " to " << lowerProtocol << std::endl; |
tony
2011/02/07 20:51:45
remove debugging code here and other places. you
koz (OOO until 15th September)
2011/02/13 22:33:48
Done.
|
+ return new ProtocolHandler(lowerProtocol, url, title); |
+} |
+ |
+ProtocolHandler* ProtocolHandler::CreateProtocolHandler(const DictionaryValue* value) { |
+ std::string protocol, url, title; |
+ value->GetString("protocol", &protocol); |
+ value->GetString("url", &url); |
+ value->GetString("title", &title); |
+ return ProtocolHandler::CreateProtocolHandler(protocol, url, title); |
+} |
+ |
+GURL ProtocolHandler::TranslateUrl(const GURL& url) { |
+ std::string urlToMangle = url.spec(); |
+ int offset = urlToMangle.find("://"); |
+ std::string remainder = urlToMangle.substr(offset + 3); |
tony
2011/02/07 20:51:45
You can use url_cannon::Replacements to change the
koz (OOO until 15th September)
2011/02/13 22:33:48
Right - we'd like to clear the scheme, but it is e
|
+ |
+ return GURL(SpliceInto(url_, remainder)); |
+} |
+ |
+Value* ProtocolHandler::Encode() { |
+ DictionaryValue* d = new DictionaryValue(); |
+ d->Set("protocol", Value::CreateStringValue(protocol_)); |
+ d->Set("url", Value::CreateStringValue(url_)); |
+ d->Set("title", Value::CreateStringValue(title_)); |
+ return d; |
+} |
+ |
+std::string ProtocolHandler::SpliceInto(const std::string& templ, const std::string& value) { |
+ std::string result(templ); |
+ result.replace(result.find("%s"), 2, value); |
tony
2011/02/07 20:51:45
Can we share this code with the code for search en
koz (OOO until 15th September)
2011/02/13 22:33:48
The search engine code just calls ReplaceSubstring
|
+ return result; |
+} |
+ |
+// ProtocolHandlerRegistry ------------------------------------------------------------- |
+ |
+ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile) |
+ :profile_(profile) { |
+ printf("New protocol handler registry!\n"); |
+} |
+ |
+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() { |
+ printf("Loading from profile.\n"); |
+ PrefService* prefs = profile_->GetPrefs(); |
+ if (!prefs->HasPrefPath(prefs::kRegisteredProtocolHandlers)) { |
+ printf("Don't have a profile, cancelling load.\n"); |
+ return; |
+ } |
+ const DictionaryValue* dict = prefs->GetDictionary(prefs::kRegisteredProtocolHandlers); |
+ |
+ for (DictionaryValue::key_iterator i = dict->begin_keys(); i != dict->end_keys(); ++i) { |
+ DictionaryValue* value; |
+ dict->GetDictionary(*i, &value); |
+ RegisterHandlerFromValue(value); |
+ } |
+} |
+ |
+void ProtocolHandlerRegistry::RegisterHandlerFromValue(const DictionaryValue* value) { |
+ ProtocolHandler* handler = ProtocolHandler::CreateProtocolHandler(value); |
+ if (handler) { |
+ RegisterProtocolHandler(handler); |
+ } else { |
+ printf("Bad PH!\n"); |
+ } |
+} |
+ |
+void ProtocolHandlerRegistry::Save() { |
+ printf("Saving to profile.\n"); |
+ Value* value = Encode(); |
tony
2011/02/07 20:51:45
Can we use a scoped_ptr here?
koz (OOO until 15th September)
2011/02/13 22:33:48
Done.
|
+ profile_->GetPrefs()->Set(prefs::kRegisteredProtocolHandlers, *value); |
+ profile_->GetPrefs()->ScheduleSavePersistentPrefs(); |
+ delete value; |
+} |
+ |
+net::URLRequestJob* ProtocolHandlerRegistry::CreateJob(net::URLRequest* request, const std::string& scheme) const { |
+ ProtocolHandlerMap::const_iterator i = protocolHandlers_.find(scheme); |
+ if (i == protocolHandlers_.end()) { |
+ return NULL; |
+ } |
+ |
+ return new net::URLRequestRedirectJob(request, i->second->TranslateUrl(request->url())); |
+} |
+ |
+net::URLRequestJob* ProtocolHandlerRegistry::Factory(net::URLRequest* request, |
+ const std::string& scheme) { |
+ ChromeURLRequestContext* context = reinterpret_cast<ChromeURLRequestContext*>(request->context()); |
+ return context->protocol_handler_registry()->CreateJob(request, scheme); |
+} |
+ |
+Value* ProtocolHandlerRegistry::Encode() { |
+ DictionaryValue* schemes = new DictionaryValue(); |
+ |
+ for (ProtocolHandlerMap::iterator i = protocolHandlers_.begin(); i != protocolHandlers_.end(); ++i) { |
+ schemes->Set(i->first, i->second->Encode()); |
+ } |
+ return schemes; |
+} |
+ |
+void ProtocolHandlerRegistry::OnAcceptRegisterProtocolHandler(ProtocolHandler* handler) { |
+ RegisterProtocolHandler(handler); |
+ Save(); |
+} |
+ |
+void ProtocolHandlerRegistry::OnDenyRegisterProtocolHandler(ProtocolHandler* handler) { |
+ |
+} |
+ |
+void ProtocolHandlerRegistry::RegisterPrefs(PrefService* prefService) { |
+ prefService->RegisterDictionaryPref(prefs::kRegisteredProtocolHandlers); |
+} |