I created a REST resource for GETing custom made data by an external site. This works fine if I provide an empty string as Basic HTTP Auth in the request, but fails when providing data for an existing user. I can also reproduce this with the Watchdog database log (/dblog/{id}) endpoint that comes with core.
Steps to reproduce:
1. Enable the following core modules:
- HTTP Basic Authentication
- RESTful Web Services
- Database Logging
2. For easy REST config add / enable:
- REST UI
3. Goto: admin/config/services/rest and enable the resource "Watchdog database log"
4. Goto: /admin/config/services/rest/resource/dblog/edit and configure the resource for using basic_auth as "Authentication provider"
5. Access the endpoint with Postman or a similar tool. eg.: http://MY.DOMAIN/dblog/37035?_format=json Use the login credentials for user 1 as basic auth header. You get an NotAcceptableHttpException as resulting data you see "No route found for the specified format html."
Problem
Before the request is even handed over to the resource plugin that handles the json response it is always checked if there is a route for returning html. For this path such a route is not existent. Therefore in \Drupal\Core\Routing\RequestFormatRouteFilter::filter the execution stops with an exception and the json is never returned. Why and where the decision is made to run into this check is unclear to me. But creating a route /dblog/{id} with some bogus return fixes the problem as the first filter call is then passed and also gets passed a few steps later if it is checked if there is a component that returns json format.
Example:
After returning something on the normal route without _format parameter everything works.
/**
* Controller callback for the api route as there is an error if there is no
* response controller for html format.
*
* @return mixed
*/
public function noHtml() {
$output['message'] = array(
'#markup' => 'No output here.',
);
return $output;
}
Solution
Don't check for format HTML if another format is already provided in the URL?
Comments
Comment #2
wim leershttp://MY.DOMAIN/dblog/37035?_format=json+No route found for the specified format html.= makes no sense :)You're requesting JSON (and doing so correctly), yet the server is seeing you're requesting HTML.
This looks like it can be a bug in the routing system, or in REST's routes. I've seen many bugs in either.
On the other hand, you'd think this would've been reported a long time ago. However, few people use the
dblogREST resource. Most use theentityresource. And, sure enough, entities do render HTML at/node/1,dblogdoes not render HTML at/dblog/{id}. So I think it's quite plausible you've indeed found a major bug. It's certainly a routing bug, but we'll have to see where exactly something is wrong.Just to be sure: can you export your configuration and post it here?
Comment #3
wim leersGoing out on a limb and updating the issue title to describe what I strongly suspect to be the problem. I don't think the authentication aspect here is relevant to the bug.
Comment #4
manu manuI may have the same issue, using entityqueryapi
8.x-1.0-alpha8and core8.2.x-dev. It began breaking recently, maybe last week.In short and based on previous comments, adding a
htmlformat tojsonin therequirementssection made it somewhat working:This module is quite simple and I suspect it is not responsible for this issue. It's very similar to any custom module defining a route with only a
jsonformat supported.Drupal\Core\Routing\RequestFormatRouteFilter::filter()gets indeed the defaulthtmlformat from$requestinstead ofjson.If it helps, here is a gist containing a backtrace until
Drupal\Core\Routing\RequestFormatRouteFilter::filter().Comment #5
manu manuComment #6
manu manuNote that I experienced this problem with a custom Rest resource, too.
I will try to package a simple module to reproduce this on a clean install.
Comment #8
wim leersI followed the exact steps to reproduce in the IS. I can't reproduce this. The many fixes to the REST module (and related subsystems) in the past few months has likely fixed this. Update to Drupal 8.3 and it should be solved :)
Comment #9
manu manuAll right Wim, I will test when I will come back to the project that was having the issue :-)