|
2 | 2 |
|
3 | 3 | from base64 import b64encode
|
4 | 4 | from collections.abc import Mapping, MutableMapping, Sequence
|
| 5 | +from io import BytesIO |
5 | 6 | from typing import Any, Union, overload
|
6 | 7 |
|
7 | 8 | from w3lib.util import to_bytes, to_unicode
|
@@ -44,21 +45,23 @@ def headers_raw_to_dict(headers_raw: bytes | None) -> HeadersDictOutput | None:
|
44 | 45 |
|
45 | 46 | if headers_raw is None:
|
46 | 47 | return None
|
47 |
| - headers = headers_raw.splitlines() |
48 |
| - headers_tuples = [header.split(b":", 1) for header in headers] |
| 48 | + |
| 49 | + if not headers_raw: |
| 50 | + return {} |
49 | 51 |
|
50 | 52 | result_dict: HeadersDictOutput = {}
|
51 |
| - for header_item in headers_tuples: |
52 |
| - if len(header_item) != 2: |
| 53 | + |
| 54 | + for header in BytesIO(headers_raw): |
| 55 | + key, sep, value = header.partition(b":") |
| 56 | + if not sep: |
53 | 57 | continue
|
54 | 58 |
|
55 |
| - item_key = header_item[0].strip() |
56 |
| - item_value = header_item[1].strip() |
| 59 | + key, value = key.strip(), value.strip() |
57 | 60 |
|
58 |
| - if item_key in result_dict: |
59 |
| - result_dict[item_key].append(item_value) |
| 61 | + if key in result_dict: |
| 62 | + result_dict[key].append(value) |
60 | 63 | else:
|
61 |
| - result_dict[item_key] = [item_value] |
| 64 | + result_dict[key] = [value] |
62 | 65 |
|
63 | 66 | return result_dict
|
64 | 67 |
|
@@ -93,13 +96,25 @@ def headers_dict_to_raw(headers_dict: HeadersDictInput | None) -> bytes | None:
|
93 | 96 |
|
94 | 97 | if headers_dict is None:
|
95 | 98 | return None
|
96 |
| - raw_lines = [] |
| 99 | + |
| 100 | + if not headers_dict: |
| 101 | + return b"" |
| 102 | + |
| 103 | + parts = bytearray() |
| 104 | + |
97 | 105 | for key, value in headers_dict.items():
|
98 | 106 | if isinstance(value, bytes):
|
99 |
| - raw_lines.append(b": ".join([key, value])) |
| 107 | + if parts: |
| 108 | + parts.extend(b"\r\n") |
| 109 | + parts.extend(key + b": " + value) |
| 110 | + |
100 | 111 | elif isinstance(value, (list, tuple)):
|
101 |
| - raw_lines.extend(b": ".join([key, v]) for v in value) |
102 |
| - return b"\r\n".join(raw_lines) |
| 112 | + for v in value: |
| 113 | + if parts: |
| 114 | + parts.extend(b"\r\n") |
| 115 | + parts.extend(key + b": " + v) |
| 116 | + |
| 117 | + return bytes(parts) |
103 | 118 |
|
104 | 119 |
|
105 | 120 | def basic_auth_header(
|
|
0 commit comments