Skip to content

Commit

Permalink
Use 'absolute_url' as property instead of 'rewrite'
Browse files Browse the repository at this point in the history
Also make this work with websockets
  • Loading branch information
yuvipanda committed Jan 30, 2019
1 parent c1f409c commit 8e6ed7c
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 29 deletions.
26 changes: 26 additions & 0 deletions docs/server-process.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,32 @@ pairs.
* A callable that takes any :ref:`callable arguments <server-process/callable-argument>`,
and returns a dictionary of strings that are used & treated same as above.

#. **absolute_url**

*True* if the URL as seen by the proxied application should be the full URL
sent by the user. *False* if the URL as seen by the proxied application should
see the URL after the parts specific to jupyter-server-proxy have been stripped.

For example, with the following config:

.. code:: python
c.ServerProxy.servers = {
'test-server': {
'command': ['python3', '-m', 'http.server', '{port}'],
'absolute_url': False
}
}
When a user requests ``/test-server/some-url``, the proxied server will see it
as a request for ``/some-url`` - the ``/test-server`` part is stripped out.

If ``absolute_url`` is set to ``True`` instead, the proxied server will see it
as a request for ``/test-server/some-url`` instead - without any stripping.

This is very useful with applications that require a ``base_url`` to be set.


#. **launcher_entry**

A dictionary with options on if / how an entry in the classic Jupyter Notebook
Expand Down
16 changes: 8 additions & 8 deletions jupyter_server_proxy/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from collections import namedtuple
from .utils import call_with_asked_args

def _make_serverproxy_handler(name, command, environment, timeout, rewrite):
def _make_serverproxy_handler(name, command, environment, timeout, absolute_url):
"""
Create a SuperviseAndProxyHandler subclass with given parameters
"""
Expand All @@ -19,7 +19,7 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
self.proxy_base = name
self.rewrite = rewrite
self.absolute_url = absolute_url

@property
def process_args(self):
Expand Down Expand Up @@ -79,7 +79,7 @@ def make_handlers(base_url, server_processes):
sp.command,
sp.environment,
sp.timeout,
sp.rewrite,
sp.absolute_url,
)
handlers.append((
ujoin(base_url, sp.name, r'(.*)'), handler, dict(state={}),
Expand All @@ -91,7 +91,7 @@ def make_handlers(base_url, server_processes):

LauncherEntry = namedtuple('LauncherEntry', ['enabled', 'icon_path', 'title'])
ServerProcess = namedtuple('ServerProcess', [
'name', 'command', 'environment', 'timeout', 'rewrite', 'launcher_entry'])
'name', 'command', 'environment', 'timeout', 'absolute_url', 'launcher_entry'])

def make_server_process(name, server_process_config):
le = server_process_config.get('launcher_entry', {})
Expand All @@ -100,7 +100,7 @@ def make_server_process(name, server_process_config):
command=server_process_config['command'],
environment=server_process_config.get('environment', {}),
timeout=server_process_config.get('timeout', 5),
rewrite=server_process_config.get('rewrite', '/'),
absolute_url=server_process_config.get('absolute_url', False),
launcher_entry=LauncherEntry(
enabled=le.get('enabled', True),
icon_path=le.get('icon_path'),
Expand Down Expand Up @@ -134,9 +134,9 @@ class ServerProxy(Configurable):
timeout
Timeout in seconds for the process to become ready, default 5s.
rewrite
Proxy requests default to being rewritten to '/'. If this is ''
(empty) the absolute URL will be sent to the backend instead.
absolute_url
Proxy requests default to being rewritten to '/'. If this is True,
the absolute URL will be sent to the backend instead.
launcher_entry
A dictionary of various options for entries in classic notebook / jupyterlab launchers.
Expand Down
41 changes: 20 additions & 21 deletions jupyter_server_proxy/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class LocalProxyHandler(WebSocketHandlerMixin, IPythonHandler):

def __init__(self, *args, **kwargs):
self.proxy_base = ''
self.rewrite = kwargs.pop('rewrite', '/')
self.absolute_url = kwargs.pop('absolute_url', False)
super().__init__(*args, **kwargs)

async def open(self, port, proxied_path=''):
Expand All @@ -45,13 +45,7 @@ async def open(self, port, proxied_path=''):
if not proxied_path.startswith('/'):
proxied_path = '/' + proxied_path

client_uri = '{uri}:{port}{path}'.format(
uri='ws://127.0.0.1',
port=port,
path=proxied_path
)
if self.request.query:
client_uri += '?' + self.request.query
client_uri = self.get_client_uri('ws', port, proxied_path)
headers = self.request.headers

def message_cb(message):
Expand Down Expand Up @@ -142,32 +136,37 @@ def _get_context_path(self, port):
"""
if self.proxy_base:
return url_path_join(self.base_url, self.proxy_base)
if self.rewrite == '/':
return url_path_join(self.base_url, 'proxy', str(port))
if self.rewrite == '':
if self.absolute_url:
return url_path_join(self.base_url, 'proxy', 'absolute', str(port))
raise ValueError('Unsupported rewrite: "{}"'.format(self.rewrite))
else:
return url_path_join(self.base_url, 'proxy', str(port))

def _build_proxy_request(self, port, proxied_path, body):
def get_client_uri(self, protocol, port, proxied_path):
context_path = self._get_context_path(port)
if self.rewrite:
client_path = proxied_path
else:
if self.absolute_url:
client_path = url_path_join(context_path, proxied_path)
else:
client_path = proxied_path

client_uri = '{uri}:{port}{path}'.format(
uri='http://localhost',
client_uri = '{protocol}://{host}:{port}{path}'.format(
protocol=protocol,
host='localhost',
port=port,
path=client_path
)
if self.request.query:
client_uri += '?' + self.request.query

return client_uri

def _build_proxy_request(self, port, proxied_path, body):

headers = self.proxy_request_headers()

client_uri = self.get_client_uri('http', port, proxied_path)
# Some applications check X-Forwarded-Context and X-ProxyContextPath
# headers to see if and where they are being proxied from.
if self.rewrite == '/':
if not self.absolute_url:
headers['X-Forwarded-Context'] = context_path
headers['X-ProxyContextPath'] = context_path

Expand Down Expand Up @@ -412,9 +411,9 @@ def setup_handlers(web_app):
host_pattern = '.*$'
web_app.add_handlers('.*', [
(url_path_join(web_app.settings['base_url'], r'/proxy/(\d+)(.*)'),
LocalProxyHandler, {'rewrite': '/'}),
LocalProxyHandler, {'absolute_url': False}),
(url_path_join(web_app.settings['base_url'], r'/proxy/absolute/(\d+)(.*)'),
LocalProxyHandler, {'rewrite': ''}),
LocalProxyHandler, {'absolute_url': True}),
])

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

0 comments on commit 8e6ed7c

Please sign in to comment.