fa28d5b912
Change-Id: I80cff0d2f864828386f1b8711810e960bbe00f3d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105729 Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
259 lines
7.6 KiB
Dart
259 lines
7.6 KiB
Dart
// 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 "package:crypto/crypto.dart";
|
|
import "package:expect/expect.dart";
|
|
import 'dart:async';
|
|
import 'dart:io';
|
|
import 'dart:isolate';
|
|
import 'dart:convert';
|
|
|
|
class Server {
|
|
HttpServer server;
|
|
bool passwordChanged = false;
|
|
|
|
Future<Server> start() {
|
|
var completer = new Completer<Server>();
|
|
HttpServer.bind("127.0.0.1", 0).then((s) {
|
|
server = s;
|
|
server.listen((HttpRequest request) {
|
|
var response = request.response;
|
|
if (request.uri.path == "/passwdchg") {
|
|
passwordChanged = true;
|
|
response.close();
|
|
return;
|
|
}
|
|
;
|
|
|
|
String username;
|
|
String password;
|
|
if (request.uri.path == "/") {
|
|
username = "username";
|
|
password = "password";
|
|
} else {
|
|
username = request.uri.path.substring(1, 6);
|
|
password = request.uri.path.substring(1, 6);
|
|
}
|
|
if (passwordChanged) password = "${password}1";
|
|
if (request.headers[HttpHeaders.authorizationHeader] != null) {
|
|
Expect.equals(
|
|
1, request.headers[HttpHeaders.authorizationHeader].length);
|
|
String authorization =
|
|
request.headers[HttpHeaders.authorizationHeader][0];
|
|
List<String> tokens = authorization.split(" ");
|
|
Expect.equals("Basic", tokens[0]);
|
|
String auth = base64.encode(utf8.encode("$username:$password"));
|
|
if (passwordChanged && auth != tokens[1]) {
|
|
response.statusCode = HttpStatus.unauthorized;
|
|
response.headers
|
|
.set(HttpHeaders.wwwAuthenticateHeader, "Basic, realm=realm");
|
|
} else {
|
|
Expect.equals(auth, tokens[1]);
|
|
}
|
|
} else {
|
|
response.statusCode = HttpStatus.unauthorized;
|
|
response.headers
|
|
.set(HttpHeaders.wwwAuthenticateHeader, "Basic, realm=realm");
|
|
}
|
|
response.close();
|
|
});
|
|
completer.complete(this);
|
|
});
|
|
return completer.future;
|
|
}
|
|
|
|
void shutdown() {
|
|
server.close();
|
|
}
|
|
|
|
int get port => server.port;
|
|
}
|
|
|
|
Future<Server> setupServer() {
|
|
return new Server().start();
|
|
}
|
|
|
|
void testUrlUserInfo() {
|
|
setupServer().then((server) {
|
|
HttpClient client = new HttpClient();
|
|
|
|
client
|
|
.getUrl(Uri.parse("http://username:password@127.0.0.1:${server.port}/"))
|
|
.then((request) => request.close())
|
|
.then((HttpClientResponse response) {
|
|
response.listen((_) {}, onDone: () {
|
|
server.shutdown();
|
|
client.close();
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
void testBasicNoCredentials() {
|
|
setupServer().then((server) {
|
|
HttpClient client = new HttpClient();
|
|
|
|
Future makeRequest(Uri url) {
|
|
return client
|
|
.getUrl(url)
|
|
.then((HttpClientRequest request) => request.close())
|
|
.then((HttpClientResponse response) {
|
|
Expect.equals(HttpStatus.unauthorized, 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}/test$i")));
|
|
futures.add(
|
|
makeRequest(Uri.parse("http://127.0.0.1:${server.port}/test$i/xxx")));
|
|
}
|
|
Future.wait(futures).then((_) {
|
|
server.shutdown();
|
|
client.close();
|
|
});
|
|
});
|
|
}
|
|
|
|
void testBasicCredentials() {
|
|
setupServer().then((server) {
|
|
HttpClient client = new HttpClient();
|
|
|
|
Future makeRequest(Uri url) {
|
|
return client
|
|
.getUrl(url)
|
|
.then((HttpClientRequest request) => request.close())
|
|
.then((HttpClientResponse response) {
|
|
Expect.equals(HttpStatus.ok, response.statusCode);
|
|
return response.fold(null, (x, y) {});
|
|
});
|
|
}
|
|
|
|
for (int i = 0; i < 5; i++) {
|
|
client.addCredentials(Uri.parse("http://127.0.0.1:${server.port}/test$i"),
|
|
"realm", new HttpClientBasicCredentials("test$i", "test$i"));
|
|
}
|
|
|
|
var futures = <Future>[];
|
|
for (int i = 0; i < 5; i++) {
|
|
futures.add(
|
|
makeRequest(Uri.parse("http://127.0.0.1:${server.port}/test$i")));
|
|
futures.add(
|
|
makeRequest(Uri.parse("http://127.0.0.1:${server.port}/test$i/xxx")));
|
|
}
|
|
Future.wait(futures).then((_) {
|
|
server.shutdown();
|
|
client.close();
|
|
});
|
|
});
|
|
}
|
|
|
|
void testBasicAuthenticateCallback() {
|
|
setupServer().then((server) {
|
|
HttpClient client = new HttpClient();
|
|
bool passwordChanged = false;
|
|
|
|
client.authenticate = (Uri url, String scheme, String realm) {
|
|
Expect.equals("Basic", scheme);
|
|
Expect.equals("realm", realm);
|
|
String username = url.path.substring(1, 6);
|
|
String password = url.path.substring(1, 6);
|
|
if (passwordChanged) password = "${password}1";
|
|
Completer completer = new Completer<bool>();
|
|
new Timer(const Duration(milliseconds: 10), () {
|
|
client.addCredentials(
|
|
url, realm, new HttpClientBasicCredentials(username, password));
|
|
completer.complete(true);
|
|
});
|
|
return completer.future;
|
|
};
|
|
|
|
Future makeRequest(Uri url) {
|
|
return client
|
|
.getUrl(url)
|
|
.then((HttpClientRequest request) => request.close())
|
|
.then((HttpClientResponse response) {
|
|
Expect.equals(HttpStatus.ok, response.statusCode);
|
|
return response.fold(null, (x, y) {});
|
|
});
|
|
}
|
|
|
|
List<Future> makeRequests() {
|
|
var futures = <Future>[];
|
|
for (int i = 0; i < 5; i++) {
|
|
futures.add(
|
|
makeRequest(Uri.parse("http://127.0.0.1:${server.port}/test$i")));
|
|
futures.add(makeRequest(
|
|
Uri.parse("http://127.0.0.1:${server.port}/test$i/xxx")));
|
|
}
|
|
return futures;
|
|
}
|
|
|
|
Future.wait(makeRequests()).then((_) {
|
|
makeRequest(Uri.parse("http://127.0.0.1:${server.port}/passwdchg"))
|
|
.then((_) {
|
|
passwordChanged = true;
|
|
Future.wait(makeRequests()).then((_) {
|
|
server.shutdown();
|
|
client.close();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
void testLocalServerBasic() {
|
|
HttpClient client = new HttpClient();
|
|
|
|
client.authenticate = (Uri url, String scheme, String realm) {
|
|
client.addCredentials(Uri.parse("http://127.0.0.1/basic"), "test",
|
|
new HttpClientBasicCredentials("test", "test"));
|
|
return new Future.value(true);
|
|
};
|
|
|
|
client
|
|
.getUrl(Uri.parse("http://127.0.0.1/basic/test"))
|
|
.then((HttpClientRequest request) => request.close())
|
|
.then((HttpClientResponse response) {
|
|
Expect.equals(HttpStatus.ok, response.statusCode);
|
|
response.fold(null, (x, y) {}).then((_) {
|
|
client.close();
|
|
});
|
|
});
|
|
}
|
|
|
|
void testLocalServerDigest() {
|
|
HttpClient client = new HttpClient();
|
|
|
|
client.authenticate = (Uri url, String scheme, String realm) {
|
|
print("url: $url, scheme: $scheme, realm: $realm");
|
|
client.addCredentials(Uri.parse("http://127.0.0.1/digest"), "test",
|
|
new HttpClientDigestCredentials("test", "test"));
|
|
return new Future.value(true);
|
|
};
|
|
|
|
client
|
|
.getUrl(Uri.parse("http://127.0.0.1/digest/test"))
|
|
.then((HttpClientRequest request) => request.close())
|
|
.then((HttpClientResponse response) {
|
|
Expect.equals(HttpStatus.ok, response.statusCode);
|
|
response.fold(null, (x, y) {}).then((_) {
|
|
client.close();
|
|
});
|
|
});
|
|
}
|
|
|
|
main() {
|
|
testUrlUserInfo();
|
|
testBasicNoCredentials();
|
|
testBasicCredentials();
|
|
testBasicAuthenticateCallback();
|
|
// These teste are not normally run. They can be used for locally
|
|
// testing with another web server (e.g. Apache).
|
|
//testLocalServerBasic();
|
|
//testLocalServerDigest();
|
|
}
|