New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add support for HTTPS protocol #307
Changes from 9 commits
b9872cc
89298c8
a3fff9a
f0e0900
af8d0f6
502effc
edf07c3
99aac12
9a2c4aa
cb69d67
b292d2d
92f407c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,12 +47,12 @@ class TornadoServer(AbstractServer): | |
""" Flexx Server implemented in Tornado. | ||
""" | ||
|
||
def __init__(self, host, port, new_loop): | ||
def __init__(self, host, port, new_loop, **kwargs): | ||
self._new_loop = new_loop | ||
self._app = None | ||
self._server = None | ||
self._get_io_loop() | ||
super().__init__(host, port) | ||
super().__init__(host, port, **kwargs) | ||
|
||
def _get_io_loop(self): | ||
# Get a new ioloop or the current ioloop for this thread | ||
|
@@ -63,17 +63,30 @@ def _get_io_loop(self): | |
if self._loop is None: | ||
self._loop = IOLoop(make_current=True) | ||
|
||
def _open(self, host, port): | ||
def _open(self, host, port, **kwargs): | ||
# Note: does not get called if host is False. That way we can | ||
# run Flexx in e.g. JLab's application. | ||
|
||
|
||
# handle ssl, wether from configuration or given args | ||
if 'ssl_certfile' in config and config.ssl_certfile: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That first test |
||
if 'ssl_options' not in kwargs: | ||
kwargs['ssl_options'] = {} | ||
if 'certfile' not in kwargs['ssl_options']: | ||
kwargs['ssl_options']['certfile'] = config.ssl_certfile | ||
|
||
if 'ssl_keyfile' in config and config.ssl_keyfile: | ||
if 'ssl_options' not in kwargs: | ||
kwargs['ssl_options'] = {} | ||
if 'keyfile' not in kwargs['ssl_options']: | ||
kwargs['ssl_options']['keyfile'] = config.ssl_keyfile | ||
|
||
# Create tornado application | ||
self._app = Application([(r"/flexx/ws/(.*)", WSHandler), | ||
(r"/flexx/(.*)", MainHandler), | ||
(r"/(.*)", AppHandler), ]) | ||
# Create tornado server, bound to our own ioloop | ||
self._server = HTTPServer(self._app, io_loop=self._loop) | ||
self._server = HTTPServer(self._app, io_loop=self._loop, **kwargs) | ||
|
||
# Start server (find free port number if port not given) | ||
if port: | ||
# Turn port into int, use hashed port number if a string was given | ||
|
@@ -100,7 +113,10 @@ def _open(self, host, port): | |
|
||
# Notify address, so its easy to e.g. copy and paste in the browser | ||
self._serving = self._app._flexx_serving = host, port | ||
logger.info('Serving apps at http://%s:%i/' % (host, port)) | ||
proto = 'http' | ||
if 'ssl_options' in kwargs: | ||
proto = 'https' | ||
logger.info('Serving apps at %s://%s:%i/' % (proto, host, port)) | ||
|
||
def _start(self): | ||
# Ensure that our loop is the current loop for this thread | ||
|
@@ -156,6 +172,13 @@ def server(self): | |
""" The Tornado HttpServer object being used.""" | ||
return self._server | ||
|
||
@property | ||
def protocol(self): | ||
""" Get a string representing served protocol.""" | ||
if self._server.ssl_options is not None: | ||
return 'https' | ||
|
||
return 'http' | ||
|
||
def port_hash(name): | ||
""" Given a string, returns a port number between 49152 and 65535 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
""" | ||
Flexx can be configured to use SSL. | ||
|
||
This example first creates a self-signed certificate and then uses it to create | ||
a SSL enabled web server (through Tornado ssl_option argument). | ||
|
||
Application served through this server is loaded on the browser with 'https' | ||
protocol and its websocket is using 'wss'. | ||
""" | ||
|
||
from flexx import app, ui | ||
|
||
# generate self-signed certificate for this example | ||
import os | ||
|
||
CERTFILE = '/tmp/self-signed.crt' | ||
KEYFILE = '/tmp/self-signed.key' | ||
|
||
os.system('openssl req -x509 -nodes -days 1 -batch -newkey rsa:2048 ' | ||
'-keyout %s -out %s' % (KEYFILE, CERTFILE)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity, if Flexx ever supports a web framework alternative to Tornado, would the same key and cert files be usable? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As long as this new web framework uses a certificate and key files, it should be fine. Since tornado's ssl_options is built from flex config variables id done in _tornadoserver.py, you would just need to use the same variables in the new server |
||
|
||
# Some very secret Model | ||
class Example(ui.Widget): | ||
def init(self): | ||
ui.Button(text='Secret Button') | ||
|
||
# configure web server for SSL | ||
app.create_server(ssl_options={'certfile' : CERTFILE, | ||
'keyfile' : KEYFILE}) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you please use |
||
# run application | ||
app.serve(Example, 'Example') | ||
app.run() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of setting ssl options via the config. In fact, I think we should advocate that as the way to do it. We can keep the
server_kwargs
, but can you please please remove the example in this docstring (I know I asked you to add it earlier, sorry!).