window.URL.createObjectURL(blob) fails in PWA
Categories
(GeckoView :: General, defect, P1)
Tracking
(firefox78 fixed)
Tracking | Status | |
---|---|---|
firefox78 | --- | fixed |
People
(Reporter: colormatch, Assigned: owlish, Mentored)
References
Details
(Whiteboard: [fenix:p1][geckoview:m78])
Attachments
(2 files)
Comment 1•6 years ago
|
||
Reporter | ||
Comment 2•6 years ago
|
||
Comment 3•6 years ago
|
||
Updated•6 years ago
|
Updated•6 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Assignee | ||
Updated•5 years ago
|
Assignee | ||
Comment 4•5 years ago
|
||
TLDR: I am not sure if I can reproduce the bug.
Long version:
Note on installation: In Nightly, there's an "Install" option. I press it, it asks to confirm if I want to add the app to my Home screen. I press "Add", and the app icon appears on my Home screen. When I tap that icon, the app opens full screen, with no Fenix UI to be seen. In debugger, that "app" is seen as a Nightly's "tab", and I see the URL for that has ?pwa=1
parameter. It looks to me like I do have the app installed as PWA. All of this is happening on Samsung Galaxy S8 device with Android 9 and Firefox Preview Nightly 200501 build 21220607.
I am not sure how to install as PWA on regular FF Preview (it has "Add to Home Screen" option in the menu, which seemingly does the same thing as "Install" in Nightly, but when I tap on the resulting icon, I see Fenix's UI, so it seems like it adds the URL to the homescreen rather than installs as PWA) - I have 4.3.0 build 21082025
So in Nightly, when I follow STR, after the step 5 I am presented with an image download prompt. When I press "Download" button, I see Firefox Nightly can't download this file type
message.
In logcat, when pressing "Download" button, this error appears:
2020-05-01 14:36:36.823 655-12581/? E/msm8974_platform: platform_check_backends_match: Invalid snd_device =
In console, I see this:
15:00:03.564 GET https://kinoseed.com/manifest.webmanifest[HTTP/1.1 200 OK 0ms]
15:01:17.958 XHRPOST https://kinoseed.com/getlut.php[HTTP/1.1 200 OK 0ms]
15:01:23.787 Navigated to blob:https://kinoseed.com/632c640d-3c85-4bff-a2fe-863284041ead
15:02:02.338 XHRPOST https://kinoseed.com/getlut.php [HTTP/1.1 200 OK 0ms]
15:02:05.954 XHRPOST https://kinoseed.com/getlut.php
The download prompt appears after Navigated to
line.
So it looks like the downloaded is being initiated.... Why it's not working for me is another question - there might be something misconfigured on my device.
snorp, what would be the plan now?
I don't think the PWA bit is important in this case, it's just that the PWA in question relies on the blob download functionality. You should be able to reproduce this in the browser without a PWA. This one seems to show the problem for me: http://5509.github.io/demos/blob/
In desktop, this downloads some JSON. In Fenix, the download (predictably) fails.
The reason this fails is because we only deliver the URL + some metadata to Fenix (WebResponseInfo), and then it fetches the download itself using GeckoWebExecutor
. GeckoWebExecutor
only supports HTTP. I think we have at least two options here:
-
Add something like
objectData
toWebResponseInfo
in the case of object URLs (which can come from aBlob
,File
, or other things). This would contain the bytes referred by the URL. -
Deliver an actual WebResponse in onExternalResponse() instead of
WebResponseInfo
.
The second is likely higher difficulty, but it is actually what we wanted to do in the first place. WebResponse
didn't exist when that API was added, and when I tried to change it later on we had problems with e10s. Now that we're using DocumentChannel this may be easier. The first option is almost certainly doable with a reasonable amount of effort, so we can always fall back to that.
Assignee | ||
Comment 6•5 years ago
|
||
The second is likely higher difficulty, but it is actually what we wanted to do in the first place.
I'll take this route then
Assignee | ||
Comment 8•5 years ago
•
|
||
As per our convo with Snorp, we divide the option 2 from comment 5 into two steps:
- Preliminary work: make WebExecutor process object urls
- Actually make
onExternalResponse
accept WebResponse instead of WebResponseInfo
Comment 9•5 years ago
|
||
(In reply to [:owlish] 🦉 PST from comment #8)
- Actually make
onExternalResponse
accept WebResponse instead of WebResponseInfo
Do we have any plans to support both for a limited time so that we have some time migrating over in AC?
Assignee | ||
Comment 10•5 years ago
|
||
We will try to make this change as painless as possible for sure! More specific plan will be formed once we have set on one of the options above
Assignee | ||
Comment 11•5 years ago
•
|
||
(In reply to Sebastian Kaspari (:sebastian; :pocmo) from comment #9)
(In reply to [:owlish] 🦉 PST from comment #8)
- Actually make
onExternalResponse
accept WebResponse instead of WebResponseInfoDo we have any plans to support both for a limited time so that we have some time migrating over in AC?
The support for object URIs in WebExtecutor is landed. We will not be proceeding with the API change at this point.
To bring the blob download functionality to Fenix (and other apps) you'd need to allow blob
schema in the DownloadManager
, FetchDownloadManager
etc. classes when GV78 goes live.
Assignee | ||
Updated•5 years ago
|
Comment 12•5 years ago
|
||
Thanks :owlish!
Comment 13•5 years ago
|
||
Great job :owlish, there are some sites that are working now, but there are some that still failing. From our site we see thatGeckoViewFetchClient.fetch
returns with a statusCode
of 0
These are some site that are still failing
It's not a HTTP request, so the statusCode
doesn't make sense for blob:
requests. For those, simply checking the content length should be enough.
Assignee | ||
Comment 15•5 years ago
|
||
Thank you for testing, Arturo! Looking into this
Assignee | ||
Comment 16•5 years ago
|
||
double-checked - we don't set statusCode for blobs. And Snorp is right.
Comment 17•5 years ago
|
||
Ok, let me do some testing!
Comment 18•5 years ago
|
||
After following the :snorp's recommendation in comment 14, we are ignoring the status code for blob urls two of the sites mentioned in comment 13 worked as a result of that, but there are still issues with Firefox send. We call GeckoViewFetchClient.fetch
but we don't get any result back, then after the timeout expires, we get a TimeoutException
the same happens with a similar website https://send.tresorit.com/
Comment 19•5 years ago
•
|
||
Additionally, when we navigate to a blob url from an extension it is not triggering a call on GeckoSession.ContentDelegate.onExternalReponse
causing us to not start the download STR
Assignee | ||
Comment 20•5 years ago
|
||
(In reply to Arturo Mejia from comment #19)
Additionally, when we navigate to a blob url from an extension it is not triggering a call on
GeckoSession.ContentDelegate.onExternalReponse
causing us to not start the download STR
I'll take a look at Privacy Badger, but if they use browser.downloads.download
- that at the moment is not triggering anything indeed. (I am working on that btw, it's a separate bug from this)
Assignee | ||
Comment 21•5 years ago
|
||
(In reply to Arturo Mejia from comment #18)
After following the :snorp's recommendation in comment 14, we are ignoring the status code for blob urls two of the sites mentioned in comment 13 worked as a result of that, but there are still issues with Firefox send. We call
GeckoViewFetchClient.fetch
but we don't get any result back, then after the timeout expires, we get aTimeoutException
the same happens with a similar website https://send.tresorit.com/
I'll poke around. Thanks for testing!
Assignee | ||
Comment 22•5 years ago
•
|
||
Ok, so I dug into this a bit yesterday.
So the reason for the timeout is that the WebExecutor's C++ helper is convinced the URI it gets from Send is not a blob URI (specifically, opening the channel to start the download produces NS_ERROR_MALFORMED_URI, which currently isn't caught anywhere, hence the silent timeout; also, dom::IsBlobURI(uri)
returns false for these URIs). The schema is most definitely "blob" - I am logging the URI before calling onExternalResponse
. At the same time, trying to create an http channel of the channel produced with the uri fails either.
I then tried downloading something from Send in Focus - just for funzies, and wasn't disappointed: Focus is perfectly able to download. GV in Focus was last updated on May 7th to GV76, so the bug 1635862 fix isn't even remotely there... Then I decided to see if ye olde C++ code works in reference browser - maybe the bug 1635862 fix broke something? - it doesn't. The code predictably fails at the point of creating an http channel. So it seems like the URI that the WebExecutor's C++ helper gets in Focus is somehow different from the URI it gets in reference browser.
Arturo, I wonder if you could investigate how the flow is different in reference browser vs Focus in the case of FF Send downloads?
Meanwhile, I'm going to see if the folks from Send team can shade shed any light on this. It seems to me there's something peculiar about how FF Send generates these links and what they really are. It doesn't look like they are straightforward blob URIs.
Assignee | ||
Comment 23•5 years ago
|
||
dcoates helped me navigate Send codebase: so Send uses two ways of downloading: either blob or stream. Apparently, Focus and reference browser might be using different ways of downloads.
Also, Send uses service worker to decrypt a stream. As Snorp mentioned in Matrix, Focus uses private mode where service workers don't work, so probably that might be the reason why the results are different? I'll wait to see what Arturo's investigation yields
Comment 24•5 years ago
|
||
The differences it's that Focus doesn't use the GeckoWebExecutor
for downloads it uses the android download manager. An alternative for deeper debugging the issue is to use about:debugging
to connect your devices browser and add breaking points in the FF Send code and in the GV code.
Assignee | ||
Comment 25•5 years ago
•
|
||
(In reply to Arturo Mejia from comment #24)
The differences it's that Focus doesn't use the
GeckoWebExecutor
for downloads it uses the android download manager.
Oh I see. I'll continue investigation on WebExecutor side then
An alternative for deeper debugging the issue is to use
about:debugging
to connect your devices browser and add breaking points in the FF Send code and in the GV code.
yep, that's what I have been using
Assignee | ||
Comment 26•5 years ago
•
|
||
I found the reason for WebExecutor’s misbehavior - it happens when the web app/website revokes the URI right after a [simulated] click on it. This technique is used in three apps we saw - Firefox Send, Privacy Badger and Tresorit (this is one is not open source, but I strongly suspect has the same issue), all of which are security-related apps. I was able to reproduce this in a unit test, which fails in exactly same way as reference browser.
As a result, by the time the URI gets into WebExecutor it becomes recently revoked. It seems to me like it still might be possible to get the data somehow, and I tried a few approaches none of which worked.
Continuing my search for solution.
Assignee | ||
Comment 27•5 years ago
•
|
||
(On desktop, Send works because the flow goes through downloadStream
and not downloadBlob
.)
Assignee | ||
Comment 28•5 years ago
|
||
Assignee | ||
Comment 29•4 years ago
|
||
Depends on D75659
Assignee | ||
Updated•4 years ago
|
Updated•4 years ago
|
Comment 30•4 years ago
|
||
Comment 31•4 years ago
|
||
bugherder |
Reporter | ||
Comment 32•4 years ago
|
||
Awesome! It works.
Thanks.
Comment 33•4 years ago
|
||
Comment 34•4 years ago
|
||
bugherder |
Description
•