(
self, lines: list[bytes]
)
| 172 | self._lax = lax |
| 173 | |
| 174 | def parse_headers( |
| 175 | self, lines: list[bytes] |
| 176 | ) -> tuple["CIMultiDictProxy[str]", RawHeaders]: |
| 177 | headers: CIMultiDict[str] = CIMultiDict() |
| 178 | # note: "raw" does not mean inclusion of OWS before/after the field value |
| 179 | raw_headers = [] |
| 180 | |
| 181 | lines_idx = 0 |
| 182 | line = lines[lines_idx] |
| 183 | line_count = len(lines) |
| 184 | |
| 185 | while line: |
| 186 | # Parse initial header name : value pair. |
| 187 | try: |
| 188 | bname, bvalue = line.split(b":", 1) |
| 189 | except ValueError: |
| 190 | raise InvalidHeader(line) from None |
| 191 | |
| 192 | if len(bname) == 0: |
| 193 | raise InvalidHeader(bname) |
| 194 | |
| 195 | # https://www.rfc-editor.org/rfc/rfc9112.html#section-5.1-2 |
| 196 | if {bname[0], bname[-1]} & {32, 9}: # {" ", "\t"} |
| 197 | raise InvalidHeader(line) |
| 198 | |
| 199 | bvalue = bvalue.lstrip(b" \t") |
| 200 | name = bname.decode("utf-8", "surrogateescape") |
| 201 | if not TOKENRE.fullmatch(name): |
| 202 | raise InvalidHeader(bname) |
| 203 | |
| 204 | # next line |
| 205 | lines_idx += 1 |
| 206 | line = lines[lines_idx] |
| 207 | |
| 208 | # consume continuation lines |
| 209 | continuation = self._lax and line and line[0] in (32, 9) # (' ', '\t') |
| 210 | |
| 211 | # Deprecated: https://www.rfc-editor.org/rfc/rfc9112.html#name-obsolete-line-folding |
| 212 | if continuation: |
| 213 | header_length = len(bvalue) |
| 214 | bvalue_lst = [bvalue] |
| 215 | while continuation: |
| 216 | header_length += len(line) |
| 217 | if header_length > self.max_field_size: |
| 218 | header_line = bname + b": " + b"".join(bvalue_lst) |
| 219 | raise LineTooLong( |
| 220 | header_line[:100] + b"...", self.max_field_size |
| 221 | ) |
| 222 | bvalue_lst.append(line) |
| 223 | |
| 224 | # next line |
| 225 | lines_idx += 1 |
| 226 | if lines_idx < line_count: |
| 227 | line = lines[lines_idx] |
| 228 | if line: |
| 229 | continuation = line[0] in (32, 9) # (' ', '\t') |
| 230 | else: |
| 231 | line = b"" |
no test coverage detected