| 638 | namespace header { |
| 639 | |
| 640 | Try<WWWAuthenticate> WWWAuthenticate::create(const string& input) |
| 641 | { |
| 642 | // Set `maxTokens` as 2 since auth-param quoted string may |
| 643 | // contain space (e.g., "Basic realm="Registry Realm"). |
| 644 | vector<string> tokens = strings::tokenize(input, " ", 2); |
| 645 | if (tokens.size() != 2) { |
| 646 | return Error("Unexpected WWW-Authenticate header format: '" + input + "'"); |
| 647 | } |
| 648 | |
| 649 | // Since the authentication parameters can contain quote values, we |
| 650 | // do not use `strings::split` here since the delimiter may occur in |
| 651 | // a quoted value which should not be split. |
| 652 | hashmap<string, string> authParam; |
| 653 | Option<string> key, value; |
| 654 | bool inQuotes = false; |
| 655 | |
| 656 | foreach (char c, tokens[1]) { |
| 657 | // Auth-param values can be a quoted-string or directive values. |
| 658 | // Please see section "3.2.2.4 Directive values and quoted-string": |
| 659 | // https://tools.ietf.org/html/rfc2617. |
| 660 | // |
| 661 | // If we see a quote we know we must already be parsing `value` |
| 662 | // since `key` cannot be a quoted-string. |
| 663 | if (c != '"' && inQuotes) { |
| 664 | if (value.isNone()) { |
| 665 | return Error("Unexpected auth-param format: '" + tokens[1] + "'"); |
| 666 | } |
| 667 | |
| 668 | value->append({c}); |
| 669 | continue; |
| 670 | } |
| 671 | |
| 672 | // If we have not yet parsed `key` this character must belong to |
| 673 | // it if it is not a space, and cannot be a `,` delimiter. |
| 674 | if (key.isNone()) { |
| 675 | if (c == ',') { |
| 676 | return Error("Unexpected auth-param format: '" + tokens[1] + "'"); |
| 677 | } |
| 678 | |
| 679 | if (c == ' ') { |
| 680 | continue; |
| 681 | } |
| 682 | |
| 683 | key = string({c}); |
| 684 | continue; |
| 685 | } |
| 686 | |
| 687 | // If the current character is `=` we must start parsing a new |
| 688 | // `value`. Since we have already handled `=` in quotes above we |
| 689 | // cannot already have started parsing `value`. |
| 690 | if (c == '=') { |
| 691 | if (value.isSome()) { |
| 692 | return Error("Unexpected auth-param format: '" + tokens[1] + "'"); |
| 693 | } |
| 694 | value = ""; |
| 695 | continue; |
| 696 | } |
| 697 |
nothing calls this directly
no test coverage detected