Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crash when using protocol module on startup. #100

Merged
merged 3 commits into from Sep 20, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions browser/api/atom_api_protocol.cc
Expand Up @@ -29,6 +29,9 @@ v8::Persistent<v8::Object> g_protocol_object;
typedef std::map<std::string, v8::Persistent<v8::Function>> HandlersMap;
static HandlersMap g_handlers;

static const char* kEarlyUseProtocolError = "This method can only be used"
"after the application has finished launching.";

// Emit an event for the protocol module.
void EmitEventInUI(const std::string& event, const std::string& parameter) {
v8::HandleScope scope;
Expand Down Expand Up @@ -185,6 +188,9 @@ v8::Handle<v8::Value> Protocol::RegisterProtocol(const v8::Arguments& args) {
net::URLRequest::IsHandledProtocol(scheme))
return node::ThrowError("The scheme is already registered");

if (AtomBrowserContext::Get()->url_request_context_getter() == NULL)
return node::ThrowError(kEarlyUseProtocolError);

// Store the handler in a map.
if (!args[1]->IsFunction())
return node::ThrowError("Handler must be a function");
Expand All @@ -202,6 +208,9 @@ v8::Handle<v8::Value> Protocol::RegisterProtocol(const v8::Arguments& args) {
v8::Handle<v8::Value> Protocol::UnregisterProtocol(const v8::Arguments& args) {
std::string scheme(*v8::String::Utf8Value(args[0]));

if (AtomBrowserContext::Get()->url_request_context_getter() == NULL)
return node::ThrowError(kEarlyUseProtocolError);

// Erase the handler from map.
HandlersMap::iterator it(g_handlers.find(scheme));
if (it == g_handlers.end())
Expand Down Expand Up @@ -230,6 +239,9 @@ v8::Handle<v8::Value> Protocol::InterceptProtocol(const v8::Arguments& args) {
if (ContainsKey(g_handlers, scheme))
return node::ThrowError("Cannot intercept custom procotols");

if (AtomBrowserContext::Get()->url_request_context_getter() == NULL)
return node::ThrowError(kEarlyUseProtocolError);

// Store the handler in a map.
if (!args[1]->IsFunction())
return node::ThrowError("Handler must be a function");
Expand All @@ -246,6 +258,9 @@ v8::Handle<v8::Value> Protocol::InterceptProtocol(const v8::Arguments& args) {
v8::Handle<v8::Value> Protocol::UninterceptProtocol(const v8::Arguments& args) {
std::string scheme(*v8::String::Utf8Value(args[0]));

if (AtomBrowserContext::Get()->url_request_context_getter() == NULL)
return node::ThrowError(kEarlyUseProtocolError);

// Erase the handler from map.
HandlersMap::iterator it(g_handlers.find(scheme));
if (it == g_handlers.end())
Expand Down
5 changes: 5 additions & 0 deletions browser/atom_browser_main_parts.cc
Expand Up @@ -75,6 +75,11 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {

node_bindings_->RunMessageLoop();

// Make sure the url request job factory is created before the
// will-finish-launching event.
static_cast<content::BrowserContext*>(AtomBrowserContext::Get())->
GetRequestContext();

#if !defined(OS_MACOSX)
// The corresponding call in OS X is in AtomApplicationDelegate.
Browser::Get()->WillFinishLaunching();
Expand Down
3 changes: 3 additions & 0 deletions docs/api/browser/protocol.md
Expand Up @@ -14,6 +14,9 @@ protocol.registerProtocol('atom', function(request) {
});
```

**Note:** This module can only be used after the `will-finish-launching` event
was emitted.

## protocol.registerProtocol(scheme, handler)

* `scheme` String
Expand Down
3 changes: 3 additions & 0 deletions spec/main.js
Expand Up @@ -35,6 +35,9 @@ app.on('window-all-closed', function() {
});

app.on('finish-launching', function() {
// Test if using protocol module would crash.
require('protocol').registerProtocol('test-if-crashes', function() {});

window = new BrowserWindow({
title: 'atom-shell tests',
show: false,
Expand Down