def check(self, path: str, query_string: str, headers, client_address: str) -> tuple:
"""Check the request against policies and return decision and response.
Returned values are:
- allowed: (bool) True if request is accepted
- content: (bytes|None) Response body if rejected, otherwise None
- status: (HTTPDStatus|None) Status if rejected, otherwise None
- mime_type: (str|None) Mime of the body, None if the body is empty
:param path: (str) Normalized URL path (without query).
:param query_string: (str) Raw query string (without '?').
:param headers: (Any) Request headers or environ. Must support ".get(...)".
:param client_address: (str) The address of the client of the request.
:return: (tuple) (allowed, content, status, mime_type)
"""
if type(path) is not str:
raise TypeError('HTTPDPolicy.check: path must be a string.')
if type(query_string) is not str:
raise TypeError('HTTPDPolicy.check: query_string must be a string.')
if type(client_address) is not str:
raise TypeError('HTTPDPolicy.check: client_address must be a string.')
user_agent = self._get_user_agent(headers)
client = self._get_client_address(headers, client_address)
if self.__banlist_enabled is True:
if self.__banlist.match(client_address) is True:
logging.warning("Banned address rejected: '{:s}' for path '{:s}'".format(client_address, path))
content, status = HTTPDHandlerUtils.blacklisted_page_answer()
return (False, content, status, None)
if self.__blacklist_agent_enabled is True:
if self.__blacklist_agent.match(user_agent) is True:
logging.warning("Blacklisted user agent rejected: '{:s}' for path '{:s}' from {:s}".format(user_agent, path, client))
content, status = HTTPDHandlerUtils.blacklisted_page_answer()
return (False, content, status, None)
if self.__blacklist_path_enabled is True:
if self.__blacklist_path.match(path) is True:
logging.warning("Blacklisted path rejected: '{:s}' for user agent '{:s}' from {:s}".format(path, user_agent, client))
if self.__banlist_enabled is True:
self.__banlist.add(client_address)
content, status = HTTPDHandlerUtils.blacklisted_page_answer()
return (False, content, status, None)
ttl_seconds = self.__signed_url_cfg.get('ttl', None)
if ttl_seconds is not None:
protect = self.__signed_url_cfg.get('protect', [])
if self.__signed_url.match_protect(path, protect) is True:
if self.__signed_url.verify(path, query_string, ttl_seconds) is False:
content, status = HTTPDHandlerUtils.signed_url_page_answer()
return (False, content, status, 'text/html')
return (True, None, None, None)