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 234229 6a170ee249b2efeb91ecf9261d5184dc7d1eed06
parent 234228 62729dad4a89f57e1daae7352bfda2ee492f6ddd
child 234230 3019cfbbfd0db7444c7c15a914f2409c01fbb4e6
push id11828
push userryanvm@gmail.com
push dateWed, 18 Mar 2015 15:24:53 +0000
treeherderfx-team@4b5850a205d0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst, bz
bugs1113431
milestone39.0a1
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});
   },