@@ -209,12 +209,16 @@ def _get_context_path(self, host, port):
209
209
return url_path_join (self .base_url , 'proxy' , host_and_port )
210
210
211
211
def get_client_uri (self , protocol , host , port , proxied_path ):
212
- context_path = self ._get_context_path (host , port )
213
212
if self .absolute_url :
213
+ context_path = self ._get_context_path (host , port )
214
214
client_path = url_path_join (context_path , proxied_path )
215
215
else :
216
216
client_path = proxied_path
217
217
218
+ # ensure client_path always starts with '/'
219
+ if not client_path .startswith ("/" ):
220
+ client_path = "/" + client_path
221
+
218
222
# Quote spaces, åäö and such, but only enough to send a valid web
219
223
# request onwards. To do this, we mark the RFC 3986 specs' "reserved"
220
224
# and "un-reserved" characters as safe that won't need quoting. The
@@ -228,7 +232,7 @@ def get_client_uri(self, protocol, host, port, proxied_path):
228
232
protocol = protocol ,
229
233
host = host ,
230
234
port = port ,
231
- path = client_path
235
+ path = client_path ,
232
236
)
233
237
if self .request .query :
234
238
client_uri += '?' + self .request .query
@@ -297,13 +301,14 @@ async def proxy(self, host, port, proxied_path):
297
301
client = httpclient .AsyncHTTPClient ()
298
302
299
303
req = self ._build_proxy_request (host , port , proxied_path , body )
304
+ self .log .debug (f"Proxying request to { req .url } " )
300
305
301
306
try :
302
307
# Here, "response" is a tornado.httpclient.HTTPResponse object.
303
308
response = await client .fetch (req , raise_error = False )
304
309
except httpclient .HTTPError as err :
305
310
# We need to capture the timeout error even with raise_error=False,
306
- # because it only affects the HTTPError raised when a non-200 response
311
+ # because it only affects the HTTPError raised when a non-200 response
307
312
# code is used, instead of suppressing all errors.
308
313
# Ref: https://www.tornadoweb.org/en/stable/httpclient.html#tornado.httpclient.AsyncHTTPClient.fetch
309
314
if err .code == 599 :
@@ -324,7 +329,7 @@ async def proxy(self, host, port, proxied_path):
324
329
else :
325
330
# Represent the original response as a RewritableResponse object.
326
331
original_response = RewritableResponse (orig_response = response )
327
-
332
+
328
333
# The function (or list of functions) which should be applied to modify the
329
334
# response.
330
335
rewrite_response = self .rewrite_response
@@ -688,53 +693,57 @@ def options(self, path):
688
693
def setup_handlers (web_app , serverproxy_config ):
689
694
host_allowlist = serverproxy_config .host_allowlist
690
695
rewrite_response = serverproxy_config .non_service_rewrite_response
691
- web_app .add_handlers ('.*' , [
692
- (
693
- url_path_join (
694
- web_app .settings ['base_url' ],
695
- r'/proxy/([^/]*):(\d+)(.*)' ,
696
+ web_app .add_handlers (
697
+ ".*" ,
698
+ [
699
+ (
700
+ url_path_join (
701
+ web_app .settings ["base_url" ],
702
+ r"/proxy/([^/:@]+):(\d+)(/.*|)" ,
703
+ ),
704
+ RemoteProxyHandler ,
705
+ {
706
+ "absolute_url" : False ,
707
+ "host_allowlist" : host_allowlist ,
708
+ "rewrite_response" : rewrite_response ,
709
+ },
696
710
),
697
- RemoteProxyHandler ,
698
- {
699
- 'absolute_url' : False ,
700
- 'host_allowlist' : host_allowlist ,
701
- 'rewrite_response' : rewrite_response ,
702
- }
703
- ),
704
- (
705
- url_path_join (
706
- web_app . settings [ 'base_url' ] ,
707
- r'/proxy/absolute/([^/]*):(\d+)(.*)' ,
711
+ (
712
+ url_path_join (
713
+ web_app . settings [ "base_url" ] ,
714
+ r"/proxy/absolute/([^/:@]+):(\d+)(/.*|)" ,
715
+ ) ,
716
+ RemoteProxyHandler ,
717
+ {
718
+ "absolute_url" : True ,
719
+ "host_allowlist" : host_allowlist ,
720
+ "rewrite_response" : rewrite_response ,
721
+ } ,
708
722
),
709
- RemoteProxyHandler ,
710
- {
711
- 'absolute_url' : True ,
712
- 'host_allowlist' : host_allowlist ,
713
- 'rewrite_response' : rewrite_response ,
714
- }
715
- ),
716
- (
717
- url_path_join (
718
- web_app .settings ['base_url' ],
719
- r'/proxy/(\d+)(.*)' ,
723
+ (
724
+ url_path_join (
725
+ web_app .settings ["base_url" ],
726
+ r"/proxy/(\d+)(/.*|)" ,
727
+ ),
728
+ LocalProxyHandler ,
729
+ {
730
+ "absolute_url" : False ,
731
+ "rewrite_response" : rewrite_response ,
732
+ },
720
733
),
721
- LocalProxyHandler ,
722
- {
723
- 'absolute_url' : False ,
724
- 'rewrite_response' : rewrite_response ,
725
- } ,
726
- ) ,
727
- (
728
- url_path_join (
729
- web_app . settings [ 'base_url' ] ,
730
- r'/proxy/absolute/(\d+)(.*)' ,
734
+ (
735
+ url_path_join (
736
+ web_app . settings [ "base_url" ] ,
737
+ r"/proxy/absolute/(\d+)(/.*|)" ,
738
+ ) ,
739
+ LocalProxyHandler ,
740
+ {
741
+ "absolute_url" : True ,
742
+ "rewrite_response" : rewrite_response ,
743
+ } ,
731
744
),
732
- LocalProxyHandler ,
733
- {
734
- 'absolute_url' : True ,
735
- 'rewrite_response' : rewrite_response ,
736
- },
737
- ),
738
- ])
745
+ ],
746
+ )
747
+
739
748
740
749
# vim: set et ts=4 sw=4:
0 commit comments