.php files are not compressing, while GZIP is set in .htaccess - php

According to checkgzipcompression all my .js and .css are correctly GZIP compressed.
Except for my php webpages:
www.website.nl/webpages.php seem not gzipped, resulting in a 75% increase in "wasted" data transfer. My .htaccess file ends with the following below. What needs to be changed here to get GZIP compression for my php webpages to work properly? (Excluding the .php files from the /includes/ folder ofcourse since those are not "transferred to the browser" and are processed internally so they need no compression). Thanks!
# compress speficic filetypes
<IfModule mod_deflate.c>
<FilesMatch "\.(js|css|txt|php)$">
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>

Pages served in the browser with .php extension are considered html. PHP uses Content-Type "text/html" as default.
I would say, find out what's your web server, and then find out the correct compression method for it.
Good luck!

Related

Apache2 mod autoindex does not read .php

Apache2's mod autoindex allows to include a header and a readme files, that I configured this way in the directory's .htaccess:
ReadMeName footer.html
HeaderName header.php
For some obscure reason, the header file is not read if it is a .php. I renamed it to header.html and in the htaccess too:
HeaderName header.html
and it worked perfectly (even when in .html it included <?php ?> markups)
Why does apache do hat, and is there a way to fix it?
Per the manual on mod_autoindex / HeaderName directive:
Filename must resolve to a document with a major content type of
text/* (e.g., text/html, text/plain, etc.). This means that filename
may refer to a CGI script if the script's actual file type (as opposed
to its output) is marked as text/html...
...while a .php file's content-type is defined as application/x-httpd-php, even if the script's output is by default text/html. However, there's hope yet. You can actually get the PHP parsed by adding the following combo into your .htaccess before your HeaderName directive:
AddHandler application/x-httpd-php .php
AddType text/html .php
Neither of the two on their own will do the job. I presume that here Apache (tested on 2.4) first sets a handler and parses the .php file, and then agrees to understand that the output type is majorly text/html indeed. I'm calling this quirky, but it's working!

Why GZip compression doesn't work for .css and .js but only on .php file extensions

A strange problem occurs when GZipping files on our (updated?migrated) shared hosting server.
Examine these two identical files in the the includes folder /_inc/ with exactly the same contents (php code) with the purpose of collecting, minifying and generating a single Gzipped css file from various source cdd files. Now, files ending with php seem to get GZipped nicely, however files ending with extension css and js do not get GZipped yet...
/_inc/all.css (24 kbyte, extension won't let herself Gzipped)
/_inc/allcss.php (5 kbyte! extension lets herself Gzipped)
Changing the extension from css to php makes the file to compress as you see, BUT browsers still prefer the css extension for best caching...
Q: Why is it, that only files ending with php are Gzipped, and php files ending with css and js extension are not Gzipped? How to achieve Gzipping for css and js extensions as well? How can I set the main .htacces or php.ini to Gzip all .php, .css, .js files as well?
/.htaccess (root .htaccess file portion for compression)
## interpreted extensions as php
AddType application/x-httpd-php .php
AddType image/svg+xml svg svgz
AddEncoding gzip svgz
#AddType text/css css
#AddType text/javascript js
## compress speficic filetypes BUTTTT doesn't work anymore since server upgrade!
## with or without the code below the result is the same!
<IfModule mod_deflate.c>
<FilesMatch "\.(js|css|eot|ttf|svg|xml|php|txt)$">
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>
/_inc/.htaccess (.htacces file that makes css and js files interpret as php files)
AddType application/x-httpd-php-cgi .js .css
Action application/x-httpd-php-cgi /cgi-php/php-cgi
php.ini (from the Apache server running PHP 5.3.28)
session.gc_maxlifetime = 1440
session.name = PHPSESSID
session.save_handler = files
session.serialize_handler = php
zlib.output_compression = On
zlib.output_handler = ob_gzhandler
allow_call_time_pass_reference =
implicit_flush = Off

Browser Not Interpreting .css File when using AddType .css in .htaccess

I have a very interesting problem related to Deflate Compression, Apache (htaccess), and CSS files.
I have two CSS files on my server. One is called styles.php and has dynamic values added based on database values through mod_rewrite in the styles/ directory (it is rewritten from styles.php to site.css and there is a text/css header at the beginning of the file). I also have a regular old css file with static content that doesn't change in the same directory called styles.css.
I've wanted to add compression to my site so I added the following line to start compressing my css and js files. I added this to the root_directory for my website.
<ifModule mod_deflate.c>
<filesMatch "\.(js|css)$">
SetOutputFilter DEFLATE
</filesMatch>
</ifModule>
Well initially that didn't work. So I changed this line in the root htaccess file from this to the next thing. (this code below is located at the top of the file)
AddType application/x-httpd-php5 .html .php
AddType application/x-httpd-php5 .html .php .js .css
Then my js and one of the css files started to be compressed (verified with YSlow.....yay!). The odd thing was the css file that was being rewritten was being compressed (the styles.php file) but the styles.css file (the static one) was no longer being read by the browser. As soon as I deleted ".css" from that AddType line the browser started reading the file again and my css returned to normal, however it was no longer being compressed through apache.
Any thoughts on why a static css file is not being read by the browser if I add the type? I tried it with just text/css instead of .css and it was not compressing the file (but the browser interpreted it).
UPDATE:
I added this to the root htaccess file. We have compressed, interpretted sweetness now.
<filesMatch "\.css$">
FileETag None
<ifModule mod_headers.c>
Header set Content-type "text/css"
</ifModule>
</filesMatch>
When you run a CSS file through the PHP pre-processor, PHP will automatically output it as a text/html file, via default headers, since you're not manually specifying it. So really, your browser is receiving a file with a .css extension which has headers claiming it's an HTML file, so it's trying to interpret it as HTML rather than CSS.
If your CSS file actually needs to be run as PHP and there is PHP in it, you need to re-issue the appropriate file type so when it output, it's still CSS:
<?php
header('Content-type: text/css');
?>
You can't just send a CSS file through PHP and expect it to work exactly the same. If you're not actually pre-processing it with PHP, then you shouldn't be sending it through there.
As for the deflation issue, I could never actually get mod_deflate to work personally (no idea why). I had to use mod_gzip instead.

Prevent mod_deflate on zip file served by PHP

I'm having some trouble prevent mod_deflate from jumping in on this scenario:
user running CodeIgniter (or any other framework that re-directs to index.php)
mod_deflate is active
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);
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.
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.
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.
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>
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');

Do I need PHP to serve an HTTP Header with the correct content-type for RSS/ATOM?

I want to send my RSS/Atom feeds with the correct Content-type header, can I do this without access to PHP or any other server-side language? The goal is for the browser to treat the file as a feed and not just a plain XML file.
You can tell the server to send that specific file with a specific media type.
Apache has the AddType and ForceType directive to do that:
# send all .atom files with application/atom+xml
AddType application/atom+xml .atom
# send only foo.bar as application/atom+xml
<FilesMatch ^foo\.bar$>
ForceType application/atom+xml
</FilesMatch>
You can use <Directory>, <DirectoryMatch>, <Files>, <FilesMatch>, <Location> and <LocationMatch> sections to restrict the directives only to specific directories, files or URL paths. But be aware of the context they are allowed in. Only <Files> and <FilesMatch> can be used in a .htaccess file.
If your RSS/ATOM feed has a specific extension, or is served from a specific dorectory, I suppose you could use Apache's AddType directive, so Apache would serve your RSS feeds with the right content-type :
The AddType directive maps the given
filename extensions onto the specified
content type. MIME-type is the MIME
type to use for filenames containing
extension.
Not tested, but I suppose something like this, either in your Apache's main configuration file, or in a .htaccess file, might do, for RSS feeds :
AddType application/rss+xml .rss
And, for ATOM, something like this, probably :
AddType application/atom+xml .atom

Categories