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 290703 073bbd96f75766ec2843bb905da2f7d1f0eaa0d2
parent 290702 4840ae780ac1b30464fd93be2c1170939a512887
child 290704 a66bf0a800f3d859b4bd2ceebc57b2e3fa6544d8
child 290719 ae25970e4fc50be6e55daae6b28f8330b35a35e6
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfelipe
bugs1184739
milestone48.0a1
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;