1

I mostly see the response code being set like this:

header('HTTP/1.1 404 Not Found');

But the below also seems to work fine

header('HTTP/1.1 404');

wanted to know if it absolutely necessary to specify the status code description like OK, Not Found etc. I would like to avoid specifying since my status code is a variable and I would need to maintain a table of some sort mapping every single status code to the status code description. Please find the the code I am using below.

$status = 404; //or any other response code
$protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');
header($protocol." $status");

Appreciate any help.

  • 1
    Maybe https://stackoverflow.com/questions/4797274/how-to-send-a-status-code-in-php-without-maintaining-an-array-of-status-names ? – Syscall Jan 20 '21 at 13:18
  • The reason phrase (the thing after statuscode-and-whitespace) is not optional, but can be empty. – Julian Reschke Jan 20 '21 at 13:36
  • @Syscall that page does have info on various ways to set the status code, However, I have a more specific question and want to understand if there are any pitfalls in implementing it this way (because I haven't come across this form in documentation) – applecodervinegar Jan 20 '21 at 14:04
  • @JulianReschke apologies, but that statement seems contradictory? if you can elaborate that would be great. – applecodervinegar Jan 20 '21 at 14:06
  • even if the reason phrase is empty, you still need a trailing whitespace in the status line; see RFC 7230, Section 3.1.2 – Julian Reschke Jan 20 '21 at 16:08

1 Answers1

2

The message is sent, even if you don't provide it.

In the PHP source code, we can see how it works.

In sapi/litespeed/lsapi_main.c, a list of code/message is stored.

static const http_error http_error_codes[] = {
   {100, "Continue"},
   {101, "Switching Protocols"},
   {200, "OK"},
   // ...
   {403, "Forbidden"},
   {404, "Not Found"},
   // ...
   {0,   NULL}
};

Then, in the sapi_lsapi_send_headers_like_cgi(), from sapi_lsapi_send_headers(), the status is converted to integer and message is found in the http_error structure (many lines ommited below) :

if (SG(sapi_headers).http_response_code != 200)
{
    // ...
    if (SG(sapi_headers).http_status_line &&
         (s = strchr(SG(sapi_headers).http_status_line, ' ')) != 0 &&
         (s - SG(sapi_headers).http_status_line) >= 5 &&
         strncasecmp(SG(sapi_headers).http_status_line, "HTTP/", 5) == 0
    ) {
        len = slprintf(buf, sizeof(buf), "Status:%s", s);
        response_status = atoi((s + 1));
    }
    // ...
            http_error *err = (http_error*)http_error_codes;
            while (err->code != 0) {
                if (err->code == SG(sapi_headers).http_response_code) {
                    break;
                }
                err++;
            }
            if (err->msg) {
                len = slprintf(buf, sizeof(buf), "Status: %d %s", SG(sapi_headers).http_response_code, err->msg);
            } else {
                len = slprintf(buf, sizeof(buf), "Status: %d", SG(sapi_headers).http_response_code);
            }
        //...

Then the function LSAPI_SetRespStatus_r() hold this information and finally, the function LSAPI_FinalizeRespHeaders_r() send the finalized header informations.

The most interesting line is (store the message from the http_error) :

len = slprintf(buf, sizeof(buf), "Status: %d %s", SG(sapi_headers).http_response_code, err->msg);

For information, see also the simple structure of http_error :

typedef struct _http_error {
  int code;
  const char* msg;
} http_error;
Syscall
  • 19,327
  • 10
  • 37
  • 52
  • Thanks for the details. let me go through the code and understand this better. Would you know if this behaviour is version independent? – applecodervinegar Jan 27 '21 at 12:24
  • @applecodervinegar This code was added in the version 7.2. – Syscall Jan 27 '21 at 16:18
  • I tested in PHP/7.1.33 and it was working fine without the message – applecodervinegar Jan 29 '21 at 16:26
  • Right. Just checked in PHP source code : before 7.2, the function was `sapi_cgi_send_headers()`. So it works at least as of PHP 5.6 (checked). – Syscall Jan 29 '21 at 17:30
  • 1
    Also, note that the _"Reason-Phrase is intended for the human user. The client is not required to examine or display the Reason-Phrase."_ ([Hypertext Transfer Protocol §6.1.1](http://www.faqs.org/rfcs/rfc2616.html)) – Syscall Jan 29 '21 at 18:02