Closed Bug 1432949 Opened 7 years ago Closed 4 years ago

window.URL.createObjectURL(blob) fails in PWA

Categories

(GeckoView :: General, defect, P1)

62 Branch
defect

Tracking

(firefox78 fixed)

RESOLVED FIXED
mozilla78
Tracking Status
firefox78 --- fixed

People

(Reporter: colormatch, Assigned: owlish, Mentored)

References

Details

(Whiteboard: [fenix:p1][geckoview:m78])

Attachments

(2 files)

User Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0 Build ID: 20180103231032 Steps to reproduce: 1) load the page https://kinoseed.com/ 2) +Add to homescreen (install as PWA) 3) start the PWA of kinoseed from the homescreen icon 4) load a target image 5) press "save" Actual results: a new tab is opened with url: blob:https://kinoseed.com/ae928fd0-0daa-.... which has only a blank screen - there is no blob, no download Expected results: var blob = new Blob(data, {type: "image/jpeg"}); a.href = window.URL.createObjectURL(blob); A file should have been created as a blob and passed it's URL for download. NOTE: this only fails when started as PWA (when it's ran through the browser it works fine)
Closing per https://bugzilla.mozilla.org/show_bug.cgi?id=1473195 Contact :susheel if you think this bug should be re-opened
Status: UNCONFIRMED → RESOLVED
Closed: 6 years ago
Resolution: --- → INACTIVE
@susheel
Status: RESOLVED → UNCONFIRMED
Component: Web Apps → GeckoView
Resolution: INACTIVE → ---
Version: Firefox 58 → Firefox 62
We confirmed this in triage today. Thanks for filing.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Priority: -- → P2
Product: Firefox for Android → GeckoView
Version: Firefox 62 → 62 Branch
See Also: → 1501735
Rank: 40
Whiteboard: [fenix:p1][geckoview:m78]
Priority: P2 → P1
Mentor: snorp
Assignee: nobody → bugzeeeeee

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?

Flags: needinfo?(snorp)

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:

  1. Add something like objectData to WebResponseInfo in the case of object URLs (which can come from a Blob, File, or other things). This would contain the bytes referred by the URL.

  2. 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.

Flags: needinfo?(snorp)

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

As per our convo with Snorp, we divide the option 2 from comment 5 into two steps:

  1. Preliminary work: make WebExecutor process object urls
  2. Actually make onExternalResponse accept WebResponse instead of WebResponseInfo
Depends on: 1635862

(In reply to [:owlish] 🦉 PST from comment #8)

  1. 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?

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

(In reply to Sebastian Kaspari (:sebastian; :pocmo) from comment #9)

(In reply to [:owlish] 🦉 PST from comment #8)

  1. 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?

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.

Status: NEW → RESOLVED
Closed: 6 years ago5 years ago
Resolution: --- → FIXED

Thanks :owlish!

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

Status: RESOLVED → REOPENED
Resolution: FIXED → ---

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.

Thank you for testing, Arturo! Looking into this

double-checked - we don't set statusCode for blobs. And Snorp is right.

Ok, let me do some testing!

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/

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

(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)

(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 a TimeoutException the same happens with a similar website https://send.tresorit.com/

I'll poke around. Thanks for testing!

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.

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

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.

(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

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.

(On desktop, Send works because the flow goes through downloadStream and not downloadBlob.)

Depends on: 1530022
No longer depends on: 1530022
See Also: → 1530022
Attachment #9149575 - Attachment description: Bug 1432949 - Allow system principal create a channel for revoked blob URL → Bug 1432949 - Allow system principal initialize a channel for revoked blob URLs
Pushed by istorozhko@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/8b425b5dfb9f Allow system principal initialize a channel for revoked blob URLs r=geckoview-reviewers,snorp,baku,ckerschb
Status: REOPENED → RESOLVED
Closed: 5 years ago4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla78

Awesome! It works.
Thanks.

Pushed by istorozhko@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/3221db51a16c Return error if channel cannot be opened. Expand download blob test case r=geckoview-reviewers,snorp
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: