Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[HttpKernel] Deprecate X-Status-Code for better alternative #19822

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 1, 2017

Conversation

jameshalsall
Copy link
Contributor

@jameshalsall jameshalsall commented Sep 2, 2016

Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? yes
Tests pass? yes
Fixed tickets #12343
License MIT
Doc PR symfony/symfony-docs#6948

This marks the X-Status-Code header method of setting a custom response status
code in exception listeners for a better alternative. There is now a new method
on the GetResponseForExceptionEvent that allows successful status codes in
the response sent to the client.

The old method of setting the X-Status-Code header will now throw a deprecation warning.

Instead, in your exception listener you simply call GetResponseForExceptionEvent::allowCustomResponseCode() which will tell the Kernel not to override the status code of the event's response object.

Currenty the X-Status-Code header will still be removed, so as not to change the existing behaviour, but this is something we can remove in 4.0.

TODO:

  • Replace usage of X-Status-Code in FormAuthenticationEntryPoint
  • Open Silex issue
  • Rename method on the response
  • Ensure correct response code is set in AuthenticationEntryPointInterface implementations
  • Ensure the exception listeners are marking GetResponseForExceptionEvent as allowing a custom response code
  • In the Security component we should only use the new method of setting a custom response code if it is available, and fall back to the X-Status-Code method

@jameshalsall jameshalsall force-pushed the deprecate-x-status-code-header branch 2 times, most recently from b742e97 to 2eae976 Compare September 2, 2016 10:24
@jameshalsall jameshalsall changed the title [HttpKernel] Deprecate X-Status-Code for better alternative [WIP][HttpKernel] Deprecate X-Status-Code for better alternative Sep 2, 2016
@jameshalsall jameshalsall force-pushed the deprecate-x-status-code-header branch from 2eae976 to 001c2da Compare September 2, 2016 12:28
@@ -54,7 +54,7 @@ public function start(Request $request, AuthenticationException $authException =

$response = $this->httpKernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
if (200 === $response->getStatusCode()) {
$response->headers->set('X-Status-Code', 401);
$response->setStatusCode(401);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fabpot I'm not sure about this change, in the authentication listeners found in the Symfony\Component\Security\Http\Firewall namespace the response returned from the AuthenticationEntryPointInterface::start() method is set on the response. From what I can see the X-Status-Code is only ever used when handling the exception in the kernel, so I don't think this will have any adverse impact

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fabpot interested on hearing your thoughts on the above? would be good to get this into 3.2 before the development window closes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks suspicious to me. You are saying that this can basically be removed, right? If that's the case, we probably need to understand what changed between the time the PR adding this was merged and now.

@jameshalsall jameshalsall force-pushed the deprecate-x-status-code-header branch from 001c2da to 75d9d7c Compare September 2, 2016 12:36
@jameshalsall jameshalsall changed the title [WIP][HttpKernel] Deprecate X-Status-Code for better alternative [WIP][HttpKernel] Deprecate X-Status-Code for better alternativ Sep 2, 2016
@jameshalsall jameshalsall changed the title [WIP][HttpKernel] Deprecate X-Status-Code for better alternativ [HttpKernel] Deprecate X-Status-Code for better alternativ Sep 2, 2016
@jameshalsall jameshalsall changed the title [HttpKernel] Deprecate X-Status-Code for better alternativ [HttpKernel] Deprecate X-Status-Code for better alternative Sep 2, 2016
public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, \Exception $e)
{
parent::__construct($kernel, $request, $requestType);

$this->setException($e);
$this->allowSuccessfulResponse = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be set on variable declaration not in construct.

@jameshalsall jameshalsall force-pushed the deprecate-x-status-code-header branch from 75d9d7c to 703108f Compare September 2, 2016 14:54
@jameshalsall
Copy link
Contributor Author

The build failure in AppVeyor is not look related to these changes.

@jameshalsall jameshalsall force-pushed the deprecate-x-status-code-header branch from 703108f to cbcc2b4 Compare September 6, 2016 09:34
@lemoinem
Copy link
Contributor

@jameshalsall If you could rebase your PR so the Conflict can be resolved, I think we could switch this to Reviewed!

@jameshalsall jameshalsall force-pushed the deprecate-x-status-code-header branch from cbcc2b4 to 51e8614 Compare September 28, 2016 07:54
@jameshalsall
Copy link
Contributor Author

Rebased.

@lemoinem
Copy link
Contributor

Status: Reviewed

/**
* @var bool
*/
private $allowSuccessfulResponse = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you choose this name? This feature is not limited to successful response codes, is it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point - I used this as it was proposed in the original issue, but I'll re-name it to something more appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xabbuh updated this now to allowCustomResponseCode

@jameshalsall jameshalsall force-pushed the deprecate-x-status-code-header branch 2 times, most recently from 0c17566 to 96a8caa Compare October 15, 2016 21:22
@fabpot
Copy link
Member

fabpot commented Oct 24, 2016

Some notes from my research about this (I wanted to understand why it was not used more in Symfony itself):

@nicolas-grekas nicolas-grekas added this to the 3.x milestone Dec 6, 2016
@fabpot
Copy link
Member

fabpot commented Feb 16, 2017

@jameshalsall Do you have time to finish this one?

@jameshalsall
Copy link
Contributor Author

@fabpot I will get to this early next week - it's completely slipped my mind

@jameshalsall jameshalsall force-pushed the deprecate-x-status-code-header branch 5 times, most recently from f9ce498 to 6dbf9f7 Compare February 20, 2017 22:33
@jameshalsall
Copy link
Contributor Author

@fabpot this is ready for re-review now

@@ -242,10 +242,12 @@ private function handleException(\Exception $e, $request, $type)

// the developer asked for a specific status code
if ($response->headers->has('X-Status-Code')) {
@trigger_error(sprintf('Using the X-Status-Code header is deprecated, use %s::allowCustomResponseCode() instead.', GetResponseForExceptionEvent::class), E_USER_DEPRECATED);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be is deprecated since version 3.3 and will be removed in 4.0. Use ...

@@ -112,6 +112,9 @@ private function handleAuthenticationException(GetResponseForExceptionEvent $eve

try {
$event->setResponse($this->startAuthentication($event->getRequest(), $exception));
if (method_exists($event, 'allowCustomResponseCode')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition should be removed and composer.json (both for symfony/security and symfony/security-http) should be updated to only allow symfony/http-kernel 3.3+. The reason is that you are using setStatusCode above anyway, so the code only works for patched versions oh http-kernel.

@@ -155,6 +158,9 @@ private function handleAccessDeniedException(GetResponseForExceptionEvent $event
$subRequest->attributes->set(Security::ACCESS_DENIED_ERROR, $exception);

$event->setResponse($event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true));
if (method_exists($event, 'allowCustomResponseCode')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Condition should be removed

@@ -110,7 +117,12 @@ public function testAccessDeniedExceptionFullFledgedAndWithoutAccessDeniedHandle
$listener = $this->createExceptionListener(null, $this->createTrustResolver(true), $httpUtils, null, '/error');
$listener->onKernelException($event);

$this->assertEquals('error', $event->getResponse()->getContent());
if (method_exists($event, 'isAllowingCustomResponseCode')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Condition can be removed

$listener->onKernelException($event);

$this->assertEquals('OK', $event->getResponse()->getContent());
if (method_exists($event, 'isAllowingCustomResponseCode')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be removed

@fabpot
Copy link
Member

fabpot commented Feb 22, 2017

Also, we need to work on a PR on Silex to be sure that the code proposed here works there as well.

@jameshalsall jameshalsall force-pushed the deprecate-x-status-code-header branch from 6dbf9f7 to 01595e0 Compare February 23, 2017 18:43
This marks the X-Status-Code header method of setting a custom response
status code in exception listeners as deprecated. Instead there is now
a new method on the GetResponseForExceptionEvent that allows successful
status codes in the response sent to the client.
@jameshalsall jameshalsall force-pushed the deprecate-x-status-code-header branch from 01595e0 to cc0ef28 Compare February 23, 2017 21:30
@fabpot
Copy link
Member

fabpot commented Mar 1, 2017

Thank you @jameshalsall.

@fabpot fabpot merged commit cc0ef28 into symfony:master Mar 1, 2017
@fabpot
Copy link
Member

fabpot commented Mar 1, 2017

@jameshalsall Can you finish the PR for Silex? Thanks.

fabpot added a commit that referenced this pull request Mar 1, 2017
…ative (jameshalsall)

This PR was merged into the 3.3-dev branch.

Discussion
----------

[HttpKernel] Deprecate X-Status-Code for better alternative

| Q | A |
| --- | --- |
| Branch? | master |
| Bug fix? | no |
| New feature? | yes |
| BC breaks? | no |
| Deprecations? | yes |
| Tests pass? | yes |
| Fixed tickets | #12343 |
| License | MIT |
| Doc PR | symfony/symfony-docs#6948 |

This marks the X-Status-Code header method of setting a custom response status
code in exception listeners for a better alternative. There is now a new method
on the `GetResponseForExceptionEvent` that allows successful status codes in
the response sent to the client.

The old method of setting the X-Status-Code header will now throw a deprecation warning.

Instead, in your exception listener you simply call `GetResponseForExceptionEvent::allowCustomResponseCode()` which will tell the Kernel not to override the status code of the event's response object.

Currenty the `X-Status-Code` header will still be removed, so as not to change the existing behaviour, but this is something we can remove in 4.0.

TODO:
- [x] Replace usage of X-Status-Code in `FormAuthenticationEntryPoint`
- [x] Open Silex issue
- [x] Rename method on the response
- [x] Ensure correct response code is set in `AuthenticationEntryPointInterface` implementations
- [x] Ensure the exception listeners are marking `GetResponseForExceptionEvent` as allowing a custom response code
- [x] In the Security component we should only use the new method of setting a custom response code if it is available, and fall back to the `X-Status-Code` method

Commits
-------

cc0ef28 [HttpKernel] Deprecate X-Status-Code for better alternative
@nicolas-grekas nicolas-grekas modified the milestones: 3.x, 3.3 Mar 24, 2017
@fabpot fabpot mentioned this pull request May 1, 2017
@iisisrael
Copy link

As a result of this change, PhpUnit functional tests no longer recognize redirects on ACL exceptions. When authenticated as a user without the required role, this fails:

$this->assertEquals(Response::HTTP_FORBIDDEN, $client->getResponse()->getStatusCode());

Functional tests have to resort to confirming that the response content matches the expected redirect page (e.g. the home page) instead of the tested forbidden page's content. This can also be seen in debug mode in the Symfony profiler - the HTTP status is 200, though a Sub Request exists with an AccessDeniedException.

Either of these changes to Symfony\Component\HttpKernel\HttpKernel::handleException() resolves the unnoticed sub request, and the only visible change on the front end is the HTTP response code (restored to a 403 as before instead of a 200):

-         } elseif (!$event->isAllowingCustomResponseCode() && !$response->isClientError() && !$response->isServerError() && !$response->isRedirect()) {
+         } elseif (!$response->isClientError() && !$response->isServerError() && !$response->isRedirect()) {

or:

-         } elseif (!$event->isAllowingCustomResponseCode() && !$response->isClientError() && !$response->isServerError() && !$response->isRedirect()) {
+         } elseif ((!$event->isAllowingCustomResponseCode() && !$response->isClientError() && !$response->isServerError() && !$response->isRedirect())
+             || ($event->isAllowingCustomResponseCode() && $e->getStatusCode() === Response::HTTP_FORBIDDEN)
+         ) {

I can't tell what the original intent was for the change in this particular instance, so I'm not sure which would be preferred.

javiereguiluz added a commit to symfony/symfony-docs that referenced this pull request Jan 9, 2018
… handler (jameshalsall)

This PR was submitted for the master branch but it was merged into the 3.3 branch instead (closes #6948).

Discussion
----------

Update docs for setting custom response code in exception handler

Docs update for the changes applied in symfony/symfony#19822

Commits
-------

5f0becf Update docs for setting custom response code in exception handler
fabpot added a commit to silexphp/Silex that referenced this pull request Feb 26, 2018
…obrev)

This PR was merged into the 2.3.x-dev branch.

Discussion
----------

Allow setting custom status code on exception response

Closes #1450.

Prior and related PRs and issues:

- symfony/symfony#19822
- symfony/symfony-docs@5f0becf
- symfony/symfony-docs#9336

Commits
-------

7103511 Allow setting custom status code on exception response
javiereguiluz pushed a commit to symfony/symfony-docs that referenced this pull request Feb 26, 2018
…Code

Introduced in 5f0becf

The functionality was introduced in symfony/symfony#19822.
The method got renamed during code review, but was not updated in the docs.
symfony/symfony#19822 (comment)
javiereguiluz added a commit to symfony/symfony-docs that referenced this pull request Feb 26, 2018
…onseCode (hkdobrev)

This PR was submitted for the master branch but it was merged into the 3.4 branch instead (closes #9336).

Discussion
----------

Rename allowSuccessfulResponse to correct allowCustomResponseCode

Introduced in 5f0becf

The functionality was introduced in symfony/symfony#19822.
The method got renamed during code review, but was not updated in the docs.
symfony/symfony#19822 (comment)

Commits
-------

0cda0d5 Rename missing allowCustomResponseCode to correct allowCustomResponseCode
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants