My browser shows page with incorrect encoding. I have figured out that the server sends headers
HTTP/1.1 200 OK
Date: Thu, 02 Jan 2014 18:21:11 GMT
Server: Apache/2.2.4 (Win32) mod_ssl/2.2.4 OpenSSL/0.9.8k PHP/5.2.12
X-Powered-By: PHP/5.2.12
Content-Length: 4
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=windows-1251
but php script doesn't contain encoding set command. I even added exit on the script top and browser still getting Content-Type: text/html; charset=windows-1251. How so?
First look at default_charset in php.ini. Leave it empty if you do not want a Content-Type header.
In PHP one always can do a header('Content-Type', 'text/html; charset=UTF-8');.
Apache also has a config for Content-Type, but the error probably lies at the PHP side.
Related
Maybe it's the jetlag, but I'm failing to make PHP/HHVM give me the Content-Type header when I need it.
I've deployed the full stack (MySQL, HHVM, Nginx) on a Vagrant machine and I've managed to reproduce the issue on a test script:
<?php
$file='/usr/share/doc/iptables/html/NAT-HOWTO.html'; # random test file
header('Content-Length: ' . filesize($file));
echo(readfile($file));
?>
If you examine the headers with curl:
hostname:~ jsimpson$ curl -I http://vagrant/test.php
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Tue, 16 Sep 2014 22:09:25 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 2592
Connection: keep-alive
X-Powered-By: HHVM/3.2.0
Content-Encoding: none;
We have a content length header. However if we hit the same URL from Chrome, and get the headers from the Dev tools:
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Tue, 16 Sep 2014 22:14:41 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: HHVM/3.2.0
Content-Encoding: gzip
No Content-Length header. I've also packet sniffed this to verify that the header isn't sent. I can switch to PHP FPM and it sends the header.
I reproduced the issue by hitting the server with:
curl -H 'Accept-Encoding: gzip,deflate' --compressed -v http://foo/bar
HHVM enables compression by default. Disabling that gave me the header back.
Everything was awesome after adding this to /etc/hhvm/server.ini
hhvm.server.gzip_compression_level = 0
I stumbled upon this issue/feature. Not running HHVM though. Pure nginx + PHP-FPM.
The thing is, if your PHP app calculates and sets Content-Lenght header field, and your nginx is configured to gzip content, it will just ditch this information and replace it by Chunked transfer encoding and GZIP headers.
So do not set GZIP to a very small buffers, default is 20 bytes which does quite the opposite (end result is larger then before GZIP compression).
I set it like this:
gzip_min_length 1024;
I have installed php + apache. From one php file i send some headers using the header() function.
header("HTTP/1.1 200 OK");
header("Connection: Keep-Alive");
header("Content-Type: video/mp2t");
But i don't want apache to send its own headers. If i execute the PHP File i get these headers:
HTTP/1.1 200 OK
Date: Tue, 15 Apr 2014 10:26:57 GMT
Server: Apache/2.2.22 (Debian)
X-Powered-By: PHP/5.4.4-14+deb7u8
Connection: Keep-Alive, Keep-Alive
Keep-Alive: timeout=5, max=100
Transfer-Encoding: chunked
Content-Type: video/mp2t
How can i prevent apache from sending its own headers?
I have created two files, one on my wamp server (localhost), and one on my ovh.com private space. Both files contains only this content :
echo $search = file_get_contents('https://prod.api.pvp.net/api/lol/euw/v1.3/game/by-summoner/19319907/recent?api_key=6fa73a35-6477-412d-97a6-b6739cb6cf1b');
On my server, there is some wrong characters, like â, þ or ¬, etc ...
How it can happends, and how can I resolve this ?
Edit: It's not about files ! It's about servers, cause files are exactly the same !
You can check the good one here : http://www.dietadom.fr/test.php, and the bad one here : http://82.124.50.144/test.php
headers from requests to both those scripts:
Working:
curl -I http://www.dietadom.fr/test.php
HTTP/1.1 200 OK
Set-Cookie: clusterBAK=R1564861669; path=/; expires=Wed, 19-Mar-2014 16:38:43 GMT
Date: Wed, 19 Mar 2014 15:19:31 GMT
Content-Type: text/html
Connection: keep-alive
Set-Cookie: cluster=R1649376954; path=/; expires=Wed, 19-Mar-2014 16:32:22 GMT
Server: Apache
X-Powered-By: PHP/5.4.24
Pragma: no-cache
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Vary: Accept-Encoding
Not Working:
curl -I http://82.124.50.144/test.php
HTTP/1.1 200 OK
Date: Wed, 19 Mar 2014 15:19:48 GMT
Server: Apache/2.4.4 (Win64) OpenSSL/1.0.1d PHP/5.4.12
X-Powered-By: PHP/5.4.12
Content-Type: text/plain; charset: UTF-8
Most likely the default character encoding header provided by your two servers is different. You can fix this by changing the server configurations to make sure they both have the default. Or you can modify your script to over-ride this, adding a content encoding header will make this consistent.
If you modify your PHP file for UTF-8 plain test content the line would be
header('Content-type: text/plain; charset=UTF-8');
Your source URL is responding with:
Content-Type: application/json; charset=UTF-8
retrieved using
curl -I https://prod.api.pvp.net/api/lol/euw/v1.3/game/by-summoner/19319907/recent?api_key=6fa73a35-6477-412d-97a6-b6739cb6cf1b
hence how I know it's UTF-8 encoded.
EDIT
Having checked against your server I can see the header for an error page of:
curl -I http://82.124.50.144/404.html
HTTP/1.1 403 Forbidden
Date: Wed, 19 Mar 2014 17:24:17 GMT
Server: Apache/2.4.4 (Win64) OpenSSL/1.0.1d PHP/5.4.12
Content-Type: text/html; charset=iso-8859-1
The last line showing me the default charecter encoding is iso-8859-1, which means that the utf-8 data from your source is being transmitted with the wrong encoding. Adding the correct header line to your script should fix the issue.
You could change your apache server configuration by adding AddDefaultCharset UTF-8 as well.
I'm sure that your issue is with character encoding, so you should look into that.
I have an HTML page that shows a progress bar as it steps through a process. It uses flush() to send the data to the browser. I'm trying to get this to work in a Zend process which I'm short circuiting by specifically sending a header, content, then ending the process with an exit command.
The HTML page displays correctly (progress bar steps through being done). The Zend/PHP page only shows the finished page (not the steps). I'm assuming this is a header problem since the method (flush()) is identical.
In Chrome, the header for the HTML page comes up as:
HTTP/1.1 200 OK
Date: Fri, 27 Jul 2012 14:38:07 GMT
Server: Apache/2.2.16 (Unix) mod_ssl/2.2.16 OpenSSL/0.9.8r DAV/2 PHP/5.3.2
X-Powered-By: PHP/5.3.2
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html
And the header for the Zend/PHP page comes up as:
HTTP/1.1 200 OK
Date: Fri, 27 Jul 2012 14:44:13 GMT
Server: Apache/2.2.16 (Unix) mod_ssl/2.2.16 OpenSSL/0.9.8r DAV/2 PHP/5.3.2
X-Powered-By: PHP/5.3.2
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-cache
Pragma: no-cache
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
The only header information I'm specifying in the PHP is:
header('Content-Type: text/html; charset=utf-8');
I'm using this code from this page: http://w3shaman.com/article/php-progress-bar-script
Any help would be appreciated. Thanks.
Call ob_flush() before you call flush() as Zend could have output buffering activated.
Mathieu had the fix. Adding ob_flush() before flush() in the Zend/PHP page fixed the problem. I'm not sure if Zend is activating output buffering as suggested or not.
I'm using charles proxy to debug a zend amf response. The headers are coming back as:
HTTP/1.1 200 OK
Date: Sat, 29 Aug 2009 10:04:32 GMT
Server: Apache/2.2.11 (Unix) mod_ssl/2.2.11 OpenSSL/0.9.8k DAV/2 PHP/5.3.0
X-Powered-By: PHP/5.3.0
Content-Length: 33
Content-Type: text/html; charset=utf-8
Should the content type be application/x-amf.
Does apache need something special to do this?
Thanks
The headers should be x-amf. Something in my php script was corrupting the output. The charles proxy item should have an 'A' icon. I didn't have to add anything in Apache.