Browse Source

Merge pull request #11804 from electron/fix-protocol-origin-filtering

Fix protocol filtering of net.request
John Kleinschmidt 7 years ago
parent
commit
f3415c04cd

+ 0 - 4
atom/browser/api/atom_api_protocol.h

@@ -78,10 +78,6 @@ class Protocol : public mate::TrackableObject<Protocol> {
     net::URLRequestJob* MaybeCreateJob(
         net::URLRequest* request,
         net::NetworkDelegate* network_delegate) const override {
-      if (!request->initiator().has_value()) {
-        // Don't intercept this request as it was created by `net.request`.
-        return nullptr;
-      }
       RequestJob* request_job = new RequestJob(request, network_delegate);
       request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
       return request_job;

+ 4 - 0
atom/browser/net/atom_url_request.cc

@@ -7,6 +7,7 @@
 #include <string>
 #include "atom/browser/api/atom_api_url_request.h"
 #include "atom/browser/atom_browser_context.h"
+#include "atom/browser/net/atom_url_request_job_factory.h"
 #include "base/callback.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/base/elements_upload_data_stream.h"
@@ -121,6 +122,9 @@ void AtomURLRequest::DoInitialize(
   request_->set_method(method);
   // Do not send cookies from the cookie store.
   DoSetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES);
+  // Set a flag to stop custom protocol from intercepting this request.
+  request_->SetUserData(DisableProtocolInterceptFlagKey(),
+                        base::WrapUnique(new base::SupportsUserData::Data()));
 }
 
 void AtomURLRequest::DoTerminate() {

+ 12 - 0
atom/browser/net/atom_url_request_job_factory.cc

@@ -15,8 +15,18 @@ using content::BrowserThread;
 
 namespace atom {
 
+namespace {
+
+int disable_protocol_intercept_flag_key = 0;
+
+}  // namespace
+
 typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler;
 
+const void* DisableProtocolInterceptFlagKey() {
+  return &disable_protocol_intercept_flag_key;
+}
+
 AtomURLRequestJobFactory::AtomURLRequestJobFactory() {}
 
 AtomURLRequestJobFactory::~AtomURLRequestJobFactory() {
@@ -93,6 +103,8 @@ net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
   auto it = protocol_handler_map_.find(scheme);
   if (it == protocol_handler_map_.end())
     return nullptr;
+  if (request->GetUserData(DisableProtocolInterceptFlagKey()))
+    return nullptr;
   return it->second->MaybeCreateJob(request, network_delegate);
 }
 

+ 2 - 0
atom/browser/net/atom_url_request_job_factory.h

@@ -16,6 +16,8 @@
 
 namespace atom {
 
+const void* DisableProtocolInterceptFlagKey();
+
 class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
  public:
   AtomURLRequestJobFactory();

+ 31 - 2
spec/api-session-spec.js

@@ -275,6 +275,7 @@ describe('session module', () => {
 
   describe('DownloadItem', () => {
     const mockPDF = Buffer.alloc(1024 * 1024 * 5)
+    const protocolName = 'custom-dl'
     let contentDisposition = 'inline; filename="mock.pdf"'
     const downloadFilePath = path.join(fixtures, 'mock.pdf')
     const downloadServer = http.createServer((req, res) => {
@@ -289,11 +290,15 @@ describe('session module', () => {
     })
     const assertDownload = (event, state, url, mimeType,
                                    receivedBytes, totalBytes, disposition,
-                                   filename, port, savePath) => {
+                                   filename, port, savePath, isCustom) => {
       assert.equal(state, 'completed')
       assert.equal(filename, 'mock.pdf')
       assert.equal(savePath, path.join(__dirname, 'fixtures', 'mock.pdf'))
-      assert.equal(url, `http://127.0.0.1:${port}/`)
+      if (isCustom) {
+        assert.equal(url, `${protocolName}://item`)
+      } else {
+        assert.equal(url, `http://127.0.0.1:${port}/`)
+      }
       assert.equal(mimeType, 'application/pdf')
       assert.equal(receivedBytes, mockPDF.length)
       assert.equal(totalBytes, mockPDF.length)
@@ -318,6 +323,30 @@ describe('session module', () => {
       })
     })
 
+    it('can download from custom protocols using WebContents.downloadURL', (done) => {
+      const protocol = session.defaultSession.protocol
+      downloadServer.listen(0, '127.0.0.1', () => {
+        const port = downloadServer.address().port
+        const handler = (ignoredError, callback) => {
+          callback({url: `${url}:${port}`})
+        }
+        protocol.registerHttpProtocol(protocolName, handler, (error) => {
+          if (error) return done(error)
+          ipcRenderer.sendSync('set-download-option', false, false)
+          w.webContents.downloadURL(`${protocolName}://item`)
+          ipcRenderer.once('download-done', (event, state, url,
+                                                      mimeType, receivedBytes,
+                                                      totalBytes, disposition,
+                                                      filename, savePath) => {
+            assertDownload(event, state, url, mimeType, receivedBytes,
+                           totalBytes, disposition, filename, port, savePath,
+                           true)
+            done()
+          })
+        })
+      })
+    })
+
     it('can download using WebView.downloadURL', (done) => {
       downloadServer.listen(0, '127.0.0.1', () => {
         const port = downloadServer.address().port