Getting Tornado to return HTTP 400 on all unused URLs

2.1k Views Asked by At

Is it possible to set up a Tornado server to run on a certain port, actively serving an API at several URLs, and having it return an HTTP 400: Bad request on every other URL requested on that port?

Say for example that I've got a simple GET and POST API running on http://example.com:1234/get and http://example.com:1234/post respectively that return 2xx statuses as appropriate, but requests to http://example.com:1234/someRandomUrlRequest return an HTTP 400.

1

There are 1 best solutions below

0
On BEST ANSWER

Put a catch-all URL route at the end of your application's list of routes. Make a handler for that catch-all route that raises HTTPError(400) for GET and POST requests. Here's an example:

import tornado.ioloop
import tornado.web


class GetHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("GetHandler\n")


class PostHandler(tornado.web.RequestHandler):
    def post(self):
        self.write("PostHandler\n")


class BadRequestHandler(tornado.web.RequestHandler):
    def get(self):
        raise tornado.web.HTTPError(400)

    post = get

application = tornado.web.Application([
    (r"/get", GetHandler),
    (r"/post", PostHandler),
    (r"/.*", BadRequestHandler),
])

if __name__ == "__main__":
    application.listen(1234)
    tornado.ioloop.IOLoop.instance().start()

Testing this with curl:

$ curl localhost:1234/get
GetHandler
$ curl --data 'foo' localhost:1234/post
PostHandler
$ curl localhost:1234
<html><title>400: Bad Request</title><body>400: Bad Request</body></html>
$ curl localhost:1234/adsf
<html><title>400: Bad Request</title><body>400: Bad Request</body></html>
$ curl --data 'foo' localhost:1234/adsf
<html><title>400: Bad Request</title><body>400: Bad Request</body></html>