|
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