Safari browser not decoding the filename that set in content-disposition header - safari

I had encoded the filename using org.apache.catalina.util.URLEncoder and set in content-disposition header as follows:
String encoded = urlEncoder.encode(fileName, StandardCharsets.UTF_8);
response.setHeader("Content-Disposition", "attachment;filename=\""+encodedFileName+"\"");
Filename : ຕົວຢ່າງ.pptx
Encoded : %E0%BA%95%E0%BA%BB%E0%BA%A7%E0%BA%A2%E0%BB%88%E0%BA%B2%E0%BA%87%pptx
While downloading in chrome browser it decodes and download correctly. But safari doesnot decode the name, it downloads in the encoded format.
Also, the extension is appended to the filename while downloading from safari browser.
Like %E0%BA%95%E0%BA%BB%E0%BA%A7%E0%BA%A2%E0%BB%88%E0%BA%B2%E0%BA%87%2Epptx.pptx
Thanks, in advance.

Because URL-encoding the filename is not portable.
All the details are in RFC 6266; the format described over there will work with all current browsers.

Related

How can I see submitted POST request data in Chrome DevTools for multipart/form-data [duplicate]

I'm creating some performance tests for a web application that sends requests of the same type that a browser would send to our server. One of these requests is a POST that uploads an image. I looked at this question where it looks like the actual contents of the image file should be inside the body of the request. However when I use F12 dev tools in Chrome to inspect what the browser sends in the request it looks like this:
------WebKitFormBoundaryjHN86sGb89n2HUZOT
Content-Disposition: form-data; name="profileImg[]"; filename="bmp.bmp"
Content-Type: image/bmp
------WebKitFormBoundaryjHN86sGb89n2HUZOT--
The space where I expected to see the file contents is blank. I was expecting to see some string of seemingly random characters representing the contents of the image file. There's also no path to the image in the request, only the name of the file, so I can't understand exactly how the file could be uploaded? Is Chrome just hiding the data from me?
Chrome hides the file data, when viewing the request payload using dev tools, for performance reasons:
https://groups.google.com/forum/#!topic/google-chrome-developer-tools/FaInquBDhU0
So I downloaded Fiddler and it actually shows that there is data being sent where we in Chrome see only a blank space. This means that Chrome does indeed hide the data.

S3/Cloudfront does not send image/jpeg Content-Type

I have a .jpg file stored in S3 and distributed using CloudFront. I can view the file when I download it, but I cannot view the file in Chrome or Safari. From what I can tell, I can't view the file in a browser because the Content-Type isn't getting sent despite the fact that I've set it in S3.
You can see what happens when you enter this signed CloudFront url into a browser. It should remain valid for roughly 24 hours after this post. https://media.development.doctheapp.com/claims/us-east-1:4877c3da-786a-4b3b-b1e0-c70bde0f9c4e741afc7c5a8304564963080a98e5675d09d1aca3d623911e34bd3b4eb0808579/300ae913-8f88-44b9-a4ab-e46d11133c76/receipt.jpg?Expires=1526533530&Signature=crnjhje1noP-7WfBMI6rMDPd-zdCAVKLaojFFNvxCZEdx0~EJHeqbL8oKwL64AULavekMHm~2r6vHto1d4IAt5eoLpbZR~q5PAfhSakte1iNNvuTxQ7q-mYOwoCemb5VD~bFXUBdrF1yiybaRHw-v6USbw53QZ2Qa4hfDkqgoEKwvEznBvR~sQnk5v-slX8~aJBhySS5XpkfdoE-yl8hh697xIyH~OliwrCg7h5iSkotwW9~EvTnLoVkXkuvru35eLhN4~gGMs3WDUAuucOl8JZdeg6CjAQQ~JWv6FJnb2wyvGrGJzOf70~8s08~qSqiCroyZfqUiZmw20eCIWXp4A__&Key-Pair-Id=APKAJVSE2BEPIQCCPH6Q
It seems like the original image is a TIFF file, not a JPEG. That's why you cannot see it in a browser but can open it upon download. The content type header is being sent correctly by Cloudfront if you look at the response headers.

Specify content-type for documents uploaded in Magnolia

We have uploaded an mp4 video file into our Magnolia DMS, which fails to play on Safari (Mac/iPad). Investigation shows that the Content-Type returned by Magnolia is "application/octet-stream" for the request. When serving the file through Tomcat directly, the correct Content-Type "video/mp4" is returned and video playback works.
How can we configure the content-type to be returned in Magnolia?
We know the content-type is a function of the request (e.g. if we add ".jpg" to the URL the type returned is "image/jpeg"), but couldn't use this knowledge to come up with a solution.
Update:
We found the MIME configuration and could change the Content-Type for "mp4" to "video/mp4". However, the Content-Type returned by Magnolia is now
Content-Type: video/mp4;charset=UTF-8
while the correct, working Content-Type returned for files hosted by Tomcat is
Content-Type: video/mp4
Is it possible to make Magnolia not append any charset info to the Content-Type?
Glad you found the MIME configuration OK.
Both the MIME type and the character encoding are set in ContentTypeFilter.java and MIMEMapping.java. You can specify a charset for a MIME type yourself by including it in the mime-type definition. (E.g. "video/mp4;charset=UTF-8".)
If you don't include one, however, Magnolia automatically assigns the default (in this case, UTF-8). If you want to change this behavior, you'd need to tweak the source code.
Out of curiosity, is the charset causing you any trouble, or are you just trying to get Magnolia to match what Tomcat does by default?

How do I force files to open in the browser instead of downloading (PDF)?

Is there a way to force PDF files to open in the browser when the option "Display PDF in browser" is unchecked?
I tried using the embed tag and an iframe, but it only works when that option is checked.
What can I do?
To indicate to the browser that the file should be viewed in the browser, the HTTP response should include these headers:
Content-Type: application/pdf
Content-Disposition: inline; filename="filename.pdf"
To have the file downloaded rather than viewed:
Content-Type: application/pdf
Content-Disposition: attachment; filename="filename.pdf"
The quotes around the filename are required if the filename contains special characters such as filename[1].pdf which may otherwise break the browser's ability to handle the response.
How you set the HTTP response headers will depend on your HTTP server (or, if you are generating the PDF response from server-side code: your server-side programming language).
The correct type is application/pdf for PDF, not application/force-download. This looks like a hack for some legacy browsers. Always use the correct mimetype if you can.
If you have control over the server code:
Forced download/prompt: use header("Content-Disposition", "attachment; filename=myfilename.myextension");
Browser tries to open it: use header("Content-Disposition", "inline; filename=myfilename.myextension");
No control over the server code:
Use the HTML5 download attribute. It uses the custom filename specified on the view side.
NOTE: I prefer setting the filename on the server side as you may have more information and can use common code.
(I misread the question, the following answer is about forcefully downloading the file instead of opening it in the browser)
If you are using HTML5 (and I guess nowadays everyone uses that), there is an attribute called download.
For example,
<a href="somepathto.pdf" download="filename">
Here filename is optional, but if provided, it will take this name for the downloaded file.
EDIT
I know this is the opposite of what the question asked. I am keeping the opposite answer for those (like me) who came searching for the opposite question (Evidence: this answer has more upvotes then downvotes)
I had the same issue and most of the above answers should resolve your issue. Unfortunately, even if i was receiving the content-type & content-disposition headers in the response but still my pdf was being downloaded rather than viewed. After brainstorming and trying for many hours.
The Culprit was firefox, well in a way it was me. Nervous Laughter
By default, when you open a pdf file in firefox, it will provide you with a popup to either save the pdf file or to open it directly and there is also a check box which says do this action automatically from now on and guess who selected it.
Due to this mistake, my pdf was being downloaded rather than viewed, even if had all the required headers in response. This is a simple mistake but cost me a good amount of time.
To resolve this, just go to settings and search for applications and change pdf setting to whatever you need.
This is for ASP.NET MVC
In your cshtml page:
<section>
<h4><i class="fa fa-download"></i> #Model.Name</h4>
<object data="#Url.Action("View", "Document", new { id = #Model.GUID })" type="application/pdf" width="100%" height="800" class="col-md-12">
<h2>Your browser does not support viewing PDFs, click on the link above to download the document.</h2>
</object>
</section>
In your controller:
public ActionResult Download(Guid id)
{
if (id == Guid.Empty)
return null;
var model = GetModel(id);
return File(model.FilePath, "application/pdf", model.FileName);
}
public FileStreamResult View(Guid id)
{
if (id == Guid.Empty)
return null;
var model = GetModel(id);
FileStream fs = new FileStream(model.FilePath, FileMode.Open, FileAccess.Read);
return File(fs, "application/pdf");
}
While the following works well on firefox, it DOES NOT work on chrome and mobile browsers.
Content-Type: application/pdf
Content-Disposition: inline; filename="filename.pdf"
To fix the chrome & mobile browsers error, do the following:
Store your files on a directory in your project
Use the google PDF Viewer
Google PDF Viewer can be used as so:
<iframe src="http://docs.google.com/gview?url=http://example.com/path/to/my/directory/pdffile.pdf&embedded=true" frameborder="0"></iframe>
If you have Apache add this to the .htaccess file:
<FilesMatch "\.(?i:pdf)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
Oops, there were typing errors in my previous post.
header("Content-Type: application/force-download");
header("Content-type: application/pdf");
header("Content-Disposition: inline; filename=\"".$name."\";");
If you don't want the browser to prompt the user then use "inline" for the third string instead of "attachment". Inline works very well. The PDF display immediately without asking the user to click on Open. I've used "attachment" and this will prompt the user for Open, Save. I've tried to change the browser setting nut it doesn't prevent the prompt.
for large files you need to get your output buffer started add :-
ob_start(); // at the start
..//your code
ob_clean();// at the end of you file
You can do this in the following way:
Open PDF
If the PDF file is inside some folder and that folder doesn't have permission to access files in that folder directly then you have to bypass some file access restrictions using .htaccess file setting by this way:
<FilesMatch ".*\.(jpe?g|JPE?G|gif|GIF|png|PNG|swf|SWF|pdf|PDF)$" >
Order Allow,Deny
Allow from all
</FilesMatch>
But now allow just certain necessary files.
I have used this code and it worked perfectly.
Open downloads.php from rootfile.
Then go to line 186 and change it to the following:
if(preg_match("/\.jpg|\.gif|\.png|\.jpeg/i", $name)){
$mime = getimagesize($download_location);
if(!empty($mime)) {
header("Content-Type: {$mime['mime']}");
}
}
elseif(preg_match("/\.pdf/i", $name)){
header("Content-Type: application/force-download");
header("Content-type: application/pdf");
header("Content-Disposition: inline; filename=\"".$name."\";");
}
else{
header("Content-Type: application/force-download");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$name."\";");
}
Here is another method of forcing a file to view in the browser in PHP:
$extension = pathinfo($file_name, PATHINFO_EXTENSION);
$url = 'uploads/'.$file_name;
echo '<html>'
.header('Content-Type: application/'.$extension).'<br>'
.header('Content-Disposition: inline; filename="'.$file_name.'"').'<br>'
.'<body>'
.'<object style="overflow: hidden; height: 100%;
width: 100%; position: absolute;" height="100%" width="100%" data="'.$url.'" type="application/'.$extension.'">
<embed src="'.$url.'" type="application/'.$extension.'" />
</object>'
.'</body>'
. '</html>';
Either use
<embed src="file.pdf" />
if embedding is an option or my new plugin, PIFF: https://github.com/terrasoftlabs/piff
If you link to a .PDF it will open in the browser.
If the box is unchecked it should link to a .zip to force the download.
If a .zip is not an option, then use headers in PHP to force the download
header('Content-Type: application/force-download');
header('Content-Description: File Transfer');

how to force file download instead of opening in any application

I want to prompt users to save file instead of opening file in application. For example if user click a mp3 file link....mp3 file must not be open in win media player...instead user promoted to download that file.
Set the Content-Disposition header to attachment; filename=filename.mp3. This will suggest to the browser that it should prompt the user to save as the given file name.
I believe you can just send a content-disposition header. I.e.
Content-Disposition: attachment; filename=<file name.ext>
And that should force the option to download the file.