Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

abort method in Flask-Restful ignoring CORS options

I have a Flask-Restful API configured with some CORS options:

api = Api()
api.decorators=[cors.crossdomain(origin='*', headers=['accept', 'Content-Type'])]

...

api.init_app(app)

My API accepts POST requests which may fail if the data in the request is invalid:

class myAPI(Resource):
    def post(self):
        args = request.get_json()
        if args.get('something'):
            return {'message': 'Request worked, data received!',
                    'something': args['something']}
        else:
            abort(500, "Error: Data must contain a 'something' field!")

When I make a successful POST request to my API I can see that the CORS options are properly set:

...
* upload completely sent off: 81 out of 81 bytes
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: application/json
< Content-Length: 205
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: HEAD, GET, POST, OPTIONS
< Access-Control-Max-Age: 21600
< Access-Control-Allow-Headers: ACCEPT, CONTENT-TYPE
< Server: Werkzeug/0.9.4 Python/2.7.6

If, however, the post call in my class exits through the abort method (by purposely sending bad data to the request) then the Access-Control-* fields are all missing from the response:

* upload completely sent off: 75 out of 75 bytes
* HTTP 1.0, assume close after body
< HTTP/1.0 500 INTERNAL SERVER ERROR
< Content-Type: application/json
< Content-Length: 51
< Server: Werkzeug/0.9.4 Python/2.7.6

Is it possible to make the abort method play nice with my CORS rules, or should I create my own full-fledged response and avoid using the abort function?

like image 349
Javier Avatar asked May 29 '14 16:05

Javier


1 Answers

When you trigger an abort, the error handler registered to the HTTP error code is automatically invoked, and the response is not actually served by your view function.

If you use the CORS middleware which is provided by Flask-Cors, instead of the decorator form, in the case of handled exceptions and aborts, the CORS headers will be injected as expected.

If an unhandled exception occurs, (E.G. there is an error in your code, and a 500 internal server error), Flask bypasses middleware, and after_request handlers are not run.

Full disclosure, I wrote Flask-Cors.

like image 100
Cory Dolphin Avatar answered Oct 31 '22 08:10

Cory Dolphin