From 98ab903e2509756a0786242a6b954971c921930d Mon Sep 17 00:00:00 2001 From: Jeremy Apthorp Date: Wed, 21 Mar 2018 15:57:50 -0700 Subject: [PATCH] Propagate referrer to new windows Fixes #9205 --- atom/browser/api/atom_api_app.cc | 4 ++-- atom/browser/api/atom_api_web_contents.cc | 5 +++-- atom/browser/api/atom_api_web_contents.h | 1 + .../native_mate_converters/content_converter.cc | 10 ++++++++++ .../native_mate_converters/content_converter.h | 7 +++++++ lib/browser/api/browser-window.js | 7 ++++--- lib/browser/guest-window-manager.js | 15 +++++++++------ 7 files changed, 36 insertions(+), 13 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index c38f9e237238d..e5a6307a6486c 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -689,8 +689,8 @@ bool App::CanCreateWindow( content::WebContents::FromRenderFrameHost(opener); if (web_contents) { auto api_web_contents = WebContents::CreateFrom(isolate(), web_contents); - api_web_contents->OnCreateWindow(target_url, frame_name, disposition, - additional_features, body); + api_web_contents->OnCreateWindow(target_url, referrer, frame_name, + disposition, additional_features, body); } return false; diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 695ac4346cd6c..51c20924e0f9d 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -527,14 +527,15 @@ bool WebContents::DidAddMessageToConsole(content::WebContents* source, void WebContents::OnCreateWindow( const GURL& target_url, + const content::Referrer& referrer, const std::string& frame_name, WindowOpenDisposition disposition, const std::vector& features, const scoped_refptr& body) { if (type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) - Emit("-new-window", target_url, frame_name, disposition, features, body); + Emit("-new-window", target_url, referrer, frame_name, disposition, features, body); else - Emit("new-window", target_url, frame_name, disposition, features); + Emit("new-window", target_url, referrer, frame_name, disposition, features); } void WebContents::WebContentsCreated( diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index ceb0c75e7d875..69031c57c24f9 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -223,6 +223,7 @@ class WebContents : public mate::TrackableObject, // Create window with the given disposition. void OnCreateWindow( const GURL& target_url, + const content::Referrer& referrer, const std::string& frame_name, WindowOpenDisposition disposition, const std::vector& features, diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index 01682bb7706ea..1c6d2db6a3d21 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -318,4 +318,14 @@ bool Converter::FromV8( return true; } +// static +v8::Local Converter::ToV8( + v8::Isolate* isolate, const content::Referrer& val) { + //return atom::api::WebContents::CreateFrom(isolate, val).ToV8(); + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("url", ConvertToV8(isolate, val.url)); + dict.Set("policy", ConvertToV8(isolate, (int)val.policy)); + return mate::ConvertToV8(isolate, dict); +} + } // namespace mate diff --git a/atom/common/native_mate_converters/content_converter.h b/atom/common/native_mate_converters/content_converter.h index 9ce7973ac39a5..586bbe61dd85b 100644 --- a/atom/common/native_mate_converters/content_converter.h +++ b/atom/common/native_mate_converters/content_converter.h @@ -10,6 +10,7 @@ #include "content/public/browser/permission_type.h" #include "content/public/common/menu_item.h" #include "content/public/common/stop_find_action.h" +#include "content/public/common/referrer.h" #include "native_mate/converter.h" #include "third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h" @@ -71,6 +72,12 @@ struct Converter { content::WebContents** out); }; +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + const content::Referrer& val); +}; + } // namespace mate #endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_CONTENT_CONVERTER_H_ diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index 22565dcf9875b..fe872c0e1a13d 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -19,7 +19,7 @@ BrowserWindow.prototype._init = function () { } // Make new windows requested by links behave like "window.open" - this.webContents.on('-new-window', (event, url, frameName, + this.webContents.on('-new-window', (event, url, referrer, frameName, disposition, additionalFeatures, postData) => { const options = { @@ -28,7 +28,7 @@ BrowserWindow.prototype._init = function () { height: 600 } ipcMain.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', - event, url, frameName, disposition, + event, url, referrer, frameName, disposition, options, additionalFeatures, postData) }) @@ -59,8 +59,9 @@ BrowserWindow.prototype._init = function () { height: height || 600, webContents: webContents } + const referrer = { url: '', policy: 2 } ipcMain.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', - event, url, frameName, disposition, options) + event, url, referrer, frameName, disposition, options) }) // window.resizeTo(...) diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index ec77a7abdff1b..7f6d75a964a7d 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -102,7 +102,7 @@ const setupGuest = function (embedder, frameName, guest, options) { } // Create a new guest created by |embedder| with |options|. -const createGuest = function (embedder, url, frameName, options, postData) { +const createGuest = function (embedder, url, referrer, frameName, options, postData) { let guest = frameToGuest.get(frameName) if (frameName && (guest != null)) { guest.loadURL(url) @@ -137,7 +137,9 @@ const createGuest = function (embedder, url, frameName, options, postData) { // // The above code would not work if a navigation to "about:blank" is done // here, since the window would be cleared of all changes in the next tick. - const loadOptions = {} + const loadOptions = { + httpReferrer: referrer.url, + } if (postData != null) { loadOptions.postData = postData loadOptions.extraHeaders = 'content-type: application/x-www-form-urlencoded' @@ -242,13 +244,14 @@ ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url, frameName, } } + const referrer = { url: '', policy: 2 } ipcMain.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', event, - url, frameName, disposition, options, additionalFeatures) + url, referrer, frameName, disposition, options, additionalFeatures) }) // Routed window.open messages with fully parsed options -ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', function (event, url, frameName, - disposition, options, +ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', function (event, url, referrer, + frameName, disposition, options, additionalFeatures, postData) { options = mergeBrowserWindowOptions(event.sender, options) event.sender.emit('new-window', event, url, frameName, disposition, options, additionalFeatures) @@ -265,7 +268,7 @@ ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', function (event event.returnValue = null } } else { - event.returnValue = createGuest(event.sender, url, frameName, options, postData) + event.returnValue = createGuest(event.sender, url, referrer, frameName, options, postData) } })