blob: eda4ac24777ea5e1a7a4c848b3875df0b73472ef [file] [log] [blame]
// Copyright (c) 2021, 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.
// @dart = 2.9
import "dart:io";
import 'dart:convert';
import "package:expect/expect.dart";
import 'http_proxy_test.dart' show setupProxyServer;
import 'test_utils.dart' show withTempDir;
testDirectConnection() async {
var server = await HttpServer.bind(InternetAddress.anyIPv6, 0);
server.forEach((HttpRequest request) {
request.response.write('Hello, world!');
request.response.close();
});
final serverUri = Uri.http("127.0.0.1:${server.port}", "/");
var client = HttpClient()
..connectionFactory = (uri, proxyHost, proxyPort) {
Expect.isNull(proxyHost);
Expect.isNull(proxyPort);
Expect.equals(serverUri, uri);
return Socket.startConnect(uri.host, uri.port);
}
..findProxy = (uri) => 'DIRECT';
final response = await client.getUrl(serverUri).then((request) {
return request.close();
});
Expect.equals(200, response.statusCode);
final responseText = await response
.transform(utf8.decoder)
.fold('', (String x, String y) => x + y);
Expect.equals("Hello, world!", responseText);
client.close();
server.close();
}
testConnectionViaProxy() async {
var proxyServer = await setupProxyServer();
var server = await HttpServer.bind(InternetAddress.anyIPv6, 0);
server.forEach((HttpRequest request) {
request.response.write('Hello via Proxy');
request.response.close();
});
final serverUri = Uri.http("127.0.0.1:${server.port}", "/");
final client = HttpClient()
..connectionFactory = (uri, proxyHost, proxyPort) {
Expect.equals("localhost", proxyHost);
Expect.equals(proxyServer.port, proxyPort);
Expect.equals(serverUri, uri);
return Socket.startConnect(proxyHost, proxyPort as int);
}
..findProxy = (uri) => "PROXY localhost:${proxyServer.port}";
final response = await client.getUrl(serverUri).then((request) {
return request.close();
});
Expect.equals(200, response.statusCode);
final responseText = await response
.transform(utf8.decoder)
.fold('', (String x, String y) => x + y);
Expect.equals("Hello via Proxy", responseText);
client.close();
server.close();
proxyServer.shutdown();
}
testDifferentAddressFamiliesAndProxySettings(String dir) async {
// Test a custom connection factory for Unix domain sockets that also allows
// regular INET/INET6 access with and without a proxy.
var proxyServer = await setupProxyServer();
var inet6Server = await HttpServer.bind(InternetAddress.anyIPv6, 0);
inet6Server.forEach((HttpRequest request) {
request.response.write('Hello via Proxy');
request.response.close();
});
final inet6ServerUri = Uri.http("127.0.0.1:${inet6Server.port}", "/");
final unixPath = '$dir/sock';
final unixAddress = InternetAddress(unixPath, type: InternetAddressType.unix);
final unixServer = await HttpServer.bind(unixAddress, 0);
unixServer.forEach((HttpRequest request) {
request.response.write('Hello via Unix');
request.response.close();
});
final client = HttpClient()
..connectionFactory = (uri, proxyHost, proxyPort) {
if (uri.scheme == 'unix') {
assert(proxyHost == null);
assert(proxyPort == null);
var address = InternetAddress(unixPath, type: InternetAddressType.unix);
return Socket.startConnect(address, 0);
} else {
if (proxyHost != null && proxyPort != null) {
return Socket.startConnect(proxyHost, proxyPort);
}
return Socket.startConnect(uri.host, uri.port);
}
}
..findProxy = (uri) {
if (uri.scheme == 'unix') {
// Proxy settings are not meaningful for Unix domain sockets.
return 'DIRECT';
} else {
return "PROXY localhost:${proxyServer.port}";
}
};
// Fetch a URL from the INET6 server and verify the results.
final inet6Response = await client.getUrl(inet6ServerUri).then((request) {
return request.close();
});
Expect.equals(200, inet6Response.statusCode);
final inet6ResponseText = await inet6Response
.transform(utf8.decoder)
.fold('', (String x, String y) => x + y);
Expect.equals("Hello via Proxy", inet6ResponseText);
// Fetch a URL from the Unix server and verify the results.
final unixResponse = await client
.getUrl(Uri(
scheme: "unix",
// Connection pooling is based on the host/port combination
// so ensure that the host is unique for unique logical
// endpoints. Also, the `host` property is converted to
// lowercase so you cannot use it directly for file paths.
host: 'dummy',
path: "/"))
.then((request) {
return request.close();
});
Expect.equals(200, unixResponse.statusCode);
final unixResponseText = await unixResponse
.transform(utf8.decoder)
.fold('', (String x, String y) => x + y);
Expect.equals("Hello via Unix", unixResponseText);
client.close();
inet6Server.close();
unixServer.close();
proxyServer.shutdown();
}
main() async {
await testDirectConnection();
await testConnectionViaProxy();
if (Platform.isMacOS || Platform.isLinux || Platform.isAndroid) {
await withTempDir('unix_socket_test', (Directory dir) async {
await testDifferentAddressFamiliesAndProxySettings('${dir.path}');
});
}
}