Skip to content

Commit cfc9045

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 ------- cc0ef282cd [HttpKernel] Deprecate X-Status-Code for better alternative
2 parents f4d9308 + efdaccd commit cfc9045

File tree

5 files changed

+21
-11
lines changed

5 files changed

+21
-11
lines changed

EntryPoint/FormAuthenticationEntryPoint.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function start(Request $request, AuthenticationException $authException =
5454

5555
$response = $this->httpKernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
5656
if (200 === $response->getStatusCode()) {
57-
$response->headers->set('X-Status-Code', 401);
57+
$response->setStatusCode(401);
5858
}
5959

6060
return $response;

Firewall/ExceptionListener.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ private function handleAuthenticationException(GetResponseForExceptionEvent $eve
112112

113113
try {
114114
$event->setResponse($this->startAuthentication($event->getRequest(), $exception));
115+
$event->allowCustomResponseCode();
115116
} catch (\Exception $e) {
116117
$event->setException($e);
117118
}
@@ -155,6 +156,7 @@ private function handleAccessDeniedException(GetResponseForExceptionEvent $event
155156
$subRequest->attributes->set(Security::ACCESS_DENIED_ERROR, $exception);
156157

157158
$event->setResponse($event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true));
159+
$event->allowCustomResponseCode();
158160
}
159161
} catch (\Exception $e) {
160162
if (null !== $this->logger) {

Tests/EntryPoint/FormAuthenticationEntryPointTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,6 @@ public function testStartWithUseForward()
6464
$entryPointResponse = $entryPoint->start($request);
6565

6666
$this->assertEquals($response, $entryPointResponse);
67-
$this->assertEquals(401, $entryPointResponse->headers->get('X-Status-Code'));
67+
$this->assertEquals(401, $entryPointResponse->getStatusCode());
6868
}
6969
}

Tests/Firewall/ExceptionListenerTest.php

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,19 @@ public function testAuthenticationExceptionWithoutEntryPoint(\Exception $excepti
4444
/**
4545
* @dataProvider getAuthenticationExceptionProvider
4646
*/
47-
public function testAuthenticationExceptionWithEntryPoint(\Exception $exception, \Exception $eventException = null)
47+
public function testAuthenticationExceptionWithEntryPoint(\Exception $exception)
4848
{
49-
$event = $this->createEvent($exception = new AuthenticationException());
49+
$event = $this->createEvent($exception);
50+
51+
$response = new Response('Forbidden', 403);
5052

51-
$listener = $this->createExceptionListener(null, null, null, $this->createEntryPoint());
53+
$listener = $this->createExceptionListener(null, null, null, $this->createEntryPoint($response));
5254
$listener->onKernelException($event);
5355

54-
$this->assertEquals('OK', $event->getResponse()->getContent());
56+
$this->assertTrue($event->isAllowingCustomResponseCode());
57+
58+
$this->assertEquals('Forbidden', $event->getResponse()->getContent());
59+
$this->assertEquals(403, $event->getResponse()->getStatusCode());
5560
$this->assertSame($exception, $event->getException());
5661
}
5762

@@ -100,7 +105,7 @@ public function testAccessDeniedExceptionFullFledgedAndWithoutAccessDeniedHandle
100105
public function testAccessDeniedExceptionFullFledgedAndWithoutAccessDeniedHandlerAndWithErrorPage(\Exception $exception, \Exception $eventException = null)
101106
{
102107
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
103-
$kernel->expects($this->once())->method('handle')->will($this->returnValue(new Response('error')));
108+
$kernel->expects($this->once())->method('handle')->will($this->returnValue(new Response('Unauthorized', 401)));
104109

105110
$event = $this->createEvent($exception, $kernel);
106111

@@ -110,7 +115,10 @@ public function testAccessDeniedExceptionFullFledgedAndWithoutAccessDeniedHandle
110115
$listener = $this->createExceptionListener(null, $this->createTrustResolver(true), $httpUtils, null, '/error');
111116
$listener->onKernelException($event);
112117

113-
$this->assertEquals('error', $event->getResponse()->getContent());
118+
$this->assertTrue($event->isAllowingCustomResponseCode());
119+
120+
$this->assertEquals('Unauthorized', $event->getResponse()->getContent());
121+
$this->assertEquals(401, $event->getResponse()->getStatusCode());
114122
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
115123
}
116124

@@ -159,10 +167,10 @@ public function getAccessDeniedExceptionProvider()
159167
);
160168
}
161169

162-
private function createEntryPoint()
170+
private function createEntryPoint(Response $response = null)
163171
{
164172
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
165-
$entryPoint->expects($this->once())->method('start')->will($this->returnValue(new Response('OK')));
173+
$entryPoint->expects($this->once())->method('start')->will($this->returnValue($response ?: new Response('OK')));
166174

167175
return $entryPoint;
168176
}

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"symfony/security-core": "~3.2",
2121
"symfony/event-dispatcher": "~2.8|~3.0",
2222
"symfony/http-foundation": "~2.8|~3.0",
23-
"symfony/http-kernel": "~2.8|~3.0",
23+
"symfony/http-kernel": "~3.3",
2424
"symfony/polyfill-php56": "~1.0",
2525
"symfony/polyfill-php70": "~1.0",
2626
"symfony/property-access": "~2.8|~3.0"

0 commit comments

Comments
 (0)