Stop request processing in CherryPy and return 200 response from a tool

爷,独闯天下 提交于 2019-12-10 13:46:14

问题


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.


回答1:


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


来源:https://stackoverflow.com/questions/32133758/stop-request-processing-in-cherrypy-and-return-200-response-from-a-tool

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!