Search code examples
phphttphttp-headershttp-response-codes

Setting HTTP response status code in PHP using header('HTTP/1.1 <status-code>')?


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.


Solution

  • 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;