OpenClinica / enketo-oc

OpenClinica's fork of the Enketo web forms monorepo
Apache License 2.0
0 stars 1 forks source link

File download fails in Chrome for files uploaded in a prior form session #150

Open pbowen-oc opened 4 years ago

pbowen-oc commented 4 years ago

This seems to be a new issue in Chrome only. It is affecting us on 1.86.3 and also on our Production version (1.85.1.oc-1)

after a file is uploaded onto a form, it can be downloaded with the download button in the same session without any problem. Once the form is closed and then reopened, clicking the download button fails to download the file. It is displayed at the bottom of the browser window as "Failed - Server Problem". The More Information link Chrome points to this address - https://support.google.com/chrome/answer/2898334

Annotation 2020-03-30 112755

Note that the first time I tried downloading an uploaded form today, Chrome first brought up a permissions prompt asking if I wanted to Allow downloading multiple files. Even though I said yes, this issue still occurred.

Especially since this is a security setting, having this popup to all users isn't a good solution even if it worked. We need to change the form functionality so that the browser does not think that multiple files are being downloaded.

Note a current workaround is to right click the download button and choose Save As. This stilll downloads the file as expected (unlike the left click action).

This has been reported by multiple users, so I don't think it is form-specific. Here is a sample form to see the issue. Note that the issue is only present after uploading a file and then re-opening the form. File upload form.xml.txt

MartijnR commented 4 years ago

Ah thanks. Sounds like a browser change. Will check it out.

On Mon, Mar 30, 2020 at 9:38 AM pbowen-oc notifications@github.com wrote:

Assigned OpenClinica/enketo-oc#150 https://github.com/OpenClinica/enketo-oc/issues/150 to @MartijnR https://github.com/MartijnR.

— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub https://github.com/OpenClinica/enketo-oc/issues/150, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEZFFRZDQN6IVP4QRGMC53RKC4IJANCNFSM4LWV5XMQ .

-- Pushing data since 2012.

Enketo https://enketo.org | LinkedIn http://www.linkedin.com/company/enketo-llc | GitHub https://github.com/enketo | Twitter https://twitter.com/enketo | Blog http://blog.enketo.org

-- --  Revolutionizing data collection since 2012.

Enketo https://enketo.org/    |    LinkedIn http://www.linkedin.com/company/enketo-llc    |    GitHub https://github.com/enketo    |    Twitter https://twitter.com/enketo    |    Blog http://blog.enketo.org/

MartijnR commented 4 years ago

within session: <a> with blob:abacadabra href when loading from record: <a> with /media/get/https/url

The issue might be that that particular file was already loaded as a preview (hence 'multiple').

No request is made (so no server involved). Seems like a bug in Chrome to me.

Possibly Chrome does make the request (though not shown in browser network tab, and has a problem with the different origin (though it's proxied via local URL).

Turns out the headers.referer is undefined. That's probably the change in Chrome, and sloppy coding caused a server exception. Easy fix.

pbowen-oc commented 4 years ago

@MartijnR - We can download one file from the from a form now, but when we download a second file we get a prompt that the site wants to download multiple files. If the form is then closed and reopened, it is reporting the multi-file download prompt (or hiding the warning in the Chrome toolbar) on the first download attempt.

Note that I think this is only occurring if you open a form that already has files as part of its record.

Annotation 2020-04-17 102758

Note that if you click to Allow from the multi-download prompt, it seems to whitelist the form server for future downloads without prompt.

MartijnR commented 4 years ago
curl --user enketorules: -d "server_url=https://api.ona.io/enketo&form_id=widgets&instance=<widgets><text_widgets><text>mart</text></text_widgets><media_widgets><image>img.png</image><file>test.pdf</file></media_widgets></widgets>&instance_id=someUUID&return_url=https://enketo.org&instance_attachments[test.pdf]=https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf&instance_attachments[img.png]=https://github.com/enketo/enketo-website/raw/master/src/media/images/fast.png" http://localhost:8005/api/v2/instance/view
MartijnR commented 4 years ago

@pbowen-oc, is this what you see?

Screen Shot 2020-04-20 at 1 35 09 PM
MartijnR commented 4 years ago

If so, I can only reproduce it by turning off the toggle on chrome://settings/content/automaticDownloads

Screen Shot 2020-04-20 at 1 39 15 PM

I think it is on by default.

pbowen-oc commented 4 years ago

@MartijnR - Yes, that is what we see.

The settings seem to be Do not Allow and Ask first, with ask being the default.

If you select Always Allow in the popup permissions window you showed first, it seems to white list the site (which is why you wouldn't see the permissions message next time).

This behavior where Chrome treats these single file downloads as multiple file downloads is new (whether due to Chrome or the recent updates in Enketo to deal with Chrome's changes).

MartijnR commented 4 years ago

I cannot figure out why it's considered 'multiple'. But if the default Chrome setting has no warning, then I wonder if this is really important spending more time on.

MartijnR commented 4 years ago

check if removing the download attribute makes any difference

Problem is that some users may click 'No' and then never can download files again (except by diving into Chrome settings)

MartijnR commented 4 years ago

I have not found a solution for this.

There does appear to be a small difference between what I'm experiencing and what you demoed @pbowen-oc. When the Chrome setting is toggled on, I don't get any message ever (without having added the site to the Allow list). It could be that the iframe (from a different subdomain?) has something to do with that.

MartijnR commented 4 years ago

parent: a.enketo.fake form: b.enketo.fake

from Code/enketo-iframe-demo do python -m SimpleHTTPServer 8000

http://a.enketo.fake:8000/ serves http://b.enketo.fake:8005/view/c89e9303f524188382c4252ff9461228?instance_id=someUUID&returnUrl=https%3A%2F%2Fenketo.org

MartijnR commented 4 years ago

Yes, I get the same behavior as you @pbowen-oc when parent page and iframe source have different subdomains.

Knowing how OC uses subdomains, I don't immediately see how we can use this knowledge to circumvent the issue, other than perhaps:

  1. not using iframes
  2. use some very advanced wizardry to serve Enketo forms hosted on the same Enketo server but from different subdomains (ie. same subdomains as use to serve parent page that contains iframe) + using Enketo with path prefix
  3. use a different Enketo server for each subdomain used and use Enketo with path prefix instead of separate subdomain

You could test how it would work by loading the iframe source directly in a browser tab. However, when loading a record you'd have to be very quick (otherwise, the cached record will no longer be available), or quickly use a snippet like this in the browser console immediately after the form loads:

location.href = document.querySelector('iframe').src

This assumes that the first iframe element on your page contains the Enketo form. If the second iframe element contains the Enketo form do this instead:

location.href = document.querySelectorAll('iframe')[1].src
pbowen-oc commented 4 years ago

@MartijnR - Thanks. I have confirmed that opening our form manually outside the iframe allowed me to download multiple files without issue.

MartijnR commented 4 years ago

I had actually forgotten to test with using the same subdomain for the parent page as well as the iframe source. That turns out to have the same problem. So it's not subdomain-related after all. It's iframe-related. I've updated the options above. Sorry, I should have done that yesterday.

MartijnR commented 4 years ago

Worth checking some iframe attributes: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe

svadla-oc commented 4 years ago

@MartijnR @pbowen-oc Looks like this issue may be related to downloading resources using the a element in a cross-origin situation. Please see https://html.spec.whatwg.org/multipage/links.html#downloading-resources From what I understand, I think we need to add "Content-Disposition" header with "attachment" as the value to resolve this issue.

pbowen-oc commented 4 years ago

@MartijnR - Can you try the update suggested by @svadla-oc so we can see if it resolves the issue?

MartijnR commented 4 years ago

I was able to reproduce it from the same domain, so according to the spec this shouldn't be necessary. But it's worth a shot.

MartijnR commented 4 years ago

Sadly, this header does not change the behavior.

pbowen-oc commented 4 years ago

If no other fix can be identified, we can consider adding hovertext instructing the user to right click and save as if the download button has not worked:

'Right click and select "Save link as..." to download'

pbowen-oc commented 3 years ago

@MartijnR - For now, please add this hovertext to the download button:

Right click and select "Save link as..." to download

MartijnR commented 3 years ago
MartijnR commented 3 years ago

I've made the easiest implementation using a built-in browser hover tooltip. We can tweak it. The advantage of using is that it positions nicely. The disadvantage is that it takes a second or so to show up.

pbowen-oc commented 3 years ago

The initial fix and tooltip update to direct users is working, but I want to leave this open until we have a long-term fix that allows multiple downloads just via left click.