Manage a collection of HTTP response headers
| 31 | |
| 32 | |
| 33 | class Headers: |
| 34 | """Manage a collection of HTTP response headers""" |
| 35 | |
| 36 | def __init__(self, headers=None): |
| 37 | headers = headers if headers is not None else [] |
| 38 | if type(headers) is not list: |
| 39 | raise TypeError("Headers must be a list of name/value tuples") |
| 40 | self._headers = headers |
| 41 | if __debug__: |
| 42 | for k, v in headers: |
| 43 | self._convert_string_type(k, name=True) |
| 44 | self._convert_string_type(v, name=False) |
| 45 | |
| 46 | def _convert_string_type(self, value, *, name): |
| 47 | """Convert/check value type.""" |
| 48 | if type(value) is str: |
| 49 | regex = (_name_disallowed_re if name else _value_disallowed_re) |
| 50 | if regex.search(value): |
| 51 | raise ValueError("Control characters not allowed in headers") |
| 52 | return value |
| 53 | raise AssertionError("Header names/values must be" |
| 54 | " of type str (got {0})".format(repr(value))) |
| 55 | |
| 56 | def __len__(self): |
| 57 | """Return the total number of headers, including duplicates.""" |
| 58 | return len(self._headers) |
| 59 | |
| 60 | def __setitem__(self, name, val): |
| 61 | """Set the value of a header.""" |
| 62 | del self[name] |
| 63 | self._headers.append( |
| 64 | (self._convert_string_type(name, name=True), self._convert_string_type(val, name=False))) |
| 65 | |
| 66 | def __delitem__(self,name): |
| 67 | """Delete all occurrences of a header, if present. |
| 68 | |
| 69 | Does *not* raise an exception if the header is missing. |
| 70 | """ |
| 71 | name = self._convert_string_type(name.lower(), name=True) |
| 72 | self._headers[:] = [kv for kv in self._headers if kv[0].lower() != name] |
| 73 | |
| 74 | def __getitem__(self,name): |
| 75 | """Get the first header value for 'name' |
| 76 | |
| 77 | Return None if the header is missing instead of raising an exception. |
| 78 | |
| 79 | Note that if the header appeared multiple times, the first exactly which |
| 80 | occurrence gets returned is undefined. Use getall() to get all |
| 81 | the values matching a header field name. |
| 82 | """ |
| 83 | return self.get(name) |
| 84 | |
| 85 | def __contains__(self, name): |
| 86 | """Return true if the message contains the header.""" |
| 87 | return self.get(name) is not None |
| 88 | |
| 89 | |
| 90 | def get_all(self, name): |
no outgoing calls
searching dependent graphs…