bug 1184739 - Blob URLs as favicons don't work r=felipe
authorBrad Lassey <blassey@mozilla.com>
Fri, 25 Mar 2016 10:06:38 -0400
changeset 290644 073bbd96f75766ec2843bb905da2f7d1f0eaa0d2
parent 290643 4840ae780ac1b30464fd93be2c1170939a512887
child 290645 a66bf0a800f3d859b4bd2ceebc57b2e3fa6544d8
child 290660 ae25970e4fc50be6e55daae6b28f8330b35a35e6
push id30123
push userkwierso@gmail.com
push dateMon, 28 Mar 2016 20:04:22 +0000
treeherderautoland@a66bf0a800f3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfelipe
bugs1184739
milestone48.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 1184739 - Blob URLs as favicons don't work r=felipe
browser/modules/ContentLinkHandler.jsm
--- a/browser/modules/ContentLinkHandler.jsm
+++ b/browser/modules/ContentLinkHandler.jsm
@@ -102,19 +102,44 @@ this.ContentLinkHandler = {
                 }
               }
             }
           } else {
             sizesType = SIZES_TELEMETRY_ENUM.NO_SIZES;
           }
           sizeHistogramTypes.add(sizesType);
 
-          chromeGlobal.sendAsyncMessage(
-            "Link:SetIcon",
-            {url: uri.spec, loadingPrincipal: link.ownerDocument.nodePrincipal});
+	  if (uri.scheme == 'blob') {
+            // Blob URLs don't work cross process, work around this by sending as a data uri
+            let channel = Cc["@mozilla.org/network/io-service;1"].
+                getService(Ci.nsIIOService).newChannelFromURI2(uri, null, Services.scriptSecurityManager.getSystemPrincipal(), null, Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, Ci.nsIContentPolicy.TYPE_OTHER);
+            let listener = {
+              encoded: "",
+              bis: null,
+              onStartRequest: function(aRequest, aContext) {
+                this.bis = Components.classes["@mozilla.org/binaryinputstream;1"]
+                    .createInstance(Components.interfaces.nsIBinaryInputStream);
+              },
+              onStopRequest: function(aRequest, aContext, aStatusCode) {
+                let spec = "data:" + channel.contentType + ";base64," + this.encoded;
+                chromeGlobal.sendAsyncMessage(
+                  "Link:SetIcon",
+                  {url: spec, loadingPrincipal: link.ownerDocument.nodePrincipal});
+              },
+              onDataAvailable: function(request, context, inputStream, offset, count) {
+                this.bis.setInputStream(inputStream);
+                this.encoded += btoa(this.bis.readBytes(this.bis.available()));
+              }
+            }
+            channel.asyncOpen(listener, null);
+          } else {
+            chromeGlobal.sendAsyncMessage(
+              "Link:SetIcon",
+              {url: uri.spec, loadingPrincipal: link.ownerDocument.nodePrincipal});
+          }
           iconAdded = true;
           break;
         case "search":
           if (!searchAdded && event.type == "DOMLinkAdded") {
             var type = link.type && link.type.toLowerCase();
             type = type.replace(/^\s+|\s*(?:;.*)?$/g, "");
 
             let re = /^(?:https?|ftp):/i;