Bug 1107638 - Add innerWindowID to LoadInfo (r=sicking,jduell)
authorChristoph Kerschbaumer <mozilla@christophkerschbaumer.com>
Wed, 07 Jan 2015 15:51:20 -0800
changeset 235619 eab4b3520c509ec440cc648d795964b06b353d01
parent 235618 87ca345a376736ce695cbc157fdb280e9b4d911b
child 235620 7584b643e7e9e44c450c186e2631bed91fea5850
push id366
push usercmanchester@mozilla.com
push dateThu, 08 Jan 2015 16:40:24 +0000
reviewerssicking, jduell
bugs1107638
milestone37.0a1
Bug 1107638 - Add innerWindowID to LoadInfo (r=sicking,jduell)
docshell/base/LoadInfo.cpp
docshell/base/LoadInfo.h
docshell/base/nsILoadInfo.idl
netwerk/ipc/NeckoChannelParams.ipdlh
netwerk/protocol/ftp/FTPChannelChild.cpp
netwerk/protocol/ftp/FTPChannelParent.cpp
netwerk/protocol/ftp/FTPChannelParent.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.h
--- a/docshell/base/LoadInfo.cpp
+++ b/docshell/base/LoadInfo.cpp
@@ -23,31 +23,48 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
   : mLoadingPrincipal(aLoadingContext ?
                         aLoadingContext->NodePrincipal() : aLoadingPrincipal)
   , mTriggeringPrincipal(aTriggeringPrincipal ?
                            aTriggeringPrincipal : mLoadingPrincipal.get())
   , mLoadingContext(do_GetWeakReference(aLoadingContext))
   , mSecurityFlags(aSecurityFlags)
   , mContentPolicyType(aContentPolicyType)
   , mBaseURI(aBaseURI)
+  , mInnerWindowID(aLoadingContext ?
+                     aLoadingContext->OwnerDoc()->InnerWindowID() : 0)
 {
   MOZ_ASSERT(mLoadingPrincipal);
   MOZ_ASSERT(mTriggeringPrincipal);
 
   // if consumers pass both, aLoadingContext and aLoadingPrincipal
   // then the loadingPrincipal must be the same as the node's principal
   MOZ_ASSERT(!aLoadingContext || !aLoadingPrincipal ||
              aLoadingContext->NodePrincipal() == aLoadingPrincipal);
 
   // if the load is sandboxed, we can not also inherit the principal
   if (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED) {
     mSecurityFlags ^= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
   }
 }
 
+LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
+                   nsIPrincipal* aTriggeringPrincipal,
+                   nsSecurityFlags aSecurityFlags,
+                   nsContentPolicyType aContentPolicyType,
+                   uint32_t aInnerWindowID)
+  : mLoadingPrincipal(aLoadingPrincipal)
+  , mTriggeringPrincipal(aTriggeringPrincipal)
+  , mSecurityFlags(aSecurityFlags)
+  , mContentPolicyType(aContentPolicyType)
+  , mInnerWindowID(aInnerWindowID)
+{
+  MOZ_ASSERT(mLoadingPrincipal);
+  MOZ_ASSERT(mTriggeringPrincipal);
+}
+
 LoadInfo::~LoadInfo()
 {
 }
 
 NS_IMPL_ISUPPORTS(LoadInfo, nsILoadInfo)
 
 NS_IMETHODIMP
 LoadInfo::GetLoadingPrincipal(nsIPrincipal** aLoadingPrincipal)
@@ -130,9 +147,16 @@ LoadInfo::GetBaseURI(nsIURI** aBaseURI)
 }
 
 nsIURI*
 LoadInfo::BaseURI()
 {
   return mBaseURI;
 }
 
+NS_IMETHODIMP
+LoadInfo::GetInnerWindowID(uint32_t* outInnerWindowID)
+{
+  *outInnerWindowID = mInnerWindowID;
+  return NS_OK;
+}
+
 } // namespace mozilla
--- a/docshell/base/LoadInfo.h
+++ b/docshell/base/LoadInfo.h
@@ -12,16 +12,21 @@
 #include "nsIPrincipal.h"
 #include "nsIWeakReferenceUtils.h" // for nsWeakPtr
 #include "nsIURI.h"
 
 class nsINode;
 
 namespace mozilla {
 
+namespace net {
+class HttpChannelParent;
+class FTPChannelParent;
+}
+
 /**
  * Class that provides an nsILoadInfo implementation.
  */
 class MOZ_EXPORT LoadInfo MOZ_FINAL : public nsILoadInfo
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSILOADINFO
@@ -30,22 +35,35 @@ public:
   LoadInfo(nsIPrincipal* aLoadingPrincipal,
            nsIPrincipal* aTriggeringPrincipal,
            nsINode* aLoadingContext,
            nsSecurityFlags aSecurityFlags,
            nsContentPolicyType aContentPolicyType,
            nsIURI* aBaseURI = nullptr);
 
 private:
+  // private constructor that is only allowed to be called from within
+  // HttpChannelParent and FTPChannelParent declared as friends undeneath.
+  // In e10s we can not serialize nsINode, hence we store the innerWindowID.
+  LoadInfo(nsIPrincipal* aLoadingPrincipal,
+           nsIPrincipal* aTriggeringPrincipal,
+           nsSecurityFlags aSecurityFlags,
+           nsContentPolicyType aContentPolicyType,
+           uint32_t aInnerWindowID);
+
+  friend class net::HttpChannelParent;
+  friend class net::FTPChannelParent;
+
   ~LoadInfo();
 
   nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
   nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
   nsWeakPtr              mLoadingContext;
   nsSecurityFlags        mSecurityFlags;
   nsContentPolicyType    mContentPolicyType;
   nsCOMPtr<nsIURI>       mBaseURI;
+  uint32_t               mInnerWindowID;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_LoadInfo_h
 
--- a/docshell/base/nsILoadInfo.idl
+++ b/docshell/base/nsILoadInfo.idl
@@ -175,9 +175,29 @@ interface nsILoadInfo : nsISupports
    */
   readonly attribute nsIURI baseURI;
 
   /**
    * A C++-friendly version of baseURI.
    */
   [noscript, notxpcom, nostdcall, binaryname(BaseURI)]
   nsIURI binaryBaseURI();
+
+  /**
+   * The innerWindowId of the loadingDocument, used to identify
+   * the loadingDocument in e10s where the loadingDocument is
+   * not available.
+   *
+   * Warning: If the loadingDocument is null, then the
+   * innerWindowId is 0.
+   */
+  readonly attribute unsigned long innerWindowID;
+
+%{ C++
+  inline uint32_t GetInnerWindowID()
+  {
+    uint32_t result;
+    mozilla::DebugOnly<nsresult> rv = GetInnerWindowID(&result);
+    MOZ_ASSERT(NS_SUCCEEDED(rv));
+    return result;
+  }
+%}
 };
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -52,16 +52,17 @@ struct HttpChannelOpenArgs
   bool                        chooseApplicationCache;
   nsCString                   appCacheClientID;
   bool                        allowSpdy;
   OptionalFileDescriptorSet   fds;
   PrincipalInfo               requestingPrincipalInfo;
   PrincipalInfo               triggeringPrincipalInfo;
   uint32_t                    securityFlags;
   uint32_t                    contentPolicyType;
+  uint32_t                    innerWindowID;
 };
 
 struct HttpChannelConnectArgs
 {
   uint32_t channelId;
 };
 
 union HttpChannelCreationArgs
@@ -79,16 +80,17 @@ struct FTPChannelOpenArgs
   URIParams                 uri;
   uint64_t                  startPos;
   nsCString                 entityID;
   OptionalInputStreamParams uploadStream;
   PrincipalInfo             requestingPrincipalInfo;
   PrincipalInfo             triggeringPrincipalInfo;
   uint32_t                  securityFlags;
   uint32_t                  contentPolicyType;
+  uint32_t                  innerWindowID;
 };
 
 struct FTPChannelConnectArgs
 {
   uint32_t channelId;
 };
 
 union FTPChannelCreationArgs
--- a/netwerk/protocol/ftp/FTPChannelChild.cpp
+++ b/netwerk/protocol/ftp/FTPChannelChild.cpp
@@ -158,26 +158,28 @@ propagateLoadInfo(nsILoadInfo *aLoadInfo
     openArgs.requestingPrincipalInfo() = requestingPrincipalInfo;
 
     mozilla::ipc::PrincipalToPrincipalInfo(aLoadInfo->TriggeringPrincipal(),
                                            &triggeringPrincipalInfo);
     openArgs.triggeringPrincipalInfo() = triggeringPrincipalInfo;
 
     openArgs.securityFlags() = aLoadInfo->GetSecurityFlags();
     openArgs.contentPolicyType() = aLoadInfo->GetContentPolicyType();
+    openArgs.innerWindowID() = aLoadInfo->GetInnerWindowID();
     return;
   }
 
   // use default values if no loadInfo is provided
   mozilla::ipc::PrincipalToPrincipalInfo(nsContentUtils::GetSystemPrincipal(),
                                          &requestingPrincipalInfo);
   openArgs.requestingPrincipalInfo() = requestingPrincipalInfo;
   openArgs.triggeringPrincipalInfo() = requestingPrincipalInfo;
   openArgs.securityFlags() = nsILoadInfo::SEC_NORMAL;
   openArgs.contentPolicyType() = nsIContentPolicy::TYPE_OTHER;
+  openArgs.innerWindowID() = 0;
 }
 
 NS_IMETHODIMP
 FTPChannelChild::AsyncOpen(::nsIStreamListener* listener, nsISupports* aContext)
 {
   LOG(("FTPChannelChild::AsyncOpen [this=%p]\n", this));
 
   NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE);
--- a/netwerk/protocol/ftp/FTPChannelParent.cpp
+++ b/netwerk/protocol/ftp/FTPChannelParent.cpp
@@ -14,16 +14,17 @@
 #include "nsIForcePendingChannel.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/unused.h"
 #include "SerializedLoadContext.h"
 #include "nsIContentPolicy.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "nsIOService.h"
+#include "mozilla/LoadInfo.h"
 
 using namespace mozilla::ipc;
 
 #undef LOG
 #define LOG(args) PR_LOG(gFTPLog, PR_LOG_DEBUG, args)
 
 namespace mozilla {
 namespace net {
@@ -83,17 +84,17 @@ bool
 FTPChannelParent::Init(const FTPChannelCreationArgs& aArgs)
 {
   switch (aArgs.type()) {
   case FTPChannelCreationArgs::TFTPChannelOpenArgs:
   {
     const FTPChannelOpenArgs& a = aArgs.get_FTPChannelOpenArgs();
     return DoAsyncOpen(a.uri(), a.startPos(), a.entityID(), a.uploadStream(),
                        a.requestingPrincipalInfo(), a.triggeringPrincipalInfo(),
-                       a.securityFlags(), a.contentPolicyType());
+                       a.securityFlags(), a.contentPolicyType(), a.innerWindowID());
   }
   case FTPChannelCreationArgs::TFTPChannelConnectArgs:
   {
     const FTPChannelConnectArgs& cArgs = aArgs.get_FTPChannelConnectArgs();
     return ConnectChannel(cArgs.channelId());
   }
   default:
     NS_NOTREACHED("unknown open type");
@@ -104,17 +105,18 @@ FTPChannelParent::Init(const FTPChannelC
 bool
 FTPChannelParent::DoAsyncOpen(const URIParams& aURI,
                               const uint64_t& aStartPos,
                               const nsCString& aEntityID,
                               const OptionalInputStreamParams& aUploadStream,
                               const ipc::PrincipalInfo& aRequestingPrincipalInfo,
                               const ipc::PrincipalInfo& aTriggeringPrincipalInfo,
                               const uint32_t& aSecurityFlags,
-                              const uint32_t& aContentPolicyType)
+                              const uint32_t& aContentPolicyType,
+                              const uint32_t& aInnerWindowID)
 {
   nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
   if (!uri)
       return false;
 
 #ifdef DEBUG
   nsCString uriSpec;
   uri->GetSpec(uriSpec);
@@ -143,29 +145,26 @@ FTPChannelParent::DoAsyncOpen(const URIP
   if (NS_FAILED(rv)) {
     return SendFailedAsyncOpen(rv);
   }
   nsCOMPtr<nsIPrincipal> triggeringPrincipal =
     mozilla::ipc::PrincipalInfoToPrincipal(aTriggeringPrincipalInfo, &rv);
   if (NS_FAILED(rv)) {
     return SendFailedAsyncOpen(rv);
   }
-  
+
+  nsCOMPtr<nsILoadInfo> loadInfo =
+    new mozilla::LoadInfo(requestingPrincipal, triggeringPrincipal,
+                          aSecurityFlags, aContentPolicyType,
+                          aInnerWindowID);
 
   nsCOMPtr<nsIChannel> chan;
-  rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(chan),
-                                            uri,
-                                            requestingPrincipal,
-                                            triggeringPrincipal,
-                                            aSecurityFlags,
-                                            aContentPolicyType,
-                                            nullptr, // aLoadGroup
-                                            nullptr, // aCallbacks
-                                            nsIRequest::LOAD_NORMAL,
-                                            ios);
+  rv = NS_NewChannelInternal(getter_AddRefs(chan), uri, loadInfo,
+                             nullptr, nullptr,
+                             nsIRequest::LOAD_NORMAL, ios);
 
   if (NS_FAILED(rv))
     return SendFailedAsyncOpen(rv);
 
   mChannel = chan;
 
   // later on mChannel may become an HTTP channel (we'll be redirected to one
   // if we're using a proxy), but for now this is safe
--- a/netwerk/protocol/ftp/FTPChannelParent.h
+++ b/netwerk/protocol/ftp/FTPChannelParent.h
@@ -63,17 +63,18 @@ protected:
   void FailDiversion(nsresult aErrorCode, bool aSkipResume = true);
 
   bool DoAsyncOpen(const URIParams& aURI, const uint64_t& aStartPos,
                    const nsCString& aEntityID,
                    const OptionalInputStreamParams& aUploadStream,
                    const ipc::PrincipalInfo& aRequestingPrincipalInfo,
                    const ipc::PrincipalInfo& aTriggeringPrincipalInfo,
                    const uint32_t& aSecurityFlags,
-                   const uint32_t& aContentPolicyType);
+                   const uint32_t& aContentPolicyType,
+                   const uint32_t& aInnerWindowID);
 
   // used to connect redirected-to channel in parent with just created
   // ChildChannel.  Used during HTTP->FTP redirects.
   bool ConnectChannel(const uint32_t& channelId);
 
   virtual bool RecvCancel(const nsresult& status) MOZ_OVERRIDE;
   virtual bool RecvSuspend() MOZ_OVERRIDE;
   virtual bool RecvResume() MOZ_OVERRIDE;
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -1270,26 +1270,28 @@ propagateLoadInfo(nsILoadInfo *aLoadInfo
     openArgs.requestingPrincipalInfo() = requestingPrincipalInfo;
 
     mozilla::ipc::PrincipalToPrincipalInfo(aLoadInfo->TriggeringPrincipal(),
                                            &triggeringPrincipalInfo);
     openArgs.triggeringPrincipalInfo() = triggeringPrincipalInfo;
 
     openArgs.securityFlags() = aLoadInfo->GetSecurityFlags();
     openArgs.contentPolicyType() = aLoadInfo->GetContentPolicyType();
+    openArgs.innerWindowID() = aLoadInfo->GetInnerWindowID();
     return;
   }
 
   // use default values if no loadInfo is provided
   mozilla::ipc::PrincipalToPrincipalInfo(nsContentUtils::GetSystemPrincipal(),
                                          &requestingPrincipalInfo);
   openArgs.requestingPrincipalInfo() = requestingPrincipalInfo;
   openArgs.triggeringPrincipalInfo() = requestingPrincipalInfo;
   openArgs.securityFlags() = nsILoadInfo::SEC_NORMAL;
   openArgs.contentPolicyType() = nsIContentPolicy::TYPE_OTHER;
+  openArgs.innerWindowID() = 0;
 }
 
 NS_IMETHODIMP
 HttpChannelChild::GetSecurityInfo(nsISupports **aSecurityInfo)
 {
   NS_ENSURE_ARG_POINTER(aSecurityInfo);
   NS_IF_ADDREF(*aSecurityInfo = mSecurityInfo);
   return NS_OK;
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -26,17 +26,17 @@
 #include "mozilla/ipc/URIUtils.h"
 #include "SerializedLoadContext.h"
 #include "nsIAuthInformation.h"
 #include "nsIAuthPromptCallback.h"
 #include "nsIContentPolicy.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "nsIOService.h"
 #include "nsICachingChannel.h"
-
+#include "mozilla/LoadInfo.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 HttpChannelParent::HttpChannelParent(const PBrowserOrId& iframeEmbedding,
@@ -101,17 +101,17 @@ HttpChannelParent::Init(const HttpChanne
                        a.loadFlags(), a.requestHeaders(),
                        a.requestMethod(), a.uploadStream(),
                        a.uploadStreamHasHeaders(), a.priority(), a.classOfService(),
                        a.redirectionLimit(), a.allowPipelining(), a.allowSTS(),
                        a.thirdPartyFlags(), a.resumeAt(), a.startPos(),
                        a.entityID(), a.chooseApplicationCache(),
                        a.appCacheClientID(), a.allowSpdy(), a.fds(),
                        a.requestingPrincipalInfo(), a.triggeringPrincipalInfo(),
-                       a.securityFlags(), a.contentPolicyType());
+                       a.securityFlags(), a.contentPolicyType(), a.innerWindowID());
   }
   case HttpChannelCreationArgs::THttpChannelConnectArgs:
   {
     const HttpChannelConnectArgs& cArgs = aArgs.get_HttpChannelConnectArgs();
     return ConnectChannel(cArgs.channelId());
   }
   default:
     NS_NOTREACHED("unknown open type");
@@ -191,17 +191,18 @@ HttpChannelParent::DoAsyncOpen(  const U
                                  const nsCString&           entityID,
                                  const bool&                chooseApplicationCache,
                                  const nsCString&           appCacheClientID,
                                  const bool&                allowSpdy,
                                  const OptionalFileDescriptorSet& aFds,
                                  const ipc::PrincipalInfo&  aRequestingPrincipalInfo,
                                  const ipc::PrincipalInfo&  aTriggeringPrincipalInfo,
                                  const uint32_t&            aSecurityFlags,
-                                 const uint32_t&            aContentPolicyType)
+                                 const uint32_t&            aContentPolicyType,
+                                 const uint32_t&            aInnerWindowID)
 {
   nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
   if (!uri) {
     // URIParams does MOZ_ASSERT if null, but we need to protect opt builds from
     // null deref here.
     return false;
   }
   nsCOMPtr<nsIURI> originalUri = DeserializeURI(aOriginalURI);
@@ -241,27 +242,24 @@ HttpChannelParent::DoAsyncOpen(  const U
 
   uint32_t loadFlags = aLoadFlags;
   if (appOffline) {
     loadFlags |= nsICachingChannel::LOAD_ONLY_FROM_CACHE;
     loadFlags |= nsIRequest::LOAD_FROM_CACHE;
     loadFlags |= nsICachingChannel::LOAD_NO_NETWORK_IO;
   }
 
+  nsCOMPtr<nsILoadInfo> loadInfo =
+    new mozilla::LoadInfo(requestingPrincipal, triggeringPrincipal,
+                          aSecurityFlags, aContentPolicyType,
+                          aInnerWindowID);
+
   nsCOMPtr<nsIChannel> channel;
-  rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(channel),
-                                            uri,
-                                            requestingPrincipal,
-                                            triggeringPrincipal,
-                                            aSecurityFlags,
-                                            aContentPolicyType,
-                                            nullptr,   // loadGroup
-                                            nullptr,   // aCallbacks
-                                            loadFlags,
-                                            ios);
+  rv = NS_NewChannelInternal(getter_AddRefs(channel), uri, loadInfo,
+                             nullptr, nullptr, loadFlags, ios);
 
   if (NS_FAILED(rv))
     return SendFailedAsyncOpen(rv);
 
   mChannel = static_cast<nsHttpChannel *>(channel.get());
   mChannel->SetTimingEnabled(true);
   if (mPBOverride != kPBOverride_Unset) {
     mChannel->SetPrivate(mPBOverride == kPBOverride_Private ? true : false);
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -109,17 +109,18 @@ protected:
                    const nsCString&           entityID,
                    const bool&                chooseApplicationCache,
                    const nsCString&           appCacheClientID,
                    const bool&                allowSpdy,
                    const OptionalFileDescriptorSet& aFds,
                    const ipc::PrincipalInfo&  aRequestingPrincipalInfo,
                    const ipc::PrincipalInfo&  aTriggeringPrincipalInfo,
                    const uint32_t&            aSecurityFlags,
-                   const uint32_t&            aContentPolicyType);
+                   const uint32_t&            aContentPolicyType,
+                   const uint32_t&            aInnerWindowID);
 
   virtual bool RecvSetPriority(const uint16_t& priority) MOZ_OVERRIDE;
   virtual bool RecvSetClassOfService(const uint32_t& cos) MOZ_OVERRIDE;
   virtual bool RecvSetCacheTokenCachedCharset(const nsCString& charset) MOZ_OVERRIDE;
   virtual bool RecvSuspend() MOZ_OVERRIDE;
   virtual bool RecvResume() MOZ_OVERRIDE;
   virtual bool RecvCancel(const nsresult& status) MOZ_OVERRIDE;
   virtual bool RecvRedirect2Verify(const nsresult& result,