Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Respect response's status code #273

Merged

Conversation

lcobucci
Copy link
Contributor

This basically ensures that zend-diactoros sends the status code to header() while emitting the response headers, preventing PHP from overriding it silently.

IMO this is a bug fix, since the emitted response is different from the created response.

We have a similar solution in symfony/http-foundation: https://github.com/symfony/http-foundation/blob/dd97248b62153457d0716738d0dbcc0c2b31e285/Response.php#L331-L338

More info:

In order to be able to verify that we're calling the function with the
correct values.
Although we have tests covering multiple `Set-Cookie` headers, they are
not verifying if the function `header()` is being called correctly.
@lcobucci lcobucci changed the title Respect response status code Respect response's status code Oct 10, 2017
@weierophinney
Copy link
Member

In looking at this, I think there may be a better approach.

Each of the two SAPI emitter implementations call the following:

$this->emitStatusLine($response);
$this->emitHeaders($response);

I'm thinking that perhaps those lines should be reversed, and emitStatusLine() modified to pass the $http_response_code argument when calling header().

Alternately, we keep your suggested solution, but also make those changes, to be 100% certain in situations where custom implementations call the methods in a different order.

Thoughts?

@lcobucci
Copy link
Contributor Author

@weierophinney reversing the calls also fixes it indeed. However IMO is a bit fragile, specially having the possibility of creating custom emitters that shares the trait, and not really "natural" - I expect that the header stack would be status line and then the headers.

I'd suggest to only force the response code when calling header(), but I can modify this PR according to your preference.

@weierophinney
Copy link
Member

I'd suggest to only force the response code when calling header(), but I can modify this PR according to your preference.

Well, emitStatusLine() also calls header(), so we should do it there, too.

Let's do the following:

  • Add the response code when calling header() in emitStatusLine()
  • Reverse the emitStatusLine() and emitHeaders() calls in both implementations
  • Add information in the emitStatusLine() docblock indicating that method should generally be called after emitHeaders().

This will cover all bases, I think.

Thanks, @lcobucci !

If we don't pass the response status code to the function `header()` PHP
might silently change the response code, which is not really nice since
it should be up for the developers to define how they design the
application.

This silent change usually happens when one uses "Location" with a
status code that's not 201 or 3xx, and some people already discussed a
lot and essencially they've said that PHP will not modify its behaviour
regarding this because it allows high level code to modify (fix) this.

References:

- https://bugs.php.net/bug.php?id=70273
- https://bugs.php.net/bug.php?id=51749
- https://bugs.php.net/bug.php?id=74535
To ensure that the emitted response will always be correct according
with the response object.
@lcobucci
Copy link
Contributor Author

@weierophinney done, thanks!

@weierophinney weierophinney merged commit 35f5af1 into zendframework:master Oct 12, 2017
weierophinney added a commit that referenced this pull request Oct 12, 2017
weierophinney added a commit that referenced this pull request Oct 12, 2017
weierophinney added a commit that referenced this pull request Oct 12, 2017
weierophinney added a commit that referenced this pull request Oct 12, 2017
Forward port #273

Conflicts:
	CHANGELOG.md
@weierophinney
Copy link
Member

Thanks, @lcobucci! Merged, and released with 1.6.1.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants