I would like my server to return a header with a custom message. Using the header() function, I can generate the appropriate headers but the message always reverts to some standard string, not the text I provide.
For example, if I put this in my server code
header ($_SERVER['SERVER_PROTOCOL'] . ' 501 test error', true, 501);
I always see 501 Not Implemented in my client. For clients, I've used Postman and also my Xamarin Forms client app. With the latter, I stopped it in the debugger to look at the text returned from httpClient.GetAsynch().
I've also tried having only the first parameter
header ($_SERVER['SERVER_PROTOCOL'] . ' 501 test error');
but I get the same results.
Here's another try. I returned this:
header ($_SERVER['SERVER_PROTOCOL'] . ' Status: 501 test error', true, 501);
But curl on a command line shows this:
HTTP/1.1 200 OK
Connection: Keep-Alive
X-Powered-By: PHP/5.6.40
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Date: Thu, 24 Dec 2020 17:20:54 GMT
Server: LiteSpeed
Alt-Svc: quic=":443"; ma=2592000; v="43,46", h3-Q043=":443"; ma=2592000, h3-Q046=":443"; ma=2592000, h3-Q050=":443"; ma=2592000, h3-25=":443"; ma=2592000, h3-27=":443"; ma=2592000
And, if I take out "Status: ", I get this:
HTTP/1.1 501 Not Implemented
Connection: Keep-Alive
X-Powered-By: PHP/5.6.40
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Date: Thu, 24 Dec 2020 17:28:09 GMT
Server: LiteSpeed
Alt-Svc: quic=":443"; ma=2592000; v="43,46", h3-Q043=":443"; ma=2592000, h3-Q046=":443"; ma=2592000, h3-Q050=":443"; ma=2592000, h3-25=":443"; ma=2592000, h3-27=":443"; ma=2592000
header("HTTP/1.1 …") is a workaround for CGI setups. It's not a HTTP header as such. It's transformed and cleansed by PHP-FPM in most cases: https://github.com/php/php-src/blob/97d2dd0f90b328e771b60634cc377fd20eececbc/sapi/fpm/fpm/fpm_main.c#L307 if sent that way.
This is how you set a Status: header:
header("Status: 429 Begone!");
Now, if your webserver (LiteSpeed) strips out custom messages, then that's that. Nothing PHP can do about it. You'll have to find a server config workaround then. (e.g. Header add with some if= for Apache)
In short, give it a rest with SERVER_PROTOCOL unless your SAPI binding requires it. Upgrading PHP is an option if you run into troubles otherwise. Else you'll have to live with the standardized status message.
After doing some reading, I believe the right way to provide a custom message for an error is to send it in the body, not the header.
So, for example, to provide a custom message "missing weight=x parameter, one can use this code:
http_response_coede (400);
print json_encode (array ('error' => 400,
'message' => 'missing weight=x parameter');
Then, in your client, you parse this json string from the result body.
This might also happen if you use HTTP/2, which no longer has the status text.
Related
I'm trying to get full HTTP answer over a call to file_get_contents function. I'm doing an HTTP POST call, putting credentials to login to my website, process some work, then return a HTTP answer to the caller.
When credentials are not good, i send a HTTP 403 return code, with a message as follow (Raw HTTP response as shown in SoapUI) :
HTTP/1.1 403 Forbidden
Server: Apache-Coyote/1.1
X-UA-Compatible: IE=edge
Pragma: no-cache
Cache-Control: no-cache
Expires: Mon, 05 Jun 2017 09:02:13 GMT
Content-Type: text/plain;charset=utf-8
Content-Length: 515
Date: Mon, 05 Jun 2017 09:02:13 GMT
L'authentification user/password n'est pas autorisée pour le login 'sebastien' depuis l'adresse '127.0.0.1'.
How can i get the message at bottom after calling file_get_contents in php ? Message is not in the headers, so $http_response_header won't work. Is there a way to do so ?
You could create an HTTP stream context to use with file_get_contents() then call stream_get_meta_data() but personally I would just use Curl with CURLOPT_HEADER=true
Note that since the service is returning a 403 rather than a 401, then you're going to need cookies (if it is possible at all) to authenticate. For that you will need Curl.
A HTTP response body should be separated from headers by an empty line: https://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html
Then the body should be available as a result of file_get_contents call.
the HTTP context option ignore_errors is needed to get the content body of the page when an HTTP error code (4XX or 5XX) is returned.
I'm using Apache 2.2 and PHP 7.0.1. I force chunked encoding with flush() like in this example:
<?php
header('HTTP/1.1 200 OK');
echo "hello";
flush();
echo "world";
die;
And I get unwanted characters at the beginning and end of the response:
HTTP/1.1 200 OK
Date: Fri, 09 Sep 2016 15:58:20 GMT
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/7.0.9
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
a
helloworld
0
The first one is the chunk size in hex (10 = A). I'm using Klein as PHP router and I have found that the problem comes up only when the HTTP status header is rewritten. I guess there is a problem with my Apache config, but I wasn't able to figure it out.
Edited: My problem had nothing to do with Apache but Nginx and chunked_transfer_encoding directive. Check the answer below.
This is how Transfer-Encoding: chunked works. The extra characters you're seeing are part of the encoding, rather than the body.
A client that understands the encoding will not include them in the result; a client that doesn't doesn't support HTTP/1.1, and should be considered bugged.
As #Joe pointed out before, that is the normal behavior when Chunked transfer enconding is enabled. My tests where not accurate because I was requesting Apache directly on the server. Actually, when I was experiencing the problem in Chrome I was querying a Nginx service as a proxy for Apache.
By running tcpdump I realized that Nginx was rechunking responses, but only when rewritting HTTP status header (header('HTTP/1.1 200 OK')) in PHP. The solution to sending Transfer-Encoding: chunked twice is to set chunked_transfer_encoding off in the location context of my Nginx .php handler.
I made a curl request to a PHP file on my server from my machine and it returns the following response.
HTTP/1.1 200 OK
Content-Length: 317
Content-Type: application/json
Server: Microsoft-IIS/7.5
Last-Modified: Wed, 19 Feb 2014 11:30:16 GMT
Via: 1.1 SC10100_83_75
Connection: keep-alive
Date: Wed, 19 Feb 2014 12:00:47 GMT
The problem is, this seems to be caching my request and is not returning the latest values. I suspect it is due to the Via header (read that it is about proxies). What is it and how can I remove it?
Looks like via - indicates that you have been routed via a proxy - however - this is information only - you need to make sure you caching headers are being set correctly so that the proxy takes the correct action.
Currently there is no caching headers being set on your request.
If you do not want it to be cached - then set the following header:
Cache-Control: no-cache
See http://www.w3.org/Protocols/HTTP/Issues/cache-private.html
I have a piece of code that has stopped working as I am developing it (but has worked before) . It sends a few headers and then serves an image with readfile().
Here is my action:
public function actionShowMediaFile2() {
if (headers_sent()) {
...
In other words, the very first thing in my action is headers_sent() and this returns true.
Indeed, looking at the GET response in Firebug, there are several headers there. This prevents my sending my own headers and also seems to frustrate the readfile().
My questions:
1.- Does Yii Framework send headers autonomously?
2.- If so, how do I prevent this?
3.- Or is this perhaps not Yii-related?
Here are the headers that appear to be generated autonomously by Yii:
HTTP/1.1 200 OK
Date: Sun, 28 Oct 2012 10:59:05 GMT
Server: Apache
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 22
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/html
Checking with Fiddler, the server response appears to be: ���?�P�����k�[��� This is meaningless to me ...
Is it a good idea to send a checksum with the content of the response? And if so, what is the most common way to calculate the checksum?
Example:
HTTP/1.1 200 OK
Date: Thu, 30 Jun 2011 21:32:20 GMT
Server: Apache
Connection: close
Content-Type: application/json
22
{test:1}
The underlying protocol for HTTP is TCP which already has a checksum mechanism, so I think it would be useless.
If you still need this kind of thing you could calculate a SHA1 signature of the body content and include it as a custom header in your response, something like
HTTP/1.1 200 OK
Date: Thu, 30 Jun 2011 21:32:20 GMT
Server: Apache
Connection: close
Content-Type: application/json
X-Checksum: 40325305549f7a09edb51ff8df9528ffd8434ac6
You could always use the Content-MD5 header (see RFCs 2616 & 1864).
For what? Basically TCP pretty much handles that for you (since it's supposed to be a reliable protocol), so a checksum is less necessary and arguably redundant.
However, if you were to insist on it, I'd simply add an X-Checksum HTTP header of some kind.