10000 feature #19822 [HttpKernel] Deprecate X-Status-Code for better altern… · symfony/http-kernel@35a8c53 · GitHub
[go: up one dir, main page]

Skip to content

Commit 35a8c53

Browse files
committed
feature #19822 [HttpKernel] Deprecate X-Status-Code for better alternative (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
2 parents 2d49eed + df261fd commit 35a8c53

File tree

4 files changed

+82
-2
lines changed

4 files changed

+82
-2
lines changed

Event/GetResponseForExceptionEvent.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ class GetResponseForExceptionEvent extends GetResponseEvent
3636
*/
3737
private $exception;
3838

39+
/**
40+
* @var bool
41+
*/
42+
private $allowCustomResponseCode = false;
43+
3944
public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, \Exception $e)
4045
{
4146
parent::__construct($kernel, $request, $requestType);
@@ -64,4 +69,22 @@ public function setException(\Exception $exception)
6469
{
6570
$this->exception = $exception;
6671
}
72+
73+
/**
74+
* Mark the event as allowing a custom response code.
75+
*/
76+
public function allowCustomResponseCode()
77+
{
78+
$this->allowCustomResponseCode = true;
79+
}
80+
81+
/**
82+
* Returns true if the event allows a custom response code.
83+
*
84+
* @return bool
85+
*/
86+
public function isAllowingCustomResponseCode()
87+
{
88+
return $this->allowCustomResponseCode;
89+
}
6790
}

HttpKernel.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,12 @@ private function handleException(\Exception $e, $request, $type)
242242

243243
// the developer asked for a specific status code
244244
if ($response->headers->has('X-Status-Code')) {
245+
@trigger_error(sprintf('Using the X-Status-Code header is deprecated since version 3.3 and will be removed in 4.0. Use %s::allowCustomResponseCode() instead.', GetResponseForExceptionEvent::class), E_USER_DEPRECATED);
246+
245247
$response->setStatusCode($response->headers->get('X-Status-Code'));
246248

247249
$response->headers->remove('X-Status-Code');
248-
} elseif (!$response->isClientError() && !$response->isServerError() && !$response->isRedirect()) {
250+
} elseif (!$event->isAllowingCustomResponseCode() && !$response->isClientError() && !$response->isServerError() && !$response->isRedirect()) {
249251
// ensure that we actually have an error response
250252
if ($e instanceof HttpExceptionInterface) {
251253
// keep the HTTP status code and headers
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\HttpKernel\Tests\Event;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
17+
use Symfony\Component\HttpKernel\Tests\TestHttpKernel;
18+
19+
class GetResponseForExceptionEventTest extends TestCase
20+
{
21+
public function testAllowSuccessfulResponseIsFalseByDefault()
22+
{
23+
$event = new GetResponseForExceptionEvent(new TestHttpKernel(), new Request(), 1, new \Exception());
24+
25+
$this->assertFalse($event->isAllowingCustomResponseCode());
26+
}
27+
}

Tests/HttpKernelTest.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
1818
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
1919
use Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent;
20+
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
2021
use Symfony\Component\HttpKernel\HttpKernel;
2122
use Symfony\Component\HttpKernel\HttpKernelInterface;
2223
use Symfony\Component\HttpKernel\KernelEvents;
@@ -111,9 +112,10 @@ public function testHandleHttpException()
111112
}
112113

113114
/**
115+
* @group legacy
114116
* @dataProvider getStatusCodes
115117
*/
116-
public function testHandleWhenAnExceptionIsHandledWithASpecificStatusCode($responseStatusCode, $expectedStatusCode)
118+
public function testLegacyHandleWhenAnExceptionIsHandledWithASpecificStatusCode($responseStatusCode, $expectedStatusCode)
117119
{
118120
$dispatcher = new EventDispatcher();
119121
$dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) use ($responseStatusCode, $expectedStatusCode) {
@@ -137,6 +139,32 @@ public function getStatusCodes()
137139
);
138140
}
139141

142+
/**
143+
* @dataProvider getSpecificStatusCodes
144+
*/
145+
public function testHandleWhenAnExceptionIsHandledWithASpecificStatusCode($expectedStatusCode)
146+
{
147+
$dispatcher = new EventDispatcher();
148+
$dispatcher->addListener(KernelEvents::EXCEPTION, function (GetResponseForExceptionEvent $event) use ($expectedStatusCode) {
149+
$event->allowCustomResponseCode();
150+
$event->setResponse(new Response('', $expectedStatusCode));
151+
});
152+
153+
$kernel = $this->getHttpKernel($dispatcher, function () { throw new \RuntimeException(); });
154+
$response = $kernel->handle(new Request());
155+
156+
$this->assertEquals($expectedStatusCode, $response->getStatusCode());
157+
}
158+
159+
public function getSpecificStatusCodes()
160+
{
161+
return array(
162+
array(200),
163+
array(302),
164+
array(403),
165+
);
166+
}
167+
140168
public function testHandleWhenAListenerReturnsAResponse()
141169
{
142170
$dispatcher = new EventDispatcher();

0 commit comments

Comments
 (0)
0