Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use default redirect when nothing matches. #89

Merged
merged 1 commit into from
Feb 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions tests/test_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ def test_redirect_with_mime_match(self, urihandler):
def test_redirect_with_mime_no_match(self, urihandler):
req = testing.DummyRequest(accept="application/pdf")
req.host_url = "http://test.urihandler.org"
with pytest.raises(HTTPNotAcceptable):
urihandler.handle("http://test.urihandler.org/foobar/18", req)
res = urihandler.handle("http://test.urihandler.org/foobar/18", req)
assert res == "http://localhost:5555/foobar/18"

def test_redirect_default_mime(self, urihandler):
def test_redirect_default_set(self, urihandler):
req = testing.DummyRequest()
req.host_url = "http://test.urihandler.org"
res = urihandler.handle("http://test.urihandler.org/pdf_default/18", req)
Expand All @@ -54,12 +54,17 @@ def test_redirect_default_mime(self, urihandler):
res = urihandler.handle("http://test.urihandler.org/pdf_default/18", req)
assert res == "http://localhost:5555/pdf_default/18.json"

def test_redirect_no_default_mime(self, urihandler):
def test_redirect_no_default(self, urihandler):
req = testing.DummyRequest()
req.host_url = "http://test.urihandler.org"
with pytest.raises(HTTPNotAcceptable):
urihandler.handle("http://test.urihandler.org/mime_no_default/18", req)

req = testing.DummyRequest(accept="application/pdf")
req.host_url = "http://test.urihandler.org"
with pytest.raises(HTTPNotAcceptable):
urihandler.handle("http://test.urihandler.org/mime_no_default/18", req)

def test_unanchored_redirect(self, urihandler):
req = testing.DummyRequest()
req.host_url = "http://test.urihandler.org"
Expand Down
39 changes: 28 additions & 11 deletions urihandler/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,39 @@ def handle(self, uri, request):
if m:
redirect = u["redirect"]
if isinstance(redirect, dict):
if isinstance(request.accept, AcceptNoHeader):
redirect = redirect.get("default")
if not redirect:
raise HTTPNotAcceptable()
else:
for mime, redirect in redirect.items():
if mime in request.accept:
break
else:
# No matching mime was found.
raise HTTPNotAcceptable()
redirect = self._get_redirect_based_on_accept_header(
request.accept, redirect
)
redirect = redirect.format(**m.groupdict())
log.debug(f"Match found. Redirecting to {redirect}.")
return redirect
return None

def _get_redirect_based_on_accept_header(self, accept_header, redirect_rule):
"""
Return the redirect rule based on accept header.

At its core it simply looks for a matching mime between accept header
and the configured mime type redirects. But exceptions apply.

If there is no accept header specified or if no matching mime is found,
the default will be returned. If default is not set, HTTP 406 gets raised.
"""
default = redirect_rule.get("default")
if isinstance(accept_header, AcceptNoHeader):
if not default:
raise HTTPNotAcceptable()
return default

for mime, redirect in redirect_rule.items():
if mime in accept_header:
return redirect

if not default:
raise HTTPNotAcceptable()

return default


def _build_uri_handler(registry, handlerconfig):
"""
Expand Down