Improving the request/response format autodetection

This commit is contained in:
Yonel Ceruto 2019-07-02 17:48:31 -04:00
parent 2452ef8978
commit 1952928471
4 changed files with 51 additions and 2 deletions

View File

@ -192,6 +192,10 @@ class Request
protected static $requestFactory;
/**
* @var string|null
*/
private $preferredFormat;
private $isHostValid = true;
private $isForwardedValid = true;
@ -1559,6 +1563,25 @@ class Request
return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma');
}
public function getPreferredFormat(?string $default = 'html'): ?string
{
if (null !== $this->preferredFormat) {
return $this->preferredFormat;
}
$this->preferredFormat = $this->getRequestFormat($this->getContentType());
if (null === $this->preferredFormat) {
foreach ($this->getAcceptableContentTypes() as $contentType) {
if (null !== $this->preferredFormat = $this->getFormat($contentType)) {
break;
}
}
}
return $this->preferredFormat ?: $default;
}
/**
* Returns the preferred language.
*

View File

@ -270,7 +270,7 @@ class Response
} else {
// Content-type based on the Request
if (!$headers->has('Content-Type')) {
$format = $request->getRequestFormat();
$format = $request->getPreferredFormat();
if (null !== $format && $mimeType = $request->getMimeType($format)) {
$headers->set('Content-Type', $mimeType);
}

View File

@ -399,6 +399,32 @@ class RequestTest extends TestCase
$this->assertEquals('xml', $dup->getRequestFormat());
}
public function testGetPreferredFormat()
{
$request = new Request();
$this->assertNull($request->getPreferredFormat(null));
$this->assertSame('html', $request->getPreferredFormat());
$this->assertSame('json', $request->getPreferredFormat('json'));
$request->setRequestFormat('atom');
$request->headers->set('Content-Type', 'application/json');
$request->headers->set('Accept', 'application/xml');
$this->assertSame('atom', $request->getPreferredFormat());
$request = new Request();
$request->headers->set('Content-Type', 'application/json');
$request->headers->set('Accept', 'application/xml');
$this->assertSame('json', $request->getPreferredFormat());
$request = new Request();
$request->headers->set('Accept', 'application/xml');
$this->assertSame('xml', $request->getPreferredFormat());
$request = new Request();
$request->headers->set('Accept', 'application/json;q=0.8,application/xml;q=0.9');
$this->assertSame('xml', $request->getPreferredFormat());
}
/**
* @dataProvider getFormatToMimeTypeMapProviderWithAdditionalNullFormat
*/

View File

@ -174,7 +174,7 @@ class DebugHandlersListener implements EventSubscriberInterface
$e = $request->attributes->get('exception');
try {
return new Response($this->errorFormatter->render($e, $request->getRequestFormat()), $e->getStatusCode(), $e->getHeaders());
return new Response($this->errorFormatter->render($e, $request->getPreferredFormat()), $e->getStatusCode(), $e->getHeaders());
} catch (ErrorRendererNotFoundException $_) {
return new Response($this->errorFormatter->render($e), $e->getStatusCode(), $e->getHeaders());
}