Safari URL encoding behaves strange - safari

I have an Elixir/Phoenix crud app that serves some static files.
The file names are likely to contain (german) umlauts and I want to preserve them.
First I just responded with the file to the :show route of the upload but this had the unwanted effect that the filename at the downloading client would be the uploads id (e.g. 1 or 123).
To change that I switched to serving the files via a static plug. That worked well on Chrome and Firefox but today I noticed that it doesn't on Safari. On Safari I just get Page not found.
For me it seems like Safari doesn't encode the umlauts. Is this a bug in Safari? How do I work around that?
Here is a link to a page of the app that contains such a link: https://sozialoekonomie.klausurenarchiv.de/courses/21/instructors/25/uploads
On Safari the link of the file is: https://sozialoekonomie.klausurenarchiv.de/data/Makroökonomie/Pfannkuche/1474905178102463842/Makroökonomie%20Pfannekuche%20SoSe%2015%20mit%20Lösung%201,3.pdf
While on Chrome/Firefox the file uri is:
https://sozialoekonomie.klausurenarchiv.de/data/Makro%C3%B6konomie/Pfannkuche/1474905178102463842/Makroo%CC%88konomie%20Pfannekuche%20SoSe%2015%20mit%20Lo%CC%88sung%201,3.pdf

Related

How to force Firefox to download file (custom extension, non-text file) versus display it?

I fear this might be a bug with firefox, as this seems to work fine on any other browser I've used. If it is not a bug, what steps need to happen to force a download (versus a display in browser) of a file that can't be displayed in the browser.
Created a react site with a fastapi backend, through the api I am able to attain the url for a file to download.
A standard Anchor element is created for the download, when the user presses a button:
let a = document.createElement('a');
a.href = url;
a.dispatchEvent(new MouseEvent('click'))
but I get a matrix screen of characters rather than a download (only on firefox). I have another file on the same page that is text-based and through the same process get a "save file box" pop-up from firefox.
I've tried, surrounding the above code with
document.body.appendChild(a);
and
document.body.removeChild(a);
as I read that at one time firefox required that.
I've tried using the settings in firefox to force a download e.g. "Save File", but the extension is not listed and I changed all the extensions and the selection for "other files" to "ask whether to open or save files"
On the Anchor Element table of browser compatibility
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a
there is an * for firefox that says "see implementation notes", yet the only notes I see referring to firefox are
If the Content-Disposition header has different information from the download attribute, resulting behavior may differ:
If the header specifies a filename, it takes priority over a filename specified in the download attribute.
If the header specifies a disposition of inline, Chrome and Firefox prioritize the attribute and treat it as a download. Old Firefox versions (before 82) prioritize the header and will display the content inline.
Which I am unsure how to use that information, I have the latest firefox version and the above code works fine on Chrome and other browsers. There doesn't seem to be much information about "specifying a disposition of inline", at least for react.
I can also take the link directly from the api and put it in the different browsers with the same effect (outside of the react/web front end). The only one that tries to open the file is firefox, the rest download it.
Thanks!
There doesn't seem to be much information about "specifying a disposition of inline", at least for react.
The Content-Disposition header is an HTTP header and needs to be set on the HTTP response given by the server.
React has nothing to do with it as it runs on the client.
(And you want to set the disposition to attachment, not inline, since the download attribute isn't working).
but I get a matrix screen of characters rather than a download (only on firefox).
This suggests that:
The download attribute isn't working anywhere (likely because you are making a cross-origin request so the attribute isn't supported).
The content-type of whatever the URL points to is either:
Wrong
Just not recognised by Firefox
… and downloads in other browsers are triggered by them recognising the content-type correctly (i.e. not the download attribute).
The solution is going to involve changing the Content-Type (if it is wrong) and/or Content-Disposition (to specify that the resource is an attachment and so should be downloaded and not displayed inline) of the resource the URL points to.

Firefox Ignores Content-Disposition

I'm trying to write MVC endpoint that will optionally set the content-disposition to inline or attachment in order to either display the file (a pdf) inside a new browser tab or else to download it. The UI allows the user to select how they'd like to open the file (not my design - can't change that aspect of it).
Note that this works in Chrome/Edge just as expected.
In Firefox, the application settings for PDF appear to trump the content-disposition. Is there a reliable way to get Firefox to respect the content-disposition? Preferably a way that will work w/ a vanilla installation of the browser such that end-users don't need to make any modifications on their end for it to work.
Here's the code I'm using to setup my response (class is derived from ApiController):
var response = Request.CreateResponse(System.Net.HttpStatusCode.OK);
response.Content = new PushStreamContent((stream, content, context) =>
{
dispatcher.Dispatch(request, stream);
}, new MediaTypeHeaderValue(MediaTypeNames.Application.Pdf));
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue(contentDisposition)
{
FileName = $"{auto_generated_fileName}.pdf",
};
response.Headers.CacheControl = new CacheControlHeaderValue()
{
NoCache = true,
NoStore = true
};
return response;
We have noticed this issue in our webapp as well. The webapp has a download button that lets the user download a PDF file. Firefox shows the PDF file in the current tab, which effectively kills the webapp.
After a bit of research, this appears to be an intentional feature, see the release notes for Firefox 98:
When you set an application to open files of a specific type in your Firefox preference settings, those files will open automatically, even files served by the website with "content-disposition: attachment". The same applies to PDF files that are set to open in Firefox by default. This is a fix to bug 453455.
Personally, while I can understand some users may want this for web pages that don't behave well, this is an issue for well-behaved web apps.
Setting the download attribute on the anchor does not appear to work either, Firefox still shows the file inline (tested with Firefox 99.0)
So as far as I am aware, you cannot force the browser to download the file if the browser does not allow it. Other web apps such as OwnCloud or Google Drive are having the same issue -- if you click right on a PDF file in Google Drive and then click on Dowload, Firefox still open the PDF file inline, whereas Chrome downloads it.
For now, it seems the best you can do is to open file in a new tab, to prevent the webapp or web page from being replaced by the downloaded file (which is also what Google Drive seems to be doing). You can open the download in a new tab or window e.g. via the target attribute on an <a> links or via the formtarget atttribute on a <button> element.
I found #blutorange's answer after trying to find a solution to the same problem as OP. However, just before I got here, I stumbled across this answer from back in 2013 - https://stackoverflow.com/a/16515146 which suggests to set the Content-Type header to application/octet-stream, instead of application/pdf.
I tried that solution and what do you know - it works! The PDF opens in a new tab in Firefox automatically, but at least it doesn't replace the tab of my application, so yay! Chrome doesn't seem to mind it either and my PDF viewer on my computer also recognizes the files as PDFs.
Now, this might not be the most "correct" fix to the issue we're facing, but it's an alternative to forcing open a new tab.

Safari doesn't load all resources of the webpage

I have a very weird problem with Safari opening my web app.
The setup: I am running an Vuejs application stored in a S3 Bucket on AWS. The app is exposed by an API Gateway.
The Problem: When opening the app only index.html and the favicon are loaded but not the other assets. Sometimes they occur inside the Network tab in dev tools with the message "Failed to load resource" but sometimes not.
"Solution": When I open the app with http (which doesn't work) and then with https again, the resources can be loaded somehow and the app will work fine even when reloading with cache clearing.
Does anyone know how to overcome this problem? 🤷‍♂️
I have a similar problem (not related to vue.js and amazon, but just to Subject: Safari selectively loads resources):
Mac OS Safari 14 (desktop version, I don't know for a mobile one) doesn't load all referred css, js, and image files.
Safari 13 performed well. Other browsers (Chrome, Firefox) perform well. All files are referred the same way, using relative URLs.
When using Safari 14, some of them are loaded, some are not. Caching is not an issue (I use "empty caches" before loading a page).
It looks like successfully loaded files are randomly chosen (the same file is sometimes loaded, sometimes it isn't).
In the Network tab of Develop menu, for not loaded files Preview says: "An error occurred trying to load the resource",
and in Headers, section "Request", there are only: Accept, Referer, and User-Agent lines, while:
GET, Cookie, Accept-Encoding, Host, Accept-Language, and Connection lines are missing.
Response says: "No response headers".
In the server's access log, there are no lines related to not loaded files.
EDIT:
The cause: TLS 1.0
The solution: TLS 1.2

How do I return css files with response headers using a flask app running on Apache with HTTPS?

I have a flask app running on an apache HTTP server on ubuntu 14.04. Everything works great, but I'm now trying to make things secure and get HTTPS up and running. The content still renders properly when requesting the HTTP URLs, but static CSS files are not loading when changing the prefix to HTTPS.
Some useful details and previous attempts:
I have the CSS files in the usual static/css location.
This answer was helpful, and got javascript rendering properly, but using AddType for CSS isn't working for some reason.
I tried sudo a2enmod mime to make sure that Apache module was enabled, and it was.
I tried forcing the type for css (similar to what was suggested here, but with css instead of js and javascript), but that didn't work either.
I've tried adding the AddType declaration to my configuration file located in /etc/apache/sites-available/FlaskApp.conf (that's where the successful AddType text/javascript .js declaration is located), and I've also tried putting the AddType declaration in a .htaccess file located in the root directory of my FlaskApp, but both attempts were unsuccessful.
Everything loads fine when accessing the site with the http:// prefix, just not the https:// prefix. I've tried accessing it from Chrome and Firefox.
Chrome Response
Looking at the console when loading the page in Chrome is shows the following for all CSS files:
Resource interpreted as Stylesheet but transferred with MIME type application/x-gzip
Looking at the network tab, everything looks similar between the http request and the https request, except that the https request is completely missing the Response Headers section.
When attempting to load just the /static/css/styles.css file in Chrome, it attempts to download the file instead of displaying it in the browser.
Firefox Response
When attempting to load just the /static/css/styles.css file in Firefox, it loads in the browser. However, it's not ascii text but rather jumbled characters as though it's loading a binary file. Here's the console error message in Firefox:
The character encoding of the plain text document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the file needs to be declared in the transfer protocol or file needs to use a byte order mark as an encoding signature.
So my question is, how do I get my HTTPS/Flask/Apache/Ubuntu setup to properly return static css files so that my pages render properly?
This suggestion and this suggestion look promising, but I'm not sure how to make it so that any request that hits /static/css/*.css returns the proper css file with the "Content Type" or "mimetype" set correctly.

One Click install for Safari Extensions

When a user downloads a plugin firefox (for example) the plugin installation begins as soon as the download has completed.
Is it possible to achieve the same thing in safari? i.e. user clicks link to download plugin, once it has downloaded it automatically begins the installation.
I don't think this is possible to do on any other domain except extensions.apple.com.
I've done some extensive testing on this and the safari.installExtension() method is only present if the domain matches extensions.apple.com (probably controlled by the browser, similar to how certain Chrome APIs only shows up inside of extensions themselves).
I tested this theory by going to the JS file itself and opening the JS console:
https://extensions.apple.com/home/scripts/extensionInstall.js
After that JS file has loaded, type typeof(safari.installExtension) in the JS console and it should return "function". Notice that it exists on a non-HTML page, meaning it's being provided by the browser (since this script doesn't execute, nor has the code in it to provide this method).
I tried doing this on other sites and it doesn't exist: "undefined".
I also had a crazy thought that it just needs extensions as the subdomain, so I tested it on http://extensions.joomla.org too, no dice. I can't seem to find an extensions sub-domain that's SSL though. That may work, but I seriously doubt it as the method appears to be regulated to only show up when on Apple's specific extensions sub-domain.
No solution for that here, but maybe this can help?
In apple extension gallery at https://extensions.apple.com the extensions do install in one click, and i wanted to achieve the same in a website of mine, so i went and checked their JS source code.
A javascript file there defines a "ExtensionOneClick" Object (https://extensions.apple.com/home/scripts/extensions.js).
A method is dedicated to installing extensions:
// href : path to the extension ".safariextz" file
// id : com.whatever.myextension-<safaridevelopper10charsid>
safari.installExtension(id, href);
I tried to replicate this on my website, but i get "safari is undefined", so I guess a site specific hack in Safari is helping here?