Merge *base_prefix config keys into base_prefix (fixes #996)
This commit is contained in:
parent
eaa969a05c
commit
bf8e874e4d
6
config
6
config
@ -27,10 +27,8 @@ certificate = /etc/apache2/ssl/server.crt
|
|||||||
key = /etc/apache2/ssl/server.key
|
key = /etc/apache2/ssl/server.key
|
||||||
# Reverse DNS to resolve client address in logs
|
# Reverse DNS to resolve client address in logs
|
||||||
dns_lookup = True
|
dns_lookup = True
|
||||||
# base URL if / is not the CalDAV root. If set, must start with /
|
# Root URL of Radicale (starting and ending with a slash)
|
||||||
base_prefix =
|
base_prefix = /
|
||||||
# base URL if Radicale is running with / as CalDAV root, but in a subdir behind a proxy (like nginx). If set, must start with /
|
|
||||||
proxy_base_prefix =
|
|
||||||
|
|
||||||
|
|
||||||
[encoding]
|
[encoding]
|
||||||
|
@ -246,9 +246,17 @@ class Application(object):
|
|||||||
headers = pprint.pformat(self.headers_log(environ))
|
headers = pprint.pformat(self.headers_log(environ))
|
||||||
log.LOGGER.debug("Request headers:\n%s" % headers)
|
log.LOGGER.debug("Request headers:\n%s" % headers)
|
||||||
|
|
||||||
|
base_prefix = config.get("server", "base_prefix")
|
||||||
|
if environ["PATH_INFO"].startswith(base_prefix):
|
||||||
# Sanitize request URI
|
# Sanitize request URI
|
||||||
environ["PATH_INFO"] = self.sanitize_uri(environ["PATH_INFO"])
|
environ["PATH_INFO"] = self.sanitize_uri(
|
||||||
|
"/%s" % environ["PATH_INFO"][len(base_prefix):])
|
||||||
log.LOGGER.debug("Sanitized path: %s", environ["PATH_INFO"])
|
log.LOGGER.debug("Sanitized path: %s", environ["PATH_INFO"])
|
||||||
|
else:
|
||||||
|
# Request path not starting with base_prefix, not allowed
|
||||||
|
log.LOGGER.debug(
|
||||||
|
"Path not starting with prefix: %s", environ["PATH_INFO"])
|
||||||
|
environ["PATH_INFO"] = None
|
||||||
|
|
||||||
# Get content
|
# Get content
|
||||||
content_length = int(environ.get("CONTENT_LENGTH") or 0)
|
content_length = int(environ.get("CONTENT_LENGTH") or 0)
|
||||||
|
@ -146,6 +146,9 @@ def run():
|
|||||||
finally:
|
finally:
|
||||||
shutdown_program.set()
|
shutdown_program.set()
|
||||||
|
|
||||||
|
log.LOGGER.debug(
|
||||||
|
"Base URL prefix: %s" % config.get("server", "base_prefix"))
|
||||||
|
|
||||||
# Start the servers in a different loop to avoid possible race-conditions,
|
# Start the servers in a different loop to avoid possible race-conditions,
|
||||||
# when a server exists but another server is added to the list at the same
|
# when a server exists but another server is added to the list at the same
|
||||||
# time
|
# time
|
||||||
|
@ -46,8 +46,7 @@ INITIAL_CONFIG = {
|
|||||||
"certificate": "/etc/apache2/ssl/server.crt",
|
"certificate": "/etc/apache2/ssl/server.crt",
|
||||||
"key": "/etc/apache2/ssl/server.key",
|
"key": "/etc/apache2/ssl/server.key",
|
||||||
"dns_lookup": "True",
|
"dns_lookup": "True",
|
||||||
"base_prefix": "",
|
"base_prefix": "/"},
|
||||||
"proxy_base_prefix": ""},
|
|
||||||
"encoding": {
|
"encoding": {
|
||||||
"request": "utf-8",
|
"request": "utf-8",
|
||||||
"stock": "utf-8"},
|
"stock": "utf-8"},
|
||||||
|
@ -203,6 +203,10 @@ class Collection(object):
|
|||||||
The ``path`` is relative.
|
The ``path`` is relative.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
# path == None means wrong URL
|
||||||
|
if path is None:
|
||||||
|
return []
|
||||||
|
|
||||||
# First do normpath and then strip, to prevent access to FOLDER/../
|
# First do normpath and then strip, to prevent access to FOLDER/../
|
||||||
sane_path = posixpath.normpath(path.replace(os.sep, "/")).strip("/")
|
sane_path = posixpath.normpath(path.replace(os.sep, "/")).strip("/")
|
||||||
attributes = sane_path.split("/")
|
attributes = sane_path.split("/")
|
||||||
@ -490,7 +494,7 @@ class Collection(object):
|
|||||||
@property
|
@property
|
||||||
def url(self):
|
def url(self):
|
||||||
"""Get the standard collection URL."""
|
"""Get the standard collection URL."""
|
||||||
return "/%s/" % self.path
|
return "%s/" % self.path
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def version(self):
|
def version(self):
|
||||||
|
@ -119,9 +119,9 @@ def _response(code):
|
|||||||
return "HTTP/1.1 %i %s" % (code, client.responses[code])
|
return "HTTP/1.1 %i %s" % (code, client.responses[code])
|
||||||
|
|
||||||
|
|
||||||
def _href_with_proxy_base_prefix(href):
|
def _href(href):
|
||||||
href = "%s%s" % (config.get("server", "proxy_base_prefix"), href)
|
"""Return prefixed href."""
|
||||||
return href.replace("//", "/")
|
return "%s%s" % (config.get("server", "base_prefix"), href.lstrip("/"))
|
||||||
|
|
||||||
|
|
||||||
def name_from_path(path, collection):
|
def name_from_path(path, collection):
|
||||||
@ -179,7 +179,7 @@ def delete(path, collection):
|
|||||||
multistatus.append(response)
|
multistatus.append(response)
|
||||||
|
|
||||||
href = ET.Element(_tag("D", "href"))
|
href = ET.Element(_tag("D", "href"))
|
||||||
href.text = _href_with_proxy_base_prefix(path)
|
href.text = _href(path)
|
||||||
response.append(href)
|
response.append(href)
|
||||||
|
|
||||||
status = ET.Element(_tag("D", "status"))
|
status = ET.Element(_tag("D", "status"))
|
||||||
@ -231,11 +231,8 @@ def _propfind_response(path, item, props, user):
|
|||||||
response = ET.Element(_tag("D", "response"))
|
response = ET.Element(_tag("D", "response"))
|
||||||
|
|
||||||
href = ET.Element(_tag("D", "href"))
|
href = ET.Element(_tag("D", "href"))
|
||||||
if is_collection:
|
uri = item.url if is_collection else "%s/%s" % (path, item.name)
|
||||||
uri = "%s%s" % (config.get("server", "base_prefix"), item.url)
|
href.text = _href(uri.replace("//", "/"))
|
||||||
else:
|
|
||||||
uri = "%s/%s" % (path, item.name)
|
|
||||||
href.text = _href_with_proxy_base_prefix(uri)
|
|
||||||
response.append(href)
|
response.append(href)
|
||||||
|
|
||||||
propstat404 = ET.Element(_tag("D", "propstat"))
|
propstat404 = ET.Element(_tag("D", "propstat"))
|
||||||
@ -255,14 +252,14 @@ def _propfind_response(path, item, props, user):
|
|||||||
element.text = item.etag
|
element.text = item.etag
|
||||||
elif tag == _tag("D", "principal-URL"):
|
elif tag == _tag("D", "principal-URL"):
|
||||||
tag = ET.Element(_tag("D", "href"))
|
tag = ET.Element(_tag("D", "href"))
|
||||||
tag.text = _href_with_proxy_base_prefix(path)
|
tag.text = _href(path)
|
||||||
element.append(tag)
|
element.append(tag)
|
||||||
elif tag in (_tag("D", "principal-collection-set"),
|
elif tag in (_tag("D", "principal-collection-set"),
|
||||||
_tag("C", "calendar-user-address-set"),
|
_tag("C", "calendar-user-address-set"),
|
||||||
_tag("CR", "addressbook-home-set"),
|
_tag("CR", "addressbook-home-set"),
|
||||||
_tag("C", "calendar-home-set")):
|
_tag("C", "calendar-home-set")):
|
||||||
tag = ET.Element(_tag("D", "href"))
|
tag = ET.Element(_tag("D", "href"))
|
||||||
tag.text = _href_with_proxy_base_prefix(path)
|
tag.text = _href(path)
|
||||||
element.append(tag)
|
element.append(tag)
|
||||||
elif tag == _tag("C", "supported-calendar-component-set"):
|
elif tag == _tag("C", "supported-calendar-component-set"):
|
||||||
# This is not a Todo
|
# This is not a Todo
|
||||||
@ -274,8 +271,7 @@ def _propfind_response(path, item, props, user):
|
|||||||
# pylint: enable=W0511
|
# pylint: enable=W0511
|
||||||
elif tag == _tag("D", "current-user-principal") and user:
|
elif tag == _tag("D", "current-user-principal") and user:
|
||||||
tag = ET.Element(_tag("D", "href"))
|
tag = ET.Element(_tag("D", "href"))
|
||||||
prefixed_path = "%s/%s/" % (config.get("server", "base_prefix"), user)
|
tag.text = _href("/%s/" % user)
|
||||||
tag.text = _href_with_proxy_base_prefix(prefixed_path)
|
|
||||||
element.append(tag)
|
element.append(tag)
|
||||||
elif tag == _tag("D", "current-user-privilege-set"):
|
elif tag == _tag("D", "current-user-privilege-set"):
|
||||||
privilege = ET.Element(_tag("D", "privilege"))
|
privilege = ET.Element(_tag("D", "privilege"))
|
||||||
@ -399,7 +395,7 @@ def proppatch(path, xml_request, collection):
|
|||||||
multistatus.append(response)
|
multistatus.append(response)
|
||||||
|
|
||||||
href = ET.Element(_tag("D", "href"))
|
href = ET.Element(_tag("D", "href"))
|
||||||
href.text = _href_with_proxy_base_prefix(path)
|
href.text = _href(path)
|
||||||
response.append(href)
|
response.append(href)
|
||||||
|
|
||||||
with collection.props as collection_props:
|
with collection.props as collection_props:
|
||||||
@ -442,23 +438,15 @@ def report(path, xml_request, collection):
|
|||||||
prop_element = root.find(_tag("D", "prop"))
|
prop_element = root.find(_tag("D", "prop"))
|
||||||
props = [prop.tag for prop in prop_element]
|
props = [prop.tag for prop in prop_element]
|
||||||
|
|
||||||
proxy_prefix = config.get("server", "proxy_base_prefix")
|
|
||||||
base_prefix = config.get("server", "base_prefix")
|
|
||||||
|
|
||||||
if collection:
|
if collection:
|
||||||
if root.tag in (_tag("C", "calendar-multiget"),
|
if root.tag in (_tag("C", "calendar-multiget"),
|
||||||
_tag("CR", "addressbook-multiget")):
|
_tag("CR", "addressbook-multiget")):
|
||||||
# Read rfc4791-7.9 for info
|
# Read rfc4791-7.9 for info
|
||||||
hreferences = set()
|
base_prefix = config.get("server", "base_prefix")
|
||||||
for href_element in root.findall(_tag("D", "href")):
|
hreferences = set(
|
||||||
# skip elements that don't have the correct base prefixes
|
href_element.text[len(base_prefix):] for href_element
|
||||||
if not href_element.text.startswith(proxy_prefix):
|
in root.findall(_tag("D", "href"))
|
||||||
continue
|
if href_element.text.startswith(base_prefix))
|
||||||
unprefixed = href_element.text[len(proxy_prefix):]
|
|
||||||
if not unprefixed.startswith(base_prefix):
|
|
||||||
continue
|
|
||||||
# we keep the base prefix here, to be aligned with other paths
|
|
||||||
hreferences.add(unprefixed)
|
|
||||||
else:
|
else:
|
||||||
hreferences = (path,)
|
hreferences = (path,)
|
||||||
# TODO: handle other filters
|
# TODO: handle other filters
|
||||||
@ -480,9 +468,8 @@ def report(path, xml_request, collection):
|
|||||||
collection_timezones = collection.timezones
|
collection_timezones = collection.timezones
|
||||||
|
|
||||||
for hreference in hreferences:
|
for hreference in hreferences:
|
||||||
unprefixed_hreference = hreference[len(base_prefix):]
|
|
||||||
# Check if the reference is an item or a collection
|
# Check if the reference is an item or a collection
|
||||||
name = name_from_path(unprefixed_hreference, collection)
|
name = name_from_path(hreference, collection)
|
||||||
if name:
|
if name:
|
||||||
# Reference is an item
|
# Reference is an item
|
||||||
path = "/".join(hreference.split("/")[:-1]) + "/"
|
path = "/".join(hreference.split("/")[:-1]) + "/"
|
||||||
@ -500,7 +487,7 @@ def report(path, xml_request, collection):
|
|||||||
multistatus.append(response)
|
multistatus.append(response)
|
||||||
|
|
||||||
href = ET.Element(_tag("D", "href"))
|
href = ET.Element(_tag("D", "href"))
|
||||||
href.text = _href_with_proxy_base_prefix("%s/%s" % (path.rstrip("/"), item.name))
|
href.text = _href("%s/%s" % (path.rstrip("/"), item.name))
|
||||||
response.append(href)
|
response.append(href)
|
||||||
|
|
||||||
propstat = ET.Element(_tag("D", "propstat"))
|
propstat = ET.Element(_tag("D", "propstat"))
|
||||||
|
Loading…
Reference in New Issue
Block a user