Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
D
drupal
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Custom Issue Tracker
Custom Issue Tracker
Labels
Merge Requests
311
Merge Requests
311
Requirements
Requirements
List
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Analytics
Analytics
Code Review
Insights
Issue
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
project
drupal
Commits
8ce2a3ec
Unverified
Commit
8ce2a3ec
authored
Jun 02, 2018
by
alexpott
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue
#2955383
by Wim Leers, borisson_, dawehner: List available representations in 406 responses
parent
f54efcf2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
55 additions
and
8 deletions
+55
-8
core/lib/Drupal/Core/Routing/RequestFormatRouteFilter.php
core/lib/Drupal/Core/Routing/RequestFormatRouteFilter.php
+32
-8
core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
.../src/Functional/EntityResource/EntityResourceTestBase.php
+2
-0
core/tests/Drupal/Tests/Core/Routing/RequestFormatRouteFilterTest.php
...rupal/Tests/Core/Routing/RequestFormatRouteFilterTest.php
+21
-0
No files found.
core/lib/Drupal/Core/Routing/RequestFormatRouteFilter.php
View file @
8ce2a3ec
...
...
@@ -2,6 +2,7 @@
namespace
Drupal\Core\Routing
;
use
Drupal\Core\Url
;
use
Symfony\Component\HttpFoundation\Request
;
use
Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException
;
use
Symfony\Component\Routing\Route
;
...
...
@@ -60,7 +61,18 @@ public function filter(RouteCollection $collection, Request $request) {
// We do not throw a
// \Symfony\Component\Routing\Exception\ResourceNotFoundException here
// because we don't want to return a 404 status code, but rather a 406.
throw
new
NotAcceptableHttpException
(
"No route found for the specified format
$format
."
);
$available_formats
=
static
::
getAvailableFormats
(
$collection
);
$not_acceptable
=
new
NotAcceptableHttpException
(
"No route found for the specified format
$format
. Supported formats: "
.
implode
(
', '
,
$available_formats
)
.
'.'
);
if
(
$available_formats
)
{
$links
=
[];
foreach
(
$available_formats
as
$available_format
)
{
$url
=
Url
::
fromUri
(
$request
->
getUri
(),
[
'query'
=>
[
'_format'
=>
$available_format
]])
->
toString
(
TRUE
)
->
getGeneratedUrl
();
$content_type
=
$request
->
getMimeType
(
$available_format
);
$links
[]
=
"<
$url
>; rel=
\"
alternate
\"
; type=
\"
$content_type
\"
"
;
}
$not_acceptable
->
setHeaders
([
'Link'
=>
implode
(
', '
,
$links
)]);
}
throw
$not_acceptable
;
}
/**
...
...
@@ -79,7 +91,24 @@ public function filter(RouteCollection $collection, Request $request) {
* The default format.
*/
protected
static
function
getDefaultFormat
(
RouteCollection
$collection
)
{
// Get the set of formats across all routes in the collection.
$formats
=
static
::
getAvailableFormats
(
$collection
);
// The default format is 'html' unless ALL routes require the same format.
return
count
(
$formats
)
===
1
?
reset
(
$formats
)
:
'html'
;
}
/**
* Gets the set of formats across all routes in the collection.
*
* @param \Symfony\Component\Routing\RouteCollection $collection
* The route collection to filter.
*
* @return string[]
* All available formats.
*/
protected
static
function
getAvailableFormats
(
RouteCollection
$collection
)
{
$all_formats
=
array_reduce
(
$collection
->
all
(),
function
(
array
$carry
,
Route
$route
)
{
// Routes without a '_format' requirement are assumed to require HTML.
$route_formats
=
!
$route
->
hasRequirement
(
'_format'
)
...
...
@@ -87,12 +116,7 @@ protected static function getDefaultFormat(RouteCollection $collection) {
:
explode
(
'|'
,
$route
->
getRequirement
(
'_format'
));
return
array_merge
(
$carry
,
$route_formats
);
},
[]);
$formats
=
array_unique
(
array_filter
(
$all_formats
));
// The default format is 'html' unless ALL routes require the same format.
return
count
(
$formats
)
===
1
?
reset
(
$formats
)
:
'html'
;
return
array_unique
(
array_filter
(
$all_formats
));
}
}
core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
View file @
8ce2a3ec
...
...
@@ -1492,6 +1492,8 @@ protected function assert406Response(ResponseInterface $response) {
else
{
// This is the desired response.
$this
->
assertSame
(
406
,
$response
->
getStatusCode
());
$this
->
stringContains
(
'?_format='
.
static
::
$format
.
'>; rel="alternate"; type="'
.
static
::
$mimeType
.
'"'
,
$response
->
getHeader
(
'Link'
));
$this
->
stringContains
(
'?_format=foobar>; rel="alternate"'
,
$response
->
getHeader
(
'Link'
));
}
}
...
...
core/tests/Drupal/Tests/Core/Routing/RequestFormatRouteFilterTest.php
View file @
8ce2a3ec
...
...
@@ -2,7 +2,10 @@
namespace
Drupal\Tests\Core\Routing
;
use
Drupal\Core\DependencyInjection\ContainerBuilder
;
use
Drupal\Core\GeneratedUrl
;
use
Drupal\Core\Routing\RequestFormatRouteFilter
;
use
Drupal\Core\Utility\UnroutedUrlAssemblerInterface
;
use
Drupal\Tests\UnitTestCase
;
use
Symfony\Component\HttpFoundation\Request
;
use
Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException
;
...
...
@@ -59,6 +62,14 @@ public function filterProvider() {
* @covers ::filter
*/
public
function
testNoRouteFound
()
{
$url
=
$this
->
prophesize
(
GeneratedUrl
::
class
);
$url_assembler
=
$this
->
prophesize
(
UnroutedUrlAssemblerInterface
::
class
);
$url_assembler
->
assemble
(
'http://localhost/test?_format=xml'
,
[
'query'
=>
[
'_format'
=>
'json'
],
'external'
=>
TRUE
],
TRUE
)
->
willReturn
(
$url
);
$container
=
new
ContainerBuilder
();
$container
->
set
(
'unrouted_url_assembler'
,
$url_assembler
->
reveal
());
\
Drupal
::
setContainer
(
$container
);
$collection
=
new
RouteCollection
();
$route_with_format
=
$route
=
new
Route
(
'/test'
);
$route_with_format
->
setRequirement
(
'_format'
,
'json'
);
...
...
@@ -78,6 +89,16 @@ public function testNoRouteFound() {
public
function
testNoRouteFoundWhenNoRequestFormatAndSingleRouteWithMultipleFormats
()
{
$this
->
setExpectedException
(
NotAcceptableHttpException
::
class
,
'No route found for the specified format html.'
);
$url
=
$this
->
prophesize
(
GeneratedUrl
::
class
);
$url_assembler
=
$this
->
prophesize
(
UnroutedUrlAssemblerInterface
::
class
);
$url_assembler
->
assemble
(
'http://localhost/test'
,
[
'query'
=>
[
'_format'
=>
'json'
],
'external'
=>
TRUE
],
TRUE
)
->
willReturn
(
$url
);
$url_assembler
->
assemble
(
'http://localhost/test'
,
[
'query'
=>
[
'_format'
=>
'xml'
],
'external'
=>
TRUE
],
TRUE
)
->
willReturn
(
$url
);
$container
=
new
ContainerBuilder
();
$container
->
set
(
'unrouted_url_assembler'
,
$url_assembler
->
reveal
());
\
Drupal
::
setContainer
(
$container
);
$collection
=
new
RouteCollection
();
$route_with_format
=
$route
=
new
Route
(
'/test'
);
$route_with_format
->
setRequirement
(
'_format'
,
'json|xml'
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment