From 85800256deb7c2eb543bba8d28eb369e3521eb54 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 19 Feb 2016 19:39:01 +0530 Subject: [PATCH] protocol: respect requests from partition --- atom/browser/api/atom_api_protocol.cc | 70 +++++++++++---------------- atom/browser/api/atom_api_protocol.h | 11 +++-- atom/browser/api/atom_api_session.cc | 10 ++++ atom/browser/api/atom_api_session.h | 2 + atom/browser/api/lib/protocol.js | 9 +++- atom/common/node_bindings.cc | 1 - spec/api-protocol-spec.js | 51 +++++++++++++++++++ 7 files changed, 105 insertions(+), 49 deletions(-) diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 09da9c71cadb..335c20e11e3b 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -28,33 +28,6 @@ Protocol::Protocol(AtomBrowserContext* browser_context) CHECK(job_factory_); } -mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - return mate::ObjectTemplateBuilder(isolate) - .SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes) - .SetMethod("registerServiceWorkerSchemes", - &Protocol::RegisterServiceWorkerSchemes) - .SetMethod("registerStringProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerBufferProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerFileProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerHttpProtocol", - &Protocol::RegisterProtocol) - .SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol) - .SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled) - .SetMethod("interceptStringProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptBufferProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptFileProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptHttpProtocol", - &Protocol::InterceptProtocol) - .SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol); -} - void Protocol::RegisterStandardSchemes( const std::vector& schemes) { atom::AtomBrowserClient::SetCustomSchemes(schemes); @@ -153,21 +126,34 @@ mate::Handle Protocol::Create( return mate::CreateHandle(isolate, new Protocol(browser_context)); } +// static +void Protocol::BuildPrototype(v8::Isolate* isolate, + v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes) + .SetMethod("registerServiceWorkerSchemes", + &Protocol::RegisterServiceWorkerSchemes) + .SetMethod("registerStringProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerBufferProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerFileProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerHttpProtocol", + &Protocol::RegisterProtocol) + .SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol) + .SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled) + .SetMethod("interceptStringProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptBufferProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptFileProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptHttpProtocol", + &Protocol::InterceptProtocol) + .SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol); +} + } // namespace api } // namespace atom - -namespace { - -void Initialize(v8::Local exports, v8::Local unused, - v8::Local context, void* priv) { - v8::Isolate* isolate = context->GetIsolate(); - mate::Dictionary dict(isolate, exports); - auto browser_context = static_cast( - atom::AtomBrowserMainParts::Get()->browser_context()); - dict.Set("protocol", atom::api::Protocol::Create(isolate, browser_context)); -} - -} // namespace - -NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_protocol, Initialize) diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h index 8aef406fbc38..36ab46ba8231 100644 --- a/atom/browser/api/atom_api_protocol.h +++ b/atom/browser/api/atom_api_protocol.h @@ -9,6 +9,7 @@ #include #include +#include "atom/browser/api/trackable_object.h" #include "atom/browser/net/atom_url_request_job_factory.h" #include "base/callback.h" #include "base/containers/scoped_ptr_hash_map.h" @@ -30,7 +31,7 @@ class AtomURLRequestJobFactory; namespace api { -class Protocol : public mate::Wrappable { +class Protocol : public mate::TrackableObject { public: using Handler = base::Callback)>; @@ -40,13 +41,13 @@ class Protocol : public mate::Wrappable { static mate::Handle Create( v8::Isolate* isolate, AtomBrowserContext* browser_context); + // mate::TrackableObject: + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + protected: explicit Protocol(AtomBrowserContext* browser_context); - // mate::Wrappable implementations: - virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate); - private: // Possible errors. enum ProtocolError { diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index e5c5198f0341..51f7c1bb811c 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -9,6 +9,7 @@ #include "atom/browser/api/atom_api_cookies.h" #include "atom/browser/api/atom_api_download_item.h" +#include "atom/browser/api/atom_api_protocol.h" #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/api/atom_api_web_request.h" #include "atom/browser/api/save_page_handler.h" @@ -443,6 +444,14 @@ v8::Local Session::Cookies(v8::Isolate* isolate) { return v8::Local::New(isolate, cookies_); } +v8::Local Session::Protocol(v8::Isolate* isolate) { + if (protocol_.IsEmpty()) { + auto handle = atom::api::Protocol::Create(isolate, browser_context()); + protocol_.Reset(isolate, handle.ToV8()); + } + return v8::Local::New(isolate, protocol_); +} + v8::Local Session::WebRequest(v8::Isolate* isolate) { if (web_request_.IsEmpty()) { auto handle = atom::api::WebRequest::Create(isolate, browser_context()); @@ -490,6 +499,7 @@ void Session::BuildPrototype(v8::Isolate* isolate, &Session::SetPermissionRequestHandler) .SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache) .SetProperty("cookies", &Session::Cookies) + .SetProperty("protocol", &Session::Protocol) .SetProperty("webRequest", &Session::WebRequest); } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index 02d8ba5cdec0..63c4cfc612bd 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -80,10 +80,12 @@ class Session: public mate::TrackableObject, mate::Arguments* args); void ClearHostResolverCache(mate::Arguments* args); v8::Local Cookies(v8::Isolate* isolate); + v8::Local Protocol(v8::Isolate* isolate); v8::Local WebRequest(v8::Isolate* isolate); // Cached object. v8::Global cookies_; + v8::Global protocol_; v8::Global web_request_; scoped_refptr browser_context_; diff --git a/atom/browser/api/lib/protocol.js b/atom/browser/api/lib/protocol.js index 41cb48db09b9..caef0ad646b4 100644 --- a/atom/browser/api/lib/protocol.js +++ b/atom/browser/api/lib/protocol.js @@ -4,7 +4,10 @@ if (!app.isReady()) { throw new Error('Can not initialize protocol module before app is ready'); } -const protocol = process.atomBinding('protocol').protocol; +const session = require('electron').session; + +// Returns the protocol property for default session. +const protocol = session.defaultSession.protocol; // Warn about removed APIs. var logAndThrow = function(callback, message) { @@ -16,6 +19,10 @@ var logAndThrow = function(callback, message) { } }; +protocol.fromPartition = function(partition) { + return session.fromPartition(partition).protocol; +}; + protocol.registerProtocol = function(scheme, handler, callback) { return logAndThrow(callback, 'registerProtocol API has been replaced by the register[File/Http/Buffer/String]Protocol API family, please switch to the new APIs.'); }; diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 69e7906ffbbb..4af3ba5b64be 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -41,7 +41,6 @@ REFERENCE_MODULE(atom_browser_download_item); REFERENCE_MODULE(atom_browser_menu); REFERENCE_MODULE(atom_browser_power_monitor); REFERENCE_MODULE(atom_browser_power_save_blocker); -REFERENCE_MODULE(atom_browser_protocol); REFERENCE_MODULE(atom_browser_global_shortcut); REFERENCE_MODULE(atom_browser_session); REFERENCE_MODULE(atom_browser_tray); diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 215868bfdc8a..483155b70652 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -3,6 +3,7 @@ const http = require('http'); const path = require('path'); const qs = require('querystring'); const remote = require('electron').remote; +const BrowserWindow = remote.require('electron').BrowserWindow; const protocol = remote.require('electron').protocol; describe('protocol module', function() { @@ -814,4 +815,54 @@ describe('protocol module', function() { }); }); }); + + describe('protocol.fromPartition', function() { + var partitionName = 'temp'; + var tempProtocol = protocol.fromPartition(partitionName); + var w = null; + + beforeEach(function() { + if (w != null) { + w.destroy(); + } + w = new BrowserWindow({ + show: false, + width: 400, + height: 400, + webPreferences: { + partition: partitionName + } + }); + }); + + afterEach(function() { + if (w != null) { + w.destroy(); + } + w = null; + }); + + it('handles requests from a partition', function(done) { + var handler = function(error, callback) { + callback({ + data: text + }); + }; + tempProtocol.registerStringProtocol(protocolName, handler, function(error) { + if (error) { + return done(error); + } + protocol.isProtocolHandled(protocolName, function(result) { + assert.equal(result, false); + }); + tempProtocol.isProtocolHandled(protocolName, function(result) { + assert.equal(result, true); + }); + }); + w.webContents.on('did-finish-load', function() { + done(); + }); + w.loadURL(protocolName + "://fake-host"); + }); + }); });