|
8 | 8 | """ |
9 | 9 |
|
10 | 10 | try: |
11 | | - from typing import Dict, Tuple, Union |
| 11 | + from typing import Dict, List, Union |
12 | 12 | except ImportError: |
13 | 13 | pass |
14 | 14 |
|
| 15 | +from .interfaces import _IFieldStorage |
15 | 16 |
|
16 | | -class Headers: |
| 17 | + |
| 18 | +class Headers(_IFieldStorage): |
17 | 19 | """ |
18 | 20 | A dict-like class for storing HTTP headers. |
19 | 21 |
|
@@ -47,23 +49,30 @@ class Headers: |
47 | 49 | # True |
48 | 50 | """ |
49 | 51 |
|
50 | | - _storage: Dict[str, Tuple[str, str]] |
| 52 | + _storage: Dict[str, List[str]] |
51 | 53 |
|
52 | 54 | def __init__(self, headers: Union[str, Dict[str, str]] = None) -> None: |
| 55 | + self._storage = {} |
| 56 | + |
53 | 57 | if isinstance(headers, str): |
54 | | - headers = { |
55 | | - name: value |
56 | | - for header_line in headers.strip().splitlines() |
57 | | - for name, value in [header_line.split(": ", 1)] |
58 | | - } |
| 58 | + for header_line in headers.strip().splitlines(): |
| 59 | + name, value = header_line.split(": ", 1) |
| 60 | + self.add(name, value) |
59 | 61 | else: |
60 | | - headers = headers or {} |
| 62 | + for key, value in (headers or {}).items(): |
| 63 | + self.add(key, value) |
61 | 64 |
|
62 | | - self._storage = {key.lower(): [key, value] for key, value in headers.items()} |
| 65 | + def add(self, field_name: str, value: str): |
| 66 | + """Adds a header with the given field name and value.""" |
| 67 | + self._add_field_value(field_name.lower(), value) |
63 | 68 |
|
64 | | - def get(self, name: str, default: str = None) -> Union[str, None]: |
| 69 | + def get(self, field_name: str, default: str = None) -> Union[str, None]: |
65 | 70 | """Returns the value for the given header name, or default if not found.""" |
66 | | - return self._storage.get(name.lower(), [None, default])[1] |
| 71 | + return super().get(field_name.lower(), default) |
| 72 | + |
| 73 | + def get_list(self, field_name: str) -> List[str]: |
| 74 | + """Get the list of values of a field.""" |
| 75 | + return super().get_list(field_name.lower()) |
67 | 76 |
|
68 | 77 | def get_directive(self, name: str, default: str = None) -> Union[str, None]: |
69 | 78 | """ |
@@ -102,49 +111,36 @@ def get_parameter( |
102 | 111 | return header_parameter.strip().split("=")[1].strip('" ') |
103 | 112 | return default |
104 | 113 |
|
| 114 | + def set(self, name: str, value: str): |
| 115 | + """Sets the value for the given header name.""" |
| 116 | + self._storage[name.lower()] = [value] |
| 117 | + |
105 | 118 | def setdefault(self, name: str, default: str = None): |
106 | 119 | """Sets the value for the given header name if it does not exist.""" |
107 | | - return self._storage.setdefault(name.lower(), [name, default])[1] |
108 | | - |
109 | | - def items(self): |
110 | | - """Returns a list of (name, value) tuples.""" |
111 | | - return dict(self._storage.values()).items() |
112 | | - |
113 | | - def keys(self): |
114 | | - """Returns a list of header names.""" |
115 | | - return list(dict(self._storage.values()).keys()) |
116 | | - |
117 | | - def values(self): |
118 | | - """Returns a list of header values.""" |
119 | | - return list(dict(self._storage.values()).values()) |
| 120 | + return self._storage.setdefault(name.lower(), [default]) |
120 | 121 |
|
121 | 122 | def update(self, headers: Dict[str, str]): |
122 | 123 | """Updates the headers with the given dict.""" |
123 | 124 | return self._storage.update( |
124 | | - {key.lower(): [key, value] for key, value in headers.items()} |
| 125 | + {key.lower(): [value] for key, value in headers.items()} |
125 | 126 | ) |
126 | 127 |
|
127 | 128 | def copy(self): |
128 | 129 | """Returns a copy of the headers.""" |
129 | | - return Headers(dict(self._storage.values())) |
| 130 | + return Headers( |
| 131 | + "\r\n".join( |
| 132 | + f"{key}: {value}" for key in self.fields for value in self.get_list(key) |
| 133 | + ) |
| 134 | + ) |
130 | 135 |
|
131 | 136 | def __getitem__(self, name: str): |
132 | | - return self._storage[name.lower()][1] |
| 137 | + return super().__getitem__(name.lower()) |
133 | 138 |
|
134 | 139 | def __setitem__(self, name: str, value: str): |
135 | | - self._storage[name.lower()] = [name, value] |
| 140 | + self._storage[name.lower()] = [value] |
136 | 141 |
|
137 | 142 | def __delitem__(self, name: str): |
138 | 143 | del self._storage[name.lower()] |
139 | 144 |
|
140 | | - def __iter__(self): |
141 | | - return iter(dict(self._storage.values())) |
142 | | - |
143 | | - def __len__(self): |
144 | | - return len(self._storage) |
145 | | - |
146 | 145 | def __contains__(self, key: str): |
147 | | - return key.lower() in self._storage.keys() |
148 | | - |
149 | | - def __repr__(self): |
150 | | - return f"{self.__class__.__name__}({dict(self._storage.values())})" |
| 146 | + return super().__contains__(key.lower()) |
0 commit comments