Merge branch 'authentication-challenge' into case-insensitive-map
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3ac45ef..cdf85d4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,9 @@
* Added an `AuthenticationChallenge` class for parsing and representing the
value of `WWW-Authenticate` and related headers.
+* Added a `CaseInsensitiveMap` class for representing case-insensitive HTTP
+ values.
+
## 0.0.2+8
* Bring in the latest `dart:io` WebSocket code.
diff --git a/lib/http_parser.dart b/lib/http_parser.dart
index f5921ee..77c75c0 100644
--- a/lib/http_parser.dart
+++ b/lib/http_parser.dart
@@ -5,6 +5,7 @@
library http_parser;
export 'src/authentication_challenge.dart';
+export 'src/case_insensitive_map.dart';
export 'src/http_date.dart';
export 'src/media_type.dart';
export 'src/web_socket.dart';
diff --git a/lib/src/authentication_challenge.dart b/lib/src/authentication_challenge.dart
index 3b70fed..773ee3b 100644
--- a/lib/src/authentication_challenge.dart
+++ b/lib/src/authentication_challenge.dart
@@ -8,6 +8,7 @@
import 'package:string_scanner/string_scanner.dart';
+import 'case_insensitive_map.dart';
import 'scan.dart';
import 'utils.dart';
@@ -26,7 +27,8 @@
/// The parameters describing how to authenticate.
///
- /// The semantics of these parameters are scheme-specific.
+ /// The semantics of these parameters are scheme-specific. The keys of this
+ /// map are case-insensitive.
final Map<String, String> parameters;
/// Parses a WWW-Authenticate header, which should contain one or more
@@ -59,7 +61,7 @@
if (scanner.matches(",") || scanner.isDone) continue;
scanner.expect(token, name: "a token");
- var name = scanner.lastMatch[0].toLowerCase();
+ var name = scanner.lastMatch[0];
scanner.scan(whitespace);
// If there's no "=", then this is another challenge rather than a
@@ -129,7 +131,7 @@
/// Scans a single authentication parameter and stores its result in [params].
static void _scanAuthParam(StringScanner scanner, Map params) {
scanner.expect(token, name: "a token");
- var name = scanner.lastMatch[0].toLowerCase();
+ var name = scanner.lastMatch[0];
scanner.scan(whitespace);
scanner.expect('=');
scanner.scan(whitespace);
@@ -146,5 +148,6 @@
/// Creates a new challenge value with [scheme] and [parameters].
AuthenticationChallenge(this.scheme, Map<String, String> parameters)
- : parameters = new UnmodifiableMapView(parameters);
+ : parameters = new UnmodifiableMapView(
+ new CaseInsensitiveMap.from(parameters));
}
diff --git a/lib/src/case_insensitive_map.dart b/lib/src/case_insensitive_map.dart
new file mode 100644
index 0000000..34e85b2
--- /dev/null
+++ b/lib/src/case_insensitive_map.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library http_parser.case_insensitive_map;
+
+import 'package:collection/collection.dart';
+
+/// A map from case-insensitive strings to values.
+///
+/// Much of HTTP is case-insensitive, so this is useful to have pre-defined.
+class CaseInsensitiveMap<V> extends CanonicalizedMap<String, String, V> {
+ CaseInsensitiveMap()
+ : super((key) => key.toLowerCase(), isValidKey: (key) => key != null);
+
+ CaseInsensitiveMap.from(Map<String, V> other)
+ : super.from(other, (key) => key.toLowerCase(),
+ isValidKey: (key) => key != null);
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index 9af4b45..06c3529 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: http_parser
-version: 1.0.0-dev
+version: 1.0.0
author: "Dart Team <misc@dartlang.org>"
homepage: https://github.com/dart-lang/http_parser
description: >
diff --git a/test/case_insensitive_map_test.dart b/test/case_insensitive_map_test.dart
new file mode 100644
index 0000000..9bfa00a
--- /dev/null
+++ b/test/case_insensitive_map_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:http_parser/http_parser.dart';
+import 'package:test/test.dart';
+
+void main() {
+ test("provides case-insensitive access to the map", () {
+ var map = new CaseInsensitiveMap();
+ map["fOo"] = "bAr";
+ expect(map, containsPair("FoO", "bAr"));
+
+ map["foo"] = "baz";
+ expect(map, containsPair("FOO", "baz"));
+ });
+
+ test("stores the original key cases", () {
+ var map = new CaseInsensitiveMap();
+ map["fOo"] = "bAr";
+ expect(map, equals({"fOo": "bAr"}));
+ });
+
+ test(".from() converts an existing map", () {
+ var map = new CaseInsensitiveMap.from({"fOo": "bAr"});
+ expect(map, containsPair("FoO", "bAr"));
+ expect(map, equals({"fOo": "bAr"}));
+ });
+}