Redirect GET and HEAD requests to sanitized path
This commit is contained in:
parent
6dee974b74
commit
b93842b10c
@ -161,6 +161,9 @@ class Application(ApplicationPartDelete, ApplicationPartHead,
|
|||||||
# Return response content
|
# Return response content
|
||||||
return status_text, list(headers.items()), answers
|
return status_text, list(headers.items()), answers
|
||||||
|
|
||||||
|
time_begin = datetime.datetime.now()
|
||||||
|
request_method = environ["REQUEST_METHOD"].upper()
|
||||||
|
unsafe_path = environ.get("PATH_INFO", "")
|
||||||
remote_host = "unknown"
|
remote_host = "unknown"
|
||||||
if environ.get("REMOTE_HOST"):
|
if environ.get("REMOTE_HOST"):
|
||||||
remote_host = repr(environ["REMOTE_HOST"])
|
remote_host = repr(environ["REMOTE_HOST"])
|
||||||
@ -175,10 +178,8 @@ class Application(ApplicationPartDelete, ApplicationPartHead,
|
|||||||
depthinfo = ""
|
depthinfo = ""
|
||||||
if environ.get("HTTP_DEPTH"):
|
if environ.get("HTTP_DEPTH"):
|
||||||
depthinfo = " with depth %r" % environ["HTTP_DEPTH"]
|
depthinfo = " with depth %r" % environ["HTTP_DEPTH"]
|
||||||
time_begin = datetime.datetime.now()
|
logger.info("%s request for %r%s received from %s%s",
|
||||||
logger.info(
|
request_method, unsafe_path, depthinfo,
|
||||||
"%s request for %r%s received from %s%s",
|
|
||||||
environ["REQUEST_METHOD"], environ.get("PATH_INFO", ""), depthinfo,
|
|
||||||
remote_host, remote_useragent)
|
remote_host, remote_useragent)
|
||||||
logger.debug("Request headers:\n%s",
|
logger.debug("Request headers:\n%s",
|
||||||
pprint.pformat(self._scrub_headers(environ)))
|
pprint.pformat(self._scrub_headers(environ)))
|
||||||
@ -191,12 +192,19 @@ class Application(ApplicationPartDelete, ApplicationPartHead,
|
|||||||
logger.debug("Base prefix: %r", base_prefix)
|
logger.debug("Base prefix: %r", base_prefix)
|
||||||
# Sanitize request URI (a WSGI server indicates with an empty path,
|
# Sanitize request URI (a WSGI server indicates with an empty path,
|
||||||
# that the URL targets the application root without a trailing slash)
|
# that the URL targets the application root without a trailing slash)
|
||||||
path = pathutils.sanitize_path(environ.get("PATH_INFO", ""))
|
path = pathutils.sanitize_path(unsafe_path)
|
||||||
|
if unsafe_path != path and request_method in ["GET", "HEAD"]:
|
||||||
|
location = base_prefix + path
|
||||||
|
logger.info("Redirecting to sanitized path: %r ==> %r",
|
||||||
|
base_prefix + unsafe_path, location)
|
||||||
|
return response(
|
||||||
|
client.MOVED_PERMANENTLY,
|
||||||
|
{"Location": location, "Content-Type": "text/plain"},
|
||||||
|
"Redirected to %s" % location)
|
||||||
logger.debug("Sanitized path: %r", path)
|
logger.debug("Sanitized path: %r", path)
|
||||||
|
|
||||||
# Get function corresponding to method
|
# Get function corresponding to method
|
||||||
function = getattr(
|
function = getattr(self, "do_%s" % request_method, None)
|
||||||
self, "do_%s" % environ["REQUEST_METHOD"].upper(), None)
|
|
||||||
if not function:
|
if not function:
|
||||||
return response(*httputils.METHOD_NOT_ALLOWED)
|
return response(*httputils.METHOD_NOT_ALLOWED)
|
||||||
|
|
||||||
|
@ -62,13 +62,10 @@ class ApplicationPartGet(ApplicationBase):
|
|||||||
"""Manage GET request."""
|
"""Manage GET request."""
|
||||||
# Redirect to .web if the root URL is requested
|
# Redirect to .web if the root URL is requested
|
||||||
if not pathutils.strip_path(path):
|
if not pathutils.strip_path(path):
|
||||||
web_path = ".web"
|
location = ".web"
|
||||||
if not environ.get("PATH_INFO"):
|
|
||||||
web_path = posixpath.join(posixpath.basename(base_prefix),
|
|
||||||
web_path)
|
|
||||||
return (client.FOUND,
|
return (client.FOUND,
|
||||||
{"Location": web_path, "Content-Type": "text/plain"},
|
{"Location": location, "Content-Type": "text/plain"},
|
||||||
"Redirected to %s" % web_path)
|
"Redirected to %s" % location)
|
||||||
# Dispatch .web URL to web module
|
# Dispatch .web URL to web module
|
||||||
if path == "/.web" or path.startswith("/.web/"):
|
if path == "/.web" or path.startswith("/.web/"):
|
||||||
return self._web.get(environ, base_prefix, path, user)
|
return self._web.get(environ, base_prefix, path, user)
|
||||||
|
@ -60,8 +60,15 @@ permissions: RrWw""")
|
|||||||
"""GET request at "/" with SCRIPT_NAME."""
|
"""GET request at "/" with SCRIPT_NAME."""
|
||||||
_, answer = self.get("/", check=302, SCRIPT_NAME="/radicale")
|
_, answer = self.get("/", check=302, SCRIPT_NAME="/radicale")
|
||||||
assert answer == "Redirected to .web"
|
assert answer == "Redirected to .web"
|
||||||
_, answer = self.get("", check=302, SCRIPT_NAME="/radicale")
|
|
||||||
assert answer == "Redirected to radicale/.web"
|
def test_sanitized_path(self) -> None:
|
||||||
|
"""GET request with unsanitized paths."""
|
||||||
|
for path, sane_path in [("//", "/"), ("", "/"), ("/a//b", "/a/b"),
|
||||||
|
("/a//b/", "/a/b/")]:
|
||||||
|
_, answer = self.get(path, check=301)
|
||||||
|
assert answer == "Redirected to %s" % sane_path
|
||||||
|
_, answer = self.get(path, check=301, SCRIPT_NAME="/radicale")
|
||||||
|
assert answer == "Redirected to /radicale%s" % sane_path
|
||||||
|
|
||||||
def test_add_event(self) -> None:
|
def test_add_event(self) -> None:
|
||||||
"""Add an event."""
|
"""Add an event."""
|
||||||
|
@ -28,7 +28,7 @@ const SERVER = location.origin;
|
|||||||
* @const
|
* @const
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
const ROOT_PATH = location.pathname.replace(new RegExp("/+[^/]+/*(/index\\.html?)?$"), "") + '/';
|
const ROOT_PATH = (new URL("..", location.href)).pathname;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regex to match and normalize color
|
* Regex to match and normalize color
|
||||||
|
Loading…
Reference in New Issue
Block a user