force browser to download a file instead viewing it - pdf

On my web I want to have two buttons - first Download that should download a pdf to the user's computer and another View that opens pdf in a new tab. The thing is, I don't know how to make the Download button. You might say that it is useless as you can save pdf after "viewing" it but I have already made graphics like that and don't really want to change it. Is it possible to prevent browser from opening the pdf file and make it download the file instead?

You need to force file download in your server-side script:
Here is a PHP example:
$file = "path/to/my-file.pdf";
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$file");
header("Content-Type: application/pdf");
header("Content-Transfer-Encoding: binary");

In the end, as I use nginx, I decided to solve this at http-server level:
location /media {
alias /srv/www/novacek/media/;
}
location /download/media {
alias /srv/www/novacek/media/;
add_header Content-Disposition "attachment";
}

Related

cfdocument: open download prompt to ask user where to save pdf

I'm using cfdocument to create a pdf. Displaying the pdf in the browser works fine, but I would like to just open a download prompt when the user opens that url.
<cfdocument format="PDF" localUrl="yes" margintop="0.25" orientation="landscape">
What I tried:
I followed this and added a filename: https://community.adobe.com/t5/coldfusion-discussions/how-to-use-cfdocument-create-a-pdf-file-and-save-the-file-in-server/td-p/966276
But it just saves that file in a lucee temp folder.
What I want is that it opens a prompt and asks the user, where he wants to save that file.
I'm pretty sure you can't prompt the "save as" directly. The cause is that nowadays most browsers save the file immediately/directly to the "download" folder by default. For example in Chrome the user can deactivate this behaviour in "Settings -> Downloads -> Ask where to save each file before downloading". A similar setting exists in Firefox.
However, if you don't want to display the PDF in the browser but start a direct download, just add the http headers used for that. This is an example how to achieve it (
I've tested this on Lucee only but should work for ACF the same way):
<cfheader name="Content-Transfer-Encoding" value="binary">
<cfheader name="Content-Disposition" value="attachment; filename=""somefilename.pdf""">
<cfheader name="Content-Type" value="application/pdf">
<cfdocument format = "PDF" pagetype="A4" orientation="portrait">
Just a test for download!
</cfdocument>
If you omit the attribute filename="somefilename.pdf" of the Content-Disposition response header, the name of the url will be taken. Alternatively you could ask the user to specify a name in a form input field and populate that variable. But it still will be downloaded to the "download" directory as specified in the users browser setting.

how to enable gzip compression in libwebsocket on ESP32

I am running a webserver on an ESP32 chip using the libwebsocket library. The server files are in a ROMFS partition on the ESP32.
Currently I am in the process of trying to improve the loading time by concatenating, minifying and compressing the javascript, html and css files.
The concatenation and minification worked properly, I now only have a concatenated.js and concatenated.css file in my website. But the issue came when I tried to get the compression working.
Initially, I thought my server would compress the files by itself before sending them, however when I looked at the server file transfer using Chrome developper extension, I found out that the javascript file GET request was returned with "content-type: text/javascript".
I tried several solutions I could think of, but none seem to work:
gzip the file before creating the romfs (ie there is now only a concatenated.js.gz in my ROMFS file system)
The server returns 404 when trying to access "concatenated.js"
gzip the file before creating the romfs and make it live alongside the original file (I was thinking maybe libwebsocket would be able to see they were both there and pick the most efficient one)
The server only returns the js file, and never the gz file
Does anybody knows how to enable the gzip compression in libwebsocket ? I am guessing there must be some options I don't have enabled, but it has been hard finding resources on the web. Most of them only discuss about the ability of the libwebsocket to get gzip from a zipped file.
Regards,
The issue ended up coming directly from the libwebsocket code.
When opening a file from the ESP32, there was no logic in place to look for a file with the same name and ".gz" at the end. The logic to look for such a file if the browser accepted gzip file needed to be added to the function.
This change was done on an older version of the libwebsocket, and as such may not apply to the latest version (for anybody looking at this modification). Also, I needed to include <string.h> to have access to the string manipulation functions:
libwebsocket/lib/plate/freertos/esp32/esp32-helpers.c -> function esp32_lws_fops_open
Replace
f->i = romfs_get_info(lws_esp32_romfs, filename, &len, &csum);
By
// check for the gzip file if gzip is allowed by the browser
f->i = NULL;
if((*flags & LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP) == LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP)
{
char *filename_gz = malloc(strlen(filename) + 3 + 1); // add space for ".gz" and null termination
sprintf(filename_gz, "%s.gz", filename);
f->i = romfs_get_info(lws_esp32_romfs, filename_gz, &len, &csum);
}
// if we haven't found a gz file (not allowed or no gzip), search for the regular file
if(!f->i)
{
f->i = romfs_get_info(lws_esp32_romfs, filename, &len, &csum);
}
// otherwise, add the flags to let the library knows the file transfered is a gzip file
else
{
*flags |= LWS_FOP_FLAG_COMPR_IS_GZIP;
}

NextJS doesn't create index.html for subfolders in static export

I made a fully static website using NextJS, exported it and I'm hosting it on S3 using static website hosting. I can click around and successfully view all the pages, including example.com/blog. However if in the browser I click refresh, or enter example.com/blog directly, I get a 404 Not Found error.
When viewing the exported files, I see that /blog/ has no index.html file, even though there should be (in my opinion) since in the original source files I have a /blog/index.ts file, and when in dev mode I can refresh localhost/blog or enter it directly and it works as expected.
In summary, I believe NextJS should create a /blog/index.html file but it doesn't. Is there any way to force this? Am I doing something wrong? Thank you!
To generate an index.html file when exporting to static HTML, enable the trailingSlash setting in your next.config.js:
module.exports = {
trailingSlash: true,
}
./out/blog.html should now become ./out/blog/index.html after the export.

Problem with opening pdf file in site

I have pdf file in serwer and link to it. In local host when i click on link pdf file display in site. On server I've got popup with asking to download file. How to change type from application/octet-stream to application/pdf to display pdf normal on site?
Here is screen after clicking on link:
The reason that the listed solutions are reported not to work half the time, is because using the default MIME association or setting the Content-Type header in <Files> or <FilesMatch> (for the PDF file extension) will have no effect on PDF files that are dynamically transferred via PHP code (i.e., readfile())...
To force a PDF to open in the browser rather than downloading, you should use LocationMatch instead:
<LocationMatch "\.(?i:pdf)$">
ForceType application/pdf
Header set Content-Disposition inline
</LocationMatch>
This way it picks up on transfers that are not direct from the file-system.
If it a unix server add an entry for pdfs in /etc/mime.types, if it's a Windows server, add a mime type in IIS.
Problem solved with using solution from this site:
http://www.thingy-ma-jig.co.uk/blog/06-08-2007/force-a-pdf-to-download
Thanks Joost Evertse

How is the download file name chosen and is there a way to change it?

I have a link to a file not on my server:
NASA
I would like to make it so that when a visitor clicks on the link to download, the name that would pop up for the PDF would be NASA.pdf, and not monograph15b.pdf.
Is this possible in any language?
If you aren't going to host the file yourself, you may be able to read in the file contents and then send those contents directly to the browser with the appropriate headers.
Note that this will be slow because you'll be re-downloading the file from NASA each time your PHP page runs.
<?php
$filename = "http://history.nasa.gov/monograph15b.pdf";
$outputfilename = "NASA.pdf";
header("Content-Type: application/pdf");
header("Content-Disposition: attachment; filename=\"" . basename($outputfilename) . "\";" );
header("Content-Transfer-Encoding: binary");
readfile("$filename");
?>
This approach also requires that PHP be configured so that fopen() can handle reading a file over HTTP.
The only way to really do that is to first download the file in question onto your own server, name it as you wish, and then serve it back up to your end users.
Look into the HTTP header Content-Disposition header, it will allow you to specify the filename.
You need to use any server side technology like ASP.NET. Where in you put in a button on the page. When the button is clicked it will perform following tasks.
1.) Response.Clear();
2.) Response.AddHeader("Content-Disposition", "attachment; filename=Nasa.pdf");
3.) Response.ContentType = "application/octet-stream";
4.) Response.WriteFile(context.Server.MapPath("history.nasa.gov/monograph15b.pdf")); // you need to set the realtively correct path for your application.