Collect HTTP response headers, preserving all values for duplicate names. Python's http.client.HTTPMessage yields duplicate header names (e.g. multiple Set-Cookie lines) as separate items when iterated. A plain dict assignment silently overwrites earlier values, so sites like auth.open
(raw_headers)
| 159 | |
| 160 | |
| 161 | def _collect_headers(raw_headers) -> dict: |
| 162 | """Collect HTTP response headers, preserving all values for duplicate names. |
| 163 | |
| 164 | Python's http.client.HTTPMessage yields duplicate header names (e.g. multiple |
| 165 | Set-Cookie lines) as separate items when iterated. A plain dict assignment |
| 166 | silently overwrites earlier values, so sites like auth.openai.com that set |
| 167 | several Set-Cookie headers in one response would lose all but the last one. |
| 168 | Accumulate duplicates into a list so every value reaches the browser. |
| 169 | """ |
| 170 | out: dict = {} |
| 171 | key_map: dict[str, str] = {} # lowercase name → first-seen canonical case |
| 172 | for k, v in raw_headers.items(): |
| 173 | kl = k.lower() |
| 174 | if kl not in key_map: |
| 175 | key_map[kl] = k |
| 176 | out[k] = v |
| 177 | else: |
| 178 | canonical = key_map[kl] |
| 179 | cur = out[canonical] |
| 180 | if isinstance(cur, list): |
| 181 | cur.append(v) |
| 182 | else: |
| 183 | out[canonical] = [cur, v] |
| 184 | return out |
| 185 | |
| 186 | |
| 187 | def _relay_request( |