Bug 1247843 - Part 3: Set request context ID to the http channel created in imgLoader::LoadImage. r=baku
authorKershaw Chang <kechang@mozilla.com>
Wed, 20 Sep 2017 20:09:00 -0400
changeset 382187 1615dd915bb8be7f86fd74e2aa7b5a6f8898d2b7
parent 382186 9237c64b078dc6c785a70cfd6be601be01529690
child 382188 d177f35862abcc7e76354c4cb56858083d7c1f0b
push id95276
push userryanvm@gmail.com
push dateThu, 21 Sep 2017 14:20:09 +0000
treeherdermozilla-inbound@d177f35862ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1247843
milestone57.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 1247843 - Part 3: Set request context ID to the http channel created in imgLoader::LoadImage. r=baku In order to let necko postpone the load of favicon, we have to set request context ID to the http channel that is created to load favicon. This patch starts with passing a request context ID to nsContentUtils::LoadImage and makes other necessary changes to set the request context ID to the channel.
docshell/base/nsContextMenuInfo.cpp
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/base/nsDocument.cpp
dom/base/nsImageLoadingContent.cpp
dom/xbl/nsXBLResourceLoader.cpp
image/imgLoader.cpp
image/imgLoader.h
layout/generic/nsImageFrame.cpp
layout/style/ImageLoader.cpp
layout/xul/nsImageBoxFrame.cpp
layout/xul/tree/nsTreeBodyFrame.cpp
widget/cocoa/nsMenuItemIconX.mm
--- a/docshell/base/nsContextMenuInfo.cpp
+++ b/docshell/base/nsContextMenuInfo.cpp
@@ -294,17 +294,17 @@ nsContextMenuInfo::GetBackgroundImageReq
           nsCOMPtr<nsIURI> bgUri;
           NS_NewURI(getter_AddRefs(bgUri), bgStringValue);
           NS_ENSURE_TRUE(bgUri, NS_ERROR_FAILURE);
 
           imgLoader* il = imgLoader::NormalLoader();
           NS_ENSURE_TRUE(il, NS_ERROR_FAILURE);
 
           return il->LoadImage(bgUri, nullptr, nullptr,
-                               doc->GetReferrerPolicy(), principal, nullptr,
+                               doc->GetReferrerPolicy(), principal, 0, nullptr,
                                nullptr, nullptr, nullptr, nsIRequest::LOAD_NORMAL,
                                nullptr, nsIContentPolicy::TYPE_INTERNAL_IMAGE,
                                EmptyString(),
                                /* aUseUrgentStartForChannel */ false, aRequest);
         }
       }
 
       // bail if we encounter non-transparent background-color
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -3709,17 +3709,19 @@ nsContentUtils::IsImageInCache(nsIURI* a
     nsresult rv = cache->FindEntryProperties(aURI, domDoc, getter_AddRefs(props));
     return (NS_SUCCEEDED(rv) && props);
 }
 
 // static
 nsresult
 nsContentUtils::LoadImage(nsIURI* aURI, nsINode* aContext,
                           nsIDocument* aLoadingDocument,
-                          nsIPrincipal* aLoadingPrincipal, nsIURI* aReferrer,
+                          nsIPrincipal* aLoadingPrincipal,
+                          uint64_t aRequestContextID,
+                          nsIURI* aReferrer,
                           net::ReferrerPolicy aReferrerPolicy,
                           imgINotificationObserver* aObserver, int32_t aLoadFlags,
                           const nsAString& initiatorType,
                           imgRequestProxy** aRequest,
                           uint32_t aContentPolicyType,
                           bool aUseUrgentStartForChannel)
 {
   NS_PRECONDITION(aURI, "Must have a URI");
@@ -3746,16 +3748,17 @@ nsContentUtils::LoadImage(nsIURI* aURI, 
 
   // XXXbz using "documentURI" for the initialDocumentURI is not quite
   // right, but the best we can do here...
   return imgLoader->LoadImage(aURI,                 /* uri to load */
                               documentURI,          /* initialDocumentURI */
                               aReferrer,            /* referrer */
                               aReferrerPolicy,      /* referrer policy */
                               aLoadingPrincipal,    /* loading principal */
+                              aRequestContextID,    /* request context ID */
                               loadGroup,            /* loadgroup */
                               aObserver,            /* imgINotificationObserver */
                               aContext,             /* loading context */
                               aLoadingDocument,     /* uniquification key */
                               aLoadFlags,           /* load flags */
                               nullptr,              /* cache key */
                               aContentPolicyType,   /* content policy type */
                               initiatorType,        /* the load initiator */
@@ -10416,18 +10419,21 @@ nsContentUtils::AppendNativeAnonymousChi
     AppendDocumentLevelNativeAnonymousContentTo(aContent->OwnerDoc(), aKids);
   }
 }
 
 
 /* static */ void
 nsContentUtils::GetContentPolicyTypeForUIImageLoading(nsIContent* aLoadingNode,
                                                       nsIPrincipal** aLoadingPrincipal,
-                                                      nsContentPolicyType& aContentPolicyType)
-{
+                                                      nsContentPolicyType& aContentPolicyType,
+                                                      uint64_t* aRequestContextID)
+{
+  MOZ_ASSERT(aRequestContextID);
+
   // Use the serialized loadingPrincipal from the image element. Fall back
   // to mContent's principal (SystemPrincipal) if not available.
   aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE;
   nsCOMPtr<nsIPrincipal> loadingPrincipal = aLoadingNode->NodePrincipal();
   nsAutoString imageLoadingPrincipal;
   aLoadingNode->GetAttr(kNameSpaceID_None, nsGkAtoms::loadingprincipal,
                         imageLoadingPrincipal);
   if (!imageLoadingPrincipal.IsEmpty()) {
@@ -10435,16 +10441,25 @@ nsContentUtils::GetContentPolicyTypeForU
     NS_DeserializeObject(NS_ConvertUTF16toUTF8(imageLoadingPrincipal),
                          getter_AddRefs(serializedPrincipal));
     loadingPrincipal = do_QueryInterface(serializedPrincipal);
 
     if (loadingPrincipal) {
       // Set the content policy type to TYPE_INTERNAL_IMAGE_FAVICON for
       // indicating it's a favicon loading.
       aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON;
+
+      nsAutoString requestContextID;
+      aLoadingNode->GetAttr(kNameSpaceID_None, nsGkAtoms::requestcontextid,
+                            requestContextID);
+      nsresult rv;
+      int64_t val  = requestContextID.ToInteger64(&rv);
+      *aRequestContextID = NS_SUCCEEDED(rv)
+        ? val
+        : 0;
     } else {
       // Fallback if the deserialization is failed.
       loadingPrincipal = aLoadingNode->NodePrincipal();
     }
   }
   loadingPrincipal.forget(aLoadingPrincipal);
 }
 
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -795,16 +795,17 @@ public:
    * @param aUseUrgentStartForChannel,(Optional) a flag to mark on channel if it
    *        is triggered by user input events.
    * @return the imgIRequest for the image load
    */
   static nsresult LoadImage(nsIURI* aURI,
                             nsINode* aContext,
                             nsIDocument* aLoadingDocument,
                             nsIPrincipal* aLoadingPrincipal,
+                            uint64_t aRequestContextID,
                             nsIURI* aReferrer,
                             mozilla::net::ReferrerPolicy aReferrerPolicy,
                             imgINotificationObserver* aObserver,
                             int32_t aLoadFlags,
                             const nsAString& initiatorType,
                             imgRequestProxy** aRequest,
                             uint32_t aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE,
                             bool aUseUrgentStartForChannel = false);
@@ -3033,17 +3034,18 @@ public:
   /**
    * Returns the content policy type that should be used for loading images
    * for displaying in the UI.  The sources of such images can be <xul:image>,
    * <xul:menuitem> on OSX where we load the image through nsMenuItemIconX, etc.
    */
   static void
   GetContentPolicyTypeForUIImageLoading(nsIContent* aLoadingNode,
                                         nsIPrincipal** aLoadingPrincipal,
-                                        nsContentPolicyType& aContentPolicyType);
+                                        nsContentPolicyType& aContentPolicyType,
+                                        uint64_t* aRequestContextID);
 
   static nsresult
   CreateJSValueFromSequenceOfObject(JSContext* aCx,
                                     const mozilla::dom::Sequence<JSObject*>& aTransfer,
                                     JS::MutableHandle<JS::Value> aValue);
 
   static bool
   IsWebComponentsEnabled() { return sIsWebComponentsEnabled; }
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -9882,16 +9882,17 @@ nsDocument::MaybePreLoadImage(nsIURI* ur
 
   // Image not in cache - trigger preload
   RefPtr<imgRequestProxy> request;
   nsresult rv =
     nsContentUtils::LoadImage(uri,
                               static_cast<nsINode*>(this),
                               this,
                               NodePrincipal(),
+                              0,
                               mDocumentURI, // uri of document used as referrer
                               aReferrerPolicy,
                               nullptr,       // no observer
                               loadFlags,
                               NS_LITERAL_STRING("img"),
                               getter_AddRefs(request),
                               policyType);
 
--- a/dom/base/nsImageLoadingContent.cpp
+++ b/dom/base/nsImageLoadingContent.cpp
@@ -1041,16 +1041,17 @@ nsImageLoadingContent::LoadImage(nsIURI*
   nsCOMPtr<nsIContent> content =
       do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
   nsCOMPtr<nsINode> thisNode =
     do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
   nsresult rv = nsContentUtils::LoadImage(aNewURI,
                                           thisNode,
                                           aDocument,
                                           aDocument->NodePrincipal(),
+                                          0,
                                           aDocument->GetDocumentURI(),
                                           referrerPolicy,
                                           this, loadFlags,
                                           content->LocalName(),
                                           getter_AddRefs(req),
                                           policyType,
                                           mUseUrgentStartForChannel);
 
--- a/dom/xbl/nsXBLResourceLoader.cpp
+++ b/dom/xbl/nsXBLResourceLoader.cpp
@@ -116,17 +116,17 @@ nsXBLResourceLoader::LoadResources(nsICo
                             doc->GetDocumentCharacterSet(), docURL)))
       continue;
 
     if (curr->mType == nsGkAtoms::image) {
       // Now kick off the image load...
       // Passing nullptr for pretty much everything -- cause we don't care!
       // XXX: initialDocumentURI is nullptr!
       RefPtr<imgRequestProxy> req;
-      nsContentUtils::LoadImage(url, doc, doc, docPrincipal, docURL,
+      nsContentUtils::LoadImage(url, doc, doc, docPrincipal, 0, docURL,
                                 doc->GetReferrerPolicy(), nullptr,
                                 nsIRequest::LOAD_BACKGROUND, EmptyString(),
                                 getter_AddRefs(req));
     }
     else if (curr->mType == nsGkAtoms::stylesheet) {
       // Kick off the load of the stylesheet.
 
       // Always load chrome synchronously
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -2121,16 +2121,17 @@ imgLoader::LoadImageXPCOM(nsIURI* aURI,
     ReferrerPolicy refpol = ReferrerPolicyFromString(aReferrerPolicy);
     nsCOMPtr<nsINode> node = do_QueryInterface(aCX);
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(aCX);
     nsresult rv = LoadImage(aURI,
                             aInitialDocumentURI,
                             aReferrerURI,
                             refpol,
                             aLoadingPrincipal,
+                            0,
                             aLoadGroup,
                             aObserver,
                             node,
                             doc,
                             aLoadFlags,
                             aCacheKey,
                             aContentPolicyType,
                             EmptyString(),
@@ -2141,16 +2142,17 @@ imgLoader::LoadImageXPCOM(nsIURI* aURI,
 }
 
 nsresult
 imgLoader::LoadImage(nsIURI* aURI,
                      nsIURI* aInitialDocumentURI,
                      nsIURI* aReferrerURI,
                      ReferrerPolicy aReferrerPolicy,
                      nsIPrincipal* aLoadingPrincipal,
+                     uint64_t aRequestContextID,
                      nsILoadGroup* aLoadGroup,
                      imgINotificationObserver* aObserver,
                      nsINode *aContext,
                      nsIDocument* aLoadingDocument,
                      nsLoadFlags aLoadFlags,
                      nsISupports* aCacheKey,
                      nsContentPolicyType aContentPolicyType,
                      const nsAString& initiatorType,
@@ -2295,18 +2297,30 @@ imgLoader::LoadImage(nsIURI* aURI,
                        getter_AddRefs(request),
                        getter_AddRefs(entry));
 
     MOZ_LOG(gImgLog, LogLevel::Debug,
            ("[this=%p] imgLoader::LoadImage -- Created new imgRequest"
             " [request=%p]\n", this, request.get()));
 
     nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(newChannel));
-    if (cos && aUseUrgentStartForChannel) {
-      cos->AddClassFlags(nsIClassOfService::UrgentStart);
+    if (cos) {
+      if (aUseUrgentStartForChannel) {
+        cos->AddClassFlags(nsIClassOfService::UrgentStart);
+      }
+
+      if (nsContentUtils::IsTailingEnabled() &&
+          aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON) {
+        cos->AddClassFlags(nsIClassOfService::Throttleable |
+                           nsIClassOfService::Tail);
+        nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(newChannel));
+        if (httpChannel) {
+          Unused << httpChannel->SetRequestContextID(aRequestContextID);
+        }
+      }
     }
 
     nsCOMPtr<nsILoadGroup> channelLoadGroup;
     newChannel->GetLoadGroup(getter_AddRefs(channelLoadGroup));
     rv = request->Init(aURI, aURI, /* aHadInsecureRedirect = */ false,
                        channelLoadGroup, newChannel, entry, aLoadingDocument,
                        aLoadingPrincipal, corsmode, aReferrerPolicy);
     if (NS_FAILED(rv)) {
--- a/image/imgLoader.h
+++ b/image/imgLoader.h
@@ -286,16 +286,17 @@ public:
   imgLoader();
   nsresult Init();
 
   MOZ_MUST_USE nsresult LoadImage(nsIURI* aURI,
                                   nsIURI* aInitialDocumentURI,
                                   nsIURI* aReferrerURI,
                                   ReferrerPolicy aReferrerPolicy,
                                   nsIPrincipal* aLoadingPrincipal,
+                                  uint64_t aRequestContextID,
                                   nsILoadGroup* aLoadGroup,
                                   imgINotificationObserver* aObserver,
                                   nsINode* aContext,
                                   nsIDocument* aLoadingDocument,
                                   nsLoadFlags aLoadFlags,
                                   nsISupports* aCacheKey,
                                   nsContentPolicyType aContentPolicyType,
                                   const nsAString& initiatorType,
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -2266,16 +2266,17 @@ nsImageFrame::LoadIcon(const nsAString& 
 
   return il->LoadImage(realURI,     /* icon URI */
                        nullptr,      /* initial document URI; this is only
                                        relevant for cookies, so does not
                                        apply to icons. */
                        nullptr,      /* referrer (not relevant for icons) */
                        mozilla::net::RP_Unset,
                        nullptr,      /* principal (not relevant for icons) */
+                       0,
                        loadGroup,
                        gIconLoad,
                        nullptr,      /* No context */
                        nullptr,      /* Not associated with any particular document */
                        loadFlags,
                        nullptr,
                        contentPolicyType,
                        EmptyString(),
--- a/layout/style/ImageLoader.cpp
+++ b/layout/style/ImageLoader.cpp
@@ -263,17 +263,17 @@ ImageLoader::LoadImage(nsIURI* aURI, nsI
   aImage->mRequests.Put(nullptr, nullptr);
 
   if (!aURI) {
     return;
   }
 
   RefPtr<imgRequestProxy> request;
   nsresult rv = nsContentUtils::LoadImage(aURI, mDocument, mDocument,
-                                          aOriginPrincipal, aReferrer,
+                                          aOriginPrincipal, 0, aReferrer,
                                           mDocument->GetReferrerPolicy(),
                                           nullptr, nsIRequest::LOAD_NORMAL,
                                           NS_LITERAL_STRING("css"),
                                           getter_AddRefs(request));
 
   if (NS_FAILED(rv) || !request) {
     return;
   }
--- a/layout/xul/nsImageBoxFrame.cpp
+++ b/layout/xul/nsImageBoxFrame.cpp
@@ -236,28 +236,30 @@ nsImageBoxFrame::UpdateImage()
   nsAutoString src;
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src);
   mUseSrcAttr = !src.IsEmpty();
   if (mUseSrcAttr) {
     nsIDocument* doc = mContent->GetComposedDoc();
     if (doc) {
       nsContentPolicyType contentPolicyType;
       nsCOMPtr<nsIPrincipal> loadingPrincipal;
+      uint64_t requestContextID = 0;
       nsContentUtils::GetContentPolicyTypeForUIImageLoading(mContent,
                                                             getter_AddRefs(loadingPrincipal),
-                                                            contentPolicyType);
+                                                            contentPolicyType,
+                                                            &requestContextID);
 
       nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
       nsCOMPtr<nsIURI> uri;
       nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
                                                 src,
                                                 doc,
                                                 baseURI);
       if (uri) {
-        nsresult rv = nsContentUtils::LoadImage(uri, mContent, doc, loadingPrincipal,
+        nsresult rv = nsContentUtils::LoadImage(uri, mContent, doc, loadingPrincipal, requestContextID,
                                                 doc->GetDocumentURI(), doc->GetReferrerPolicy(),
                                                 mListener, mLoadFlags,
                                                 EmptyString(), getter_AddRefs(mImageRequest),
                                                 contentPolicyType);
 
         if (NS_SUCCEEDED(rv) && mImageRequest) {
           nsLayoutUtils::RegisterImageRequestIfAnimated(presContext,
                                                         mImageRequest,
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -2194,16 +2194,17 @@ nsTreeBodyFrame::GetImage(int32_t aRowIn
         return NS_ERROR_FAILURE;
 
       // XXXbz what's the origin principal for this stuff that comes from our
       // view?  I guess we should assume that it's the node's principal...
       nsresult rv = nsContentUtils::LoadImage(srcURI,
                                               mContent,
                                               doc,
                                               mContent->NodePrincipal(),
+                                              0,
                                               doc->GetDocumentURI(),
                                               doc->GetReferrerPolicy(),
                                               imgNotificationObserver,
                                               nsIRequest::LOAD_NORMAL,
                                               EmptyString(),
                                               getter_AddRefs(imageRequest));
       NS_ENSURE_SUCCESS(rv, rv);
     }
--- a/widget/cocoa/nsMenuItemIconX.mm
+++ b/widget/cocoa/nsMenuItemIconX.mm
@@ -206,19 +206,21 @@ nsMenuItemIconX::GetIconURI(nsIURI** aIc
     rv = primitiveValue->GetPrimitiveType(&primitiveType);
     if (NS_FAILED(rv)) return rv;
     if (primitiveType != nsIDOMCSSPrimitiveValue::CSS_URI)
       return NS_ERROR_FAILURE;
 
     rv = primitiveValue->GetStringValue(imageURIString);
     if (NS_FAILED(rv)) return rv;
   } else {
+    uint64_t dummy = 0;
     nsContentUtils::GetContentPolicyTypeForUIImageLoading(mContent,
                                                           getter_AddRefs(mLoadingPrincipal),
-                                                          mContentType);
+                                                          mContentType,
+                                                          &dummy);
   }
 
   // Empty the mImageRegionRect initially as the image region CSS could
   // have been changed and now have an error or have been removed since the
   // last GetIconURI call.
   mImageRegionRect.SetEmpty();
 
   // If this menu item shouldn't have an icon, the string will be empty,
@@ -311,17 +313,17 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconU
     if (!sPlaceholderIconImage) return NS_ERROR_FAILURE;
 
     if (mNativeMenuItem)
       [mNativeMenuItem setImage:sPlaceholderIconImage];
   }
 
   nsresult rv = loader->LoadImage(aIconURI, nullptr, nullptr,
                                   mozilla::net::RP_Unset,
-                                  mLoadingPrincipal, loadGroup, this,
+                                  mLoadingPrincipal, 0, loadGroup, this,
                                   mContent, document, nsIRequest::LOAD_NORMAL, nullptr,
                                   mContentType, EmptyString(),
                                   /* aUseUrgentStartForChannel */ false,
                                   getter_AddRefs(mIconRequest));
   if (NS_FAILED(rv)) return rv;
 
   return NS_OK;