From 96c173217f80385520085b5f587f3a3f5f44e903 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 24 Aug 2013 16:38:19 +0800 Subject: [PATCH] Remember registered schemes. --- browser/api/atom_api_protocol.cc | 39 ++++++++++++++++++++++++++++++++ browser/api/atom_api_protocol.h | 9 ++++++++ spec/api/protocol.coffee | 15 ++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 spec/api/protocol.coffee diff --git a/browser/api/atom_api_protocol.cc b/browser/api/atom_api_protocol.cc index 871ae4b7e13f..41d223387c5a 100644 --- a/browser/api/atom_api_protocol.cc +++ b/browser/api/atom_api_protocol.cc @@ -4,6 +4,7 @@ #include "browser/api/atom_api_protocol.h" +#include "content/public/browser/browser_thread.h" #include "net/url_request/url_request_job_manager.h" #include "vendor/node/src/node.h" @@ -11,16 +12,54 @@ namespace atom { namespace api { +Protocol::HandlersMap Protocol::handlers_; + // static v8::Handle Protocol::RegisterProtocol(const v8::Arguments& args) { + std::string scheme(*v8::String::Utf8Value(args[0])); + if (handlers_.find(scheme) != handlers_.end()) + return node::ThrowError("The scheme is already registered"); + + // Store the handler in a map. + if (!args[1]->IsFunction()) + return node::ThrowError("Handler must be a function"); + handlers_[scheme] = v8::Persistent::New( + node::node_isolate, v8::Handle::Cast(args[1])); + + content::BrowserThread::PostTask(content::BrowserThread::IO, + FROM_HERE, + base::Bind(&RegisterProtocolInIO, scheme)); + return v8::Undefined(); } // static v8::Handle Protocol::UnregisterProtocol(const v8::Arguments& args) { + std::string scheme(*v8::String::Utf8Value(args[0])); + + // Erase the handler from map. + HandlersMap::iterator it(handlers_.find(scheme)); + if (it == handlers_.end()) + return node::ThrowError("The scheme has not been registered"); + handlers_.erase(it); + + content::BrowserThread::PostTask(content::BrowserThread::IO, + FROM_HERE, + base::Bind(&UnregisterProtocolInIO, scheme)); + return v8::Undefined(); } +// static +void Protocol::RegisterProtocolInIO(const std::string& scheme) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); +} + +// static +void Protocol::UnregisterProtocolInIO(const std::string& scheme) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); +} + // static void Protocol::Initialize(v8::Handle target) { node::SetMethod(target, "registerProtocol", RegisterProtocol); diff --git a/browser/api/atom_api_protocol.h b/browser/api/atom_api_protocol.h index 11b48f0a165e..4f53c1d287a9 100644 --- a/browser/api/atom_api_protocol.h +++ b/browser/api/atom_api_protocol.h @@ -5,6 +5,9 @@ #ifndef ATOM_BROWSER_API_ATOM_API_PROTOCOL_H_ #define ATOM_BROWSER_API_ATOM_API_PROTOCOL_H_ +#include +#include + #include "base/basictypes.h" #include "v8/include/v8.h" @@ -20,6 +23,12 @@ class Protocol { static v8::Handle RegisterProtocol(const v8::Arguments& args); static v8::Handle UnregisterProtocol(const v8::Arguments& args); + static void RegisterProtocolInIO(const std::string& scheme); + static void UnregisterProtocolInIO(const std::string& scheme); + + typedef std::map> HandlersMap; + static HandlersMap handlers_; + DISALLOW_IMPLICIT_CONSTRUCTORS(Protocol); }; diff --git a/spec/api/protocol.coffee b/spec/api/protocol.coffee new file mode 100644 index 000000000000..332afecf8d38 --- /dev/null +++ b/spec/api/protocol.coffee @@ -0,0 +1,15 @@ +assert = require 'assert' +protocol = require('remote').require 'protocol' + +describe 'protocol API', -> + describe 'protocol.registerProtocol', -> + it 'throws error when scheme is already registered', -> + register = -> protocol.registerProtocol('test', ->) + register() + assert.throws register, /The scheme is already registered/ + protocol.unregisterProtocol 'test' + + describe 'protocol.unregisterProtocol', -> + it 'throws error when scheme does not exist', -> + unregister = -> protocol.unregisterProtocol 'test' + assert.throws unregister, /The scheme has not been registered/