Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set charset in ErrorDocument messages

I have an .htaccess file that looks like this:

AddDefaultCharset utf-8
AddCharset utf-8 .html
Order Allow,Deny 
ErrorDocument 403 "Error 403 - Esta ubicación no es pública"

The file itself is encoded as UTF-8. However, Apache insists on declaring ISO-8859-1 and the error message is mangled:

HTTP/1.1 403 Forbidden
Date: Fri, 29 Nov 2013 10:06:25 GMT
Server: Apache/2.4.6 (Win32) OpenSSL/1.0.1e PHP/5.5.6
Content-Length: 42
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1

If I manually change encoding to UTF-8 in my browser text looks correct.

Site has been granted all permissions:

<VirtualHost *:80>
    ServerName tmp
    DocumentRoot "D:/tmp"

    <Directory "D:/tmp">
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

... and there's nothing relevant in Apache logs.

What bit am I missing?

like image 418
Álvaro González Avatar asked Nov 29 '13 10:11

Álvaro González


1 Answers

Terrific question!! I must say. I had to dig all my resources and read lot of manuals to find the reason for this behavior.

It appears to be a known behavior but not very well covered in official manuals. Finally, I found one reference of it in this Apache manual:

suppress-error-charset

Available in versions after 2.0.54

When Apache issues a redirect in response to a client request, the response includes some actual text to be displayed in case the client can't (or doesn't) automatically follow the redirection. Apache ordinarily labels this text according to the character set which it uses, which is ISO-8859-1.

However, if the redirection is to a page that uses a different character set, some broken browser versions will try to use the character set from the redirection text rather than the actual page. This can result in Greek, for instance, being incorrectly rendered.

Setting this environment variable causes Apache to omit the character set for the redirection text, and these broken browsers will then correctly use that of the destination page.

And that is exactly the behavior you're seeing that charset=iso-8859-1 is coming in the headers.


How to fix:

Have your .htaccess code like this:

# set desired env variable to suppress iso-8859-1 charset
SetEnvIf Host ^ suppress-error-charset

# set desired 403 message with desired charset 
ErrorDocument 403 "<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'></head><body>Error 403 - Esta ubicación no es pública</body></html>"

Please note that SetEnvIf Host ^ is a condition that will always hold true hence suppress-error-charset will always be set. I have tested just with those 2 lines in my .htaccess and got correct error message displayed in my browser.

like image 147
anubhava Avatar answered Nov 01 '22 06:11

anubhava