Source code for uw.web.wsgi.status

"""HTTP status reporting.

This module provides classes corresponding to the various HTTP redirection
and error codes.  A typical page handler can report an HTTP status (other than
the regular "200 OK") by raising an instance of one of these classes.
"""

from wsgiref.util import request_uri
from urllib.parse import urljoin

from ll.xist.ns import html

[docs]class HTTPStatus (Exception): """Top-level class for HTTP status reporting. """ def __init__ (self, status, description, body=None): super (HTTPStatus, self).__init__ () self.__status = status self.__description = description self.__body = body @property def status (self): return self.__status @property def description (self): return self.__description
[docs] def get_status (self): return '%i %s' % (self.status, self.description)
[docs] def get_headers (self, environ): return []
[docs] def get_body (self): return self.__body or html.p ("HTTP Error")
[docs]class HTTPRedirection (HTTPStatus): """HTTP redirection status codes (3xx). """ def __init__ (self, status, description, url): super (HTTPRedirection, self).__init__ (status, description) # If string supplied as Unicode, need to reduce to str as regular # str must be supplied to flup start_response function. # URLs are ASCII-only anyway; non-ASCII characters must be reprsented # using %-sequences so this does not actually restrict anything. self.__url = str (url) @property def url (self): return self.__url
[docs] def get_headers (self, environ): result = super (HTTPRedirection, self).get_headers (environ) if self.url is not None: result.append (('Location', urljoin (request_uri (environ), self.url))) return result
[docs]class HTTPMovedPermanently (HTTPRedirection): def __init__ (self, url): super (HTTPMovedPermanently, self).__init__ (301, "Moved Permanently", url)
[docs]class HTTPFound (HTTPRedirection): def __init__ (self, url): super (HTTPFound, self).__init__ (302, "Found", url)
[docs]class HTTPSeeOther (HTTPRedirection): def __init__ (self, url): super (HTTPSeeOther, self).__init__ (303, "See Other", url)
[docs]class HTTPTemporaryRedirect (HTTPRedirection): def __init__ (self, url): super (HTTPTemporaryRedirect, self).__init__ (307, "Temporary Redirect", url)
[docs]class HTTPError (HTTPStatus): """HTTP error status codes (4xx, 5xx). """ pass
[docs]class HTTPClientError (HTTPError): """HTTP client error status codes (4xx). """ pass
[docs]class HTTPBadRequest (HTTPClientError): def __init__ (self): super (HTTPBadRequest, self).__init__ (400, "Bad Request")
[docs] @staticmethod def handler (environ, start_response): raise HTTPBadRequest ()
[docs]class HTTPForbidden (HTTPClientError): def __init__ (self): super (HTTPForbidden, self).__init__ (403, "Forbidden")
[docs] @staticmethod def handler (environ, start_response): raise HTTPForbidden ()
[docs]class HTTPNotFound (HTTPClientError): def __init__ (self): super (HTTPNotFound, self).__init__ (404, "Not Found")
[docs] @staticmethod def handler (environ, start_response): raise HTTPNotFound ()
[docs]class HTTPMethodNotAllowed (HTTPClientError): def __init__ (self, methods): super (HTTPMethodNotAllowed, self).__init__ (405, "Method Not Allowed", body=html.ul (html.li (method) for method in methods)) self.__methods = tuple (methods) @property def methods (self): return self.__methods
[docs] @staticmethod def handler (methods): def result (environ, start_response): raise HTTPMethodNotAllowed (methods) return result
[docs] def get_headers (self, environ): result = super (HTTPMethodNotAllowed, self).get_headers (environ) result.append (('Allow', ', '.join (self.methods))) return result
[docs]class HTTPGone (HTTPClientError): def __init__ (self): super (HTTPGone, self).__init__ (410, "Gone")
[docs] @staticmethod def handler (environ, start_response): raise HTTPGone ()
[docs]class HTTPServerError (HTTPError): """HTTP server error status codes (5xx). """ pass
[docs]class HTTPInternalServerError (HTTPServerError): def __init__ (self, body=None): super (HTTPInternalServerError, self).__init__ (500, "Internal Server Error", body)