With NGINX I was able to set the header per filetypes in a folder, like
location /tuts (.*\.pdf) {
add_header Content-disposition "attachment";
}
to ensure files like pdf/mp4 etc are always forced to download, regardless of browser.
I have something like
tuts.example.com {
root /var/www/static/tuts
browse
header / Content-disposition "attachment"
log ../logs/tuts.log
}
but visiting tuts.example.com just downloads the HTML.
I would like that any file (or preferably specific files) at that location would get that header applied. The folder can have pdf/txt/mp4 files (amongst others), and some will open in the browser and others will download, again depending on the browser used.
The only 100% reliable way with NGINX that I could have a simple indexed page _and_ force certain filetypes to download was to use the add_header method I mentioned above. I also tried changing the mime type to application/octet-stream but that wasn't reliable either.
Is this possible with Caddy or have I just messed up the syntax?
With the headers directive, you've set the base path to / which equates to all requests. It should instead be the path to only the folder which has the downloads stored in it.
That's what I had initially but it didn't seem to work at all. I tried just adding a custom header with
header /var/www/static/tuts X-Custom-Header "Some value"
but I couldn't see that in the response in the Chrome dev tools.
If I test a file that I know will download by default, like a zip, then I'll get something like
Accept-Ranges:bytes
Connection:keep-alive
Content-Disposition:attachment
Content-Length:7
Content-Type:application/zip
Date:Mon, 18 Jan 2016 12:23:03 GMT
ETag:"569cd4c7-7"
Last-Modified:Mon, 18 Jan 2016 12:04:23 GMT
Server:nginx/1.4.6 (Ubuntu)
with NGINX, but with Caddy
accept-ranges:bytes
content-length:7
content-type:application/zip
date:Mon, 18 Jan 2016 12:18:05 GMT
last-modified:Mon, 18 Jan 2016 12:04:23 GMT
server:Caddy
status:200
The server blocks are identical between NGINX/Caddy. All I did was change the syntax where needed, like browse instead of autoindex on.
If your root is /var/www/static/, you should set the header for /tuts. It is doing matching based on the HTTP GET path.
The root is /var/www/static/tuts. It's a folder with a bunch of files in it. When someone hits tuts.example.com then I want to serve the contents as a basic indexed page. This much works fine, barring the headers. I have it stripped down to simply
tuts.example.com {
root /var/www/static/tuts
browse
header /var/www/static/tuts Content-disposition "attachment"
}
but no headers get applied.
For testing purposes, I tried making a files folder within tuts and moving the files in there, then used
tuts.example.com {
root /var/www/static/tuts
browse
header /var/www/static/tuts/files Content-disposition "attachment"
}
but no difference.
header is request path based (not OS path based). Maybe try adding mime type too.
tuts.example.com {
root /var/www/static/tuts
browse
header / Content-disposition "attachment"
mime .mp4 application/octect-stream
mime .pdf application/octect-stream
}
That was my initial assumption, but when I implement it exactly as you mentioned then visiting tuts.example.com downloads the HTML, it doesn't render the index.
Oh, you mean it downloads every file, including html. But you only want it limited to mp4, pdf e.t.c ?
No, I mean it literally downloads a copy of the HTML. If I go to that address it'll download download.htm. It doesn't actually take me to tuts.example.com.
That's what I've been saying -- the path you set for your header directive should only be the path for files you WANT the browser to download (in your case) -- not the path that includes the html files.
There are no HTML files in that tuts folder. It's just a file dump for txt/zip/mp4/pdfs mostly. That's why I used browse so it would just display as a list of files to choose from to download.
If I use
tuts.example.com {
root /var/www/static/tuts
browse
header /var/www/static/tuts Content-disposition "attachment"
}
then the page renders properly but none of the files get that header applied. If I use
tuts.example.com {
root /var/www/static/tuts
browse
header / Content-disposition "attachment"
}
then it's as I described. The browser just downloads the HTML (i.e the HTML that would be used if the page was to be displayed).
Ohh. So what's happening is you're setting the header for all requests, which tells the browser to download a file no matter what the response is. The browse middleware just writes an HTML response - the browser doesn't know it's not a real file on disk, it just thinks it has to download it because you're setting that header.
That's the problem. Either I get the page as a download, or the page renders as an indexed page but none of the downloadable files get that header applied.
With NGINX my setup was this
server {
listen 80;
root /var/www/static/tuts;
server_name tuts.example.com;
location ~* \.pdf$ {
add_header Content-Disposition "attachment";
}
autoindex on;
}
Visiting the page would show a list of the files in the tuts folder, much like browse. The crucial difference being that it allowed me to target files inside the folder and apply a header only to them.
If I didn't specify a file(s) and just used
server {
listen 80;
root /var/www/static/tuts;
server_name tuts.example.com;
add_header Content-Disposition "attachment";
autoindex on;
}
then it behaves exactly as
tuts.example.com {
root /var/www/static/tuts
browse
header / Content-disposition "attachment"
}
in that it returns an HTML download, not a page listing.
So, as it stands, I can't use browse _and_ target files in that folder to apply headers to? Something like
header /*.pdf Content-disposition "attachment"
Thanks for the help btw. I was able to get as much done in 10 minutes with Caddy as it took me the best part of an hour with NGINX.
Ahhh, I see, so you need to apply headers to just .pdf files.
This can't be done right now -- not intuitively, anyway -- except maybe using a hack with the rewrite directive (@abiosoft?).
Meanwhile I'm considering implementing more powerful request matching features since the number of valid use cases seem to be adding up.
Actually, rewrite can as well be able to add/remove headers since proxy can do that.
Closing since the answer to the question is the same feature request as in a few other related issues. Thanks!
Closing since the answer to the question is the same feature request as in a few other related issues.
I am trying to track down the status of this feature request. Specifically, I want to add headers to a rewrite rule - i.e., if I match a rewrite regex, I want to add response headers.
Is this possible today?
Most helpful comment
header is request path based (not OS path based). Maybe try adding mime type too.