Index: pkg/oauth2/lib/src/utils.dart |
diff --git a/pkg/oauth2/lib/src/utils.dart b/pkg/oauth2/lib/src/utils.dart |
index 583a5bc4438ecea546e41cb8b833b235448676de..59428b3c6fa906927c3f067df2f736c619467b9a 100644 |
--- a/pkg/oauth2/lib/src/utils.dart |
+++ b/pkg/oauth2/lib/src/utils.dart |
@@ -65,6 +65,52 @@ List<String> split1(String toSplit, String pattern) { |
toSplit.substring(index + pattern.length)]; |
} |
+/// A WWW-Authenticate header value, parsed as per [RFC 2617][]. |
+/// |
+/// [RFC 2617]: http://tools.ietf.org/html/rfc2617 |
+class AuthenticateHeader { |
+ final String scheme; |
+ final Map<String, String> parameters; |
+ |
+ AuthenticateHeader(this.scheme, this.parameters); |
+ |
+ /// Parses a header string. Throws a [FormatException] if the header is |
+ /// invalid. |
+ factory AuthenticateHeader.parse(String header) { |
+ var split = split1(header, ' '); |
+ if (split.length == 0) { |
+ throw new FormatException('Invalid WWW-Authenticate header: "$header"'); |
+ } else if (split.length == 1 || split[1].trim().isEmpty) { |
+ return new AuthenticateHeader(split[0].toLowerCase(), {}); |
+ } |
+ var scheme = split[0].toLowerCase(); |
+ var paramString = split[1]; |
+ |
+ // From http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html. |
+ var tokenChar = r'[^\0-\x1F()<>@,;:\\"/\[\]?={} \t\x7F]'; |
+ var quotedStringChar = r'(?:[^\0-\x1F\x7F"]|\\.)'; |
+ var regexp = new RegExp('^ *($tokenChar+)="($quotedStringChar*)" *(, *)?'); |
+ |
+ var parameters = {}; |
+ var match; |
+ do { |
+ match = regexp.firstMatch(paramString); |
+ if (match == null) { |
+ throw new FormatException('Invalid WWW-Authenticate header: "$header"'); |
+ } |
+ |
+ paramString = paramString.substring(match.end); |
+ parameters[match.group(1).toLowerCase()] = match.group(2); |
+ } while (match.group(3) != null); |
+ |
+ if (!paramString.trim().isEmpty) { |
+ throw new FormatException('Invalid WWW-Authenticate header: "$header"'); |
+ } |
+ |
+ return new AuthenticateHeader(scheme, parameters); |
+ } |
+} |
+ |
/// Returns a [Future] that asynchronously completes to `null`. |
Future get async { |
var completer = new Completer(); |