Skip to content

Instantly share code, notes, and snippets.

@paxan
Last active August 15, 2023 01:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paxan/6c63815f0767eca55a24 to your computer and use it in GitHub Desktop.
Save paxan/6c63815f0767eca55a24 to your computer and use it in GitHub Desktop.
A hack to make Tornado web server redirect http requests to https for Heroku or similar reverse-proxied deployments
from __future__ import absolute_import, print_function
import os
import tornado.httpserver
import tornado.ioloop
import tornado.web
def create_server(*args, **kwargs):
'''
Makes HTTPServer based on 'args' & 'kwargs' that have the same meaining
as in HTTPServer's constructor.
If xheaders=True and force_https=True are passed, also patches _RequestDispatcher
to generate redirects to https URLs.
'''
kw = dict(kwargs)
force_https = kw.pop('force_https', False)
if kw.get('xheaders', False) and force_https:
class PatchedDispatcher(tornado.web._RequestDispatcher):
def _find_handler(self):
req = self.request
if req.headers.get('X-Forwarded-Proto') != 'https':
self.handler_class = tornado.web.RedirectHandler
self.handler_kwargs = {'url': 'https://%s%s' % (req.headers['Host'], req.uri)}
return
return super(PatchedDispatcher, self)._find_handler()
tornado.web._RequestDispatcher = PatchedDispatcher
return tornado.httpserver.HTTPServer(*args, **kw)
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
app = tornado.web.Application([
(r"/", MainHandler),
])
server = create_server(app,
xheaders=True,
force_https=os.environ.get('FORCE_HTTPS') in ('true', 'True'))
server.listen(int(os.environ['PORT']))
tornado.ioloop.IOLoop.current().start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment