Migrate more tests (#12)
diff --git a/lib/src/http_impl.dart b/lib/src/http_impl.dart
index e9760d4..ba24cc7 100644
--- a/lib/src/http_impl.dart
+++ b/lib/src/http_impl.dart
@@ -1634,7 +1634,7 @@
// If the proxy configuration contains user information use that
// for proxy basic authorization.
String auth = _CryptoUtils
- .bytesToBase64(utf8.encode("${proxy.username}:${proxy.password}"));
+ .bytesToBase64(UTF8.encode("${proxy.username}:${proxy.password}"));
request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic $auth");
} else if (!proxy.isDirect && _httpClient._proxyCredentials.isNotEmpty) {
proxyCreds = _httpClient._findProxyCredentials(proxy);
@@ -1645,7 +1645,7 @@
if (uri.userInfo != null && uri.userInfo.isNotEmpty) {
// If the URL contains user information use that for basic
// authorization.
- String auth = _CryptoUtils.bytesToBase64(utf8.encode(uri.userInfo));
+ String auth = _CryptoUtils.bytesToBase64(UTF8.encode(uri.userInfo));
request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth");
} else {
// Look for credentials.
@@ -1756,7 +1756,7 @@
// If the proxy configuration contains user information use that
// for proxy basic authorization.
String auth = _CryptoUtils
- .bytesToBase64(utf8.encode("${proxy.username}:${proxy.password}"));
+ .bytesToBase64(UTF8.encode("${proxy.username}:${proxy.password}"));
request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic $auth");
}
return request.close().then((response) {
@@ -2831,11 +2831,11 @@
// now always use UTF-8 encoding.
_HttpClientDigestCredentials creds = credentials;
var hasher = new _MD5()
- ..add(utf8.encode(creds.username))
+ ..add(UTF8.encode(creds.username))
..add([_CharCode.COLON])
..add(realm.codeUnits)
..add([_CharCode.COLON])
- ..add(utf8.encode(creds.password));
+ ..add(UTF8.encode(creds.password));
ha1 = _CryptoUtils.bytesToHex(hasher.close());
}
}
@@ -2918,7 +2918,7 @@
// http://tools.ietf.org/html/draft-reschke-basicauth-enc-06. For
// now always use UTF-8 encoding.
String auth =
- _CryptoUtils.bytesToBase64(utf8.encode("$username:$password"));
+ _CryptoUtils.bytesToBase64(UTF8.encode("$username:$password"));
return "Basic $auth";
}
diff --git a/pubspec.yaml b/pubspec.yaml
index 4a71c68..8e40eb7 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -4,6 +4,8 @@
homepage: https://github.com/dart-lang/http_io
description: HTTP Client and Server APIs.
dev_dependencies:
+ convert: "^2.0.1"
+ crypto: "^2.0.2+1"
test: "^0.12.18"
environment:
sdk: ">=1.24.0 <3.0.0"
diff --git a/test/http_100_continue_test.dart b/test/http_100_continue_test.dart
new file mode 100644
index 0000000..9b284c6
--- /dev/null
+++ b/test/http_100_continue_test.dart
@@ -0,0 +1,80 @@
+// 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 'dart:async';
+import 'dart:convert';
+import "dart:io" hide HttpServer, HttpClient;
+
+import "package:http_io/http_io.dart";
+import "package:test/test.dart";
+
+Future<Null> doTest(responseBytes, bodyLength) async {
+ fullRequest(bytes) {
+ var len = bytes.length;
+ return len > 4 &&
+ bytes[len - 4] == 13 &&
+ bytes[len - 3] == 10 &&
+ bytes[len - 2] == 13 &&
+ bytes[len - 1] == 10;
+ }
+
+ handleSocket(socket) async {
+ var bytes = [];
+ await for (var data in socket) {
+ bytes.addAll(data);
+ if (fullRequest(bytes)) {
+ socket.add(responseBytes);
+ socket.close();
+ }
+ }
+ }
+
+ var server = await ServerSocket.bind('127.0.0.1', 0);
+ server.listen(handleSocket);
+
+ var client = new HttpClient();
+ var request =
+ await client.getUrl(Uri.parse('http://127.0.0.1:${server.port}/'));
+ var response = await request.close();
+ expect(response.statusCode, equals(200));
+ expect(bodyLength,
+ equals((await response.fold([], (p, e) => p..addAll(e))).length));
+ await server.close();
+}
+
+main() {
+ var r1 = '''
+HTTP/1.1 100 Continue\r
+\r
+HTTP/1.1 200 OK\r
+\r
+''';
+
+ var r2 = '''
+HTTP/1.1 100 Continue\r
+My-Header-1: hello\r
+My-Header-2: world\r
+\r
+HTTP/1.1 200 OK\r
+\r
+''';
+
+ var r3 = '''
+HTTP/1.1 100 Continue\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 2\r
+\r
+AB''';
+
+ test("Continue OK", () async {
+ await doTest(ASCII.encode(r1), 0);
+ });
+ test("Continue hello world OK", () async {
+ await doTest(ASCII.encode(r2), 0);
+ });
+ test("Continue OK length AB", () async {
+ await doTest(ASCII.encode(r3), 2);
+ });
+}
diff --git a/test/http_10_test.dart b/test/http_10_test.dart
new file mode 100644
index 0000000..c2a19ba
--- /dev/null
+++ b/test/http_10_test.dart
@@ -0,0 +1,228 @@
+// (c) 2013, 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 'dart:async';
+import "dart:io" hide HttpServer, HttpClient, HttpRequest, HttpException;
+
+import "package:http_io/http_io.dart";
+import "package:test/test.dart";
+
+// Client makes a HTTP 1.0 request without connection keep alive. The
+// server sets a content length but still needs to close the
+// connection as there is no keep alive.
+Future<Null> testHttp10NoKeepAlive() {
+ Completer<Null> completer = new Completer();
+ HttpServer.bind("127.0.0.1", 0).then((server) {
+ server.listen((HttpRequest request) {
+ expect(request.headers.value('content-length'), isNull);
+ expect(-1, equals(request.contentLength));
+ var response = request.response;
+ response.contentLength = 1;
+ expect("1.0", equals(request.protocolVersion));
+ response.done
+ .then((_) => fail("Unexpected response completion"))
+ .catchError((error) => expect((error is HttpException), isTrue));
+ response.write("Z");
+ response.write("Z");
+ response.close();
+ }, onError: (e, trace) {
+ String msg = "Unexpected error $e";
+ if (trace != null) msg += "\nStackTrace: $trace";
+ fail(msg);
+ });
+
+ int count = 0;
+ makeRequest() {
+ Socket.connect("127.0.0.1", server.port).then((socket) {
+ socket.write("GET / HTTP/1.0\r\n\r\n");
+
+ List<int> response = [];
+ socket.listen(response.addAll, onDone: () {
+ count++;
+ socket.destroy();
+ String s = new String.fromCharCodes(response).toLowerCase();
+ expect(-1, equals(s.indexOf("keep-alive")));
+ if (count < 10) {
+ makeRequest();
+ } else {
+ server.close();
+ completer.complete(null);
+ }
+ });
+ });
+ }
+
+ makeRequest();
+ });
+ return completer.future;
+}
+
+// Client makes a HTTP 1.0 request and the server does not set a
+// content length so it has to close the connection to mark the end of
+// the response.
+Future<Null> testHttp10ServerClose() {
+ Completer<Null> completer = new Completer();
+ HttpServer.bind("127.0.0.1", 0).then((server) {
+ server.listen((HttpRequest request) {
+ expect(request.headers.value('content-length'), isNull);
+ expect(-1, equals(request.contentLength));
+ request.listen((_) {}, onDone: () {
+ var response = request.response;
+ expect("1.0", equals(request.protocolVersion));
+ response.write("Z");
+ response.close();
+ });
+ }, onError: (e, trace) {
+ String msg = "Unexpected error $e";
+ if (trace != null) msg += "\nStackTrace: $trace";
+ fail(msg);
+ });
+
+ int count = 0;
+ makeRequest() {
+ Socket.connect("127.0.0.1", server.port).then((socket) {
+ socket.write("GET / HTTP/1.0\r\n");
+ socket.write("Connection: Keep-Alive\r\n\r\n");
+
+ List<int> response = [];
+ socket.listen(response.addAll,
+ onDone: () {
+ socket.destroy();
+ count++;
+ String s = new String.fromCharCodes(response).toLowerCase();
+ expect("z", equals(s[s.length - 1]));
+ expect(-1, equals(s.indexOf("content-length:")));
+ expect(-1, equals(s.indexOf("keep-alive")));
+ if (count < 10) {
+ makeRequest();
+ } else {
+ server.close();
+ completer.complete(null);
+ }
+ },
+ onError: (e) => print(e));
+ });
+ }
+
+ makeRequest();
+ });
+ return completer.future;
+}
+
+// Client makes a HTTP 1.0 request with connection keep alive. The
+// server sets a content length so the persistent connection can be
+// used.
+Future<Null> testHttp10KeepAlive() {
+ Completer<Null> completer = new Completer();
+ HttpServer.bind("127.0.0.1", 0).then((server) {
+ server.listen((HttpRequest request) {
+ expect(request.headers.value('content-length'), isNull);
+ expect(-1, equals(request.contentLength));
+ var response = request.response;
+ response.contentLength = 1;
+ response.persistentConnection = true;
+ expect("1.0", equals(request.protocolVersion));
+ response.write("Z");
+ response.close();
+ }, onError: (e, trace) {
+ String msg = "Unexpected error $e";
+ if (trace != null) msg += "\nStackTrace: $trace";
+ fail(msg);
+ });
+
+ Socket.connect("127.0.0.1", server.port).then((socket) {
+ void sendRequest() {
+ socket.write("GET / HTTP/1.0\r\n");
+ socket.write("Connection: Keep-Alive\r\n\r\n");
+ }
+
+ List<int> response = [];
+ int count = 0;
+ socket.listen((d) {
+ response.addAll(d);
+ if (response[response.length - 1] == "Z".codeUnitAt(0)) {
+ String s = new String.fromCharCodes(response).toLowerCase();
+ expect(s.indexOf("\r\nconnection: keep-alive\r\n") > 0, isTrue);
+ expect(s.indexOf("\r\ncontent-length: 1\r\n") > 0, isTrue);
+ count++;
+ if (count < 10) {
+ response = [];
+ sendRequest();
+ } else {
+ socket.close();
+ }
+ }
+ }, onDone: () {
+ socket.destroy();
+ server.close();
+ completer.complete(null);
+ });
+ sendRequest();
+ });
+ });
+ return completer.future;
+}
+
+// Client makes a HTTP 1.0 request with connection keep alive. The
+// server does not set a content length so it cannot honor connection
+// keep alive.
+Future<Null> testHttp10KeepAliveServerCloses() {
+ Completer<Null> completer = new Completer();
+ HttpServer.bind("127.0.0.1", 0).then((server) {
+ server.listen((HttpRequest request) {
+ expect(request.headers.value('content-length'), isNull);
+ expect(-1, equals(request.contentLength));
+ var response = request.response;
+ expect("1.0", equals(request.protocolVersion));
+ response.write("Z");
+ response.close();
+ }, onError: (e, trace) {
+ String msg = "Unexpected error $e";
+ if (trace != null) msg += "\nStackTrace: $trace";
+ fail(msg);
+ });
+
+ int count = 0;
+ makeRequest() {
+ Socket.connect("127.0.0.1", server.port).then((socket) {
+ socket.write("GET / HTTP/1.0\r\n");
+ socket.write("Connection: Keep-Alive\r\n\r\n");
+
+ List<int> response = [];
+ socket.listen(response.addAll, onDone: () {
+ socket.destroy();
+ count++;
+ String s = new String.fromCharCodes(response).toLowerCase();
+ expect("z", equals(s[s.length - 1]));
+ expect(-1, equals(s.indexOf("content-length")));
+ expect(-1, equals(s.indexOf("connection")));
+ if (count < 10) {
+ makeRequest();
+ } else {
+ server.close();
+ completer.complete(null);
+ }
+ });
+ });
+ }
+
+ makeRequest();
+ });
+ return completer.future;
+}
+
+void main() {
+ test("Http10NoKeepAlive", () async {
+ await testHttp10NoKeepAlive();
+ });
+ test("Http10ServerClose", () async {
+ await testHttp10ServerClose();
+ });
+ test("Http10KeepAlive", () async {
+ await testHttp10KeepAlive();
+ });
+ test("Http10KeepAliveServerCloses", () async {
+ await testHttp10KeepAliveServerCloses();
+ });
+}
diff --git a/test/http_auth_digest_test.dart b/test/http_auth_digest_test.dart
new file mode 100644
index 0000000..5101744
--- /dev/null
+++ b/test/http_auth_digest_test.dart
@@ -0,0 +1,365 @@
+// Copyright (c) 2013, 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 'dart:async';
+
+import "package:convert/convert.dart";
+import "package:crypto/crypto.dart";
+import "package:http_io/http_io.dart";
+import "package:test/test.dart";
+
+class Server {
+ HttpServer server;
+ int unauthCount = 0; // Counter of the 401 responses.
+ int successCount = 0; // Counter of the successful responses.
+ int nonceCount = 0; // Counter of use of current nonce.
+ String ha1;
+
+ static Future<Server> start(String algorithm, String qop,
+ {int nonceStaleAfter, bool useNextNonce: false}) {
+ return new Server()._start(algorithm, qop, nonceStaleAfter, useNextNonce);
+ }
+
+ Future<Server> _start(String serverAlgorithm, String serverQop,
+ int nonceStaleAfter, bool useNextNonce) {
+ Set ncs = new Set();
+ // Calculate ha1.
+ String realm = "test";
+ String username = "dart";
+ String password = "password";
+ var hasher = md5.convert("$username:$realm:$password".codeUnits);
+ ha1 = hex.encode(hasher.bytes);
+
+ var nonce = "12345678"; // No need for random nonce in test.
+
+ var completer = new Completer<Server>();
+ HttpServer.bind("127.0.0.1", 0).then((s) {
+ server = s;
+ server.listen((HttpRequest request) {
+ sendUnauthorizedResponse(HttpResponse response, {stale: false}) {
+ response.statusCode = HttpStatus.UNAUTHORIZED;
+ StringBuffer authHeader = new StringBuffer();
+ authHeader.write('Digest');
+ authHeader.write(', realm="$realm"');
+ authHeader.write(', nonce="$nonce"');
+ if (stale) authHeader.write(', stale="true"');
+ if (serverAlgorithm != null) {
+ authHeader.write(', algorithm=$serverAlgorithm');
+ }
+ authHeader.write(', domain="/digest/"');
+ if (serverQop != null) authHeader.write(', qop="$serverQop"');
+ response.headers.set(HttpHeaders.WWW_AUTHENTICATE, authHeader);
+ unauthCount++;
+ }
+
+ var response = request.response;
+ if (request.headers[HttpHeaders.AUTHORIZATION] != null) {
+ expect(1, equals(request.headers[HttpHeaders.AUTHORIZATION].length));
+ String authorization = request.headers[HttpHeaders.AUTHORIZATION][0];
+ HeaderValue header =
+ HeaderValue.parse(authorization, parameterSeparator: ",");
+ if (header.value.toLowerCase() == "basic") {
+ sendUnauthorizedResponse(response);
+ } else if (!useNextNonce && nonceCount == nonceStaleAfter) {
+ nonce = "87654321";
+ nonceCount = 0;
+ sendUnauthorizedResponse(response, stale: true);
+ } else {
+ var uri = header.parameters["uri"];
+ var qop = header.parameters["qop"];
+ var cnonce = header.parameters["cnonce"];
+ var nc = header.parameters["nc"];
+ expect("digest", equals(header.value.toLowerCase()));
+ expect("dart", equals(header.parameters["username"]));
+ expect(realm, equals(header.parameters["realm"]));
+ expect("MD5", equals(header.parameters["algorithm"]));
+ expect(nonce, equals(header.parameters["nonce"]));
+ expect(request.uri.toString(), equals(uri));
+ if (qop != null) {
+ // A server qop of auth-int is downgraded to none by the client.
+ expect("auth", equals(serverQop));
+ expect("auth", equals(header.parameters["qop"]));
+ expect(cnonce, isNotNull);
+ expect(nc, isNotNull);
+ expect(ncs.contains(nc), isFalse);
+ ncs.add(nc);
+ } else {
+ expect(cnonce, isNull);
+ expect(nc, isNull);
+ }
+ expect(header.parameters["response"], isNotNull);
+
+ var hasher = md5.convert("${request.method}:$uri".codeUnits);
+ var ha2 = hex.encode(hasher.bytes);
+
+ Digest digest;
+ if (qop == null || qop == "" || qop == "none") {
+ digest = md5.convert("$ha1:$nonce:$ha2".codeUnits);
+ } else {
+ digest =
+ md5.convert("$ha1:$nonce:$nc:$cnonce:$qop:$ha2".codeUnits);
+ }
+ expect(hex.encode(digest.bytes),
+ equals(header.parameters["response"]));
+
+ successCount++;
+ nonceCount++;
+
+ // Add a bogus Authentication-Info for testing.
+ var info = 'rspauth="77180d1ab3d6c9de084766977790f482", '
+ 'cnonce="8f971178", '
+ 'nc=000002c74, '
+ 'qop=auth';
+ if (useNextNonce && nonceCount == nonceStaleAfter) {
+ nonce = "abcdef01";
+ info += ', nextnonce="$nonce"';
+ }
+ response.headers.set("Authentication-Info", info);
+ }
+ } else {
+ sendUnauthorizedResponse(response);
+ }
+ response.close();
+ });
+ completer.complete(this);
+ });
+ return completer.future;
+ }
+
+ void shutdown() {
+ server.close();
+ }
+
+ int get port => server.port;
+}
+
+Future<Null> testNoCredentials(String algorithm, String qop) {
+ Completer<Null> completer = new Completer();
+ Server.start(algorithm, qop).then((server) {
+ HttpClient client = new HttpClient();
+
+ // Add digest credentials which does not match the path requested.
+ client.addCredentials(Uri.parse("http://127.0.0.1:${server.port}/xxx"),
+ "test", new HttpClientDigestCredentials("dart", "password"));
+
+ // Add basic credentials for the path requested.
+ client.addCredentials(Uri.parse("http://127.0.0.1:${server.port}/digest"),
+ "test", new HttpClientBasicCredentials("dart", "password"));
+
+ Future makeRequest(Uri url) {
+ return client
+ .getUrl(url)
+ .then((HttpClientRequest request) => request.close())
+ .then((HttpClientResponse response) {
+ expect(HttpStatus.UNAUTHORIZED, equals(response.statusCode));
+ return response.fold(null, (x, y) {});
+ });
+ }
+
+ var futures = <Future>[];
+ for (int i = 0; i < 5; i++) {
+ futures.add(
+ makeRequest(Uri.parse("http://127.0.0.1:${server.port}/digest")));
+ }
+ Future.wait(futures).then((_) {
+ server.shutdown();
+ client.close();
+ completer.complete(null);
+ });
+ });
+ return completer.future;
+}
+
+Future<Null> testCredentials(String algorithm, String qop) {
+ Completer<Null> completer = new Completer();
+ Server.start(algorithm, qop).then((server) {
+ HttpClient client = new HttpClient();
+
+ Future makeRequest(Uri url) {
+ return client
+ .getUrl(url)
+ .then((HttpClientRequest request) => request.close())
+ .then((HttpClientResponse response) {
+ expect(HttpStatus.OK, equals(response.statusCode));
+ expect(1, equals(response.headers["Authentication-Info"].length));
+ return response.fold(null, (x, y) {});
+ });
+ }
+
+ client.addCredentials(Uri.parse("http://127.0.0.1:${server.port}/digest"),
+ "test", new HttpClientDigestCredentials("dart", "password"));
+
+ var futures = <Future>[];
+ for (int i = 0; i < 2; i++) {
+ String uriBase = "http://127.0.0.1:${server.port}/digest";
+ futures.add(makeRequest(Uri.parse(uriBase)));
+ futures.add(makeRequest(Uri.parse("$uriBase?querystring")));
+ futures.add(makeRequest(Uri.parse("$uriBase?querystring#fragment")));
+ }
+ Future.wait(futures).then((_) {
+ server.shutdown();
+ client.close();
+ completer.complete(null);
+ });
+ });
+ return completer.future;
+}
+
+Future<Null> testAuthenticateCallback(String algorithm, String qop) {
+ Completer<Null> completer = new Completer();
+ Server.start(algorithm, qop).then((server) {
+ HttpClient client = new HttpClient();
+
+ client.authenticate = (Uri url, String scheme, String realm) {
+ expect("Digest", equals(scheme));
+ expect("test", equals(realm));
+ Completer completer = new Completer();
+ new Timer(const Duration(milliseconds: 10), () {
+ client.addCredentials(
+ Uri.parse("http://127.0.0.1:${server.port}/digest"),
+ "test",
+ new HttpClientDigestCredentials("dart", "password"));
+ completer.complete(true);
+ });
+ return completer.future;
+ };
+
+ Future makeRequest(Uri url) {
+ return client
+ .getUrl(url)
+ .then((HttpClientRequest request) => request.close())
+ .then((HttpClientResponse response) {
+ expect(HttpStatus.OK, equals(response.statusCode));
+ expect(1, equals(response.headers["Authentication-Info"].length));
+ return response.fold(null, (x, y) {});
+ });
+ }
+
+ var futures = <Future>[];
+ for (int i = 0; i < 5; i++) {
+ futures.add(
+ makeRequest(Uri.parse("http://127.0.0.1:${server.port}/digest")));
+ }
+ Future.wait(futures).then((_) {
+ server.shutdown();
+ client.close();
+ completer.complete(null);
+ });
+ });
+ return completer.future;
+}
+
+Future<Null> testStaleNonce() {
+ Completer<Null> completer = new Completer();
+ Server.start("MD5", "auth", nonceStaleAfter: 2).then((server) {
+ HttpClient client = new HttpClient();
+
+ Future makeRequest(Uri url) {
+ return client
+ .getUrl(url)
+ .then((HttpClientRequest request) => request.close())
+ .then((HttpClientResponse response) {
+ expect(HttpStatus.OK, equals(response.statusCode));
+ expect(1, equals(response.headers["Authentication-Info"].length));
+ return response.fold(null, (x, y) {});
+ });
+ }
+
+ Uri uri = Uri.parse("http://127.0.0.1:${server.port}/digest");
+ var credentials = new HttpClientDigestCredentials("dart", "password");
+ client.addCredentials(uri, "test", credentials);
+
+ makeRequest(uri)
+ .then((_) => makeRequest(uri))
+ .then((_) => makeRequest(uri))
+ .then((_) => makeRequest(uri))
+ .then((_) {
+ expect(2, equals(server.unauthCount));
+ expect(4, equals(server.successCount));
+ server.shutdown();
+ client.close();
+ completer.complete(null);
+ });
+ });
+ return completer.future;
+}
+
+Future<Null> testNextNonce() {
+ Completer<Null> completer = new Completer();
+ Server
+ .start("MD5", "auth", nonceStaleAfter: 2, useNextNonce: true)
+ .then((server) {
+ HttpClient client = new HttpClient();
+
+ Future makeRequest(Uri url) {
+ return client
+ .getUrl(url)
+ .then((HttpClientRequest request) => request.close())
+ .then((HttpClientResponse response) {
+ expect(HttpStatus.OK, equals(response.statusCode));
+ expect(1, equals(response.headers["Authentication-Info"].length));
+ return response.fold(null, (x, y) {});
+ });
+ }
+
+ Uri uri = Uri.parse("http://127.0.0.1:${server.port}/digest");
+ var credentials = new HttpClientDigestCredentials("dart", "password");
+ client.addCredentials(uri, "test", credentials);
+
+ makeRequest(uri)
+ .then((_) => makeRequest(uri))
+ .then((_) => makeRequest(uri))
+ .then((_) => makeRequest(uri))
+ .then((_) {
+ expect(1, equals(server.unauthCount));
+ expect(4, equals(server.successCount));
+ server.shutdown();
+ client.close();
+ completer.complete(null);
+ });
+ });
+ return completer.future;
+}
+
+main() {
+ test("NoCredentials", () async {
+ await testNoCredentials(null, null);
+ });
+ test("NoCredentials MD5", () async {
+ await testNoCredentials("MD5", null);
+ });
+ test("NoCredentials MD5 auth", () async {
+ await testNoCredentials("MD5", "auth");
+ });
+ test("Credentials", () async {
+ await testCredentials(null, null);
+ });
+ test("Credentials MD5", () async {
+ await testCredentials("MD5", null);
+ });
+ test("Credentials MD5 auth", () async {
+ await testCredentials("MD5", "auth");
+ });
+ test("Credentials MD5 auth-int", () async {
+ await testCredentials("MD5", "auth-int");
+ });
+ test("AuthenticateCallback", () async {
+ await testAuthenticateCallback(null, null);
+ });
+ test("AuthenticateCallback MD5", () async {
+ await testAuthenticateCallback("MD5", null);
+ });
+ test("AuthenticateCallback MD5 auth", () async {
+ await testAuthenticateCallback("MD5", "auth");
+ });
+ test("AuthenticateCallback MD5 auth-int", () async {
+ await testAuthenticateCallback("MD5", "auth-int");
+ });
+ test("StaleNonce", () async {
+ await testStaleNonce();
+ });
+ test("NextNonce", () async {
+ await testNextNonce();
+ });
+}