Skip to content

Commit 5fae676

Browse files
committed
Don't rewrite Location when absolute_url is True.
1 parent 0a32659 commit 5fae676

File tree

3 files changed

+46
-7
lines changed

3 files changed

+46
-7
lines changed

jupyter_server_proxy/handlers.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -578,13 +578,13 @@ def rewrite_pe(rewritable_response: RewritableResponse):
578578
self._headers = httputil.HTTPHeaders()
579579
for header, v in rewritten_response.headers.get_all():
580580
if header not in ("Content-Length", "Transfer-Encoding", "Connection"):
581-
# Rewrite Location header in redirects to preserve proxy prefix
582-
if header == "Location" and rewritten_response.code in (
583-
301,
584-
302,
585-
303,
586-
307,
587-
308,
581+
# Rewrite Location header in redirects to preserve proxy prefix.
582+
# If absolute_url is True, the backend already sees the
583+
# full path and handles redirects appropriately.
584+
if (
585+
header == "Location"
586+
and not self.absolute_url
587+
and rewritten_response.code in (301, 302, 303, 307, 308)
588588
):
589589
v = self._rewrite_location_header(v, host, port, proxied_path)
590590
# some header appear multiple times, eg 'Set-Cookie'

tests/resources/jupyter_server_config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ def my_env():
146146
"python-redirect": {
147147
"command": [sys.executable, _get_path("redirectserver.py"), "--port={port}"],
148148
},
149+
"python-redirect-abs": {
150+
"command": [sys.executable, _get_path("redirectserver.py"), "--port={port}"],
151+
"absolute_url": True,
152+
},
149153
}
150154

151155
c.ServerProxy.non_service_rewrite_response = hello_to_foo

tests/test_proxies.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,3 +558,38 @@ def test_server_proxy_redirect_location_header_rewrite(
558558
# Should be rewritten to include the proxy prefix
559559
# The token query parameter should be preserved in the redirect
560560
assert location == f"/python-redirect/target/path?token={TOKEN}"
561+
562+
563+
@pytest.mark.parametrize("a_server", ["notebook", "lab"], indirect=True)
564+
def test_server_proxy_redirect_location_header_absolute_url(
565+
a_server_port_and_token: Tuple[int, str],
566+
) -> None:
567+
"""
568+
Test that Location headers in redirect responses are not rewritten when
569+
absolute_url=True is configured.
570+
571+
When absolute_url=True, the backend server receives the full proxy path
572+
(e.g., /python-redirect-abs/mydir instead of just /mydir). The proxy does
573+
not rewrite Location headers, passing them through as-is from the backend.
574+
575+
This means the backend must be aware of the proxy prefix to generate
576+
correct redirects, which is the intended behavior of absolute_url=True.
577+
"""
578+
PORT, TOKEN = a_server_port_and_token
579+
580+
# Test 1: Named server proxy with absolute_url=True, redirect without trailing slash
581+
r = request_get(PORT, "/python-redirect-abs/mydir", TOKEN)
582+
assert r.code == 301
583+
location = r.headers.get("Location")
584+
# Location header is not rewritten by proxy, passed through as-is from backend
585+
# Backend sees /python-redirect-abs/mydir and adds trailing slash: /python-redirect-abs/mydir/
586+
assert location == f"/python-redirect-abs/mydir/?token={TOKEN}"
587+
588+
# Test 2: Named server proxy with absolute_url=True, verify no rewriting occurs
589+
# Request to /python-redirect-abs/abc (without trailing slash)
590+
r = request_get(PORT, "/python-redirect-abs/abc", TOKEN)
591+
assert r.code == 301
592+
location = r.headers.get("Location")
593+
# Backend returns whatever it wants, proxy doesn't rewrite it
594+
# In this case, backend adds trailing slash to the full path it received
595+
assert location == f"/python-redirect-abs/abc/?token={TOKEN}"

0 commit comments

Comments
 (0)