Mark attributes for internal use with underscore
This commit is contained in:
		| @@ -76,11 +76,11 @@ class Application( | ||||
|         """ | ||||
|         super().__init__() | ||||
|         self.configuration = configuration | ||||
|         self.auth = auth.load(configuration) | ||||
|         self.storage = storage.load(configuration) | ||||
|         self.rights = rights.load(configuration) | ||||
|         self.Web = web.load(configuration) | ||||
|         self.encoding = configuration.get("encoding", "request") | ||||
|         self._auth = auth.load(configuration) | ||||
|         self._storage = storage.load(configuration) | ||||
|         self._rights = rights.load(configuration) | ||||
|         self._web = web.load(configuration) | ||||
|         self._encoding = configuration.get("encoding", "request") | ||||
|  | ||||
|     def _headers_log(self, environ): | ||||
|         """Sanitize headers for logging.""" | ||||
| @@ -107,7 +107,7 @@ class Application( | ||||
|             charsets.append( | ||||
|                 content_type.split("charset=")[1].split(";")[0].strip()) | ||||
|         # Then append default Radicale charset | ||||
|         charsets.append(self.encoding) | ||||
|         charsets.append(self._encoding) | ||||
|         # Then append various fallbacks | ||||
|         charsets.append("utf-8") | ||||
|         charsets.append("iso8859-1") | ||||
| @@ -153,8 +153,8 @@ class Application( | ||||
|             if answer: | ||||
|                 if hasattr(answer, "encode"): | ||||
|                     logger.debug("Response content:\n%s", answer) | ||||
|                     headers["Content-Type"] += "; charset=%s" % self.encoding | ||||
|                     answer = answer.encode(self.encoding) | ||||
|                     headers["Content-Type"] += "; charset=%s" % self._encoding | ||||
|                     answer = answer.encode(self._encoding) | ||||
|                 accept_encoding = [ | ||||
|                     encoding.strip() for encoding in | ||||
|                     environ.get("HTTP_ACCEPT_ENCODING", "").split(",") | ||||
| @@ -231,7 +231,7 @@ class Application( | ||||
|  | ||||
|         # Ask authentication backend to check rights | ||||
|         login = password = "" | ||||
|         external_login = self.auth.get_external_login(environ) | ||||
|         external_login = self._auth.get_external_login(environ) | ||||
|         authorization = environ.get("HTTP_AUTHORIZATION", "") | ||||
|         if external_login: | ||||
|             login, password = external_login | ||||
| @@ -241,7 +241,7 @@ class Application( | ||||
|             login, password = self.decode(base64.b64decode( | ||||
|                 authorization.encode("ascii")), environ).split(":", 1) | ||||
|  | ||||
|         user = self.auth.login(login, password) or "" if login else "" | ||||
|         user = self._auth.login(login, password) or "" if login else "" | ||||
|         if user and login == user: | ||||
|             logger.info("Successful login: %r", user) | ||||
|         elif user: | ||||
| @@ -263,15 +263,15 @@ class Application( | ||||
|         # Create principal collection | ||||
|         if user: | ||||
|             principal_path = "/%s/" % user | ||||
|             if self.rights.authorized(user, principal_path, "W"): | ||||
|                 with self.storage.acquire_lock("r", user): | ||||
|             if self._rights.authorized(user, principal_path, "W"): | ||||
|                 with self._storage.acquire_lock("r", user): | ||||
|                     principal = next( | ||||
|                         self.storage.discover(principal_path, depth="1"), | ||||
|                         self._storage.discover(principal_path, depth="1"), | ||||
|                         None) | ||||
|                 if not principal: | ||||
|                     with self.storage.acquire_lock("w", user): | ||||
|                     with self._storage.acquire_lock("w", user): | ||||
|                         try: | ||||
|                             self.storage.create_collection(principal_path) | ||||
|                             self._storage.create_collection(principal_path) | ||||
|                         except ValueError as e: | ||||
|                             logger.warning("Failed to create principal " | ||||
|                                            "collection %r: %s", user, e) | ||||
| @@ -327,12 +327,12 @@ class Application( | ||||
|         else: | ||||
|             permissions = "" | ||||
|             parent_permissions = permission | ||||
|         if permissions and self.rights.authorized(user, path, permissions): | ||||
|         if permissions and self._rights.authorized(user, path, permissions): | ||||
|             return True | ||||
|         if parent_permissions: | ||||
|             parent_path = pathutils.unstrip_path( | ||||
|                 posixpath.dirname(pathutils.strip_path(path)), True) | ||||
|             if self.rights.authorized(user, parent_path, parent_permissions): | ||||
|             if self._rights.authorized(user, parent_path, parent_permissions): | ||||
|                 return True | ||||
|         return False | ||||
|  | ||||
| @@ -369,14 +369,14 @@ class Application( | ||||
|             logger.debug("Response content:\n%s", | ||||
|                          xmlutils.pretty_xml(xml_content)) | ||||
|         f = io.BytesIO() | ||||
|         ET.ElementTree(xml_content).write(f, encoding=self.encoding, | ||||
|         ET.ElementTree(xml_content).write(f, encoding=self._encoding, | ||||
|                                           xml_declaration=True) | ||||
|         return f.getvalue() | ||||
|  | ||||
|     def webdav_error_response(self, namespace, name, | ||||
|                               status=httputils.WEBDAV_PRECONDITION_FAILED[0]): | ||||
|         """Generate XML error response.""" | ||||
|         headers = {"Content-Type": "text/xml; charset=%s" % self.encoding} | ||||
|         headers = {"Content-Type": "text/xml; charset=%s" % self._encoding} | ||||
|         content = self.write_xml_content( | ||||
|             xmlutils.webdav_error(namespace, name)) | ||||
|         return status, headers, content | ||||
|   | ||||
| @@ -51,8 +51,8 @@ class ApplicationDeleteMixin: | ||||
|         """Manage DELETE request.""" | ||||
|         if not self.access(user, path, "w"): | ||||
|             return httputils.NOT_ALLOWED | ||||
|         with self.storage.acquire_lock("w", user): | ||||
|             item = next(self.storage.discover(path), None) | ||||
|         with self._storage.acquire_lock("w", user): | ||||
|             item = next(self._storage.discover(path), None) | ||||
|             if not item: | ||||
|                 return httputils.NOT_FOUND | ||||
|             if not self.access(user, path, "w", item): | ||||
| @@ -66,5 +66,5 @@ class ApplicationDeleteMixin: | ||||
|             else: | ||||
|                 xml_answer = xml_delete( | ||||
|                     base_prefix, path, item.collection, item.href) | ||||
|             headers = {"Content-Type": "text/xml; charset=%s" % self.encoding} | ||||
|             headers = {"Content-Type": "text/xml; charset=%s" % self._encoding} | ||||
|             return client.OK, headers, self.write_xml_content(xml_answer) | ||||
|   | ||||
| @@ -47,13 +47,13 @@ class ApplicationGetMixin: | ||||
|     def _content_disposition_attachement(self, filename): | ||||
|         value = "attachement" | ||||
|         try: | ||||
|             encoded_filename = quote(filename, encoding=self.encoding) | ||||
|             encoded_filename = quote(filename, encoding=self._encoding) | ||||
|         except UnicodeEncodeError: | ||||
|             logger.warning("Failed to encode filename: %r", filename, | ||||
|                            exc_info=True) | ||||
|             encoded_filename = "" | ||||
|         if encoded_filename: | ||||
|             value += "; filename*=%s''%s" % (self.encoding, encoded_filename) | ||||
|             value += "; filename*=%s''%s" % (self._encoding, encoded_filename) | ||||
|         return value | ||||
|  | ||||
|     def do_GET(self, environ, base_prefix, path, user): | ||||
| @@ -69,11 +69,11 @@ class ApplicationGetMixin: | ||||
|                     "Redirected to %s" % web_path) | ||||
|         # Dispatch .web URL to web module | ||||
|         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) | ||||
|         if not self.access(user, path, "r"): | ||||
|             return httputils.NOT_ALLOWED | ||||
|         with self.storage.acquire_lock("r", user): | ||||
|             item = next(self.storage.discover(path), None) | ||||
|         with self._storage.acquire_lock("r", user): | ||||
|             item = next(self._storage.discover(path), None) | ||||
|             if not item: | ||||
|                 return httputils.NOT_FOUND | ||||
|             if not self.access(user, path, "r", item): | ||||
|   | ||||
| @@ -30,7 +30,7 @@ from radicale.log import logger | ||||
| class ApplicationMkcalendarMixin: | ||||
|     def do_MKCALENDAR(self, environ, base_prefix, path, user): | ||||
|         """Manage MKCALENDAR request.""" | ||||
|         if not self.rights.authorized(user, path, "w"): | ||||
|         if not self._rights.authorized(user, path, "w"): | ||||
|             return httputils.NOT_ALLOWED | ||||
|         try: | ||||
|             xml_content = self.read_xml_content(environ) | ||||
| @@ -51,21 +51,21 @@ class ApplicationMkcalendarMixin: | ||||
|         except ValueError as e: | ||||
|             logger.warning( | ||||
|                 "Bad MKCALENDAR request on %r: %s", path, e, exc_info=True) | ||||
|         with self.storage.acquire_lock("w", user): | ||||
|             item = next(self.storage.discover(path), None) | ||||
|         with self._storage.acquire_lock("w", user): | ||||
|             item = next(self._storage.discover(path), None) | ||||
|             if item: | ||||
|                 return self.webdav_error_response( | ||||
|                     "D", "resource-must-be-null") | ||||
|             parent_path = pathutils.unstrip_path( | ||||
|                 posixpath.dirname(pathutils.strip_path(path)), True) | ||||
|             parent_item = next(self.storage.discover(parent_path), None) | ||||
|             parent_item = next(self._storage.discover(parent_path), None) | ||||
|             if not parent_item: | ||||
|                 return httputils.CONFLICT | ||||
|             if (not isinstance(parent_item, storage.BaseCollection) or | ||||
|                     parent_item.get_meta("tag")): | ||||
|                 return httputils.FORBIDDEN | ||||
|             try: | ||||
|                 self.storage.create_collection(path, props=props) | ||||
|                 self._storage.create_collection(path, props=props) | ||||
|             except ValueError as e: | ||||
|                 logger.warning( | ||||
|                     "Bad MKCALENDAR request on %r: %s", path, e, exc_info=True) | ||||
|   | ||||
| @@ -30,7 +30,7 @@ from radicale.log import logger | ||||
| class ApplicationMkcolMixin: | ||||
|     def do_MKCOL(self, environ, base_prefix, path, user): | ||||
|         """Manage MKCOL request.""" | ||||
|         permissions = self.rights.authorized(user, path, "Ww") | ||||
|         permissions = self._rights.authorized(user, path, "Ww") | ||||
|         if not permissions: | ||||
|             return httputils.NOT_ALLOWED | ||||
|         try: | ||||
| @@ -53,20 +53,20 @@ class ApplicationMkcolMixin: | ||||
|         if (props.get("tag") and "w" not in permissions or | ||||
|                 not props.get("tag") and "W" not in permissions): | ||||
|             return httputils.NOT_ALLOWED | ||||
|         with self.storage.acquire_lock("w", user): | ||||
|             item = next(self.storage.discover(path), None) | ||||
|         with self._storage.acquire_lock("w", user): | ||||
|             item = next(self._storage.discover(path), None) | ||||
|             if item: | ||||
|                 return httputils.METHOD_NOT_ALLOWED | ||||
|             parent_path = pathutils.unstrip_path( | ||||
|                 posixpath.dirname(pathutils.strip_path(path)), True) | ||||
|             parent_item = next(self.storage.discover(parent_path), None) | ||||
|             parent_item = next(self._storage.discover(parent_path), None) | ||||
|             if not parent_item: | ||||
|                 return httputils.CONFLICT | ||||
|             if (not isinstance(parent_item, storage.BaseCollection) or | ||||
|                     parent_item.get_meta("tag")): | ||||
|                 return httputils.FORBIDDEN | ||||
|             try: | ||||
|                 self.storage.create_collection(path, props=props) | ||||
|                 self._storage.create_collection(path, props=props) | ||||
|             except ValueError as e: | ||||
|                 logger.warning( | ||||
|                     "Bad MKCOL request on %r: %s", path, e, exc_info=True) | ||||
|   | ||||
| @@ -45,8 +45,8 @@ class ApplicationMoveMixin: | ||||
|         if not self.access(user, to_path, "w"): | ||||
|             return httputils.NOT_ALLOWED | ||||
|  | ||||
|         with self.storage.acquire_lock("w", user): | ||||
|             item = next(self.storage.discover(path), None) | ||||
|         with self._storage.acquire_lock("w", user): | ||||
|             item = next(self._storage.discover(path), None) | ||||
|             if not item: | ||||
|                 return httputils.NOT_FOUND | ||||
|             if (not self.access(user, path, "w", item) or | ||||
| @@ -56,13 +56,13 @@ class ApplicationMoveMixin: | ||||
|                 # TODO: support moving collections | ||||
|                 return httputils.METHOD_NOT_ALLOWED | ||||
|  | ||||
|             to_item = next(self.storage.discover(to_path), None) | ||||
|             to_item = next(self._storage.discover(to_path), None) | ||||
|             if isinstance(to_item, storage.BaseCollection): | ||||
|                 return httputils.FORBIDDEN | ||||
|             to_parent_path = pathutils.unstrip_path( | ||||
|                 posixpath.dirname(pathutils.strip_path(to_path)), True) | ||||
|             to_collection = next( | ||||
|                 self.storage.discover(to_parent_path), None) | ||||
|                 self._storage.discover(to_parent_path), None) | ||||
|             if not to_collection: | ||||
|                 return httputils.CONFLICT | ||||
|             tag = item.collection.get_meta("tag") | ||||
| @@ -78,7 +78,7 @@ class ApplicationMoveMixin: | ||||
|                     "C" if tag == "VCALENDAR" else "CR", "no-uid-conflict") | ||||
|             to_href = posixpath.basename(pathutils.strip_path(to_path)) | ||||
|             try: | ||||
|                 self.storage.move(item, to_collection, to_href) | ||||
|                 self._storage.move(item, to_collection, to_href) | ||||
|             except ValueError as e: | ||||
|                 logger.warning( | ||||
|                     "Bad MOVE request on %r: %s", path, e, exc_info=True) | ||||
|   | ||||
| @@ -27,7 +27,8 @@ from radicale import httputils, pathutils, rights, storage, xmlutils | ||||
| from radicale.log import logger | ||||
|  | ||||
|  | ||||
| def xml_propfind(base_prefix, path, xml_request, allowed_items, user): | ||||
| def xml_propfind(base_prefix, path, xml_request, allowed_items, user, | ||||
|                  encoding): | ||||
|     """Read and answer PROPFIND requests. | ||||
|  | ||||
|     Read rfc4918-9.1 for info. | ||||
| @@ -63,7 +64,7 @@ def xml_propfind(base_prefix, path, xml_request, allowed_items, user): | ||||
|     for item, permission in allowed_items: | ||||
|         write = permission == "w" | ||||
|         response = xml_propfind_response( | ||||
|             base_prefix, path, item, props, user, write=write, | ||||
|             base_prefix, path, item, props, user, encoding, write=write, | ||||
|             allprop=allprop, propname=propname) | ||||
|         if response: | ||||
|             multistatus.append(response) | ||||
| @@ -71,8 +72,8 @@ def xml_propfind(base_prefix, path, xml_request, allowed_items, user): | ||||
|     return client.MULTI_STATUS, multistatus | ||||
|  | ||||
|  | ||||
| def xml_propfind_response(base_prefix, path, item, props, user, write=False, | ||||
|                           propname=False, allprop=False): | ||||
| def xml_propfind_response(base_prefix, path, item, props, user, encoding, | ||||
|                           write=False, propname=False, allprop=False): | ||||
|     """Build and return a PROPFIND response.""" | ||||
|     if propname and allprop or (props and (propname or allprop)): | ||||
|         raise ValueError("Only use one of props, propname and allprops") | ||||
| @@ -234,7 +235,6 @@ def xml_propfind_response(base_prefix, path, item, props, user, write=False, | ||||
|                 element.append(supported) | ||||
|         elif tag == xmlutils.make_tag("D", "getcontentlength"): | ||||
|             if not is_collection or is_leaf: | ||||
|                 encoding = collection.configuration.get("encoding", "request") | ||||
|                 element.text = str(len(item.serialize().encode(encoding))) | ||||
|             else: | ||||
|                 is404 = True | ||||
| @@ -299,7 +299,7 @@ def xml_propfind_response(base_prefix, path, item, props, user, write=False, | ||||
|                     is404 = True | ||||
|         # Not for collections | ||||
|         elif tag == xmlutils.make_tag("D", "getcontenttype"): | ||||
|             element.text = xmlutils.get_content_type(item) | ||||
|             element.text = xmlutils.get_content_type(item, encoding) | ||||
|         elif tag == xmlutils.make_tag("D", "resourcetype"): | ||||
|             # resourcetype must be returned empty for non-collection elements | ||||
|             pass | ||||
| @@ -331,14 +331,14 @@ class ApplicationPropfindMixin: | ||||
|             if isinstance(item, storage.BaseCollection): | ||||
|                 path = pathutils.unstrip_path(item.path, True) | ||||
|                 if item.get_meta("tag"): | ||||
|                     permissions = self.rights.authorized(user, path, "rw") | ||||
|                     permissions = self._rights.authorized(user, path, "rw") | ||||
|                     target = "collection with tag %r" % item.path | ||||
|                 else: | ||||
|                     permissions = self.rights.authorized(user, path, "RW") | ||||
|                     permissions = self._rights.authorized(user, path, "RW") | ||||
|                     target = "collection %r" % item.path | ||||
|             else: | ||||
|                 path = pathutils.unstrip_path(item.collection.path, True) | ||||
|                 permissions = self.rights.authorized(user, path, "rw") | ||||
|                 permissions = self._rights.authorized(user, path, "rw") | ||||
|                 target = "item %r from %r" % (item.href, item.collection.path) | ||||
|             if rights.intersect_permissions(permissions, "Ww"): | ||||
|                 permission = "w" | ||||
| @@ -368,8 +368,9 @@ class ApplicationPropfindMixin: | ||||
|         except socket.timeout: | ||||
|             logger.debug("client timed out", exc_info=True) | ||||
|             return httputils.REQUEST_TIMEOUT | ||||
|         with self.storage.acquire_lock("r", user): | ||||
|             items = self.storage.discover(path, environ.get("HTTP_DEPTH", "0")) | ||||
|         with self._storage.acquire_lock("r", user): | ||||
|             items = self._storage.discover( | ||||
|                 path, environ.get("HTTP_DEPTH", "0")) | ||||
|             # take root item for rights checking | ||||
|             item = next(items, None) | ||||
|             if not item: | ||||
| @@ -380,9 +381,10 @@ class ApplicationPropfindMixin: | ||||
|             items = itertools.chain([item], items) | ||||
|             allowed_items = self._collect_allowed_items(items, user) | ||||
|             headers = {"DAV": httputils.DAV_HEADERS, | ||||
|                        "Content-Type": "text/xml; charset=%s" % self.encoding} | ||||
|                        "Content-Type": "text/xml; charset=%s" % self._encoding} | ||||
|             status, xml_answer = xml_propfind( | ||||
|                 base_prefix, path, xml_content, allowed_items, user) | ||||
|                 base_prefix, path, xml_content, allowed_items, user, | ||||
|                 self._encoding) | ||||
|             if status == client.FORBIDDEN: | ||||
|                 return httputils.NOT_ALLOWED | ||||
|             return status, headers, self.write_xml_content(xml_answer) | ||||
|   | ||||
| @@ -98,8 +98,8 @@ class ApplicationProppatchMixin: | ||||
|         except socket.timeout: | ||||
|             logger.debug("client timed out", exc_info=True) | ||||
|             return httputils.REQUEST_TIMEOUT | ||||
|         with self.storage.acquire_lock("w", user): | ||||
|             item = next(self.storage.discover(path), None) | ||||
|         with self._storage.acquire_lock("w", user): | ||||
|             item = next(self._storage.discover(path), None) | ||||
|             if not item: | ||||
|                 return httputils.NOT_FOUND | ||||
|             if not self.access(user, path, "w", item): | ||||
| @@ -107,7 +107,7 @@ class ApplicationProppatchMixin: | ||||
|             if not isinstance(item, storage.BaseCollection): | ||||
|                 return httputils.FORBIDDEN | ||||
|             headers = {"DAV": httputils.DAV_HEADERS, | ||||
|                        "Content-Type": "text/xml; charset=%s" % self.encoding} | ||||
|                        "Content-Type": "text/xml; charset=%s" % self._encoding} | ||||
|             try: | ||||
|                 xml_answer = xml_proppatch(base_prefix, path, xml_content, | ||||
|                                            item) | ||||
|   | ||||
| @@ -47,8 +47,8 @@ class ApplicationPutMixin: | ||||
|         # Prepare before locking | ||||
|         parent_path = pathutils.unstrip_path( | ||||
|             posixpath.dirname(pathutils.strip_path(path)), True) | ||||
|         permissions = self.rights.authorized(user, path, "Ww") | ||||
|         parent_permissions = self.rights.authorized(user, parent_path, "w") | ||||
|         permissions = self._rights.authorized(user, path, "Ww") | ||||
|         parent_permissions = self._rights.authorized(user, parent_path, "w") | ||||
|  | ||||
|         def prepare(vobject_items, tag=None, write_whole_collection=None): | ||||
|             if (write_whole_collection or | ||||
| @@ -149,9 +149,9 @@ class ApplicationPutMixin: | ||||
|         (prepared_items, prepared_tag, prepared_write_whole_collection, | ||||
|          prepared_props, prepared_exc_info) = prepare(vobject_items) | ||||
|  | ||||
|         with self.storage.acquire_lock("w", user): | ||||
|             item = next(self.storage.discover(path), None) | ||||
|             parent_item = next(self.storage.discover(parent_path), None) | ||||
|         with self._storage.acquire_lock("w", user): | ||||
|             item = next(self._storage.discover(path), None) | ||||
|             parent_item = next(self._storage.discover(parent_path), None) | ||||
|             if not parent_item: | ||||
|                 return httputils.CONFLICT | ||||
|  | ||||
| @@ -165,9 +165,10 @@ class ApplicationPutMixin: | ||||
|                 tag = parent_item.get_meta("tag") | ||||
|  | ||||
|             if write_whole_collection: | ||||
|                 if not self.rights.authorized(user, path, "w" if tag else "W"): | ||||
|                 if not self._rights.authorized( | ||||
|                         user, path, "w" if tag else "W"): | ||||
|                     return httputils.NOT_ALLOWED | ||||
|             elif not self.rights.authorized(user, parent_path, "w"): | ||||
|             elif not self._rights.authorized(user, parent_path, "w"): | ||||
|                 return httputils.NOT_ALLOWED | ||||
|  | ||||
|             etag = environ.get("HTTP_IF_MATCH", "") | ||||
| @@ -197,7 +198,7 @@ class ApplicationPutMixin: | ||||
|  | ||||
|             if write_whole_collection: | ||||
|                 try: | ||||
|                     etag = self.storage.create_collection( | ||||
|                     etag = self._storage.create_collection( | ||||
|                         path, prepared_items, props).etag | ||||
|                 except ValueError as e: | ||||
|                     logger.warning( | ||||
|   | ||||
| @@ -29,7 +29,8 @@ from radicale.item import filter as radicale_filter | ||||
| from radicale.log import logger | ||||
|  | ||||
|  | ||||
| def xml_report(base_prefix, path, xml_request, collection, unlock_storage_fn): | ||||
| def xml_report(base_prefix, path, xml_request, collection, encoding, | ||||
|                unlock_storage_fn): | ||||
|     """Read and answer REPORT requests. | ||||
|  | ||||
|     Read rfc3253-3.6 for info. | ||||
| @@ -208,7 +209,7 @@ def xml_report(base_prefix, path, xml_request, collection, unlock_storage_fn): | ||||
|                 element.text = item.etag | ||||
|                 found_props.append(element) | ||||
|             elif tag == xmlutils.make_tag("D", "getcontenttype"): | ||||
|                 element.text = xmlutils.get_content_type(item) | ||||
|                 element.text = xmlutils.get_content_type(item, encoding) | ||||
|                 found_props.append(element) | ||||
|             elif tag in ( | ||||
|                     xmlutils.make_tag("C", "calendar-data"), | ||||
| @@ -270,8 +271,8 @@ class ApplicationReportMixin: | ||||
|             logger.debug("client timed out", exc_info=True) | ||||
|             return httputils.REQUEST_TIMEOUT | ||||
|         with contextlib.ExitStack() as lock_stack: | ||||
|             lock_stack.enter_context(self.storage.acquire_lock("r", user)) | ||||
|             item = next(self.storage.discover(path), None) | ||||
|             lock_stack.enter_context(self._storage.acquire_lock("r", user)) | ||||
|             item = next(self._storage.discover(path), None) | ||||
|             if not item: | ||||
|                 return httputils.NOT_FOUND | ||||
|             if not self.access(user, path, "r", item): | ||||
| @@ -280,10 +281,10 @@ class ApplicationReportMixin: | ||||
|                 collection = item | ||||
|             else: | ||||
|                 collection = item.collection | ||||
|             headers = {"Content-Type": "text/xml; charset=%s" % self.encoding} | ||||
|             headers = {"Content-Type": "text/xml; charset=%s" % self._encoding} | ||||
|             try: | ||||
|                 status, xml_answer = xml_report( | ||||
|                     base_prefix, path, xml_content, collection, | ||||
|                     base_prefix, path, xml_content, collection, self._encoding, | ||||
|                     lock_stack.close) | ||||
|             except ValueError as e: | ||||
|                 logger.warning( | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Unrud
					Unrud