I just realized my apparent problem (and the "solution" Content-Encoding: none
from the StackOverflow question I referred to in my initial question, below) may very well have simply been due to a misunderstanding how things are actually working. Please review my addendum at the end.
In a PHP application I'm building, I'm trying to manage my own content-encoding negotiation and compression.
When I set the response header Content-Encoding
from within PHP to either gzip
or deflate
, Apache respects this. However, when I set it to identity
Apache ignores this and compresses the response.
It only seems to respect the non-standard Content-Encoding: none
, as I found in some of the answers and their comments in this Stack Overflow question.
I'm therefore currently setting it to none
, from within PHP and then altering the header through .htaccess
with:
Header edit Content-Encoding ^none$ identity
... but this really feels like an ugly hack. I wish I didn't have to do this, in case I ever switch servers, for instance.
Is this a known issue and/or is this non-standard behavior documented somewhere? I can't seem to find any concrete documentation about this.
I've also searched Apache's bug tracker, but was only able to find a tangentially related bug report, about Apache not respecting Accept-Encoding
header values.
Addendum
When I disable Apache's mod_deflate in .htaccess
with (there are other options available to do this as well):
SetEnv no-gzip 1
... and set Content-Encoding: identity
from within PHP, Apache keeps this header and the content intact, just fine.
Therefore, here's what I think is actually happening:
It's not that Content-Encoding: none
is some official signal to Apache to disable compression (Content-Encoding: bogus
, for instance, produces the same result), which would explain why I couldn't find any documentation about it.
Rather, it is simply a value that is not an RFC standard. Therefore mod_deflate leaves the content untouched, assuming it's some non-standard encoding it doesn't want to interfere with.
So, when I set Content-Encoding: identity
from within PHP, mod_deflate probably recognizes this as a valid RFC standard, signifying that content has not been compressed yet and, since mod_deflate is enabled, goes ahead and compresses it.
Furthermore, if I set Content-Encoding
to gzip
or deflate
, for instance, mod_deflate probably either leaves it untouched completely, or tries to compress it anyway, but the compression algorithm recognizes that the content was already compressed.
Can somebody perhaps confirm whether this is a correct interpretation of what is actually going on?
So, a possible solution would be to either disable mod_deflate for some selected files/paths that my PHP application manages, or perhaps even disable mod_deflate altogether/site-wide/server-wide if all my content was already compressed in some other way.
So, I've managed to solve my issues, by taking into account the assumptions I've outlined in my question, which appear to be correct. But not without a struggle.
On trying to implement it for only PHP-generated content, I ran into some other issues, which I'll describe here:
I initially had the following rewrite rules in my
.htaccess
:With
RewriteRule
flags, you should be able to set environment variables. So, I figured I should be able to set theE=no-gzip:1
flag on merely the lastRewriteRule
, by doing:And even though the earlier mentioned
worked fine, the
RewriteRule
flag just wouldn't catch on. Then I looked into all sorts of related questions on Stack Overflow, such as this one this one. But they didn't offer satisfactory solutions.I then momentarily resorted to setting the environment variable from within PHP with
apache_setenv( 'no-gzip', 1 );
, which did the trick. But that just didn't feel right and also made me wonder why the damnRewriteRule
flag wouldn't work just as well.I then decided to do a
var_dump( $_SERVER )
, to see whether theRewriteRule
flag was actually set, only to be confronted with an old nemesis I had forgotten about:The damn
REDIRECT_
that gets prepended to environment variables when rewriting.I was under the impression that the
L
flag on my lastRewriteRule
should mean stop rewriting, but apparently I had misinterpreted this rule and it's conditions:Since
RewriteRule ^.*$ index.php [NC,E=no-gzip:1,L]
rewrites toindex.php
, which is a regular file (-s
), the aforementioned conditions and rule still kick in.Now that I've changed that rule to
everything is finally working as desired!