diff --git a/dom/browser-element/BrowserElementChildPreload.js b/dom/browser-element/BrowserElementChildPreload.js index c377fe9bbe7d..994530b10407 100644 --- a/dom/browser-element/BrowserElementChildPreload.js +++ b/dom/browser-element/BrowserElementChildPreload.js @@ -816,21 +816,25 @@ BrowserElementChild.prototype = { }, _getSystemCtxMenuData: function(elem) { + let documentURI = docShell.QueryInterface(Ci.nsIWebNavigation).currentURI; if ((elem instanceof Ci.nsIDOMHTMLAnchorElement && elem.href) || (elem instanceof Ci.nsIDOMHTMLAreaElement && elem.href)) { return {uri: elem.href, + documentURI: documentURI, text: elem.textContent.substring(0, kLongestReturnedString)}; } if (elem instanceof Ci.nsIImageLoadingContent && elem.currentURI) { - return {uri: elem.currentURI.spec}; + return {uri: elem.currentURI.spec, documentURI: documentURI}; } if (elem instanceof Ci.nsIDOMHTMLImageElement) { - return {uri: elem.src}; + return {uri: elem.src, documentURI: documentURI}; } if (elem instanceof Ci.nsIDOMHTMLMediaElement) { let hasVideo = !(elem.readyState >= elem.HAVE_METADATA && (elem.videoWidth == 0 || elem.videoHeight == 0)); - return {uri: elem.currentSrc || elem.src, hasVideo: hasVideo}; + return {uri: elem.currentSrc || elem.src, + hasVideo: hasVideo, + documentURI: documentURI}; } if (elem instanceof Ci.nsIDOMHTMLInputElement && elem.hasAttribute("name")) { @@ -847,6 +851,7 @@ BrowserElementChild.prototype = { ? parent.getAttribute("method").toLowerCase() : "get"; return { + documentURI: documentURI, action: actionHref, method: method, name: elem.getAttribute("name"), diff --git a/dom/browser-element/BrowserElementParent.js b/dom/browser-element/BrowserElementParent.js index 701dcd87b186..a81f0ba3fc4d 100644 --- a/dom/browser-element/BrowserElementParent.js +++ b/dom/browser-element/BrowserElementParent.js @@ -643,18 +643,19 @@ BrowserElementParent.prototype = { if (!this._isAlive()) { return null; } - let ioService = - Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService); - let uri = ioService.newURI(_url, null, null); + + let uri = Services.io.newURI(_url, null, null); let url = uri.QueryInterface(Ci.nsIURL); + debug('original _options = ' + uneval(_options)); + // Ensure we have _options, we always use it to send the filename. _options = _options || {}; if (!_options.filename) { _options.filename = url.fileName; } - debug('_options = ' + uneval(_options)); + debug('final _options = ' + uneval(_options)); // Ensure we have a filename. if (!_options.filename) { @@ -732,7 +733,37 @@ BrowserElementParent.prototype = { Ci.nsIRequestObserver]) }; - let channel = ioService.newChannelFromURI(url); + // If we have a URI we'll use it to get the triggering principal to use, + // if not available a null principal is acceptable. + let referrer = null; + let principal = null; + if (_options.referrer) { + // newURI can throw on malformed URIs. + try { + referrer = Services.io.newURI(_options.referrer, null, null); + } + catch(e) { + debug('Malformed referrer -- ' + e); + } + // This simply returns null if there is no principal available + // for the requested uri. This is an acceptable fallback when + // calling newChannelFromURI2. + principal = + Services.scriptSecurityManager.getAppCodebasePrincipal( + referrer, + this._frameLoader.loadContext.appId, + this._frameLoader.loadContext.isInBrowserElement); + } + + debug('Using principal? ' + !!principal); + + let channel = + Services.io.newChannelFromURI2(url, + null, // No document. + principal, // Loading principal + principal, // Triggering principal + Ci.nsILoadInfo.SEC_NORMAL, + Ci.nsIContentPolicy.TYPE_OTHER); // XXX We would set private browsing information prior to calling this. channel.notificationCallbacks = interfaceRequestor; @@ -749,8 +780,8 @@ BrowserElementParent.prototype = { channel.loadFlags |= flags; if (channel instanceof Ci.nsIHttpChannel) { - debug('Setting HTTP referrer = ' + this._window.document.documentURIObject); - channel.referrer = this._window.document.documentURIObject; + debug('Setting HTTP referrer = ' + (referrer && referrer.spec)); + channel.referrer = referrer; if (channel instanceof Ci.nsIHttpChannelInternal) { channel.forceAllowThirdPartyCookie = true; } diff --git a/dom/webidl/BrowserElement.webidl b/dom/webidl/BrowserElement.webidl index 2d94ffbc6869..256637ed731d 100644 --- a/dom/webidl/BrowserElement.webidl +++ b/dom/webidl/BrowserElement.webidl @@ -8,6 +8,7 @@ callback BrowserElementNextPaintEventCallback = void (); dictionary BrowserElementDownloadOptions { DOMString? filename; + DOMString? referrer; }; [NoInterfaceObject]