parseHeader static method

List<AuthenticationChallenge> parseHeader(
  1. String header
)

Parses a WWW-Authenticate header, which should contain one or more challenges.

Throws a FormatException if the header is invalid.

Implementation

static List<AuthenticationChallenge> parseHeader(String header) =>
    wrapFormatException('authentication header', header, () {
      final scanner = StringScanner(header);
      scanner.scan(whitespace);
      final challenges = parseList(scanner, () {
        final scheme = _scanScheme(scanner, whitespaceName: '" " or "="');

        // Manually parse the inner list. We need to do some lookahead to
        // disambiguate between an auth param and another challenge.
        final params = <String, String>{};

        // Consume initial empty values.
        while (scanner.scan(',')) {
          scanner.scan(whitespace);
        }

        _scanAuthParam(scanner, params);

        var beforeComma = scanner.position;
        while (scanner.scan(',')) {
          scanner.scan(whitespace);

          // Empty elements are allowed, but excluded from the results.
          if (scanner.matches(',') || scanner.isDone) continue;

          scanner.expect(token, name: 'a token');
          final name = scanner.lastMatch![0]!;
          scanner.scan(whitespace);

          // If there's no "=", then this is another challenge rather than a
          // parameter for the current challenge.
          if (!scanner.scan('=')) {
            scanner.position = beforeComma;
            break;
          }

          scanner.scan(whitespace);

          if (scanner.scan(token)) {
            params[name] = scanner.lastMatch![0]!;
          } else {
            params[name] = expectQuotedString(scanner,
                name: 'a token or a quoted string');
          }

          scanner.scan(whitespace);
          beforeComma = scanner.position;
        }

        return AuthenticationChallenge(scheme, params);
      });

      scanner.expectDone();
      return challenges;
    });