Why is gzip compression with Internet Explorer not working? - php

My site is gzipped compressed, and it doesn't load properly in IE. It works fine in FF/Chrome, but in IE, the only thing that pops up is a box asking to download the .gz file which contains the html document for the page.
Is this normal? Do I have to turn off gzip?

Are you sending the correct headers?
You need to send the
Content-Encoding: gzip
header for IE to understand that it is gzipped (Firefox, et al are smart enough to detect this automatically - even though they shouldn't!)
In PHP, you can do this using:-
header('Content-Encoding: gzip');

One thing to add - you should turn off gzip compression for IE6 pre-SP2. Before SP2, IE6 doesn't always read and cache gzipped content properly and you end up with mangled code.
You can identify an IE6 SP2 install by looking for "SV1" in the user-agent string.

I have seen problems when using gzip with Internet Explorer on a page that has flash on it. If your page has flash this may be why. I don't remember the cause and at the time we found it it was causing problems on a live site so we just disabled gzip for Internet Explorer to get around it.

The HTTP headers are the issue. If you have the gzip header along with one of the following:
Vary
Transfer Encoding: Chunked
one or both need to be removed.
This problem is more likely to occur on a computer that is running Apache HTTP Server because Apache HTTP Server can use chunked encoding on any kind of file. This includes static files such as a JavaScript file or a .gif file. When the problem that is described in this article occurs, the content that is stored in the Internet Explorer cache may be truncated or corrupted.
For XML, XHTML, and XSLT files, prevent parsing as text/html or text/xsl:
RewriteCond %{HTTP_ACCEPT} text\/html [OR]
RewriteCond %{HTTP_ACCEPT} text\/xsl [OR]
RewriteCond %{HTTP_ACCEPT} gif|jpeg|png$
ReWriteRule .*\.(xsl|xslt)$ - [F]
And add application/xml as a content type mapping:
AddType application/xml .xsl
References
Internet Explorer may not decompress HTTP content when you visit a Web site
Vary with Care
IE 8 seems unable to display some Wikipedia Pages - application/x-gzip-compressed MIME type
Internet Explorer 6 does not display XHTML strict Web pages correctly

Related

How to update the browser cache on log in / log out?

I am using browser caching to speed up my PHP website. If a user visits a page before logging in and comes back to the page again after logging in, the page doesn't get updated with the contents that are only visible to the logged-in users.
i.e. The "Log in" link on the header menu doesn't change to the "Log out" link if the user visited the page before logging in. And if they visited a new page after logging in, the "Log out" link on the header menu doesn't change to the "Log in" link even after log out.
Here is a sample code
<h2>Contact Form</h2>
<form method="post" action="" onsubmit="">
<?php
if (logged_in() === false) {
?>
Name*
<input type="text" name="name" required />
Email*
<input type="email" name="email" required />
<?php
}
?>
Message*
<textarea name="message" rows="12"></textarea>
<input type="submit" name="contact" value="Send Message" />
</form>
It would be a huge help for me if someone could help me on this issue.
Thanks in advance!
I'll formulate the answer based on the comments we had together.
Check the HTTP headers sent to the browser
The HTTP headers sent by PHP, Apache, NGINX or whatever is running on your server or even passing through (such as reverse proxies like Varnish) will inform the browser what to do with the response.
If you have an Expire or Cache-Control HTTP header that says the page can be cached then effectively the browser won't retrieve the page again once you're logged in.
If you don't want your dynamic pages to be cached you have to set the HTTP header in adequation, ex: Cache-Control: no-cache, no-store, private
This could be done in PHP:
header('Cache-Control: no-cache, no-store, private');
It can also be done later in your web server config for page requests handled by PHP.
By the way, the web server can override what PHP says, so you have to check the output yourself with the browser. Even some other layers such as proxies could alter the HTTP headers.
The Vary HTTP header
If your server responds for a given URL in different ways then it has to inform that the response can vary depending on something. Typically, almost all assets should be compressed to gzip or brotli to save bandwidth. But not all browsers handle brotli compression. So when they do the request, they say what they can handle, ex: accept-encoding: gzip, deflate, br. Here, the browser can handle br = brotli.
The response will then be compressed with brotli to reduce the size. But if a reverse proxy caches it and someone else comes with a browser that doesn't handle brotli then we'll be in trouble. This is why the server should inform all caching layers that the response varies depending on the Accept-Encoding header by returning Vary: Accept-Encoding.
It's also common to have a language detection script for the homepage URL (if you hit the domain without a language path). In this case, we have to send Vary: Accept-Encoding, Accept-Language
For the HTML generated by PHP, it would also be important to say that the response can vary depending on the Cookie header. This is because a page for a specific user could be allowed for caching in private mode, let's say for a minute or more but it should not be messed up with another user's page.
So in PHP, you could do:
header('Vary: Accept-Language, Accept-Encoding, Cookie');
Caching static files and re-deploying them
In terms of performance, it's important to cache static data. So typically this should be done for all assets such as CSS, JS, images, favicons, fonts, etc. They are not dynamic so they can be stored for ages. This can be done by setting Cache-Control: max-age=31536000 for these static files.
If you change a CSS rule, the CSS file won't be re-downloaded by a visitor that already came before. But it's not a problem because your HTML can point to a new URL for this same static file. This can be done by adding a query parameter in the URL of this asset:
<?php
// Increment the version when you change your CSS.
// This can even be done automatically during deployment.
// You could also use the file timestamp or an hash instead.
$css_version = 3;
echo "<link rel=\"stylesheet\" media=\"all\" href=\"/css/theme.css?version=$css_version\" />\n";
Apache config for compressed static files
The idea to have a performance improvement is to compress all CSS and JS files. This can be done by minifying, aggregating and then compressing.
I use NodeJS and made some NPM scripts to do that. There's plenty of info about that on the web
Then you need to add a few rules in your .htaccess file:
RewriteEngine On
# Redirect to HTTPS if we are not in HTTPS:
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Redirect to www.example.com if it's example.com without the www. prefix:
RewriteCond %{HTTP_HOST} !^www\. [NC]
# But don't do it if it's on the local development machine (ex: example.com.local).
RewriteCond %{HTTP_HOST} !\.local$ [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# If the URL looks like only having the language in the path, such as
# https://www.example.com/de or https://www.example.com/EN then rewrite it
# to index.php?lang=XX where XX is the captured language.
# It's case insensitive with [NC] because PHP makes it to lowercase after.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(en|de|fr|es|it)$ index.php?lang=$1 [NC]
# Serve brotli compressed assets if they exist.
RewriteCond %{HTTP:Accept-Encoding} br
RewriteCond %{REQUEST_FILENAME}.br -f
RewriteRule (.*\.(?:css|js|svg|ico))(?:$|\?) $1.br [NC,L]
# Serve gzipped compressed assets if they exist.
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule (.*\.(?:css|js|svg|ico))(?:$|\?) $1.gz [NC,L]
# Set MIME types and avoid double compression done by some Apache modules.
RewriteRule \.css\.(gz|br) - [NC,E=no-gzip:1,E=no-brotli:1,T=text/css]
RewriteRule \.js\.(gz|br) - [NC,E=no-gzip:1,E=no-brotli:1,T=application/javascript]
RewriteRule \.svg\.(gz|br) - [NC,E=no-gzip:1,E=no-brotli:1,T=image/svg+xml]
RewriteRule \.ico\.(gz|br) - [NC,E=no-gzip:1,E=no-brotli:1,T=image/x-icon]
# Tell proxies to cache files separately depending on the Accept-Encoding header
# value sent by the browser. This is because we respond with different content
# encodings (none, brotli, gzip) for the same requested URL. We'll only do that
# for the static files. For pages, we'll let the PHP app set the Vary header.
<FilesMatch "\.(?i:css|js|svg|ico)(?:\.(?:gz|br))?$">
Header append Vary Accept-Encoding
</FilesMatch>
# Send the correct encoding header for *.gz files served instead of the original.
<FilesMatch "\.(?i:css|js|svg|ico)\.gz$">
Header set Content-Encoding gzip
</FilesMatch>
# Send the correct encoding header for *.br files served instead of the original.
<FilesMatch "\.(?i:css|js|svg|ico)\.br$">
Header set Content-Encoding br
</FilesMatch>
# Set a long cache age of 2 years for all static files.
# You have to change the URL if you update the file. Be aware
# that if you upload documents to your website you might have
# to disable this rule in the uploaded folder.
<FilesMatch "\.(?i:br|css|gif|gz|ico|jpe?g|js|png|svg)$">
Header set Cache-Control "max-age=63072000, public"
</FilesMatch>
# PHP can be configured to compress automatically the output if the browser
# accepts gzip compression. According to the documentation it is more effective
# this way than using ob_start('ob_gzhandler') in the PHP code.
# If output_compression is enabled then it will automatically set the
# "Vary: Accept-Encoding" HTTP header.
php_flag zlib.output_compression On
php_value zlib.output_compression_level 9
# Hide PHP's X-Powered-By HTTP header if php.ini doesn't already do it.
Header unset X-Powered-By
Compress PHP's output with gzip
As you see in the Apache config above, we can enable the
zlib.output_compression functionnality of PHP, which will
compress the output if the browser handles it and the Vary
HTTP header will also be automatically set.
But if you cannot enable it via Apache or php.ini then you
can still do the compression yourself in the PHP code with the
output buffering. Just put this piece of code in your PHP before
outputing any text:
// If zlib.output_compression=On then the output will be automatically compressed
// and the "Vary: Accept-Encoding" header will be set too. But if it's not enabled
// then we could compress the page ourselves with PHP's output buffering.
if (preg_match('/^(Off|0)$/i', ini_get('zlib.output_compression'))) {
// If the browser accepts gzip then compress with PHP's output buffering.
if (preg_match('/\bgzip\b/', $_SERVER['HTTP_ACCEPT_ENCODING'])) {
// No need to set the "Vary: Accept-Encoding" header because this is
// already done by ob_gzhandler() called below.
ob_start('ob_gzhandler');
}
}
// Hide the X-Powered-By HTTP header if expose_php=Off cannot be set.
if (function_exists('header_remove')) {
header_remove('X-Powered-By');
} else {
// We cannot remove it but we can set it to empty.
header('X-Powered-By:');
// We'll also try to remove it in the .htaccess file.
}

Apache RewriteRule discards SetInputFilter DEFLATE config directive

I have the following (simplified) folder/file structure:
/.htaccess
/test.php
/api/web/index.php
And the following directive in apache config:
<IfModule mod_deflate.c>
<IfModule mod_filter.c>
SetInputFilter DEFLATE
</IfModule>
</IfModule>
I am sending a POST request with a gzipped body with the appropiated headers:
POST /test.php HTTP/1.1
Host: 192.168.1.248
Authorization: Bearer ed717c077e4bf81201196011adb457731b24e19d
Content-Type: application/json
Content-Encoding: gzip
And I have the following config for the .htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^api/(.*) api/web/index.php/$1 [NC,L]
The issue is, if I post to /test.php, everything works as expected, the body is deflated and I can access decompressed contents just right.
However if I post to something that gets redirected (/api/ or /api/v1/project) the index.php script does not get the body decompressed.
I think it must be related to the RewriteRule directive ignoring the SetInputFilter directive, but, how can I avoid this situation?
I tried to add the SetInputFilter directive directly in the .htaccess without solving the issue (may be it was not in the right place?).
Do you know how can I solve this?
Indeed, there is a problem. The first thing I did to investigate deeper was to log traces of concerned modules (rewrite, filter and deflate).
mod_rewrite logs were OK, nothing suspicious there. To make sure everything was really OK, I looked at the very last version of its source code. And again, nothing suspicious regarding encoding/decoding (nor http request/response headers, more generally).
So I started thinking the problem may come from either filter or deflate module, even if it may also come from somewhere else. To confirm/infirm what I thought, I looked at those modules logs. Quickly, I was able to see a difference between the two test cases: with or without mod_rewrite involved.
mod_rewrite not involved
mod_deflate.c(1421): [client 127.0.0.1:53000] AH01393: Zlib: Inflated 35 to 41 : URL /test.php
mod_filter.c(188): [client 127.0.0.1:53000] Content-Type condition for 'deflate' matched
I took this one as a reference to compare the next case below
mod_rewrite involved
mod_filter.c(188): [client 127.0.0.1:53002] Content-Type condition for 'deflate' matched
Interesting. Actually, it looked like mod_deflate was the problem. I suspected its action was after the right moment. That's the reason why you don't see it in action, here, in this case.
Solution
So far, so good. So... what ? Well, a quick search on the known bugs list of Apache, with keywords mod_deflate too late, gave me by chance what I was searching for. This ticket called mod_deflate adjusts the headers "too late", states the following:
When mod_deflate is used to inflate, it must adjust the request
headers (e.g. it needs to remove the "Content-Length" header and
adjust the "Content-Encoding" header).
Currently mod_deflate adjusts the headers when the request body is
read. But this is too late. For example, if a content generator module
needs to look at the request headers before reading the request body,
the content generator module "sees" the old (unmodified) headers.
mod_deflate should adjust the headers in an early stage, for example
in a fixup hook (ap_hook_fixups).
Eureka ! This is exactly the problem we're facing. Now, good news is there is a patch to overcome this issue. Bad news: it is not yet reviewed/accepted/merged in available versions.
You have the choice:
Apply this patch and recompile your server. It should work because the all thing makes sense. But, be careful... this may introduce other bugs/holes (that's sometimes the case, even when reviewed/accepted)
Wait for it to be included in available versions (maybe a long time, considering the ticket date). By then, use your custom deflate with php.
Update
Just tried to apply the patch and recompile mod_deflate. Looks like it's on the right track: it eats Content-Encoding header. Anyway, Content-Length is still there. Result: no yet decompressed. So, there is still something to do and adapt, but the problem is definitely in that area.
Update 2 (working)
I managed to make it work, finally. Here is the patch I applied to Apache (httpd version 2.4.34):
diff --git a/modules/filters/mod_deflate.c b/modules/filters/mod_deflate.c
index 1428460..cc8c0cb 100644
--- a/modules/filters/mod_deflate.c
+++ b/modules/filters/mod_deflate.c
## -1099,10 +1099,10 ## static apr_status_t deflate_in_filter(ap_filter_t *f,
if (!ctx) {
/* only work on main request/no subrequests */
- if (!ap_is_initial_req(r)) {
+ /*if (!ap_is_initial_req(r)) {
ap_remove_input_filter(f);
return ap_get_brigade(f->next, bb, mode, block, readbytes);
- }
+ }*/
/* We can't operate on Content-Ranges */
if (apr_table_get(r->headers_in, "Content-Range") != NULL) {
Actually, I made mod_deflate handle sub-requests too. I'm not sure it's not gonna break some other modules, but it works for your use case (it's more a proof of concept). Anyway, I proposed my patch on the ticket mentioned above. Here is a screenshot of the result:

How to disable Nginx double gzip encoding when fastcgi backend occasionally serves gzipped with content-encoding?

Is there any clever way to trick nginx to stop gzip if the backend already has set the "content-encoding" header?
Nginx is configured to gzip the output from the php fastcgi backend.
This works great in 99% of the cases.
Except on rare occasion php will send a raw gzipped file and attach a Content-Encoding: gzip header.
Nginx unfortunately will go right ahead and try to gzip that content a second time.
The produces a double content-encoding: gzip content-encoding: gzip header and double-encoded gzipped body.
Most modern browsers can handle this, Firefox, Chrome.
IE8 cannot, Safari mobile cannot, old Safari 5 for Windows cannot - instead they will show garbled gzipped content because it merges the content-encoding headers and only decodes the gzipped body once.
Thanks for any ideas.
Somewhere in nginx.conf where it applies (there should be a fastcgi_params file somewhere) :
fastcgi_param HTTP_ACCEPT_ENCODING "";
This will disable the encoding from the backend.
I hope that still Nginx will serve encoded content after this. (I am not sure)

"no acceptable variant" from MultiViews in Apache

In one deployment of a PHP-based application, Apache's MultiViews option is being used to hide the .php extension of a request dispatcher script. E.g. a request to
/page/about
...would be handled by
/page.php
...with the trailing part of the request URI available in PATH_INFO.
Most of the time this works fine, but occasionally results in errors like
[error] [client 86.x.x.x] no acceptable variant: /path/to/document/root/page
My question is: What triggers this error occasionally, and how can I fix the problem?
Short Answer
This error can occur when all the following are simultaneously true:
Your webserver has Multiviews enabled
You are allowing Multiviews to serve PHP files by assigning them an arbitrary type with the AddType directive, most likely with a line like this:
AddType application/x-httpd-php .php
Your client's browser sends with requests an Accept header that does not include */* as an acceptable MIME type (this is highly unusual, which is why you see the error only rarely).
You have your MultiviewsMatch directive set to its default of NegotiatedOnly.
You can resolve the error by adding the following incantation to your Apache config:
<Files "*.php">
MultiviewsMatch Any
</Files>
Explanation
Understanding what is going on here requires getting at least a superficial overview of the workings of Apache's mod_negotiation and HTTP's Accept and Accept-Foo headers. Prior to hitting the bug described by the OP, I knew nothing about either of these; I had mod_negotiation enabled not by deliberate choice but because that's how apt-get set up Apache for me, and I had enabled MultiViews without much understanding of the implications of that besides that it would let me leave .php off the end of my URLs. Your circumstances may be similar or identical.
So here are some important fundamentals that I didn't know:
request headers like Accept and Accept-Language let the client specify what MIME types or languages it is acceptable for them to receive the response in, as well as specifying weighted preferences for the acceptable types or languages. (Naturally, these are only useful if the server has, or is capable of generating, different responses based upon these headers.) For example, Chromium sends off the following headers for me whenever I load a page:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Apache's mod_negotiation lets you store multiple files like myresource.html.en, myresource.html.fr, myresource.pdf.en and myresource.pdf.fr in the same folder and then automatically use the request's Accept-* headers to decide which to serve when the client sends a request to myresource. There are two ways of doing this. The first is to create a Type Map file in the same folder that explicitly declares the MIME Type and language for each of the available documents. The other is Multiviews.
When Multiviews are enabled...
Multiviews
... If the server receives a request for /some/dir/foo and /some/dir/foo does not exist, then the server reads the directory looking for all files named foo.*, and effectively fakes up a type map which names all those files, assigning them the same media types and content-encodings it would have if the client had asked for one of them by name. It then chooses the best match to the client's requirements, and returns that document.
The important thing to note here is that the Accept header is still being respected by Apache even with Multiviews enabled; the only difference from the type map approach is that Apache is inferring the MIME types of files from their file extensions rather than through you explicitly declaring it in a type map.
The no acceptable variant error is thrown (and a 406 response sent) by Apache when there exist files for the URL it has received, but it's not allowed to serve any of them because their MIME types don't match any of the possibilities provided in the request's Accept header. (The same thing can happen if there is, for example, no variant in an acceptable language.) This is compliant with the HTTP spec, which states:
If an Accept header field is present, and if the server cannot send a response which is acceptable according to the combined Accept field value, then the server SHOULD send a 406 (not acceptable) response.
You can test this behaviour easily enough. Just create a file called test.html containing the string "Hello World" in the webroot of an Apache server with Multiviews enabled and then try to request it with an Accept header that permits HTML responses versus one that doesn't. I demonstrate this here on my local (Ubuntu) machine with curl:
$ curl --header "Accept: text/html" localhost/test
Hello World
$ curl --header "Accept: image/png" localhost/test
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>406 Not Acceptable</title>
</head><body>
<h1>Not Acceptable</h1>
<p>An appropriate representation of the requested resource /test could not be found on this server.</p>
Available variants:
<ul>
<li>test.html , type text/html</li>
</ul>
<hr>
<address>Apache/2.4.6 (Ubuntu) Server at localhost Port 80</address>
</body></html>
This brings us to a question that we haven't yet addressed: how does mod_negotiate determine the MIME type of a PHP file when deciding whether it can serve it? Since the file is going to be executed, and could spit out any Content-Type header it likes, the type isn't known prior to execution.
Well, by default, the answer is that MultiViews simply won't serve .php files. But chances are that you followed the advice of one of the many, many posts on the internet (I get 4 on the first page if I Google 'php apache multiviews', the top one clearly being the one the OP of this question followed, since he actually commented upon it) advocating getting around this using an AddType directive, probably looking something like this:
AddType application/x-httpd-php .php
Huh? Why does this magically cause Apache to be happy to serve .php files? Surely browsers aren't including application/x-httpd-php as one of the types they'll accept in their Accept headers?
Well, not exactly. But all the major ones do include */* (thus permitting a response of any MIME type - they're using the Accept header only for expressing preference weighting, not for restricting the types they'll accept.) This causes mod_negotiation to be willing to select and serve .php files as long as some MIME type - any at all! - is associated with them.
For example, if I just type a URL into the address bar in Chromium or Firefox, the Accept header the browser sends is, in the case of Chromium...
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
... and in the case of Firefox:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Both of these headers contain */* as an acceptable content type, and thus permit the server to serve a file of any content type it likes. But some less popular browsers don't accept */* - or perhaps only include it for page requests, not when loading the content of a <script> or <img> tag that you might also be serving through PHP - and that's where our problem comes from.
If you check the user agents of the requests that result in 406 errors, you'll likely see that they're from relatively unusual user agents. When I experienced this error, it was when I had the src of an <img> element pointing to a PHP script that dynamically served images (with the .php extension omitted from the URL), and I first witnessed it failing for BlackBerry users:
Mozilla/5.0 (BlackBerry; U; BlackBerry 9320; fr) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.714 Mobile Safari/534.11+
To get around this, we need to let mod_negotiate serve PHP scripts via some means other than giving them an arbitrary type and then relying upon the browser to send an Accept: */* header. To do this, we use the MultiviewsMatch directive to specify that multiviews can serve PHP files regardless of whether they match the request's Accept header. The default option is NegotiatedOnly:
The NegotiatedOnly option provides that every extension following the base name must correlate to a recognized mod_mime extension for content negotiation, e.g. Charset, Content-Type, Language, or Encoding. This is the strictest implementation with the fewest unexpected side effects, and is the default behavior.
But we can get what we want with the Any option:
You may finally allow Any extensions to match, even if mod_mime doesn't recognize the extension.
To restrict this rule change only to .php files, we use a <Files> directive, like this:
<Files "*.php">
MultiviewsMatch Any
</Files>
And with that tiny (but difficult-to-figure-out) change, we're done!
The answer given by Mark Amery is almost complete, however it is missing the sweet spot and does not address the 'no extension is given in the request thus negotiation fails with alternatives.
You can resolve this error by adding the follwing config-snippets:
Your PHP config should be something like this:
<FilesMatch "\.ph(p3?|tml)$">
SetHandler application/x-httpd-php
</FilesMatch>
Do NOT use AddType application/x-httpd-php .php or any other AddType
And your additional config should be like this:
RemoveType .php
<Files "*.php">
MultiviewsMatch Any
</Files>
If you do use AddType you will get errors like this:
GET /index/123/434 HTTP/1.1
Host: test.net
Accept: image/*
HTTP/1.1 406 Not Acceptable
Date: Tue, 15 Jul 2014 13:08:27 GMT
Server: Apache
Alternates: {"index.php" 1 {type application/x-httpd-php}}
Vary: Accept-Encoding
Content-Length: 427
Connection: close
Content-Type: text/html; charset=iso-8859-1
As you can see, it does find index.php, however it does not use this alternative as it cannot match the Accept: image/* to application/x-httpd-php. If you request /index.php/1/2/3/4 it works fine.
The reason for this I found in the source code of the mod_negotiation module. I was trying to find out why Apache would work if the .php type was 'cgi' but not otherwise (hint: application/x-httpd-cgi is hardcoded..). While in the source i noticed that apache would only see the file as a match if the Content-Type of that file matched the Accept header, or if the Content-Type of that file was empty.
If you use the SetHandler than apache won't see the .php files as application/x-httpd-php, but unfortunatly, many distro's also define this in the /etc/mime.types file. So to be sure, just add the RemoveType .php to your config if this bug is bothering you.

This page is downloaded when the site is visited

Try to open it with Safari or IE
webtelevideo.com
Chrome has no problems
What does it depend?
The server does not identify the page as HTML:
Content-Type: text-html;charset=UTF-8
The appropriate MIME type is text/html, not text-html. It's a serious server misconfiguration.
as Álvaro G. Vicario stated, the w3c validator indicates between other things:
The document is being served with the text-html Mime Type which is not a registered media type for the Document Type. The recommended media type for this document is: application/xhtml+xml
i suggest you to valide your site structure through http://validator.w3.org/
I think it's because of the apache configuration try adding
AddType application/x-httpd-php .php
Got absolutely no idea what exactly you're position is with this... Are you the developer? I assume not, however, unable to load in IE, until I changed the URL to: http://www.webtelevideo.com/Programmi-TV/Martin - May work with other things, but up to you to check.

Categories