9092ee9f0e
* introduced basic entity and hopbyhop header identification * removed entity headers * coding style fixes * remove unneeded header check * moved from bytes to unicode in headers * changed list to tuple in empty response statuses
129 lines
3.6 KiB
Python
129 lines
3.6 KiB
Python
"""Defines basics of HTTP standard."""
|
|
|
|
STATUS_CODES = {
|
|
100: b'Continue',
|
|
101: b'Switching Protocols',
|
|
102: b'Processing',
|
|
200: b'OK',
|
|
201: b'Created',
|
|
202: b'Accepted',
|
|
203: b'Non-Authoritative Information',
|
|
204: b'No Content',
|
|
205: b'Reset Content',
|
|
206: b'Partial Content',
|
|
207: b'Multi-Status',
|
|
208: b'Already Reported',
|
|
226: b'IM Used',
|
|
300: b'Multiple Choices',
|
|
301: b'Moved Permanently',
|
|
302: b'Found',
|
|
303: b'See Other',
|
|
304: b'Not Modified',
|
|
305: b'Use Proxy',
|
|
307: b'Temporary Redirect',
|
|
308: b'Permanent Redirect',
|
|
400: b'Bad Request',
|
|
401: b'Unauthorized',
|
|
402: b'Payment Required',
|
|
403: b'Forbidden',
|
|
404: b'Not Found',
|
|
405: b'Method Not Allowed',
|
|
406: b'Not Acceptable',
|
|
407: b'Proxy Authentication Required',
|
|
408: b'Request Timeout',
|
|
409: b'Conflict',
|
|
410: b'Gone',
|
|
411: b'Length Required',
|
|
412: b'Precondition Failed',
|
|
413: b'Request Entity Too Large',
|
|
414: b'Request-URI Too Long',
|
|
415: b'Unsupported Media Type',
|
|
416: b'Requested Range Not Satisfiable',
|
|
417: b'Expectation Failed',
|
|
418: b'I\'m a teapot',
|
|
422: b'Unprocessable Entity',
|
|
423: b'Locked',
|
|
424: b'Failed Dependency',
|
|
426: b'Upgrade Required',
|
|
428: b'Precondition Required',
|
|
429: b'Too Many Requests',
|
|
431: b'Request Header Fields Too Large',
|
|
451: b'Unavailable For Legal Reasons',
|
|
500: b'Internal Server Error',
|
|
501: b'Not Implemented',
|
|
502: b'Bad Gateway',
|
|
503: b'Service Unavailable',
|
|
504: b'Gateway Timeout',
|
|
505: b'HTTP Version Not Supported',
|
|
506: b'Variant Also Negotiates',
|
|
507: b'Insufficient Storage',
|
|
508: b'Loop Detected',
|
|
510: b'Not Extended',
|
|
511: b'Network Authentication Required'
|
|
}
|
|
|
|
# According to https://tools.ietf.org/html/rfc2616#section-7.1
|
|
_ENTITY_HEADERS = frozenset([
|
|
'allow',
|
|
'content-encoding',
|
|
'content-language',
|
|
'content-length',
|
|
'content-location',
|
|
'content-md5',
|
|
'content-range',
|
|
'content-type',
|
|
'expires',
|
|
'last-modified',
|
|
'extension-header'
|
|
])
|
|
|
|
# According to https://tools.ietf.org/html/rfc2616#section-13.5.1
|
|
_HOP_BY_HOP_HEADERS = frozenset([
|
|
'connection',
|
|
'keep-alive',
|
|
'proxy-authenticate',
|
|
'proxy-authorization',
|
|
'te',
|
|
'trailers',
|
|
'transfer-encoding',
|
|
'upgrade'
|
|
])
|
|
|
|
|
|
def has_message_body(status):
|
|
"""
|
|
According to the following RFC message body and length SHOULD NOT
|
|
be included in responses status 1XX, 204 and 304.
|
|
https://tools.ietf.org/html/rfc2616#section-4.4
|
|
https://tools.ietf.org/html/rfc2616#section-4.3
|
|
"""
|
|
return status not in (204, 304) and not (100 <= status < 200)
|
|
|
|
|
|
def is_entity_header(header):
|
|
"""Checks if the given header is an Entity Header"""
|
|
return header.lower() in _ENTITY_HEADERS
|
|
|
|
|
|
def is_hop_by_hop_header(header):
|
|
"""Checks if the given header is a Hop By Hop header"""
|
|
return header.lower() in _HOP_BY_HOP_HEADERS
|
|
|
|
|
|
def remove_entity_headers(headers,
|
|
allowed=('content-location', 'expires')):
|
|
"""
|
|
Removes all the entity headers present in the headers given.
|
|
According to RFC 2616 Section 10.3.5,
|
|
Content-Location and Expires are allowed as for the
|
|
"strong cache validator".
|
|
https://tools.ietf.org/html/rfc2616#section-10.3.5
|
|
|
|
returns the headers without the entity headers
|
|
"""
|
|
allowed = set([h.lower() for h in allowed])
|
|
headers = {header: value for header, value in headers.items()
|
|
if not is_entity_header(header)
|
|
and header.lower() not in allowed}
|
|
return headers
|