My Question
I am looking for a way to stop request processing in a Tool without raising an exception. In other words: I want to stop the request befor it gets to the specified controller and return a 2xx status code?
Background
We want our application to support CORS and therefore the preflight request. The idea was to write a tool which hooks before_handler
. If an OPTIONS request is made, return the relevant CORS-headers and exit.
The problem is, that I havn't found a way to stop the execution flow. This means that the original URL is processed, as it would be if requested normally. The point is: this could lead to security issues, as the preflight request is always made. This is what I have so far:
class CORSTool(cherrypy.Tool):
def __init__(self):
cherrypy.Tool.__init__(self, 'before_handler', self.insert_cors_header, priority=40)
cherrypy.request.hooks.attach('before_handler', self.insert_cors_header, priority=40)
def _setup(self):
cherrypy.Tool._setup(self)
def insert_cors_header(self):
"""
Inserts the relevant CORS-Headers:
- Access-Control-Allow-Origin: <from-config>
- Access-Control-Allow-Methods: POST, GET, OPTIONS
- Access-Control-Max-Age: 86400
"""
if cherrypy.config.get('enable_cors') is True:
if cherrypy.request.method.upper() == "OPTIONS":
cherrypy.response.headers['Access-Control-Allow-Origin'] = cherrypy.config.get('cors_domains')
cherrypy.response.headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
cherrypy.response.headers['Access-Control-Max-Age'] = '86400'
# Stop execution
cherrypy.response.body = None
cherrypy.response.status = 200
cherrypy.response.finalize()
# And NOW stop doing anything else...
Alternatives likely not working
I know that there is a cherrypy-cors plugin, but from the source I can't see how this stops the execution.
I also know that CherryPy has a MethodDispatcher, but that would mean a complete rewrite of our code.
Searching Stackoverflow I found this answer, however I don't want to "kill" the execution, I just want a way to prevent the handler from being called.
Just have your Tool set request.handler = None. See Request.respond for the code which implements this and the CachingTool for an example:
request = cherrypy.serving.request if _caching.get(**kwargs): request.handler = None
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With