Prevent mod_deflate on zip file served by PHP
Asked Answered
O

5

8

I'm having some trouble prevent mod_deflate from jumping in on this scenario:

  1. user running CodeIgniter (or any other framework that re-directs to index.php)
  2. mod_deflate is active
  3. zip file is served by a CodeIgniter controller (headers + readfile)

The thing is that Apache always detects the content as being php and therefor something like the lines bellow wont work as the server assumes the ZIP file as being a PHP one.

<FilesMatch "\.(xml|txt|html|php)$">
   SetOutputFilter DEFLATE
</FilesMatch>

Any ideas on how I can have Apache distinguish from an HTML file or a ZIP file both generated by the same index.php framework file.

Edit:
apache log

[Mon Jun 20 02:14:19 2011] [debug] 
mod_deflate.c(602): [client 192.168.0.5] 
Zlib: Compressed 50870209 to 50878224 : URL /index.php, 
referer: http://demo.dev/

Edit:
CI controller that serves the zip

header('Content-Type: application/zip');
header('Content-Transfer-Encoding: binary');
header("Content-Length: " . filesize($file_location)); 
header('Content-Disposition: attachment; filename="' . $file_title . '"'); 
readfile($file_location);
Oklahoma answered 20/6, 2011 at 0:25 Comment(2)
Can you show the code that sets the headers in CodeIgniter?Stammel
@Stammel updated the question. Thks!Oklahoma
O
6

Even tough all answers should have been perfectly valid in a reasonable scenario (and were actually tested prior to making the question) the reason to why I've been unable to instruct Apache to deflate a file by MIME-Type remains unknown.

I was able to have it work as desired by forcing the following instructions into the script

apache_setenv('no-gzip', 1);
ini_set('zlib.output_compression', 0);

I do understand that this is a hot patch and is not addressing the problem's root but so far that will have to suffice. As there are others who may hit the same flag, the above code stays here for reference in what is a dirty fix.

Oklahoma answered 22/6, 2011 at 20:3 Comment(0)
C
2

You can either:

  • use the deprecated AddOutputFilterByType and specify only the content types you do want to filter; or
  • use the more powerful mod_filter. In FilterProvider you can provide a rule that excludes the filter when the zip content type (application/zip) is found in the response headers.
Checkerwork answered 20/6, 2011 at 0:37 Comment(4)
this single line AddOutputFilterByType DEFLATE text/html is good enough to have Apache deflating my fake zip. Doesn't deflate none of the other files though (so it does works more or less as it should).Oklahoma
@Oklahoma It works here. Make sure you don't have mod_deflate configuration elsewhere. For example, some distros include extra configuration in /etc/apaches/mods-enabled/deflate.confCheckerwork
thks. Don't have any fancy modules (CentOS) but gonna clean up my httpd.conf tomorrow and see if I can identify the culprit. Thanks.Oklahoma
installed a vanilla version of Fedora 15 only to experience the exact same problem. Tried to reproduce your setup using different alternatives but none worked. Eventually, and building upon your great examples, was able to find the following command: @apache_setenv('no-gzip', 1); that was a clear winner. So if you could only update your answer to include the command I'd be more than glad to accept it. Thanks for all the trouble.Oklahoma
D
2

You can make use of mod_rewrite to change the mime-type of the request on the Apache level:

# Serve .zip request as zip-files
RewriteRule \.zip$ - [T=application/zip,E=no-gzip:1]

Place it above the rules of the framework, however this needs to make DEFLATE as well depended on mime-type and not file-extension as you do with <FilesMatch>.

Probably it works well together with

AddOutputFilterByType DEFLATE text/html

instead of the <FilesMatch> Directive.

Edit: Added the L flag which should be used in .htaccess context and additionally turned DEFLATE off via the no-gzip environment variable.

Demetria answered 20/6, 2011 at 0:45 Comment(8)
@Demetria Apache is still treating the file as a php one. The actual path is: example.com/files/myfile.zip but somewhat Apache knows and is treating it as a .php file.Oklahoma
Because it's a .php on disk (resolved file for apache). You need to make DEFLATE dependent on mime-type. I just edited my answer.Demetria
@hakre, unfortunately no luck. Gonna edit my question to reflect my current .htaccess file and httpd.conf.Oklahoma
@hakre, if I add the [L] the whole thing stops as it really tries to serve the file and it doesn't exist. Log entry goes as follows: File does not exist: /home/demo.dev/www/file. The www/file is CI's controller responsible for serving the ZIP file.Oklahoma
Okay, L was a bad idea. But as I read about the no-gzip environment variable I thought it's a good idea to set it.Demetria
The rewrite rule should be unnecessary as PHP is already setting the correct content-type.Checkerwork
You misunderstood the intention. It's mime-type and it's for the request processing within apache, not (only) for the response HTTP content-type header.Demetria
@Checkerwork @hakre, I must get some sleep so I'm gonna leave this as it is and tomorrow will get back to you guys. Thanks.Oklahoma
S
1

Try this (since your urls appear to end in .zip it might work for you):

<FilesMatch "\.(xml|txt|html|php)$">
   SetEnvIf Request_URI "\.zip$" no-gzip
   SetOutputFilter DEFLATE
</FilesMatch>
Stammel answered 20/6, 2011 at 1:35 Comment(1)
thks but unfortunately no luck. If I do a FileMatch only to CSS and JS it will work... as soon as I put php into the cradle... stops working.Oklahoma
M
0

Instead of using

<FilesMatch "\.(xml|txt|html|php)$">
   SetOutputFilter DEFLATE
</FilesMatch>

Use this configuration for setting compression rules.

AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml application/x-javascript application/javascript

This way, your output will be compressed only if content-type matches with above directives.

CI controller that serves the zip is already sending correct content-type header, so this will not get compressed.

header('Content-Type: application/zip');
Medovich answered 23/7, 2012 at 6:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.