@@ -28,14 +28,17 @@ def get(self, *args):
2828 dest = src ._replace (path = src .path + '/' )
2929 self .redirect (urlunparse (dest ))
3030
31- class LocalProxyHandler (WebSocketHandlerMixin , IPythonHandler ):
32-
31+ class ProxyHandler (WebSocketHandlerMixin , IPythonHandler ):
32+ """
33+ A tornado request handler that proxies HTTP and websockets from
34+ a given host/port combination.
35+ """
3336 def __init__ (self , * args , ** kwargs ):
3437 self .proxy_base = ''
3538 self .absolute_url = kwargs .pop ('absolute_url' , False )
3639 super ().__init__ (* args , ** kwargs )
3740
38- async def open (self , port , proxied_path = '' ):
41+ async def open (self , host , port , proxied_path = '' ):
3942 """
4043 Called when a client opens a websocket connection.
4144
@@ -45,7 +48,7 @@ async def open(self, port, proxied_path=''):
4548 if not proxied_path .startswith ('/' ):
4649 proxied_path = '/' + proxied_path
4750
48- client_uri = self .get_client_uri ('ws' , port , proxied_path )
51+ client_uri = self .get_client_uri ('ws' , host , port , proxied_path )
4952 headers = self .request .headers
5053
5154 def message_cb (message ):
@@ -141,7 +144,7 @@ def _get_context_path(self, port):
141144 else :
142145 return url_path_join (self .base_url , 'proxy' , str (port ))
143146
144- def get_client_uri (self , protocol , port , proxied_path ):
147+ def get_client_uri (self , protocol , host , port , proxied_path ):
145148 context_path = self ._get_context_path (port )
146149 if self .absolute_url :
147150 client_path = url_path_join (context_path , proxied_path )
@@ -150,7 +153,7 @@ def get_client_uri(self, protocol, port, proxied_path):
150153
151154 client_uri = '{protocol}://{host}:{port}{path}' .format (
152155 protocol = protocol ,
153- host = 'localhost' ,
156+ host = host ,
154157 port = port ,
155158 path = client_path
156159 )
@@ -159,11 +162,11 @@ def get_client_uri(self, protocol, port, proxied_path):
159162
160163 return client_uri
161164
162- def _build_proxy_request (self , port , proxied_path , body ):
165+ def _build_proxy_request (self , host , port , proxied_path , body ):
163166
164167 headers = self .proxy_request_headers ()
165168
166- client_uri = self .get_client_uri ('http' , port , proxied_path )
169+ client_uri = self .get_client_uri ('http' , host , port , proxied_path )
167170 # Some applications check X-Forwarded-Context and X-ProxyContextPath
168171 # headers to see if and where they are being proxied from.
169172 if not self .absolute_url :
@@ -177,7 +180,7 @@ def _build_proxy_request(self, port, proxied_path, body):
177180 return req
178181
179182 @web .authenticated
180- async def proxy (self , port , proxied_path ):
183+ async def proxy (self , host , port , proxied_path ):
181184 '''
182185 This serverextension handles:
183186 {base_url}/proxy/{port([0-9]+)}/{proxied_path}
@@ -205,7 +208,7 @@ async def proxy(self, port, proxied_path):
205208
206209 client = httpclient .AsyncHTTPClient ()
207210
208- req = self ._build_proxy_request (port , proxied_path , body )
211+ req = self ._build_proxy_request (host , port , proxied_path , body )
209212 response = await client .fetch (req , raise_error = False )
210213 # record activity at start and end of requests
211214 self ._record_activity ()
@@ -242,27 +245,27 @@ def proxy_request_options(self):
242245 # Support all the methods that torando does by default except for GET which
243246 # is passed to WebSocketHandlerMixin and then to WebSocketHandler.
244247
245- async def http_get (self , port , proxy_path = '' ):
248+ async def http_get (self , host , port , proxy_path = '' ):
246249 '''Our non-websocket GET.'''
247- return await self .proxy (port , proxy_path )
250+ return await self .proxy (host , port , proxy_path )
248251
249- def post (self , port , proxy_path = '' ):
250- return self .proxy (port , proxy_path )
252+ def post (self , host , port , proxy_path = '' ):
253+ return self .proxy (host , port , proxy_path )
251254
252255 def put (self , port , proxy_path = '' ):
253- return self .proxy (port , proxy_path )
256+ return self .proxy (host , port , proxy_path )
254257
255- def delete (self , port , proxy_path = '' ):
256- return self .proxy (port , proxy_path )
258+ def delete (self , host , port , proxy_path = '' ):
259+ return self .proxy (host , port , proxy_path )
257260
258- def head (self , port , proxy_path = '' ):
259- return self .proxy (port , proxy_path )
261+ def head (self , host , port , proxy_path = '' ):
262+ return self .proxy (host , port , proxy_path )
260263
261- def patch (self , port , proxy_path = '' ):
262- return self .proxy (port , proxy_path )
264+ def patch (self , host , port , proxy_path = '' ):
265+ return self .proxy (host , port , proxy_path )
263266
264- def options (self , port , proxy_path = '' ):
265- return self .proxy (port , proxy_path )
267+ def options (self , host , port , proxy_path = '' ):
268+ return self .proxy (host , port , proxy_path )
266269
267270 def check_xsrf_cookie (self ):
268271 '''
@@ -280,6 +283,40 @@ def select_subprotocol(self, subprotocols):
280283 return super ().select_subprotocol (subprotocols )
281284
282285
286+ class LocalProxyHandler (ProxyHandler ):
287+ """
288+ A tornado request handler that proxies HTTP and websockets
289+ from a port on the local system. Same as the above ProxyHandler,
290+ but specific to 'localhost'.
291+ """
292+ async def http_get (self , port , proxied_path ):
293+ return await self .proxy (port , proxied_path )
294+
295+ async def open (self , port , proxied_path ):
296+ return await super ().open ('localhost' , port , proxied_path )
297+
298+ def post (self , port , proxied_path ):
299+ return self .proxy (port , proxied_path )
300+
301+ def put (self , port , proxied_path ):
302+ return self .proxy (port , proxied_path )
303+
304+ def delete (self , port , proxied_path ):
305+ return self .proxy (port , proxied_path )
306+
307+ def head (self , port , proxied_path ):
308+ return self .proxy (port , proxied_path )
309+
310+ def patch (self , port , proxied_path ):
311+ return self .proxy (port , proxied_path )
312+
313+ def options (self , port , proxied_path ):
314+ return self .proxy (port , proxied_path )
315+
316+ def proxy (self , port , proxied_path ):
317+ return super ().proxy ('localhost' , port , proxied_path )
318+
319+
283320# FIXME: Move this to its own file. Too many packages now import this from nbrserverproxy.handlers
284321class SuperviseAndProxyHandler (LocalProxyHandler ):
285322 '''Manage a given process and requests to it '''
0 commit comments