Ad-hoc parser for Netscape protocol cookie-attributes. The old Netscape cookie format for Set-Cookie can for instance contain an unquoted "," in the expires field, so we have to use this ad-hoc parser instead of split_header_words. XXX This may not make the best possible effort to
(ns_headers)
| 465 | return text |
| 466 | |
| 467 | def parse_ns_headers(ns_headers): |
| 468 | """Ad-hoc parser for Netscape protocol cookie-attributes. |
| 469 | |
| 470 | The old Netscape cookie format for Set-Cookie can for instance contain |
| 471 | an unquoted "," in the expires field, so we have to use this ad-hoc |
| 472 | parser instead of split_header_words. |
| 473 | |
| 474 | XXX This may not make the best possible effort to parse all the crap |
| 475 | that Netscape Cookie headers contain. Ronald Tschalar's HTTPClient |
| 476 | parser is probably better, so could do worse than following that if |
| 477 | this ever gives any trouble. |
| 478 | |
| 479 | Currently, this is also used for parsing RFC 2109 cookies. |
| 480 | |
| 481 | """ |
| 482 | known_attrs = ("expires", "domain", "path", "secure", |
| 483 | # RFC 2109 attrs (may turn up in Netscape cookies, too) |
| 484 | "version", "port", "max-age") |
| 485 | |
| 486 | result = [] |
| 487 | for ns_header in ns_headers: |
| 488 | pairs = [] |
| 489 | version_set = False |
| 490 | |
| 491 | # XXX: The following does not strictly adhere to RFCs in that empty |
| 492 | # names and values are legal (the former will only appear once and will |
| 493 | # be overwritten if multiple occurrences are present). This is |
| 494 | # mostly to deal with backwards compatibility. |
| 495 | for ii, param in enumerate(ns_header.split(';')): |
| 496 | param = param.strip() |
| 497 | |
| 498 | key, sep, val = param.partition('=') |
| 499 | key = key.strip() |
| 500 | |
| 501 | if not key: |
| 502 | if ii == 0: |
| 503 | break |
| 504 | else: |
| 505 | continue |
| 506 | |
| 507 | # allow for a distinction between present and empty and missing |
| 508 | # altogether |
| 509 | val = val.strip() if sep else None |
| 510 | |
| 511 | if ii != 0: |
| 512 | lc = key.lower() |
| 513 | if lc in known_attrs: |
| 514 | key = lc |
| 515 | |
| 516 | if key == "version": |
| 517 | # This is an RFC 2109 cookie. |
| 518 | if val is not None: |
| 519 | val = strip_quotes(val) |
| 520 | version_set = True |
| 521 | elif key == "expires": |
| 522 | # convert expires date to seconds since epoch |
| 523 | if val is not None: |
| 524 | val = http2time(strip_quotes(val)) # None if invalid |
searching dependent graphs…