Skip to content

Commit

Permalink
Redirect …/.well-known/{caldav,carddav} to /
Browse files Browse the repository at this point in the history
Closes Kozea#1200
  • Loading branch information
Unrud committed Jan 22, 2022
1 parent 10d2571 commit e4cc730
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
11 changes: 9 additions & 2 deletions radicale/app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,15 @@ def response(status: int, headers: types.WSGIResponseHeaders,
if not function:
return response(*httputils.METHOD_NOT_ALLOWED)

# If "/.well-known" is not available, clients query "/"
if path == "/.well-known" or path.startswith("/.well-known/"):
# Redirect all "…/.well-known/{caldav,carddav}" paths to "/".
# This shouldn't be necessary but some clients like TbSync require it.
# Status must be MOVED PERMANENTLY using FOUND causes problems
if (path.rstrip("/").endswith("/.well-known/caldav") or
path.rstrip("/").endswith("/.well-known/carddav")):
return response(*httputils.redirect(
base_prefix + "/", client.MOVED_PERMANENTLY))
# Return NOT FOUND for all other paths containing ".well-knwon"
if path.endswith("/.well-known") or "/.well-known/" in path:
return response(*httputils.NOT_FOUND)

# Ask authentication backend to check rights
Expand Down
21 changes: 19 additions & 2 deletions radicale/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1615,14 +1615,31 @@ def test_existence_of_root_collections(self) -> None:
self.delete("/")
self.propfind("/")

def test_well_known(self) -> None:
for path in ["/.well-known/caldav", "/.well-known/carddav"]:
for path in [path, "/foo" + path]:
_, headers, _ = self.request("GET", path, check=301)
assert headers.get("Location") == "/"

def test_well_known_script_name(self) -> None:
for path in ["/.well-known/caldav", "/.well-known/carddav"]:
for path in [path, "/foo" + path]:
_, headers, _ = self.request(
"GET", path, check=301, SCRIPT_NAME="/radicale")
assert headers.get("Location") == "/radicale/"

def test_well_known_not_found(self) -> None:
for path in ["/.well-known", "/.well-known/", "/.well-known/foo"]:
for path in [path, "/foo" + path]:
self.get(path, check=404)

def test_custom_headers(self) -> None:
self.configure({"headers": {"test": "123"}})
# Test if header is set on success
_, headers, _ = self.request("OPTIONS", "/", check=200)
assert headers.get("test") == "123"
# Test if header is set on failure
_, headers, _ = self.request("GET", "/.well-known/does not exist",
check=404)
_, headers, _ = self.request("GET", "/.well-known/foo", check=404)
assert headers.get("test") == "123"

@pytest.mark.skipif(sys.version_info < (3, 6),
Expand Down

0 comments on commit e4cc730

Please sign in to comment.