Bug 1113431 - Expose referrer policy to UI code via Document and nsIWebNavigation. r=jst, sr=bz
authorAlex Verstak <averstak@google.com>
Mon, 05 Jan 2015 09:42:31 -0800
changeset 234302 6a170ee249b2efeb91ecf9261d5184dc7d1eed06
parent 234301 62729dad4a89f57e1daae7352bfda2ee492f6ddd
child 234303 3019cfbbfd0db7444c7c15a914f2409c01fbb4e6
push id28440
push userkwierso@gmail.com
push dateWed, 18 Mar 2015 22:38:34 +0000
treeherdermozilla-central@f3d9582e34fb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst, bz
bugs1113431
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1113431 - Expose referrer policy to UI code via Document and nsIWebNavigation. r=jst, sr=bz
docshell/base/nsDocShell.cpp
docshell/base/nsIWebNavigation.idl
docshell/shistory/src/nsSHistory.cpp
dom/base/nsDocument.h
dom/base/nsIDocument.h
dom/webidl/Document.webidl
embedding/browser/nsWebBrowser.cpp
netwerk/protocol/http/nsIHttpChannel.idl
toolkit/components/viewsource/content/viewPartialSource.js
toolkit/content/browser-child.js
toolkit/modules/RemoteWebNavigation.jsm
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4730,27 +4730,29 @@ nsDocShell::GotoIndex(int32_t aIndex)
 
 NS_IMETHODIMP
 nsDocShell::LoadURI(const char16_t* aURI,
                     uint32_t aLoadFlags,
                     nsIURI* aReferringURI,
                     nsIInputStream* aPostStream,
                     nsIInputStream* aHeaderStream)
 {
-  return LoadURIWithBase(aURI, aLoadFlags, aReferringURI, aPostStream,
-                         aHeaderStream, nullptr);
-}
-
-NS_IMETHODIMP
-nsDocShell::LoadURIWithBase(const char16_t* aURI,
-                            uint32_t aLoadFlags,
-                            nsIURI* aReferringURI,
-                            nsIInputStream* aPostStream,
-                            nsIInputStream* aHeaderStream,
-                            nsIURI* aBaseURI)
+  return LoadURIWithOptions(aURI, aLoadFlags, aReferringURI,
+                            mozilla::net::RP_Default, aPostStream,
+                            aHeaderStream, nullptr);
+}
+
+NS_IMETHODIMP
+nsDocShell::LoadURIWithOptions(const char16_t* aURI,
+                               uint32_t aLoadFlags,
+                               nsIURI* aReferringURI,
+                               uint32_t aReferrerPolicy,
+                               nsIInputStream* aPostStream,
+                               nsIInputStream* aHeaderStream,
+                               nsIURI* aBaseURI)
 {
   NS_ASSERTION((aLoadFlags & 0xf) == 0, "Unexpected flags");
 
   if (!IsNavigationAllowed()) {
     return NS_OK; // JS may not handle returning of an error code
   }
   nsCOMPtr<nsIURI> uri;
   nsCOMPtr<nsIInputStream> postStream(aPostStream);
@@ -4850,16 +4852,17 @@ nsDocShell::LoadURIWithBase(const char16
     loadType = MAKE_LOAD_TYPE(LOAD_NORMAL_ALLOW_MIXED_CONTENT, aLoadFlags);
   } else {
     loadType = MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags);
   }
 
   loadInfo->SetLoadType(ConvertLoadTypeToDocShellLoadInfo(loadType));
   loadInfo->SetPostDataStream(postStream);
   loadInfo->SetReferrer(aReferringURI);
+  loadInfo->SetReferrerPolicy(aReferrerPolicy);
   loadInfo->SetHeadersStream(aHeaderStream);
   loadInfo->SetBaseURI(aBaseURI);
 
   if (fixupInfo) {
     nsAutoString searchProvider, keyword;
     fixupInfo->GetKeywordProviderName(searchProvider);
     fixupInfo->GetKeywordAsSent(keyword);
     MaybeNotifyKeywordSearchLoading(searchProvider, keyword);
--- a/docshell/base/nsIWebNavigation.idl
+++ b/docshell/base/nsIWebNavigation.idl
@@ -11,17 +11,17 @@ interface nsISHistory;
 interface nsIURI;
 
 /**
  * The nsIWebNavigation interface defines an interface for navigating the web.
  * It provides methods and attributes to direct an object to navigate to a new
  * location, stop or restart an in process load, or determine where the object
  * has previously gone.
  */
-[scriptable, uuid(b7568a50-4c50-442c-a6be-3a340a48d89a)]
+[scriptable, uuid(0e92d522-53a5-4af6-9a24-4eccdcbf4f91)]
 interface nsIWebNavigation : nsISupports
 {
   /**
    * Indicates if the object can go back.  If true this indicates that
    * there is back session history available for navigation.
    */
   readonly attribute boolean canGoBack;
 
@@ -235,34 +235,34 @@ interface nsIWebNavigation : nsISupports
                in nsIInputStream aPostData,
                in nsIInputStream aHeaders);
 
   /**
    * Loads a given URI.  This will give priority to loading the requested URI
    * in the object implementing this interface.  If it can't be loaded here
    * however, the URI dispatcher will go through its normal process of content
    * loading.
-   * Behaves like loadURI, except an additional parameter is provided to supply
-   * a base URI to be used in specific situations where one cannot be inferred
-   * by other means, for example when this is called to view selection source.
-   * Outside of these situations, the behaviour of this function is no
-   * different to loadURI.
+   *
+   * Behaves like loadURI, but allows passing of additional parameters.
    *
    * @param aURI
    *        The URI string to load.  For HTTP and FTP URLs and possibly others,
    *        characters above U+007F will be converted to UTF-8 and then URL-
    *        escaped per the rules of RFC 2396.
    * @param aLoadFlags
    *        Flags modifying load behaviour.  This parameter is a bitwise
    *        combination of the load flags defined above.  (Undefined bits are
    *        reserved for future use.)  Generally you will pass LOAD_FLAGS_NONE
    *        for this parameter.
    * @param aReferrer
    *        The referring URI.  If this argument is null, then the referring
    *        URI will be inferred internally.
+   * @param aReferrerPolicy
+   *        One of the REFERRER_POLICY_* constants from nsIHttpChannel.
+   *        Normal case is REFERRER_POLICY_DEFAULT.
    * @param aPostData
    *        If the URI corresponds to a HTTP request, then this stream is
    *        appended directly to the HTTP request headers.  It may be prefixed
    *        with additional HTTP headers.  This stream must contain a "\r\n"
    *        sequence separating any HTTP headers from the HTTP request body.
    *        This parameter is optional and may be null.
    * @param aHeaders
    *        If the URI corresponds to a HTTP request, then any HTTP headers
@@ -271,22 +271,23 @@ interface nsIWebNavigation : nsISupports
    *            ( HEADER "\r\n" )*
    *        This parameter is optional and may be null.
    * @param aBaseURI
    *        Set to indicate a base URI to be associated with the load. Note
    *        that at present this argument is only used with view-source aURIs
    *        and cannot be used to resolve aURI.
    *        This parameter is optional and may be null.
    */
-  void loadURIWithBase(in wstring        aURI,
-                       in unsigned long  aLoadFlags,
-                       in nsIURI         aReferrer,
-                       in nsIInputStream aPostData,
-                       in nsIInputStream aHeaders,
-                       in nsIURI         aBaseURI);
+  void loadURIWithOptions(in wstring        aURI,
+                          in unsigned long  aLoadFlags,
+                          in nsIURI         aReferrer,
+                          in unsigned long  aReferrerPolicy,
+                          in nsIInputStream aPostData,
+                          in nsIInputStream aHeaders,
+                          in nsIURI         aBaseURI);
 
   /**
    * Tells the Object to reload the current page.  There may be cases where the
    * user will be asked to confirm the reload (for example, when it is
    * determined that the request is non-idempotent).
    *
    * @param aReloadFlags
    *        Flags modifying load behaviour.  This parameter is a bitwise
--- a/docshell/shistory/src/nsSHistory.cpp
+++ b/docshell/shistory/src/nsSHistory.cpp
@@ -1508,22 +1508,23 @@ nsSHistory::SetSessionHistory(nsISHistor
 NS_IMETHODIMP
 nsSHistory::GetSessionHistory(nsISHistory** aSessionHistory)
 {
   // Not implemented
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSHistory::LoadURIWithBase(const char16_t* aURI,
-                            uint32_t aLoadFlags,
-                            nsIURI* aReferringURI,
-                            nsIInputStream* aPostStream,
-                            nsIInputStream* aExtraHeaderStream,
-                            nsIURI* aBaseURI)
+nsSHistory::LoadURIWithOptions(const char16_t* aURI,
+                               uint32_t aLoadFlags,
+                               nsIURI* aReferringURI,
+                               uint32_t aReferrerPolicy,
+                               nsIInputStream* aPostStream,
+                               nsIInputStream* aExtraHeaderStream,
+                               nsIURI* aBaseURI)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSHistory::LoadURI(const char16_t* aURI,
                     uint32_t aLoadFlags,
                     nsIURI* aReferringURI,
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -681,16 +681,17 @@ class nsDocument : public nsIDocument,
                    public nsIObserver,
                    public nsIDOMXPathEvaluator
 {
   friend class nsIDocument;
 
 public:
   typedef mozilla::dom::Element Element;
   using nsIDocument::GetElementsByTagName;
+  typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_SIZEOF_EXCLUDING_THIS
 
   virtual void Reset(nsIChannel *aChannel, nsILoadGroup *aLoadGroup) MOZ_OVERRIDE;
   virtual void ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
                           nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -178,17 +178,17 @@ NS_GetContentList(nsINode* aRootNode,
 //----------------------------------------------------------------------
 
 // Document interface.  This is implemented by all document objects in
 // Gecko.
 class nsIDocument : public nsINode
 {
   typedef mozilla::dom::GlobalObject GlobalObject;
 public:
-  typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
+  typedef mozilla::net::ReferrerPolicy ReferrerPolicyEnum;
   typedef mozilla::dom::Element Element;
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENT_IID)
   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
 
 #ifdef MOZILLA_INTERNAL_API
   nsIDocument();
 #endif
@@ -285,22 +285,30 @@ public:
    * chrome privileged script.
    */
   virtual void SetChromeXHRDocBaseURI(nsIURI* aURI) = 0;
 
   /**
    * Return the referrer policy of the document. Return "default" if there's no
    * valid meta referrer tag found in the document.
    */
-  ReferrerPolicy GetReferrerPolicy() const
+  ReferrerPolicyEnum GetReferrerPolicy() const
   {
     return mReferrerPolicy;
   }
 
   /**
+   * GetReferrerPolicy() for Document.webidl.
+   */
+  uint32_t ReferrerPolicy() const
+  {
+    return GetReferrerPolicy();
+  }
+
+  /**
    * Set the principal responsible for this document.
    */
   virtual void SetPrincipal(nsIPrincipal *aPrincipal) = 0;
 
   /**
    * Return the LoadGroup for the document. May return null.
    */
   already_AddRefed<nsILoadGroup> GetDocumentLoadGroup() const
@@ -1964,32 +1972,32 @@ public:
   /**
    * Called by nsParser to preload images. Can be removed and code moved
    * to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
    * parser-module is linked with gklayout-module.  aCrossOriginAttr should
    * be a void string if the attr is not present.
    */
   virtual void MaybePreLoadImage(nsIURI* uri,
                                  const nsAString& aCrossOriginAttr,
-                                 ReferrerPolicy aReferrerPolicy) = 0;
+                                 ReferrerPolicyEnum aReferrerPolicy) = 0;
 
   /**
    * Called by images to forget an image preload when they start doing
    * the real load.
    */
   virtual void ForgetImagePreload(nsIURI* aURI) = 0;
 
   /**
    * Called by nsParser to preload style sheets.  Can also be merged into the
    * parser if and when the parser is merged with libgklayout.  aCrossOriginAttr
    * should be a void string if the attr is not present.
    */
   virtual void PreloadStyle(nsIURI* aURI, const nsAString& aCharset,
                             const nsAString& aCrossOriginAttr,
-                            ReferrerPolicy aReferrerPolicy) = 0;
+                            ReferrerPolicyEnum aReferrerPolicy) = 0;
 
   /**
    * Called by the chrome registry to load style sheets.  Can be put
    * back there if and when when that module is merged with libgklayout.
    *
    * This always does a synchronous load.  If aIsAgentSheet is true,
    * it also uses the system principal and enables unsafe rules.
    * DO NOT USE FOR UNTRUSTED CONTENT.
@@ -2576,17 +2584,17 @@ protected:
   nsCOMPtr<nsIURI> mOriginalURI;
   nsCOMPtr<nsIURI> mChromeXHRDocURI;
   nsCOMPtr<nsIURI> mDocumentBaseURI;
   nsCOMPtr<nsIURI> mChromeXHRDocBaseURI;
 
   nsWeakPtr mDocumentLoadGroup;
 
   bool mReferrerPolicySet;
-  ReferrerPolicy mReferrerPolicy;
+  ReferrerPolicyEnum mReferrerPolicy;
 
   mozilla::WeakPtr<nsDocShell> mDocumentContainer;
 
   nsCString mCharacterSet;
   int32_t mCharacterSetSource;
 
   // This is just a weak pointer; the parent document owns its children.
   nsIDocument* mParentDocument;
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -199,16 +199,23 @@ partial interface Document {
    * @see <https://developer.mozilla.org/en/DOM/document.mozSetImageElement>
    */
   void mozSetImageElement(DOMString aImageElementId,
                           Element? aImageElement);
 
   [ChromeOnly]
   readonly attribute URI? documentURIObject;
 
+  /**
+   * Current referrer policy - one of the REFERRER_POLICY_* constants
+   * from nsIHttpChannel.
+   */
+  [ChromeOnly]
+  readonly attribute unsigned long referrerPolicy;
+
 };
 
 // http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#api
 partial interface Document {
   // Note: Per spec the 'S' in these two is lowercase, but the "Moz"
   // versions hve it uppercase.
   readonly attribute boolean mozFullScreenEnabled;
   [Throws]
--- a/embedding/browser/nsWebBrowser.cpp
+++ b/embedding/browser/nsWebBrowser.cpp
@@ -573,31 +573,33 @@ NS_IMETHODIMP nsWebBrowser::GoBack()
 
 NS_IMETHODIMP nsWebBrowser::GoForward()
 {
   NS_ENSURE_STATE(mDocShell);
 
   return mDocShellAsNav->GoForward();
 }
 
-NS_IMETHODIMP nsWebBrowser::LoadURIWithBase(const char16_t* aURI,
-                                            uint32_t aLoadFlags,
-                                            nsIURI* aReferringURI,
-                                            nsIInputStream* aPostDataStream,
-                                            nsIInputStream* aExtraHeaderStream,
-                                            nsIURI* aBaseURI)
+NS_IMETHODIMP nsWebBrowser::LoadURIWithOptions(const char16_t* aURI,
+                                               uint32_t aLoadFlags,
+                                               nsIURI* aReferringURI,
+                                               uint32_t aReferrerPolicy,
+                                               nsIInputStream* aPostDataStream,
+                                               nsIInputStream* aExtraHeaderStream,
+                                               nsIURI* aBaseURI)
 {
   NS_ENSURE_STATE(mDocShell);
 
-  return mDocShellAsNav->LoadURIWithBase(aURI,
-                                         aLoadFlags,
-                                         aReferringURI,
-                                         aPostDataStream,
-                                         aExtraHeaderStream,
-                                         aBaseURI);
+  return mDocShellAsNav->LoadURIWithOptions(aURI,
+                                            aLoadFlags,
+                                            aReferringURI,
+                                            aReferrerPolicy,
+                                            aPostDataStream,
+                                            aExtraHeaderStream,
+                                            aBaseURI);
 }
 
 NS_IMETHODIMP nsWebBrowser::LoadURI(const char16_t* aURI,
                                     uint32_t aLoadFlags,
                                     nsIURI* aReferringURI,
                                     nsIInputStream* aPostDataStream,
                                     nsIInputStream* aExtraHeaderStream)
 {
--- a/netwerk/protocol/http/nsIHttpChannel.idl
+++ b/netwerk/protocol/http/nsIHttpChannel.idl
@@ -9,17 +9,17 @@ interface nsIHttpHeaderVisitor;
 
 /**
  * nsIHttpChannel
  *
  * This interface allows for the modification of HTTP request parameters and
  * the inspection of the resulting HTTP response status and headers when they
  * become available.
  */
-[scriptable, uuid(a8bed710-653c-4ea4-9747-a629cc482cf8)]
+[scriptable, uuid(86ad7e1f-3a64-4e0f-a104-395ebecd7d5c)]
 interface nsIHttpChannel : nsIChannel
 {
     /**************************************************************************
      * REQUEST CONFIGURATION
      *
      * Modifying request parameters after asyncOpen has been called is an error.
      */
 
@@ -54,16 +54,18 @@ interface nsIHttpChannel : nsIChannel
      * @throws NS_ERROR_IN_PROGRESS if set after the channel has been opened.
      */
     attribute nsIURI referrer;
 
     /**
      * Referrer policies. See ReferrerPolicy.h for more details.
      */
 
+    /*   default state, a shorter name for no-referrer-when-downgrade   */
+    const unsigned long REFERRER_POLICY_DEFAULT                    = 0;
     /*   default state, doesn't send referrer from https->http          */
     const unsigned long REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE = 0;
     /*   sends no referrer                                              */
     const unsigned long REFERRER_POLICY_NO_REFERRER                = 1;
     /*   only sends the origin of the referring URL                     */
     const unsigned long REFERRER_POLICY_ORIGIN                     = 2;
     /*   same as default, but reduced to ORIGIN when cross-origin.      */
     const unsigned long REFERRER_POLICY_ORIGIN_WHEN_XORIGIN        = 3;
--- a/toolkit/components/viewsource/content/viewPartialSource.js
+++ b/toolkit/components/viewsource/content/viewPartialSource.js
@@ -168,22 +168,25 @@ function viewPartialSourceForSelection(s
   // the load is aynchronous and so we will wait until the view-source DOM is done
   // before drawing the selection.
   if (canDrawSelection) {
     window.document.getElementById("content").addEventListener("load", drawSelection, true);
   }
 
   // all our content is held by the data:URI and URIs are internally stored as utf-8 (see nsIURI.idl)
   var loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_NONE;
-  getWebNavigation().loadURIWithBase((isHTML ?
-                                      "view-source:data:text/html;charset=utf-8," :
-                                      "view-source:data:application/xml;charset=utf-8,")
-                                     + encodeURIComponent(tmpNode.innerHTML),
-                                     loadFlags, null, null, null,
-                                     Services.io.newURI(doc.baseURI, null, null));
+  var referrerPolicy = Components.interfaces.nsIHttpChannel.REFERRER_POLICY_DEFAULT;
+  getWebNavigation().loadURIWithOptions((isHTML ?
+                                         "view-source:data:text/html;charset=utf-8," :
+                                         "view-source:data:application/xml;charset=utf-8,")
+                                        + encodeURIComponent(tmpNode.innerHTML),
+                                        loadFlags,
+                                        null, referrerPolicy,  // referrer
+                                        null, null,  // postData, headers
+                                        Services.io.newURI(doc.baseURI, null, null));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // helper to get a path like FIXptr, but with an array instead of the "tumbler" notation
 // see FIXptr: http://lists.w3.org/Archives/Public/www-xml-linking-comments/2001AprJun/att-0074/01-NOTE-FIXptr-20010425.htm
 function getPath(ancestor, node)
 {
   var n = node;
--- a/toolkit/content/browser-child.js
+++ b/toolkit/content/browser-child.js
@@ -213,17 +213,19 @@ let WebNavigation =  {
         break;
       case "WebNavigation:GoForward":
         this.goForward();
         break;
       case "WebNavigation:GotoIndex":
         this.gotoIndex(message.data.index);
         break;
       case "WebNavigation:LoadURI":
-        this.loadURI(message.data.uri, message.data.flags, message.data.referrer);
+        this.loadURI(message.data.uri, message.data.flags,
+                     message.data.referrer, message.data.referrerPolicy,
+                     message.data.baseURI);
         break;
       case "WebNavigation:Reload":
         this.reload(message.data.flags);
         break;
       case "WebNavigation:Stop":
         this.stop(message.data.flags);
         break;
     }
@@ -239,24 +241,27 @@ let WebNavigation =  {
     if (this._webNavigation.canGoForward)
       this._webNavigation.goForward();
   },
 
   gotoIndex: function(index) {
     this._webNavigation.gotoIndex(index);
   },
 
-  loadURI: function(uri, flags, referrer) {
+  loadURI: function(uri, flags, referrer, referrerPolicy, baseURI) {
 #ifdef MOZ_CRASHREPORTER
     if (CrashReporter.enabled)
       CrashReporter.annotateCrashReport("URL", uri);
 #endif
     if (referrer)
       referrer = Services.io.newURI(referrer, null, null);
-    this._webNavigation.loadURI(uri, flags, referrer, null, null);
+    if (baseURI)
+      baseURI = Services.io.newURI(baseURI, null, null);
+    this._webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy,
+                                           null, null, baseURI);
   },
 
   reload: function(flags) {
     this._webNavigation.reload(flags);
   },
 
   stop: function(flags) {
     this._webNavigation.stop(flags);
--- a/toolkit/modules/RemoteWebNavigation.jsm
+++ b/toolkit/modules/RemoteWebNavigation.jsm
@@ -62,23 +62,31 @@ RemoteWebNavigation.prototype = {
   },
   goForward: function() {
     this._sendMessage("WebNavigation:GoForward", {});
   },
   gotoIndex: function(aIndex) {
     this._sendMessage("WebNavigation:GotoIndex", {index: aIndex});
   },
   loadURI: function(aURI, aLoadFlags, aReferrer, aPostData, aHeaders) {
+    this.loadURIWithOptions(aURI, aLoadFlags, aReferrer,
+                            Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT,
+                            aPostData, aHeaders, null);
+  },
+  loadURIWithOptions: function(aURI, aLoadFlags, aReferrer, aReferrerPolicy,
+                               aPostData, aHeaders, aBaseURI) {
     if (aPostData || aHeaders)
       throw Components.Exception("RemoteWebNavigation doesn't accept postdata or headers.", Cr.NS_ERROR_INVALID_ARGS);
 
     this._sendMessage("WebNavigation:LoadURI", {
       uri: aURI,
       flags: aLoadFlags,
-      referrer: aReferrer ? aReferrer.spec : null
+      referrer: aReferrer ? aReferrer.spec : null,
+      referrerPolicy: aReferrerPolicy,
+      baseURI: aBaseURI ? aBaseURI.spec : null,
     });
   },
   reload: function(aReloadFlags) {
     this._sendMessage("WebNavigation:Reload", {flags: aReloadFlags});
   },
   stop: function(aStopFlags) {
     this._sendMessage("WebNavigation:Stop", {flags: aStopFlags});
   },