11import re
2- from typing import AnyStr , cast , List , overload , Sequence , Tuple , TYPE_CHECKING , Union
2+ from typing import List , overload , Sequence , Tuple , TYPE_CHECKING , TypeVar , Union
33
44from ._abnf import field_name , field_value
55from ._util import bytesify , LocalProtocolError , validate
1313 from typing_extensions import Literal # type: ignore
1414
1515
16+ T = TypeVar ("T" )
17+
1618# Facts
1719# -----
1820#
@@ -84,19 +86,29 @@ class Headers(Sequence[Tuple[bytes, bytes]]):
8486 r = Request(
8587 method="GET",
8688 target="/",
87- headers=[("Host", "example.org"), ("Connection", "keep-alive")],
89+ headers=[
90+ ("Host", "example.org"),
91+ ("Connection", "keep-alive"),
92+ ("Cookie", "session=1234"),
93+ ("Cookie", "lang=en_US"),
94+ ],
8895 http_version="1.1",
8996 )
9097 assert r.headers == [
9198 (b"host", b"example.org"),
92- (b"connection", b"keep-alive")
99+ (b"connection", b"keep-alive"),
100+ (b"cookie", b"session=1234"),
101+ (b"cookie", b"lang=en_US"),
93102 ]
94103 assert r.headers.raw_items() == [
95104 (b"Host", b"example.org"),
96- (b"Connection", b"keep-alive")
105+ (b"Connection", b"keep-alive"),
106+ (b"Cookie", b"session=1234"),
107+ (b"Cookie", b"lang=en_US"),
97108 ]
109+ assert r.headers.get(b"host") == b"example.org"
110+ assert r.headers.getlist(b"cookie") == [b"session=1234", b"lang=en_US"]
98111 """
99-
100112 __slots__ = "_full_items"
101113
102114 def __init__ (self , full_items : List [Tuple [bytes , bytes , bytes ]]) -> None :
@@ -118,6 +130,27 @@ def __getitem__(self, idx: int) -> Tuple[bytes, bytes]: # type: ignore[override
118130 _ , name , value = self ._full_items [idx ]
119131 return (name , value )
120132
133+ def get (self , key : bytes , default : T = None ) -> Union [bytes , T ]:
134+ """Find the first header with lowercased-name :param:`key`, it returns
135+ its value when found, and :param:`default` otherwise.
136+
137+ Args:
138+ key (bytes): The lowercased header name to find.
139+
140+ default: The value to return when the header is not found.
141+ """
142+ return next ((value for name , value in self if name == key ), default )
143+
144+ def getlist (self , key : bytes ) -> List [bytes ]:
145+ """Find the all the headers with lowercased-name :param:`key`,
146+ it returns their values in a list. It returns an empty list when
147+ no header matched.
148+
149+ Args:
150+ key (bytes): The lowercased header name to find.
151+ """
152+ return [value for name , value in self if name == key ]
153+
121154 def raw_items (self ) -> List [Tuple [bytes , bytes ]]:
122155 return [(raw_name , value ) for raw_name , _ , value in self ._full_items ]
123156
0 commit comments