Skip to content

Commit f9047cc

Browse files
committed
Make whitelist hook configurable
1 parent 8ca70fe commit f9047cc

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

jupyter_server_proxy/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def load_jupyter_server_extension(nbapp):
2929
nbapp.web_app.add_handlers('.*', server_handlers)
3030

3131
# Set up default handler
32-
setup_handlers(nbapp.web_app)
32+
setup_handlers(nbapp.web_app, serverproxy.host_whitelist_hook)
3333

3434
launcher_entries = []
3535
icons = {}
@@ -40,4 +40,4 @@ def load_jupyter_server_extension(nbapp):
4040
nbapp.web_app.add_handlers('.*', [
4141
(ujoin(base_url, 'server-proxy/servers-info'), ServersInfoHandler, {'server_processes': server_proccesses}),
4242
(ujoin(base_url, 'server-proxy/icon/(.*)'), IconHandler, {'icons': icons})
43-
])
43+
])

jupyter_server_proxy/config.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Traitlets based configuration for jupyter_server_proxy
33
"""
44
from notebook.utils import url_path_join as ujoin
5-
from traitlets import Dict
5+
from traitlets import Any, Dict
66
from traitlets.config import Configurable
77
from .handlers import SuperviseAndProxyHandler, AddSlashHandler
88
import pkg_resources
@@ -162,3 +162,25 @@ class ServerProxy(Configurable):
162162
""",
163163
config=True
164164
)
165+
166+
host_whitelist_hook = Any(
167+
lambda handler, host: host in ['localhost', '127.0.0.1'],
168+
help="""
169+
Verify that a host should be proxied.
170+
171+
This should be a callable that checks whether a host should be proxied
172+
and returns True if so (False otherwise). It could be a very simple
173+
check that the host is present in a list of allowed hosts, or it could
174+
be a more complex verification against a regular expression. It should
175+
probably not be a slow check against an external service. Here is an
176+
example that could be placed in a site-wide Jupyter notebook config:
177+
178+
def hook(handler, host):
179+
handler.log.info("Request to proxy to host " + host)
180+
return host.startswith("10.")
181+
c.ServerProxy.host_whitelist_hook = hook
182+
183+
The default check is to return True if the host is localhost.
184+
""",
185+
config=True
186+
)

jupyter_server_proxy/handlers.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class ProxyHandler(WebSocketHandlerMixin, IPythonHandler):
4343
def __init__(self, *args, **kwargs):
4444
self.proxy_base = ''
4545
self.absolute_url = kwargs.pop('absolute_url', False)
46+
self.host_whitelist_hook = kwargs.pop('host_whitelist_hook',
47+
lambda handler, host: host in ['localhost', '127.0.0.1'])
4648
super().__init__(*args, **kwargs)
4749

4850
# Support all the methods that torando does by default except for GET which
@@ -168,9 +170,7 @@ def _build_proxy_request(self, host, port, proxied_path, body):
168170
return req
169171

170172
def _check_host_whitelist(self, host):
171-
# TODO Get whitelist from config
172-
whitelist = [r'localhost', r'127\.0\.0\.1']
173-
return any([bool(re.match(pattern, host)) for pattern in whitelist])
173+
return self.host_whitelist_hook(self, host)
174174

175175
@web.authenticated
176176
async def proxy(self, host, port, proxied_path):
@@ -521,17 +521,17 @@ def options(self, path):
521521
return self.proxy(self.port, path)
522522

523523

524-
def setup_handlers(web_app):
524+
def setup_handlers(web_app, host_whitelist_hook):
525525
host_pattern = '.*$'
526526
web_app.add_handlers('.*', [
527527
(url_path_join(web_app.settings['base_url'], r'/proxy/(\d+)(.*)'),
528528
LocalProxyHandler, {'absolute_url': False}),
529529
(url_path_join(web_app.settings['base_url'], r'/proxy/absolute/(\d+)(.*)'),
530530
LocalProxyHandler, {'absolute_url': True}),
531531
(url_path_join(web_app.settings['base_url'], r'/proxy/(.*):(\d+)(.*)'),
532-
RemoteProxyHandler, {'absolute_url': False}),
532+
RemoteProxyHandler, {'absolute_url': False, 'host_whitelist_hook': host_whitelist_hook}),
533533
(url_path_join(web_app.settings['base_url'], r'/proxy/absolute/(.*):(\d+)(.*)'),
534-
RemoteProxyHandler, {'absolute_url': True}),
534+
RemoteProxyHandler, {'absolute_url': True, 'host_whitelist_hook': host_whitelist_hook}),
535535
])
536536

537537
# vim: set et ts=4 sw=4:

0 commit comments

Comments
 (0)