Skip to content

Http Statuscode-Line is ignored in ISS Server (and maybe other fastCGI servers) #19923

@Radon8472

Description

@Radon8472

What steps will reproduce the problem?

Set response-code in an IIS Server like this:

\Yii::$app->response->statusCode = 500;

or create any critical php error (e.g. echo 10/0).

What is the expected result?

Expected result is Statuscode 500 in Browser, and HTTP/1.1 500 Internal Server Error on first line of http headers.

What do you get instead?

Statuscode 200 and first header line of HTTP/1.1 200 OK

Additional info

Q A
Yii version 2.0.48.1
PHP version 8.1
Microsoft-IIS version 8.5
Operating system Window

my Researches to find the problem

I discovered, that yii does not return a statuscode 500 on php errors, and made some research.
I followed the defined status-code in the response until I found yii\web\Response::sendHeaders().

After more testing I can ensure that the statuscode is correctly passed in this method and correctly passed into the header function.
E.g. adding a custom header as debug like this (e.g. in one of your controller actions):

header("X-StatusLine: HTTP/{$this->version} {$statusCode} {$this->statusText}")

Gives the header X-StatusLine: HTTP/1.0 500 Internal Server Error, what makes me sure that a currect formated statusline is created in the sendHeaders() function, but statuscode is not delivered to browser.

After more reseach I discovered the Status-header, and made some tests adding this extra header.
The line

header("Status: {$statusCode} {$this->statusText}");

in Response::sendStatus did not chance anything.
But adding the stuscode to the 3. argument of the header function gave the expected result.

Suggestion to fix

Add the line

header("Status: {$statusCode} {$this->statusText}", true, $statusCode);

right after

header("HTTP/{$this->version} {$statusCode} {$this->statusText}");

or maybe replace the existing line with

if (php_sapi_name() === 'cgi-fcgi')
  header("Status: {$statusCode} {$this->statusText}", true, $statusCode);
else
  header("HTTP/{$this->version} {$statusCode} {$this->statusText}");

Reasons

It seems that IIS (and maybe other servers) do not respect the statuscode / message set as HTTP/{Protocol} {code} {message} -header.
Adding the extra header Status: {code} {message} tells this server to chance their statusline line expected.

As far as I could find out, this behavior has something to do with cgi/fastCGI, so I thinkt this is not only an IIS exclusive problem, and could affect other server types too.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions