1b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik""" 2b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikThis module processes Python exceptions that relate to HTTP exceptions 3b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikby defining a set of exceptions, all subclasses of HTTPException. 4b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikEach exception, in addition to being a Python exception that can be 5b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikraised and caught, is also a WSGI application and ``webob.Response`` 6b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikobject. 7b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 8b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikThis module defines exceptions according to RFC 2068 [1]_ : codes with 9b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik100-300 are not really errors; 400's are client errors, and 500's are 10b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikserver errors. According to the WSGI specification [2]_ , the application 11b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikcan call ``start_response`` more then once only under two conditions: 12b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik(a) the response has not yet been sent, or (b) if the second and 13b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craiksubsequent invocations of ``start_response`` have a valid ``exc_info`` 14b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikargument obtained from ``sys.exc_info()``. The WSGI specification then 15b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikrequires the server or gateway to handle the case where content has been 16b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craiksent and then an exception was encountered. 17b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 18b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikException 19b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik HTTPException 20b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik HTTPOk 21b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 200 - :class:`HTTPOk` 22b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 201 - :class:`HTTPCreated` 23b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 202 - :class:`HTTPAccepted` 24b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 203 - :class:`HTTPNonAuthoritativeInformation` 25b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 204 - :class:`HTTPNoContent` 26b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 205 - :class:`HTTPResetContent` 27b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 206 - :class:`HTTPPartialContent` 28b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik HTTPRedirection 29b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 300 - :class:`HTTPMultipleChoices` 30b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 301 - :class:`HTTPMovedPermanently` 31b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 302 - :class:`HTTPFound` 32b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 303 - :class:`HTTPSeeOther` 33b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 304 - :class:`HTTPNotModified` 34b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 305 - :class:`HTTPUseProxy` 35b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 307 - :class:`HTTPTemporaryRedirect` 36b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik HTTPError 37b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik HTTPClientError 38b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 400 - :class:`HTTPBadRequest` 39b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 401 - :class:`HTTPUnauthorized` 40b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 402 - :class:`HTTPPaymentRequired` 41b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 403 - :class:`HTTPForbidden` 42b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 404 - :class:`HTTPNotFound` 43b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 405 - :class:`HTTPMethodNotAllowed` 44b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 406 - :class:`HTTPNotAcceptable` 45b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 407 - :class:`HTTPProxyAuthenticationRequired` 46b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 408 - :class:`HTTPRequestTimeout` 47b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 409 - :class:`HTTPConflict` 48b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 410 - :class:`HTTPGone` 49b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 411 - :class:`HTTPLengthRequired` 50b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 412 - :class:`HTTPPreconditionFailed` 51b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 413 - :class:`HTTPRequestEntityTooLarge` 52b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 414 - :class:`HTTPRequestURITooLong` 53b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 415 - :class:`HTTPUnsupportedMediaType` 54b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 416 - :class:`HTTPRequestRangeNotSatisfiable` 55b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 417 - :class:`HTTPExpectationFailed` 56b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 422 - :class:`HTTPUnprocessableEntity` 57b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 423 - :class:`HTTPLocked` 58b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 424 - :class:`HTTPFailedDependency` 59b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 428 - :class:`HTTPPreconditionRequired` 60b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 429 - :class:`HTTPTooManyRequests` 61b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 431 - :class:`HTTPRequestHeaderFieldsTooLarge` 62b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 451 - :class:`HTTPUnavailableForLegalReasons` 63b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik HTTPServerError 64b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 500 - :class:`HTTPInternalServerError` 65b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 501 - :class:`HTTPNotImplemented` 66b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 502 - :class:`HTTPBadGateway` 67b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 503 - :class:`HTTPServiceUnavailable` 68b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 504 - :class:`HTTPGatewayTimeout` 69b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 505 - :class:`HTTPVersionNotSupported` 70b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * 511 - :class:`HTTPNetworkAuthenticationRequired` 71b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 72b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikUsage notes 73b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik----------- 74b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 75b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikThe HTTPException class is complicated by 4 factors: 76b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 77b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1. The content given to the exception may either be plain-text or 78b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik as html-text. 79b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 80b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 2. The template may want to have string-substitutions taken from 81b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the current ``environ`` or values from incoming headers. This 82b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik is especially troublesome due to case sensitivity. 83b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 84b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 3. The final output may either be text/plain or text/html 85b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik mime-type as requested by the client application. 86b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 87b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 4. Each exception has a default explanation, but those who 88b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik raise exceptions may want to provide additional detail. 89b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 90b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikSubclass attributes and call parameters are designed to provide an easier path 91b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikthrough the complications. 92b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 93b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikAttributes: 94b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 95b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``code`` 96b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the HTTP status code for the exception 97b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 98b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``title`` 99b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik remainder of the status line (stuff after the code) 100b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 101b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``explanation`` 102b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik a plain-text explanation of the error message that is 103b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik not subject to environment or header substitutions; 104b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik it is accessible in the template via %(explanation)s 105b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 106b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``detail`` 107b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik a plain-text message customization that is not subject 108b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik to environment or header substitutions; accessible in 109b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the template via %(detail)s 110b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 111b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``body_template`` 112b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik a content fragment (in HTML) used for environment and 113b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik header substitution; the default template includes both 114b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the explanation and further detail provided in the 115b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik message 116b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 117b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikParameters: 118b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 119b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``detail`` 120b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik a plain-text override of the default ``detail`` 121b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 122b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``headers`` 123b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik a list of (k,v) header pairs 124b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 125b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``comment`` 126b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik a plain-text additional information which is 127b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik usually stripped/hidden for end-users 128b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 129b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``body_template`` 130b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik a string.Template object containing a content fragment in HTML 131b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik that frames the explanation and further detail 132b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 133b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikTo override the template (which is HTML content) or the plain-text 134b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexplanation, one must subclass the given exception; or customize it 135b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikafter it has been created. This particular breakdown of a message 136b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikinto explanation, detail and template allows both the creation of 137b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikplain-text and html messages for various clients as well as 138b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikerror-free substitution of environment variables and headers. 139b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 140b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 141b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikThe subclasses of :class:`~_HTTPMove` 142b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik(:class:`~HTTPMultipleChoices`, :class:`~HTTPMovedPermanently`, 143b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik:class:`~HTTPFound`, :class:`~HTTPSeeOther`, :class:`~HTTPUseProxy` and 144b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik:class:`~HTTPTemporaryRedirect`) are redirections that require a ``Location`` 145b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfield. Reflecting this, these subclasses have two additional keyword arguments: 146b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik``location`` and ``add_slash``. 147b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 148b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikParameters: 149b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 150b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``location`` 151b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik to set the location immediately 152b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 153b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``add_slash`` 154b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik set to True to redirect to the same URL as the request, except with a 155b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``/`` appended 156b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 157b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikRelative URLs in the location will be resolved to absolute. 158b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 159b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikReferences: 160b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 161b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik.. [1] http://www.python.org/peps/pep-0333.html#error-handling 162b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik.. [2] http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5 163b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 164b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 165b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik""" 166b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 167b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom string import Template 168b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport re 169b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport sys 170b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 171b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom webob.compat import ( 172b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik class_types, 173b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik text_, 174b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik text_type, 175b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik urlparse, 176b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ) 177b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom webob.request import Request 178b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom webob.response import Response 179b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom webob.util import ( 180b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik html_escape, 181b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik warn_deprecation, 182b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ) 183b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 184b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craiktag_re = re.compile(r'<.*?>', re.S) 185b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikbr_re = re.compile(r'<br.*?>', re.I|re.S) 186b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikcomment_re = re.compile(r'<!--|-->') 187b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 188b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef no_escape(value): 189b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if value is None: 190b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return '' 191b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if not isinstance(value, text_type): 192b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if hasattr(value, '__unicode__'): 193b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value = value.__unicode__() 194b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(value, bytes): 195b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value = text_(value, 'utf-8') 196b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 197b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value = text_type(value) 198b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return value 199b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 200b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef strip_tags(value): 201b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value = value.replace('\n', ' ') 202b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value = value.replace('\r', '') 203b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value = br_re.sub('\n', value) 204b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value = comment_re.sub('', value) 205b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value = tag_re.sub('', value) 206b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return value 207b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 208b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPException(Exception): 209b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def __init__(self, message, wsgi_response): 210b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Exception.__init__(self, message) 211b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.wsgi_response = wsgi_response 212b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 213b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def __call__(self, environ, start_response): 214b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return self.wsgi_response(environ, start_response) 215b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 216b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass WSGIHTTPException(Response, HTTPException): 217b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 218b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ## You should set in subclasses: 219b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # code = 200 220b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # title = 'OK' 221b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # explanation = 'why this happens' 222b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # body_template_obj = Template('response template') 223b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 500 224b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Internal Server Error' 225b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = '' 226b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik body_template_obj = Template('''\ 227b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik${explanation}<br /><br /> 228b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik${detail} 229b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik${html_comment} 230b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik''') 231b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 232b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik plain_template_obj = Template('''\ 233b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik${status} 234b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 235b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik${body}''') 236b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 237b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik html_template_obj = Template('''\ 238b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik<html> 239b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik <head> 240b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik <title>${status}</title> 241b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik </head> 242b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik <body> 243b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik <h1>${status}</h1> 244b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ${body} 245b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik </body> 246b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik</html>''') 247b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 248b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ## Set this to True for responses that should have no request body 249b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik empty_body = False 250b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 251b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def __init__(self, detail=None, headers=None, comment=None, 252b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik body_template=None, **kw): 253b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Response.__init__(self, 254b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik status='%s %s' % (self.code, self.title), 255b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik **kw) 256b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Exception.__init__(self, detail) 257b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if headers: 258b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.headers.extend(headers) 259b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.detail = detail 260b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.comment = comment 261b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if body_template is not None: 262b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.body_template = body_template 263b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.body_template_obj = Template(body_template) 264b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if self.empty_body: 265b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik del self.content_type 266b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik del self.content_length 267b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 268b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def __str__(self): 269b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return self.detail or self.explanation 270b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 271b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def _make_body(self, environ, escape): 272b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik args = { 273b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'explanation': escape(self.explanation), 274b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'detail': escape(self.detail or ''), 275b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'comment': escape(self.comment or ''), 276b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik } 277b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if self.comment: 278b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik args['html_comment'] = '<!-- %s -->' % escape(self.comment) 279b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 280b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik args['html_comment'] = '' 281b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if WSGIHTTPException.body_template_obj is not self.body_template_obj: 282b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # Custom template; add headers to args 283b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for k, v in environ.items(): 284b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik args[k] = escape(v) 285b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for k, v in self.headers.items(): 286b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik args[k.lower()] = escape(v) 287b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik t_obj = self.body_template_obj 288b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return t_obj.substitute(args) 289b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 290b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def plain_body(self, environ): 291b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik body = self._make_body(environ, no_escape) 292b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik body = strip_tags(body) 293b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return self.plain_template_obj.substitute(status=self.status, 294b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title=self.title, 295b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik body=body) 296b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 297b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def html_body(self, environ): 298b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik body = self._make_body(environ, html_escape) 299b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return self.html_template_obj.substitute(status=self.status, 300b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik body=body) 301b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 302b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def generate_response(self, environ, start_response): 303b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if self.content_length is not None: 304b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik del self.content_length 305b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik headerlist = list(self.headerlist) 306b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik accept = environ.get('HTTP_ACCEPT', '') 307b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if accept and 'html' in accept or '*/*' in accept: 308b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik content_type = 'text/html' 309b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik body = self.html_body(environ) 310b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 311b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik content_type = 'text/plain' 312b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik body = self.plain_body(environ) 313b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik extra_kw = {} 314b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(body, text_type): 315b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik extra_kw.update(charset='utf-8') 316b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik resp = Response(body, 317b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik status=self.status, 318b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik headerlist=headerlist, 319b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik content_type=content_type, 320b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik **extra_kw 321b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ) 322b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik resp.content_type = content_type 323b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return resp(environ, start_response) 324b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 325b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def __call__(self, environ, start_response): 326b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik is_head = environ['REQUEST_METHOD'] == 'HEAD' 327b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if self.body or self.empty_body or is_head: 328b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik app_iter = Response.__call__(self, environ, start_response) 329b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 330b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik app_iter = self.generate_response(environ, start_response) 331b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if is_head: 332b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik app_iter = [] 333b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return app_iter 334b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 335b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik @property 336b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def wsgi_response(self): 337b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return self 338b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 339b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 340b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 341b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPError(WSGIHTTPException): 342b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 343b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik base class for status codes in the 400's and 500's 344b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 345b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This is an exception which indicates that an error has occurred, 346b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik and that any work in progress should not be committed. These are 347b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik typically results in the 400's and 500's. 348b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 349b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 350b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPRedirection(WSGIHTTPException): 351b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 352b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik base class for 300's status code (redirections) 353b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 354b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This is an abstract base class for 3xx redirection. It indicates 355b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik that further action needs to be taken by the user agent in order 356b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik to fulfill the request. It does not necessarly signal an error 357b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik condition. 358b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 359b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 360b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPOk(WSGIHTTPException): 361b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 362b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Base class for the 200's status code (successful responses) 363b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 364b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 200, title: OK 365b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 366b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 200 367b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'OK' 368b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 369b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik############################################################ 370b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik## 2xx success 371b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik############################################################ 372b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 373b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPCreated(HTTPOk): 374b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 375b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPOk` 376b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 377b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that request has been fulfilled and resulted in a new 378b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik resource being created. 379b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 380b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 201, title: Created 381b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 382b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 201 383b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Created' 384b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 385b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPAccepted(HTTPOk): 386b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 387b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPOk` 388b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 389b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the request has been accepted for processing, but the 390b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik processing has not been completed. 391b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 392b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 202, title: Accepted 393b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 394b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 202 395b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Accepted' 396b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = 'The request is accepted for processing.' 397b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 398b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPNonAuthoritativeInformation(HTTPOk): 399b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 400b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPOk` 401b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 402b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the returned metainformation in the entity-header is 403b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik not the definitive set as available from the origin server, but is 404b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik gathered from a local or a third-party copy. 405b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 406b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 203, title: Non-Authoritative Information 407b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 408b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 203 409b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Non-Authoritative Information' 410b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 411b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPNoContent(HTTPOk): 412b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 413b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPOk` 414b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 415b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server has fulfilled the request but does 416b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik not need to return an entity-body, and might want to return updated 417b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik metainformation. 418b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 419b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 204, title: No Content 420b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 421b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 204 422b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'No Content' 423b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik empty_body = True 424b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 425b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPResetContent(HTTPOk): 426b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 427b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPOk` 428b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 429b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the the server has fulfilled the request and 430b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the user agent SHOULD reset the document view which caused the 431b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik request to be sent. 432b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 433b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 205, title: Reset Content 434b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 435b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 205 436b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Reset Content' 437b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik empty_body = True 438b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 439b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPPartialContent(HTTPOk): 440b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 441b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPOk` 442b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 443b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server has fulfilled the partial GET 444b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik request for the resource. 445b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 446b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 206, title: Partial Content 447b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 448b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 206 449b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Partial Content' 450b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 451b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik############################################################ 452b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik## 3xx redirection 453b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik############################################################ 454b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 455b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass _HTTPMove(HTTPRedirection): 456b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 457b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik redirections which require a Location field 458b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 459b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Since a 'Location' header is a required attribute of 301, 302, 303, 460b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 305 and 307 (but not 304), this base class provides the mechanics to 461b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik make this easy. 462b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 463b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik You can provide a location keyword argument to set the location 464b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik immediately. You may also give ``add_slash=True`` if you want to 465b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik redirect to the same URL as the request, except with a ``/`` added 466b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik to the end. 467b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 468b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Relative URLs in the location will be resolved to absolute. 469b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 470b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = 'The resource has been moved to' 471b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik body_template_obj = Template('''\ 472b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik${explanation} <a href="${location}">${location}</a>; 473b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikyou should be redirected automatically. 474b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik${detail} 475b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik${html_comment}''') 476b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 477b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def __init__(self, detail=None, headers=None, comment=None, 478b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik body_template=None, location=None, add_slash=False): 479b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik super(_HTTPMove, self).__init__( 480b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik detail=detail, headers=headers, comment=comment, 481b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik body_template=body_template) 482b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if location is not None: 483b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.location = location 484b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if add_slash: 485b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik raise TypeError( 486b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik "You can only provide one of the arguments location " 487b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik "and add_slash") 488b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.add_slash = add_slash 489b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 490b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def __call__(self, environ, start_response): 491b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik req = Request(environ) 492b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if self.add_slash: 493b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik url = req.path_url 494b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik url += '/' 495b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if req.environ.get('QUERY_STRING'): 496b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik url += '?' + req.environ['QUERY_STRING'] 497b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.location = url 498b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.location = urlparse.urljoin(req.path_url, self.location) 499b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return super(_HTTPMove, self).__call__( 500b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik environ, start_response) 501b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 502b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPMultipleChoices(_HTTPMove): 503b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 504b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~_HTTPMove` 505b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 506b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the requested resource corresponds to any one 507b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik of a set of representations, each with its own specific location, 508b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik and agent-driven negotiation information is being provided so that 509b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the user can select a preferred representation and redirect its 510b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik request to that location. 511b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 512b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 300, title: Multiple Choices 513b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 514b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 300 515b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Multiple Choices' 516b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 517b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPMovedPermanently(_HTTPMove): 518b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 519b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~_HTTPMove` 520b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 521b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the requested resource has been assigned a new 522b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik permanent URI and any future references to this resource SHOULD use 523b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik one of the returned URIs. 524b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 525b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 301, title: Moved Permanently 526b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 527b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 301 528b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Moved Permanently' 529b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 530b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPFound(_HTTPMove): 531b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 532b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~_HTTPMove` 533b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 534b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the requested resource resides temporarily under 535b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik a different URI. 536b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 537b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 302, title: Found 538b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 539b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 302 540b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Found' 541b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = 'The resource was found at' 542b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 543b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# This one is safe after a POST (the redirected location will be 544b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# retrieved with GET): 545b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPSeeOther(_HTTPMove): 546b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 547b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~_HTTPMove` 548b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 549b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the response to the request can be found under 550b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik a different URI and SHOULD be retrieved using a GET method on that 551b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik resource. 552b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 553b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 303, title: See Other 554b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 555b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 303 556b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'See Other' 557b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 558b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPNotModified(HTTPRedirection): 559b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 560b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPRedirection` 561b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 562b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that if the client has performed a conditional GET 563b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik request and access is allowed, but the document has not been 564b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik modified, the server SHOULD respond with this status code. 565b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 566b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 304, title: Not Modified 567b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 568b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # TODO: this should include a date or etag header 569b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 304 570b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Not Modified' 571b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik empty_body = True 572b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 573b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPUseProxy(_HTTPMove): 574b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 575b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~_HTTPMove` 576b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 577b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the requested resource MUST be accessed through 578b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the proxy given by the Location field. 579b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 580b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 305, title: Use Proxy 581b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 582b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # Not a move, but looks a little like one 583b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 305 584b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Use Proxy' 585b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ( 586b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'The resource must be accessed through a proxy located at') 587b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 588b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPTemporaryRedirect(_HTTPMove): 589b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 590b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~_HTTPMove` 591b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 592b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the requested resource resides temporarily 593b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik under a different URI. 594b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 595b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 307, title: Temporary Redirect 596b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 597b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 307 598b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Temporary Redirect' 599b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 600b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik############################################################ 601b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik## 4xx client error 602b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik############################################################ 603b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 604b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPClientError(HTTPError): 605b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 606b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik base class for the 400's, where the client is in error 607b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 608b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This is an error condition in which the client is presumed to be 609b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik in-error. This is an expected problem, and thus is not considered 610b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik a bug. A server-side traceback is not warranted. Unless specialized, 611b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik this is a '400 Bad Request' 612b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 613b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 400, title: Bad Request 614b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 615b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 400 616b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Bad Request' 617b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('The server could not comply with the request since\r\n' 618b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'it is either malformed or otherwise incorrect.\r\n') 619b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 620b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPBadRequest(HTTPClientError): 621b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik pass 622b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 623b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPUnauthorized(HTTPClientError): 624b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 625b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 626b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 627b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the request requires user authentication. 628b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 629b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 401, title: Unauthorized 630b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 631b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 401 632b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Unauthorized' 633b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ( 634b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'This server could not verify that you are authorized to\r\n' 635b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'access the document you requested. Either you supplied the\r\n' 636b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'wrong credentials (e.g., bad password), or your browser\r\n' 637b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'does not understand how to supply the credentials required.\r\n') 638b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 639b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPPaymentRequired(HTTPClientError): 640b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 641b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 642b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 643b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 402, title: Payment Required 644b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 645b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 402 646b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Payment Required' 647b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('Access was denied for financial reasons.') 648b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 649b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPForbidden(HTTPClientError): 650b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 651b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 652b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 653b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server understood the request, but is 654b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik refusing to fulfill it. 655b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 656b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 403, title: Forbidden 657b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 658b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 403 659b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Forbidden' 660b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('Access was denied to this resource.') 661b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 662b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPNotFound(HTTPClientError): 663b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 664b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 665b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 666b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server did not find anything matching the 667b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Request-URI. 668b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 669b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 404, title: Not Found 670b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 671b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 404 672b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Not Found' 673b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('The resource could not be found.') 674b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 675b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPMethodNotAllowed(HTTPClientError): 676b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 677b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 678b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 679b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the method specified in the Request-Line is 680b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik not allowed for the resource identified by the Request-URI. 681b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 682b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 405, title: Method Not Allowed 683b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 684b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 405 685b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Method Not Allowed' 686b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # override template since we need an environment variable 687b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik body_template_obj = Template('''\ 688b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikThe method ${REQUEST_METHOD} is not allowed for this resource. <br /><br /> 689b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik${detail}''') 690b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 691b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPNotAcceptable(HTTPClientError): 692b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 693b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 694b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 695b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates the resource identified by the request is only 696b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik capable of generating response entities which have content 697b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik characteristics not acceptable according to the accept headers 698b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik sent in the request. 699b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 700b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 406, title: Not Acceptable 701b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 702b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 406 703b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Not Acceptable' 704b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # override template since we need an environment variable 705b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik template = Template('''\ 706b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikThe resource could not be generated that was acceptable to your browser 707b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik(content of type ${HTTP_ACCEPT}. <br /><br /> 708b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik${detail}''') 709b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 710b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPProxyAuthenticationRequired(HTTPClientError): 711b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 712b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 713b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 714b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This is similar to 401, but indicates that the client must first 715b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik authenticate itself with the proxy. 716b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 717b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 407, title: Proxy Authentication Required 718b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 719b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 407 720b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Proxy Authentication Required' 721b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('Authentication with a local proxy is needed.') 722b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 723b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPRequestTimeout(HTTPClientError): 724b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 725b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 726b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 727b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the client did not produce a request within 728b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the time that the server was prepared to wait. 729b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 730b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 408, title: Request Timeout 731b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 732b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 408 733b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Request Timeout' 734b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('The server has waited too long for the request to ' 735b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'be sent by the client.') 736b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 737b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPConflict(HTTPClientError): 738b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 739b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 740b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 741b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the request could not be completed due to a 742b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik conflict with the current state of the resource. 743b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 744b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 409, title: Conflict 745b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 746b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 409 747b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Conflict' 748b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('There was a conflict when trying to complete ' 749b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'your request.') 750b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 751b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPGone(HTTPClientError): 752b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 753b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 754b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 755b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the requested resource is no longer available 756b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik at the server and no forwarding address is known. 757b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 758b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 410, title: Gone 759b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 760b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 410 761b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Gone' 762b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('This resource is no longer available. No forwarding ' 763b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'address is given.') 764b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 765b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPLengthRequired(HTTPClientError): 766b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 767b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 768b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 769b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the the server refuses to accept the request 770b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik without a defined Content-Length. 771b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 772b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 411, title: Length Required 773b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 774b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 411 775b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Length Required' 776b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('Content-Length header required.') 777b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 778b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPPreconditionFailed(HTTPClientError): 779b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 780b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 781b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 782b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the precondition given in one or more of the 783b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik request-header fields evaluated to false when it was tested on the 784b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik server. 785b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 786b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 412, title: Precondition Failed 787b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 788b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 412 789b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Precondition Failed' 790b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('Request precondition failed.') 791b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 792b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPRequestEntityTooLarge(HTTPClientError): 793b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 794b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 795b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 796b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server is refusing to process a request 797b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik because the request entity is larger than the server is willing or 798b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik able to process. 799b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 800b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 413, title: Request Entity Too Large 801b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 802b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 413 803b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Request Entity Too Large' 804b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('The body of your request was too large for this server.') 805b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 806b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPRequestURITooLong(HTTPClientError): 807b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 808b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 809b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 810b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server is refusing to service the request 811b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik because the Request-URI is longer than the server is willing to 812b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik interpret. 813b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 814b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 414, title: Request-URI Too Long 815b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 816b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 414 817b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Request-URI Too Long' 818b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('The request URI was too long for this server.') 819b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 820b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPUnsupportedMediaType(HTTPClientError): 821b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 822b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 823b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 824b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server is refusing to service the request 825b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik because the entity of the request is in a format not supported by 826b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the requested resource for the requested method. 827b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 828b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 415, title: Unsupported Media Type 829b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 830b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 415 831b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Unsupported Media Type' 832b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # override template since we need an environment variable 833b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik template_obj = Template('''\ 834b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikThe request media type ${CONTENT_TYPE} is not supported by this server. 835b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik<br /><br /> 836b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik${detail}''') 837b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 838b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPRequestRangeNotSatisfiable(HTTPClientError): 839b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 840b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 841b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 842b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The server SHOULD return a response with this status code if a 843b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik request included a Range request-header field, and none of the 844b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik range-specifier values in this field overlap the current extent 845b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik of the selected resource, and the request did not include an 846b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik If-Range request-header field. 847b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 848b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 416, title: Request Range Not Satisfiable 849b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 850b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 416 851b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Request Range Not Satisfiable' 852b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('The Range requested is not available.') 853b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 854b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPExpectationFailed(HTTPClientError): 855b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 856b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 857b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 858b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indidcates that the expectation given in an Expect 859b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik request-header field could not be met by this server. 860b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 861b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 417, title: Expectation Failed 862b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 863b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 417 864b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Expectation Failed' 865b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('Expectation failed.') 866b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 867b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPUnprocessableEntity(HTTPClientError): 868b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 869b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 870b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 871b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server is unable to process the contained 872b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik instructions. 873b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 874b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 422, title: Unprocessable Entity 875b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 876b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ## Note: from WebDAV 877b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 422 878b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Unprocessable Entity' 879b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = 'Unable to process the contained instructions' 880b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 881b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPLocked(HTTPClientError): 882b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 883b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 884b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 885b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the resource is locked. 886b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 887b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 423, title: Locked 888b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 889b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ## Note: from WebDAV 890b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 423 891b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Locked' 892b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('The resource is locked') 893b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 894b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPFailedDependency(HTTPClientError): 895b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 896b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 897b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 898b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the method could not be performed because the 899b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik requested action depended on another action and that action failed. 900b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 901b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 424, title: Failed Dependency 902b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 903b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ## Note: from WebDAV 904b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 424 905b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Failed Dependency' 906b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ( 907b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'The method could not be performed because the requested ' 908b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'action dependended on another action and that action failed') 909b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 910b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPPreconditionRequired(HTTPClientError): 911b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 912b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 913b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 914b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the origin server requires the request to be 915b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik conditional. From RFC 6585, "Additional HTTP Status Codes". 916b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 917b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 428, title: Precondition Required 918b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 919b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 428 920b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Precondition Required' 921b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('This request is required to be conditional') 922b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 923b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPTooManyRequests(HTTPClientError): 924b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 925b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 926b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 927b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the client has sent too many requests in a 928b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik given amount of time. Useful for rate limiting. 929b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 930b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik From RFC 6585, "Additional HTTP Status Codes". 931b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 932b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 429, title: Too Many Requests 933b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 934b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 429 935b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Too Many Requests' 936b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ( 937b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'The client has sent too many requests in a given amount of time') 938b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 939b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPRequestHeaderFieldsTooLarge(HTTPClientError): 940b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 941b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 942b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 943b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server is unwilling to process the request 944b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik because its header fields are too large. The request may be resubmitted 945b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik after reducing the size of the request header fields. 946b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 947b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik From RFC 6585, "Additional HTTP Status Codes". 948b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 949b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 431, title: Request Header Fields Too Large 950b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 951b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 431 952b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Request Header Fields Too Large' 953b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ( 954b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'The request header fields were too large') 955b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 956b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPUnavailableForLegalReasons(HTTPClientError): 957b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 958b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPClientError` 959b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 960b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server is unable to process the request 961b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik because of legal reasons, e.g. censorship or government-mandated 962b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik blocked access. 963b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 964b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik From the draft "A New HTTP Status Code for Legally-restricted Resources" 965b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik by Tim Bray: 966b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 967b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik http://tools.ietf.org/html/draft-tbray-http-legally-restricted-status-00 968b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 969b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 451, title: Unavailable For Legal Reasons 970b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 971b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 451 972b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Unavailable For Legal Reasons' 973b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('The resource is not available due to legal reasons.') 974b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 975b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik############################################################ 976b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik## 5xx Server Error 977b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik############################################################ 978b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# Response status codes beginning with the digit "5" indicate cases in 979b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# which the server is aware that it has erred or is incapable of 980b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# performing the request. Except when responding to a HEAD request, the 981b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# server SHOULD include an entity containing an explanation of the error 982b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# situation, and whether it is a temporary or permanent condition. User 983b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# agents SHOULD display any included entity to the user. These response 984b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# codes are applicable to any request method. 985b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 986b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPServerError(HTTPError): 987b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 988b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik base class for the 500's, where the server is in-error 989b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 990b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This is an error condition in which the server is presumed to be 991b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik in-error. This is usually unexpected, and thus requires a traceback; 992b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ideally, opening a support ticket for the customer. Unless specialized, 993b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik this is a '500 Internal Server Error' 994b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 995b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 500 996b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Internal Server Error' 997b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ( 998b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'The server has either erred or is incapable of performing\r\n' 999b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'the requested operation.\r\n') 1000b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1001b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPInternalServerError(HTTPServerError): 1002b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik pass 1003b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1004b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPNotImplemented(HTTPServerError): 1005b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1006b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPServerError` 1007b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1008b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server does not support the functionality 1009b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik required to fulfill the request. 1010b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1011b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 501, title: Not Implemented 1012b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1013b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 501 1014b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Not Implemented' 1015b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik template = Template(''' 1016b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikThe request method ${REQUEST_METHOD} is not implemented for this server. <br /><br /> 1017b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik${detail}''') 1018b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1019b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPBadGateway(HTTPServerError): 1020b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1021b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPServerError` 1022b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1023b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server, while acting as a gateway or proxy, 1024b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik received an invalid response from the upstream server it accessed 1025b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik in attempting to fulfill the request. 1026b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1027b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 502, title: Bad Gateway 1028b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1029b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 502 1030b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Bad Gateway' 1031b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('Bad gateway.') 1032b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1033b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPServiceUnavailable(HTTPServerError): 1034b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1035b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPServerError` 1036b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1037b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server is currently unable to handle the 1038b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik request due to a temporary overloading or maintenance of the server. 1039b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1040b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 503, title: Service Unavailable 1041b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1042b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 503 1043b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Service Unavailable' 1044b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('The server is currently unavailable. ' 1045b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'Please try again at a later time.') 1046b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1047b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPGatewayTimeout(HTTPServerError): 1048b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1049b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPServerError` 1050b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1051b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server, while acting as a gateway or proxy, 1052b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik did not receive a timely response from the upstream server specified 1053b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik by the URI (e.g. HTTP, FTP, LDAP) or some other auxiliary server 1054b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik (e.g. DNS) it needed to access in attempting to complete the request. 1055b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1056b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 504, title: Gateway Timeout 1057b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1058b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 504 1059b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Gateway Timeout' 1060b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('The gateway has timed out.') 1061b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1062b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPVersionNotSupported(HTTPServerError): 1063b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1064b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPServerError` 1065b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1066b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server does not support, or refuses to 1067b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik support, the HTTP protocol version that was used in the request 1068b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik message. 1069b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1070b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 505, title: HTTP Version Not Supported 1071b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1072b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 505 1073b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'HTTP Version Not Supported' 1074b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('The HTTP version is not supported.') 1075b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1076b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPInsufficientStorage(HTTPServerError): 1077b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1078b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPServerError` 1079b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1080b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the server does not have enough space to save 1081b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the resource. 1082b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1083b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 507, title: Insufficient Storage 1084b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1085b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 507 1086b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Insufficient Storage' 1087b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('There was not enough space to save the resource') 1088b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1089b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPNetworkAuthenticationRequired(HTTPServerError): 1090b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1091b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik subclass of :class:`~HTTPServerError` 1092b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1093b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This indicates that the client needs to authenticate to gain 1094b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik network access. From RFC 6585, "Additional HTTP Status Codes". 1095b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1096b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code: 511, title: Network Authentication Required 1097b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1098b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik code = 511 1099b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik title = 'Network Authentication Required' 1100b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik explanation = ('Network authentication is required') 1101b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1102b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass HTTPExceptionMiddleware(object): 1103b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1104b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Middleware that catches exceptions in the sub-application. This 1105b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik does not catch exceptions in the app_iter; only during the initial 1106b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik calling of the application. 1107b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1108b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This should be put *very close* to applications that might raise 1109b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik these exceptions. This should not be applied globally; letting 1110b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik *expected* exceptions raise through the WSGI stack is dangerous. 1111b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 1112b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1113b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def __init__(self, application): 1114b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.application = application 1115b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def __call__(self, environ, start_response): 1116b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik try: 1117b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return self.application(environ, start_response) 1118b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik except HTTPException: 1119b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik parent_exc_info = sys.exc_info() 1120b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def repl_start_response(status, headers, exc_info=None): 1121b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if exc_info is None: 1122b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik exc_info = parent_exc_info 1123b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return start_response(status, headers, exc_info) 1124b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return parent_exc_info[1](environ, repl_start_response) 1125b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1126b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craiktry: 1127b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik from paste import httpexceptions 1128b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexcept ImportError: # pragma: no cover 1129b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # Without Paste we don't need to do this fixup 1130b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik pass 1131b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikelse: # pragma: no cover 1132b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for name in dir(httpexceptions): 1133b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik obj = globals().get(name) 1134b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (obj and isinstance(obj, type) and issubclass(obj, HTTPException) 1135b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik and obj is not HTTPException 1136b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik and obj is not WSGIHTTPException): 1137b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik obj.__bases__ = obj.__bases__ + (getattr(httpexceptions, name),) 1138b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik del name, obj, httpexceptions 1139b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1140b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik__all__ = ['HTTPExceptionMiddleware', 'status_map'] 1141b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikstatus_map={} 1142b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfor name, value in list(globals().items()): 1143b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if (isinstance(value, (type, class_types)) and 1144b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik issubclass(value, HTTPException) 1145b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik and not name.startswith('_')): 1146b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik __all__.append(name) 1147b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if getattr(value, 'code', None): 1148b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik status_map[value.code]=value 1149b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if hasattr(value, 'explanation'): 1150b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik value.explanation = ' '.join(value.explanation.strip().split()) 1151b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdel name, value 1152