Force PDF file download using htaccess - apache

i am using Apache as backend server and nginx as frontend server. I need to make PDF files downloadable (at this moment they are opening in a browser window).
Here's a link:
link
Here's what i have tried so far in my .htaccess file:
<FilesMatch "\.(pdf)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
Didn't work, just opens the file in a browser.
AddType application/force-download pdf
Didn't work.
AddType application/octet-stream .pdf
Didn't work.
UPDATE
Tried: wget --server-response -O /dev/null http://domain.com/files/teltomat.pdf
And got response:
HTTP request sent, awaiting response...
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 24 Sep 2014 17:40:54 GMT
Content-Type: application/pdf
Content-Length: 3116445
Last-Modified: Wed, 24 Sep 2014 13:28:07 GMT
Connection: keep-alive
Keep-Alive: timeout=60
ETag: "5422c6e7-2f8d9d"
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Cache-Control: max-age=315360000
Accept-Ranges: bytes
Length: 3116445 (3,0M) [application/pdf]
Saving to: ‘/dev/null’

You could try the HTML5 solution of adding a "download" instead of "target":
link
As it looks like the server's end is doing the right thing (by making the disposition "attachment") but maybe the browser is deciding on its own that it can handle PDF's inline and opens a new window instead.

Related

How to apply cache control header to a specific file with .htaccess

I'm trying to apply a no cache header to the style.css file in the child theme of my WordPress site, using the .htaccess file. I want to avoid having to clear my browser cache every time I make CSS styling changes to the site, in order to see the changes. Currently my cache control looks like this -
<Files ~ https://my-domain.org.au/wp-content/themes/church-suite_child_theme/style.css>
FileEtag None
<ifModule mod_headers.c>
Header Unset ETag
Header Set Cache-Control "max-age=0, no-store, no-cache, must-revalidate"
Header Set Pragma "no-cache"
Header Set Expires "Thu, 30 June 2022 00:00:00 GMT"
</ifModule>
</Files>
It doesn't appear to be working. I'm using the Network Inspector in Chrome Dev Tools to view the network requests. The following is returned when I refresh the page and inspect the request -
RESPONSE HEADERS,
cache-control: max-age=31536000
content-encoding: br
content-type: text/css
date: Fri, 12 Nov 2021 01:41:45 GMT
etag: W/"6188f369-73b"
expires: Sat, 12 Nov 2022 01:41:45 GMT
host-header: 8441280b0c35cbc1147f8ba998a563a7
last-modified: Mon, 08 Nov 2021 09:52:41 GMT
server: nginx
vary: Accept-Encoding
x-proxy-cache-info: DT:1

Apache still load from cache even disable mod_expires

Test on this url
http://getapple.net/phpbb/banners.js
It return 304, File not modified.
I have once enable plugin "mod_expires" and set up js to cache for 1 month.
But now i want to reset the rules. I try to comment this line
ExpiresByType application/javascript "access 1 month"
and then restart apache.
But the file still load from cache. (Response Header return 304 in Chrome Browser)
But after i run this
curl -I http://getapple.net/phpbb/banners.js
in command line, the result are
HTTP/1.1 200 OK
Date: Sun, 10 May 2015 14:51:59 GMT
Server: Apache/2.4.7 (Ubuntu)
Last-Modified: Sun, 10 May 2015 14:34:14 GMT
ETag: "9dd2-515bb27cf250a"
Accept-Ranges: bytes
Content-Length: 40402
Vary: Accept-Encoding
Content-Type: application/javascript
I don't know what i did wrong. Please suggest how to get the updated version of my file via url.
Thanks a lot.
When you send Expires header to browser, it will cache your response and only check for newer version after the expiration date has passed. Since browser won't check for newer version, changing your server settings won't affect browser's cached data. If you made some mistake in your script or there is an update, you can use query string to force browsers to ask for your script.
Assume this is your current script:
<script src="http://getapple.net/phpbb/banners.js" ></script>
What you need to do:
<script src="http://getapple.net/phpbb/banners.js?v=20150510" ></script>
Since URL is not the same, browser will ask for the one with query string and your new settings will be applied!

apache mod_cache stores but doesn't serve url with 'Transfer-Encoding: chunked'

I have setup apache2 with django and mod_wsgi in Debian Wheezy. I enabled mod_mem_cache with this configuration:
<IfModule mod_mem_cache.c>
CacheEnable mem /
MCacheSize 400000
MCacheMaxObjectCount 100
MCacheMinObjectSize 1
MCacheMaxObjectSize 500000
CacheIgnoreNoLastMod On
CacheIgnoreHeaders Set-Cookie
</IfModule>
based on the fact that MCacheMaxStreamingBuffer is the smaller of 100000 or MCacheMaxObjectSize as stated in the docs.
When I try hitting a page with size 3.3KB I get these response headers in firebug:
Connection Keep-Alive
Content-Encoding gzip
Content-Type text/html; charset=utf-8
Date Wed, 27 Aug 2014 14:47:39 GMT
Keep-Alive timeout=5, max=100
Server Apache/2.2.22 (Debian)
Transfer-Encoding chunked
Vary Cookie,Accept-Encoding
and the page isn't served from cache. In the page source there is however the correct header 'Cache-Control: max-age=300,must-revalidate' but doesn't show up in firebug.
In apache log I only see correctly:
[info] mem_cache: Cached url: https://83.212.**.**/?
With another test page that I created outside of django that doesn't have chunked encoding as a header, caching works fine. Why is the page not served from cache? Has anyone seen something similar?

Apache: Get rid of Keep-Alive entry in the headers list

I'm using LAMP (Linux, Apache, MySQL, PHP) server.
Currently the server sends the response with next Headers list. I want to eliminate Keep-Alive entry for security reasons, to have Headers list without it. Is it possible to prevent sending the Keep-Alive entry in the Headers list?
Current Response Headers:
Cache-Control private, no-cache, no-store, must-revalidate, post-check=0, pre-check=0
Connection Keep-Alive
Content-Encoding gzip
Content-Type text/html; charset=UTF-8
Date Thu, 13 Mar 2014 01:43:49 GMT
Expires Thu, 13 Mar 2014 01:43:49 GMT
Keep-Alive timeout=5, max=200
Last-Modified Thu, 13 Mar 2014 01:43:49 GMT
Pragma no-cache
Server Apache
Transfer-Encoding chunked
Vary Accept-Encoding
X-DNS-Prefetch-Control off
X-Frame-Options sameorigin
Response Headers I Would Like Instead:
Cache-Control private, no-cache, no-store, must-revalidate, post-check=0, pre-check=0
Connection Keep-Alive
Content-Encoding gzip
Content-Type text/html; charset=UTF-8
Date Thu, 13 Mar 2014 01:43:49 GMT
Expires Thu, 13 Mar 2014 01:43:49 GMT
Last-Modified Thu, 13 Mar 2014 01:43:49 GMT
Pragma no-cache
Server Apache
Transfer-Encoding chunked
Vary Accept-Encoding
X-DNS-Prefetch-Control off
X-Frame-Options sameorigin
Is it possible to prevent sending the Keep-Alive entry in the Headers list?
To my knowledge, no. The whole purpose of the Keep-Alive header is to communicate the need for a persistent connection to the client. So getting rid of the headers gets rid of the main form of communication between the client & the server.
That said, you might be able to get it unset by using unset in your Apache config or .htaccess as explained here. I emphasize might since I have had header directives not behave as expected in some versions of Apache. But assuming good faith, first be sure the headers module is enabled. In Ubuntu 12.04 you would do this:
sudo a2enmod headers
And then add this to your Apache config or .htaccess:
<IfModule mod_headers.c>
Header unset Keep-Alive
</IfModule>
Now restart Apache:
sudo service apache2 restart
More details on the header directive are here.
There are a few ways to this in apache:
Server-wide using the KeepAlive directive ( KeepAlive ). However you can not have this in per-directory configuration files, so setting KeepAlive Off will turn off keep alive for the entire server.
Using SetEnv or SetEnvIf with mod_env, and set the nokeepalive environmental variable. This will turn off keepalive for the location where the environmental is set, or the rule that is matched by SetEnvIf (depending with you use). e.g.
can be in HTACCESS
SetEnv nokeepalive 1
Using mod_rewrite to again set the environmental for a specific rule, e.g.
RewriteRule some-file.html - [E=nokeepalive:1]
Using PHP (or any other server site language) and sending the header Connection: close. This will cause Apache to omit the Keep-Alive header, since the connection is no longer keepalive. e.g.
php
header('Connection: close');
Use mod_headers to set the connection header to close again, e.g.
Header set Connection "close"
I personally have not tested the last one, but it should work.
KeepAlive behavior (availability and timeouts) is directly configurable:
http://httpd.apache.org/docs/2.4/mod/core.html#keepalive
Changing this is primarily an aspect of performance rather than security, but you're free to test the implications in your own environment.

Browser fails to cache SWF file

I am having an issue with the browser not caching a SWF file.
I have the following in my apache configuration:
ExpiresByType application/x-shockwave-flash "access plus 2 months"
I can see the headers coming back from the original request for the SWF look like this (the expires header looks like it's being set properly):
Request:
User-Agent Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5
Accept HTTP Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip,deflate
Cookie auth_token=
Response:
Server Apache/2.2.8 (Ubuntu) PHP/5.2.4-2ubuntu5.5 with Suhosin-Patch proxy_html/3.0.0 mod_ssl/2.2.8 OpenSSL/0.9.8g Phusion_Passenger/2.2.5
Last-Modified Sat, 14 Nov 2009 04:48:19 GMT
Etag "49384-4784d7c3c8ac0"
Accept-Ranges bytes
Content-Length 299908
Cache-Control max-age=5184000
Expires Fri, 15 Jan 2010 20:25:42 GMT
Content-Type application/x-shockwave-flash
However, on subsequent loads of the page, the browser still sends If-Range requests for the SWF as follows:
Request:
User-Agent Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5
Accept HTTP Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip,deflate
Cookie auth_token=
Range bytes=0-
If-Range "49384-4784d7c3c8ac0"
Response:
Server Apache/2.2.8 (Ubuntu) PHP/5.2.4-2ubuntu5.5 with Suhosin-Patch proxy_html/3.0.0 mod_ssl/2.2.8 OpenSSL/0.9.8g Phusion_Passenger/2.2.5
Last-Modified Sat, 14 Nov 2009 04:48:19 GMT
Etag "49384-4784d7c3c8ac0"
Accept-Ranges bytes
Content-Length 299908
Cache-Control max-age=5184000
Expires Fri, 15 Jan 2010 20:25:45 GMT
Content-Range bytes 0-299907/299908
Content-Type application/x-shockwave-flash
These subsequent requests appear to be sending the Etag in the If-Range header, and are getting 206 responses with the entire content. I've tried setting apache up to unset the Accept-Ranges header and Etags, but the browser will re-request the file in either cases.
Has anyone seen anything like this before and know what to do to get the SWF to cache?
Thanks!