Merge pull request #2125 from deepak1556/protocol_cleanup
protocol: cleanup
This commit is contained in:
commit
7a390bdd4c
7 changed files with 257 additions and 168 deletions
|
@ -36,7 +36,6 @@ struct Converter<const net::URLRequest*> {
|
|||
|
||||
} // namespace mate
|
||||
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
@ -65,7 +64,7 @@ class CustomProtocolRequestJob : public AdapterRequestJob {
|
|||
|
||||
// AdapterRequestJob:
|
||||
void GetJobTypeInUI() override {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
v8::Locker locker(registry_->isolate());
|
||||
v8::HandleScope handle_scope(registry_->isolate());
|
||||
|
@ -189,6 +188,26 @@ class CustomProtocolHandler : public ProtocolHandler {
|
|||
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
|
||||
};
|
||||
|
||||
std::string ConvertErrorCode(int error_code) {
|
||||
switch (error_code) {
|
||||
case Protocol::ERR_SCHEME_REGISTERED:
|
||||
return "The Scheme is already registered";
|
||||
case Protocol::ERR_SCHEME_UNREGISTERED:
|
||||
return "The Scheme has not been registered";
|
||||
case Protocol::ERR_SCHEME_INTERCEPTED:
|
||||
return "There is no protocol handler to intercept";
|
||||
case Protocol::ERR_SCHEME_UNINTERCEPTED:
|
||||
return "The protocol is not intercepted";
|
||||
case Protocol::ERR_NO_SCHEME:
|
||||
return "The Scheme does not exist.";
|
||||
case Protocol::ERR_SCHEME:
|
||||
return "Cannot intercept custom protocols";
|
||||
default:
|
||||
NOTREACHED();
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Protocol::Protocol(AtomBrowserContext* browser_context)
|
||||
|
@ -202,42 +221,30 @@ Protocol::JsProtocolHandler Protocol::GetProtocolHandler(
|
|||
return protocol_handlers_[scheme];
|
||||
}
|
||||
|
||||
void Protocol::OnIOActionCompleted(const JsCompletionCallback& callback,
|
||||
int error) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
if (error) {
|
||||
callback.Run(v8::Exception::Error(
|
||||
mate::StringToV8(isolate(), ConvertErrorCode(error))));
|
||||
return;
|
||||
}
|
||||
|
||||
callback.Run(v8::Null(isolate()));
|
||||
}
|
||||
|
||||
mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("registerProtocol", &Protocol::RegisterProtocol)
|
||||
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
|
||||
.SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes)
|
||||
.SetMethod("isHandledProtocol", &Protocol::IsHandledProtocol)
|
||||
.SetMethod("interceptProtocol", &Protocol::InterceptProtocol)
|
||||
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
|
||||
}
|
||||
|
||||
void Protocol::RegisterProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const JsProtocolHandler& callback) {
|
||||
if (ContainsKey(protocol_handlers_, scheme) ||
|
||||
job_factory_->IsHandledProtocol(scheme))
|
||||
return node::ThrowError(isolate, "The scheme is already registered");
|
||||
|
||||
protocol_handlers_[scheme] = callback;
|
||||
BrowserThread::PostTask(BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
base::Bind(&Protocol::RegisterProtocolInIO,
|
||||
base::Unretained(this), scheme));
|
||||
}
|
||||
|
||||
void Protocol::UnregisterProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme) {
|
||||
ProtocolHandlersMap::iterator it(protocol_handlers_.find(scheme));
|
||||
if (it == protocol_handlers_.end())
|
||||
return node::ThrowError(isolate, "The scheme has not been registered");
|
||||
|
||||
protocol_handlers_.erase(it);
|
||||
BrowserThread::PostTask(BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
base::Bind(&Protocol::UnregisterProtocolInIO,
|
||||
base::Unretained(this), scheme));
|
||||
.SetMethod("_registerProtocol", &Protocol::RegisterProtocol)
|
||||
.SetMethod("_unregisterProtocol", &Protocol::UnregisterProtocol)
|
||||
.SetMethod("_interceptProtocol", &Protocol::InterceptProtocol)
|
||||
.SetMethod("_uninterceptProtocol", &Protocol::UninterceptProtocol);
|
||||
}
|
||||
|
||||
void Protocol::RegisterStandardSchemes(
|
||||
|
@ -245,109 +252,127 @@ void Protocol::RegisterStandardSchemes(
|
|||
atom::AtomBrowserClient::SetCustomSchemes(schemes);
|
||||
}
|
||||
|
||||
bool Protocol::IsHandledProtocol(const std::string& scheme) {
|
||||
return job_factory_->IsHandledProtocol(scheme);
|
||||
void Protocol::IsHandledProtocol(const std::string& scheme,
|
||||
const net::CompletionCallback& callback) {
|
||||
BrowserThread::PostTaskAndReplyWithResult(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&AtomURLRequestJobFactory::IsHandledProtocol,
|
||||
base::Unretained(job_factory_), scheme),
|
||||
callback);
|
||||
}
|
||||
|
||||
void Protocol::RegisterProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const JsProtocolHandler& handler,
|
||||
const JsCompletionCallback& callback) {
|
||||
BrowserThread::PostTaskAndReplyWithResult(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Protocol::RegisterProtocolInIO,
|
||||
base::Unretained(this), scheme, handler),
|
||||
base::Bind(&Protocol::OnIOActionCompleted,
|
||||
base::Unretained(this), callback));
|
||||
}
|
||||
|
||||
void Protocol::UnregisterProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const JsCompletionCallback& callback) {
|
||||
BrowserThread::PostTaskAndReplyWithResult(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Protocol::UnregisterProtocolInIO,
|
||||
base::Unretained(this), scheme),
|
||||
base::Bind(&Protocol::OnIOActionCompleted,
|
||||
base::Unretained(this), callback));
|
||||
}
|
||||
|
||||
void Protocol::InterceptProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const JsProtocolHandler& callback) {
|
||||
if (!job_factory_->HasProtocolHandler(scheme))
|
||||
return node::ThrowError(isolate, "Scheme does not exist.");
|
||||
|
||||
if (ContainsKey(protocol_handlers_, scheme))
|
||||
return node::ThrowError(isolate, "Cannot intercept custom procotols");
|
||||
|
||||
protocol_handlers_[scheme] = callback;
|
||||
BrowserThread::PostTask(BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
const JsProtocolHandler& handler,
|
||||
const JsCompletionCallback& callback) {
|
||||
BrowserThread::PostTaskAndReplyWithResult(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Protocol::InterceptProtocolInIO,
|
||||
base::Unretained(this), scheme));
|
||||
base::Unretained(this), scheme, handler),
|
||||
base::Bind(&Protocol::OnIOActionCompleted,
|
||||
base::Unretained(this), callback));
|
||||
}
|
||||
|
||||
void Protocol::UninterceptProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme) {
|
||||
const std::string& scheme,
|
||||
const JsCompletionCallback& callback) {
|
||||
BrowserThread::PostTaskAndReplyWithResult(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Protocol::UninterceptProtocolInIO,
|
||||
base::Unretained(this), scheme),
|
||||
base::Bind(&Protocol::OnIOActionCompleted,
|
||||
base::Unretained(this), callback));
|
||||
}
|
||||
|
||||
int Protocol::RegisterProtocolInIO(const std::string& scheme,
|
||||
const JsProtocolHandler& handler) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
if (ContainsKey(protocol_handlers_, scheme) ||
|
||||
job_factory_->IsHandledProtocol(scheme)) {
|
||||
return ERR_SCHEME_REGISTERED;
|
||||
}
|
||||
|
||||
protocol_handlers_[scheme] = handler;
|
||||
job_factory_->SetProtocolHandler(scheme, new CustomProtocolHandler(this));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int Protocol::UnregisterProtocolInIO(const std::string& scheme) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
ProtocolHandlersMap::iterator it(protocol_handlers_.find(scheme));
|
||||
if (it == protocol_handlers_.end())
|
||||
return node::ThrowError(isolate, "The scheme has not been registered");
|
||||
if (it == protocol_handlers_.end()) {
|
||||
return ERR_SCHEME_UNREGISTERED;
|
||||
}
|
||||
|
||||
protocol_handlers_.erase(it);
|
||||
BrowserThread::PostTask(BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
base::Bind(&Protocol::UninterceptProtocolInIO,
|
||||
base::Unretained(this), scheme));
|
||||
}
|
||||
|
||||
void Protocol::RegisterProtocolInIO(const std::string& scheme) {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
||||
|
||||
job_factory_->SetProtocolHandler(scheme, new CustomProtocolHandler(this));
|
||||
BrowserThread::PostTask(BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(&Protocol::EmitEventInUI,
|
||||
base::Unretained(this),
|
||||
"registered", scheme));
|
||||
}
|
||||
|
||||
void Protocol::UnregisterProtocolInIO(const std::string& scheme) {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
||||
|
||||
job_factory_->SetProtocolHandler(scheme, NULL);
|
||||
BrowserThread::PostTask(BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(&Protocol::EmitEventInUI,
|
||||
base::Unretained(this),
|
||||
"unregistered", scheme));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void Protocol::InterceptProtocolInIO(const std::string& scheme) {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
||||
int Protocol::InterceptProtocolInIO(const std::string& scheme,
|
||||
const JsProtocolHandler& handler) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
if (!job_factory_->HasProtocolHandler(scheme))
|
||||
return ERR_NO_SCHEME;
|
||||
|
||||
if (ContainsKey(protocol_handlers_, scheme))
|
||||
return ERR_SCHEME;
|
||||
|
||||
protocol_handlers_[scheme] = handler;
|
||||
ProtocolHandler* original_handler = job_factory_->GetProtocolHandler(scheme);
|
||||
if (original_handler == NULL) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
|
||||
&Protocol::EmitEventInUI,
|
||||
base::Unretained(this),
|
||||
"error", "There is no protocol handler to intercpet"));
|
||||
return;
|
||||
if (original_handler == nullptr) {
|
||||
return ERR_SCHEME_INTERCEPTED;
|
||||
}
|
||||
|
||||
job_factory_->ReplaceProtocol(
|
||||
scheme, new CustomProtocolHandler(this, original_handler));
|
||||
BrowserThread::PostTask(BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(&Protocol::EmitEventInUI,
|
||||
base::Unretained(this),
|
||||
"intercepted", scheme));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void Protocol::UninterceptProtocolInIO(const std::string& scheme) {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
||||
int Protocol::UninterceptProtocolInIO(const std::string& scheme) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
ProtocolHandlersMap::iterator it(protocol_handlers_.find(scheme));
|
||||
if (it == protocol_handlers_.end())
|
||||
return ERR_SCHEME_UNREGISTERED;
|
||||
|
||||
protocol_handlers_.erase(it);
|
||||
CustomProtocolHandler* handler = static_cast<CustomProtocolHandler*>(
|
||||
job_factory_->GetProtocolHandler(scheme));
|
||||
if (handler->original_handler() == NULL) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
|
||||
&Protocol::EmitEventInUI,
|
||||
base::Unretained(this),
|
||||
"error", "The protocol is not intercpeted"));
|
||||
return;
|
||||
if (handler->original_handler() == nullptr) {
|
||||
return ERR_SCHEME_UNINTERCEPTED;
|
||||
}
|
||||
|
||||
// Reset the protocol handler to the orignal one and delete current protocol
|
||||
// handler.
|
||||
ProtocolHandler* original_handler = handler->ReleaseDefaultProtocolHandler();
|
||||
delete job_factory_->ReplaceProtocol(scheme, original_handler);
|
||||
BrowserThread::PostTask(BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(&Protocol::EmitEventInUI,
|
||||
base::Unretained(this),
|
||||
"unintercepted", scheme));
|
||||
}
|
||||
|
||||
void Protocol::EmitEventInUI(const std::string& event,
|
||||
const std::string& parameter) {
|
||||
Emit(event, parameter);
|
||||
return OK;
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "base/callback.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/base/completion_callback.h"
|
||||
|
||||
namespace net {
|
||||
class URLRequest;
|
||||
|
@ -26,8 +27,19 @@ namespace api {
|
|||
|
||||
class Protocol : public mate::EventEmitter {
|
||||
public:
|
||||
typedef base::Callback<v8::Local<v8::Value>(const net::URLRequest*)>
|
||||
JsProtocolHandler;
|
||||
using JsProtocolHandler =
|
||||
base::Callback<v8::Local<v8::Value>(const net::URLRequest*)>;
|
||||
using JsCompletionCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
|
||||
enum {
|
||||
OK = 0,
|
||||
ERR_SCHEME_REGISTERED,
|
||||
ERR_SCHEME_UNREGISTERED,
|
||||
ERR_SCHEME_INTERCEPTED,
|
||||
ERR_SCHEME_UNINTERCEPTED,
|
||||
ERR_NO_SCHEME,
|
||||
ERR_SCHEME
|
||||
};
|
||||
|
||||
static mate::Handle<Protocol> Create(
|
||||
v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
|
@ -46,35 +58,41 @@ class Protocol : public mate::EventEmitter {
|
|||
private:
|
||||
typedef std::map<std::string, JsProtocolHandler> ProtocolHandlersMap;
|
||||
|
||||
// Callback called after performing action on IO thread.
|
||||
void OnIOActionCompleted(const JsCompletionCallback& callback,
|
||||
int error);
|
||||
|
||||
// Register schemes to standard scheme list.
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes);
|
||||
|
||||
// Returns whether a scheme has been registered.
|
||||
void IsHandledProtocol(const std::string& scheme,
|
||||
const net::CompletionCallback& callback);
|
||||
|
||||
// Register/unregister an networking |scheme| which would be handled by
|
||||
// |callback|.
|
||||
void RegisterProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const JsProtocolHandler& callback);
|
||||
void UnregisterProtocol(v8::Isolate* isolate, const std::string& scheme);
|
||||
|
||||
// Returns whether a scheme has been registered.
|
||||
// FIXME Should accept a callback and be asynchronous so we do not have to use
|
||||
// locks.
|
||||
bool IsHandledProtocol(const std::string& scheme);
|
||||
const JsProtocolHandler& handler,
|
||||
const JsCompletionCallback& callback);
|
||||
void UnregisterProtocol(v8::Isolate* isolate, const std::string& scheme,
|
||||
const JsCompletionCallback& callback);
|
||||
|
||||
// Intercept/unintercept an existing protocol handler.
|
||||
void InterceptProtocol(v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const JsProtocolHandler& callback);
|
||||
void UninterceptProtocol(v8::Isolate* isolate, const std::string& scheme);
|
||||
const JsProtocolHandler& handler,
|
||||
const JsCompletionCallback& callback);
|
||||
void UninterceptProtocol(v8::Isolate* isolate, const std::string& scheme,
|
||||
const JsCompletionCallback& callback);
|
||||
|
||||
// The networking related operations have to be done in IO thread.
|
||||
void RegisterProtocolInIO(const std::string& scheme);
|
||||
void UnregisterProtocolInIO(const std::string& scheme);
|
||||
void InterceptProtocolInIO(const std::string& scheme);
|
||||
void UninterceptProtocolInIO(const std::string& scheme);
|
||||
|
||||
// Do protocol.emit(event, parameter) under UI thread.
|
||||
void EmitEventInUI(const std::string& event, const std::string& parameter);
|
||||
int RegisterProtocolInIO(const std::string& scheme,
|
||||
const JsProtocolHandler& handler);
|
||||
int UnregisterProtocolInIO(const std::string& scheme);
|
||||
int InterceptProtocolInIO(const std::string& scheme,
|
||||
const JsProtocolHandler& handler);
|
||||
int UninterceptProtocolInIO(const std::string& scheme);
|
||||
|
||||
AtomBrowserContext* browser_context_;
|
||||
AtomURLRequestJobFactory* job_factory_;
|
||||
|
|
|
@ -6,6 +6,29 @@ EventEmitter = require('events').EventEmitter
|
|||
|
||||
protocol.__proto__ = EventEmitter.prototype
|
||||
|
||||
GetWrappedCallback = (scheme, callback, notification) ->
|
||||
wrappedCallback = (error) ->
|
||||
if not callback?
|
||||
if error
|
||||
throw error
|
||||
else
|
||||
protocol.emit notification, scheme
|
||||
else
|
||||
callback error, scheme
|
||||
|
||||
# Compatibility with old api.
|
||||
protocol.registerProtocol = (scheme, handler, callback) ->
|
||||
protocol._registerProtocol scheme, handler, GetWrappedCallback(scheme, callback, 'registered')
|
||||
|
||||
protocol.unregisterProtocol = (scheme, callback) ->
|
||||
protocol._unregisterProtocol scheme, GetWrappedCallback(scheme, callback, 'unregistered')
|
||||
|
||||
protocol.interceptProtocol = (scheme, handler, callback) ->
|
||||
protocol._interceptProtocol scheme, handler, GetWrappedCallback(scheme, callback, 'intercepted')
|
||||
|
||||
protocol.uninterceptProtocol = (scheme, callback) ->
|
||||
protocol._uninterceptProtocol scheme, GetWrappedCallback(scheme, callback, 'unintercepted')
|
||||
|
||||
protocol.RequestStringJob =
|
||||
class RequestStringJob
|
||||
constructor: ({mimeType, charset, data}) ->
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
|
||||
#include "base/stl_util.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
|
||||
typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler;
|
||||
|
@ -22,9 +25,7 @@ AtomURLRequestJobFactory::~AtomURLRequestJobFactory() {
|
|||
bool AtomURLRequestJobFactory::SetProtocolHandler(
|
||||
const std::string& scheme,
|
||||
ProtocolHandler* protocol_handler) {
|
||||
DCHECK(CalledOnValidThread());
|
||||
|
||||
base::AutoLock locked(lock_);
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
if (!protocol_handler) {
|
||||
ProtocolHandlerMap::iterator it = protocol_handler_map_.find(scheme);
|
||||
|
@ -45,10 +46,9 @@ bool AtomURLRequestJobFactory::SetProtocolHandler(
|
|||
ProtocolHandler* AtomURLRequestJobFactory::ReplaceProtocol(
|
||||
const std::string& scheme,
|
||||
ProtocolHandler* protocol_handler) {
|
||||
DCHECK(CalledOnValidThread());
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
DCHECK(protocol_handler);
|
||||
|
||||
base::AutoLock locked(lock_);
|
||||
if (!ContainsKey(protocol_handler_map_, scheme))
|
||||
return nullptr;
|
||||
ProtocolHandler* original_protocol_handler = protocol_handler_map_[scheme];
|
||||
|
@ -58,9 +58,8 @@ ProtocolHandler* AtomURLRequestJobFactory::ReplaceProtocol(
|
|||
|
||||
ProtocolHandler* AtomURLRequestJobFactory::GetProtocolHandler(
|
||||
const std::string& scheme) const {
|
||||
DCHECK(CalledOnValidThread());
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
base::AutoLock locked(lock_);
|
||||
ProtocolHandlerMap::const_iterator it = protocol_handler_map_.find(scheme);
|
||||
if (it == protocol_handler_map_.end())
|
||||
return nullptr;
|
||||
|
@ -69,7 +68,6 @@ ProtocolHandler* AtomURLRequestJobFactory::GetProtocolHandler(
|
|||
|
||||
bool AtomURLRequestJobFactory::HasProtocolHandler(
|
||||
const std::string& scheme) const {
|
||||
base::AutoLock locked(lock_);
|
||||
return ContainsKey(protocol_handler_map_, scheme);
|
||||
}
|
||||
|
||||
|
@ -77,9 +75,8 @@ net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
|
|||
const std::string& scheme,
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const {
|
||||
DCHECK(CalledOnValidThread());
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
base::AutoLock locked(lock_);
|
||||
ProtocolHandlerMap::const_iterator it = protocol_handler_map_.find(scheme);
|
||||
if (it == protocol_handler_map_.end())
|
||||
return nullptr;
|
||||
|
@ -101,7 +98,8 @@ net::URLRequestJob* AtomURLRequestJobFactory::MaybeInterceptResponse(
|
|||
|
||||
bool AtomURLRequestJobFactory::IsHandledProtocol(
|
||||
const std::string& scheme) const {
|
||||
DCHECK(CalledOnValidThread());
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
return HasProtocolHandler(scheme) ||
|
||||
net::URLRequest::IsHandledProtocol(scheme);
|
||||
}
|
||||
|
|
|
@ -56,12 +56,10 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
|
|||
bool IsSafeRedirectTarget(const GURL& location) const override;
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, ProtocolHandler*> ProtocolHandlerMap;
|
||||
using ProtocolHandlerMap = std::map<std::string, ProtocolHandler*>;
|
||||
|
||||
ProtocolHandlerMap protocol_handler_map_;
|
||||
|
||||
mutable base::Lock lock_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomURLRequestJobFactory);
|
||||
};
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@ app.on('ready', function() {
|
|||
protocol.registerProtocol('atom', function(request) {
|
||||
var url = request.url.substr(7)
|
||||
return new protocol.RequestFileJob(path.normalize(__dirname + '/' + url));
|
||||
}, function (error, scheme) {
|
||||
if (!error)
|
||||
console.log(scheme, ' registered successfully')
|
||||
});
|
||||
});
|
||||
```
|
||||
|
@ -22,10 +25,11 @@ app.on('ready', function() {
|
|||
**Note:** This module can only be used after the `ready` event
|
||||
was emitted.
|
||||
|
||||
## protocol.registerProtocol(scheme, handler)
|
||||
## protocol.registerProtocol(scheme, handler, callback)
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `callback` Function
|
||||
|
||||
Registers a custom protocol of `scheme`, the `handler` would be called with
|
||||
`handler(request)` when the a request with registered `scheme` is made.
|
||||
|
@ -33,9 +37,10 @@ Registers a custom protocol of `scheme`, the `handler` would be called with
|
|||
You need to return a request job in the `handler` to specify which type of
|
||||
response you would like to send.
|
||||
|
||||
## protocol.unregisterProtocol(scheme)
|
||||
## protocol.unregisterProtocol(scheme, callback)
|
||||
|
||||
* `scheme` String
|
||||
* `callback` Function
|
||||
|
||||
Unregisters the custom protocol of `scheme`.
|
||||
|
||||
|
@ -45,23 +50,26 @@ Unregisters the custom protocol of `scheme`.
|
|||
|
||||
`value` is an array of custom schemes to be registered to the standard.
|
||||
|
||||
## protocol.isHandledProtocol(scheme)
|
||||
## protocol.isHandledProtocol(scheme, callback)
|
||||
|
||||
* `scheme` String
|
||||
* `callback` Function
|
||||
|
||||
Returns whether the `scheme` can be handled already.
|
||||
`callback` returns a boolean whether the `scheme` can be handled already.
|
||||
|
||||
## protocol.interceptProtocol(scheme, handler)
|
||||
## protocol.interceptProtocol(scheme, handler, callback)
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `callback` Function
|
||||
|
||||
Intercepts an existing protocol with `scheme`, returning `null` or `undefined`
|
||||
in `handler` would use the original protocol handler to handle the request.
|
||||
|
||||
## protocol.uninterceptProtocol(scheme)
|
||||
## protocol.uninterceptProtocol(scheme, callback)
|
||||
|
||||
* `scheme` String
|
||||
* `callback` Function
|
||||
|
||||
Unintercepts a protocol.
|
||||
|
||||
|
|
|
@ -7,13 +7,16 @@ protocol = remote.require 'protocol'
|
|||
|
||||
describe 'protocol module', ->
|
||||
describe 'protocol.registerProtocol', ->
|
||||
it 'throws error when scheme is already registered', (done) ->
|
||||
register = -> protocol.registerProtocol('test1', ->)
|
||||
protocol.once 'registered', (event, scheme) ->
|
||||
it 'error when scheme is already registered', (done) ->
|
||||
register = ->
|
||||
protocol.registerProtocol 'test1', ((request) ->), (error, scheme) ->
|
||||
if error?
|
||||
protocol.unregisterProtocol 'test1', (error, scheme) ->
|
||||
assert.equal scheme, 'test1'
|
||||
assert.throws register, /The scheme is already registered/
|
||||
protocol.unregisterProtocol 'test1'
|
||||
done()
|
||||
else
|
||||
assert.equal scheme, 'test1'
|
||||
register()
|
||||
register()
|
||||
|
||||
it 'calls the callback when scheme is visited', (done) ->
|
||||
|
@ -25,8 +28,10 @@ describe 'protocol module', ->
|
|||
|
||||
describe 'protocol.unregisterProtocol', ->
|
||||
it 'throws error when scheme does not exist', ->
|
||||
unregister = -> protocol.unregisterProtocol 'test3'
|
||||
assert.throws unregister, /The scheme has not been registered/
|
||||
protocol.unregisterProtocol 'test3', (->), (error, scheme) ->
|
||||
if (error)
|
||||
assert.equal scheme, 'test3'
|
||||
done()
|
||||
|
||||
describe 'registered protocol callback', ->
|
||||
it 'returns string should send the string as request content', (done) ->
|
||||
|
@ -169,37 +174,51 @@ describe 'protocol module', ->
|
|||
protocol.unregisterProtocol 'atom-file-job'
|
||||
|
||||
describe 'protocol.isHandledProtocol', ->
|
||||
it 'returns true if the scheme can be handled', ->
|
||||
assert.equal protocol.isHandledProtocol('file'), true
|
||||
assert.equal protocol.isHandledProtocol('http'), true
|
||||
assert.equal protocol.isHandledProtocol('https'), true
|
||||
assert.equal protocol.isHandledProtocol('atom'), false
|
||||
it 'returns true if the file scheme can be handled', (done) ->
|
||||
protocol.isHandledProtocol 'file', (result) ->
|
||||
assert.equal result, true
|
||||
done()
|
||||
it 'returns true if the http scheme can be handled', (done) ->
|
||||
protocol.isHandledProtocol 'http', (result) ->
|
||||
assert.equal result, true
|
||||
done()
|
||||
it 'returns true if the https scheme can be handled', (done) ->
|
||||
protocol.isHandledProtocol 'https', (result) ->
|
||||
assert.equal result, true
|
||||
done()
|
||||
it 'returns false if the atom scheme cannot be handled', (done) ->
|
||||
protocol.isHandledProtocol 'atom', (result) ->
|
||||
assert.equal result, false
|
||||
done()
|
||||
|
||||
describe 'protocol.interceptProtocol', ->
|
||||
it 'throws error when scheme is not a registered one', ->
|
||||
register = -> protocol.interceptProtocol('test-intercept', ->)
|
||||
assert.throws register, /Scheme does not exist/
|
||||
it 'throws error when scheme is not a registered one', (done) ->
|
||||
protocol.interceptProtocol 'test-intercept', ( ->), (error, scheme) ->
|
||||
if error?
|
||||
assert.equal scheme, 'test-intercept'
|
||||
done()
|
||||
|
||||
it 'throws error when scheme is a custom protocol', (done) ->
|
||||
protocol.once 'unregistered', (event, scheme) ->
|
||||
protocol.once 'unregistered', (scheme) ->
|
||||
assert.equal scheme, 'atom'
|
||||
done()
|
||||
protocol.once 'registered', (event, scheme) ->
|
||||
protocol.once 'registered', (scheme) ->
|
||||
assert.equal scheme, 'atom'
|
||||
register = -> protocol.interceptProtocol('test-intercept', ->)
|
||||
assert.throws register, /Scheme does not exist/
|
||||
protocol.interceptProtocol 'test-intercept', (->), (error, newScheme) ->
|
||||
if error?
|
||||
assert.equal newScheme, 'test-intercept'
|
||||
protocol.unregisterProtocol scheme
|
||||
protocol.registerProtocol('atom', ->)
|
||||
|
||||
it 'returns original job when callback returns nothing', (done) ->
|
||||
targetScheme = 'file'
|
||||
protocol.once 'intercepted', (event, scheme) ->
|
||||
protocol.once 'intercepted', (scheme) ->
|
||||
assert.equal scheme, targetScheme
|
||||
free = -> protocol.uninterceptProtocol targetScheme
|
||||
$.ajax
|
||||
url: "#{targetScheme}://#{__filename}",
|
||||
success: ->
|
||||
protocol.once 'unintercepted', (event, scheme) ->
|
||||
protocol.once 'unintercepted', (scheme) ->
|
||||
assert.equal scheme, targetScheme
|
||||
done()
|
||||
free()
|
||||
|
|
Loading…
Reference in a new issue