Closed DmitryVarennikov closed 1 year ago
Sorry but I don't really understand what you're asking here. Can you explain more specifically?
Sure. Browser makes an OPTIONS
request before the main one every time. So backend should support it and answer accordingly which is perfectly done by CorsListener
except for one thing. I use FOSRestBundle
where one has to explicitly specify an acceptable HTTP method for every controller method, i.e. GET
, POST
, etc (you may also specify it implicitly by following naming convention but this is irrelevant for this matter).
default:
type: rest
prefix: api
resource: AppBundle\Controller\DefaultController
methods: [GET, POST, OPTIONS]
What would be nice is to skip OPTIONS
configuration for each route and to have a listener which intercepts incoming OPTIONS
requests and tells Symfony core not to raise MethodNotAllowedException
.
Does it make sense now?
Sorry but no I don't get it.. what is throwing the MethodNotAllowedException? The OPTIONS request should be handled by the CorsListener and then symfony should just return that response if it's valid. The FOSRest stuff should not be called AFAIK, but if it is it sounds like maybe a listener priority bug?!
The Bundle behaves correctly. Yes in some special cases the browser does a preflight OPTIONS
Request. But within this request the clients sends the desired "real" method within an Access-Control-Request-Method: PUT
Header. So the listener has to check if the desired Method is within the allow_methods: ['POST', 'PUT', 'GET', 'DELETE']
Array of _nelmio_cors:
_ Configuration. It has nothing to do with the FOSRestuBundle.
In other words: In the preflight-OPTIONS Request the client asks the server "Hey, am I allowed to do a PUT-Request to your endpoint?" And the server looks up the allowed methods (PUT is allowed) and says yes! (Status 200) or no! (Status 405 - MethodNotAllowed
)
Here is a nice explanation http://www.html5rocks.com/en/tutorials/cors/
That's the thing. If OPTIONS
method isn't configured explicitly (not sure about ANY
as I use FOSRestuBundle) CorsListener
is never triggered instead MethodNotAllowedException
is thrown somewhere before.
I'll give my example. I take advantage of implicit resource name definition and implement ClassResourceInterface
in my controllers. I have to add 2 empty methods for OPTIONS
requests to satisfy browser, e.g. optionAction($id)
and coptionAction()
. Yes they are empty as CorsListener
takes care of OPTIONS
requests but they still have to be in place.
Then that's a bug in whatever other bundle you are using, it must be registering a listener on kernel.request with a priority that is too high and makes it take priority over this bundle.
The CorsListener
has an extremely high priority (10000) while FosRestBundle's AllowedMethodsListener
has default priority, so I don't see how that can be the case...
Hi guys, I think I have the same problem.
If i put the method in my route configuration I get: 400 Method not allowed. If I remove the "Method Put" declaration it works ok.
/**
* @Route("/tareas/modificar", name="api_tareas_modificar")
* @Method("PUT")
*/
I figured this one out. Your api is not doing it right: There is a case where CorsListener returns 405 if the Access-Control-Request-Method
is missing in the request or the method on the list is not listed in allowed-methods configuration
@mvrhov Since version 2.0.0 the priority has been lowered to 28. Now it produces this problem again. When debugging the request listeners it looks like this:
"kernel.request" event
----------------------
------- ------------------------------------------------------------------------------------------------- ----------
Order Callable Priority
------- ------------------------------------------------------------------------------------------------- ----------
#1 Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::configure() 2048
#2 Symfony\Component\HttpKernel\EventListener\ValidateRequestListener::onKernelRequest() 256
#3 Symfony\Component\HttpKernel\EventListener\SessionListener::onKernelRequest() 128
#4 Symfony\Component\HttpKernel\EventListener\LocaleListener::setDefaultLocale() 100
#5 Symfony\Component\HttpKernel\EventListener\RouterListener::onKernelRequest() 32
#6 Nelmio\CorsBundle\EventListener\CorsListener::onKernelRequest() 28
#7 Symfony\Bundle\FrameworkBundle\EventListener\ResolveControllerNameSubscriber::onKernelRequest() 24
#8 Symfony\Component\HttpKernel\EventListener\LocaleListener::onKernelRequest() 16
#9 Symfony\Component\HttpKernel\EventListener\LocaleAwareListener::onKernelRequest() 15
#10 Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener::configureLogoutUrlGenerator() 8
#11 Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener::onKernelRequest() 8
#12 Sentry\SentryBundle\EventListener\RequestListener::onKernelRequest() 1
#13 Sentry\SentryBundle\EventListener\SubRequestListener::onKernelRequest() 1
------- ------------------------------------------------------------------------------------------------- ----------
As you can see, it now ends up below the routerlistener. This means the routerlistener already captures the request and looks at the configured methods for that route.
I changed the priority to 34 instead of the current 28 and it seems to fix this problem.
This was fixed in 2.0.1
Is there a way to configure
OPTIONS
method for every request to avoidMethodNotAllowedException
?