Format tests/standalone/ using 3.8 style.
Change-Id: I4d492a63a41880ef8cd69321372a4853825b9efd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426321 Reviewed-by: Liam Appelbe <liama@google.com> Auto-Submit: Bob Nystrom <rnystrom@google.com> Commit-Queue: Liam Appelbe <liama@google.com>
This commit is contained in:
committed by
Commit Queue
parent
81ab0dab3c
commit
a323c55162
@@ -13,69 +13,71 @@ main() {
|
||||
final buildDir = path.dirname(Platform.executable);
|
||||
final sdkDir = path.dirname(path.dirname(buildDir));
|
||||
final platformDill = path.join(buildDir, 'vm_platform_strong.dill');
|
||||
final genKernel =
|
||||
path.join(sdkDir, 'pkg', 'vm', 'tool', 'gen_kernel$_batchSuffix');
|
||||
Expect.isTrue(File(genKernel).existsSync(),
|
||||
"Can't locate gen_kernel$_batchSuffix on this platform");
|
||||
Expect.isTrue(File(genKernel).existsSync(),
|
||||
"Can't locate gen_kernel$_batchSuffix on this platform");
|
||||
final genKernel = path.join(
|
||||
sdkDir,
|
||||
'pkg',
|
||||
'vm',
|
||||
'tool',
|
||||
'gen_kernel$_batchSuffix',
|
||||
);
|
||||
Expect.isTrue(
|
||||
File(genKernel).existsSync(),
|
||||
"Can't locate gen_kernel$_batchSuffix on this platform",
|
||||
);
|
||||
Expect.isTrue(
|
||||
File(genKernel).existsSync(),
|
||||
"Can't locate gen_kernel$_batchSuffix on this platform",
|
||||
);
|
||||
final genSnapshot = path.join(buildDir, 'gen_snapshot$_execSuffix');
|
||||
Expect.isTrue(File(genSnapshot).existsSync(),
|
||||
"Can't locate gen_snapshot$_execSuffix on this platform");
|
||||
Expect.isTrue(
|
||||
File(genSnapshot).existsSync(),
|
||||
"Can't locate gen_snapshot$_execSuffix on this platform",
|
||||
);
|
||||
|
||||
final exePath = path.join(buildDir, 'dart$_execSuffix');
|
||||
Expect.isTrue(File(exePath).existsSync(),
|
||||
"Can't locate dart$_execSuffix on this platform");
|
||||
Expect.isTrue(
|
||||
File(exePath).existsSync(),
|
||||
"Can't locate dart$_execSuffix on this platform",
|
||||
);
|
||||
final powTest = path.join(sdkDir, 'tests', 'standalone', 'pow_test.dart');
|
||||
Expect.isTrue(File(powTest).existsSync(),
|
||||
"Can't locate dart$_execSuffix on this platform");
|
||||
Expect.isTrue(
|
||||
File(powTest).existsSync(),
|
||||
"Can't locate dart$_execSuffix on this platform",
|
||||
);
|
||||
final d = Directory.systemTemp.createTempSync('aot_tmp');
|
||||
final kernelOutput = File.fromUri(d.uri.resolve('pow_test.dill')).path;
|
||||
final aotOutput = File.fromUri(d.uri.resolve('pow_test.aot')).path;
|
||||
|
||||
final genKernelResult = runAndPrintOutput(
|
||||
genKernel,
|
||||
[
|
||||
'--aot',
|
||||
'--platform=$platformDill',
|
||||
'-o',
|
||||
kernelOutput,
|
||||
powTest,
|
||||
],
|
||||
);
|
||||
final genKernelResult = runAndPrintOutput(genKernel, [
|
||||
'--aot',
|
||||
'--platform=$platformDill',
|
||||
'-o',
|
||||
kernelOutput,
|
||||
powTest,
|
||||
]);
|
||||
Expect.equals(genKernelResult.exitCode, 0);
|
||||
print("Ran successfully.\n");
|
||||
|
||||
final genAotResult = runAndPrintOutput(
|
||||
genSnapshot,
|
||||
[
|
||||
'--snapshot_kind=app-aot-elf',
|
||||
'--elf=$aotOutput',
|
||||
kernelOutput,
|
||||
],
|
||||
);
|
||||
final genAotResult = runAndPrintOutput(genSnapshot, [
|
||||
'--snapshot_kind=app-aot-elf',
|
||||
'--elf=$aotOutput',
|
||||
kernelOutput,
|
||||
]);
|
||||
Expect.equals(genAotResult.exitCode, 0);
|
||||
print("Ran successfully.\n");
|
||||
|
||||
final runAotDirectlyResult = runAndPrintOutput(
|
||||
exePath,
|
||||
[
|
||||
aotOutput,
|
||||
],
|
||||
);
|
||||
final runAotDirectlyResult = runAndPrintOutput(exePath, [aotOutput]);
|
||||
Expect.equals(runAotDirectlyResult.exitCode, 255);
|
||||
Expect.contains(
|
||||
"pow_test.aot is an AOT snapshot and should be run with 'dartaotruntime'",
|
||||
runAotDirectlyResult.stderr);
|
||||
"pow_test.aot is an AOT snapshot and should be run with 'dartaotruntime'",
|
||||
runAotDirectlyResult.stderr,
|
||||
);
|
||||
print('Got expected error result.');
|
||||
|
||||
final runAotUsingCommandResult = runAndPrintOutput(
|
||||
exePath,
|
||||
[
|
||||
'run',
|
||||
aotOutput,
|
||||
],
|
||||
);
|
||||
final runAotUsingCommandResult = runAndPrintOutput(exePath, [
|
||||
'run',
|
||||
aotOutput,
|
||||
]);
|
||||
Expect.equals(runAotUsingCommandResult.exitCode, 255);
|
||||
Expect.containsAny(<String>[
|
||||
"pow_test.aot is an AOT snapshot and should be run with 'dartaotruntime'",
|
||||
|
||||
@@ -22,7 +22,7 @@ const int LINE_E = 57;
|
||||
bar() {
|
||||
// Keep the 'throw' and its argument on separate lines.
|
||||
throw // force linebreak with dart format // LINE_A
|
||||
"Hello, Dwarf!";
|
||||
"Hello, Dwarf!";
|
||||
}
|
||||
|
||||
@pragma("vm:never-inline")
|
||||
@@ -67,12 +67,18 @@ Future<void> main() async {
|
||||
return; // Generated dwarf.so not available on the test device.
|
||||
}
|
||||
|
||||
final dwarf = Dwarf.fromFile(path.join(
|
||||
final dwarf = Dwarf.fromFile(
|
||||
path.join(
|
||||
Platform.environment["TEST_COMPILATION_DIR"]!,
|
||||
"dwarf_invisible_functions.so"))!;
|
||||
"dwarf_invisible_functions.so",
|
||||
),
|
||||
)!;
|
||||
|
||||
await dwarf_stack_trace_test.checkStackTrace(
|
||||
rawStack, dwarf, expectedCallsInfo);
|
||||
rawStack,
|
||||
dwarf,
|
||||
expectedCallsInfo,
|
||||
);
|
||||
}
|
||||
|
||||
final expectedCallsInfo = <List<DartCallInfo>>[
|
||||
@@ -80,44 +86,49 @@ final expectedCallsInfo = <List<DartCallInfo>>[
|
||||
// into foo (so we'll get information for two calls for that PC address).
|
||||
[
|
||||
DartCallInfo(
|
||||
function: "bar",
|
||||
filename: "dwarf_stack_trace_invisible_functions_test.dart",
|
||||
line: LINE_A,
|
||||
column: 3,
|
||||
inlined: true),
|
||||
function: "bar",
|
||||
filename: "dwarf_stack_trace_invisible_functions_test.dart",
|
||||
line: LINE_A,
|
||||
column: 3,
|
||||
inlined: true,
|
||||
),
|
||||
DartCallInfo(
|
||||
function: "foo",
|
||||
filename: "dwarf_stack_trace_invisible_functions_test.dart",
|
||||
line: LINE_B,
|
||||
column: 3,
|
||||
inlined: false)
|
||||
function: "foo",
|
||||
filename: "dwarf_stack_trace_invisible_functions_test.dart",
|
||||
line: LINE_B,
|
||||
column: 3,
|
||||
inlined: false,
|
||||
),
|
||||
],
|
||||
// Frame 2: call to foo in bazz.
|
||||
[
|
||||
DartCallInfo(
|
||||
function: "bazz",
|
||||
filename: "dwarf_stack_trace_invisible_functions_test.dart",
|
||||
line: LINE_C,
|
||||
column: 3,
|
||||
inlined: false)
|
||||
function: "bazz",
|
||||
filename: "dwarf_stack_trace_invisible_functions_test.dart",
|
||||
line: LINE_C,
|
||||
column: 3,
|
||||
inlined: false,
|
||||
),
|
||||
],
|
||||
// Frame 3: call to bazz in A.method.
|
||||
[
|
||||
DartCallInfo(
|
||||
function: "A.add",
|
||||
filename: "dwarf_stack_trace_invisible_functions_test.dart",
|
||||
line: LINE_D,
|
||||
column: 5,
|
||||
inlined: false)
|
||||
function: "A.add",
|
||||
filename: "dwarf_stack_trace_invisible_functions_test.dart",
|
||||
line: LINE_D,
|
||||
column: 5,
|
||||
inlined: false,
|
||||
),
|
||||
],
|
||||
// Frame 4: the call to foo in main.
|
||||
[
|
||||
DartCallInfo(
|
||||
function: "main",
|
||||
filename: "dwarf_stack_trace_invisible_functions_test.dart",
|
||||
line: LINE_E,
|
||||
column: 8,
|
||||
inlined: false)
|
||||
function: "main",
|
||||
filename: "dwarf_stack_trace_invisible_functions_test.dart",
|
||||
line: LINE_E,
|
||||
column: 8,
|
||||
inlined: false,
|
||||
),
|
||||
],
|
||||
// Don't assume anything about any of the frames below the main,
|
||||
// as this makes the test too brittle.
|
||||
|
||||
@@ -16,7 +16,7 @@ import 'dwarf_stack_trace_test.dart' as base;
|
||||
bar() {
|
||||
// Keep the 'throw' and its argument on separate lines.
|
||||
throw // force linebreak with dart format
|
||||
"Hello, Dwarf!";
|
||||
"Hello, Dwarf!";
|
||||
}
|
||||
|
||||
@pragma("vm:never-inline")
|
||||
@@ -40,8 +40,12 @@ Future<void> main() async {
|
||||
return; // Generated dwarf.so not available on the test device.
|
||||
}
|
||||
|
||||
final dwarf = Dwarf.fromFile(path.join(
|
||||
Platform.environment['TEST_COMPILATION_DIR']!, "dwarf_obfuscate.so"))!;
|
||||
final dwarf = Dwarf.fromFile(
|
||||
path.join(
|
||||
Platform.environment['TEST_COMPILATION_DIR']!,
|
||||
"dwarf_obfuscate.so",
|
||||
),
|
||||
)!;
|
||||
|
||||
await base.checkStackTrace(rawStack, dwarf, expectedCallsInfo);
|
||||
}
|
||||
@@ -51,26 +55,29 @@ final expectedCallsInfo = <List<DartCallInfo>>[
|
||||
// into foo (so we'll get information for two calls for that PC address).
|
||||
[
|
||||
DartCallInfo(
|
||||
function: "bar",
|
||||
filename: "dwarf_stack_trace_obfuscate_test.dart",
|
||||
line: 18,
|
||||
column: 3,
|
||||
inlined: true),
|
||||
function: "bar",
|
||||
filename: "dwarf_stack_trace_obfuscate_test.dart",
|
||||
line: 18,
|
||||
column: 3,
|
||||
inlined: true,
|
||||
),
|
||||
DartCallInfo(
|
||||
function: "foo",
|
||||
filename: "dwarf_stack_trace_obfuscate_test.dart",
|
||||
line: 24,
|
||||
column: 3,
|
||||
inlined: false)
|
||||
function: "foo",
|
||||
filename: "dwarf_stack_trace_obfuscate_test.dart",
|
||||
line: 24,
|
||||
column: 3,
|
||||
inlined: false,
|
||||
),
|
||||
],
|
||||
// The second frame corresponds to call to foo in main.
|
||||
[
|
||||
DartCallInfo(
|
||||
function: "main",
|
||||
filename: "dwarf_stack_trace_obfuscate_test.dart",
|
||||
line: 30,
|
||||
column: 5,
|
||||
inlined: false)
|
||||
function: "main",
|
||||
filename: "dwarf_stack_trace_obfuscate_test.dart",
|
||||
line: 30,
|
||||
column: 5,
|
||||
inlined: false,
|
||||
),
|
||||
],
|
||||
// Don't assume anything about any of the frames below the call to foo
|
||||
// in main, as this makes the test too brittle.
|
||||
|
||||
@@ -16,7 +16,7 @@ import 'package:path/path.dart' as path;
|
||||
bar() {
|
||||
// Keep the 'throw' and its argument on separate lines.
|
||||
throw // force linebreak with dart format
|
||||
"Hello, Dwarf!";
|
||||
"Hello, Dwarf!";
|
||||
}
|
||||
|
||||
@pragma("vm:never-inline")
|
||||
@@ -41,19 +41,24 @@ Future<void> main() async {
|
||||
}
|
||||
|
||||
final dwarf = Dwarf.fromFile(
|
||||
path.join(Platform.environment["TEST_COMPILATION_DIR"]!, "dwarf.so"))!;
|
||||
path.join(Platform.environment["TEST_COMPILATION_DIR"]!, "dwarf.so"),
|
||||
)!;
|
||||
|
||||
await checkStackTrace(rawStack, dwarf, expectedCallsInfo);
|
||||
}
|
||||
|
||||
Future<void> checkStackTrace(String rawStack, Dwarf dwarf,
|
||||
List<List<DartCallInfo>> expectedCallsInfo) async {
|
||||
Future<void> checkStackTrace(
|
||||
String rawStack,
|
||||
Dwarf dwarf,
|
||||
List<List<DartCallInfo>> expectedCallsInfo,
|
||||
) async {
|
||||
print("");
|
||||
print("Raw stack trace:");
|
||||
print(rawStack);
|
||||
|
||||
final rawLines =
|
||||
await Stream.value(rawStack).transform(const LineSplitter()).toList();
|
||||
final rawLines = await Stream.value(
|
||||
rawStack,
|
||||
).transform(const LineSplitter()).toList();
|
||||
|
||||
final pcOffsets = collectPCOffsets(rawLines).toList();
|
||||
Expect.isNotEmpty(pcOffsets);
|
||||
@@ -73,8 +78,9 @@ Future<void> checkStackTrace(String rawStack, Dwarf dwarf,
|
||||
print('Isolate start offset: 0x${isolateStart!.toRadixString(16)}');
|
||||
|
||||
// The addresses of the stack frames in the separate DWARF debugging info.
|
||||
final virtualAddresses =
|
||||
pcOffsets.map((o) => dwarf.virtualAddressOf(o)).toList();
|
||||
final virtualAddresses = pcOffsets
|
||||
.map((o) => dwarf.virtualAddressOf(o))
|
||||
.toList();
|
||||
|
||||
print('Virtual addresses from PCOffsets:');
|
||||
for (final address in virtualAddresses) {
|
||||
@@ -87,8 +93,10 @@ Future<void> checkStackTrace(String rawStack, Dwarf dwarf,
|
||||
print('DSO base address: 0x${dsoBase.toRadixString(16)}');
|
||||
|
||||
final absoluteIsolateStart = isolateStartAddresses(rawLines).single;
|
||||
print('Absolute isolate start address: '
|
||||
'0x${absoluteIsolateStart.toRadixString(16)}');
|
||||
print(
|
||||
'Absolute isolate start address: '
|
||||
'0x${absoluteIsolateStart.toRadixString(16)}',
|
||||
);
|
||||
|
||||
final absolutes = absoluteAddresses(rawLines);
|
||||
// The relocated addresses of the stack frames in the loaded DSO. These is
|
||||
@@ -125,19 +133,25 @@ Future<void> checkStackTrace(String rawStack, Dwarf dwarf,
|
||||
for (final offset in pcOffsets) {
|
||||
final externalCallInfo = dwarf.callInfoForPCOffset(offset);
|
||||
Expect.isNotNull(externalCallInfo);
|
||||
final allCallInfo =
|
||||
dwarf.callInfoForPCOffset(offset, includeInternalFrames: true);
|
||||
final allCallInfo = dwarf.callInfoForPCOffset(
|
||||
offset,
|
||||
includeInternalFrames: true,
|
||||
);
|
||||
Expect.isNotNull(allCallInfo);
|
||||
for (final call in externalCallInfo!) {
|
||||
Expect.isTrue(call is DartCallInfo, "got non-Dart call info ${call}");
|
||||
Expect.isFalse(call.isInternal);
|
||||
Expect.isTrue(allCallInfo!.contains(call),
|
||||
"External call info ${call} is not among all calls");
|
||||
Expect.isTrue(
|
||||
allCallInfo!.contains(call),
|
||||
"External call info ${call} is not among all calls",
|
||||
);
|
||||
}
|
||||
for (final call in allCallInfo!) {
|
||||
if (!call.isInternal) {
|
||||
Expect.isTrue(externalCallInfo.contains(call),
|
||||
"External call info ${call} is not among external calls");
|
||||
Expect.isTrue(
|
||||
externalCallInfo.contains(call),
|
||||
"External call info ${call} is not among external calls",
|
||||
);
|
||||
}
|
||||
}
|
||||
gotCallsInfo.add(externalCallInfo.cast<DartCallInfo>().toList());
|
||||
@@ -160,8 +174,9 @@ Future<void> checkStackTrace(String rawStack, Dwarf dwarf,
|
||||
.transform(DwarfStackTraceDecoder(dwarf, includeInternalFrames: false))
|
||||
.toList();
|
||||
|
||||
final gotSymbolizedCalls =
|
||||
gotSymbolizedLines.where((s) => s.startsWith('#')).toList();
|
||||
final gotSymbolizedCalls = gotSymbolizedLines
|
||||
.where((s) => s.startsWith('#'))
|
||||
.toList();
|
||||
|
||||
print("");
|
||||
print("Symbolized stack trace:");
|
||||
@@ -178,8 +193,9 @@ Future<void> checkStackTrace(String rawStack, Dwarf dwarf,
|
||||
|
||||
// Strip off any unexpected lines, so we can also make sure we didn't get
|
||||
// unexpected calls prior to those calls we expect.
|
||||
final gotCallsTrace =
|
||||
gotSymbolizedCalls.sublist(0, expectedCallCount).join('\n');
|
||||
final gotCallsTrace = gotSymbolizedCalls
|
||||
.sublist(0, expectedCallCount)
|
||||
.join('\n');
|
||||
|
||||
Expect.containsInOrder(expectedStrings, gotCallsTrace);
|
||||
}
|
||||
@@ -189,33 +205,38 @@ final expectedCallsInfo = <List<DartCallInfo>>[
|
||||
// into foo (so we'll get information for two calls for that PC address).
|
||||
[
|
||||
DartCallInfo(
|
||||
function: "bar",
|
||||
filename: "dwarf_stack_trace_test.dart",
|
||||
line: 17,
|
||||
column: 3,
|
||||
inlined: true),
|
||||
function: "bar",
|
||||
filename: "dwarf_stack_trace_test.dart",
|
||||
line: 17,
|
||||
column: 3,
|
||||
inlined: true,
|
||||
),
|
||||
DartCallInfo(
|
||||
function: "foo",
|
||||
filename: "dwarf_stack_trace_test.dart",
|
||||
line: 23,
|
||||
column: 3,
|
||||
inlined: false)
|
||||
function: "foo",
|
||||
filename: "dwarf_stack_trace_test.dart",
|
||||
line: 23,
|
||||
column: 3,
|
||||
inlined: false,
|
||||
),
|
||||
],
|
||||
// The second frame corresponds to call to foo in main.
|
||||
[
|
||||
DartCallInfo(
|
||||
function: "main",
|
||||
filename: "dwarf_stack_trace_test.dart",
|
||||
line: 29,
|
||||
column: 5,
|
||||
inlined: false)
|
||||
function: "main",
|
||||
filename: "dwarf_stack_trace_test.dart",
|
||||
line: 29,
|
||||
column: 5,
|
||||
inlined: false,
|
||||
),
|
||||
],
|
||||
// Don't assume anything about any of the frames below the call to foo
|
||||
// in main, as this makes the test too brittle.
|
||||
];
|
||||
|
||||
void checkFrames(
|
||||
List<List<DartCallInfo>> gotInfo, List<List<DartCallInfo>> expectedInfo) {
|
||||
List<List<DartCallInfo>> gotInfo,
|
||||
List<List<DartCallInfo>> expectedInfo,
|
||||
) {
|
||||
// There may be frames below those we check.
|
||||
Expect.isTrue(gotInfo.length >= expectedInfo.length);
|
||||
|
||||
|
||||
@@ -13,12 +13,16 @@ import "package:expect/expect.dart";
|
||||
main() {
|
||||
// User string entry, const.
|
||||
Expect.isTrue(const bool.hasEnvironment("testFlag"));
|
||||
Expect.equals("testValue",
|
||||
const String.fromEnvironment("testFlag", defaultValue: "nonce"));
|
||||
Expect.equals(
|
||||
"testValue",
|
||||
const String.fromEnvironment("testFlag", defaultValue: "nonce"),
|
||||
);
|
||||
// User string entry, runtime.
|
||||
Expect.isTrue(bool.hasEnvironment("testFlag"));
|
||||
Expect.equals(
|
||||
"testValue", String.fromEnvironment("testFlag", defaultValue: "nonce"));
|
||||
"testValue",
|
||||
String.fromEnvironment("testFlag", defaultValue: "nonce"),
|
||||
);
|
||||
|
||||
// User number entry, const.
|
||||
Expect.isTrue(const bool.hasEnvironment("numFlag"));
|
||||
@@ -33,7 +37,9 @@ main() {
|
||||
Expect.isTrue(const bool.hasEnvironment("boolFlag"));
|
||||
Expect.equals("false", const String.fromEnvironment("boolFlag"));
|
||||
Expect.equals(
|
||||
false, const bool.fromEnvironment("boolFlag", defaultValue: true));
|
||||
false,
|
||||
const bool.fromEnvironment("boolFlag", defaultValue: true),
|
||||
);
|
||||
// User bool entry, runtime.
|
||||
Expect.isTrue(bool.hasEnvironment("boolFlag"));
|
||||
Expect.equals("false", String.fromEnvironment("boolFlag"));
|
||||
@@ -43,7 +49,9 @@ main() {
|
||||
Expect.isFalse(const bool.hasEnvironment("noEntry"));
|
||||
Expect.equals("", const String.fromEnvironment("noEntry"));
|
||||
Expect.equals(
|
||||
"nonce", const String.fromEnvironment("noEntry", defaultValue: "nonce"));
|
||||
"nonce",
|
||||
const String.fromEnvironment("noEntry", defaultValue: "nonce"),
|
||||
);
|
||||
Expect.equals(0, const int.fromEnvironment("noEntry"));
|
||||
Expect.equals(42, const int.fromEnvironment("noEntry", defaultValue: 42));
|
||||
Expect.isFalse(const bool.fromEnvironment("noEntry"));
|
||||
@@ -52,7 +60,9 @@ main() {
|
||||
Expect.isFalse(bool.hasEnvironment("noEntry"));
|
||||
Expect.equals("", String.fromEnvironment("noEntry"));
|
||||
Expect.equals(
|
||||
"nonce", String.fromEnvironment("noEntry", defaultValue: "nonce"));
|
||||
"nonce",
|
||||
String.fromEnvironment("noEntry", defaultValue: "nonce"),
|
||||
);
|
||||
Expect.equals(0, int.fromEnvironment("noEntry"));
|
||||
Expect.equals(42, int.fromEnvironment("noEntry", defaultValue: 42));
|
||||
Expect.isFalse(bool.fromEnvironment("noEntry"));
|
||||
@@ -60,57 +70,77 @@ main() {
|
||||
|
||||
// General platform library entry, const.
|
||||
Expect.isTrue(const bool.hasEnvironment("dart.library.core"));
|
||||
Expect.equals("true",
|
||||
const String.fromEnvironment("dart.library.core", defaultValue: "nonce"));
|
||||
Expect.equals(
|
||||
"true",
|
||||
const String.fromEnvironment("dart.library.core", defaultValue: "nonce"),
|
||||
);
|
||||
Expect.isTrue(
|
||||
const bool.fromEnvironment("dart.library.core", defaultValue: false));
|
||||
const bool.fromEnvironment("dart.library.core", defaultValue: false),
|
||||
);
|
||||
// General platform library entry, runtime.
|
||||
Expect.isTrue(bool.hasEnvironment("dart.library.core"));
|
||||
Expect.equals("true",
|
||||
String.fromEnvironment("dart.library.core", defaultValue: "nonce"));
|
||||
Expect.equals(
|
||||
"true",
|
||||
String.fromEnvironment("dart.library.core", defaultValue: "nonce"),
|
||||
);
|
||||
Expect.isTrue(bool.fromEnvironment("dart.library.core", defaultValue: false));
|
||||
|
||||
// Standalone VM-specific library, const.
|
||||
Expect.isTrue(const bool.hasEnvironment("dart.library.io"));
|
||||
Expect.equals("true",
|
||||
const String.fromEnvironment("dart.library.io", defaultValue: "nonce"));
|
||||
Expect.equals(
|
||||
"true",
|
||||
const String.fromEnvironment("dart.library.io", defaultValue: "nonce"),
|
||||
);
|
||||
Expect.isTrue(
|
||||
const bool.fromEnvironment("dart.library.io", defaultValue: false));
|
||||
const bool.fromEnvironment("dart.library.io", defaultValue: false),
|
||||
);
|
||||
// Standalone VM-specific library, runtime.
|
||||
Expect.isTrue(bool.hasEnvironment("dart.library.io"));
|
||||
Expect.equals(
|
||||
"true", String.fromEnvironment("dart.library.io", defaultValue: "nonce"));
|
||||
"true",
|
||||
String.fromEnvironment("dart.library.io", defaultValue: "nonce"),
|
||||
);
|
||||
Expect.isTrue(bool.fromEnvironment("dart.library.io", defaultValue: false));
|
||||
|
||||
// Web-specific library, not available here, const.
|
||||
Expect.isFalse(const bool.hasEnvironment("dart.library.html"));
|
||||
Expect.equals("", const String.fromEnvironment("dart.library.html"));
|
||||
Expect.equals("nonce",
|
||||
const String.fromEnvironment("dart.library.html", defaultValue: "nonce"));
|
||||
Expect.equals(
|
||||
"nonce",
|
||||
const String.fromEnvironment("dart.library.html", defaultValue: "nonce"),
|
||||
);
|
||||
Expect.isFalse(const bool.fromEnvironment("dart.library.html"));
|
||||
Expect.isTrue(
|
||||
const bool.fromEnvironment("dart.library.html", defaultValue: true));
|
||||
const bool.fromEnvironment("dart.library.html", defaultValue: true),
|
||||
);
|
||||
// Web-specific library, not available here, runtime.
|
||||
Expect.isFalse(bool.hasEnvironment("dart.library.html"));
|
||||
Expect.equals("", String.fromEnvironment("dart.library.html"));
|
||||
Expect.equals("nonce",
|
||||
String.fromEnvironment("dart.library.html", defaultValue: "nonce"));
|
||||
Expect.equals(
|
||||
"nonce",
|
||||
String.fromEnvironment("dart.library.html", defaultValue: "nonce"),
|
||||
);
|
||||
Expect.isFalse(bool.fromEnvironment("dart.library.html"));
|
||||
Expect.isTrue(bool.fromEnvironment("dart.library.html", defaultValue: true));
|
||||
|
||||
// Non-existing library, const.
|
||||
Expect.isFalse(const bool.hasEnvironment("dart.library.not"));
|
||||
Expect.equals("", const String.fromEnvironment("dart.library.not"));
|
||||
Expect.equals("nonce",
|
||||
const String.fromEnvironment("dart.library.not", defaultValue: "nonce"));
|
||||
Expect.equals(
|
||||
"nonce",
|
||||
const String.fromEnvironment("dart.library.not", defaultValue: "nonce"),
|
||||
);
|
||||
Expect.isFalse(const bool.fromEnvironment("dart.library.not"));
|
||||
Expect.isTrue(
|
||||
const bool.fromEnvironment("dart.library.not", defaultValue: true));
|
||||
const bool.fromEnvironment("dart.library.not", defaultValue: true),
|
||||
);
|
||||
// Non-existing library, runtime.
|
||||
Expect.isFalse(bool.hasEnvironment("dart.library.not"));
|
||||
Expect.equals("", String.fromEnvironment("dart.library.not"));
|
||||
Expect.equals("nonce",
|
||||
String.fromEnvironment("dart.library.not", defaultValue: "nonce"));
|
||||
Expect.equals(
|
||||
"nonce",
|
||||
String.fromEnvironment("dart.library.not", defaultValue: "nonce"),
|
||||
);
|
||||
Expect.isFalse(bool.fromEnvironment("dart.library.not"));
|
||||
Expect.isTrue(bool.fromEnvironment("dart.library.not", defaultValue: true));
|
||||
}
|
||||
|
||||
@@ -10,8 +10,11 @@ import 'dart:io';
|
||||
main(List<String> arguments) {
|
||||
int port = int.parse(arguments[0]);
|
||||
ReceivePort receivePort = new ReceivePort();
|
||||
Isolate.spawnUri(Uri.parse('http://127.0.0.1:$port/http_isolate_main.dart'),
|
||||
['hello'], receivePort.sendPort);
|
||||
Isolate.spawnUri(
|
||||
Uri.parse('http://127.0.0.1:$port/http_isolate_main.dart'),
|
||||
['hello'],
|
||||
receivePort.sendPort,
|
||||
);
|
||||
receivePort.first.then((response) {
|
||||
print(response);
|
||||
});
|
||||
|
||||
@@ -55,31 +55,39 @@ serverRunning(HttpServer server) {
|
||||
port = server.port;
|
||||
server.listen(handleRequest);
|
||||
Future<ProcessResult> no_http_run = Process.run(
|
||||
pathToExecutable,
|
||||
[]
|
||||
..add('--verbosity=warning')
|
||||
..addAll(executableArguments)
|
||||
..add(pathOfData.resolve('http_launch_main.dart').toFilePath()));
|
||||
pathToExecutable,
|
||||
[]
|
||||
..add('--verbosity=warning')
|
||||
..addAll(executableArguments)
|
||||
..add(pathOfData.resolve('http_launch_main.dart').toFilePath()),
|
||||
);
|
||||
Future<ProcessResult> http_run = Process.run(
|
||||
pathToExecutable,
|
||||
[]
|
||||
..add('--verbosity=warning')
|
||||
..addAll(executableArguments)
|
||||
..add('http://127.0.0.1:$port/http_launch_main.dart'));
|
||||
pathToExecutable,
|
||||
[]
|
||||
..add('--verbosity=warning')
|
||||
..addAll(executableArguments)
|
||||
..add('http://127.0.0.1:$port/http_launch_main.dart'),
|
||||
);
|
||||
Future<ProcessResult> http_pkg_root_run = Process.run(
|
||||
pathToExecutable,
|
||||
[]
|
||||
..add('--verbosity=warning')
|
||||
..addAll(executableArguments)
|
||||
..addAll(['http://127.0.0.1:$port/http_launch_main.dart']));
|
||||
pathToExecutable,
|
||||
[]
|
||||
..add('--verbosity=warning')
|
||||
..addAll(executableArguments)
|
||||
..addAll(['http://127.0.0.1:$port/http_launch_main.dart']),
|
||||
);
|
||||
Future<ProcessResult> isolate_run = Process.run(
|
||||
pathToExecutable,
|
||||
[]
|
||||
..add('--verbosity=warning')
|
||||
..addAll(executableArguments)
|
||||
..addAll(['http://127.0.0.1:$port/http_spawn_main.dart', '$port']));
|
||||
Future<List<ProcessResult>> results =
|
||||
Future.wait([no_http_run, http_run, http_pkg_root_run, isolate_run]);
|
||||
pathToExecutable,
|
||||
[]
|
||||
..add('--verbosity=warning')
|
||||
..addAll(executableArguments)
|
||||
..addAll(['http://127.0.0.1:$port/http_spawn_main.dart', '$port']),
|
||||
);
|
||||
Future<List<ProcessResult>> results = Future.wait([
|
||||
no_http_run,
|
||||
http_run,
|
||||
http_pkg_root_run,
|
||||
isolate_run,
|
||||
]);
|
||||
results.then((results) {
|
||||
// Close server.
|
||||
server.close();
|
||||
|
||||
@@ -94,7 +94,7 @@ testSameHash(String tmpDirPath) {
|
||||
path.join(dartRootPath, "tools", "addlatexhash.dart"),
|
||||
tmpPar8timesPath,
|
||||
hashPath,
|
||||
listPath
|
||||
listPath,
|
||||
]);
|
||||
return Process.runSync(dartExecutable, args);
|
||||
}
|
||||
@@ -167,7 +167,7 @@ testSameDVI(String tmpDirPath) {
|
||||
path.join(dartRootPath, "tools", "addlatexhash.dart"),
|
||||
tmpSpecPath,
|
||||
hashPath,
|
||||
listPath
|
||||
listPath,
|
||||
]);
|
||||
return Process.runSync(dartExecutable, args);
|
||||
}
|
||||
|
||||
@@ -14,8 +14,11 @@ void main() async {
|
||||
asyncStart();
|
||||
final result = <InternetAddress>[];
|
||||
try {
|
||||
result.addAll(await InternetAddress.lookup("some.bad.host.name.7654321")
|
||||
.timeout(const Duration(milliseconds: 1), onTimeout: () => []));
|
||||
result.addAll(
|
||||
await InternetAddress.lookup(
|
||||
"some.bad.host.name.7654321",
|
||||
).timeout(const Duration(milliseconds: 1), onTimeout: () => []),
|
||||
);
|
||||
} catch (e) {
|
||||
print('managed to fail with $e lookup before timeout');
|
||||
}
|
||||
|
||||
@@ -12,27 +12,33 @@ var events = [];
|
||||
|
||||
Future testSocketException() {
|
||||
var completer = new Completer();
|
||||
runZonedGuarded(() {
|
||||
Socket.connect("4", 1, timeout: Duration(seconds: 5)).then((Socket s) {
|
||||
Expect.fail("Socket should not be able to connect");
|
||||
});
|
||||
}, (err, s) {
|
||||
if (err is! SocketException) Expect.fail("Not expected error: $err");
|
||||
completer.complete("socket test, ok.");
|
||||
events.add("SocketException");
|
||||
});
|
||||
runZonedGuarded(
|
||||
() {
|
||||
Socket.connect("4", 1, timeout: Duration(seconds: 5)).then((Socket s) {
|
||||
Expect.fail("Socket should not be able to connect");
|
||||
});
|
||||
},
|
||||
(err, s) {
|
||||
if (err is! SocketException) Expect.fail("Not expected error: $err");
|
||||
completer.complete("socket test, ok.");
|
||||
events.add("SocketException");
|
||||
},
|
||||
);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Future testFileSystemException() {
|
||||
var completer = new Completer();
|
||||
runZonedGuarded(() {
|
||||
new File("lol it's not a file\n").openRead().listen(null);
|
||||
}, (err, s) {
|
||||
if (err is! FileSystemException) Expect.fail("Not expected error: $err");
|
||||
completer.complete("file test, ok.");
|
||||
events.add("FileSystemException");
|
||||
});
|
||||
runZonedGuarded(
|
||||
() {
|
||||
new File("lol it's not a file\n").openRead().listen(null);
|
||||
},
|
||||
(err, s) {
|
||||
if (err is! FileSystemException) Expect.fail("Not expected error: $err");
|
||||
completer.complete("file test, ok.");
|
||||
events.add("FileSystemException");
|
||||
},
|
||||
);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,26 +20,33 @@ void clientSocketAddCloseErrorTest() {
|
||||
Socket.connect("127.0.0.1", server.port).then((client) {
|
||||
const int SIZE = 1024 * 1024;
|
||||
int errors = 0;
|
||||
client.listen((data) => Expect.fail("Unexpected data"), onError: (error) {
|
||||
Expect.isTrue(error is SocketException);
|
||||
errors++;
|
||||
}, onDone: () {
|
||||
// We get either a close or an error followed by a close
|
||||
// on the socket. Whether we get both depends on
|
||||
// whether the system notices the error for the read
|
||||
// event or only for the write event.
|
||||
Expect.isTrue(errors <= 1);
|
||||
server.close();
|
||||
});
|
||||
client.listen(
|
||||
(data) => Expect.fail("Unexpected data"),
|
||||
onError: (error) {
|
||||
Expect.isTrue(error is SocketException);
|
||||
errors++;
|
||||
},
|
||||
onDone: () {
|
||||
// We get either a close or an error followed by a close
|
||||
// on the socket. Whether we get both depends on
|
||||
// whether the system notices the error for the read
|
||||
// event or only for the write event.
|
||||
Expect.isTrue(errors <= 1);
|
||||
server.close();
|
||||
},
|
||||
);
|
||||
client.add(new List.filled(SIZE, 0));
|
||||
// Destroy other socket now.
|
||||
completer.complete(null);
|
||||
client.done.then((_) {
|
||||
Expect.fail("Expected error");
|
||||
}, onError: (error) {
|
||||
Expect.isTrue(error is SocketException);
|
||||
asyncEnd();
|
||||
});
|
||||
client.done.then(
|
||||
(_) {
|
||||
Expect.fail("Expected error");
|
||||
},
|
||||
onError: (error) {
|
||||
Expect.isTrue(error is SocketException);
|
||||
asyncEnd();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,10 +20,13 @@ void clientSocketAddCloseNoErrorTest() {
|
||||
Socket.connect("127.0.0.1", server.port).then((client) {
|
||||
const int SIZE = 1024 * 1024;
|
||||
int count = 0;
|
||||
client.listen((data) => count += data.length, onDone: () {
|
||||
Expect.equals(SIZE, count);
|
||||
server.close();
|
||||
});
|
||||
client.listen(
|
||||
(data) => count += data.length,
|
||||
onDone: () {
|
||||
Expect.equals(SIZE, count);
|
||||
server.close();
|
||||
},
|
||||
);
|
||||
client.add(new List.filled(SIZE, 0));
|
||||
client.close();
|
||||
// Start piping now.
|
||||
|
||||
@@ -28,8 +28,10 @@ void main() async {
|
||||
client.listen((data) {}, onDone: server.close);
|
||||
client.add(new List.filled(1024 * 1024, 0));
|
||||
client.destroy();
|
||||
await client.addStream(Stream.fromIterable([
|
||||
[1, 2, 3, 4]
|
||||
]));
|
||||
await client.addStream(
|
||||
Stream.fromIterable([
|
||||
[1, 2, 3, 4],
|
||||
]),
|
||||
);
|
||||
asyncEnd();
|
||||
}
|
||||
|
||||
@@ -78,8 +78,9 @@ Future expectFutureIsTrue(Future future) =>
|
||||
|
||||
Future expectFileSystemException(Function f, String message) {
|
||||
return f().then(
|
||||
(_) => Expect.fail('Expected a FileSystemException: $message'),
|
||||
onError: (e) => Expect.isTrue(e is FileSystemException));
|
||||
(_) => Expect.fail('Expected a FileSystemException: $message'),
|
||||
onError: (e) => Expect.isTrue(e is FileSystemException),
|
||||
);
|
||||
}
|
||||
|
||||
testCreateDirectoryRecursive() {
|
||||
@@ -123,16 +124,21 @@ testCreateLinkRecursive() {
|
||||
Directory.systemTemp.createTemp('dart_directory').then((temp) {
|
||||
var link = new Link(join(temp.path, 'a', 'b', 'c'));
|
||||
return expectFileSystemException(
|
||||
() => link.create(temp.path), 'link.create')
|
||||
() => link.create(temp.path),
|
||||
'link.create',
|
||||
)
|
||||
.then((_) => link.create(temp.path, recursive: true))
|
||||
.then((_) => expectFutureIsTrue(link.exists()))
|
||||
// Test cases where the link or parent directory already exists.
|
||||
.then((_) => link.delete())
|
||||
.then((_) => link.create(temp.path, recursive: true))
|
||||
.then((_) => expectFutureIsTrue(link.exists()))
|
||||
.then((_) => expectFileSystemException(
|
||||
.then(
|
||||
(_) => expectFileSystemException(
|
||||
() => link.create(temp.path, recursive: true),
|
||||
'existing link.create'))
|
||||
'existing link.create',
|
||||
),
|
||||
)
|
||||
.then((_) => expectFutureIsTrue(link.exists()))
|
||||
.then((_) => asyncEnd())
|
||||
.whenComplete(() => temp.delete(recursive: true));
|
||||
|
||||
@@ -27,7 +27,7 @@ void testCreateRecursiveRace() {
|
||||
d.create(recursive: true),
|
||||
d.create(recursive: true),
|
||||
d.create(recursive: true),
|
||||
d.create(recursive: true)
|
||||
d.create(recursive: true),
|
||||
]).then((_) {
|
||||
Expect.isTrue(new Directory('${temp.path}/a').existsSync());
|
||||
Expect.isTrue(new Directory('${temp.path}/a/b').existsSync());
|
||||
|
||||
@@ -31,8 +31,10 @@ bool checkCreateInNonExistentFileSystemException(e) {
|
||||
|
||||
void testCreateInNonExistent(Directory temp, Function done) {
|
||||
Directory inNonExistent = new Directory("${temp.path}/nonExistent/xxx");
|
||||
Expect.throws(() => inNonExistent.createSync(),
|
||||
(e) => checkCreateInNonExistentFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => inNonExistent.createSync(),
|
||||
(e) => checkCreateInNonExistentFileSystemException(e),
|
||||
);
|
||||
|
||||
Future<Directory?>.value(inNonExistent.create()).catchError((error) {
|
||||
checkCreateInNonExistentFileSystemException(error);
|
||||
@@ -56,11 +58,14 @@ bool checkCreateTempInNonExistentFileSystemException(e) {
|
||||
|
||||
void testCreateTempInNonExistent(Directory temp, Function done) {
|
||||
Directory nonExistent = new Directory("${temp.path}/nonExistent/xxx");
|
||||
Expect.throws(() => nonExistent.createTempSync('tempdir'),
|
||||
(e) => checkCreateTempInNonExistentFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => nonExistent.createTempSync('tempdir'),
|
||||
(e) => checkCreateTempInNonExistentFileSystemException(e),
|
||||
);
|
||||
|
||||
Future<Directory?>.value(nonExistent.createTemp('tempdir'))
|
||||
.catchError((error) {
|
||||
Future<Directory?>.value(nonExistent.createTemp('tempdir')).catchError((
|
||||
error,
|
||||
) {
|
||||
checkCreateTempInNonExistentFileSystemException(error);
|
||||
done();
|
||||
});
|
||||
@@ -77,8 +82,10 @@ bool checkDeleteNonExistentFileSystemException(e) {
|
||||
|
||||
void testDeleteNonExistent(Directory temp, Function done) {
|
||||
Directory nonExistent = new Directory("${temp.path}/nonExistent");
|
||||
Expect.throws(() => nonExistent.deleteSync(),
|
||||
(e) => checkDeleteNonExistentFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => nonExistent.deleteSync(),
|
||||
(e) => checkDeleteNonExistentFileSystemException(e),
|
||||
);
|
||||
|
||||
Future<FileSystemEntity?>.value(nonExistent.delete()).catchError((error) {
|
||||
checkDeleteNonExistentFileSystemException(error);
|
||||
@@ -98,11 +105,14 @@ bool checkDeleteRecursivelyNonExistentFileSystemException(e) {
|
||||
|
||||
void testDeleteRecursivelyNonExistent(Directory temp, Function done) {
|
||||
Directory nonExistent = new Directory("${temp.path}/nonExistent");
|
||||
Expect.throws(() => nonExistent.deleteSync(recursive: true),
|
||||
(e) => checkDeleteRecursivelyNonExistentFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => nonExistent.deleteSync(recursive: true),
|
||||
(e) => checkDeleteRecursivelyNonExistentFileSystemException(e),
|
||||
);
|
||||
|
||||
Future<FileSystemEntity?>.value(nonExistent.delete(recursive: true))
|
||||
.catchError((error) {
|
||||
Future<FileSystemEntity?>.value(
|
||||
nonExistent.delete(recursive: true),
|
||||
).catchError((error) {
|
||||
checkDeleteRecursivelyNonExistentFileSystemException(error);
|
||||
done();
|
||||
});
|
||||
@@ -130,22 +140,26 @@ bool checkAsyncListNonExistentFileSystemException(error) {
|
||||
void testListNonExistent(Directory temp, Function done) {
|
||||
Directory nonExistent = new Directory("${temp.path}/nonExistent");
|
||||
Expect.throws(() => nonExistent.listSync(), (e) => e is FileSystemException);
|
||||
nonExistent.list().listen((_) => Expect.fail("listing should not succeed"),
|
||||
onError: (e) {
|
||||
checkAsyncListNonExistentFileSystemException(e);
|
||||
done();
|
||||
});
|
||||
nonExistent.list().listen(
|
||||
(_) => Expect.fail("listing should not succeed"),
|
||||
onError: (e) {
|
||||
checkAsyncListNonExistentFileSystemException(e);
|
||||
done();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void testRenameNonExistent(Directory temp, Function done) {
|
||||
Directory nonExistent = new Directory("${temp.path}/nonExistent");
|
||||
var newPath = "${temp.path}/nonExistent2";
|
||||
Expect.throws(
|
||||
() => nonExistent.renameSync(newPath), (e) => e is PathNotFoundException);
|
||||
() => nonExistent.renameSync(newPath),
|
||||
(e) => e is PathNotFoundException,
|
||||
);
|
||||
var renameDone = nonExistent.rename(newPath);
|
||||
renameDone
|
||||
.then((ignore) => Expect.fail('rename non existent'))
|
||||
.catchError((error) {
|
||||
renameDone.then((ignore) => Expect.fail('rename non existent')).catchError((
|
||||
error,
|
||||
) {
|
||||
Expect.isTrue(error is PathNotFoundException);
|
||||
done();
|
||||
});
|
||||
@@ -161,9 +175,9 @@ void testRenameFileAsDirectory(Directory temp, Function done) {
|
||||
renameDone
|
||||
.then((ignore) => Expect.fail('rename file as directory'))
|
||||
.catchError((error) {
|
||||
Expect.isTrue(error is FileSystemException);
|
||||
done();
|
||||
});
|
||||
Expect.isTrue(error is FileSystemException);
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
testRenameOverwriteFile(Directory temp, Function done) {
|
||||
@@ -171,15 +185,17 @@ testRenameOverwriteFile(Directory temp, Function done) {
|
||||
var fileName = '${temp.path}/x';
|
||||
new File(fileName).createSync();
|
||||
Expect.throws(
|
||||
() => temp1.renameSync(fileName), (e) => e is FileSystemException);
|
||||
() => temp1.renameSync(fileName),
|
||||
(e) => e is FileSystemException,
|
||||
);
|
||||
var renameDone = temp1.rename(fileName);
|
||||
renameDone
|
||||
.then((ignore) => Expect.fail('rename dir overwrite file'))
|
||||
.catchError((error) {
|
||||
Expect.isTrue(error is FileSystemException);
|
||||
temp1.deleteSync(recursive: true);
|
||||
done();
|
||||
});
|
||||
Expect.isTrue(error is FileSystemException);
|
||||
temp1.deleteSync(recursive: true);
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
void runTest(Function test) {
|
||||
|
||||
@@ -51,11 +51,13 @@ fuzzAsyncMethods() async {
|
||||
await withTempDir('dart_directory_fuzz', (temp) async {
|
||||
final futures = <Future>[];
|
||||
typeMapping.forEach((k, v) {
|
||||
futures.add(doItAsync(() {
|
||||
Directory.systemTemp
|
||||
.createTempSync("${temp.path}/${v as String}")
|
||||
.deleteSync();
|
||||
}));
|
||||
futures.add(
|
||||
doItAsync(() {
|
||||
Directory.systemTemp
|
||||
.createTempSync("${temp.path}/${v as String}")
|
||||
.deleteSync();
|
||||
}),
|
||||
);
|
||||
if (v is! String) {
|
||||
return;
|
||||
}
|
||||
@@ -63,22 +65,28 @@ fuzzAsyncMethods() async {
|
||||
futures.add(doItAsync(d.exists));
|
||||
futures.add(doItAsync(d.create));
|
||||
futures.add(doItAsync(d.delete));
|
||||
futures.add(doItAsync(() {
|
||||
return d.createTemp('tempdir').then((temp) {
|
||||
return temp.delete();
|
||||
});
|
||||
}));
|
||||
futures.add(doItAsync(() {
|
||||
return d.exists().then((res) {
|
||||
if (!res) return d.delete(recursive: true);
|
||||
return new Future.value(true);
|
||||
});
|
||||
}));
|
||||
futures.add(
|
||||
doItAsync(() {
|
||||
return d.createTemp('tempdir').then((temp) {
|
||||
return temp.delete();
|
||||
});
|
||||
}),
|
||||
);
|
||||
futures.add(
|
||||
doItAsync(() {
|
||||
return d.exists().then((res) {
|
||||
if (!res) return d.delete(recursive: true);
|
||||
return new Future.value(true);
|
||||
});
|
||||
}),
|
||||
);
|
||||
typeMapping.forEach((k2, v2) {
|
||||
futures.add(doItAsync(() => d.rename(v2 as String)));
|
||||
futures.add(doItAsync(() {
|
||||
d.list(recursive: v2 as bool).listen((_) {}, onError: (e) => null);
|
||||
}));
|
||||
futures.add(
|
||||
doItAsync(() {
|
||||
d.list(recursive: v2 as bool).listen((_) {}, onError: (e) => null);
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
await Future.wait(futures).then((_) => asyncEnd());
|
||||
|
||||
@@ -18,7 +18,9 @@ void testListNonExistent() {
|
||||
d.delete().then((ignore) {
|
||||
Expect.throws(() => d.listSync(), (e) => e is PathNotFoundException);
|
||||
Expect.throws(
|
||||
() => d.listSync(recursive: true), (e) => e is PathNotFoundException);
|
||||
() => d.listSync(recursive: true),
|
||||
(e) => e is PathNotFoundException,
|
||||
);
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
@@ -39,8 +41,10 @@ void testListTooLongName() {
|
||||
}
|
||||
var long = new Directory("${buffer.toString()}");
|
||||
Expect.throws(() => long.listSync(), (e) => e is FileSystemException);
|
||||
Expect.throws(() => long.listSync(recursive: true),
|
||||
(e) => e is FileSystemException);
|
||||
Expect.throws(
|
||||
() => long.listSync(recursive: true),
|
||||
(e) => e is FileSystemException,
|
||||
);
|
||||
d.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
|
||||
@@ -20,25 +20,30 @@ void testPauseList() {
|
||||
bool first = true;
|
||||
var subscription;
|
||||
int count = 0;
|
||||
subscription = d.list(recursive: true).listen((file) {
|
||||
if (file is File) {
|
||||
if (first) {
|
||||
first = false;
|
||||
subscription.pause();
|
||||
Timer.run(() {
|
||||
for (int i = 0; i < TOTAL; i++) {
|
||||
new File("${d.path}/$i/file").deleteSync();
|
||||
subscription = d
|
||||
.list(recursive: true)
|
||||
.listen(
|
||||
(file) {
|
||||
if (file is File) {
|
||||
if (first) {
|
||||
first = false;
|
||||
subscription.pause();
|
||||
Timer.run(() {
|
||||
for (int i = 0; i < TOTAL; i++) {
|
||||
new File("${d.path}/$i/file").deleteSync();
|
||||
}
|
||||
subscription.resume();
|
||||
});
|
||||
}
|
||||
count++;
|
||||
}
|
||||
subscription.resume();
|
||||
});
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}, onDone: () {
|
||||
Expect.notEquals(TOTAL, count);
|
||||
Expect.isTrue(count > 0);
|
||||
d.delete(recursive: true).then((ignore) => asyncEnd());
|
||||
});
|
||||
},
|
||||
onDone: () {
|
||||
Expect.notEquals(TOTAL, count);
|
||||
Expect.isTrue(count > 0);
|
||||
d.delete(recursive: true).then((ignore) => asyncEnd());
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -52,23 +57,28 @@ void testPauseResumeCancelList() {
|
||||
new File("${d.path}/$i/file").createSync();
|
||||
}
|
||||
var subscription;
|
||||
subscription = d.list(recursive: true).listen((entity) {
|
||||
subscription.pause();
|
||||
subscription.resume();
|
||||
void close() {
|
||||
d.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
}
|
||||
subscription = d
|
||||
.list(recursive: true)
|
||||
.listen(
|
||||
(entity) {
|
||||
subscription.pause();
|
||||
subscription.resume();
|
||||
void close() {
|
||||
d.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
}
|
||||
|
||||
var future = subscription.cancel();
|
||||
if (future != null) {
|
||||
future.whenComplete(close);
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
}, onDone: () {
|
||||
Expect.fail('the stream was canceled, onDone should not happen');
|
||||
});
|
||||
var future = subscription.cancel();
|
||||
if (future != null) {
|
||||
future.whenComplete(close);
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
},
|
||||
onDone: () {
|
||||
Expect.fail('the stream was canceled, onDone should not happen');
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -7,11 +7,14 @@ import 'dart:io';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
void testList() {
|
||||
final startingDir =
|
||||
Directory(path.normalize(path.join(Platform.executable, '../../../')));
|
||||
final startingDir = Directory(
|
||||
path.normalize(path.join(Platform.executable, '../../../')),
|
||||
);
|
||||
print("Recursively listing entries in directory ${startingDir.path} ...");
|
||||
List<FileSystemEntity> each =
|
||||
startingDir.listSync(recursive: true, followLinks: false);
|
||||
List<FileSystemEntity> each = startingDir.listSync(
|
||||
recursive: true,
|
||||
followLinks: false,
|
||||
);
|
||||
print("Found: ${each.length} entities");
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,9 @@ import "package:expect/expect.dart";
|
||||
import 'dart:io';
|
||||
|
||||
main() {
|
||||
Directory tempDir =
|
||||
Directory.systemTemp.createTempSync('dart_directory_non_ascii_sync');
|
||||
Directory tempDir = Directory.systemTemp.createTempSync(
|
||||
'dart_directory_non_ascii_sync',
|
||||
);
|
||||
var nonAsciiDir = new Directory("${tempDir.path}/æøå");
|
||||
// On MacOS you get the decomposed utf8 form of file and directory
|
||||
// names from the system. Therefore, we have to check for both here.
|
||||
@@ -18,11 +19,13 @@ main() {
|
||||
Expect.isTrue(nonAsciiDir.existsSync());
|
||||
var temp = new Directory("${tempDir.path}/æøå").createTempSync('tempdir');
|
||||
Expect.isTrue(
|
||||
temp.path.contains(precomposed) || temp.path.contains(decomposed));
|
||||
temp.path.contains(precomposed) || temp.path.contains(decomposed),
|
||||
);
|
||||
temp.deleteSync();
|
||||
temp = tempDir.createTempSync('æøå');
|
||||
Expect.isTrue(
|
||||
temp.path.contains(precomposed) || temp.path.contains(decomposed));
|
||||
temp.path.contains(precomposed) || temp.path.contains(decomposed),
|
||||
);
|
||||
temp.deleteSync();
|
||||
tempDir.deleteSync(recursive: true);
|
||||
Expect.isFalse(nonAsciiDir.existsSync());
|
||||
|
||||
@@ -25,14 +25,16 @@ main() {
|
||||
.then((e) => Expect.isTrue(e))
|
||||
.then((_) => new Directory("${tempDir.path}/æøå").createTemp('temp'))
|
||||
.then((temp) {
|
||||
Expect.isTrue(temp.path.contains(precomposed) ||
|
||||
temp.path.contains(decomposed));
|
||||
Expect.isTrue(
|
||||
temp.path.contains(precomposed) || temp.path.contains(decomposed),
|
||||
);
|
||||
return temp.delete();
|
||||
})
|
||||
.then((_) => tempDir.createTemp('æøå'))
|
||||
.then((temp) {
|
||||
Expect.isTrue(temp.path.contains(precomposed) ||
|
||||
temp.path.contains(decomposed));
|
||||
Expect.isTrue(
|
||||
temp.path.contains(precomposed) || temp.path.contains(decomposed),
|
||||
);
|
||||
return temp.delete();
|
||||
})
|
||||
.then((temp) => Expect.isFalse(temp.existsSync()))
|
||||
|
||||
@@ -28,13 +28,15 @@ testRenamePath() async {
|
||||
final newDir = oldDir.renameSync("${tempDir.path}/dir2");
|
||||
|
||||
Expect.isTrue(
|
||||
oldDir.path == "${tempDir.path}/dir1",
|
||||
"${oldDir.path} != '${tempDir.path}/dir1'"
|
||||
"- path should not be updated");
|
||||
oldDir.path == "${tempDir.path}/dir1",
|
||||
"${oldDir.path} != '${tempDir.path}/dir1'"
|
||||
"- path should not be updated",
|
||||
);
|
||||
Expect.isTrue(
|
||||
newDir.path == "${tempDir.path}/dir2",
|
||||
"${newDir.path} != '${tempDir.path}/dir2'"
|
||||
"- path should be updated");
|
||||
newDir.path == "${tempDir.path}/dir2",
|
||||
"${newDir.path} != '${tempDir.path}/dir2'"
|
||||
"- path should be updated",
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -63,19 +65,24 @@ testRenameToExistingFile() async {
|
||||
Expect.fail('Directory.rename should fail to rename a non-directory');
|
||||
} on FileSystemException catch (e) {
|
||||
if (Platform.isWindows) {
|
||||
Expect.isTrue(e.osError!.message.contains('file already exists'),
|
||||
'Unexpected error: $e');
|
||||
Expect.isTrue(
|
||||
e.osError!.message.contains('file already exists'),
|
||||
'Unexpected error: $e',
|
||||
);
|
||||
} else if (Platform.isLinux || Platform.isMacOS) {
|
||||
Expect.isTrue(e.osError!.message.contains('Not a directory'),
|
||||
'Unexpected error: $e');
|
||||
Expect.isTrue(
|
||||
e.osError!.message.contains('Not a directory'),
|
||||
'Unexpected error: $e',
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
testRenameToExistingEmptyDirectory() async {
|
||||
await withTempDir('testRenameToExistingEmptyDirectory',
|
||||
(Directory tempDir) async {
|
||||
await withTempDir('testRenameToExistingEmptyDirectory', (
|
||||
Directory tempDir,
|
||||
) async {
|
||||
final dir1 = Directory("${tempDir.path}/dir1");
|
||||
dir1.createSync();
|
||||
File("${dir1.path}/file").createSync();
|
||||
@@ -88,8 +95,9 @@ testRenameToExistingEmptyDirectory() async {
|
||||
// Verify that the file contained in dir1 has been moved.
|
||||
if (Platform.isWindows) {
|
||||
Expect.fail(
|
||||
'Directory.rename should fail to rename over an existing directory '
|
||||
'on Windows');
|
||||
'Directory.rename should fail to rename over an existing directory '
|
||||
'on Windows',
|
||||
);
|
||||
} else {
|
||||
Expect.isTrue(File("${dir2.path}/file").existsSync());
|
||||
}
|
||||
@@ -104,8 +112,9 @@ testRenameToExistingEmptyDirectory() async {
|
||||
}
|
||||
|
||||
testRenameToExistingNonEmptyDirectory() async {
|
||||
await withTempDir('testRenameToExistingNonEmptyDirectory',
|
||||
(Directory tempDir) async {
|
||||
await withTempDir('testRenameToExistingNonEmptyDirectory', (
|
||||
Directory tempDir,
|
||||
) async {
|
||||
final dir1 = Directory("${tempDir.path}/dir1");
|
||||
dir1.createSync();
|
||||
File("${dir1.path}/file1").createSync();
|
||||
@@ -117,14 +126,19 @@ testRenameToExistingNonEmptyDirectory() async {
|
||||
try {
|
||||
dir1.renameSync(dir2.path);
|
||||
Expect.fail(
|
||||
'Directory.rename should fail to rename a non-empty directory');
|
||||
'Directory.rename should fail to rename a non-empty directory',
|
||||
);
|
||||
} on FileSystemException catch (e) {
|
||||
if (Platform.isWindows) {
|
||||
Expect.isTrue(e.osError!.message.contains('file already exists'),
|
||||
'Unexpected error: $e');
|
||||
Expect.isTrue(
|
||||
e.osError!.message.contains('file already exists'),
|
||||
'Unexpected error: $e',
|
||||
);
|
||||
} else if (Platform.isLinux || Platform.isMacOS) {
|
||||
Expect.isTrue(e.osError!.message.contains('Directory not empty'),
|
||||
'Unexpected error: $e');
|
||||
Expect.isTrue(
|
||||
e.osError!.message.contains('Directory not empty'),
|
||||
'Unexpected error: $e',
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -140,13 +154,19 @@ testRenameButActuallyFile() async {
|
||||
Expect.fail("Expected a failure to rename the file.");
|
||||
} on FileSystemException catch (e) {
|
||||
Expect.isTrue(
|
||||
e.message.contains('Rename failed'), 'Unexpected error: $e');
|
||||
e.message.contains('Rename failed'),
|
||||
'Unexpected error: $e',
|
||||
);
|
||||
if (Platform.isWindows) {
|
||||
Expect.isTrue(e.osError!.message.contains('cannot find the file'),
|
||||
'Unexpected error: $e');
|
||||
Expect.isTrue(
|
||||
e.osError!.message.contains('cannot find the file'),
|
||||
'Unexpected error: $e',
|
||||
);
|
||||
} else if (Platform.isLinux || Platform.isMacOS) {
|
||||
Expect.isTrue(e.osError!.message.contains('Not a directory'),
|
||||
'Unexpected error: $e');
|
||||
Expect.isTrue(
|
||||
e.osError!.message.contains('Not a directory'),
|
||||
'Unexpected error: $e',
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -15,8 +15,9 @@ class DirectoryTest {
|
||||
bool listedDir = false;
|
||||
bool listedFile = false;
|
||||
|
||||
Directory directory =
|
||||
Directory.systemTemp.createTempSync('dart_directory_test');
|
||||
Directory directory = Directory.systemTemp.createTempSync(
|
||||
'dart_directory_test',
|
||||
);
|
||||
Directory subDirectory = new Directory("${directory.path}/subdir");
|
||||
Expect.isTrue('$directory'.contains(directory.path));
|
||||
Expect.isFalse(subDirectory.existsSync());
|
||||
@@ -52,33 +53,40 @@ class DirectoryTest {
|
||||
testSyncListing(true);
|
||||
testSyncListing(false);
|
||||
Expect.equals(
|
||||
f.resolveSymbolicLinksSync(), fLong.resolveSymbolicLinksSync());
|
||||
f.resolveSymbolicLinksSync(),
|
||||
fLong.resolveSymbolicLinksSync(),
|
||||
);
|
||||
|
||||
asyncStart();
|
||||
directory.list(recursive: true).listen((FileSystemEntity entity) {
|
||||
if (entity is File) {
|
||||
var path = entity.path;
|
||||
listedFile = true;
|
||||
Expect.isTrue(path.contains(directory.path));
|
||||
Expect.isTrue(path.contains('subdir'));
|
||||
Expect.isTrue(path.contains('file.txt'));
|
||||
} else {
|
||||
var path = entity.path;
|
||||
Expect.isTrue(entity is Directory);
|
||||
listedDir = true;
|
||||
Expect.isTrue(path.contains(directory.path));
|
||||
Expect.isTrue(path.contains('subdir'));
|
||||
}
|
||||
}, onDone: () {
|
||||
Expect.isTrue(listedDir, "directory not found");
|
||||
Expect.isTrue(listedFile, "file not found");
|
||||
directory.delete(recursive: true).then((ignore) {
|
||||
f.exists().then((exists) => Expect.isFalse(exists));
|
||||
directory.exists().then((exists) => Expect.isFalse(exists));
|
||||
subDirectory.exists().then((exists) => Expect.isFalse(exists));
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
directory
|
||||
.list(recursive: true)
|
||||
.listen(
|
||||
(FileSystemEntity entity) {
|
||||
if (entity is File) {
|
||||
var path = entity.path;
|
||||
listedFile = true;
|
||||
Expect.isTrue(path.contains(directory.path));
|
||||
Expect.isTrue(path.contains('subdir'));
|
||||
Expect.isTrue(path.contains('file.txt'));
|
||||
} else {
|
||||
var path = entity.path;
|
||||
Expect.isTrue(entity is Directory);
|
||||
listedDir = true;
|
||||
Expect.isTrue(path.contains(directory.path));
|
||||
Expect.isTrue(path.contains('subdir'));
|
||||
}
|
||||
},
|
||||
onDone: () {
|
||||
Expect.isTrue(listedDir, "directory not found");
|
||||
Expect.isTrue(listedFile, "file not found");
|
||||
directory.delete(recursive: true).then((ignore) {
|
||||
f.exists().then((exists) => Expect.isFalse(exists));
|
||||
directory.exists().then((exists) => Expect.isFalse(exists));
|
||||
subDirectory.exists().then((exists) => Expect.isFalse(exists));
|
||||
asyncEnd();
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// Listing is asynchronous, so nothing should be listed at this
|
||||
// point.
|
||||
@@ -87,8 +95,9 @@ class DirectoryTest {
|
||||
}
|
||||
|
||||
static void testListingTailingPaths() {
|
||||
Directory directory =
|
||||
Directory.systemTemp.createTempSync('dart_directory_test');
|
||||
Directory directory = Directory.systemTemp.createTempSync(
|
||||
'dart_directory_test',
|
||||
);
|
||||
Directory subDirectory = new Directory("${directory.path}/subdir/");
|
||||
subDirectory.createSync();
|
||||
File f = new File('${subDirectory.path}/file.txt');
|
||||
@@ -100,18 +109,22 @@ class DirectoryTest {
|
||||
|
||||
subDirectory.listSync().forEach(test);
|
||||
|
||||
subDirectory.list().listen(test, onDone: () {
|
||||
directory.deleteSync(recursive: true);
|
||||
});
|
||||
subDirectory.list().listen(
|
||||
test,
|
||||
onDone: () {
|
||||
directory.deleteSync(recursive: true);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static void testListNonExistent() {
|
||||
setupListerHandlers(Stream<FileSystemEntity> stream) {
|
||||
stream.listen(
|
||||
(_) => Expect.fail("Listing of non-existing directory should fail"),
|
||||
onError: (error) {
|
||||
Expect.isTrue(error is FileSystemException);
|
||||
});
|
||||
(_) => Expect.fail("Listing of non-existing directory should fail"),
|
||||
onError: (error) {
|
||||
Expect.isTrue(error is FileSystemException);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Directory.systemTemp.createTemp('dart_directory').then((d) {
|
||||
@@ -128,15 +141,16 @@ class DirectoryTest {
|
||||
var errors = 0;
|
||||
setupListHandlers(Stream<FileSystemEntity> stream) {
|
||||
stream.listen(
|
||||
(_) => Expect.fail("Listing of non-existing directory should fail"),
|
||||
onError: (error) {
|
||||
Expect.isTrue(error is FileSystemException);
|
||||
if (++errors == 2) {
|
||||
d.delete(recursive: true).then((_) {
|
||||
asyncEnd();
|
||||
});
|
||||
}
|
||||
});
|
||||
(_) => Expect.fail("Listing of non-existing directory should fail"),
|
||||
onError: (error) {
|
||||
Expect.isTrue(error is FileSystemException);
|
||||
if (++errors == 2) {
|
||||
d.delete(recursive: true).then((_) {
|
||||
asyncEnd();
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
var subDirName = 'subdir';
|
||||
@@ -159,11 +173,13 @@ class DirectoryTest {
|
||||
static void testDeleteNonExistent() {
|
||||
// Test that deleting a non-existing directory fails.
|
||||
setupFutureHandlers(future) {
|
||||
future.then((ignore) {
|
||||
Expect.fail("Deletion of non-existing directory should fail");
|
||||
}).catchError((error) {
|
||||
Expect.isTrue(error is PathNotFoundException);
|
||||
});
|
||||
future
|
||||
.then((ignore) {
|
||||
Expect.fail("Deletion of non-existing directory should fail");
|
||||
})
|
||||
.catchError((error) {
|
||||
Expect.isTrue(error is PathNotFoundException);
|
||||
});
|
||||
}
|
||||
|
||||
Directory.systemTemp.createTemp('dart_directory').then((d) {
|
||||
@@ -221,15 +237,20 @@ class DirectoryTest {
|
||||
}
|
||||
var long = new Directory("${buffer.toString()}");
|
||||
// Works only on Windows.
|
||||
long.delete(recursive: true).then((_) {
|
||||
if (Platform.isWindows) {
|
||||
asyncEnd();
|
||||
}
|
||||
}, onError: ((_) {
|
||||
if (!Platform.isWindows) {
|
||||
asyncEnd();
|
||||
}
|
||||
}));
|
||||
long
|
||||
.delete(recursive: true)
|
||||
.then(
|
||||
(_) {
|
||||
if (Platform.isWindows) {
|
||||
asyncEnd();
|
||||
}
|
||||
},
|
||||
onError: ((_) {
|
||||
if (!Platform.isWindows) {
|
||||
asyncEnd();
|
||||
}
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -411,14 +432,19 @@ class DirectoryTest {
|
||||
l.createSync("${path}target");
|
||||
d.deleteSync();
|
||||
int count = 0;
|
||||
tmp.list(followLinks: true).listen((file) {
|
||||
count++;
|
||||
Expect.isTrue(file is Link);
|
||||
}, onDone: () {
|
||||
Expect.equals(1, count);
|
||||
l.deleteSync();
|
||||
tmp.deleteSync();
|
||||
});
|
||||
tmp
|
||||
.list(followLinks: true)
|
||||
.listen(
|
||||
(file) {
|
||||
count++;
|
||||
Expect.isTrue(file is Link);
|
||||
},
|
||||
onDone: () {
|
||||
Expect.equals(1, count);
|
||||
l.deleteSync();
|
||||
tmp.deleteSync();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static void testListLinkSync() {
|
||||
@@ -429,15 +455,20 @@ class DirectoryTest {
|
||||
Link l = new Link("${path}symlink");
|
||||
l.createSync("${path}target");
|
||||
int count = 0;
|
||||
tmp.list(followLinks: true).listen((file) {
|
||||
count++;
|
||||
Expect.isTrue(file is Directory);
|
||||
}, onDone: () {
|
||||
Expect.equals(2, count);
|
||||
l.deleteSync();
|
||||
d.deleteSync();
|
||||
tmp.deleteSync();
|
||||
});
|
||||
tmp
|
||||
.list(followLinks: true)
|
||||
.listen(
|
||||
(file) {
|
||||
count++;
|
||||
Expect.isTrue(file is Directory);
|
||||
},
|
||||
onDone: () {
|
||||
Expect.equals(2, count);
|
||||
l.deleteSync();
|
||||
d.deleteSync();
|
||||
tmp.deleteSync();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static void testCreateTemp() {
|
||||
@@ -445,8 +476,9 @@ class DirectoryTest {
|
||||
String template = 'dart_temp_dir';
|
||||
if (base.existsSync()) {
|
||||
asyncStart();
|
||||
Future.wait([base.createTemp(template), base.createTemp(template)])
|
||||
.then((tempDirs) {
|
||||
Future.wait([base.createTemp(template), base.createTemp(template)]).then((
|
||||
tempDirs,
|
||||
) {
|
||||
Expect.notEquals(tempDirs[0].path, tempDirs[1].path);
|
||||
for (Directory t in tempDirs) {
|
||||
Expect.isTrue(t.existsSync());
|
||||
@@ -463,7 +495,7 @@ class DirectoryTest {
|
||||
asyncStart();
|
||||
Future.wait([
|
||||
Directory.systemTemp.createTemp(template),
|
||||
Directory.systemTemp.createTemp(template)
|
||||
Directory.systemTemp.createTemp(template),
|
||||
]).then((tempDirs) {
|
||||
Expect.notEquals(tempDirs[0].path, tempDirs[1].path);
|
||||
for (Directory t in tempDirs) {
|
||||
@@ -589,8 +621,10 @@ String? illegalTempDirectoryLocation() {
|
||||
testCreateTempErrorSync() {
|
||||
var location = illegalTempDirectoryLocation();
|
||||
if (location != null) {
|
||||
Expect.throws(() => new Directory(location).createTempSync('dart_tempdir'),
|
||||
(e) => e is FileSystemException);
|
||||
Expect.throws(
|
||||
() => new Directory(location).createTempSync('dart_tempdir'),
|
||||
(e) => e is FileSystemException,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -647,7 +681,9 @@ testCreateDirExistingFileSync() {
|
||||
file.createSync();
|
||||
Expect.isTrue(file.existsSync());
|
||||
Expect.throws(
|
||||
new Directory(path).createSync, (e) => e is FileSystemException);
|
||||
new Directory(path).createSync,
|
||||
(e) => e is FileSystemException,
|
||||
);
|
||||
temp.deleteSync(recursive: true);
|
||||
}
|
||||
|
||||
@@ -659,14 +695,17 @@ testCreateDirExistingFile() {
|
||||
var file = new File(path);
|
||||
var subDir = new Directory(path);
|
||||
file.create().then((_) {
|
||||
subDir.create().then((_) {
|
||||
Expect.fail("dir create should fail on existing file");
|
||||
}).catchError((error) {
|
||||
Expect.isTrue(error is FileSystemException);
|
||||
temp.delete(recursive: true).then((_) {
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
subDir
|
||||
.create()
|
||||
.then((_) {
|
||||
Expect.fail("dir create should fail on existing file");
|
||||
})
|
||||
.catchError((error) {
|
||||
Expect.isTrue(error is FileSystemException);
|
||||
temp.delete(recursive: true).then((_) {
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,11 +19,13 @@ void testFromUri() {
|
||||
dir.createSync();
|
||||
Expect.isTrue(new Directory.fromUri(dirUri).existsSync());
|
||||
Expect.isTrue(
|
||||
new Directory.fromUri(Uri.base.resolveUri(dirUri)).existsSync());
|
||||
new Directory.fromUri(Uri.base.resolveUri(dirUri)).existsSync(),
|
||||
);
|
||||
Directory.current = temp.path;
|
||||
Expect.isTrue(new Directory.fromUri(Uri.parse('from_uri')).existsSync());
|
||||
Expect.isTrue(
|
||||
new Directory.fromUri(Uri.base.resolve('from_uri')).existsSync());
|
||||
new Directory.fromUri(Uri.base.resolve('from_uri')).existsSync(),
|
||||
);
|
||||
Directory.current = originalWorkingDirectory;
|
||||
dir.deleteSync();
|
||||
temp.deleteSync(recursive: true);
|
||||
@@ -32,12 +34,15 @@ void testFromUri() {
|
||||
}
|
||||
|
||||
void testFromUriUnsupported() {
|
||||
Expect.throwsUnsupportedError(() =>
|
||||
new Directory.fromUri(Uri.parse('http://localhost:8080/index.html')));
|
||||
Expect.throwsUnsupportedError(
|
||||
() => new Directory.fromUri(Uri.parse('ftp://localhost/tmp/xxx')));
|
||||
() => new Directory.fromUri(Uri.parse('http://localhost:8080/index.html')),
|
||||
);
|
||||
Expect.throwsUnsupportedError(
|
||||
() => new Directory.fromUri(Uri.parse('name#fragment')));
|
||||
() => new Directory.fromUri(Uri.parse('ftp://localhost/tmp/xxx')),
|
||||
);
|
||||
Expect.throwsUnsupportedError(
|
||||
() => new Directory.fromUri(Uri.parse('name#fragment')),
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
import "dart:io";
|
||||
import "dart:isolate";
|
||||
|
||||
final bool isAppJitTrainingRun =
|
||||
Platform.executableArguments.any((arg) => arg == '--snapshot-kind=app-jit');
|
||||
final bool isAppJitTrainingRun = Platform.executableArguments.any(
|
||||
(arg) => arg == '--snapshot-kind=app-jit',
|
||||
);
|
||||
|
||||
child(msg) {
|
||||
// This should work even though the parent isolate is blocked and won't
|
||||
|
||||
@@ -39,7 +39,7 @@ testWindows() {
|
||||
'c:/abd',
|
||||
'D:\\rf',
|
||||
'\\\\a_share\\folder',
|
||||
'\\\\?\\c:\\prefixed\path\\'
|
||||
'\\\\?\\c:\\prefixed\path\\',
|
||||
]) {
|
||||
Expect.isTrue(new File(absolute).absolute.path == absolute);
|
||||
Expect.isTrue(new File(absolute).absolute.isAbsolute);
|
||||
@@ -55,8 +55,10 @@ testPosix() {
|
||||
Expect.equals(new File(relative).absolute.path, '$current/$relative');
|
||||
}
|
||||
Expect.isTrue(new File(relative).absolute.isAbsolute);
|
||||
Expect.equals(new Directory(relative).absolute.path,
|
||||
new Link(relative).absolute.path);
|
||||
Expect.equals(
|
||||
new Directory(relative).absolute.path,
|
||||
new Link(relative).absolute.path,
|
||||
);
|
||||
Expect.isTrue(new File(relative).absolute is File);
|
||||
Expect.isTrue(new Directory(relative).absolute is Directory);
|
||||
Expect.isTrue(new Link(relative).absolute is Link);
|
||||
|
||||
@@ -21,8 +21,9 @@ import "package:path/path.dart";
|
||||
|
||||
// Check whether the file is locked or not.
|
||||
runPeer(String path, int len, FileLock mode) {
|
||||
var script =
|
||||
Platform.script.resolve('file_blocking_lock_script.dart').toFilePath();
|
||||
var script = Platform.script
|
||||
.resolve('file_blocking_lock_script.dart')
|
||||
.toFilePath();
|
||||
var arguments = <String>[]
|
||||
..addAll(Platform.executableArguments)
|
||||
..add(script)
|
||||
|
||||
@@ -83,30 +83,33 @@ void testCopy() {
|
||||
Expect.equals(FILE_CONTENT1, file1.readAsStringSync());
|
||||
|
||||
// Copy to new file works.
|
||||
file1.copy('${tmp.path}/file2').then((file2) {
|
||||
Expect.equals(FILE_CONTENT1, file1.readAsStringSync());
|
||||
Expect.equals(FILE_CONTENT1, file2.readAsStringSync());
|
||||
file1
|
||||
.copy('${tmp.path}/file2')
|
||||
.then((file2) {
|
||||
Expect.equals(FILE_CONTENT1, file1.readAsStringSync());
|
||||
Expect.equals(FILE_CONTENT1, file2.readAsStringSync());
|
||||
|
||||
// Override works for files.
|
||||
file2.writeAsStringSync(FILE_CONTENT2);
|
||||
return file2.copy(file1.path).then((_) {
|
||||
Expect.equals(FILE_CONTENT2, file1.readAsStringSync());
|
||||
Expect.equals(FILE_CONTENT2, file2.readAsStringSync());
|
||||
// Override works for files.
|
||||
file2.writeAsStringSync(FILE_CONTENT2);
|
||||
return file2.copy(file1.path).then((_) {
|
||||
Expect.equals(FILE_CONTENT2, file1.readAsStringSync());
|
||||
Expect.equals(FILE_CONTENT2, file2.readAsStringSync());
|
||||
|
||||
// Fail when coping to directory.
|
||||
var dir = new Directory('${tmp.path}/dir')..createSync();
|
||||
// Fail when coping to directory.
|
||||
var dir = new Directory('${tmp.path}/dir')..createSync();
|
||||
|
||||
return file1
|
||||
.copy(dir.path)
|
||||
.then((_) => Expect.fail('expected error'), onError: (_) {})
|
||||
.then((_) {
|
||||
Expect.equals(FILE_CONTENT2, file1.readAsStringSync());
|
||||
return file1
|
||||
.copy(dir.path)
|
||||
.then((_) => Expect.fail('expected error'), onError: (_) {})
|
||||
.then((_) {
|
||||
Expect.equals(FILE_CONTENT2, file1.readAsStringSync());
|
||||
});
|
||||
});
|
||||
})
|
||||
.whenComplete(() {
|
||||
tmp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
}).whenComplete(() {
|
||||
tmp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
@@ -31,7 +31,9 @@ testExclusiveCreate() async {
|
||||
Expect.equals(file, createdFile);
|
||||
Expect.isTrue(await createdFile.exists());
|
||||
Expect.throws(
|
||||
() => file.createSync(exclusive: true), (e) => e is FileSystemException);
|
||||
() => file.createSync(exclusive: true),
|
||||
(e) => e is FileSystemException,
|
||||
);
|
||||
bool createFailed = false;
|
||||
try {
|
||||
await file.create(exclusive: true);
|
||||
|
||||
@@ -21,7 +21,9 @@ testReadSyncBigInt() {
|
||||
var bigint = 9223372036854775807;
|
||||
var openedFile = file.openSync();
|
||||
Expect.throws(
|
||||
() => openedFile.readSync(bigint), (e) => e is FileSystemException);
|
||||
() => openedFile.readSync(bigint),
|
||||
(e) => e is FileSystemException,
|
||||
);
|
||||
openedFile.closeSync();
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -47,7 +47,9 @@ bool checkDeleteNonExistentFileSystemException(e) {
|
||||
|
||||
bool checkLengthNonExistentFileSystemException(e) {
|
||||
return checkNonExistentFileSystemException(
|
||||
e, "Cannot retrieve length of file");
|
||||
e,
|
||||
"Cannot retrieve length of file",
|
||||
);
|
||||
}
|
||||
|
||||
void testOpenBlankFilename() {
|
||||
@@ -72,7 +74,9 @@ void testOpenNonExistent() {
|
||||
|
||||
// Non-existing file should throw exception.
|
||||
Expect.throws(
|
||||
() => file.openSync(), (e) => checkOpenNonExistentFileSystemException(e));
|
||||
() => file.openSync(),
|
||||
(e) => checkOpenNonExistentFileSystemException(e),
|
||||
);
|
||||
|
||||
var openFuture = file.open(mode: FileMode.read);
|
||||
openFuture.then((raf) => Expect.fail("Unreachable code")).catchError((error) {
|
||||
@@ -89,8 +93,10 @@ void testDeleteNonExistent() {
|
||||
var file = new File("${temp.path}/nonExistentFile");
|
||||
|
||||
// Non-existing file should throw exception.
|
||||
Expect.throws(() => file.deleteSync(),
|
||||
(e) => checkDeleteNonExistentFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => file.deleteSync(),
|
||||
(e) => checkDeleteNonExistentFileSystemException(e),
|
||||
);
|
||||
|
||||
var delete = file.delete();
|
||||
delete.then((ignore) => Expect.fail("Unreachable code")).catchError((error) {
|
||||
@@ -107,8 +113,10 @@ void testLengthNonExistent() {
|
||||
var file = new File("${temp.path}/nonExistentFile");
|
||||
|
||||
// Non-existing file should throw exception.
|
||||
Expect.throws(() => file.lengthSync(),
|
||||
(e) => checkLengthNonExistentFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => file.lengthSync(),
|
||||
(e) => checkLengthNonExistentFileSystemException(e),
|
||||
);
|
||||
|
||||
var lenFuture = file.length();
|
||||
lenFuture.then((len) => Expect.fail("Unreachable code")).catchError((error) {
|
||||
@@ -140,8 +148,10 @@ void testCreateInNonExistentDirectory() {
|
||||
var file = new File("${temp.path}/nonExistentDirectory/newFile");
|
||||
|
||||
// Create in nonexistent directory should throw exception.
|
||||
Expect.throws(() => file.createSync(),
|
||||
(e) => checkCreateInNonExistentFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => file.createSync(),
|
||||
(e) => checkCreateInNonExistentFileSystemException(e),
|
||||
);
|
||||
|
||||
var create = file.create();
|
||||
create.then((ignore) => Expect.fail("Unreachable code")).catchError((error) {
|
||||
@@ -168,18 +178,20 @@ void testResolveSymbolicLinksOnNonExistentDirectory() {
|
||||
var file = new File("${temp.path}/nonExistentDirectory");
|
||||
|
||||
// Full path nonexistent directory should throw exception.
|
||||
Expect.throws(() => file.resolveSymbolicLinksSync(),
|
||||
(e) => checkResolveSymbolicLinksOnNonExistentFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => file.resolveSymbolicLinksSync(),
|
||||
(e) => checkResolveSymbolicLinksOnNonExistentFileSystemException(e),
|
||||
);
|
||||
|
||||
var resolvedFuture = file.resolveSymbolicLinks();
|
||||
resolvedFuture
|
||||
.then((path) => Expect.fail("Unreachable code $path"))
|
||||
.catchError((error) {
|
||||
checkResolveSymbolicLinksOnNonExistentFileSystemException(error);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
return file;
|
||||
});
|
||||
checkResolveSymbolicLinksOnNonExistentFileSystemException(error);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
return file;
|
||||
});
|
||||
}
|
||||
|
||||
void testReadAsBytesNonExistent() {
|
||||
@@ -188,13 +200,15 @@ void testReadAsBytesNonExistent() {
|
||||
var file = new File("${temp.path}/nonExistentFile3");
|
||||
|
||||
// Non-existing file should throw exception.
|
||||
Expect.throws(() => file.readAsBytesSync(),
|
||||
(e) => checkOpenNonExistentFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => file.readAsBytesSync(),
|
||||
(e) => checkOpenNonExistentFileSystemException(e),
|
||||
);
|
||||
|
||||
var readAsBytesFuture = file.readAsBytes();
|
||||
readAsBytesFuture
|
||||
.then((data) => Expect.fail("Unreachable code"))
|
||||
.catchError((error) {
|
||||
readAsBytesFuture.then((data) => Expect.fail("Unreachable code")).catchError((
|
||||
error,
|
||||
) {
|
||||
checkOpenNonExistentFileSystemException(error);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
@@ -208,18 +222,20 @@ void testReadAsTextNonExistent() {
|
||||
var file = new File("${temp.path}/nonExistentFile4");
|
||||
|
||||
// Non-existing file should throw exception.
|
||||
Expect.throws(() => file.readAsStringSync(),
|
||||
(e) => checkOpenNonExistentFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => file.readAsStringSync(),
|
||||
(e) => checkOpenNonExistentFileSystemException(e),
|
||||
);
|
||||
|
||||
var readAsStringFuture = file.readAsString(encoding: ascii);
|
||||
readAsStringFuture
|
||||
.then((data) => Expect.fail("Unreachable code"))
|
||||
.catchError((error) {
|
||||
checkOpenNonExistentFileSystemException(error);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
return file;
|
||||
});
|
||||
readAsStringFuture.then((data) => Expect.fail("Unreachable code")).catchError(
|
||||
(error) {
|
||||
checkOpenNonExistentFileSystemException(error);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
return file;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
testReadAsLinesNonExistent() {
|
||||
@@ -228,13 +244,15 @@ testReadAsLinesNonExistent() {
|
||||
var file = new File("${temp.path}/nonExistentFile5");
|
||||
|
||||
// Non-existing file should throw exception.
|
||||
Expect.throws(() => file.readAsLinesSync(),
|
||||
(e) => checkOpenNonExistentFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => file.readAsLinesSync(),
|
||||
(e) => checkOpenNonExistentFileSystemException(e),
|
||||
);
|
||||
|
||||
var readAsLinesFuture = file.readAsLines(encoding: ascii);
|
||||
readAsLinesFuture
|
||||
.then((data) => Expect.fail("Unreachable code"))
|
||||
.catchError((error) {
|
||||
readAsLinesFuture.then((data) => Expect.fail("Unreachable code")).catchError((
|
||||
error,
|
||||
) {
|
||||
checkOpenNonExistentFileSystemException(error);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
@@ -268,8 +286,10 @@ testWriteByteToReadOnlyFile() {
|
||||
var openedFile = file.openSync(mode: FileMode.read);
|
||||
|
||||
// Writing to read only file should throw an exception.
|
||||
Expect.throws(() => openedFile.writeByteSync(0),
|
||||
(e) => checkWriteReadOnlyFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => openedFile.writeByteSync(0),
|
||||
(e) => checkWriteReadOnlyFileSystemException(e),
|
||||
);
|
||||
|
||||
var writeByteFuture = openedFile.writeByte(0);
|
||||
writeByteFuture.catchError((error) {
|
||||
@@ -286,8 +306,10 @@ testWriteFromToReadOnlyFile() {
|
||||
|
||||
List<int> data = [0, 1, 2, 3];
|
||||
// Writing to read only file should throw an exception.
|
||||
Expect.throws(() => openedFile.writeFromSync(data, 0, data.length),
|
||||
(e) => checkWriteReadOnlyFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => openedFile.writeFromSync(data, 0, data.length),
|
||||
(e) => checkWriteReadOnlyFileSystemException(e),
|
||||
);
|
||||
|
||||
var writeFromFuture = openedFile.writeFrom(data, 0, data.length);
|
||||
writeFromFuture.catchError((error) {
|
||||
@@ -306,17 +328,19 @@ testTruncateReadOnlyFile() {
|
||||
openedFile = file.openSync(mode: FileMode.read);
|
||||
|
||||
// Truncating read only file should throw an exception.
|
||||
Expect.throws(() => openedFile.truncateSync(0),
|
||||
(e) => checkWriteReadOnlyFileSystemException(e));
|
||||
Expect.throws(
|
||||
() => openedFile.truncateSync(0),
|
||||
(e) => checkWriteReadOnlyFileSystemException(e),
|
||||
);
|
||||
|
||||
var truncateFuture = openedFile.truncate(0);
|
||||
truncateFuture
|
||||
.then((ignore) => Expect.fail("Unreachable code"))
|
||||
.catchError((error) {
|
||||
checkWriteReadOnlyFileSystemException(error);
|
||||
openedFile.close().then((_) => done());
|
||||
return openedFile;
|
||||
});
|
||||
truncateFuture.then((ignore) => Expect.fail("Unreachable code")).catchError(
|
||||
(error) {
|
||||
checkWriteReadOnlyFileSystemException(error);
|
||||
openedFile.close().then((_) => done());
|
||||
return openedFile;
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -334,25 +358,45 @@ testOperateOnClosedFile() {
|
||||
|
||||
List<int> data = [0, 1, 2, 3];
|
||||
Expect.throws(
|
||||
() => openedFile.readByteSync(), (e) => checkFileClosedException(e));
|
||||
() => openedFile.readByteSync(),
|
||||
(e) => checkFileClosedException(e),
|
||||
);
|
||||
Expect.throws(
|
||||
() => openedFile.writeByteSync(0), (e) => checkFileClosedException(e));
|
||||
Expect.throws(() => openedFile.writeFromSync(data, 0, data.length),
|
||||
(e) => checkFileClosedException(e));
|
||||
Expect.throws(() => openedFile.readIntoSync(data, 0, data.length),
|
||||
(e) => checkFileClosedException(e));
|
||||
Expect.throws(() => openedFile.writeStringSync("Hello"),
|
||||
(e) => checkFileClosedException(e));
|
||||
() => openedFile.writeByteSync(0),
|
||||
(e) => checkFileClosedException(e),
|
||||
);
|
||||
Expect.throws(
|
||||
() => openedFile.positionSync(), (e) => checkFileClosedException(e));
|
||||
Expect.throws(() => openedFile.setPositionSync(0),
|
||||
(e) => checkFileClosedException(e));
|
||||
() => openedFile.writeFromSync(data, 0, data.length),
|
||||
(e) => checkFileClosedException(e),
|
||||
);
|
||||
Expect.throws(
|
||||
() => openedFile.truncateSync(0), (e) => checkFileClosedException(e));
|
||||
() => openedFile.readIntoSync(data, 0, data.length),
|
||||
(e) => checkFileClosedException(e),
|
||||
);
|
||||
Expect.throws(
|
||||
() => openedFile.lengthSync(), (e) => checkFileClosedException(e));
|
||||
() => openedFile.writeStringSync("Hello"),
|
||||
(e) => checkFileClosedException(e),
|
||||
);
|
||||
Expect.throws(
|
||||
() => openedFile.flushSync(), (e) => checkFileClosedException(e));
|
||||
() => openedFile.positionSync(),
|
||||
(e) => checkFileClosedException(e),
|
||||
);
|
||||
Expect.throws(
|
||||
() => openedFile.setPositionSync(0),
|
||||
(e) => checkFileClosedException(e),
|
||||
);
|
||||
Expect.throws(
|
||||
() => openedFile.truncateSync(0),
|
||||
(e) => checkFileClosedException(e),
|
||||
);
|
||||
Expect.throws(
|
||||
() => openedFile.lengthSync(),
|
||||
(e) => checkFileClosedException(e),
|
||||
);
|
||||
Expect.throws(
|
||||
() => openedFile.flushSync(),
|
||||
(e) => checkFileClosedException(e),
|
||||
);
|
||||
|
||||
var errorCount = 0;
|
||||
|
||||
@@ -445,7 +489,9 @@ testReadSyncClosedFile() {
|
||||
var openedFile = file.openSync();
|
||||
openedFile.closeSync();
|
||||
Expect.throws(
|
||||
() => openedFile.readSync(1), (e) => e is FileSystemException);
|
||||
() => openedFile.readSync(1),
|
||||
(e) => e is FileSystemException,
|
||||
);
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -45,11 +45,13 @@ void testOpenStreamAsync() {
|
||||
// File contains "Hello Dart\nwassup!\n"
|
||||
var expected = "Hello Dart\nwassup!\n".codeUnits;
|
||||
var byteCount = 0;
|
||||
(new File(fileName)).openRead().listen((d) => byteCount += d.length,
|
||||
onDone: () {
|
||||
Expect.equals(expected.length, byteCount);
|
||||
asyncEnd();
|
||||
});
|
||||
(new File(fileName)).openRead().listen(
|
||||
(d) => byteCount += d.length,
|
||||
onDone: () {
|
||||
Expect.equals(expected.length, byteCount);
|
||||
asyncEnd();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Create a file that is big enough that a file stream will
|
||||
@@ -76,24 +78,28 @@ void testInputStreamTruncate() {
|
||||
// without getting all data.
|
||||
var streamedBytes = 0;
|
||||
var subscription;
|
||||
subscription = file.openRead().listen((d) {
|
||||
if (streamedBytes == 0) {
|
||||
subscription.pause();
|
||||
// Truncate the file by opening it for writing.
|
||||
file.open(mode: FileMode.write).then((opened) {
|
||||
opened.close().then((_) {
|
||||
Expect.equals(0, file.lengthSync());
|
||||
subscription.resume();
|
||||
subscription = file.openRead().listen(
|
||||
(d) {
|
||||
if (streamedBytes == 0) {
|
||||
subscription.pause();
|
||||
// Truncate the file by opening it for writing.
|
||||
file.open(mode: FileMode.write).then((opened) {
|
||||
opened.close().then((_) {
|
||||
Expect.equals(0, file.lengthSync());
|
||||
subscription.resume();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
streamedBytes += d.length;
|
||||
}, onDone: () {
|
||||
Expect.isTrue(streamedBytes > 0 && streamedBytes <= originalLength);
|
||||
temp.delete(recursive: true).then((_) => asyncEnd());
|
||||
}, onError: (e) {
|
||||
Expect.fail("Unexpected error");
|
||||
});
|
||||
}
|
||||
streamedBytes += d.length;
|
||||
},
|
||||
onDone: () {
|
||||
Expect.isTrue(streamedBytes > 0 && streamedBytes <= originalLength);
|
||||
temp.delete(recursive: true).then((_) => asyncEnd());
|
||||
},
|
||||
onError: (e) {
|
||||
Expect.fail("Unexpected error");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void testInputStreamDelete() {
|
||||
@@ -106,28 +112,35 @@ void testInputStreamDelete() {
|
||||
// without getting all data.
|
||||
var streamedBytes = 0;
|
||||
var subscription;
|
||||
subscription = file.openRead().listen((d) {
|
||||
if (streamedBytes == 0) {
|
||||
subscription.pause();
|
||||
// Delete the underlying file by opening it for writing.
|
||||
file.delete().then((deleted) {
|
||||
Expect.isFalse(deleted.existsSync());
|
||||
subscription.resume();
|
||||
}).catchError((e) {
|
||||
// On Windows, you cannot delete a file that is open
|
||||
// somewhere else. The stream has this file open
|
||||
// and therefore we get an error on deletion on Windows.
|
||||
Expect.equals('windows', Platform.operatingSystem);
|
||||
subscription.resume();
|
||||
});
|
||||
}
|
||||
streamedBytes += d.length;
|
||||
}, onDone: () {
|
||||
Expect.equals(originalLength, streamedBytes);
|
||||
temp.delete(recursive: true).then((_) => asyncEnd());
|
||||
}, onError: (e) {
|
||||
Expect.fail("Unexpected error");
|
||||
});
|
||||
subscription = file.openRead().listen(
|
||||
(d) {
|
||||
if (streamedBytes == 0) {
|
||||
subscription.pause();
|
||||
// Delete the underlying file by opening it for writing.
|
||||
file
|
||||
.delete()
|
||||
.then((deleted) {
|
||||
Expect.isFalse(deleted.existsSync());
|
||||
subscription.resume();
|
||||
})
|
||||
.catchError((e) {
|
||||
// On Windows, you cannot delete a file that is open
|
||||
// somewhere else. The stream has this file open
|
||||
// and therefore we get an error on deletion on Windows.
|
||||
Expect.equals('windows', Platform.operatingSystem);
|
||||
subscription.resume();
|
||||
});
|
||||
}
|
||||
streamedBytes += d.length;
|
||||
},
|
||||
onDone: () {
|
||||
Expect.equals(originalLength, streamedBytes);
|
||||
temp.delete(recursive: true).then((_) => asyncEnd());
|
||||
},
|
||||
onError: (e) {
|
||||
Expect.fail("Unexpected error");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void testInputStreamAppend() {
|
||||
@@ -139,24 +152,28 @@ void testInputStreamAppend() {
|
||||
// underlying file and check that the stream gets all the data.
|
||||
var streamedBytes = 0;
|
||||
var subscription;
|
||||
subscription = file.openRead().listen((d) {
|
||||
if (streamedBytes == 0) {
|
||||
subscription.pause();
|
||||
// Double the length of the underlying file.
|
||||
file.readAsBytes().then((bytes) {
|
||||
file.writeAsBytes(bytes, mode: FileMode.append).then((_) {
|
||||
Expect.equals(2 * originalLength, file.lengthSync());
|
||||
subscription.resume();
|
||||
subscription = file.openRead().listen(
|
||||
(d) {
|
||||
if (streamedBytes == 0) {
|
||||
subscription.pause();
|
||||
// Double the length of the underlying file.
|
||||
file.readAsBytes().then((bytes) {
|
||||
file.writeAsBytes(bytes, mode: FileMode.append).then((_) {
|
||||
Expect.equals(2 * originalLength, file.lengthSync());
|
||||
subscription.resume();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
streamedBytes += d.length;
|
||||
}, onDone: () {
|
||||
Expect.equals(2 * originalLength, streamedBytes);
|
||||
temp.delete(recursive: true).then((_) => asyncEnd());
|
||||
}, onError: (e) {
|
||||
Expect.fail("Unexpected error");
|
||||
});
|
||||
}
|
||||
streamedBytes += d.length;
|
||||
},
|
||||
onDone: () {
|
||||
Expect.equals(2 * originalLength, streamedBytes);
|
||||
temp.delete(recursive: true).then((_) => asyncEnd());
|
||||
},
|
||||
onError: (e) {
|
||||
Expect.fail("Unexpected error");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void testInputStreamOffset() {
|
||||
@@ -167,14 +184,20 @@ void testInputStreamOffset() {
|
||||
var originalLength = writeLongFileSync(file);
|
||||
var streamedBytes = 0;
|
||||
if (expectedBytes < 0) expectedBytes = originalLength + expectedBytes;
|
||||
file.openRead(start, end).listen((d) {
|
||||
streamedBytes += d.length;
|
||||
}, onDone: () {
|
||||
Expect.equals(expectedBytes, streamedBytes);
|
||||
temp.delete(recursive: true).then((_) => asyncEnd());
|
||||
}, onError: (e) {
|
||||
Expect.fail("Unexpected error");
|
||||
});
|
||||
file
|
||||
.openRead(start, end)
|
||||
.listen(
|
||||
(d) {
|
||||
streamedBytes += d.length;
|
||||
},
|
||||
onDone: () {
|
||||
Expect.equals(expectedBytes, streamedBytes);
|
||||
temp.delete(recursive: true).then((_) => asyncEnd());
|
||||
},
|
||||
onError: (e) {
|
||||
Expect.fail("Unexpected error");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
test(10, 20, 10);
|
||||
@@ -195,15 +218,21 @@ void testInputStreamBadOffset() {
|
||||
var originalLength = writeLongFileSync(file);
|
||||
var streamedBytes = 0;
|
||||
bool error = false;
|
||||
file.openRead(start, end).listen((d) {
|
||||
streamedBytes += d.length;
|
||||
}, onDone: () {
|
||||
Expect.isTrue(error);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
}, onError: (e) {
|
||||
error = true;
|
||||
});
|
||||
file
|
||||
.openRead(start, end)
|
||||
.listen(
|
||||
(d) {
|
||||
streamedBytes += d.length;
|
||||
},
|
||||
onDone: () {
|
||||
Expect.isTrue(error);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
},
|
||||
onError: (e) {
|
||||
error = true;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
test(-1, null);
|
||||
@@ -222,15 +251,18 @@ void testStringLineSplitterEnding(String name, int length) {
|
||||
.transform(utf8.decoder)
|
||||
.transform(new LineSplitter());
|
||||
int lineCount = 0;
|
||||
lineStream.listen((line) {
|
||||
lineCount++;
|
||||
Expect.isTrue(lineCount <= 10);
|
||||
if (line[0] != "#") {
|
||||
Expect.equals("Line $lineCount", line);
|
||||
}
|
||||
}, onDone: () {
|
||||
Expect.equals(10, lineCount);
|
||||
});
|
||||
lineStream.listen(
|
||||
(line) {
|
||||
lineCount++;
|
||||
Expect.isTrue(lineCount <= 10);
|
||||
if (line[0] != "#") {
|
||||
Expect.equals("Line $lineCount", line);
|
||||
}
|
||||
},
|
||||
onDone: () {
|
||||
Expect.equals(10, lineCount);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
@@ -94,11 +94,13 @@ class FileTest {
|
||||
var expected = [206, 187, 120, 46, 32, 120, 10];
|
||||
Expect.listEquals(expected, text.codeUnits);
|
||||
var readAsStringFuture = f.readAsString(encoding: ascii);
|
||||
readAsStringFuture.then((text) {
|
||||
Expect.fail("Non-ascii char should cause error");
|
||||
}).catchError((e) {
|
||||
asyncTestDone("testReadAsText");
|
||||
});
|
||||
readAsStringFuture
|
||||
.then((text) {
|
||||
Expect.fail("Non-ascii char should cause error");
|
||||
})
|
||||
.catchError((e) {
|
||||
asyncTestDone("testReadAsText");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -116,12 +118,15 @@ class FileTest {
|
||||
static testMain() {
|
||||
asyncStart();
|
||||
var outerZone = Zone.current;
|
||||
var firstZone = Zone.current.fork(specification: ZoneSpecification(
|
||||
var firstZone = Zone.current.fork(
|
||||
specification: ZoneSpecification(
|
||||
handleUncaughtError: (self, parent, zone, error, stacktrace) {
|
||||
asyncEnd();
|
||||
print("unittest-suite-success"); // For the test harness.
|
||||
exit(0);
|
||||
}));
|
||||
asyncEnd();
|
||||
print("unittest-suite-success"); // For the test harness.
|
||||
exit(0);
|
||||
},
|
||||
),
|
||||
);
|
||||
firstZone.run(() async {
|
||||
Expect.identical(firstZone, Zone.current);
|
||||
createTempDirectory(() {
|
||||
|
||||
@@ -23,8 +23,9 @@ check(String path, int start, int end, FileLock mode, {required bool locked}) {
|
||||
..add('$start')
|
||||
..add('$end');
|
||||
var stacktrace = StackTrace.current;
|
||||
return Process.run(Platform.executable, arguments)
|
||||
.then((ProcessResult result) {
|
||||
return Process.run(Platform.executable, arguments).then((
|
||||
ProcessResult result,
|
||||
) {
|
||||
if (result.exitCode != 0 || !result.stdout.contains(expected)) {
|
||||
print("Client failed, exit code ${result.exitCode}");
|
||||
print(" stdout:");
|
||||
@@ -40,13 +41,19 @@ check(String path, int start, int end, FileLock mode, {required bool locked}) {
|
||||
});
|
||||
}
|
||||
|
||||
checkLocked(String path,
|
||||
[int start = 0, int end = -1, FileLock mode = FileLock.exclusive]) =>
|
||||
check(path, start, end, mode, locked: true);
|
||||
checkLocked(
|
||||
String path, [
|
||||
int start = 0,
|
||||
int end = -1,
|
||||
FileLock mode = FileLock.exclusive,
|
||||
]) => check(path, start, end, mode, locked: true);
|
||||
|
||||
checkNotLocked(String path,
|
||||
[int start = 0, int end = -1, FileLock mode = FileLock.exclusive]) =>
|
||||
check(path, start, end, mode, locked: false);
|
||||
checkNotLocked(
|
||||
String path, [
|
||||
int start = 0,
|
||||
int end = -1,
|
||||
FileLock mode = FileLock.exclusive,
|
||||
]) => check(path, start, end, mode, locked: false);
|
||||
|
||||
void testLockWholeFile() {
|
||||
Directory directory = Directory.systemTemp.createTempSync('dart_file_lock');
|
||||
@@ -55,16 +62,18 @@ void testLockWholeFile() {
|
||||
var raf = file.openSync(mode: FileMode.write);
|
||||
raf.lockSync();
|
||||
asyncStart();
|
||||
checkLocked(file.path).then((_) {
|
||||
return checkLocked(file.path, 0, 2).then((_) {
|
||||
raf.unlockSync();
|
||||
return checkNotLocked(file.path).then((_) {});
|
||||
});
|
||||
}).whenComplete(() {
|
||||
raf.closeSync();
|
||||
directory.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
checkLocked(file.path)
|
||||
.then((_) {
|
||||
return checkLocked(file.path, 0, 2).then((_) {
|
||||
raf.unlockSync();
|
||||
return checkNotLocked(file.path).then((_) {});
|
||||
});
|
||||
})
|
||||
.whenComplete(() {
|
||||
raf.closeSync();
|
||||
directory.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
}
|
||||
|
||||
void testLockWholeFileAsync() {
|
||||
@@ -116,11 +125,13 @@ void testLockRange() {
|
||||
() => checkLocked(file.path, 6),
|
||||
() => checkNotLocked(file.path, 7),
|
||||
() => raf2.unlockSync(6, 7),
|
||||
() => checkNotLocked(file.path)
|
||||
() => checkNotLocked(file.path),
|
||||
]);
|
||||
} else {
|
||||
tests
|
||||
.addAll([() => raf2.unlockSync(5, 7), () => checkNotLocked(file.path)]);
|
||||
tests.addAll([
|
||||
() => raf2.unlockSync(5, 7),
|
||||
() => checkNotLocked(file.path),
|
||||
]);
|
||||
}
|
||||
Future.forEach<Function>(tests, (f) => f()).whenComplete(() {
|
||||
raf1.closeSync();
|
||||
@@ -160,7 +171,7 @@ void testLockRangeAsync() {
|
||||
() => checkLocked(file.path, 6),
|
||||
() => checkNotLocked(file.path, 7),
|
||||
() => raf2.unlock(6, 7),
|
||||
() => checkNotLocked(file.path)
|
||||
() => checkNotLocked(file.path),
|
||||
]);
|
||||
} else {
|
||||
tests.addAll([() => raf2.unlock(5, 7), () => checkNotLocked(file.path)]);
|
||||
@@ -188,7 +199,7 @@ void testLockEnd() {
|
||||
() => checkLocked(file.path, 10),
|
||||
() => checkLocked(file.path, 19),
|
||||
() => raf.unlockSync(2),
|
||||
() => checkNotLocked(file.path)
|
||||
() => checkNotLocked(file.path),
|
||||
], (f) => f()).whenComplete(() {
|
||||
raf.closeSync();
|
||||
directory.deleteSync(recursive: true);
|
||||
@@ -211,7 +222,7 @@ void testLockEndAsync() {
|
||||
() => checkLocked(file.path, 10),
|
||||
() => checkLocked(file.path, 19),
|
||||
() => raf.unlock(2),
|
||||
() => checkNotLocked(file.path)
|
||||
() => checkNotLocked(file.path),
|
||||
], (f) => f()).whenComplete(() {
|
||||
raf.closeSync();
|
||||
directory.deleteSync(recursive: true);
|
||||
@@ -229,7 +240,7 @@ void testLockShared() {
|
||||
() => raf.lock(FileLock.shared),
|
||||
() => checkLocked(file.path),
|
||||
() => checkLocked(file.path, 0, 2),
|
||||
() => checkNotLocked(file.path, 0, 2, FileLock.shared)
|
||||
() => checkNotLocked(file.path, 0, 2, FileLock.shared),
|
||||
], (f) => f()).then((_) {
|
||||
raf.closeSync();
|
||||
directory.deleteSync(recursive: true);
|
||||
@@ -247,7 +258,7 @@ void testLockSharedAsync() {
|
||||
() => raf.lock(FileLock.shared),
|
||||
() => checkLocked(file.path),
|
||||
() => checkLocked(file.path, 0, 2),
|
||||
() => checkNotLocked(file.path, 0, 2, FileLock.shared)
|
||||
() => checkNotLocked(file.path, 0, 2, FileLock.shared),
|
||||
], (f) => f()).whenComplete(() {
|
||||
raf.closeSync();
|
||||
directory.deleteSync(recursive: true);
|
||||
@@ -271,7 +282,7 @@ void testLockAfterLength() {
|
||||
() => checkLocked(file.path, 10),
|
||||
() => checkNotLocked(file.path, 15),
|
||||
() => raf.unlockSync(2, 15),
|
||||
() => checkNotLocked(file.path)
|
||||
() => checkNotLocked(file.path),
|
||||
], (f) => f()).whenComplete(() {
|
||||
raf.closeSync();
|
||||
directory.deleteSync(recursive: true);
|
||||
@@ -295,7 +306,7 @@ void testLockAfterLengthAsync() {
|
||||
() => checkLocked(file.path, 10),
|
||||
() => checkNotLocked(file.path, 15),
|
||||
() => raf.unlock(2, 15),
|
||||
() => checkNotLocked(file.path)
|
||||
() => checkNotLocked(file.path),
|
||||
], (f) => f()).whenComplete(() {
|
||||
raf.closeSync();
|
||||
directory.deleteSync(recursive: true);
|
||||
|
||||
@@ -99,11 +99,15 @@ void testFileStat(String dir) {
|
||||
|
||||
file.setLastModifiedSync(dateTime);
|
||||
Expect.notEquals(
|
||||
stat.modified.toString(), file.lastModifiedSync().toString());
|
||||
stat.modified.toString(),
|
||||
file.lastModifiedSync().toString(),
|
||||
);
|
||||
|
||||
file.setLastAccessedSync(dateTime);
|
||||
Expect.notEquals(
|
||||
stat.accessed.toString(), file.lastAccessedSync().toString());
|
||||
stat.accessed.toString(),
|
||||
file.lastAccessedSync().toString(),
|
||||
);
|
||||
}
|
||||
|
||||
String _createDirectoryHelper(String currentDir, String targetDir) {
|
||||
@@ -122,10 +126,14 @@ void testCreateLinkToDir(String dir, String dir2) {
|
||||
Expect.isTrue(linkPath.length > maxPath);
|
||||
Expect.isTrue(renamedPath.length > maxPath);
|
||||
|
||||
final targetDirectory1 =
|
||||
_createDirectoryHelper(dir, p.join(dir2, 'a_long_directory_target1'));
|
||||
final targetDirectory2 =
|
||||
_createDirectoryHelper(dir, p.join(dir2, 'a_long_directory_target2'));
|
||||
final targetDirectory1 = _createDirectoryHelper(
|
||||
dir,
|
||||
p.join(dir2, 'a_long_directory_target1'),
|
||||
);
|
||||
final targetDirectory2 = _createDirectoryHelper(
|
||||
dir,
|
||||
p.join(dir2, 'a_long_directory_target2'),
|
||||
);
|
||||
|
||||
final linkTarget1 = p.isRelative(dir2)
|
||||
? p.relative(targetDirectory1, from: p.dirname(p.absolute(linkPath)))
|
||||
@@ -140,8 +148,9 @@ void testCreateLinkToDir(String dir, String dir2) {
|
||||
Expect.isTrue(link.existsSync());
|
||||
final resolvedCreatePath = link.resolveSymbolicLinksSync();
|
||||
Expect.isTrue(
|
||||
FileSystemEntity.identicalSync(targetDirectory1, resolvedCreatePath),
|
||||
'${link.path} should resolve to $targetDirectory1 but resolved to $resolvedCreatePath');
|
||||
FileSystemEntity.identicalSync(targetDirectory1, resolvedCreatePath),
|
||||
'${link.path} should resolve to $targetDirectory1 but resolved to $resolvedCreatePath',
|
||||
);
|
||||
|
||||
// Rename link
|
||||
var renamedLink = link.renameSync(renamedPath);
|
||||
@@ -149,15 +158,17 @@ void testCreateLinkToDir(String dir, String dir2) {
|
||||
Expect.isFalse(link.existsSync());
|
||||
final resolvedRenamePath = renamedLink.resolveSymbolicLinksSync();
|
||||
Expect.isTrue(
|
||||
FileSystemEntity.identicalSync(targetDirectory1, resolvedRenamePath),
|
||||
'${link.path} should resolve to $targetDirectory1 but resolved to $resolvedRenamePath');
|
||||
FileSystemEntity.identicalSync(targetDirectory1, resolvedRenamePath),
|
||||
'${link.path} should resolve to $targetDirectory1 but resolved to $resolvedRenamePath',
|
||||
);
|
||||
|
||||
// Update link target
|
||||
renamedLink.updateSync(linkTarget2);
|
||||
final resolvedUpdatedPath = renamedLink.resolveSymbolicLinksSync();
|
||||
Expect.isTrue(
|
||||
FileSystemEntity.identicalSync(targetDirectory2, resolvedUpdatedPath),
|
||||
'${link.path} should resolve to $targetDirectory2 but resolved to $resolvedRenamePath');
|
||||
FileSystemEntity.identicalSync(targetDirectory2, resolvedUpdatedPath),
|
||||
'${link.path} should resolve to $targetDirectory2 but resolved to $resolvedRenamePath',
|
||||
);
|
||||
|
||||
Directory(targetDirectory1).deleteSync();
|
||||
Directory(targetDirectory2).deleteSync();
|
||||
@@ -194,8 +205,10 @@ void testCreateLinkToFile(String dir, String dir2) {
|
||||
|
||||
Expect.isTrue(link.existsSync());
|
||||
final resolvedPath = link.resolveSymbolicLinksSync();
|
||||
Expect.isTrue(FileSystemEntity.identicalSync(target, resolvedPath),
|
||||
'${link.path} should resolve to $target but resolved to $resolvedPath');
|
||||
Expect.isTrue(
|
||||
FileSystemEntity.identicalSync(target, resolvedPath),
|
||||
'${link.path} should resolve to $target but resolved to $resolvedPath',
|
||||
);
|
||||
|
||||
// Rename link
|
||||
var renamedLink = link.renameSync(p.join(dir, 'a_renamed_long_path_link'));
|
||||
|
||||
@@ -6,8 +6,9 @@ import "package:expect/expect.dart";
|
||||
import 'dart:io';
|
||||
|
||||
main() {
|
||||
Directory tempDir =
|
||||
Directory.systemTemp.createTempSync('dart_file_non_ascii_sync');
|
||||
Directory tempDir = Directory.systemTemp.createTempSync(
|
||||
'dart_file_non_ascii_sync',
|
||||
);
|
||||
Directory nonAsciiDir = new Directory('${tempDir.path}/æøå');
|
||||
nonAsciiDir.createSync();
|
||||
Expect.isTrue(nonAsciiDir.existsSync());
|
||||
@@ -26,7 +27,8 @@ main() {
|
||||
Expect.equals(6, nonAsciiFile.lengthSync());
|
||||
nonAsciiFile.lastModifiedSync();
|
||||
path = nonAsciiFile.resolveSymbolicLinksSync();
|
||||
Expect.isTrue(path.endsWith('${precomposed}.txt') ||
|
||||
path.endsWith('${decomposed}.txt'));
|
||||
Expect.isTrue(
|
||||
path.endsWith('${precomposed}.txt') || path.endsWith('${decomposed}.txt'),
|
||||
);
|
||||
tempDir.deleteSync(recursive: true);
|
||||
}
|
||||
|
||||
@@ -15,30 +15,38 @@ main() {
|
||||
var precomposed = 'æøå';
|
||||
var decomposed = new String.fromCharCodes([47, 230, 248, 97, 778]);
|
||||
|
||||
Directory.systemTemp.createTemp('dart_file_non_ascii').then((tempDir) {
|
||||
Directory nonAsciiDir = new Directory('${tempDir.path}/æøå');
|
||||
nonAsciiDir.create().then((nonAsciiDir) {
|
||||
nonAsciiDir.exists().then((result) {
|
||||
Expect.isTrue(result);
|
||||
File nonAsciiFile = new File('${nonAsciiDir.path}/æøå.txt');
|
||||
nonAsciiFile.writeAsString('æøå').then((_) {
|
||||
nonAsciiFile.exists().then((result) {
|
||||
Directory.systemTemp
|
||||
.createTemp('dart_file_non_ascii')
|
||||
.then((tempDir) {
|
||||
Directory nonAsciiDir = new Directory('${tempDir.path}/æøå');
|
||||
nonAsciiDir.create().then((nonAsciiDir) {
|
||||
nonAsciiDir.exists().then((result) {
|
||||
Expect.isTrue(result);
|
||||
nonAsciiFile.readAsString().then((contents) {
|
||||
// The contents of the file is precomposed utf8.
|
||||
Expect.equals(precomposed, contents);
|
||||
nonAsciiFile.create().then((_) {
|
||||
var d = nonAsciiFile.parent;
|
||||
Expect.isTrue(d.path.endsWith(precomposed) ||
|
||||
d.path.endsWith(decomposed));
|
||||
nonAsciiFile.length().then((length) {
|
||||
Expect.equals(6, length);
|
||||
nonAsciiFile.lastModified().then((_) {
|
||||
nonAsciiFile.resolveSymbolicLinks().then((path) {
|
||||
Expect.isTrue(path.endsWith('${precomposed}.txt') ||
|
||||
path.endsWith('${decomposed}.txt'));
|
||||
tempDir.delete(recursive: true).then((_) {
|
||||
asyncEnd();
|
||||
File nonAsciiFile = new File('${nonAsciiDir.path}/æøå.txt');
|
||||
nonAsciiFile.writeAsString('æøå').then((_) {
|
||||
nonAsciiFile.exists().then((result) {
|
||||
Expect.isTrue(result);
|
||||
nonAsciiFile.readAsString().then((contents) {
|
||||
// The contents of the file is precomposed utf8.
|
||||
Expect.equals(precomposed, contents);
|
||||
nonAsciiFile.create().then((_) {
|
||||
var d = nonAsciiFile.parent;
|
||||
Expect.isTrue(
|
||||
d.path.endsWith(precomposed) ||
|
||||
d.path.endsWith(decomposed),
|
||||
);
|
||||
nonAsciiFile.length().then((length) {
|
||||
Expect.equals(6, length);
|
||||
nonAsciiFile.lastModified().then((_) {
|
||||
nonAsciiFile.resolveSymbolicLinks().then((path) {
|
||||
Expect.isTrue(
|
||||
path.endsWith('${precomposed}.txt') ||
|
||||
path.endsWith('${decomposed}.txt'),
|
||||
);
|
||||
tempDir.delete(recursive: true).then((_) {
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -47,9 +55,8 @@ main() {
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
.catchError((e) {
|
||||
Expect.fail("File not found");
|
||||
});
|
||||
});
|
||||
}).catchError((e) {
|
||||
Expect.fail("File not found");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,8 +9,9 @@ import "package:expect/async_helper.dart";
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
void testOpenOutputStreamSync() {
|
||||
Directory tempDirectory =
|
||||
Directory.systemTemp.createTempSync('dart_file_output_stream');
|
||||
Directory tempDirectory = Directory.systemTemp.createTempSync(
|
||||
'dart_file_output_stream',
|
||||
);
|
||||
|
||||
asyncStart();
|
||||
String fileName = "${tempDirectory.path}/test";
|
||||
|
||||
@@ -17,12 +17,15 @@ void testReadAsString() {
|
||||
Expect.throws(file.readAsStringSync, (e) => e is FileSystemException);
|
||||
|
||||
asyncStart();
|
||||
file.readAsString().then((_) {
|
||||
Expect.fail("expected exception");
|
||||
}).catchError((e) {
|
||||
tmp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
}, test: (e) => e is FileSystemException);
|
||||
file
|
||||
.readAsString()
|
||||
.then((_) {
|
||||
Expect.fail("expected exception");
|
||||
})
|
||||
.catchError((e) {
|
||||
tmp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
}, test: (e) => e is FileSystemException);
|
||||
}
|
||||
|
||||
void testReadAsLines() {
|
||||
@@ -36,12 +39,15 @@ void testReadAsLines() {
|
||||
Expect.throws(file.readAsLinesSync, (e) => e is FileSystemException);
|
||||
|
||||
asyncStart();
|
||||
file.readAsLines().then((_) {
|
||||
Expect.fail("expected exception");
|
||||
}).catchError((e) {
|
||||
tmp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
}, test: (e) => e is FileSystemException);
|
||||
file
|
||||
.readAsLines()
|
||||
.then((_) {
|
||||
Expect.fail("expected exception");
|
||||
})
|
||||
.catchError((e) {
|
||||
tmp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
}, test: (e) => e is FileSystemException);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
@@ -14,7 +14,7 @@ void openAndWriteScript(String script) {
|
||||
var file = script; // Use script as file.
|
||||
Process.start("bash", [
|
||||
"-c",
|
||||
"$executable ${Platform.executableArguments.join(' ')} $script < $file"
|
||||
"$executable ${Platform.executableArguments.join(' ')} $script < $file",
|
||||
]).then((process) {
|
||||
process.exitCode.then((exitCode) {
|
||||
Expect.equals(0, exitCode);
|
||||
|
||||
@@ -44,9 +44,11 @@ void testStat() {
|
||||
Expect.equals(FileSystemEntityType.directory, directoryStatDirect.type);
|
||||
if (Platform.operatingSystem != 'windows') {
|
||||
Expect.isTrue(
|
||||
directoryStat.modified.compareTo(directoryStat.accessed) < 0);
|
||||
directoryStat.modified.compareTo(directoryStat.accessed) < 0,
|
||||
);
|
||||
Expect.isTrue(
|
||||
directoryStat.changed.compareTo(directoryStat.accessed) < 0);
|
||||
directoryStat.changed.compareTo(directoryStat.accessed) < 0,
|
||||
);
|
||||
}
|
||||
Expect.equals(7 << 6, directoryStat.mode & (7 << 6)); // Includes +urwx.
|
||||
|
||||
@@ -64,63 +66,87 @@ Future testStatAsync() {
|
||||
return Directory.systemTemp.createTemp('dart_file_stat').then((directory) {
|
||||
File file = new File(join(directory.path, "file"));
|
||||
return FileStat.stat(file.path)
|
||||
.then((fileStat) =>
|
||||
Expect.equals(FileSystemEntityType.notFound, fileStat.type))
|
||||
.then(
|
||||
(fileStat) =>
|
||||
Expect.equals(FileSystemEntityType.notFound, fileStat.type),
|
||||
)
|
||||
.then((_) => file.stat())
|
||||
.then((fileStat) =>
|
||||
Expect.equals(FileSystemEntityType.notFound, fileStat.type))
|
||||
.then(
|
||||
(fileStat) =>
|
||||
Expect.equals(FileSystemEntityType.notFound, fileStat.type),
|
||||
)
|
||||
.then((_) => file.writeAsString("Dart IO library test of FileStat"))
|
||||
.then((_) => new Future.delayed(const Duration(seconds: 2)))
|
||||
.then((_) => file.readAsString())
|
||||
.then((_) => directory.list().last)
|
||||
.then((_) => FileStat.stat(file.path))
|
||||
.then((FileStat fileStat) {
|
||||
Expect.equals(FileSystemEntityType.file, fileStat.type);
|
||||
Expect.equals(32, fileStat.size);
|
||||
if (Platform.operatingSystem != 'windows') {
|
||||
Expect.isTrue(fileStat.modified.compareTo(fileStat.accessed) < 0);
|
||||
Expect.isTrue(fileStat.changed.compareTo(fileStat.accessed) < 0);
|
||||
}
|
||||
Expect.equals(6 << 6, fileStat.mode & (6 << 6)); // Mode includes +urw.
|
||||
return file.stat();
|
||||
}).then((FileStat fileStat) {
|
||||
Expect.equals(FileSystemEntityType.file, fileStat.type);
|
||||
Expect.equals(32, fileStat.size);
|
||||
if (Platform.operatingSystem != 'windows') {
|
||||
Expect.isTrue(fileStat.modified.compareTo(fileStat.accessed) < 0);
|
||||
Expect.isTrue(fileStat.changed.compareTo(fileStat.accessed) < 0);
|
||||
}
|
||||
Expect.equals(6 << 6, fileStat.mode & (6 << 6)); // Mode includes +urw.
|
||||
return FileStat.stat(directory.path);
|
||||
}).then((FileStat directoryStat) {
|
||||
Expect.equals(FileSystemEntityType.directory, directoryStat.type);
|
||||
if (Platform.operatingSystem != 'windows') {
|
||||
Expect.isTrue(
|
||||
directoryStat.modified.compareTo(directoryStat.accessed) < 0);
|
||||
Expect.isTrue(
|
||||
directoryStat.changed.compareTo(directoryStat.accessed) < 0);
|
||||
}
|
||||
Expect.equals(7 << 6, directoryStat.mode & (7 << 6)); // Includes +urwx.
|
||||
return directory.stat();
|
||||
}).then((FileStat directoryStat) {
|
||||
Expect.equals(FileSystemEntityType.directory, directoryStat.type);
|
||||
if (Platform.operatingSystem != 'windows') {
|
||||
Expect.isTrue(
|
||||
directoryStat.modified.compareTo(directoryStat.accessed) < 0);
|
||||
Expect.isTrue(
|
||||
directoryStat.changed.compareTo(directoryStat.accessed) < 0);
|
||||
}
|
||||
Expect.equals(7 << 6, directoryStat.mode & (7 << 6)); // Includes +urwx.
|
||||
return new Link(directory.path).stat();
|
||||
}).then((FileStat linkStat) {
|
||||
Expect.equals(FileSystemEntityType.directory, linkStat.type);
|
||||
if (Platform.operatingSystem != 'windows') {
|
||||
Expect.isTrue(linkStat.modified.compareTo(linkStat.accessed) < 0);
|
||||
Expect.isTrue(linkStat.changed.compareTo(linkStat.accessed) < 0);
|
||||
}
|
||||
Expect.equals(7 << 6, linkStat.mode & (7 << 6)); // Includes +urwx.
|
||||
return directory.delete(recursive: true);
|
||||
});
|
||||
Expect.equals(FileSystemEntityType.file, fileStat.type);
|
||||
Expect.equals(32, fileStat.size);
|
||||
if (Platform.operatingSystem != 'windows') {
|
||||
Expect.isTrue(fileStat.modified.compareTo(fileStat.accessed) < 0);
|
||||
Expect.isTrue(fileStat.changed.compareTo(fileStat.accessed) < 0);
|
||||
}
|
||||
Expect.equals(
|
||||
6 << 6,
|
||||
fileStat.mode & (6 << 6),
|
||||
); // Mode includes +urw.
|
||||
return file.stat();
|
||||
})
|
||||
.then((FileStat fileStat) {
|
||||
Expect.equals(FileSystemEntityType.file, fileStat.type);
|
||||
Expect.equals(32, fileStat.size);
|
||||
if (Platform.operatingSystem != 'windows') {
|
||||
Expect.isTrue(fileStat.modified.compareTo(fileStat.accessed) < 0);
|
||||
Expect.isTrue(fileStat.changed.compareTo(fileStat.accessed) < 0);
|
||||
}
|
||||
Expect.equals(
|
||||
6 << 6,
|
||||
fileStat.mode & (6 << 6),
|
||||
); // Mode includes +urw.
|
||||
return FileStat.stat(directory.path);
|
||||
})
|
||||
.then((FileStat directoryStat) {
|
||||
Expect.equals(FileSystemEntityType.directory, directoryStat.type);
|
||||
if (Platform.operatingSystem != 'windows') {
|
||||
Expect.isTrue(
|
||||
directoryStat.modified.compareTo(directoryStat.accessed) < 0,
|
||||
);
|
||||
Expect.isTrue(
|
||||
directoryStat.changed.compareTo(directoryStat.accessed) < 0,
|
||||
);
|
||||
}
|
||||
Expect.equals(
|
||||
7 << 6,
|
||||
directoryStat.mode & (7 << 6),
|
||||
); // Includes +urwx.
|
||||
return directory.stat();
|
||||
})
|
||||
.then((FileStat directoryStat) {
|
||||
Expect.equals(FileSystemEntityType.directory, directoryStat.type);
|
||||
if (Platform.operatingSystem != 'windows') {
|
||||
Expect.isTrue(
|
||||
directoryStat.modified.compareTo(directoryStat.accessed) < 0,
|
||||
);
|
||||
Expect.isTrue(
|
||||
directoryStat.changed.compareTo(directoryStat.accessed) < 0,
|
||||
);
|
||||
}
|
||||
Expect.equals(
|
||||
7 << 6,
|
||||
directoryStat.mode & (7 << 6),
|
||||
); // Includes +urwx.
|
||||
return new Link(directory.path).stat();
|
||||
})
|
||||
.then((FileStat linkStat) {
|
||||
Expect.equals(FileSystemEntityType.directory, linkStat.type);
|
||||
if (Platform.operatingSystem != 'windows') {
|
||||
Expect.isTrue(linkStat.modified.compareTo(linkStat.accessed) < 0);
|
||||
Expect.isTrue(linkStat.changed.compareTo(linkStat.accessed) < 0);
|
||||
}
|
||||
Expect.equals(7 << 6, linkStat.mode & (7 << 6)); // Includes +urwx.
|
||||
return directory.delete(recursive: true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -12,29 +12,30 @@ void testPauseResumeCancelStream() {
|
||||
asyncStart();
|
||||
Directory.systemTemp.createTemp('dart_file_stream').then((d) {
|
||||
var file = new File("${d.path}/file");
|
||||
new File(Platform.executable)
|
||||
.openRead()
|
||||
.cast<List<int>>()
|
||||
.pipe(file.openWrite())
|
||||
.then((_) {
|
||||
new File(
|
||||
Platform.executable,
|
||||
).openRead().cast<List<int>>().pipe(file.openWrite()).then((_) {
|
||||
var subscription;
|
||||
subscription = file.openRead().listen((data) {
|
||||
subscription.pause();
|
||||
subscription.resume();
|
||||
void close() {
|
||||
d.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
}
|
||||
subscription = file.openRead().listen(
|
||||
(data) {
|
||||
subscription.pause();
|
||||
subscription.resume();
|
||||
void close() {
|
||||
d.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
}
|
||||
|
||||
var future = subscription.cancel();
|
||||
if (future != null) {
|
||||
future.whenComplete(close);
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
}, onDone: () {
|
||||
Expect.fail('the stream was canceled, onDone should not happen');
|
||||
});
|
||||
var future = subscription.cancel();
|
||||
if (future != null) {
|
||||
future.whenComplete(close);
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
},
|
||||
onDone: () {
|
||||
Expect.fail('the stream was canceled, onDone should not happen');
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -43,11 +44,9 @@ void testStreamIsEmpty() {
|
||||
asyncStart();
|
||||
Directory.systemTemp.createTemp('dart_file_stream').then((d) {
|
||||
var file = new File("${d.path}/file");
|
||||
new File(Platform.executable)
|
||||
.openRead()
|
||||
.cast<List<int>>()
|
||||
.pipe(file.openWrite())
|
||||
.then((_) {
|
||||
new File(
|
||||
Platform.executable,
|
||||
).openRead().cast<List<int>>().pipe(file.openWrite()).then((_) {
|
||||
// isEmpty will cancel the stream after first data event.
|
||||
file.openRead().isEmpty.then((empty) {
|
||||
Expect.isFalse(empty);
|
||||
|
||||
@@ -18,9 +18,10 @@ class FutureExpect {
|
||||
static Future listEquals(expected, Future result) =>
|
||||
result.then((value) => Expect.listEquals(expected, value));
|
||||
static Future throws(Future result) => result.then((value) {
|
||||
throw new ExpectException(
|
||||
"FutureExpect.throws received $value instead of an exception");
|
||||
}, onError: (_) => null);
|
||||
throw new ExpectException(
|
||||
"FutureExpect.throws received $value instead of an exception",
|
||||
);
|
||||
}, onError: (_) => null);
|
||||
}
|
||||
|
||||
Future testFileExistsCreate() {
|
||||
@@ -34,14 +35,30 @@ Future testFileExistsCreate() {
|
||||
.then((_) => FutureExpect.isFalse(new File(x).exists()))
|
||||
.then((_) => FutureExpect.isTrue(FileSystemEntity.isLink(y)))
|
||||
.then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
|
||||
.then((_) => FutureExpect.equals(
|
||||
FileSystemEntityType.notFound, FileSystemEntity.type(y)))
|
||||
.then((_) => FutureExpect.equals(
|
||||
FileSystemEntityType.notFound, FileSystemEntity.type(x)))
|
||||
.then((_) => FutureExpect.equals(FileSystemEntityType.link,
|
||||
FileSystemEntity.type(y, followLinks: false)))
|
||||
.then((_) => FutureExpect.equals(FileSystemEntityType.notFound,
|
||||
FileSystemEntity.type(x, followLinks: false)))
|
||||
.then(
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.notFound,
|
||||
FileSystemEntity.type(y),
|
||||
),
|
||||
)
|
||||
.then(
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.notFound,
|
||||
FileSystemEntity.type(x),
|
||||
),
|
||||
)
|
||||
.then(
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.link,
|
||||
FileSystemEntity.type(y, followLinks: false),
|
||||
),
|
||||
)
|
||||
.then(
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.notFound,
|
||||
FileSystemEntity.type(x, followLinks: false),
|
||||
),
|
||||
)
|
||||
.then((_) => FutureExpect.equals(x, new Link(y).target()))
|
||||
.then((_) => new File(y).create())
|
||||
.then((yFile) => Expect.equals(y, yFile.path))
|
||||
@@ -51,14 +68,30 @@ Future testFileExistsCreate() {
|
||||
.then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
|
||||
.then((_) => FutureExpect.isTrue(FileSystemEntity.isFile(y)))
|
||||
.then((_) => FutureExpect.isTrue(FileSystemEntity.isFile(x)))
|
||||
.then((_) => FutureExpect.equals(
|
||||
FileSystemEntityType.file, FileSystemEntity.type(y)))
|
||||
.then((_) => FutureExpect.equals(
|
||||
FileSystemEntityType.file, FileSystemEntity.type(x)))
|
||||
.then((_) => FutureExpect.equals(FileSystemEntityType.link,
|
||||
FileSystemEntity.type(y, followLinks: false)))
|
||||
.then((_) => FutureExpect.equals(FileSystemEntityType.file,
|
||||
FileSystemEntity.type(x, followLinks: false)))
|
||||
.then(
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.file,
|
||||
FileSystemEntity.type(y),
|
||||
),
|
||||
)
|
||||
.then(
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.file,
|
||||
FileSystemEntity.type(x),
|
||||
),
|
||||
)
|
||||
.then(
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.link,
|
||||
FileSystemEntity.type(y, followLinks: false),
|
||||
),
|
||||
)
|
||||
.then(
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.file,
|
||||
FileSystemEntity.type(x, followLinks: false),
|
||||
),
|
||||
)
|
||||
.then((_) => FutureExpect.equals(x, new Link(y).target()))
|
||||
.then((_) => new File(x).delete())
|
||||
.then((xDeletedFile) => Expect.equals(x, xDeletedFile.path))
|
||||
@@ -68,22 +101,46 @@ Future testFileExistsCreate() {
|
||||
.then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
|
||||
.then((_) => FutureExpect.isTrue(FileSystemEntity.isDirectory(y)))
|
||||
.then((_) => FutureExpect.isTrue(FileSystemEntity.isDirectory(x)))
|
||||
.then((_) => FutureExpect.equals(
|
||||
FileSystemEntityType.directory, FileSystemEntity.type(y)))
|
||||
.then((_) => FutureExpect.equals(
|
||||
FileSystemEntityType.directory, FileSystemEntity.type(x)))
|
||||
.then((_) => FutureExpect.equals(FileSystemEntityType.link,
|
||||
FileSystemEntity.type(y, followLinks: false)))
|
||||
.then((_) => FutureExpect.equals(FileSystemEntityType.directory,
|
||||
FileSystemEntity.type(x, followLinks: false)))
|
||||
.then(
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.directory,
|
||||
FileSystemEntity.type(y),
|
||||
),
|
||||
)
|
||||
.then(
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.directory,
|
||||
FileSystemEntity.type(x),
|
||||
),
|
||||
)
|
||||
.then(
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.link,
|
||||
FileSystemEntity.type(y, followLinks: false),
|
||||
),
|
||||
)
|
||||
.then(
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.directory,
|
||||
FileSystemEntity.type(x, followLinks: false),
|
||||
),
|
||||
)
|
||||
.then((_) => FutureExpect.equals(x, new Link(y).target()))
|
||||
.then((_) => new Link(y).delete())
|
||||
.then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(y)))
|
||||
.then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
|
||||
.then((_) => FutureExpect.equals(
|
||||
FileSystemEntityType.notFound, FileSystemEntity.type(y)))
|
||||
.then(
|
||||
(_) => FutureExpect.equals(FileSystemEntityType.directory, FileSystemEntity.type(x)))
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.notFound,
|
||||
FileSystemEntity.type(y),
|
||||
),
|
||||
)
|
||||
.then(
|
||||
(_) => FutureExpect.equals(
|
||||
FileSystemEntityType.directory,
|
||||
FileSystemEntity.type(x),
|
||||
),
|
||||
)
|
||||
.then((_) => FutureExpect.throws(new Link(y).target()))
|
||||
.then((_) => temp.delete(recursive: true));
|
||||
});
|
||||
@@ -119,8 +176,10 @@ Future testFileWriteRead() {
|
||||
return new File(x)
|
||||
.create()
|
||||
.then((_) => new Link(y).create(x))
|
||||
.then((_) =>
|
||||
(new File(y).openWrite(mode: FileMode.write)..add(data)).close())
|
||||
.then(
|
||||
(_) =>
|
||||
(new File(y).openWrite(mode: FileMode.write)..add(data)).close(),
|
||||
)
|
||||
.then((_) => FutureExpect.listEquals(data, new File(y).readAsBytes()))
|
||||
.then((_) => FutureExpect.listEquals(data, new File(x).readAsBytes()))
|
||||
.then((_) => temp.delete(recursive: true));
|
||||
@@ -142,9 +201,9 @@ Future testDirectoryExistsCreate() {
|
||||
|
||||
Future testDirectoryDelete() {
|
||||
return Directory.systemTemp.createTemp('dart_file_system_async').then((temp) {
|
||||
return Directory.systemTemp
|
||||
.createTemp('dart_file_system_async')
|
||||
.then((temp2) {
|
||||
return Directory.systemTemp.createTemp('dart_file_system_async').then((
|
||||
temp2,
|
||||
) {
|
||||
var y = '${temp.path}${Platform.pathSeparator}y';
|
||||
var x = '${temp2.path}${Platform.pathSeparator}x';
|
||||
var link = new Directory(y);
|
||||
@@ -170,25 +229,30 @@ Future testDirectoryDelete() {
|
||||
|
||||
Future testDirectoryListing() {
|
||||
return Directory.systemTemp.createTemp('dart_file_system_async').then((temp) {
|
||||
return Directory.systemTemp
|
||||
.createTemp('dart_file_system_async_links')
|
||||
.then((temp2) {
|
||||
var sep = Platform.pathSeparator;
|
||||
var y = '${temp.path}${sep}y';
|
||||
var x = '${temp2.path}${sep}x';
|
||||
return new File(x)
|
||||
.create()
|
||||
.then((_) => new Link(y).create(temp2.path))
|
||||
.then((_) =>
|
||||
temp.list(recursive: true).singleWhere((entry) => entry is File))
|
||||
.then((file) => Expect.isTrue(file.path.endsWith('$y${sep}x')))
|
||||
.then((_) => temp
|
||||
.list(recursive: true)
|
||||
.singleWhere((entry) => entry is Directory))
|
||||
.then((dir) => Expect.isTrue(dir.path.endsWith('y')))
|
||||
.then((_) => temp.delete(recursive: true))
|
||||
.then((_) => temp2.delete(recursive: true));
|
||||
});
|
||||
return Directory.systemTemp.createTemp('dart_file_system_async_links').then(
|
||||
(temp2) {
|
||||
var sep = Platform.pathSeparator;
|
||||
var y = '${temp.path}${sep}y';
|
||||
var x = '${temp2.path}${sep}x';
|
||||
return new File(x)
|
||||
.create()
|
||||
.then((_) => new Link(y).create(temp2.path))
|
||||
.then(
|
||||
(_) => temp
|
||||
.list(recursive: true)
|
||||
.singleWhere((entry) => entry is File),
|
||||
)
|
||||
.then((file) => Expect.isTrue(file.path.endsWith('$y${sep}x')))
|
||||
.then(
|
||||
(_) => temp
|
||||
.list(recursive: true)
|
||||
.singleWhere((entry) => entry is Directory),
|
||||
)
|
||||
.then((dir) => Expect.isTrue(dir.path.endsWith('y')))
|
||||
.then((_) => temp.delete(recursive: true))
|
||||
.then((_) => temp2.delete(recursive: true));
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -202,18 +266,20 @@ Future testDirectoryListingBrokenLink() {
|
||||
return new File(x)
|
||||
.create()
|
||||
.then((_) => new Link(link).create(doesNotExist))
|
||||
.then((_) => temp.list(recursive: true).forEach((entity) {
|
||||
if (entity is File) {
|
||||
Expect.isFalse(sawFile);
|
||||
sawFile = true;
|
||||
Expect.isTrue(entity.path.endsWith(x));
|
||||
} else {
|
||||
Expect.isTrue(entity is Link);
|
||||
Expect.isFalse(sawLink);
|
||||
sawLink = true;
|
||||
Expect.isTrue(entity.path.endsWith(link));
|
||||
}
|
||||
}))
|
||||
.then(
|
||||
(_) => temp.list(recursive: true).forEach((entity) {
|
||||
if (entity is File) {
|
||||
Expect.isFalse(sawFile);
|
||||
sawFile = true;
|
||||
Expect.isTrue(entity.path.endsWith(x));
|
||||
} else {
|
||||
Expect.isTrue(entity is Link);
|
||||
Expect.isFalse(sawLink);
|
||||
sawLink = true;
|
||||
Expect.isTrue(entity.path.endsWith(link));
|
||||
}
|
||||
}),
|
||||
)
|
||||
.then((_) => temp.delete(recursive: true));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,10 +22,14 @@ testFileExistsCreate() {
|
||||
Expect.isFalse(FileSystemEntity.isLinkSync(x));
|
||||
Expect.equals(FileSystemEntityType.notFound, FileSystemEntity.typeSync(y));
|
||||
Expect.equals(FileSystemEntityType.notFound, FileSystemEntity.typeSync(x));
|
||||
Expect.equals(FileSystemEntityType.link,
|
||||
FileSystemEntity.typeSync(y, followLinks: false));
|
||||
Expect.equals(FileSystemEntityType.notFound,
|
||||
FileSystemEntity.typeSync(x, followLinks: false));
|
||||
Expect.equals(
|
||||
FileSystemEntityType.link,
|
||||
FileSystemEntity.typeSync(y, followLinks: false),
|
||||
);
|
||||
Expect.equals(
|
||||
FileSystemEntityType.notFound,
|
||||
FileSystemEntity.typeSync(x, followLinks: false),
|
||||
);
|
||||
Expect.equals(x, new Link(y).targetSync());
|
||||
|
||||
new File(y).createSync();
|
||||
@@ -37,10 +41,14 @@ testFileExistsCreate() {
|
||||
Expect.isTrue(FileSystemEntity.isFileSync(x));
|
||||
Expect.equals(FileSystemEntityType.file, FileSystemEntity.typeSync(y));
|
||||
Expect.equals(FileSystemEntityType.file, FileSystemEntity.typeSync(x));
|
||||
Expect.equals(FileSystemEntityType.link,
|
||||
FileSystemEntity.typeSync(y, followLinks: false));
|
||||
Expect.equals(FileSystemEntityType.file,
|
||||
FileSystemEntity.typeSync(x, followLinks: false));
|
||||
Expect.equals(
|
||||
FileSystemEntityType.link,
|
||||
FileSystemEntity.typeSync(y, followLinks: false),
|
||||
);
|
||||
Expect.equals(
|
||||
FileSystemEntityType.file,
|
||||
FileSystemEntity.typeSync(x, followLinks: false),
|
||||
);
|
||||
Expect.equals(x, new Link(y).targetSync());
|
||||
|
||||
new File(x).deleteSync();
|
||||
@@ -51,10 +59,14 @@ testFileExistsCreate() {
|
||||
Expect.isTrue(FileSystemEntity.isDirectorySync(x));
|
||||
Expect.equals(FileSystemEntityType.directory, FileSystemEntity.typeSync(y));
|
||||
Expect.equals(FileSystemEntityType.directory, FileSystemEntity.typeSync(x));
|
||||
Expect.equals(FileSystemEntityType.link,
|
||||
FileSystemEntity.typeSync(y, followLinks: false));
|
||||
Expect.equals(FileSystemEntityType.directory,
|
||||
FileSystemEntity.typeSync(x, followLinks: false));
|
||||
Expect.equals(
|
||||
FileSystemEntityType.link,
|
||||
FileSystemEntity.typeSync(y, followLinks: false),
|
||||
);
|
||||
Expect.equals(
|
||||
FileSystemEntityType.directory,
|
||||
FileSystemEntity.typeSync(x, followLinks: false),
|
||||
);
|
||||
Expect.equals(x, new Link(y).targetSync());
|
||||
|
||||
new Link(y).deleteSync();
|
||||
@@ -171,22 +183,27 @@ testDirectoryListing() {
|
||||
|
||||
files = [];
|
||||
dirs = [];
|
||||
var lister = temp.list(recursive: true).listen((entity) {
|
||||
if (entity is File) {
|
||||
files.add(entity.path);
|
||||
} else {
|
||||
Expect.isTrue(entity is Directory);
|
||||
dirs.add(entity.path);
|
||||
}
|
||||
}, onDone: () {
|
||||
Expect.equals(1, files.length);
|
||||
Expect.isTrue(files[0].endsWith('$y${Platform.pathSeparator}x'));
|
||||
Expect.equals(1, dirs.length);
|
||||
Expect.isTrue(dirs[0].endsWith(y));
|
||||
temp.deleteSync(recursive: true);
|
||||
temp2.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
var lister = temp
|
||||
.list(recursive: true)
|
||||
.listen(
|
||||
(entity) {
|
||||
if (entity is File) {
|
||||
files.add(entity.path);
|
||||
} else {
|
||||
Expect.isTrue(entity is Directory);
|
||||
dirs.add(entity.path);
|
||||
}
|
||||
},
|
||||
onDone: () {
|
||||
Expect.equals(1, files.length);
|
||||
Expect.isTrue(files[0].endsWith('$y${Platform.pathSeparator}x'));
|
||||
Expect.equals(1, dirs.length);
|
||||
Expect.isTrue(dirs[0].endsWith(y));
|
||||
temp.deleteSync(recursive: true);
|
||||
temp2.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -203,28 +220,31 @@ testDirectoryListingBrokenLink() {
|
||||
var dirs = [];
|
||||
var links = [];
|
||||
var errors = [];
|
||||
temp.list(recursive: true).listen(
|
||||
(entity) {
|
||||
if (entity is File) {
|
||||
files.add(entity.path);
|
||||
} else if (entity is Link) {
|
||||
links.add(entity.path);
|
||||
} else {
|
||||
Expect.isTrue(entity is Directory);
|
||||
dirs.add(entity.path);
|
||||
}
|
||||
},
|
||||
onError: (e) => errors.add(e),
|
||||
onDone: () {
|
||||
Expect.equals(1, files.length);
|
||||
Expect.isTrue(files[0].endsWith(x));
|
||||
Expect.equals(1, links.length);
|
||||
Expect.isTrue(links[0].endsWith(link));
|
||||
Expect.equals(0, dirs.length);
|
||||
Expect.equals(0, errors.length);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
temp
|
||||
.list(recursive: true)
|
||||
.listen(
|
||||
(entity) {
|
||||
if (entity is File) {
|
||||
files.add(entity.path);
|
||||
} else if (entity is Link) {
|
||||
links.add(entity.path);
|
||||
} else {
|
||||
Expect.isTrue(entity is Directory);
|
||||
dirs.add(entity.path);
|
||||
}
|
||||
},
|
||||
onError: (e) => errors.add(e),
|
||||
onDone: () {
|
||||
Expect.equals(1, files.length);
|
||||
Expect.isTrue(files[0].endsWith(x));
|
||||
Expect.equals(1, links.length);
|
||||
Expect.isTrue(links[0].endsWith(link));
|
||||
Expect.equals(0, dirs.length);
|
||||
Expect.equals(0, errors.length);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -18,17 +18,20 @@ void testWatchCreateFile() {
|
||||
|
||||
asyncStart();
|
||||
var sub;
|
||||
sub = watcher.listen((event) {
|
||||
if (event is FileSystemCreateEvent && event.path.endsWith('file')) {
|
||||
Expect.isFalse(event.isDirectory);
|
||||
asyncEnd();
|
||||
sub.cancel();
|
||||
sub = watcher.listen(
|
||||
(event) {
|
||||
if (event is FileSystemCreateEvent && event.path.endsWith('file')) {
|
||||
Expect.isFalse(event.isDirectory);
|
||||
asyncEnd();
|
||||
sub.cancel();
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
},
|
||||
onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
}, onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
throw e;
|
||||
});
|
||||
throw e;
|
||||
},
|
||||
);
|
||||
|
||||
file.createSync();
|
||||
}
|
||||
@@ -41,17 +44,20 @@ void testWatchCreateDir() {
|
||||
|
||||
asyncStart();
|
||||
var sub;
|
||||
sub = watcher.listen((event) {
|
||||
if (event is FileSystemCreateEvent && event.path.endsWith('dir')) {
|
||||
Expect.isTrue(event.isDirectory);
|
||||
asyncEnd();
|
||||
sub.cancel();
|
||||
sub = watcher.listen(
|
||||
(event) {
|
||||
if (event is FileSystemCreateEvent && event.path.endsWith('dir')) {
|
||||
Expect.isTrue(event.isDirectory);
|
||||
asyncEnd();
|
||||
sub.cancel();
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
},
|
||||
onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
}, onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
throw e;
|
||||
});
|
||||
throw e;
|
||||
},
|
||||
);
|
||||
|
||||
subdir.createSync();
|
||||
}
|
||||
@@ -65,17 +71,20 @@ void testWatchModifyFile() {
|
||||
|
||||
asyncStart();
|
||||
var sub;
|
||||
sub = watcher.listen((event) {
|
||||
if (event is FileSystemModifyEvent) {
|
||||
Expect.isTrue(event.path.endsWith('file'));
|
||||
sub.cancel();
|
||||
asyncEnd();
|
||||
sub = watcher.listen(
|
||||
(event) {
|
||||
if (event is FileSystemModifyEvent) {
|
||||
Expect.isTrue(event.path.endsWith('file'));
|
||||
sub.cancel();
|
||||
asyncEnd();
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
},
|
||||
onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
}, onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
throw e;
|
||||
});
|
||||
throw e;
|
||||
},
|
||||
);
|
||||
|
||||
file.writeAsStringSync('a');
|
||||
}
|
||||
@@ -90,19 +99,22 @@ void testWatchTruncateFile() {
|
||||
|
||||
asyncStart();
|
||||
var sub;
|
||||
sub = watcher.listen((event) {
|
||||
if (event is FileSystemModifyEvent) {
|
||||
Expect.isTrue(event.path.endsWith('file'));
|
||||
Expect.isTrue(event.contentChanged);
|
||||
sub.cancel();
|
||||
asyncEnd();
|
||||
fileHandle.closeSync();
|
||||
sub = watcher.listen(
|
||||
(event) {
|
||||
if (event is FileSystemModifyEvent) {
|
||||
Expect.isTrue(event.path.endsWith('file'));
|
||||
Expect.isTrue(event.contentChanged);
|
||||
sub.cancel();
|
||||
asyncEnd();
|
||||
fileHandle.closeSync();
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
},
|
||||
onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
}, onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
throw e;
|
||||
});
|
||||
throw e;
|
||||
},
|
||||
);
|
||||
|
||||
fileHandle.truncateSync(1);
|
||||
}
|
||||
@@ -118,21 +130,24 @@ void testWatchMoveFile() {
|
||||
|
||||
asyncStart();
|
||||
var sub;
|
||||
sub = watcher.listen((event) {
|
||||
if (event is FileSystemMoveEvent) {
|
||||
Expect.isTrue(event.path.endsWith('file'));
|
||||
final destination = event.destination;
|
||||
if (destination != null) {
|
||||
Expect.isTrue(destination.endsWith('file2'));
|
||||
sub = watcher.listen(
|
||||
(event) {
|
||||
if (event is FileSystemMoveEvent) {
|
||||
Expect.isTrue(event.path.endsWith('file'));
|
||||
final destination = event.destination;
|
||||
if (destination != null) {
|
||||
Expect.isTrue(destination.endsWith('file2'));
|
||||
}
|
||||
sub.cancel();
|
||||
asyncEnd();
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
sub.cancel();
|
||||
asyncEnd();
|
||||
},
|
||||
onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
}, onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
throw e;
|
||||
});
|
||||
throw e;
|
||||
},
|
||||
);
|
||||
|
||||
file.renameSync(join(dir.path, 'file2'));
|
||||
}
|
||||
@@ -146,17 +161,20 @@ void testWatchDeleteFile() {
|
||||
|
||||
asyncStart();
|
||||
var sub;
|
||||
sub = watcher.listen((event) {
|
||||
if (event is FileSystemDeleteEvent) {
|
||||
Expect.isTrue(event.path.endsWith('file'));
|
||||
sub.cancel();
|
||||
asyncEnd();
|
||||
sub = watcher.listen(
|
||||
(event) {
|
||||
if (event is FileSystemDeleteEvent) {
|
||||
Expect.isTrue(event.path.endsWith('file'));
|
||||
sub.cancel();
|
||||
asyncEnd();
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
},
|
||||
onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
}, onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
throw e;
|
||||
});
|
||||
throw e;
|
||||
},
|
||||
);
|
||||
|
||||
file.deleteSync();
|
||||
}
|
||||
@@ -169,13 +187,16 @@ void testWatchDeleteDir() {
|
||||
var watcher = dir.watch(events: 0);
|
||||
|
||||
asyncStart();
|
||||
watcher.listen((event) {
|
||||
if (event is FileSystemDeleteEvent) {
|
||||
Expect.isTrue(event.path == dir.path);
|
||||
}
|
||||
}, onDone: () {
|
||||
asyncEnd();
|
||||
});
|
||||
watcher.listen(
|
||||
(event) {
|
||||
if (event is FileSystemDeleteEvent) {
|
||||
Expect.isTrue(event.path == dir.path);
|
||||
}
|
||||
},
|
||||
onDone: () {
|
||||
asyncEnd();
|
||||
},
|
||||
);
|
||||
|
||||
dir.deleteSync();
|
||||
}
|
||||
@@ -188,16 +209,19 @@ void testWatchOnlyModifyFile() {
|
||||
|
||||
asyncStart();
|
||||
var sub;
|
||||
sub = watcher.listen((event) {
|
||||
Expect.isTrue(event is FileSystemModifyEvent);
|
||||
Expect.isTrue(event.path.endsWith('file'));
|
||||
sub.cancel();
|
||||
asyncEnd();
|
||||
dir.deleteSync(recursive: true);
|
||||
}, onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
throw e;
|
||||
});
|
||||
sub = watcher.listen(
|
||||
(event) {
|
||||
Expect.isTrue(event is FileSystemModifyEvent);
|
||||
Expect.isTrue(event.path.endsWith('file'));
|
||||
sub.cancel();
|
||||
asyncEnd();
|
||||
dir.deleteSync(recursive: true);
|
||||
},
|
||||
onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
throw e;
|
||||
},
|
||||
);
|
||||
|
||||
file.createSync();
|
||||
file.writeAsStringSync('a');
|
||||
@@ -261,16 +285,19 @@ void testWatchRecursive() {
|
||||
|
||||
asyncStart();
|
||||
var sub;
|
||||
sub = watcher.listen((event) {
|
||||
if (event.path.endsWith('file')) {
|
||||
sub.cancel();
|
||||
asyncEnd();
|
||||
sub = watcher.listen(
|
||||
(event) {
|
||||
if (event.path.endsWith('file')) {
|
||||
sub.cancel();
|
||||
asyncEnd();
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
},
|
||||
onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
}
|
||||
}, onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
throw e;
|
||||
});
|
||||
throw e;
|
||||
},
|
||||
);
|
||||
|
||||
file.createSync();
|
||||
}
|
||||
@@ -285,14 +312,17 @@ void testWatchNonRecursive() {
|
||||
|
||||
asyncStart();
|
||||
var sub;
|
||||
sub = watcher.listen((event) {
|
||||
if (event.path.endsWith('file')) {
|
||||
throw "File change event not expected";
|
||||
}
|
||||
}, onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
throw e;
|
||||
});
|
||||
sub = watcher.listen(
|
||||
(event) {
|
||||
if (event.path.endsWith('file')) {
|
||||
throw "File change event not expected";
|
||||
}
|
||||
},
|
||||
onError: (e) {
|
||||
dir.deleteSync(recursive: true);
|
||||
throw e;
|
||||
},
|
||||
);
|
||||
|
||||
file.createSync();
|
||||
|
||||
@@ -307,12 +337,15 @@ void testWatchNonExisting() {
|
||||
// MacOS allows listening on non-existing paths.
|
||||
if (Platform.isMacOS) return;
|
||||
asyncStart();
|
||||
new Directory('__some_none_existing_dir__').watch().listen((_) {
|
||||
Expect.fail('unexpected error');
|
||||
}, onError: (e) {
|
||||
asyncEnd();
|
||||
Expect.isTrue(e is PathNotFoundException);
|
||||
});
|
||||
new Directory('__some_none_existing_dir__').watch().listen(
|
||||
(_) {
|
||||
Expect.fail('unexpected error');
|
||||
},
|
||||
onError: (e) {
|
||||
asyncEnd();
|
||||
Expect.isTrue(e is PathNotFoundException);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void testWatchMoveSelf() {
|
||||
@@ -326,16 +359,19 @@ void testWatchMoveSelf() {
|
||||
|
||||
asyncStart();
|
||||
bool gotDelete = false;
|
||||
watcher.listen((event) {
|
||||
if (event is FileSystemDeleteEvent) {
|
||||
Expect.isTrue(event.path.endsWith('dir'));
|
||||
gotDelete = true;
|
||||
}
|
||||
}, onDone: () {
|
||||
Expect.isTrue(gotDelete);
|
||||
dir.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
watcher.listen(
|
||||
(event) {
|
||||
if (event is FileSystemDeleteEvent) {
|
||||
Expect.isTrue(event.path.endsWith('dir'));
|
||||
gotDelete = true;
|
||||
}
|
||||
},
|
||||
onDone: () {
|
||||
Expect.isTrue(gotDelete);
|
||||
dir.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
},
|
||||
);
|
||||
|
||||
dir2.renameSync(join(dir.path, 'new_dir'));
|
||||
}
|
||||
@@ -386,8 +422,12 @@ testWatchConsistentModifiedFile() async {
|
||||
RawReceivePort errorReceivePort = RawReceivePort((object) {
|
||||
print('worker errored: $object');
|
||||
});
|
||||
Isolate isolate = await Isolate.spawn(modifyFiles, receivePort.sendPort,
|
||||
onExit: exitReceivePort.sendPort, onError: errorReceivePort.sendPort);
|
||||
Isolate isolate = await Isolate.spawn(
|
||||
modifyFiles,
|
||||
receivePort.sendPort,
|
||||
onExit: exitReceivePort.sendPort,
|
||||
onError: errorReceivePort.sendPort,
|
||||
);
|
||||
|
||||
await modificationEventReceived.future;
|
||||
workerSendPort.send('end');
|
||||
@@ -443,13 +483,17 @@ testWatchOverflow() async {
|
||||
ReceivePort receivePort = ReceivePort();
|
||||
Completer<bool> exiting = Completer<bool>();
|
||||
|
||||
Directory dir =
|
||||
Directory.systemTemp.createTempSync('dart_file_system_watcher');
|
||||
Directory dir = Directory.systemTemp.createTempSync(
|
||||
'dart_file_system_watcher',
|
||||
);
|
||||
var file = new File(join(dir.path, 'file'));
|
||||
file.createSync();
|
||||
|
||||
Isolate isolate =
|
||||
await Isolate.spawn(watcher, receivePort.sendPort, paused: true);
|
||||
Isolate isolate = await Isolate.spawn(
|
||||
watcher,
|
||||
receivePort.sendPort,
|
||||
paused: true,
|
||||
);
|
||||
|
||||
var subscription;
|
||||
subscription = receivePort.listen((object) async {
|
||||
@@ -476,14 +520,17 @@ testWatchOverflow() async {
|
||||
}
|
||||
|
||||
void watcher(SendPort sendPort) async {
|
||||
runZonedGuarded(() {
|
||||
var watcher = Directory.systemTemp.watch(recursive: true);
|
||||
watcher.listen((data) async {});
|
||||
sendPort.send('start');
|
||||
}, (error, stack) {
|
||||
print(error);
|
||||
sendPort.send('end');
|
||||
});
|
||||
runZonedGuarded(
|
||||
() {
|
||||
var watcher = Directory.systemTemp.watch(recursive: true);
|
||||
watcher.listen((data) async {});
|
||||
sendPort.send('start');
|
||||
},
|
||||
(error, stack) {
|
||||
print(error);
|
||||
sendPort.send('end');
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
@@ -1684,7 +1684,8 @@ class FileTest {
|
||||
}
|
||||
|
||||
static void testRename({required bool targetExists}) {
|
||||
lift(Function f) => (futureValue) => futureValue.then((value) => f(value));
|
||||
lift(Function f) =>
|
||||
(futureValue) => futureValue.then((value) => f(value));
|
||||
asyncTestStarted();
|
||||
|
||||
String source = join(tempDirectory.path, 'rename_${targetExists}_source');
|
||||
|
||||
@@ -18,26 +18,34 @@ void testWriteInt8ListAndView() {
|
||||
const int VIEW_LENGTH = 4;
|
||||
Int8List list = new Int8List(LIST_LENGTH);
|
||||
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
|
||||
var view =
|
||||
new Int8List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
|
||||
var view = new Int8List.view(
|
||||
list.buffer,
|
||||
OFFSET_IN_BYTES_FOR_VIEW,
|
||||
VIEW_LENGTH,
|
||||
);
|
||||
|
||||
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
|
||||
var file = new File("${temp.path}/test");
|
||||
file.open(mode: FileMode.write).then((raf) {
|
||||
return raf.writeFrom(list, 0, LIST_LENGTH);
|
||||
}).then((raf) {
|
||||
return raf.writeFrom(view, 0, VIEW_LENGTH);
|
||||
}).then((raf) {
|
||||
return raf.close();
|
||||
}).then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
Expect.listEquals(expected, content);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
file
|
||||
.open(mode: FileMode.write)
|
||||
.then((raf) {
|
||||
return raf.writeFrom(list, 0, LIST_LENGTH);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.writeFrom(view, 0, VIEW_LENGTH);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.close();
|
||||
})
|
||||
.then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
Expect.listEquals(expected, content);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -48,26 +56,34 @@ void testWriteUint8ListAndView() {
|
||||
const int VIEW_LENGTH = 4;
|
||||
Uint8List list = new Uint8List(LIST_LENGTH);
|
||||
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
|
||||
var view =
|
||||
new Uint8List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
|
||||
var view = new Uint8List.view(
|
||||
list.buffer,
|
||||
OFFSET_IN_BYTES_FOR_VIEW,
|
||||
VIEW_LENGTH,
|
||||
);
|
||||
|
||||
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
|
||||
var file = new File("${temp.path}/test");
|
||||
file.open(mode: FileMode.write).then((raf) {
|
||||
return raf.writeFrom(list, 0, LIST_LENGTH);
|
||||
}).then((raf) {
|
||||
return raf.writeFrom(view, 0, VIEW_LENGTH);
|
||||
}).then((raf) {
|
||||
return raf.close();
|
||||
}).then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
Expect.listEquals(expected, content);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
file
|
||||
.open(mode: FileMode.write)
|
||||
.then((raf) {
|
||||
return raf.writeFrom(list, 0, LIST_LENGTH);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.writeFrom(view, 0, VIEW_LENGTH);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.close();
|
||||
})
|
||||
.then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
Expect.listEquals(expected, content);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -79,25 +95,33 @@ void testWriteUint8ClampedListAndView() {
|
||||
Uint8ClampedList list = new Uint8ClampedList(LIST_LENGTH);
|
||||
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
|
||||
var view = new Uint8ClampedList.view(
|
||||
list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
|
||||
list.buffer,
|
||||
OFFSET_IN_BYTES_FOR_VIEW,
|
||||
VIEW_LENGTH,
|
||||
);
|
||||
|
||||
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
|
||||
var file = new File("${temp.path}/test");
|
||||
file.open(mode: FileMode.write).then((raf) {
|
||||
return raf.writeFrom(list, 0, LIST_LENGTH);
|
||||
}).then((raf) {
|
||||
return raf.writeFrom(view, 0, VIEW_LENGTH);
|
||||
}).then((raf) {
|
||||
return raf.close();
|
||||
}).then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
Expect.listEquals(expected, content);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
file
|
||||
.open(mode: FileMode.write)
|
||||
.then((raf) {
|
||||
return raf.writeFrom(list, 0, LIST_LENGTH);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.writeFrom(view, 0, VIEW_LENGTH);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.close();
|
||||
})
|
||||
.then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
Expect.listEquals(expected, content);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -110,36 +134,53 @@ void testWriteInt16ListAndView() {
|
||||
const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int16List.bytesPerElement;
|
||||
var list = new Int16List(LIST_LENGTH);
|
||||
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
|
||||
var view =
|
||||
new Int16List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
|
||||
var view = new Int16List.view(
|
||||
list.buffer,
|
||||
OFFSET_IN_BYTES_FOR_VIEW,
|
||||
VIEW_LENGTH,
|
||||
);
|
||||
|
||||
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
|
||||
var file = new File("${temp.path}/test");
|
||||
file.open(mode: FileMode.write).then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(list.buffer), 0, LIST_LENGTH_IN_BYTES);
|
||||
}).then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(
|
||||
view.buffer, view.offsetInBytes, view.lengthInBytes),
|
||||
0,
|
||||
VIEW_LENGTH_IN_BYTES);
|
||||
}).then((raf) {
|
||||
return raf.close();
|
||||
}).then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
var typed_data_content = new Uint8List(content.length);
|
||||
for (int i = 0; i < content.length; i++) {
|
||||
typed_data_content[i] = content[i];
|
||||
}
|
||||
Expect.listEquals(
|
||||
expected, new Int16List.view(typed_data_content.buffer));
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
file
|
||||
.open(mode: FileMode.write)
|
||||
.then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(list.buffer),
|
||||
0,
|
||||
LIST_LENGTH_IN_BYTES,
|
||||
);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(
|
||||
view.buffer,
|
||||
view.offsetInBytes,
|
||||
view.lengthInBytes,
|
||||
),
|
||||
0,
|
||||
VIEW_LENGTH_IN_BYTES,
|
||||
);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.close();
|
||||
})
|
||||
.then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
var typed_data_content = new Uint8List(content.length);
|
||||
for (int i = 0; i < content.length; i++) {
|
||||
typed_data_content[i] = content[i];
|
||||
}
|
||||
Expect.listEquals(
|
||||
expected,
|
||||
new Int16List.view(typed_data_content.buffer),
|
||||
);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -152,36 +193,53 @@ void testWriteUint16ListAndView() {
|
||||
const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Uint16List.bytesPerElement;
|
||||
var list = new Uint16List(LIST_LENGTH);
|
||||
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
|
||||
var view =
|
||||
new Uint16List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
|
||||
var view = new Uint16List.view(
|
||||
list.buffer,
|
||||
OFFSET_IN_BYTES_FOR_VIEW,
|
||||
VIEW_LENGTH,
|
||||
);
|
||||
|
||||
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
|
||||
var file = new File("${temp.path}/test");
|
||||
file.open(mode: FileMode.write).then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(list.buffer), 0, LIST_LENGTH_IN_BYTES);
|
||||
}).then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(
|
||||
view.buffer, view.offsetInBytes, view.lengthInBytes),
|
||||
0,
|
||||
VIEW_LENGTH_IN_BYTES);
|
||||
}).then((raf) {
|
||||
return raf.close();
|
||||
}).then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
var typed_data_content = new Uint8List(content.length);
|
||||
for (int i = 0; i < content.length; i++) {
|
||||
typed_data_content[i] = content[i];
|
||||
}
|
||||
Expect.listEquals(
|
||||
expected, new Uint16List.view(typed_data_content.buffer));
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
file
|
||||
.open(mode: FileMode.write)
|
||||
.then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(list.buffer),
|
||||
0,
|
||||
LIST_LENGTH_IN_BYTES,
|
||||
);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(
|
||||
view.buffer,
|
||||
view.offsetInBytes,
|
||||
view.lengthInBytes,
|
||||
),
|
||||
0,
|
||||
VIEW_LENGTH_IN_BYTES,
|
||||
);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.close();
|
||||
})
|
||||
.then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
var typed_data_content = new Uint8List(content.length);
|
||||
for (int i = 0; i < content.length; i++) {
|
||||
typed_data_content[i] = content[i];
|
||||
}
|
||||
Expect.listEquals(
|
||||
expected,
|
||||
new Uint16List.view(typed_data_content.buffer),
|
||||
);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -194,36 +252,53 @@ void testWriteInt32ListAndView() {
|
||||
const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int32List.bytesPerElement;
|
||||
var list = new Int32List(LIST_LENGTH);
|
||||
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
|
||||
var view =
|
||||
new Int32List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
|
||||
var view = new Int32List.view(
|
||||
list.buffer,
|
||||
OFFSET_IN_BYTES_FOR_VIEW,
|
||||
VIEW_LENGTH,
|
||||
);
|
||||
|
||||
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
|
||||
var file = new File("${temp.path}/test");
|
||||
file.open(mode: FileMode.write).then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(list.buffer), 0, LIST_LENGTH_IN_BYTES);
|
||||
}).then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(
|
||||
view.buffer, view.offsetInBytes, view.lengthInBytes),
|
||||
0,
|
||||
VIEW_LENGTH_IN_BYTES);
|
||||
}).then((raf) {
|
||||
return raf.close();
|
||||
}).then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
var typed_data_content = new Uint8List(content.length);
|
||||
for (int i = 0; i < content.length; i++) {
|
||||
typed_data_content[i] = content[i];
|
||||
}
|
||||
Expect.listEquals(
|
||||
expected, new Int32List.view(typed_data_content.buffer));
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
file
|
||||
.open(mode: FileMode.write)
|
||||
.then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(list.buffer),
|
||||
0,
|
||||
LIST_LENGTH_IN_BYTES,
|
||||
);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(
|
||||
view.buffer,
|
||||
view.offsetInBytes,
|
||||
view.lengthInBytes,
|
||||
),
|
||||
0,
|
||||
VIEW_LENGTH_IN_BYTES,
|
||||
);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.close();
|
||||
})
|
||||
.then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
var typed_data_content = new Uint8List(content.length);
|
||||
for (int i = 0; i < content.length; i++) {
|
||||
typed_data_content[i] = content[i];
|
||||
}
|
||||
Expect.listEquals(
|
||||
expected,
|
||||
new Int32List.view(typed_data_content.buffer),
|
||||
);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -236,36 +311,53 @@ void testWriteUint32ListAndView() {
|
||||
const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int32List.bytesPerElement;
|
||||
var list = new Uint32List(LIST_LENGTH);
|
||||
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
|
||||
var view =
|
||||
new Uint32List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
|
||||
var view = new Uint32List.view(
|
||||
list.buffer,
|
||||
OFFSET_IN_BYTES_FOR_VIEW,
|
||||
VIEW_LENGTH,
|
||||
);
|
||||
|
||||
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
|
||||
var file = new File("${temp.path}/test");
|
||||
file.open(mode: FileMode.write).then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(list.buffer), 0, LIST_LENGTH_IN_BYTES);
|
||||
}).then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(
|
||||
view.buffer, view.offsetInBytes, view.lengthInBytes),
|
||||
0,
|
||||
VIEW_LENGTH_IN_BYTES);
|
||||
}).then((raf) {
|
||||
return raf.close();
|
||||
}).then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
var typed_data_content = new Uint8List(content.length);
|
||||
for (int i = 0; i < content.length; i++) {
|
||||
typed_data_content[i] = content[i];
|
||||
}
|
||||
Expect.listEquals(
|
||||
expected, new Uint32List.view(typed_data_content.buffer));
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
file
|
||||
.open(mode: FileMode.write)
|
||||
.then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(list.buffer),
|
||||
0,
|
||||
LIST_LENGTH_IN_BYTES,
|
||||
);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(
|
||||
view.buffer,
|
||||
view.offsetInBytes,
|
||||
view.lengthInBytes,
|
||||
),
|
||||
0,
|
||||
VIEW_LENGTH_IN_BYTES,
|
||||
);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.close();
|
||||
})
|
||||
.then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
var typed_data_content = new Uint8List(content.length);
|
||||
for (int i = 0; i < content.length; i++) {
|
||||
typed_data_content[i] = content[i];
|
||||
}
|
||||
Expect.listEquals(
|
||||
expected,
|
||||
new Uint32List.view(typed_data_content.buffer),
|
||||
);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -278,36 +370,53 @@ void testWriteInt64ListAndView() {
|
||||
const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int64List.bytesPerElement;
|
||||
var list = new Int64List(LIST_LENGTH);
|
||||
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
|
||||
var view =
|
||||
new Int64List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
|
||||
var view = new Int64List.view(
|
||||
list.buffer,
|
||||
OFFSET_IN_BYTES_FOR_VIEW,
|
||||
VIEW_LENGTH,
|
||||
);
|
||||
|
||||
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
|
||||
var file = new File("${temp.path}/test");
|
||||
file.open(mode: FileMode.write).then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(list.buffer), 0, LIST_LENGTH_IN_BYTES);
|
||||
}).then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(
|
||||
view.buffer, view.offsetInBytes, view.lengthInBytes),
|
||||
0,
|
||||
VIEW_LENGTH_IN_BYTES);
|
||||
}).then((raf) {
|
||||
return raf.close();
|
||||
}).then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
var typed_data_content = new Uint8List(content.length);
|
||||
for (int i = 0; i < content.length; i++) {
|
||||
typed_data_content[i] = content[i];
|
||||
}
|
||||
Expect.listEquals(
|
||||
expected, new Int64List.view(typed_data_content.buffer));
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
file
|
||||
.open(mode: FileMode.write)
|
||||
.then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(list.buffer),
|
||||
0,
|
||||
LIST_LENGTH_IN_BYTES,
|
||||
);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(
|
||||
view.buffer,
|
||||
view.offsetInBytes,
|
||||
view.lengthInBytes,
|
||||
),
|
||||
0,
|
||||
VIEW_LENGTH_IN_BYTES,
|
||||
);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.close();
|
||||
})
|
||||
.then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
var typed_data_content = new Uint8List(content.length);
|
||||
for (int i = 0; i < content.length; i++) {
|
||||
typed_data_content[i] = content[i];
|
||||
}
|
||||
Expect.listEquals(
|
||||
expected,
|
||||
new Int64List.view(typed_data_content.buffer),
|
||||
);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -320,36 +429,53 @@ void testWriteUint64ListAndView() {
|
||||
const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Uint64List.bytesPerElement;
|
||||
var list = new Uint64List(LIST_LENGTH);
|
||||
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
|
||||
var view =
|
||||
new Uint64List.view(list.buffer, OFFSET_IN_BYTES_FOR_VIEW, VIEW_LENGTH);
|
||||
var view = new Uint64List.view(
|
||||
list.buffer,
|
||||
OFFSET_IN_BYTES_FOR_VIEW,
|
||||
VIEW_LENGTH,
|
||||
);
|
||||
|
||||
Directory.systemTemp.createTemp('dart_file_typed_data').then((temp) {
|
||||
var file = new File("${temp.path}/test");
|
||||
file.open(mode: FileMode.write).then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(list.buffer), 0, LIST_LENGTH_IN_BYTES);
|
||||
}).then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(
|
||||
view.buffer, view.offsetInBytes, view.lengthInBytes),
|
||||
0,
|
||||
VIEW_LENGTH_IN_BYTES);
|
||||
}).then((raf) {
|
||||
return raf.close();
|
||||
}).then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
var typed_data_content = new Uint8List(content.length);
|
||||
for (int i = 0; i < content.length; i++) {
|
||||
typed_data_content[i] = content[i];
|
||||
}
|
||||
Expect.listEquals(
|
||||
expected, new Uint64List.view(typed_data_content.buffer));
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
file
|
||||
.open(mode: FileMode.write)
|
||||
.then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(list.buffer),
|
||||
0,
|
||||
LIST_LENGTH_IN_BYTES,
|
||||
);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.writeFrom(
|
||||
new Uint8List.view(
|
||||
view.buffer,
|
||||
view.offsetInBytes,
|
||||
view.lengthInBytes,
|
||||
),
|
||||
0,
|
||||
VIEW_LENGTH_IN_BYTES,
|
||||
);
|
||||
})
|
||||
.then((raf) {
|
||||
return raf.close();
|
||||
})
|
||||
.then((_) {
|
||||
var expected = [];
|
||||
expected.addAll(list);
|
||||
expected.addAll(view);
|
||||
var content = file.readAsBytesSync();
|
||||
var typed_data_content = new Uint8List(content.length);
|
||||
for (int i = 0; i < content.length; i++) {
|
||||
typed_data_content[i] = content[i];
|
||||
}
|
||||
Expect.listEquals(
|
||||
expected,
|
||||
new Uint64List.view(typed_data_content.buffer),
|
||||
);
|
||||
temp.deleteSync(recursive: true);
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,14 @@ void testFromUri() {
|
||||
|
||||
void testFromUriUnsupported() {
|
||||
Expect.throwsUnsupportedError(
|
||||
() => new File.fromUri(Uri.parse('http://localhost:8080/index.html')));
|
||||
() => new File.fromUri(Uri.parse('http://localhost:8080/index.html')),
|
||||
);
|
||||
Expect.throwsUnsupportedError(
|
||||
() => new File.fromUri(Uri.parse('ftp://localhost/tmp/xxx')));
|
||||
() => new File.fromUri(Uri.parse('ftp://localhost/tmp/xxx')),
|
||||
);
|
||||
Expect.throwsUnsupportedError(
|
||||
() => new File.fromUri(Uri.parse('name#fragment')));
|
||||
() => new File.fromUri(Uri.parse('name#fragment')),
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
@@ -40,8 +40,10 @@ void testDriveLetterNoBackslash() {
|
||||
}
|
||||
}
|
||||
noBackslash += path.substring(3);
|
||||
Expect.equals("${Directory(noBackslash).statSync()}",
|
||||
"${Directory(path).statSync()}");
|
||||
Expect.equals(
|
||||
"${Directory(noBackslash).statSync()}",
|
||||
"${Directory(path).statSync()}",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,9 @@ testWriteAsBytesSync(dir) {
|
||||
}
|
||||
|
||||
void testWriteAsBytesOutsideOf0to256Sync(dir) {
|
||||
final f =
|
||||
new File('${dir.path}${Platform.pathSeparator}outside_bytes_sync.txt');
|
||||
final f = new File(
|
||||
'${dir.path}${Platform.pathSeparator}outside_bytes_sync.txt',
|
||||
);
|
||||
final data = [-256, -255, -1, 0, 255, 256];
|
||||
|
||||
f.writeAsBytesSync(data);
|
||||
|
||||
@@ -40,12 +40,16 @@ Future write(Directory dir) async {
|
||||
await raf.writeString('Hello');
|
||||
await raf.setPosition(0);
|
||||
await expectThrowsAsync(
|
||||
raf.readByte(), 'Read from write only file succeeded');
|
||||
raf.readByte(),
|
||||
'Read from write only file succeeded',
|
||||
);
|
||||
await raf.close();
|
||||
raf = await f.open(mode: FileMode.writeOnlyAppend);
|
||||
await raf.writeString('Hello');
|
||||
await expectThrowsAsync(
|
||||
raf.readByte(), 'Read from write only file succeeded');
|
||||
raf.readByte(),
|
||||
'Read from write only file succeeded',
|
||||
);
|
||||
await raf.setPosition(0);
|
||||
await raf.writeString('Hello');
|
||||
await raf.close();
|
||||
|
||||
@@ -16,7 +16,7 @@ const typeMapping = const {
|
||||
'FileMode': FileMode.read,
|
||||
'num': 0.50,
|
||||
'List<int>': const [1, 2, 3],
|
||||
'Map<String, int>': const {"a": 23}
|
||||
'Map<String, int>': const {"a": 23},
|
||||
};
|
||||
|
||||
typePermutations(int argCount) {
|
||||
@@ -52,7 +52,8 @@ doItSync(Function f) {
|
||||
// completion.
|
||||
Future doItAsync(FutureOr f()) {
|
||||
// Ignore value and errors.
|
||||
return new Future.delayed(Duration.zero, f)
|
||||
.catchError((_) {})
|
||||
.then((_) => true);
|
||||
return new Future.delayed(
|
||||
Duration.zero,
|
||||
f,
|
||||
).catchError((_) {}).then((_) => true);
|
||||
}
|
||||
|
||||
@@ -33,12 +33,15 @@ void test(responseBytes, bodyLength) async {
|
||||
server.listen(handleSocket);
|
||||
|
||||
var client = new HttpClient();
|
||||
var request =
|
||||
await client.getUrl(Uri.parse('http://127.0.0.1:${server.port}/'));
|
||||
var request = await client.getUrl(
|
||||
Uri.parse('http://127.0.0.1:${server.port}/'),
|
||||
);
|
||||
var response = await request.close();
|
||||
Expect.equals(response.statusCode, 200);
|
||||
Expect.equals(bodyLength,
|
||||
(await response.fold<List<int>>(<int>[], (p, e) => p..addAll(e))).length);
|
||||
Expect.equals(
|
||||
bodyLength,
|
||||
(await response.fold<List<int>>(<int>[], (p, e) => p..addAll(e))).length,
|
||||
);
|
||||
server.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,26 +17,29 @@ import "package:expect/expect.dart";
|
||||
// connection as there is no keep alive.
|
||||
void testHttp10NoKeepAlive() {
|
||||
HttpServer.bind("127.0.0.1", 0).then((server) {
|
||||
server.listen((HttpRequest request) {
|
||||
Expect.isNull(request.headers.value('content-length'));
|
||||
Expect.equals(-1, request.contentLength);
|
||||
var response = request.response;
|
||||
response.contentLength = 1;
|
||||
Expect.equals("1.0", request.protocolVersion);
|
||||
response.done
|
||||
.then((_) => Expect.fail("Unexpected response completion"))
|
||||
.catchError((error) => Expect.isTrue(error is HttpException));
|
||||
response.write("Z");
|
||||
response.write("Z");
|
||||
response.close();
|
||||
Expect.throws(() {
|
||||
response.write("x");
|
||||
}, (e) => e is StateError);
|
||||
}, onError: (e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
});
|
||||
server.listen(
|
||||
(HttpRequest request) {
|
||||
Expect.isNull(request.headers.value('content-length'));
|
||||
Expect.equals(-1, request.contentLength);
|
||||
var response = request.response;
|
||||
response.contentLength = 1;
|
||||
Expect.equals("1.0", request.protocolVersion);
|
||||
response.done
|
||||
.then((_) => Expect.fail("Unexpected response completion"))
|
||||
.catchError((error) => Expect.isTrue(error is HttpException));
|
||||
response.write("Z");
|
||||
response.write("Z");
|
||||
response.close();
|
||||
Expect.throws(() {
|
||||
response.write("x");
|
||||
}, (e) => e is StateError);
|
||||
},
|
||||
onError: (e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
},
|
||||
);
|
||||
|
||||
int count = 0;
|
||||
makeRequest() {
|
||||
@@ -44,17 +47,20 @@ void testHttp10NoKeepAlive() {
|
||||
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.equals(-1, s.indexOf("keep-alive"));
|
||||
if (count < 10) {
|
||||
makeRequest();
|
||||
} else {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
socket.listen(
|
||||
response.addAll,
|
||||
onDone: () {
|
||||
count++;
|
||||
socket.destroy();
|
||||
String s = new String.fromCharCodes(response).toLowerCase();
|
||||
Expect.equals(-1, s.indexOf("keep-alive"));
|
||||
if (count < 10) {
|
||||
makeRequest();
|
||||
} else {
|
||||
server.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -67,20 +73,26 @@ void testHttp10NoKeepAlive() {
|
||||
// the response.
|
||||
void testHttp10ServerClose() {
|
||||
HttpServer.bind("127.0.0.1", 0).then((server) {
|
||||
server.listen((HttpRequest request) {
|
||||
Expect.isNull(request.headers.value('content-length'));
|
||||
Expect.equals(-1, request.contentLength);
|
||||
request.listen((_) {}, onDone: () {
|
||||
var response = request.response;
|
||||
Expect.equals("1.0", request.protocolVersion);
|
||||
response.write("Z");
|
||||
response.close();
|
||||
});
|
||||
}, onError: (e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
});
|
||||
server.listen(
|
||||
(HttpRequest request) {
|
||||
Expect.isNull(request.headers.value('content-length'));
|
||||
Expect.equals(-1, request.contentLength);
|
||||
request.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
var response = request.response;
|
||||
Expect.equals("1.0", request.protocolVersion);
|
||||
response.write("Z");
|
||||
response.close();
|
||||
},
|
||||
);
|
||||
},
|
||||
onError: (e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
},
|
||||
);
|
||||
|
||||
int count = 0;
|
||||
makeRequest() {
|
||||
@@ -89,21 +101,23 @@ void testHttp10ServerClose() {
|
||||
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.equals("z", s[s.length - 1]);
|
||||
Expect.equals(-1, s.indexOf("content-length:"));
|
||||
Expect.equals(-1, s.indexOf("keep-alive"));
|
||||
if (count < 10) {
|
||||
makeRequest();
|
||||
} else {
|
||||
server.close();
|
||||
}
|
||||
},
|
||||
onError: (e) => print(e));
|
||||
socket.listen(
|
||||
response.addAll,
|
||||
onDone: () {
|
||||
socket.destroy();
|
||||
count++;
|
||||
String s = new String.fromCharCodes(response).toLowerCase();
|
||||
Expect.equals("z", s[s.length - 1]);
|
||||
Expect.equals(-1, s.indexOf("content-length:"));
|
||||
Expect.equals(-1, s.indexOf("keep-alive"));
|
||||
if (count < 10) {
|
||||
makeRequest();
|
||||
} else {
|
||||
server.close();
|
||||
}
|
||||
},
|
||||
onError: (e) => print(e),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -116,20 +130,23 @@ void testHttp10ServerClose() {
|
||||
// used.
|
||||
void testHttp10KeepAlive() {
|
||||
HttpServer.bind("127.0.0.1", 0).then((server) {
|
||||
server.listen((HttpRequest request) {
|
||||
Expect.isNull(request.headers.value('content-length'));
|
||||
Expect.equals(-1, request.contentLength);
|
||||
var response = request.response;
|
||||
response.contentLength = 1;
|
||||
response.persistentConnection = true;
|
||||
Expect.equals("1.0", request.protocolVersion);
|
||||
response.write("Z");
|
||||
response.close();
|
||||
}, onError: (e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
});
|
||||
server.listen(
|
||||
(HttpRequest request) {
|
||||
Expect.isNull(request.headers.value('content-length'));
|
||||
Expect.equals(-1, request.contentLength);
|
||||
var response = request.response;
|
||||
response.contentLength = 1;
|
||||
response.persistentConnection = true;
|
||||
Expect.equals("1.0", request.protocolVersion);
|
||||
response.write("Z");
|
||||
response.close();
|
||||
},
|
||||
onError: (e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
},
|
||||
);
|
||||
|
||||
Socket.connect("127.0.0.1", server.port).then((socket) {
|
||||
void sendRequest() {
|
||||
@@ -139,24 +156,27 @@ void testHttp10KeepAlive() {
|
||||
|
||||
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.isTrue(s.indexOf("\r\nconnection: keep-alive\r\n") > 0);
|
||||
Expect.isTrue(s.indexOf("\r\ncontent-length: 1\r\n") > 0);
|
||||
count++;
|
||||
if (count < 10) {
|
||||
response = [];
|
||||
sendRequest();
|
||||
} else {
|
||||
socket.close();
|
||||
socket.listen(
|
||||
(d) {
|
||||
response.addAll(d);
|
||||
if (response[response.length - 1] == "Z".codeUnitAt(0)) {
|
||||
String s = new String.fromCharCodes(response).toLowerCase();
|
||||
Expect.isTrue(s.indexOf("\r\nconnection: keep-alive\r\n") > 0);
|
||||
Expect.isTrue(s.indexOf("\r\ncontent-length: 1\r\n") > 0);
|
||||
count++;
|
||||
if (count < 10) {
|
||||
response = [];
|
||||
sendRequest();
|
||||
} else {
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, onDone: () {
|
||||
socket.destroy();
|
||||
server.close();
|
||||
});
|
||||
},
|
||||
onDone: () {
|
||||
socket.destroy();
|
||||
server.close();
|
||||
},
|
||||
);
|
||||
sendRequest();
|
||||
});
|
||||
});
|
||||
@@ -167,18 +187,21 @@ void testHttp10KeepAlive() {
|
||||
// keep alive.
|
||||
void testHttp10KeepAliveServerCloses() {
|
||||
HttpServer.bind("127.0.0.1", 0).then((server) {
|
||||
server.listen((HttpRequest request) {
|
||||
Expect.isNull(request.headers.value('content-length'));
|
||||
Expect.equals(-1, request.contentLength);
|
||||
var response = request.response;
|
||||
Expect.equals("1.0", request.protocolVersion);
|
||||
response.write("Z");
|
||||
response.close();
|
||||
}, onError: (e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
});
|
||||
server.listen(
|
||||
(HttpRequest request) {
|
||||
Expect.isNull(request.headers.value('content-length'));
|
||||
Expect.equals(-1, request.contentLength);
|
||||
var response = request.response;
|
||||
Expect.equals("1.0", request.protocolVersion);
|
||||
response.write("Z");
|
||||
response.close();
|
||||
},
|
||||
onError: (e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
},
|
||||
);
|
||||
|
||||
int count = 0;
|
||||
makeRequest() {
|
||||
@@ -187,19 +210,22 @@ void testHttp10KeepAliveServerCloses() {
|
||||
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.equals("z", s[s.length - 1]);
|
||||
Expect.equals(-1, s.indexOf("content-length"));
|
||||
Expect.equals(-1, s.indexOf("connection"));
|
||||
if (count < 10) {
|
||||
makeRequest();
|
||||
} else {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
socket.listen(
|
||||
response.addAll,
|
||||
onDone: () {
|
||||
socket.destroy();
|
||||
count++;
|
||||
String s = new String.fromCharCodes(response).toLowerCase();
|
||||
Expect.equals("z", s[s.length - 1]);
|
||||
Expect.equals(-1, s.indexOf("content-length"));
|
||||
Expect.equals(-1, s.indexOf("connection"));
|
||||
if (count < 10) {
|
||||
makeRequest();
|
||||
} else {
|
||||
server.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,10 @@ class IsolatedHttpServer {
|
||||
|
||||
void shutdown() {
|
||||
// Send server stop message to the server.
|
||||
_serverPort
|
||||
.send([new IsolatedHttpServerCommand.stop(), _statusPort.sendPort]);
|
||||
_serverPort.send([
|
||||
new IsolatedHttpServerCommand.stop(),
|
||||
_statusPort.sendPort,
|
||||
]);
|
||||
_statusPort.close();
|
||||
}
|
||||
|
||||
@@ -49,7 +51,7 @@ class IsolatedHttpServer {
|
||||
// Send chunked encoding message to the server.
|
||||
_serverPort.send([
|
||||
new IsolatedHttpServerCommand.chunkedEncoding(),
|
||||
_statusPort.sendPort
|
||||
_statusPort.sendPort,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -158,8 +160,10 @@ class TestServer {
|
||||
Expect.equals("html", request.headers.contentType!.subType);
|
||||
Expect.equals("utf-8", request.headers.contentType!.parameters["charset"]);
|
||||
|
||||
response.headers
|
||||
.set(HttpHeaders.contentTypeHeader, "text/html; charset = utf-8");
|
||||
response.headers.set(
|
||||
HttpHeaders.contentTypeHeader,
|
||||
"text/html; charset = utf-8",
|
||||
);
|
||||
response.close();
|
||||
}
|
||||
|
||||
@@ -247,36 +251,42 @@ Future testHost() {
|
||||
IsolatedHttpServer server = new IsolatedHttpServer();
|
||||
server.setServerStartedHandler((int port) {
|
||||
HttpClient httpClient = new HttpClient();
|
||||
httpClient.get("127.0.0.1", port, "/host").then((request) {
|
||||
Expect.equals("127.0.0.1:$port", request.headers["host"]![0]);
|
||||
request.headers.host = "www.dartlang.com";
|
||||
Expect.equals("www.dartlang.com:$port", request.headers["host"]![0]);
|
||||
Expect.equals("www.dartlang.com", request.headers.host);
|
||||
Expect.equals(port, request.headers.port);
|
||||
request.headers.port = 1234;
|
||||
Expect.equals("www.dartlang.com:1234", request.headers["host"]![0]);
|
||||
Expect.equals(1234, request.headers.port);
|
||||
request.headers.port = HttpClient.defaultHttpPort;
|
||||
Expect.equals(HttpClient.defaultHttpPort, request.headers.port);
|
||||
Expect.equals("www.dartlang.com", request.headers["host"]![0]);
|
||||
request.headers.set("Host", "www.dartlang.org");
|
||||
Expect.equals("www.dartlang.org", request.headers.host);
|
||||
Expect.equals(HttpClient.defaultHttpPort, request.headers.port);
|
||||
request.headers.set("Host", "www.dartlang.org:");
|
||||
Expect.equals("www.dartlang.org", request.headers.host);
|
||||
Expect.equals(HttpClient.defaultHttpPort, request.headers.port);
|
||||
request.headers.set("Host", "www.dartlang.org:1234");
|
||||
Expect.equals("www.dartlang.org", request.headers.host);
|
||||
Expect.equals(1234, request.headers.port);
|
||||
return request.close();
|
||||
}).then((response) {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
response.listen((_) {}, onDone: () {
|
||||
httpClient.close();
|
||||
server.shutdown();
|
||||
completer.complete(true);
|
||||
});
|
||||
});
|
||||
httpClient
|
||||
.get("127.0.0.1", port, "/host")
|
||||
.then((request) {
|
||||
Expect.equals("127.0.0.1:$port", request.headers["host"]![0]);
|
||||
request.headers.host = "www.dartlang.com";
|
||||
Expect.equals("www.dartlang.com:$port", request.headers["host"]![0]);
|
||||
Expect.equals("www.dartlang.com", request.headers.host);
|
||||
Expect.equals(port, request.headers.port);
|
||||
request.headers.port = 1234;
|
||||
Expect.equals("www.dartlang.com:1234", request.headers["host"]![0]);
|
||||
Expect.equals(1234, request.headers.port);
|
||||
request.headers.port = HttpClient.defaultHttpPort;
|
||||
Expect.equals(HttpClient.defaultHttpPort, request.headers.port);
|
||||
Expect.equals("www.dartlang.com", request.headers["host"]![0]);
|
||||
request.headers.set("Host", "www.dartlang.org");
|
||||
Expect.equals("www.dartlang.org", request.headers.host);
|
||||
Expect.equals(HttpClient.defaultHttpPort, request.headers.port);
|
||||
request.headers.set("Host", "www.dartlang.org:");
|
||||
Expect.equals("www.dartlang.org", request.headers.host);
|
||||
Expect.equals(HttpClient.defaultHttpPort, request.headers.port);
|
||||
request.headers.set("Host", "www.dartlang.org:1234");
|
||||
Expect.equals("www.dartlang.org", request.headers.host);
|
||||
Expect.equals(1234, request.headers.port);
|
||||
return request.close();
|
||||
})
|
||||
.then((response) {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
httpClient.close();
|
||||
server.shutdown();
|
||||
completer.complete(true);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
server.start();
|
||||
return completer.future;
|
||||
@@ -292,17 +302,24 @@ Future testExpires() {
|
||||
void processResponse(HttpClientResponse response) {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
Expect.equals(
|
||||
"Fri, 11 Jun 1999 18:46:53 GMT", response.headers["expires"]![0]);
|
||||
Expect.equals(new DateTime.utc(1999, DateTime.june, 11, 18, 46, 53, 0),
|
||||
response.headers.expires);
|
||||
response.listen((_) {}, onDone: () {
|
||||
responses++;
|
||||
if (responses == 2) {
|
||||
httpClient.close();
|
||||
server.shutdown();
|
||||
completer.complete(true);
|
||||
}
|
||||
});
|
||||
"Fri, 11 Jun 1999 18:46:53 GMT",
|
||||
response.headers["expires"]![0],
|
||||
);
|
||||
Expect.equals(
|
||||
new DateTime.utc(1999, DateTime.june, 11, 18, 46, 53, 0),
|
||||
response.headers.expires,
|
||||
);
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
responses++;
|
||||
if (responses == 2) {
|
||||
httpClient.close();
|
||||
server.shutdown();
|
||||
completer.complete(true);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
httpClient
|
||||
@@ -328,33 +345,51 @@ Future testContentType() {
|
||||
void processResponse(HttpClientResponse response) {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
Expect.equals(
|
||||
"text/html; charset=utf-8", response.headers.contentType.toString());
|
||||
"text/html; charset=utf-8",
|
||||
response.headers.contentType.toString(),
|
||||
);
|
||||
Expect.equals("text/html", response.headers.contentType!.value);
|
||||
Expect.equals("text", response.headers.contentType!.primaryType);
|
||||
Expect.equals("html", response.headers.contentType!.subType);
|
||||
Expect.equals(
|
||||
"utf-8", response.headers.contentType!.parameters["charset"]);
|
||||
response.listen((_) {}, onDone: () {
|
||||
responses++;
|
||||
if (responses == 2) {
|
||||
httpClient.close();
|
||||
server.shutdown();
|
||||
completer.complete(true);
|
||||
}
|
||||
});
|
||||
"utf-8",
|
||||
response.headers.contentType!.parameters["charset"],
|
||||
);
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
responses++;
|
||||
if (responses == 2) {
|
||||
httpClient.close();
|
||||
server.shutdown();
|
||||
completer.complete(true);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
httpClient.get("127.0.0.1", port, "/contenttype1").then((request) {
|
||||
request.headers.contentType =
|
||||
new ContentType("text", "html", charset: "utf-8");
|
||||
return request.close();
|
||||
}).then(processResponse);
|
||||
httpClient
|
||||
.get("127.0.0.1", port, "/contenttype1")
|
||||
.then((request) {
|
||||
request.headers.contentType = new ContentType(
|
||||
"text",
|
||||
"html",
|
||||
charset: "utf-8",
|
||||
);
|
||||
return request.close();
|
||||
})
|
||||
.then(processResponse);
|
||||
|
||||
httpClient.get("127.0.0.1", port, "/contenttype2").then((request) {
|
||||
request.headers
|
||||
.set(HttpHeaders.contentTypeHeader, "text/html; charset = utf-8");
|
||||
return request.close();
|
||||
}).then(processResponse);
|
||||
httpClient
|
||||
.get("127.0.0.1", port, "/contenttype2")
|
||||
.then((request) {
|
||||
request.headers.set(
|
||||
HttpHeaders.contentTypeHeader,
|
||||
"text/html; charset = utf-8",
|
||||
);
|
||||
return request.close();
|
||||
})
|
||||
.then(processResponse);
|
||||
});
|
||||
server.start();
|
||||
return completer.future;
|
||||
@@ -371,39 +406,55 @@ Future testCookies() {
|
||||
.get("127.0.0.1", port, "/cookie1")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
Expect.equals(2, response.cookies.length);
|
||||
response.cookies.forEach((cookie) {
|
||||
if (cookie.name == "name1") {
|
||||
Expect.equals("value1", cookie.value);
|
||||
DateTime date =
|
||||
new DateTime.utc(2014, DateTime.january, 5, 23, 59, 59, 0);
|
||||
Expect.equals(date, cookie.expires);
|
||||
Expect.equals("www.example.com", cookie.domain);
|
||||
Expect.isTrue(cookie.httpOnly);
|
||||
} else if (cookie.name == "name2") {
|
||||
Expect.equals("value2", cookie.value);
|
||||
Expect.equals(100, cookie.maxAge);
|
||||
Expect.equals(".example.com", cookie.domain);
|
||||
Expect.equals("/shop", cookie.path);
|
||||
} else {
|
||||
Expect.fail("Unexpected cookie");
|
||||
}
|
||||
});
|
||||
|
||||
response.listen((_) {}, onDone: () {
|
||||
httpClient.get("127.0.0.1", port, "/cookie2").then((request) {
|
||||
request.cookies.add(response.cookies[0]);
|
||||
request.cookies.add(response.cookies[1]);
|
||||
return request.close();
|
||||
}).then((response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
httpClient.close();
|
||||
server.shutdown();
|
||||
completer.complete(true);
|
||||
Expect.equals(2, response.cookies.length);
|
||||
response.cookies.forEach((cookie) {
|
||||
if (cookie.name == "name1") {
|
||||
Expect.equals("value1", cookie.value);
|
||||
DateTime date = new DateTime.utc(
|
||||
2014,
|
||||
DateTime.january,
|
||||
5,
|
||||
23,
|
||||
59,
|
||||
59,
|
||||
0,
|
||||
);
|
||||
Expect.equals(date, cookie.expires);
|
||||
Expect.equals("www.example.com", cookie.domain);
|
||||
Expect.isTrue(cookie.httpOnly);
|
||||
} else if (cookie.name == "name2") {
|
||||
Expect.equals("value2", cookie.value);
|
||||
Expect.equals(100, cookie.maxAge);
|
||||
Expect.equals(".example.com", cookie.domain);
|
||||
Expect.equals("/shop", cookie.path);
|
||||
} else {
|
||||
Expect.fail("Unexpected cookie");
|
||||
}
|
||||
});
|
||||
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
httpClient
|
||||
.get("127.0.0.1", port, "/cookie2")
|
||||
.then((request) {
|
||||
request.cookies.add(response.cookies[0]);
|
||||
request.cookies.add(response.cookies[1]);
|
||||
return request.close();
|
||||
})
|
||||
.then((response) {
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
httpClient.close();
|
||||
server.shutdown();
|
||||
completer.complete(true);
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
server.start();
|
||||
return completer.future;
|
||||
|
||||
@@ -375,8 +375,8 @@ void testMalformedAuthenticateHeaderWithAuthHandler() {
|
||||
);
|
||||
|
||||
// Request should throw an exception if the authenticate handler is set
|
||||
client.authenticate =
|
||||
(Uri url, String scheme, String? realm) async => false;
|
||||
client.authenticate = (Uri url, String scheme, String? realm) async =>
|
||||
false;
|
||||
await asyncExpectThrows<HttpException>(
|
||||
client.getUrl(uri).then((request) => request.close()),
|
||||
);
|
||||
|
||||
@@ -26,8 +26,10 @@ class TestServerMain {
|
||||
|
||||
if (chunkedEncoding) {
|
||||
// Send chunked encoding message to the server.
|
||||
port.send(
|
||||
[new TestServerCommand.chunkedEncoding(), _statusPort.sendPort]);
|
||||
port.send([
|
||||
new TestServerCommand.chunkedEncoding(),
|
||||
_statusPort.sendPort,
|
||||
]);
|
||||
}
|
||||
|
||||
// Send server start message to the server.
|
||||
@@ -110,10 +112,13 @@ class TestServer {
|
||||
void _zeroToTenHandler(HttpRequest request) {
|
||||
var response = request.response;
|
||||
Expect.equals("GET", request.method);
|
||||
request.listen((_) {}, onDone: () {
|
||||
response.write("01234567890");
|
||||
response.close();
|
||||
});
|
||||
request.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
response.write("01234567890");
|
||||
response.close();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Return a 404.
|
||||
@@ -208,15 +213,17 @@ void testGET() {
|
||||
.get("127.0.0.1", port, "/0123456789")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
StringBuffer body = new StringBuffer();
|
||||
response.listen((data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
Expect.equals("01234567890", body.toString());
|
||||
httpClient.close();
|
||||
testServerMain.close();
|
||||
});
|
||||
});
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
StringBuffer body = new StringBuffer();
|
||||
response.listen(
|
||||
(data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
Expect.equals("01234567890", body.toString());
|
||||
httpClient.close();
|
||||
testServerMain.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
testServerMain.start();
|
||||
}
|
||||
@@ -231,30 +238,35 @@ void testPOST(bool chunkedEncoding) {
|
||||
int count = 0;
|
||||
HttpClient httpClient = new HttpClient();
|
||||
void sendRequest() {
|
||||
httpClient.post("127.0.0.1", port, "/echo").then((request) {
|
||||
if (chunkedEncoding) {
|
||||
request.write(data.substring(0, 10));
|
||||
request.write(data.substring(10, data.length));
|
||||
} else {
|
||||
request.contentLength = data.length;
|
||||
request.write(data);
|
||||
}
|
||||
return request.close();
|
||||
}).then((response) {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
StringBuffer body = new StringBuffer();
|
||||
response.listen((data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
Expect.equals(data, body.toString());
|
||||
count++;
|
||||
if (count < kMessageCount) {
|
||||
sendRequest();
|
||||
} else {
|
||||
httpClient.close();
|
||||
testServerMain.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
httpClient
|
||||
.post("127.0.0.1", port, "/echo")
|
||||
.then((request) {
|
||||
if (chunkedEncoding) {
|
||||
request.write(data.substring(0, 10));
|
||||
request.write(data.substring(10, data.length));
|
||||
} else {
|
||||
request.contentLength = data.length;
|
||||
request.write(data);
|
||||
}
|
||||
return request.close();
|
||||
})
|
||||
.then((response) {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
StringBuffer body = new StringBuffer();
|
||||
response.listen(
|
||||
(data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
Expect.equals(data, body.toString());
|
||||
count++;
|
||||
if (count < kMessageCount) {
|
||||
sendRequest();
|
||||
} else {
|
||||
httpClient.close();
|
||||
testServerMain.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
sendRequest();
|
||||
@@ -272,15 +284,17 @@ void test404() {
|
||||
.get("127.0.0.1", port, "/thisisnotfound")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
Expect.equals(HttpStatus.notFound, response.statusCode);
|
||||
var body = new StringBuffer();
|
||||
response.listen((data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
Expect.equals("Page not found", body.toString());
|
||||
httpClient.close();
|
||||
testServerMain.close();
|
||||
});
|
||||
});
|
||||
Expect.equals(HttpStatus.notFound, response.statusCode);
|
||||
var body = new StringBuffer();
|
||||
response.listen(
|
||||
(data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
Expect.equals("Page not found", body.toString());
|
||||
httpClient.close();
|
||||
testServerMain.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
testServerMain.start();
|
||||
}
|
||||
@@ -289,17 +303,26 @@ void testReasonPhrase() {
|
||||
TestServerMain testServerMain = new TestServerMain();
|
||||
testServerMain.setServerStartedHandler((int port) {
|
||||
HttpClient httpClient = new HttpClient();
|
||||
httpClient.get("127.0.0.1", port, "/reasonformoving").then((request) {
|
||||
request.followRedirects = false;
|
||||
return request.close();
|
||||
}).then((response) {
|
||||
Expect.equals(HttpStatus.movedPermanently, response.statusCode);
|
||||
Expect.equals("Don't come looking here any more", response.reasonPhrase);
|
||||
response.listen((data) => Expect.fail("No data expected"), onDone: () {
|
||||
httpClient.close();
|
||||
testServerMain.close();
|
||||
});
|
||||
});
|
||||
httpClient
|
||||
.get("127.0.0.1", port, "/reasonformoving")
|
||||
.then((request) {
|
||||
request.followRedirects = false;
|
||||
return request.close();
|
||||
})
|
||||
.then((response) {
|
||||
Expect.equals(HttpStatus.movedPermanently, response.statusCode);
|
||||
Expect.equals(
|
||||
"Don't come looking here any more",
|
||||
response.reasonPhrase,
|
||||
);
|
||||
response.listen(
|
||||
(data) => Expect.fail("No data expected"),
|
||||
onDone: () {
|
||||
httpClient.close();
|
||||
testServerMain.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
testServerMain.start();
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ void testGetEmptyRequest() {
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
response.listen((data) {}, onDone: server.close);
|
||||
});
|
||||
response.listen((data) {}, onDone: server.close);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -43,12 +43,15 @@ void testGetDataRequest() {
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
int count = 0;
|
||||
response.listen((data) => count += data.length, onDone: () {
|
||||
server.close();
|
||||
Expect.equals(data.length, count);
|
||||
});
|
||||
});
|
||||
int count = 0;
|
||||
response.listen(
|
||||
(data) => count += data.length,
|
||||
onDone: () {
|
||||
server.close();
|
||||
Expect.equals(data.length, count);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -56,8 +59,8 @@ void testGetInvalidHost() {
|
||||
asyncStart();
|
||||
var client = new HttpClient();
|
||||
Future<HttpClientRequest?>.value(
|
||||
client.get("__SOMETHING_INVALID__", 8888, "/"))
|
||||
.catchError((error) {
|
||||
client.get("__SOMETHING_INVALID__", 8888, "/"),
|
||||
).catchError((error) {
|
||||
client.close();
|
||||
asyncEnd();
|
||||
});
|
||||
@@ -112,9 +115,12 @@ void testGetServerForceClose() {
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
Expect.fail("Request not expected");
|
||||
}).catchError((error) => asyncEnd(),
|
||||
test: (error) => error is HttpException);
|
||||
Expect.fail("Request not expected");
|
||||
})
|
||||
.catchError(
|
||||
(error) => asyncEnd(),
|
||||
test: (error) => error is HttpException,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -135,17 +141,19 @@ void testGetDataServerForceClose() {
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
// Close the (incomplete) response, now that we have seen
|
||||
// the response object.
|
||||
completer.complete(null);
|
||||
int errors = 0;
|
||||
response.listen((data) {},
|
||||
onError: (error) => errors++,
|
||||
onDone: () {
|
||||
Expect.equals(1, errors);
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
// Close the (incomplete) response, now that we have seen
|
||||
// the response object.
|
||||
completer.complete(null);
|
||||
int errors = 0;
|
||||
response.listen(
|
||||
(data) {},
|
||||
onError: (error) => errors++,
|
||||
onDone: () {
|
||||
Expect.equals(1, errors);
|
||||
asyncEnd();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -158,7 +166,7 @@ void testOpenEmptyRequest() {
|
||||
[client.put, 'PUT'],
|
||||
[client.delete, 'DELETE'],
|
||||
[client.patch, 'PATCH'],
|
||||
[client.head, 'HEAD']
|
||||
[client.head, 'HEAD'],
|
||||
];
|
||||
|
||||
for (var method in methods) {
|
||||
@@ -169,11 +177,11 @@ void testOpenEmptyRequest() {
|
||||
});
|
||||
|
||||
Callback1 cb = method[0] as Callback1;
|
||||
cb("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
response.listen((data) {}, onDone: server.close);
|
||||
});
|
||||
cb("127.0.0.1", server.port, "/").then((request) => request.close()).then(
|
||||
(response) {
|
||||
response.listen((data) {}, onDone: server.close);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -187,7 +195,7 @@ void testOpenUrlEmptyRequest() {
|
||||
[client.putUrl, 'PUT'],
|
||||
[client.deleteUrl, 'DELETE'],
|
||||
[client.patchUrl, 'PATCH'],
|
||||
[client.headUrl, 'HEAD']
|
||||
[client.headUrl, 'HEAD'],
|
||||
];
|
||||
|
||||
for (var method in methods) {
|
||||
@@ -198,9 +206,9 @@ void testOpenUrlEmptyRequest() {
|
||||
});
|
||||
|
||||
Callback2 cb = method[0] as Callback2;
|
||||
cb(Uri.parse("http://127.0.0.1:${server.port}/"))
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
cb(
|
||||
Uri.parse("http://127.0.0.1:${server.port}/"),
|
||||
).then((request) => request.close()).then((response) {
|
||||
response.listen((data) {}, onDone: server.close);
|
||||
});
|
||||
});
|
||||
@@ -222,36 +230,38 @@ void testNoBuffer() {
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((clientResponse) {
|
||||
var iterator = new StreamIterator(clientResponse
|
||||
.cast<List<int>>()
|
||||
.transform(utf8.decoder)
|
||||
.transform(new LineSplitter()));
|
||||
iterator.moveNext().then((hasValue) {
|
||||
Expect.isTrue(hasValue);
|
||||
Expect.equals('init', iterator.current);
|
||||
int count = 0;
|
||||
void run() {
|
||||
if (count == 10) {
|
||||
response.close();
|
||||
iterator.moveNext().then((hasValue) {
|
||||
Expect.isFalse(hasValue);
|
||||
server.close();
|
||||
asyncEnd();
|
||||
});
|
||||
} else {
|
||||
response.writeln('output$count');
|
||||
iterator.moveNext().then((hasValue) {
|
||||
Expect.isTrue(hasValue);
|
||||
Expect.equals('output$count', iterator.current);
|
||||
count++;
|
||||
run();
|
||||
});
|
||||
}
|
||||
}
|
||||
var iterator = new StreamIterator(
|
||||
clientResponse
|
||||
.cast<List<int>>()
|
||||
.transform(utf8.decoder)
|
||||
.transform(new LineSplitter()),
|
||||
);
|
||||
iterator.moveNext().then((hasValue) {
|
||||
Expect.isTrue(hasValue);
|
||||
Expect.equals('init', iterator.current);
|
||||
int count = 0;
|
||||
void run() {
|
||||
if (count == 10) {
|
||||
response.close();
|
||||
iterator.moveNext().then((hasValue) {
|
||||
Expect.isFalse(hasValue);
|
||||
server.close();
|
||||
asyncEnd();
|
||||
});
|
||||
} else {
|
||||
response.writeln('output$count');
|
||||
iterator.moveNext().then((hasValue) {
|
||||
Expect.isTrue(hasValue);
|
||||
Expect.equals('output$count', iterator.current);
|
||||
count++;
|
||||
run();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
});
|
||||
});
|
||||
run();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -261,9 +271,10 @@ void testMaxConnectionsPerHost(int connectionCap, int connections) {
|
||||
int handled = 0;
|
||||
server.listen((request) {
|
||||
Expect.isTrue(
|
||||
server.connectionsInfo().total <= connectionCap,
|
||||
'${server.connectionsInfo().total} <= $connectionCap ' +
|
||||
'(connections: $connections)');
|
||||
server.connectionsInfo().total <= connectionCap,
|
||||
'${server.connectionsInfo().total} <= $connectionCap ' +
|
||||
'(connections: $connections)',
|
||||
);
|
||||
request.response.close();
|
||||
handled++;
|
||||
if (handled == connections) {
|
||||
@@ -280,10 +291,13 @@ void testMaxConnectionsPerHost(int connectionCap, int connections) {
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
response.listen(null, onDone: () {
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
response.listen(
|
||||
null,
|
||||
onDone: () {
|
||||
asyncEnd();
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -303,8 +317,10 @@ Future<void> testMaxConnectionsWithFailure() async {
|
||||
}
|
||||
try {
|
||||
await client.getUrl(Uri.parse('http://domain.invalid'));
|
||||
Expect.fail("Calls exceed client's maxConnectionsPerHost should throw "
|
||||
"exceptions as well");
|
||||
Expect.fail(
|
||||
"Calls exceed client's maxConnectionsPerHost should throw "
|
||||
"exceptions as well",
|
||||
);
|
||||
} catch (e) {
|
||||
if (e is! SocketException) {
|
||||
Expect.fail("Unexpected exception $e is thrown");
|
||||
@@ -334,13 +350,16 @@ Future<void> testHttpAbort() async {
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
request.close().then((response) {
|
||||
Expect.fail('abort() prevents a response being returned');
|
||||
}, onError: (e) {
|
||||
Expect.type<HttpException>(e);
|
||||
Expect.isTrue(e.toString().contains('abort'));
|
||||
asyncEnd();
|
||||
});
|
||||
request.close().then(
|
||||
(response) {
|
||||
Expect.fail('abort() prevents a response being returned');
|
||||
},
|
||||
onError: (e) {
|
||||
Expect.type<HttpException>(e);
|
||||
Expect.isTrue(e.toString().contains('abort'));
|
||||
asyncEnd();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> testHttpAbortBeforeWrite() async {
|
||||
@@ -368,12 +387,15 @@ Future<void> testHttpAbortBeforeWrite() async {
|
||||
server.close();
|
||||
asyncEnd();
|
||||
});
|
||||
request.close().then((response) {
|
||||
Expect.fail('abort() prevents a response being returned');
|
||||
}, onError: (e) {
|
||||
Expect.type<HttpException>(e);
|
||||
asyncEnd();
|
||||
});
|
||||
request.close().then(
|
||||
(response) {
|
||||
Expect.fail('abort() prevents a response being returned');
|
||||
},
|
||||
onError: (e) {
|
||||
Expect.type<HttpException>(e);
|
||||
asyncEnd();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> testHttpAbortBeforeClose() async {
|
||||
@@ -401,13 +423,16 @@ Future<void> testHttpAbortBeforeClose() async {
|
||||
await completer.future;
|
||||
final string = 'abort message';
|
||||
request.abort(string);
|
||||
request.close().then((response) {
|
||||
Expect.fail('abort() prevents a response being returned');
|
||||
}, onError: (e) {
|
||||
Expect.type<String>(e);
|
||||
Expect.equals(string, e);
|
||||
asyncEnd();
|
||||
});
|
||||
request.close().then(
|
||||
(response) {
|
||||
Expect.fail('abort() prevents a response being returned');
|
||||
},
|
||||
onError: (e) {
|
||||
Expect.type<String>(e);
|
||||
Expect.equals(string, e);
|
||||
asyncEnd();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> testHttpAbortAfterClose() async {
|
||||
|
||||
@@ -10,31 +10,48 @@ import "package:expect/expect.dart";
|
||||
|
||||
void testInvalidUrl() {
|
||||
HttpClient client = new HttpClient();
|
||||
Expect.throws(() => client.getUrl(Uri.parse('ftp://www.google.com')),
|
||||
(e) => e.toString().contains("Unsupported scheme"));
|
||||
Expect.throws(() => client.getUrl(Uri.parse('httpx://www.google.com')),
|
||||
(e) => e.toString().contains("Unsupported scheme"));
|
||||
Expect.throws(
|
||||
() => client.getUrl(Uri.parse('ftp://www.google.com')),
|
||||
(e) => e.toString().contains("Unsupported scheme"),
|
||||
);
|
||||
Expect.throws(
|
||||
() => client.getUrl(Uri.parse('httpx://www.google.com')),
|
||||
(e) => e.toString().contains("Unsupported scheme"),
|
||||
);
|
||||
Expect.throwsFormatException(() => client.getUrl(Uri.parse('http://::1')));
|
||||
Expect.throws(() => client.getUrl(Uri.parse('http://user@:1')),
|
||||
(e) => e.toString().contains("No host specified"));
|
||||
Expect.throws(() => client.getUrl(Uri.parse('http:///')),
|
||||
(e) => e.toString().contains("No host specified"));
|
||||
Expect.throws(() => client.getUrl(Uri.parse('http:///index.html')),
|
||||
(e) => e.toString().contains("No host specified"));
|
||||
Expect.throws(() => client.getUrl(Uri.parse('///')),
|
||||
(e) => e.toString().contains("No host specified"));
|
||||
Expect.throws(() => client.getUrl(Uri.parse('///index.html')),
|
||||
(e) => e.toString().contains("No host specified"));
|
||||
Expect.throws(
|
||||
() => client.getUrl(Uri.parse('http://user@:1')),
|
||||
(e) => e.toString().contains("No host specified"),
|
||||
);
|
||||
Expect.throws(
|
||||
() => client.getUrl(Uri.parse('http:///')),
|
||||
(e) => e.toString().contains("No host specified"),
|
||||
);
|
||||
Expect.throws(
|
||||
() => client.getUrl(Uri.parse('http:///index.html')),
|
||||
(e) => e.toString().contains("No host specified"),
|
||||
);
|
||||
Expect.throws(
|
||||
() => client.getUrl(Uri.parse('///')),
|
||||
(e) => e.toString().contains("No host specified"),
|
||||
);
|
||||
Expect.throws(
|
||||
() => client.getUrl(Uri.parse('///index.html')),
|
||||
(e) => e.toString().contains("No host specified"),
|
||||
);
|
||||
}
|
||||
|
||||
void testBadHostName() {
|
||||
asyncStart();
|
||||
HttpClient client = new HttpClient();
|
||||
client.get("some.bad.host.name.7654321", 0, "/").then((request) {
|
||||
Expect.fail("Should not open a request on bad hostname");
|
||||
}).catchError((error) {
|
||||
asyncEnd(); // We expect onError to be called, due to bad host name.
|
||||
}, test: (error) => error is! String);
|
||||
client
|
||||
.get("some.bad.host.name.7654321", 0, "/")
|
||||
.then((request) {
|
||||
Expect.fail("Should not open a request on bad hostname");
|
||||
})
|
||||
.catchError((error) {
|
||||
asyncEnd(); // We expect onError to be called, due to bad host name.
|
||||
}, test: (error) => error is! String);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
@@ -24,24 +24,32 @@ Future testHttpClient(header) {
|
||||
});
|
||||
});
|
||||
|
||||
await runZonedGuarded(() {
|
||||
var client = new HttpClient();
|
||||
client.userAgent = null;
|
||||
client
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
response.transform(utf8.decoder).listen((contents) {
|
||||
completer.complete();
|
||||
}, onDone: () {
|
||||
client.close(force: true);
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
}, (e, st) {
|
||||
server.close();
|
||||
completer.completeError(e, st);
|
||||
});
|
||||
await runZonedGuarded(
|
||||
() {
|
||||
var client = new HttpClient();
|
||||
client.userAgent = null;
|
||||
client
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
response
|
||||
.transform(utf8.decoder)
|
||||
.listen(
|
||||
(contents) {
|
||||
completer.complete();
|
||||
},
|
||||
onDone: () {
|
||||
client.close(force: true);
|
||||
server.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
(e, st) {
|
||||
server.close();
|
||||
completer.completeError(e, st);
|
||||
},
|
||||
);
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
@@ -19,8 +19,9 @@ Future<void> main() async {
|
||||
for (var i = 0; i < max; i++) {
|
||||
new Future(() async {
|
||||
try {
|
||||
final request = await client
|
||||
.getUrl(Uri.parse("http://localhost:${servers[i].port}/"));
|
||||
final request = await client.getUrl(
|
||||
Uri.parse("http://localhost:${servers[i].port}/"),
|
||||
);
|
||||
got++;
|
||||
if (got == max) {
|
||||
// Test that no stack overflow happens.
|
||||
|
||||
@@ -23,7 +23,9 @@ testClientAndServerCloseNoListen(int connections) {
|
||||
if (closed == connections) {
|
||||
Expect.equals(0, server.connectionsInfo().active);
|
||||
Expect.equals(
|
||||
server.connectionsInfo().total, server.connectionsInfo().idle);
|
||||
server.connectionsInfo().total,
|
||||
server.connectionsInfo().idle,
|
||||
);
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
@@ -46,16 +48,21 @@ testClientCloseServerListen(int connections) {
|
||||
if (closed == connections * 2) {
|
||||
Expect.equals(0, server.connectionsInfo().active);
|
||||
Expect.equals(
|
||||
server.connectionsInfo().total, server.connectionsInfo().idle);
|
||||
server.connectionsInfo().total,
|
||||
server.connectionsInfo().idle,
|
||||
);
|
||||
server.close();
|
||||
}
|
||||
}
|
||||
|
||||
server.listen((request) {
|
||||
request.listen((_) {}, onDone: () {
|
||||
request.response.close();
|
||||
request.response.done.then((_) => check());
|
||||
});
|
||||
request.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
request.response.close();
|
||||
request.response.done.then((_) => check());
|
||||
},
|
||||
);
|
||||
});
|
||||
var client = HttpClient();
|
||||
for (int i = 0; i < connections; i++) {
|
||||
@@ -81,7 +88,9 @@ testClientCloseSendingResponse(int connections) {
|
||||
if (closed == connections * 2) {
|
||||
Expect.equals(0, server.connectionsInfo().active);
|
||||
Expect.equals(
|
||||
server.connectionsInfo().total, server.connectionsInfo().idle);
|
||||
server.connectionsInfo().total,
|
||||
server.connectionsInfo().idle,
|
||||
);
|
||||
server.close();
|
||||
}
|
||||
}
|
||||
@@ -101,14 +110,14 @@ testClientCloseSendingResponse(int connections) {
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
// Ensure we don't accept the response until we have send the entire
|
||||
// request.
|
||||
var subscription = response.listen((_) {});
|
||||
Timer(const Duration(milliseconds: 20), () {
|
||||
subscription.cancel();
|
||||
check();
|
||||
});
|
||||
});
|
||||
// Ensure we don't accept the response until we have send the entire
|
||||
// request.
|
||||
var subscription = response.listen((_) {});
|
||||
Timer(const Duration(milliseconds: 20), () {
|
||||
subscription.cancel();
|
||||
check();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -119,25 +128,32 @@ testClientCloseWhileSendingRequest(int connections) {
|
||||
HttpServer.bind("127.0.0.1", 0).then((server) {
|
||||
int serverErrors = 0;
|
||||
int clientErrors = 0;
|
||||
server.listen((request) {
|
||||
request.listen((_) {}, onError: (_) {
|
||||
serverErrors++;
|
||||
if (serverErrors == connections) {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
}, onDone: () {
|
||||
Expect.equals(connections, clientErrors);
|
||||
Expect.equals(connections, serverErrors);
|
||||
});
|
||||
server.listen(
|
||||
(request) {
|
||||
request.listen(
|
||||
(_) {},
|
||||
onError: (_) {
|
||||
serverErrors++;
|
||||
if (serverErrors == connections) {
|
||||
server.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
onDone: () {
|
||||
Expect.equals(connections, clientErrors);
|
||||
Expect.equals(connections, serverErrors);
|
||||
},
|
||||
);
|
||||
var client = HttpClient();
|
||||
for (int i = 0; i < connections; i++) {
|
||||
Future<HttpClientResponse?>.value(
|
||||
client.post("127.0.0.1", server.port, "/").then((request) {
|
||||
request.contentLength = 110;
|
||||
request.write("0123456789");
|
||||
return request.close();
|
||||
})).catchError((_) {
|
||||
client.post("127.0.0.1", server.port, "/").then((request) {
|
||||
request.contentLength = 110;
|
||||
request.write("0123456789");
|
||||
return request.close();
|
||||
}),
|
||||
).catchError((_) {
|
||||
clientErrors++;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,9 +25,13 @@ Future<void> testServerCompress({bool clientAutoUncompress = true}) async {
|
||||
request.headers.set(HttpHeaders.acceptEncodingHeader, "gzip,deflate");
|
||||
final response = await request.close();
|
||||
Expect.equals(
|
||||
"gzip", response.headers.value(HttpHeaders.contentEncodingHeader));
|
||||
final list =
|
||||
await response.fold<List<int>>(<int>[], (list, b) => list..addAll(b));
|
||||
"gzip",
|
||||
response.headers.value(HttpHeaders.contentEncodingHeader),
|
||||
);
|
||||
final list = await response.fold<List<int>>(
|
||||
<int>[],
|
||||
(list, b) => list..addAll(b),
|
||||
);
|
||||
if (clientAutoUncompress) {
|
||||
Expect.listEquals(data, list);
|
||||
} else {
|
||||
@@ -57,8 +61,10 @@ Future<void> testAcceptEncodingHeader() async {
|
||||
final request = await client.get("127.0.0.1", server.port, "/");
|
||||
request.headers.set(HttpHeaders.acceptEncodingHeader, encoding);
|
||||
final response = await request.close();
|
||||
Expect.equals(valid,
|
||||
("gzip" == response.headers.value(HttpHeaders.contentEncodingHeader)));
|
||||
Expect.equals(
|
||||
valid,
|
||||
("gzip" == response.headers.value(HttpHeaders.contentEncodingHeader)),
|
||||
);
|
||||
await response.listen((_) {}).asFuture();
|
||||
server.close();
|
||||
client.close();
|
||||
@@ -83,7 +89,9 @@ Future<void> testDisableCompressTest() async {
|
||||
Expect.equals(false, server.autoCompress);
|
||||
server.listen((request) {
|
||||
Expect.equals(
|
||||
'gzip', request.headers.value(HttpHeaders.acceptEncodingHeader));
|
||||
'gzip',
|
||||
request.headers.value(HttpHeaders.acceptEncodingHeader),
|
||||
);
|
||||
request.response.write("data");
|
||||
request.response.close();
|
||||
});
|
||||
@@ -91,7 +99,9 @@ Future<void> testDisableCompressTest() async {
|
||||
final request = await client.get("127.0.0.1", server.port, "/");
|
||||
final response = await request.close();
|
||||
Expect.equals(
|
||||
null, response.headers.value(HttpHeaders.contentEncodingHeader));
|
||||
null,
|
||||
response.headers.value(HttpHeaders.contentEncodingHeader),
|
||||
);
|
||||
await response.listen((_) {}).asFuture();
|
||||
server.close();
|
||||
client.close();
|
||||
|
||||
@@ -15,10 +15,13 @@ void testHttp10Close(bool closeRequest) {
|
||||
|
||||
Socket.connect("127.0.0.1", server.port).then((socket) {
|
||||
socket.write("GET / HTTP/1.0\r\n\r\n");
|
||||
socket.listen((data) {}, onDone: () {
|
||||
if (!closeRequest) socket.destroy();
|
||||
server.close();
|
||||
});
|
||||
socket.listen(
|
||||
(data) {},
|
||||
onDone: () {
|
||||
if (!closeRequest) socket.destroy();
|
||||
server.close();
|
||||
},
|
||||
);
|
||||
if (closeRequest) socket.close();
|
||||
});
|
||||
});
|
||||
@@ -33,10 +36,13 @@ void testHttp11Close(bool closeRequest) {
|
||||
Socket.connect("127.0.0.1", server.port).then((socket) {
|
||||
List<int> buffer = new List<int>.filled(1024, 0);
|
||||
socket.write("GET / HTTP/1.1\r\nConnection: close\r\n\r\n");
|
||||
socket.listen((data) {}, onDone: () {
|
||||
if (!closeRequest) socket.destroy();
|
||||
server.close();
|
||||
});
|
||||
socket.listen(
|
||||
(data) {},
|
||||
onDone: () {
|
||||
if (!closeRequest) socket.destroy();
|
||||
server.close();
|
||||
},
|
||||
);
|
||||
if (closeRequest) socket.close();
|
||||
});
|
||||
});
|
||||
@@ -46,12 +52,15 @@ void testStreamResponse() {
|
||||
HttpServer.bind("127.0.0.1", 0).then((server) {
|
||||
server.listen((request) {
|
||||
var timer = new Timer.periodic(const Duration(milliseconds: 0), (_) {
|
||||
request.response
|
||||
.write('data:${new DateTime.now().millisecondsSinceEpoch}\n\n');
|
||||
request.response.write(
|
||||
'data:${new DateTime.now().millisecondsSinceEpoch}\n\n',
|
||||
);
|
||||
});
|
||||
request.response.done.whenComplete(() {
|
||||
timer.cancel();
|
||||
}).catchError((_) {});
|
||||
request.response.done
|
||||
.whenComplete(() {
|
||||
timer.cancel();
|
||||
})
|
||||
.catchError((_) {});
|
||||
});
|
||||
|
||||
var client = new HttpClient();
|
||||
@@ -59,16 +68,19 @@ void testStreamResponse() {
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}"))
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
int bytes = 0;
|
||||
response.listen((data) {
|
||||
bytes += data.length;
|
||||
if (bytes > 100) {
|
||||
client.close(force: true);
|
||||
}
|
||||
}, onError: (error) {
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
int bytes = 0;
|
||||
response.listen(
|
||||
(data) {
|
||||
bytes += data.length;
|
||||
if (bytes > 100) {
|
||||
client.close(force: true);
|
||||
}
|
||||
},
|
||||
onError: (error) {
|
||||
server.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -141,17 +141,20 @@ testDifferentAddressFamiliesAndProxySettings(String dir) async {
|
||||
Expect.equals("Hello via Proxy", inet6ResponseText);
|
||||
// Fetch a URL from the Unix server and verify the results.
|
||||
final unixResponse = await client
|
||||
.getUrl(Uri(
|
||||
.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: "/"))
|
||||
path: "/",
|
||||
),
|
||||
)
|
||||
.then((request) {
|
||||
return request.close();
|
||||
});
|
||||
return request.close();
|
||||
});
|
||||
Expect.equals(200, unixResponse.statusCode);
|
||||
final unixResponseText = await unixResponse
|
||||
.transform(utf8.decoder)
|
||||
|
||||
@@ -15,19 +15,30 @@ void setConnectionHeaders(HttpHeaders headers) {
|
||||
}
|
||||
|
||||
void checkExpectedConnectionHeaders(
|
||||
HttpHeaders headers, bool persistentConnection) {
|
||||
HttpHeaders headers,
|
||||
bool persistentConnection,
|
||||
) {
|
||||
Expect.equals("some-value1", headers.value("My-Connection-Header1"));
|
||||
Expect.equals("some-value2", headers.value("My-Connection-Header2"));
|
||||
Expect.isTrue(headers[HttpHeaders.connectionHeader]!
|
||||
.any((value) => value.toLowerCase() == "my-connection-header1"));
|
||||
Expect.isTrue(headers[HttpHeaders.connectionHeader]!
|
||||
.any((value) => value.toLowerCase() == "my-connection-header2"));
|
||||
Expect.isTrue(
|
||||
headers[HttpHeaders.connectionHeader]!.any(
|
||||
(value) => value.toLowerCase() == "my-connection-header1",
|
||||
),
|
||||
);
|
||||
Expect.isTrue(
|
||||
headers[HttpHeaders.connectionHeader]!.any(
|
||||
(value) => value.toLowerCase() == "my-connection-header2",
|
||||
),
|
||||
);
|
||||
if (persistentConnection) {
|
||||
Expect.equals(2, headers[HttpHeaders.connectionHeader]!.length);
|
||||
} else {
|
||||
Expect.equals(3, headers[HttpHeaders.connectionHeader]!.length);
|
||||
Expect.isTrue(headers[HttpHeaders.connectionHeader]!
|
||||
.any((value) => value.toLowerCase() == "close"));
|
||||
Expect.isTrue(
|
||||
headers[HttpHeaders.connectionHeader]!.any(
|
||||
(value) => value.toLowerCase() == "close",
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,9 +48,13 @@ void test(int totalConnections, bool clientPersistentConnection) {
|
||||
// Check expected request.
|
||||
Expect.equals(clientPersistentConnection, request.persistentConnection);
|
||||
Expect.equals(
|
||||
clientPersistentConnection, request.response.persistentConnection);
|
||||
clientPersistentConnection,
|
||||
request.response.persistentConnection,
|
||||
);
|
||||
checkExpectedConnectionHeaders(
|
||||
request.headers, request.persistentConnection);
|
||||
request.headers,
|
||||
request.persistentConnection,
|
||||
);
|
||||
|
||||
// Generate response. If the client signaled non-persistent
|
||||
// connection the server should not need to set it.
|
||||
@@ -56,21 +71,27 @@ void test(int totalConnections, bool clientPersistentConnection) {
|
||||
client
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((HttpClientRequest request) {
|
||||
setConnectionHeaders(request.headers);
|
||||
request.persistentConnection = clientPersistentConnection;
|
||||
return request.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
Expect.isFalse(response.persistentConnection);
|
||||
checkExpectedConnectionHeaders(
|
||||
response.headers, response.persistentConnection);
|
||||
response.listen((_) {}, onDone: () {
|
||||
count++;
|
||||
if (count == totalConnections) {
|
||||
client.close();
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
setConnectionHeaders(request.headers);
|
||||
request.persistentConnection = clientPersistentConnection;
|
||||
return request.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
Expect.isFalse(response.persistentConnection);
|
||||
checkExpectedConnectionHeaders(
|
||||
response.headers,
|
||||
response.persistentConnection,
|
||||
);
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
count++;
|
||||
if (count == totalConnections) {
|
||||
client.close();
|
||||
server.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -18,25 +18,36 @@ void testHttpConnectionInfo() {
|
||||
Expect.isNotNull(clientPort);
|
||||
Expect.equals(request.connectionInfo!.remotePort, clientPort);
|
||||
Expect.equals(response.connectionInfo!.remotePort, clientPort);
|
||||
request.listen((_) {}, onDone: () {
|
||||
request.response.close();
|
||||
});
|
||||
request.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
request.response.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
HttpClient client = new HttpClient();
|
||||
client.get("127.0.0.1", server.port, "/").then((request) {
|
||||
Expect.isTrue(request.connectionInfo!.remoteAddress is InternetAddress);
|
||||
Expect.equals(request.connectionInfo!.remotePort, server.port);
|
||||
clientPort = request.connectionInfo!.localPort;
|
||||
return request.close();
|
||||
}).then((response) {
|
||||
Expect.equals(server.port, response.connectionInfo!.remotePort);
|
||||
Expect.equals(clientPort, response.connectionInfo!.localPort);
|
||||
response.listen((_) {}, onDone: () {
|
||||
client.close();
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
client
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) {
|
||||
Expect.isTrue(
|
||||
request.connectionInfo!.remoteAddress is InternetAddress,
|
||||
);
|
||||
Expect.equals(request.connectionInfo!.remotePort, server.port);
|
||||
clientPort = request.connectionInfo!.localPort;
|
||||
return request.close();
|
||||
})
|
||||
.then((response) {
|
||||
Expect.equals(server.port, response.connectionInfo!.remotePort);
|
||||
Expect.equals(clientPort, response.connectionInfo!.localPort);
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
client.close();
|
||||
server.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -15,51 +15,60 @@ import "package:expect/expect.dart";
|
||||
void testNoBody(int totalConnections, bool explicitContentLength) {
|
||||
int count = 0;
|
||||
HttpServer.bind("127.0.0.1", 0, backlog: totalConnections).then((server) {
|
||||
server.listen((HttpRequest request) {
|
||||
Expect.equals(null, request.headers.value('content-length'));
|
||||
Expect.equals(-1, request.contentLength);
|
||||
var response = request.response;
|
||||
response.contentLength = 0;
|
||||
response.done.then((_) {
|
||||
Expect.fail("Unexpected successful response completion");
|
||||
}).catchError((error) {
|
||||
Expect.isTrue(error is HttpException);
|
||||
if (++count == totalConnections) {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
// write with content length 0 closes the connection and
|
||||
// reports an error.
|
||||
response.write("x");
|
||||
// Subsequent write are ignored as there is already an
|
||||
// error.
|
||||
response.write("x");
|
||||
// After an explicit close, write becomes a state error
|
||||
// because we have said we will not add more.
|
||||
response.close();
|
||||
Expect.throws(() {
|
||||
server.listen(
|
||||
(HttpRequest request) {
|
||||
Expect.equals(null, request.headers.value('content-length'));
|
||||
Expect.equals(-1, request.contentLength);
|
||||
var response = request.response;
|
||||
response.contentLength = 0;
|
||||
response.done
|
||||
.then((_) {
|
||||
Expect.fail("Unexpected successful response completion");
|
||||
})
|
||||
.catchError((error) {
|
||||
Expect.isTrue(error is HttpException);
|
||||
if (++count == totalConnections) {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
// write with content length 0 closes the connection and
|
||||
// reports an error.
|
||||
response.write("x");
|
||||
}, (e) => e is StateError);
|
||||
}, onError: (e, trace) {
|
||||
String msg = "Unexpected server error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
});
|
||||
// Subsequent write are ignored as there is already an
|
||||
// error.
|
||||
response.write("x");
|
||||
// After an explicit close, write becomes a state error
|
||||
// because we have said we will not add more.
|
||||
response.close();
|
||||
Expect.throws(() {
|
||||
response.write("x");
|
||||
}, (e) => e is StateError);
|
||||
},
|
||||
onError: (e, trace) {
|
||||
String msg = "Unexpected server error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
},
|
||||
);
|
||||
|
||||
HttpClient client = new HttpClient();
|
||||
for (int i = 0; i < totalConnections; i++) {
|
||||
client.get("127.0.0.1", server.port, "/").then((request) {
|
||||
if (explicitContentLength) {
|
||||
request.contentLength = 0;
|
||||
}
|
||||
return request.close();
|
||||
}).then((response) {
|
||||
Expect.equals("0", response.headers.value('content-length'));
|
||||
Expect.equals(0, response.contentLength);
|
||||
response.drain();
|
||||
}).catchError((e, trace) {
|
||||
// It's also okay to fail, as headers may not be written.
|
||||
});
|
||||
client
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) {
|
||||
if (explicitContentLength) {
|
||||
request.contentLength = 0;
|
||||
}
|
||||
return request.close();
|
||||
})
|
||||
.then((response) {
|
||||
Expect.equals("0", response.headers.value('content-length'));
|
||||
Expect.equals(0, response.contentLength);
|
||||
response.drain();
|
||||
})
|
||||
.catchError((e, trace) {
|
||||
// It's also okay to fail, as headers may not be written.
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -67,133 +76,173 @@ void testNoBody(int totalConnections, bool explicitContentLength) {
|
||||
void testBody(int totalConnections, bool useHeader) {
|
||||
HttpServer.bind("127.0.0.1", 0, backlog: totalConnections).then((server) {
|
||||
int serverCount = 0;
|
||||
server.listen((HttpRequest request) {
|
||||
Expect.equals("2", request.headers.value('content-length'));
|
||||
Expect.equals(2, request.contentLength);
|
||||
var response = request.response;
|
||||
if (useHeader) {
|
||||
response.contentLength = 2;
|
||||
} else {
|
||||
response.headers.set("content-length", 2);
|
||||
}
|
||||
request.listen((d) {}, onDone: () {
|
||||
response.write("x");
|
||||
Expect.throws(
|
||||
() => response.contentLength = 3, (e) => e is HttpException);
|
||||
response.write("x");
|
||||
response.write("x");
|
||||
response.done.then((_) {
|
||||
Expect.fail("Unexpected successful response completion");
|
||||
}).catchError((error) {
|
||||
Expect.isTrue(error is HttpException, "[$error]");
|
||||
if (++serverCount == totalConnections) {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
response.close();
|
||||
Expect.throws(() {
|
||||
response.write("x");
|
||||
}, (e) => e is StateError);
|
||||
});
|
||||
}, onError: (e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
});
|
||||
server.listen(
|
||||
(HttpRequest request) {
|
||||
Expect.equals("2", request.headers.value('content-length'));
|
||||
Expect.equals(2, request.contentLength);
|
||||
var response = request.response;
|
||||
if (useHeader) {
|
||||
response.contentLength = 2;
|
||||
} else {
|
||||
response.headers.set("content-length", 2);
|
||||
}
|
||||
request.listen(
|
||||
(d) {},
|
||||
onDone: () {
|
||||
response.write("x");
|
||||
Expect.throws(
|
||||
() => response.contentLength = 3,
|
||||
(e) => e is HttpException,
|
||||
);
|
||||
response.write("x");
|
||||
response.write("x");
|
||||
response.done
|
||||
.then((_) {
|
||||
Expect.fail("Unexpected successful response completion");
|
||||
})
|
||||
.catchError((error) {
|
||||
Expect.isTrue(error is HttpException, "[$error]");
|
||||
if (++serverCount == totalConnections) {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
response.close();
|
||||
Expect.throws(() {
|
||||
response.write("x");
|
||||
}, (e) => e is StateError);
|
||||
},
|
||||
);
|
||||
},
|
||||
onError: (e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
},
|
||||
);
|
||||
|
||||
int clientCount = 0;
|
||||
HttpClient client = new HttpClient();
|
||||
for (int i = 0; i < totalConnections; i++) {
|
||||
client.get("127.0.0.1", server.port, "/").then((request) {
|
||||
if (useHeader) {
|
||||
request.contentLength = 2;
|
||||
} else {
|
||||
request.headers.add(HttpHeaders.contentLengthHeader, "7");
|
||||
request.headers.add(HttpHeaders.contentLengthHeader, "2");
|
||||
}
|
||||
request.write("x");
|
||||
Expect.throws(
|
||||
() => request.contentLength = 3, (e) => e is HttpException);
|
||||
request.write("x");
|
||||
return request.close();
|
||||
}).then((response) {
|
||||
Expect.equals("2", response.headers.value('content-length'));
|
||||
Expect.equals(2, response.contentLength);
|
||||
response.listen((d) {}, onDone: () {
|
||||
if (++clientCount == totalConnections) {
|
||||
client.close();
|
||||
}
|
||||
}, onError: (error, trace) {
|
||||
// Undefined what server response sends.
|
||||
});
|
||||
}).catchError((error) {
|
||||
// It's also okay to fail, as headers may not be written.
|
||||
});
|
||||
client
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) {
|
||||
if (useHeader) {
|
||||
request.contentLength = 2;
|
||||
} else {
|
||||
request.headers.add(HttpHeaders.contentLengthHeader, "7");
|
||||
request.headers.add(HttpHeaders.contentLengthHeader, "2");
|
||||
}
|
||||
request.write("x");
|
||||
Expect.throws(
|
||||
() => request.contentLength = 3,
|
||||
(e) => e is HttpException,
|
||||
);
|
||||
request.write("x");
|
||||
return request.close();
|
||||
})
|
||||
.then((response) {
|
||||
Expect.equals("2", response.headers.value('content-length'));
|
||||
Expect.equals(2, response.contentLength);
|
||||
response.listen(
|
||||
(d) {},
|
||||
onDone: () {
|
||||
if (++clientCount == totalConnections) {
|
||||
client.close();
|
||||
}
|
||||
},
|
||||
onError: (error, trace) {
|
||||
// Undefined what server response sends.
|
||||
},
|
||||
);
|
||||
})
|
||||
.catchError((error) {
|
||||
// It's also okay to fail, as headers may not be written.
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void testBodyChunked(int totalConnections, bool useHeader) {
|
||||
HttpServer.bind("127.0.0.1", 0, backlog: totalConnections).then((server) {
|
||||
server.listen((HttpRequest request) {
|
||||
Expect.isNull(request.headers.value('content-length'));
|
||||
Expect.equals(-1, request.contentLength);
|
||||
var response = request.response;
|
||||
if (useHeader) {
|
||||
response.contentLength = 2;
|
||||
response.headers.chunkedTransferEncoding = true;
|
||||
} else {
|
||||
response.headers.set("content-length", 2);
|
||||
response.headers.set("transfer-encoding", "chunked");
|
||||
}
|
||||
request.listen((d) {}, onDone: () {
|
||||
response.write("x");
|
||||
Expect.throws(() => response.headers.chunkedTransferEncoding = false,
|
||||
(e) => e is HttpException);
|
||||
response.write("x");
|
||||
response.write("x");
|
||||
response.close();
|
||||
Expect.throws(() {
|
||||
response.write("x");
|
||||
}, (e) => e is StateError);
|
||||
});
|
||||
}, onError: (e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
});
|
||||
server.listen(
|
||||
(HttpRequest request) {
|
||||
Expect.isNull(request.headers.value('content-length'));
|
||||
Expect.equals(-1, request.contentLength);
|
||||
var response = request.response;
|
||||
if (useHeader) {
|
||||
response.contentLength = 2;
|
||||
response.headers.chunkedTransferEncoding = true;
|
||||
} else {
|
||||
response.headers.set("content-length", 2);
|
||||
response.headers.set("transfer-encoding", "chunked");
|
||||
}
|
||||
request.listen(
|
||||
(d) {},
|
||||
onDone: () {
|
||||
response.write("x");
|
||||
Expect.throws(
|
||||
() => response.headers.chunkedTransferEncoding = false,
|
||||
(e) => e is HttpException,
|
||||
);
|
||||
response.write("x");
|
||||
response.write("x");
|
||||
response.close();
|
||||
Expect.throws(() {
|
||||
response.write("x");
|
||||
}, (e) => e is StateError);
|
||||
},
|
||||
);
|
||||
},
|
||||
onError: (e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
},
|
||||
);
|
||||
|
||||
int count = 0;
|
||||
HttpClient client = new HttpClient();
|
||||
for (int i = 0; i < totalConnections; i++) {
|
||||
client.get("127.0.0.1", server.port, "/").then((request) {
|
||||
if (useHeader) {
|
||||
request.contentLength = 2;
|
||||
request.headers.chunkedTransferEncoding = true;
|
||||
} else {
|
||||
request.headers.add(HttpHeaders.contentLengthHeader, "2");
|
||||
request.headers.set(HttpHeaders.transferEncodingHeader, "chunked");
|
||||
}
|
||||
request.write("x");
|
||||
Expect.throws(() => request.headers.chunkedTransferEncoding = false,
|
||||
(e) => e is HttpException);
|
||||
request.write("x");
|
||||
request.write("x");
|
||||
return request.close();
|
||||
}).then((response) {
|
||||
Expect.isNull(response.headers.value('content-length'));
|
||||
Expect.equals(-1, response.contentLength);
|
||||
response.listen((d) {}, onDone: () {
|
||||
if (++count == totalConnections) {
|
||||
client.close();
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
}).catchError((e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
});
|
||||
client
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) {
|
||||
if (useHeader) {
|
||||
request.contentLength = 2;
|
||||
request.headers.chunkedTransferEncoding = true;
|
||||
} else {
|
||||
request.headers.add(HttpHeaders.contentLengthHeader, "2");
|
||||
request.headers.set(
|
||||
HttpHeaders.transferEncodingHeader,
|
||||
"chunked",
|
||||
);
|
||||
}
|
||||
request.write("x");
|
||||
Expect.throws(
|
||||
() => request.headers.chunkedTransferEncoding = false,
|
||||
(e) => e is HttpException,
|
||||
);
|
||||
request.write("x");
|
||||
request.write("x");
|
||||
return request.close();
|
||||
})
|
||||
.then((response) {
|
||||
Expect.isNull(response.headers.value('content-length'));
|
||||
Expect.equals(-1, response.contentLength);
|
||||
response.listen(
|
||||
(d) {},
|
||||
onDone: () {
|
||||
if (++count == totalConnections) {
|
||||
client.close();
|
||||
server.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
})
|
||||
.catchError((e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -216,11 +265,14 @@ void testSetContentLength() {
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
client.close();
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
client.close();
|
||||
server.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -12,10 +12,24 @@ var _parseCookieDate = Testing$HttpDate.test$_parseCookieDate;
|
||||
void testParseHttpCookieDate() {
|
||||
Expect.throws(() => _parseCookieDate(""));
|
||||
|
||||
test(int year, int month, int day, int hours, int minutes, int seconds,
|
||||
String formatted) {
|
||||
DateTime date =
|
||||
new DateTime.utc(year, month, day, hours, minutes, seconds, 0);
|
||||
test(
|
||||
int year,
|
||||
int month,
|
||||
int day,
|
||||
int hours,
|
||||
int minutes,
|
||||
int seconds,
|
||||
String formatted,
|
||||
) {
|
||||
DateTime date = new DateTime.utc(
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hours,
|
||||
minutes,
|
||||
seconds,
|
||||
0,
|
||||
);
|
||||
Expect.equals(date, _parseCookieDate(formatted));
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ void testCookies() {
|
||||
{'abc': 'def'},
|
||||
{'ABC': 'DEF'},
|
||||
{'Abc': 'Def'},
|
||||
{'Abc': 'Def', 'SID': 'sffFSDF4FsdfF56765'}
|
||||
{'Abc': 'Def', 'SID': 'sffFSDF4FsdfF56765'},
|
||||
];
|
||||
|
||||
HttpServer.bind("127.0.0.1", 0).then((server) {
|
||||
@@ -31,29 +31,36 @@ void testCookies() {
|
||||
int count = 0;
|
||||
HttpClient client = new HttpClient();
|
||||
for (int i = 0; i < cookies.length; i++) {
|
||||
client.get("127.0.0.1", server.port, "/$i").then((request) {
|
||||
// Send the cookies to the server.
|
||||
cookies[i].forEach((k, v) {
|
||||
request.cookies.add(new Cookie(k, v));
|
||||
});
|
||||
return request.close();
|
||||
}).then((response) {
|
||||
// Expect the same cookies back.
|
||||
var cookiesMap = {};
|
||||
response.cookies.forEach((c) => cookiesMap[c.name] = c.value);
|
||||
Expect.mapEquals(cookies[i], cookiesMap);
|
||||
response.cookies.forEach((c) => Expect.isTrue(c.httpOnly));
|
||||
response.listen((d) {}, onDone: () {
|
||||
if (++count == cookies.length) {
|
||||
client.close();
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
}).catchError((e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
});
|
||||
client
|
||||
.get("127.0.0.1", server.port, "/$i")
|
||||
.then((request) {
|
||||
// Send the cookies to the server.
|
||||
cookies[i].forEach((k, v) {
|
||||
request.cookies.add(new Cookie(k, v));
|
||||
});
|
||||
return request.close();
|
||||
})
|
||||
.then((response) {
|
||||
// Expect the same cookies back.
|
||||
var cookiesMap = {};
|
||||
response.cookies.forEach((c) => cookiesMap[c.name] = c.value);
|
||||
Expect.mapEquals(cookies[i], cookiesMap);
|
||||
response.cookies.forEach((c) => Expect.isTrue(c.httpOnly));
|
||||
response.listen(
|
||||
(d) {},
|
||||
onDone: () {
|
||||
if (++count == cookies.length) {
|
||||
client.close();
|
||||
server.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
})
|
||||
.catchError((e, trace) {
|
||||
String msg = "Unexpected error $e";
|
||||
if (trace != null) msg += "\nStackTrace: $trace";
|
||||
Expect.fail(msg);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -63,24 +70,35 @@ void testValidateCookieWithDoubleQuotes() {
|
||||
Expect.equals(Cookie('key', '').toString(), 'key=; HttpOnly');
|
||||
Expect.equals(Cookie('key', '""').toString(), 'key=""; HttpOnly');
|
||||
Expect.equals(Cookie('key', '"value"').toString(), 'key="value"; HttpOnly');
|
||||
Expect.equals(Cookie.fromSetCookieValue('key=value; HttpOnly').toString(),
|
||||
'key=value; HttpOnly');
|
||||
Expect.equals(
|
||||
Cookie.fromSetCookieValue('key=; HttpOnly').toString(), 'key=; HttpOnly');
|
||||
Expect.equals(Cookie.fromSetCookieValue('key=""; HttpOnly').toString(),
|
||||
'key=""; HttpOnly');
|
||||
Expect.equals(Cookie.fromSetCookieValue('key="value"; HttpOnly').toString(),
|
||||
'key="value"; HttpOnly');
|
||||
Cookie.fromSetCookieValue('key=value; HttpOnly').toString(),
|
||||
'key=value; HttpOnly',
|
||||
);
|
||||
Expect.equals(
|
||||
Cookie.fromSetCookieValue('key=; HttpOnly').toString(),
|
||||
'key=; HttpOnly',
|
||||
);
|
||||
Expect.equals(
|
||||
Cookie.fromSetCookieValue('key=""; HttpOnly').toString(),
|
||||
'key=""; HttpOnly',
|
||||
);
|
||||
Expect.equals(
|
||||
Cookie.fromSetCookieValue('key="value"; HttpOnly').toString(),
|
||||
'key="value"; HttpOnly',
|
||||
);
|
||||
Expect.throwsFormatException(() => Cookie('key', '"'));
|
||||
Expect.throwsFormatException(() => Cookie('key', '"""'));
|
||||
Expect.throwsFormatException(() => Cookie('key', '"x""'));
|
||||
Expect.throwsFormatException(() => Cookie('key', '"x"y"'));
|
||||
Expect.throwsFormatException(
|
||||
() => Cookie.fromSetCookieValue('key="; HttpOnly'));
|
||||
() => Cookie.fromSetCookieValue('key="; HttpOnly'),
|
||||
);
|
||||
Expect.throwsFormatException(
|
||||
() => Cookie.fromSetCookieValue('key="""; HttpOnly'));
|
||||
() => Cookie.fromSetCookieValue('key="""; HttpOnly'),
|
||||
);
|
||||
Expect.throwsFormatException(
|
||||
() => Cookie.fromSetCookieValue('key="x""; HttpOnly'));
|
||||
() => Cookie.fromSetCookieValue('key="x""; HttpOnly'),
|
||||
);
|
||||
}
|
||||
|
||||
void testValidatePath() {
|
||||
@@ -112,37 +130,51 @@ void testValidatePath() {
|
||||
|
||||
void testCookieSameSite() {
|
||||
Cookie cookie1 = Cookie.fromSetCookieValue(
|
||||
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; Secure; "
|
||||
"HttpOnly; Path=/; SameSite=None");
|
||||
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; Secure; "
|
||||
"HttpOnly; Path=/; SameSite=None",
|
||||
);
|
||||
Expect.equals(cookie1.sameSite, SameSite.none);
|
||||
Cookie cookie2 = Cookie.fromSetCookieValue(
|
||||
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
|
||||
"Path=/; SameSite=Lax");
|
||||
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
|
||||
"Path=/; SameSite=Lax",
|
||||
);
|
||||
Expect.equals(cookie2.sameSite, SameSite.lax);
|
||||
Cookie cookie3 = Cookie.fromSetCookieValue(
|
||||
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
|
||||
"Path=/; SameSite=LAX");
|
||||
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
|
||||
"Path=/; SameSite=LAX",
|
||||
);
|
||||
Expect.equals(cookie3.sameSite, SameSite.lax);
|
||||
Cookie cookie4 = Cookie.fromSetCookieValue(
|
||||
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
|
||||
"Path=/; SameSite= Lax");
|
||||
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
|
||||
"Path=/; SameSite= Lax",
|
||||
);
|
||||
Expect.equals(cookie4.sameSite, SameSite.lax);
|
||||
Cookie cookie5 = Cookie.fromSetCookieValue(
|
||||
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
|
||||
"Path=/; sAmEsItE= nOnE");
|
||||
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
|
||||
"Path=/; sAmEsItE= nOnE",
|
||||
);
|
||||
Expect.equals(cookie5.sameSite, SameSite.none);
|
||||
Expect.throws<HttpException>(() => Cookie.fromSetCookieValue(
|
||||
Expect.throws<HttpException>(
|
||||
() => Cookie.fromSetCookieValue(
|
||||
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
|
||||
"Path=/; SameSite=Relax"),
|
||||
(e) => e.message == "SameSite value should be one of Lax, Strict or None.");
|
||||
Expect.throws<HttpException>(() => Cookie.fromSetCookieValue(
|
||||
"Path=/; SameSite=Relax",
|
||||
),
|
||||
(e) => e.message == "SameSite value should be one of Lax, Strict or None.",
|
||||
);
|
||||
Expect.throws<HttpException>(
|
||||
() => Cookie.fromSetCookieValue(
|
||||
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
|
||||
"Path=/; SameSite="),
|
||||
(e) => e.message == "SameSite value should be one of Lax, Strict or None.");
|
||||
Expect.throws<HttpException>(() => Cookie.fromSetCookieValue(
|
||||
"Path=/; SameSite=",
|
||||
),
|
||||
(e) => e.message == "SameSite value should be one of Lax, Strict or None.",
|
||||
);
|
||||
Expect.throws<HttpException>(
|
||||
() => Cookie.fromSetCookieValue(
|
||||
"name=cookie_name; Expires=Sat, 01 Apr 2023 00:00:00 GMT; HttpOnly; "
|
||||
"Path=/; SameSite=无"),
|
||||
(e) => e.message == "SameSite value should be one of Lax, Strict or None.");
|
||||
"Path=/; SameSite=无",
|
||||
),
|
||||
(e) => e.message == "SameSite value should be one of Lax, Strict or None.",
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
@@ -35,13 +35,13 @@ Future makeServer() {
|
||||
|
||||
Future runClientProcess(int port) {
|
||||
return Process.run(
|
||||
Platform.executable,
|
||||
[]
|
||||
..addAll(Platform.executableArguments)
|
||||
..add(Platform.script.toFilePath())
|
||||
..add('--client')
|
||||
..add(port.toString()))
|
||||
.then((ProcessResult result) {
|
||||
Platform.executable,
|
||||
[]
|
||||
..addAll(Platform.executableArguments)
|
||||
..add(Platform.script.toFilePath())
|
||||
..add('--client')
|
||||
..add(port.toString()),
|
||||
).then((ProcessResult result) {
|
||||
if (result.exitCode != 0 || !result.stdout.contains('SUCCESS')) {
|
||||
print("Client failed, exit code ${result.exitCode}");
|
||||
print(" stdout:");
|
||||
|
||||
@@ -26,8 +26,15 @@ void testParseHttpDate() {
|
||||
}
|
||||
|
||||
void testFormatParseHttpDate() {
|
||||
test(int year, int month, int day, int hours, int minutes, int seconds,
|
||||
String expectedFormatted) {
|
||||
test(
|
||||
int year,
|
||||
int month,
|
||||
int day,
|
||||
int hours,
|
||||
int minutes,
|
||||
int seconds,
|
||||
String expectedFormatted,
|
||||
) {
|
||||
DateTime date;
|
||||
String formatted;
|
||||
date = new DateTime.utc(year, month, day, hours, minutes, seconds, 0);
|
||||
|
||||
@@ -22,8 +22,10 @@ void testServerDetachSocket() {
|
||||
response.detachSocket().then((socket) {
|
||||
Expect.isNotNull(socket);
|
||||
var body = new StringBuffer();
|
||||
socket.listen((data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () => Expect.equals("Some data", body.toString()));
|
||||
socket.listen(
|
||||
(data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () => Expect.equals("Some data", body.toString()),
|
||||
);
|
||||
socket.write("Test!");
|
||||
socket.close();
|
||||
});
|
||||
@@ -31,20 +33,25 @@ void testServerDetachSocket() {
|
||||
});
|
||||
|
||||
Socket.connect("127.0.0.1", server.port).then((socket) {
|
||||
socket.write("GET / HTTP/1.1\r\n"
|
||||
"content-length: 0\r\n\r\n"
|
||||
"Some data");
|
||||
socket.write(
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"content-length: 0\r\n\r\n"
|
||||
"Some data",
|
||||
);
|
||||
var body = new StringBuffer();
|
||||
socket.listen((data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
Expect.equals(
|
||||
socket.listen(
|
||||
(data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
Expect.equals(
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"content-length: 0\r\n"
|
||||
"\r\n"
|
||||
"Test!",
|
||||
body.toString());
|
||||
socket.close();
|
||||
});
|
||||
body.toString(),
|
||||
);
|
||||
socket.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -57,8 +64,10 @@ void testServerDetachSocketNoWriteHeaders() {
|
||||
response.detachSocket(writeHeaders: false).then((socket) {
|
||||
Expect.isNotNull(socket);
|
||||
var body = new StringBuffer();
|
||||
socket.listen((data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () => Expect.equals("Some data", body.toString()));
|
||||
socket.listen(
|
||||
(data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () => Expect.equals("Some data", body.toString()),
|
||||
);
|
||||
socket.write("Test!");
|
||||
socket.close();
|
||||
});
|
||||
@@ -66,15 +75,19 @@ void testServerDetachSocketNoWriteHeaders() {
|
||||
});
|
||||
|
||||
Socket.connect("127.0.0.1", server.port).then((socket) {
|
||||
socket.write("GET / HTTP/1.1\r\n"
|
||||
"content-length: 0\r\n\r\n"
|
||||
"Some data");
|
||||
socket.write(
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"content-length: 0\r\n\r\n"
|
||||
"Some data",
|
||||
);
|
||||
var body = new StringBuffer();
|
||||
socket.listen((data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
Expect.equals("Test!", body.toString());
|
||||
socket.close();
|
||||
});
|
||||
socket.listen(
|
||||
(data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
Expect.equals("Test!", body.toString());
|
||||
socket.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -90,11 +103,16 @@ void testBadServerDetachSocket() {
|
||||
});
|
||||
|
||||
Socket.connect("127.0.0.1", server.port).then((socket) {
|
||||
socket.write("GET / HTTP/1.1\r\n"
|
||||
"content-length: 0\r\n\r\n");
|
||||
socket.listen((_) {}, onDone: () {
|
||||
socket.close();
|
||||
});
|
||||
socket.write(
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"content-length: 0\r\n\r\n",
|
||||
);
|
||||
socket.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
socket.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -103,22 +121,26 @@ void testClientDetachSocket() {
|
||||
ServerSocket.bind("127.0.0.1", 0).then((server) {
|
||||
server.listen((socket) {
|
||||
int port = server.port;
|
||||
socket.write("HTTP/1.1 200 OK\r\n"
|
||||
"\r\n"
|
||||
"Test!");
|
||||
socket.write(
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"\r\n"
|
||||
"Test!",
|
||||
);
|
||||
var body = new StringBuffer();
|
||||
socket.listen((data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
List<String> lines = body.toString().split("\r\n");
|
||||
Expect.equals(5, lines.length);
|
||||
Expect.equals("GET / HTTP/1.1", lines[0]);
|
||||
Expect.equals("", lines[3]);
|
||||
Expect.equals("Some data", lines[4]);
|
||||
lines.sort(); // Lines 1-2 becomes 3-4 in a fixed order.
|
||||
Expect.equals("accept-encoding: gzip", lines[3]);
|
||||
Expect.equals("host: 127.0.0.1:${port}", lines[4]);
|
||||
socket.close();
|
||||
});
|
||||
socket.listen(
|
||||
(data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
List<String> lines = body.toString().split("\r\n");
|
||||
Expect.equals(5, lines.length);
|
||||
Expect.equals("GET / HTTP/1.1", lines[0]);
|
||||
Expect.equals("", lines[3]);
|
||||
Expect.equals("Some data", lines[4]);
|
||||
lines.sort(); // Lines 1-2 becomes 3-4 in a fixed order.
|
||||
Expect.equals("accept-encoding: gzip", lines[3]);
|
||||
Expect.equals("host: 127.0.0.1:${port}", lines[4]);
|
||||
socket.close();
|
||||
},
|
||||
);
|
||||
server.close();
|
||||
});
|
||||
|
||||
@@ -128,17 +150,19 @@ void testClientDetachSocket() {
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
response.detachSocket().then((socket) {
|
||||
var body = new StringBuffer();
|
||||
socket.listen((data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
Expect.equals("Test!", body.toString());
|
||||
client.close();
|
||||
response.detachSocket().then((socket) {
|
||||
var body = new StringBuffer();
|
||||
socket.listen(
|
||||
(data) => body.write(new String.fromCharCodes(data)),
|
||||
onDone: () {
|
||||
Expect.equals("Test!", body.toString());
|
||||
client.close();
|
||||
},
|
||||
);
|
||||
socket.write("Some data");
|
||||
socket.close();
|
||||
});
|
||||
});
|
||||
socket.write("Some data");
|
||||
socket.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -161,30 +185,36 @@ void testUpgradedConnection() {
|
||||
|
||||
var client = new HttpClient();
|
||||
client.userAgent = null;
|
||||
client.get("127.0.0.1", server.port, "/").then((request) {
|
||||
request.headers.set('upgrade', 'mine');
|
||||
return request.close();
|
||||
}).then((response) {
|
||||
client.get("127.0.0.1", server.port, "/").then((request) {
|
||||
response.detachSocket().then((socket) {
|
||||
// We are testing that we can detach the socket, even though
|
||||
// we made a new connection (testing it was not reused).
|
||||
request.close().then((response) {
|
||||
asyncStart();
|
||||
response.listen(null, onDone: () {
|
||||
server.close();
|
||||
asyncEnd();
|
||||
});
|
||||
socket.add([0]);
|
||||
socket.close();
|
||||
socket.fold<List<int>>([], (l, d) => l..addAll(d)).then((data) {
|
||||
asyncEnd();
|
||||
Expect.listEquals([0], data);
|
||||
client
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) {
|
||||
request.headers.set('upgrade', 'mine');
|
||||
return request.close();
|
||||
})
|
||||
.then((response) {
|
||||
client.get("127.0.0.1", server.port, "/").then((request) {
|
||||
response.detachSocket().then((socket) {
|
||||
// We are testing that we can detach the socket, even though
|
||||
// we made a new connection (testing it was not reused).
|
||||
request.close().then((response) {
|
||||
asyncStart();
|
||||
response.listen(
|
||||
null,
|
||||
onDone: () {
|
||||
server.close();
|
||||
asyncEnd();
|
||||
},
|
||||
);
|
||||
socket.add([0]);
|
||||
socket.close();
|
||||
socket.fold<List<int>>([], (l, d) => l..addAll(d)).then((data) {
|
||||
asyncEnd();
|
||||
Expect.listEquals([0], data);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,14 @@ const sampleData = <int>[1, 2, 3, 4, 5];
|
||||
void testBadHostName() {
|
||||
asyncStart();
|
||||
HttpClient client = new HttpClient();
|
||||
client.get("some.bad.host.name.7654321", 0, "/").then((request) {
|
||||
Expect.fail("Should not open a request on bad hostname");
|
||||
}).catchError((error) {
|
||||
asyncEnd(); // We expect onError to be called, due to bad host name.
|
||||
}, test: (error) => error is! String);
|
||||
client
|
||||
.get("some.bad.host.name.7654321", 0, "/")
|
||||
.then((request) {
|
||||
Expect.fail("Should not open a request on bad hostname");
|
||||
})
|
||||
.catchError((error) {
|
||||
asyncEnd(); // We expect onError to be called, due to bad host name.
|
||||
}, test: (error) => error is! String);
|
||||
}
|
||||
|
||||
void testConnect(InternetAddress loopback, {int expectedElapsedMs = 0}) async {
|
||||
@@ -37,24 +40,31 @@ void testConnect(InternetAddress loopback, {int expectedElapsedMs = 0}) async {
|
||||
final sw = Stopwatch()..start();
|
||||
var got = 0;
|
||||
for (var i = 0; i < max; i++) {
|
||||
final client = await Socket.connect('localhost', servers[i].port,
|
||||
sourceAddress: loopback);
|
||||
client.listen((received) {
|
||||
Expect.listEquals(sampleData, received);
|
||||
}, onError: (e) {
|
||||
Expect.fail('Unexpected failure $e');
|
||||
}, onDone: () {
|
||||
client.close();
|
||||
got++;
|
||||
if (got == max) {
|
||||
// Test that no stack overflow happens.
|
||||
for (final server in servers) {
|
||||
server.close();
|
||||
final client = await Socket.connect(
|
||||
'localhost',
|
||||
servers[i].port,
|
||||
sourceAddress: loopback,
|
||||
);
|
||||
client.listen(
|
||||
(received) {
|
||||
Expect.listEquals(sampleData, received);
|
||||
},
|
||||
onError: (e) {
|
||||
Expect.fail('Unexpected failure $e');
|
||||
},
|
||||
onDone: () {
|
||||
client.close();
|
||||
got++;
|
||||
if (got == max) {
|
||||
// Test that no stack overflow happens.
|
||||
for (final server in servers) {
|
||||
server.close();
|
||||
}
|
||||
Expect.isTrue(sw.elapsedMilliseconds > expectedElapsedMs);
|
||||
asyncEnd();
|
||||
}
|
||||
Expect.isTrue(sw.elapsedMilliseconds > expectedElapsedMs);
|
||||
asyncEnd();
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,8 +78,10 @@ void main() async {
|
||||
if (localhosts.contains(InternetAddress.loopbackIPv6)) {
|
||||
// matches value in socket_patch.dart
|
||||
const concurrentLookupDelay = Duration(milliseconds: 10);
|
||||
testConnect(InternetAddress.loopbackIPv6,
|
||||
expectedElapsedMs: concurrentLookupDelay.inMilliseconds);
|
||||
testConnect(
|
||||
InternetAddress.loopbackIPv6,
|
||||
expectedElapsedMs: concurrentLookupDelay.inMilliseconds,
|
||||
);
|
||||
}
|
||||
asyncEnd();
|
||||
}
|
||||
|
||||
@@ -48,19 +48,23 @@ void testHEAD(int totalConnections) {
|
||||
.open("HEAD", "127.0.0.1", server.port, "/test$len")
|
||||
.then((request) => request.close())
|
||||
.then((HttpClientResponse response) {
|
||||
Expect.equals(len, response.contentLength);
|
||||
response.listen((_) => Expect.fail("Data from HEAD request"),
|
||||
onDone: requestDone);
|
||||
});
|
||||
Expect.equals(len, response.contentLength);
|
||||
response.listen(
|
||||
(_) => Expect.fail("Data from HEAD request"),
|
||||
onDone: requestDone,
|
||||
);
|
||||
});
|
||||
|
||||
client
|
||||
.open("HEAD", "127.0.0.1", server.port, "/testChunked$len")
|
||||
.then((request) => request.close())
|
||||
.then((HttpClientResponse response) {
|
||||
Expect.equals(-1, response.contentLength);
|
||||
response.listen((_) => Expect.fail("Data from HEAD request"),
|
||||
onDone: requestDone);
|
||||
});
|
||||
Expect.equals(-1, response.contentLength);
|
||||
response.listen(
|
||||
(_) => Expect.fail("Data from HEAD request"),
|
||||
onDone: requestDone,
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12,30 +12,38 @@ void test(int totalConnections, [String? body]) {
|
||||
server.listen((HttpRequest request) {
|
||||
HttpResponse response = request.response;
|
||||
// Cannot mutate request headers.
|
||||
Expect.throws(() => request.headers.add("X-Request-Header", "value"),
|
||||
(e) => e is HttpException);
|
||||
Expect.throws(
|
||||
() => request.headers.add("X-Request-Header", "value"),
|
||||
(e) => e is HttpException,
|
||||
);
|
||||
Expect.equals("value", request.headers.value("X-Request-Header"));
|
||||
request.listen((_) {}, onDone: () {
|
||||
// Can still mutate response headers as long as no data has been sent.
|
||||
response.headers.add("X-Response-Header", "value");
|
||||
if (body != null) {
|
||||
response.write(body);
|
||||
// Cannot change state or reason when data has been sent.
|
||||
request.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
// Can still mutate response headers as long as no data has been sent.
|
||||
response.headers.add("X-Response-Header", "value");
|
||||
if (body != null) {
|
||||
response.write(body);
|
||||
// Cannot change state or reason when data has been sent.
|
||||
Expect.throwsStateError(() => response.statusCode = 200);
|
||||
Expect.throwsStateError(() => response.reasonPhrase = "OK");
|
||||
// Cannot mutate response headers when data has been sent.
|
||||
Expect.throws(
|
||||
() => response.headers.add("X-Request-Header", "value2"),
|
||||
(e) => e is HttpException,
|
||||
);
|
||||
}
|
||||
response..close();
|
||||
// Cannot change state or reason after connection is closed.
|
||||
Expect.throwsStateError(() => response.statusCode = 200);
|
||||
Expect.throwsStateError(() => response.reasonPhrase = "OK");
|
||||
// Cannot mutate response headers when data has been sent.
|
||||
// Cannot mutate response headers after connection is closed.
|
||||
Expect.throws(
|
||||
() => response.headers.add("X-Request-Header", "value2"),
|
||||
(e) => e is HttpException);
|
||||
}
|
||||
response..close();
|
||||
// Cannot change state or reason after connection is closed.
|
||||
Expect.throwsStateError(() => response.statusCode = 200);
|
||||
Expect.throwsStateError(() => response.reasonPhrase = "OK");
|
||||
// Cannot mutate response headers after connection is closed.
|
||||
Expect.throws(() => response.headers.add("X-Request-Header", "value3"),
|
||||
(e) => e is HttpException);
|
||||
});
|
||||
() => response.headers.add("X-Request-Header", "value3"),
|
||||
(e) => e is HttpException,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
int count = 0;
|
||||
@@ -44,36 +52,46 @@ void test(int totalConnections, [String? body]) {
|
||||
client
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((HttpClientRequest request) {
|
||||
if (body != null) {
|
||||
request.contentLength = -1;
|
||||
}
|
||||
// Can still mutate request headers as long as no data has been sent.
|
||||
request.headers.add("X-Request-Header", "value");
|
||||
if (body != null) {
|
||||
request.write(body);
|
||||
// Cannot mutate request headers when data has been sent.
|
||||
Expect.throws(() => request.headers.add("X-Request-Header", "value2"),
|
||||
(e) => e is HttpException);
|
||||
}
|
||||
request.close();
|
||||
// Cannot mutate request headers when data has been sent.
|
||||
Expect.throws(() => request.headers.add("X-Request-Header", "value3"),
|
||||
(e) => e is HttpException);
|
||||
return request.done;
|
||||
}).then((HttpClientResponse response) {
|
||||
// Cannot mutate response headers.
|
||||
Expect.throws(() => response.headers.add("X-Response-Header", "value"),
|
||||
(e) => e is HttpException);
|
||||
Expect.equals("value", response.headers.value("X-Response-Header"));
|
||||
response.listen((_) {}, onDone: () {
|
||||
// Do not close the connections before we have read the
|
||||
// full response bodies for all connections.
|
||||
if (++count == totalConnections) {
|
||||
client.close();
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
if (body != null) {
|
||||
request.contentLength = -1;
|
||||
}
|
||||
// Can still mutate request headers as long as no data has been sent.
|
||||
request.headers.add("X-Request-Header", "value");
|
||||
if (body != null) {
|
||||
request.write(body);
|
||||
// Cannot mutate request headers when data has been sent.
|
||||
Expect.throws(
|
||||
() => request.headers.add("X-Request-Header", "value2"),
|
||||
(e) => e is HttpException,
|
||||
);
|
||||
}
|
||||
request.close();
|
||||
// Cannot mutate request headers when data has been sent.
|
||||
Expect.throws(
|
||||
() => request.headers.add("X-Request-Header", "value3"),
|
||||
(e) => e is HttpException,
|
||||
);
|
||||
return request.done;
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
// Cannot mutate response headers.
|
||||
Expect.throws(
|
||||
() => response.headers.add("X-Response-Header", "value"),
|
||||
(e) => e is HttpException,
|
||||
);
|
||||
Expect.equals("value", response.headers.value("X-Response-Header"));
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
// Do not close the connections before we have read the
|
||||
// full response bodies for all connections.
|
||||
if (++count == totalConnections) {
|
||||
client.close();
|
||||
server.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -26,16 +26,25 @@ void testMultiValue() {
|
||||
headers.add(HttpHeaders.pragmaHeader, "pragma2");
|
||||
Expect.equals(2, headers[HttpHeaders.pragmaHeader]!.length);
|
||||
Expect.throws(
|
||||
() => headers.value(HttpHeaders.pragmaHeader), (e) => e is HttpException);
|
||||
() => headers.value(HttpHeaders.pragmaHeader),
|
||||
(e) => e is HttpException,
|
||||
);
|
||||
|
||||
headers.add(HttpHeaders.pragmaHeader, ["pragma3", "pragma4"]);
|
||||
Expect.listEquals(["pragma1", "pragma2", "pragma3", "pragma4"],
|
||||
headers[HttpHeaders.pragmaHeader]!);
|
||||
Expect.listEquals([
|
||||
"pragma1",
|
||||
"pragma2",
|
||||
"pragma3",
|
||||
"pragma4",
|
||||
], headers[HttpHeaders.pragmaHeader]!);
|
||||
|
||||
headers.remove(HttpHeaders.pragmaHeader, "pragma3");
|
||||
Expect.equals(3, headers[HttpHeaders.pragmaHeader]!.length);
|
||||
Expect.listEquals(
|
||||
["pragma1", "pragma2", "pragma4"], headers[HttpHeaders.pragmaHeader]!);
|
||||
Expect.listEquals([
|
||||
"pragma1",
|
||||
"pragma2",
|
||||
"pragma4",
|
||||
], headers[HttpHeaders.pragmaHeader]!);
|
||||
|
||||
headers.remove(HttpHeaders.pragmaHeader, "pragma3");
|
||||
Expect.equals(3, headers[HttpHeaders.pragmaHeader]!.length);
|
||||
@@ -269,8 +278,11 @@ void testEnumeration() {
|
||||
}
|
||||
|
||||
void testHeaderValue() {
|
||||
void check(HeaderValue headerValue, String value,
|
||||
[Map<String, String?>? parameters]) {
|
||||
void check(
|
||||
HeaderValue headerValue,
|
||||
String value, [
|
||||
Map<String, String?>? parameters,
|
||||
]) {
|
||||
Expect.equals(value, headerValue.value);
|
||||
if (parameters != null) {
|
||||
Expect.equals(parameters.length, headerValue.parameters.length);
|
||||
@@ -298,28 +310,38 @@ void testHeaderValue() {
|
||||
check(headerValue, "v", {"a": ""});
|
||||
Expect.throws(() => HeaderValue.parse("v;a=\"\\"), (e) => e is HttpException);
|
||||
Expect.throws(
|
||||
() => HeaderValue.parse("v;a=\";b=\"c\""), (e) => e is HttpException);
|
||||
() => HeaderValue.parse("v;a=\";b=\"c\""),
|
||||
(e) => e is HttpException,
|
||||
);
|
||||
Expect.throws(() => HeaderValue.parse("v;a=b c"), (e) => e is HttpException);
|
||||
headerValue = HeaderValue.parse("æ;ø=å");
|
||||
check(headerValue, "æ", {"ø": "å"});
|
||||
headerValue =
|
||||
HeaderValue.parse("xxx; aaa=bbb; ccc=\"\\\";\\a\"; ddd=\" \"");
|
||||
headerValue = HeaderValue.parse(
|
||||
"xxx; aaa=bbb; ccc=\"\\\";\\a\"; ddd=\" \"",
|
||||
);
|
||||
check(headerValue, "xxx", {"aaa": "bbb", "ccc": '\";a', "ddd": " "});
|
||||
headerValue =
|
||||
new HeaderValue("xxx", {"aaa": "bbb", "ccc": '\";a', "ddd": " "});
|
||||
headerValue = new HeaderValue("xxx", {
|
||||
"aaa": "bbb",
|
||||
"ccc": '\";a',
|
||||
"ddd": " ",
|
||||
});
|
||||
check(headerValue, "xxx", {"aaa": "bbb", "ccc": '\";a', "ddd": " "});
|
||||
|
||||
headerValue = HeaderValue.parse("attachment; filename=genome.jpeg;"
|
||||
"modification-date=\"Wed, 12 February 1997 16:29:51 -0500\"");
|
||||
headerValue = HeaderValue.parse(
|
||||
"attachment; filename=genome.jpeg;"
|
||||
"modification-date=\"Wed, 12 February 1997 16:29:51 -0500\"",
|
||||
);
|
||||
var parameters = {
|
||||
"filename": "genome.jpeg",
|
||||
"modification-date": "Wed, 12 February 1997 16:29:51 -0500"
|
||||
"modification-date": "Wed, 12 February 1997 16:29:51 -0500",
|
||||
};
|
||||
check(headerValue, "attachment", parameters);
|
||||
headerValue = new HeaderValue("attachment", parameters);
|
||||
check(headerValue, "attachment", parameters);
|
||||
headerValue = HeaderValue.parse(" attachment ;filename=genome.jpeg ;"
|
||||
"modification-date = \"Wed, 12 February 1997 16:29:51 -0500\"");
|
||||
headerValue = HeaderValue.parse(
|
||||
" attachment ;filename=genome.jpeg ;"
|
||||
"modification-date = \"Wed, 12 February 1997 16:29:51 -0500\"",
|
||||
);
|
||||
check(headerValue, "attachment", parameters);
|
||||
headerValue = HeaderValue.parse("xxx; aaa; bbb; ccc");
|
||||
check(headerValue, "xxx", {"aaa": null, "bbb": null, "ccc": null});
|
||||
@@ -337,14 +359,20 @@ void testHeaderValue() {
|
||||
Expect.equals("v; a", HeaderValue("v", {"a": null}).toString());
|
||||
Expect.equals("v; a; b", HeaderValue("v", {"a": null, "b": null}).toString());
|
||||
Expect.equals(
|
||||
"v; a; b=c", HeaderValue("v", {"a": null, "b": "c"}).toString());
|
||||
"v; a; b=c",
|
||||
HeaderValue("v", {"a": null, "b": "c"}).toString(),
|
||||
);
|
||||
Expect.equals(
|
||||
"v; a=c; b", HeaderValue("v", {"a": "c", "b": null}).toString());
|
||||
"v; a=c; b",
|
||||
HeaderValue("v", {"a": "c", "b": null}).toString(),
|
||||
);
|
||||
Expect.equals("v; a=\"\"", HeaderValue("v", {"a": ""}).toString());
|
||||
Expect.equals("v; a=\"b c\"", HeaderValue("v", {"a": "b c"}).toString());
|
||||
Expect.equals("v; a=\",\"", HeaderValue("v", {"a": ","}).toString());
|
||||
Expect.equals(
|
||||
"v; a=\"\\\\\\\"\"", HeaderValue("v", {"a": "\\\""}).toString());
|
||||
"v; a=\"\\\\\\\"\"",
|
||||
HeaderValue("v", {"a": "\\\""}).toString(),
|
||||
);
|
||||
Expect.equals("v; a=\"ø\"", HeaderValue("v", {"a": "ø"}).toString());
|
||||
}
|
||||
|
||||
@@ -364,7 +392,8 @@ void testContentLength() {
|
||||
|
||||
headers = new _HttpHeaders("1.1");
|
||||
var e = Expect.throws<HttpException>(
|
||||
() => headers.set("content-length", ["cat"]));
|
||||
() => headers.set("content-length", ["cat"]),
|
||||
);
|
||||
Expect.isTrue(e.message.contains("Content-Length must contain only digits"));
|
||||
|
||||
headers = new _HttpHeaders("1.1");
|
||||
@@ -378,7 +407,8 @@ void testContentLength() {
|
||||
headers = new _HttpHeaders("1.1");
|
||||
e = Expect.throws<HttpException>(() => headers.set("content-length", [[]]));
|
||||
Expect.isTrue(
|
||||
e.message.contains("Unexpected type for header named content-length"));
|
||||
e.message.contains("Unexpected type for header named content-length"),
|
||||
);
|
||||
|
||||
headers = new _HttpHeaders("1.1");
|
||||
headers.set("content-length", ["1", "2"]);
|
||||
@@ -388,8 +418,12 @@ void testContentLength() {
|
||||
}
|
||||
|
||||
void testContentType() {
|
||||
void check(ContentType contentType, String primaryType, String subType,
|
||||
[Map<String, String?>? parameters]) {
|
||||
void check(
|
||||
ContentType contentType,
|
||||
String primaryType,
|
||||
String subType, [
|
||||
Map<String, String?>? parameters,
|
||||
]) {
|
||||
Expect.equals(primaryType, contentType.primaryType);
|
||||
Expect.equals(subType, contentType.subType);
|
||||
Expect.equals("$primaryType/$subType", contentType.value);
|
||||
@@ -418,22 +452,31 @@ void testContentType() {
|
||||
Expect.equals("text/html; charset=utf-8", contentType.toString());
|
||||
Expect.throwsUnsupportedError(() => contentType.parameters["xxx"] = "yyy");
|
||||
|
||||
contentType = new ContentType("text", "html",
|
||||
parameters: {"CHARSET": "UTF-8", "xxx": "YYY"});
|
||||
contentType = new ContentType(
|
||||
"text",
|
||||
"html",
|
||||
parameters: {"CHARSET": "UTF-8", "xxx": "YYY"},
|
||||
);
|
||||
check(contentType, "text", "html", {"charset": "utf-8", "xxx": "YYY"});
|
||||
String s = contentType.toString();
|
||||
bool expectedToString = (s == "text/html; charset=utf-8; xxx=YYY" ||
|
||||
bool expectedToString =
|
||||
(s == "text/html; charset=utf-8; xxx=YYY" ||
|
||||
s == "text/html; xxx=YYY; charset=utf-8");
|
||||
Expect.isTrue(expectedToString);
|
||||
contentType = ContentType.parse("text/html; CHARSET=UTF-8; xxx=YYY");
|
||||
check(contentType, "text", "html", {"charset": "utf-8", "xxx": "YYY"});
|
||||
Expect.throwsUnsupportedError(() => contentType.parameters["xxx"] = "yyy");
|
||||
|
||||
contentType = new ContentType("text", "html",
|
||||
charset: "ISO-8859-1", parameters: {"CHARSET": "UTF-8", "xxx": "yyy"});
|
||||
contentType = new ContentType(
|
||||
"text",
|
||||
"html",
|
||||
charset: "ISO-8859-1",
|
||||
parameters: {"CHARSET": "UTF-8", "xxx": "yyy"},
|
||||
);
|
||||
check(contentType, "text", "html", {"charset": "iso-8859-1", "xxx": "yyy"});
|
||||
s = contentType.toString();
|
||||
expectedToString = (s == "text/html; charset=iso-8859-1; xxx=yyy" ||
|
||||
expectedToString =
|
||||
(s == "text/html; charset=iso-8859-1; xxx=yyy" ||
|
||||
s == "text/html; xxx=yyy; charset=iso-8859-1");
|
||||
Expect.isTrue(expectedToString);
|
||||
|
||||
@@ -447,13 +490,15 @@ void testContentType() {
|
||||
check(contentType, "text", "html", {"charset": "utf-8"});
|
||||
contentType = ContentType.parse("text/html; charset=utf-8; xxx=yyy");
|
||||
check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
|
||||
contentType =
|
||||
ContentType.parse(" text/html ; charset = utf-8 ; xxx=yyy ");
|
||||
contentType = ContentType.parse(
|
||||
" text/html ; charset = utf-8 ; xxx=yyy ",
|
||||
);
|
||||
check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
|
||||
contentType = ContentType.parse('text/html; charset=utf-8; xxx="yyy"');
|
||||
check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
|
||||
contentType =
|
||||
ContentType.parse(" text/html ; charset = utf-8 ; xxx=yyy ");
|
||||
contentType = ContentType.parse(
|
||||
" text/html ; charset = utf-8 ; xxx=yyy ",
|
||||
);
|
||||
check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
|
||||
|
||||
contentType = ContentType.parse("text/html; charset=;");
|
||||
@@ -517,79 +562,89 @@ void testCookie() {
|
||||
DateTime date = new DateTime.utc(2014, DateTime.january, 5, 23, 59, 59, 0);
|
||||
cookie.expires = date;
|
||||
checkCookie(
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
|
||||
"; HttpOnly");
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
|
||||
"; HttpOnly",
|
||||
);
|
||||
cookie.maxAge = 567;
|
||||
checkCookie(
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
|
||||
"; Max-Age=567"
|
||||
"; HttpOnly");
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
|
||||
"; Max-Age=567"
|
||||
"; HttpOnly",
|
||||
);
|
||||
cookie.domain = "example.com";
|
||||
checkCookie(
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
|
||||
"; Max-Age=567"
|
||||
"; Domain=example.com"
|
||||
"; HttpOnly");
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
|
||||
"; Max-Age=567"
|
||||
"; Domain=example.com"
|
||||
"; HttpOnly",
|
||||
);
|
||||
cookie.path = "/xxx";
|
||||
checkCookie(
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
|
||||
"; Max-Age=567"
|
||||
"; Domain=example.com"
|
||||
"; Path=/xxx"
|
||||
"; HttpOnly");
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
|
||||
"; Max-Age=567"
|
||||
"; Domain=example.com"
|
||||
"; Path=/xxx"
|
||||
"; HttpOnly",
|
||||
);
|
||||
cookie.secure = true;
|
||||
checkCookie(
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
|
||||
"; Max-Age=567"
|
||||
"; Domain=example.com"
|
||||
"; Path=/xxx"
|
||||
"; Secure"
|
||||
"; HttpOnly");
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
|
||||
"; Max-Age=567"
|
||||
"; Domain=example.com"
|
||||
"; Path=/xxx"
|
||||
"; Secure"
|
||||
"; HttpOnly",
|
||||
);
|
||||
cookie.httpOnly = false;
|
||||
checkCookie(
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
|
||||
"; Max-Age=567"
|
||||
"; Domain=example.com"
|
||||
"; Path=/xxx"
|
||||
"; Secure");
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Expires=Sun, 05 Jan 2014 23:59:59 GMT"
|
||||
"; Max-Age=567"
|
||||
"; Domain=example.com"
|
||||
"; Path=/xxx"
|
||||
"; Secure",
|
||||
);
|
||||
cookie.expires = null;
|
||||
checkCookie(
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Max-Age=567"
|
||||
"; Domain=example.com"
|
||||
"; Path=/xxx"
|
||||
"; Secure");
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Max-Age=567"
|
||||
"; Domain=example.com"
|
||||
"; Path=/xxx"
|
||||
"; Secure",
|
||||
);
|
||||
cookie.maxAge = null;
|
||||
checkCookie(
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Domain=example.com"
|
||||
"; Path=/xxx"
|
||||
"; Secure");
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Domain=example.com"
|
||||
"; Path=/xxx"
|
||||
"; Secure",
|
||||
);
|
||||
cookie.domain = null;
|
||||
checkCookie(
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Path=/xxx"
|
||||
"; Secure");
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Path=/xxx"
|
||||
"; Secure",
|
||||
);
|
||||
cookie.path = null;
|
||||
checkCookie(
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Secure");
|
||||
cookie,
|
||||
"$name=$value"
|
||||
"; Secure",
|
||||
);
|
||||
cookie.secure = false;
|
||||
checkCookie(cookie, "$name=$value");
|
||||
}
|
||||
@@ -607,17 +662,22 @@ void testInvalidCookie() {
|
||||
Expect.throws(() => new _Cookie.fromSetCookieValue("=xxx"));
|
||||
Expect.throws(() => new _Cookie.fromSetCookieValue("xxx"));
|
||||
Expect.throws(
|
||||
() => new _Cookie.fromSetCookieValue("xxx=yyy; expires=12 jan 2013"));
|
||||
() => new _Cookie.fromSetCookieValue("xxx=yyy; expires=12 jan 2013"),
|
||||
);
|
||||
Expect.throws(() => new _Cookie.fromSetCookieValue("x x = y y"));
|
||||
Expect.throws(() => new _Cookie("[4", "y"));
|
||||
Expect.throws(() => new _Cookie("4", "y\""));
|
||||
|
||||
_HttpHeaders headers = new _HttpHeaders("1.1");
|
||||
headers.set(
|
||||
'Cookie', 'DARTSESSID=d3d6fdd78d51aaaf2924c32e991f4349; undefined');
|
||||
'Cookie',
|
||||
'DARTSESSID=d3d6fdd78d51aaaf2924c32e991f4349; undefined',
|
||||
);
|
||||
Expect.equals('DARTSESSID', headers.test$_parseCookies().single.name);
|
||||
Expect.equals('d3d6fdd78d51aaaf2924c32e991f4349',
|
||||
headers.test$_parseCookies().single.value);
|
||||
Expect.equals(
|
||||
'd3d6fdd78d51aaaf2924c32e991f4349',
|
||||
headers.test$_parseCookies().single.value,
|
||||
);
|
||||
}
|
||||
|
||||
void testHeaderLists() {
|
||||
|
||||
@@ -32,12 +32,13 @@ void testHttpIPv6() {
|
||||
.openUrl('GET', url)
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
Expect.equals(response.statusCode, HttpStatus.ok);
|
||||
}).whenComplete(() {
|
||||
server.close();
|
||||
client.close();
|
||||
asyncEnd();
|
||||
});
|
||||
Expect.equals(response.statusCode, HttpStatus.ok);
|
||||
})
|
||||
.whenComplete(() {
|
||||
server.close();
|
||||
client.close();
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,12 @@ Future getData(HttpClient client, int port, bool chunked, int length) {
|
||||
.get("127.0.0.1", port, "/?chunked=$chunked&length=$length")
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
return response
|
||||
.fold<int>(0, (bytes, data) => bytes + data.length)
|
||||
.then((bytes) {
|
||||
Expect.equals(length, bytes);
|
||||
});
|
||||
});
|
||||
return response.fold<int>(0, (bytes, data) => bytes + data.length).then(
|
||||
(bytes) {
|
||||
Expect.equals(length, bytes);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<HttpServer> startServer() {
|
||||
@@ -48,9 +48,9 @@ testKeepAliveNonChunked() {
|
||||
.then((_) => getData(client, server.port, false, 100))
|
||||
.then((_) => getData(client, server.port, false, 100))
|
||||
.then((_) {
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -64,9 +64,9 @@ testKeepAliveChunked() {
|
||||
.then((_) => getData(client, server.port, true, 100))
|
||||
.then((_) => getData(client, server.port, true, 100))
|
||||
.then((_) {
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -83,9 +83,9 @@ testKeepAliveMixed() {
|
||||
.then((_) => getData(client, server.port, true, 100))
|
||||
.then((_) => getData(client, server.port, false, 100))
|
||||
.then((_) {
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,10 @@ String localFile(path) => Platform.script.resolve(path).toFilePath();
|
||||
|
||||
SecurityContext serverContext = new SecurityContext()
|
||||
..useCertificateChain(localFile('certificates/server_chain.pem'))
|
||||
..usePrivateKey(localFile('certificates/server_key.pem'),
|
||||
password: 'dartdart');
|
||||
..usePrivateKey(
|
||||
localFile('certificates/server_key.pem'),
|
||||
password: 'dartdart',
|
||||
);
|
||||
|
||||
Future<HttpServer> startEchoServer() {
|
||||
return HttpServer.bindSecure(HOST, 0, serverContext).then((server) {
|
||||
@@ -45,8 +47,9 @@ testSuccess(HttpServer server) async {
|
||||
client.keyLog = (String line) {
|
||||
log += line;
|
||||
};
|
||||
final request =
|
||||
await client.getUrl(Uri.parse('https://localhost:${server.port}/test'));
|
||||
final request = await client.getUrl(
|
||||
Uri.parse('https://localhost:${server.port}/test'),
|
||||
);
|
||||
final response = await request.close();
|
||||
await response.drain();
|
||||
|
||||
@@ -63,8 +66,9 @@ testExceptionInKeyLogFunction(HttpServer server) async {
|
||||
++numCalls;
|
||||
throw FileSystemException("Something bad happened");
|
||||
};
|
||||
final request =
|
||||
await client.getUrl(Uri.parse('https://localhost:${server.port}/test'));
|
||||
final request = await client.getUrl(
|
||||
Uri.parse('https://localhost:${server.port}/test'),
|
||||
);
|
||||
final response = await request.close();
|
||||
await response.drain();
|
||||
|
||||
|
||||
@@ -26,12 +26,15 @@ void main() {
|
||||
HttpServer.bind(ipv6, 0).then((server) {
|
||||
server.listen((request) {
|
||||
var timer = new Timer.periodic(const Duration(milliseconds: 0), (_) {
|
||||
request.response
|
||||
.write('data:${new DateTime.now().millisecondsSinceEpoch}\n\n');
|
||||
request.response.write(
|
||||
'data:${new DateTime.now().millisecondsSinceEpoch}\n\n',
|
||||
);
|
||||
});
|
||||
request.response.done.whenComplete(() {
|
||||
timer.cancel();
|
||||
}).catchError((_) {});
|
||||
request.response.done
|
||||
.whenComplete(() {
|
||||
timer.cancel();
|
||||
})
|
||||
.catchError((_) {});
|
||||
});
|
||||
|
||||
var client = new HttpClient();
|
||||
@@ -39,18 +42,22 @@ void main() {
|
||||
.getUrl(Uri.parse("http://[${ipv6}]:${server.port}"))
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
print(
|
||||
'response: status code: ${response.statusCode}, reason: ${response.reasonPhrase}');
|
||||
int bytes = 0;
|
||||
response.listen((data) {
|
||||
bytes += data.length;
|
||||
if (bytes > 100) {
|
||||
client.close(force: true);
|
||||
}
|
||||
}, onError: (error) {
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
print(
|
||||
'response: status code: ${response.statusCode}, reason: ${response.reasonPhrase}',
|
||||
);
|
||||
int bytes = 0;
|
||||
response.listen(
|
||||
(data) {
|
||||
bytes += data.length;
|
||||
if (bytes > 100) {
|
||||
client.close(force: true);
|
||||
}
|
||||
},
|
||||
onError: (error) {
|
||||
server.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
asyncEnd();
|
||||
});
|
||||
} catch (e) {
|
||||
|
||||
@@ -23,7 +23,9 @@ makeListener([List<int>? remotePorts]) {
|
||||
/// Verify that you can't connect to loopback via mismatching protocol, e.g.
|
||||
/// if the server is listening to IPv4 then you can't connect via IPv6.
|
||||
Future<void> failureTest(
|
||||
InternetAddress serverAddr, InternetAddress clientAddr) async {
|
||||
InternetAddress serverAddr,
|
||||
InternetAddress clientAddr,
|
||||
) async {
|
||||
final remotePorts = <int>[];
|
||||
final server = await RawServerSocket.bind(serverAddr, 0);
|
||||
server.listen(makeListener(remotePorts));
|
||||
@@ -48,8 +50,10 @@ Future<void> failureTest(
|
||||
} catch (e) {
|
||||
Expect.fail('Unexpected exception: $e');
|
||||
} finally {
|
||||
Expect.isTrue(success,
|
||||
'Unexpected connection to $serverAddr via $clientAddr address!');
|
||||
Expect.isTrue(
|
||||
success,
|
||||
'Unexpected connection to $serverAddr via $clientAddr address!',
|
||||
);
|
||||
await server.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,10 +29,11 @@ void missingReasonPhrase(int statusCode, bool includeSpace) {
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/"))
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
Expect.equals(statusCode, response.statusCode);
|
||||
Expect.equals("", response.reasonPhrase);
|
||||
return response.drain();
|
||||
}).whenComplete(() => server.close());
|
||||
Expect.equals(statusCode, response.statusCode);
|
||||
Expect.equals("", response.reasonPhrase);
|
||||
return response.drain();
|
||||
})
|
||||
.whenComplete(() => server.close());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -13,17 +13,23 @@ Future testHttpServer(String name) async {
|
||||
var address = InternetAddress('$sockname', type: InternetAddressType.unix);
|
||||
var httpServer = await HttpServer.bind(address, 0);
|
||||
var sub;
|
||||
sub = httpServer.listen((HttpRequest request) {
|
||||
request.response.write('Hello, world!');
|
||||
request.response.close();
|
||||
sub.cancel();
|
||||
}, onDone: () {
|
||||
httpServer.close();
|
||||
});
|
||||
sub = httpServer.listen(
|
||||
(HttpRequest request) {
|
||||
request.response.write('Hello, world!');
|
||||
request.response.close();
|
||||
sub.cancel();
|
||||
},
|
||||
onDone: () {
|
||||
httpServer.close();
|
||||
},
|
||||
);
|
||||
|
||||
var option = "--unix-socket $sockname";
|
||||
var result =
|
||||
await Process.run("curl", ["--unix-socket", "$sockname", "localhost"]);
|
||||
var result = await Process.run("curl", [
|
||||
"--unix-socket",
|
||||
"$sockname",
|
||||
"localhost",
|
||||
]);
|
||||
Expect.isTrue(result.stdout.toString().contains('Hello, world!'));
|
||||
}
|
||||
|
||||
|
||||
@@ -8,11 +8,14 @@ import "dart:io";
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
void testInvalidArgumentException(String method) {
|
||||
Expect.throws(() => HttpClient()..open(method, "127.0.0.1", 8080, "/"),
|
||||
(e) => e is ArgumentError);
|
||||
Expect.throws(
|
||||
() => HttpClient()..openUrl(method, Uri.parse("http://127.0.0.1/")),
|
||||
(e) => e is ArgumentError);
|
||||
() => HttpClient()..open(method, "127.0.0.1", 8080, "/"),
|
||||
(e) => e is ArgumentError,
|
||||
);
|
||||
Expect.throws(
|
||||
() => HttpClient()..openUrl(method, Uri.parse("http://127.0.0.1/")),
|
||||
(e) => e is ArgumentError,
|
||||
);
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
@@ -33,19 +33,25 @@ void testChunkedBufferSizeMsg() {
|
||||
request.response.close();
|
||||
});
|
||||
var client = new HttpClient();
|
||||
client.get('127.0.0.1', server.port, '/').then((request) {
|
||||
request.headers.set(HttpHeaders.acceptEncodingHeader, "");
|
||||
return request.close();
|
||||
}).then((response) {
|
||||
var buffer = [];
|
||||
response.listen((data) => buffer.addAll(data), onDone: () {
|
||||
Expect.equals(sendData.length * 8, buffer.length);
|
||||
for (int i = 0; i < buffer.length; i++) {
|
||||
Expect.equals(sendData[i % sendData.length], buffer[i]);
|
||||
}
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
client
|
||||
.get('127.0.0.1', server.port, '/')
|
||||
.then((request) {
|
||||
request.headers.set(HttpHeaders.acceptEncodingHeader, "");
|
||||
return request.close();
|
||||
})
|
||||
.then((response) {
|
||||
var buffer = [];
|
||||
response.listen(
|
||||
(data) => buffer.addAll(data),
|
||||
onDone: () {
|
||||
Expect.equals(sendData.length * 8, buffer.length);
|
||||
for (int i = 0; i < buffer.length; i++) {
|
||||
Expect.equals(sendData[i % sendData.length], buffer[i]);
|
||||
}
|
||||
server.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,11 @@ class MyHttpClient1 implements HttpClient {
|
||||
bool enableTimelineLogging = false;
|
||||
|
||||
Future<HttpClientRequest> open(
|
||||
String method, String host, int port, String path) =>
|
||||
throw "";
|
||||
String method,
|
||||
String host,
|
||||
int port,
|
||||
String path,
|
||||
) => throw "";
|
||||
Future<HttpClientRequest> openUrl(String method, Uri url) => throw "";
|
||||
Future<HttpClientRequest> get(String host, int port, String path) => throw "";
|
||||
Future<HttpClientRequest> getUrl(Uri url) => throw "";
|
||||
@@ -40,18 +43,31 @@ class MyHttpClient1 implements HttpClient {
|
||||
Future<HttpClientRequest> headUrl(Uri url) => throw "";
|
||||
set authenticate(Future<bool> f(Uri url, String scheme, String realm)?) {}
|
||||
void addCredentials(
|
||||
Uri url, String realm, HttpClientCredentials credentials) {}
|
||||
Uri url,
|
||||
String realm,
|
||||
HttpClientCredentials credentials,
|
||||
) {}
|
||||
set connectionFactory(
|
||||
Future<ConnectionTask<Socket>> Function(
|
||||
Uri url, String? proxyHost, int? proxyPort)?
|
||||
f) {}
|
||||
Future<ConnectionTask<Socket>> Function(
|
||||
Uri url,
|
||||
String? proxyHost,
|
||||
int? proxyPort,
|
||||
)?
|
||||
f,
|
||||
) {}
|
||||
set findProxy(String f(Uri url)?) {}
|
||||
set authenticateProxy(
|
||||
Future<bool> f(String host, int port, String scheme, String realm)?) {}
|
||||
Future<bool> f(String host, int port, String scheme, String realm)?,
|
||||
) {}
|
||||
void addProxyCredentials(
|
||||
String host, int port, String realm, HttpClientCredentials credentials) {}
|
||||
String host,
|
||||
int port,
|
||||
String realm,
|
||||
HttpClientCredentials credentials,
|
||||
) {}
|
||||
set badCertificateCallback(
|
||||
bool callback(X509Certificate cert, String host, int port)?) {}
|
||||
bool callback(X509Certificate cert, String host, int port)?,
|
||||
) {}
|
||||
void set keyLog(Function(String line)? callback) {}
|
||||
void close({bool force = false}) {}
|
||||
}
|
||||
@@ -68,8 +84,11 @@ class MyHttpClient2 implements HttpClient {
|
||||
bool enableTimelineLogging = false;
|
||||
|
||||
Future<HttpClientRequest> open(
|
||||
String method, String host, int port, String path) =>
|
||||
throw "";
|
||||
String method,
|
||||
String host,
|
||||
int port,
|
||||
String path,
|
||||
) => throw "";
|
||||
Future<HttpClientRequest> openUrl(String method, Uri url) => throw "";
|
||||
Future<HttpClientRequest> get(String host, int port, String path) => throw "";
|
||||
Future<HttpClientRequest> getUrl(Uri url) => throw "";
|
||||
@@ -89,18 +108,31 @@ class MyHttpClient2 implements HttpClient {
|
||||
Future<HttpClientRequest> headUrl(Uri url) => throw "";
|
||||
set authenticate(Future<bool> f(Uri url, String scheme, String realm)?) {}
|
||||
void addCredentials(
|
||||
Uri url, String realm, HttpClientCredentials credentials) {}
|
||||
Uri url,
|
||||
String realm,
|
||||
HttpClientCredentials credentials,
|
||||
) {}
|
||||
set connectionFactory(
|
||||
Future<ConnectionTask<Socket>> Function(
|
||||
Uri url, String? proxyHost, int? proxyPort)?
|
||||
f) {}
|
||||
Future<ConnectionTask<Socket>> Function(
|
||||
Uri url,
|
||||
String? proxyHost,
|
||||
int? proxyPort,
|
||||
)?
|
||||
f,
|
||||
) {}
|
||||
set findProxy(String f(Uri url)?) {}
|
||||
set authenticateProxy(
|
||||
Future<bool> f(String host, int port, String scheme, String realm)?) {}
|
||||
Future<bool> f(String host, int port, String scheme, String realm)?,
|
||||
) {}
|
||||
void addProxyCredentials(
|
||||
String host, int port, String realm, HttpClientCredentials credentials) {}
|
||||
String host,
|
||||
int port,
|
||||
String realm,
|
||||
HttpClientCredentials credentials,
|
||||
) {}
|
||||
set badCertificateCallback(
|
||||
bool callback(X509Certificate cert, String host, int port)?) {}
|
||||
bool callback(X509Certificate cert, String host, int port)?,
|
||||
) {}
|
||||
void set keyLog(Function(String line)? callback) {}
|
||||
void close({bool force = false}) {}
|
||||
}
|
||||
@@ -170,8 +202,10 @@ nestedDifferentOverridesTest() {
|
||||
Expect.isNotNull(httpClient);
|
||||
Expect.isTrue(httpClient is MyHttpClient1);
|
||||
Expect.equals((new MyHttpClient1(null)).userAgent, httpClient.userAgent);
|
||||
Expect.equals(myFindProxyFromEnvironment(new Uri(), null),
|
||||
HttpClient.findProxyFromEnvironment(new Uri()));
|
||||
Expect.equals(
|
||||
myFindProxyFromEnvironment(new Uri(), null),
|
||||
HttpClient.findProxyFromEnvironment(new Uri()),
|
||||
);
|
||||
}, findProxyFromEnvironment: myFindProxyFromEnvironment);
|
||||
httpClient = new HttpClient();
|
||||
Expect.isNotNull(httpClient);
|
||||
|
||||
@@ -23,24 +23,25 @@ Future<void> test(String header, value) async {
|
||||
client
|
||||
.open(connect, "127.0.0.1", server.port, "/")
|
||||
.then((HttpClientRequest request) {
|
||||
return request.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
Expect.equals(200, response.statusCode);
|
||||
// Headers except Content-Length and Transfer-Encoding header will be read.
|
||||
if (header == HttpHeaders.contentLengthHeader ||
|
||||
header == HttpHeaders.transferEncodingHeader) {
|
||||
Expect.isNull(response.headers[header]);
|
||||
} else {
|
||||
final list = response.headers[header];
|
||||
Expect.isNotNull(list);
|
||||
Expect.equals(1, list!.length);
|
||||
Expect.equals(value, list[0]);
|
||||
}
|
||||
return request.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
Expect.equals(200, response.statusCode);
|
||||
// Headers except Content-Length and Transfer-Encoding header will be read.
|
||||
if (header == HttpHeaders.contentLengthHeader ||
|
||||
header == HttpHeaders.transferEncodingHeader) {
|
||||
Expect.isNull(response.headers[header]);
|
||||
} else {
|
||||
final list = response.headers[header];
|
||||
Expect.isNotNull(list);
|
||||
Expect.equals(1, list!.length);
|
||||
Expect.equals(value, list[0]);
|
||||
}
|
||||
|
||||
client.close(force: true);
|
||||
server.close();
|
||||
completer.complete();
|
||||
});
|
||||
client.close(force: true);
|
||||
server.close();
|
||||
completer.complete();
|
||||
});
|
||||
|
||||
await completer.future;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ Future<void> testFormatException() async {
|
||||
final client = HttpClient()..userAgent = 'Bob’s browser';
|
||||
try {
|
||||
await asyncExpectThrows<FormatException>(
|
||||
client.open("CONNECT", "127.0.0.1", server.port, "/"));
|
||||
client.open("CONNECT", "127.0.0.1", server.port, "/"),
|
||||
);
|
||||
} finally {
|
||||
client.close(force: true);
|
||||
server.close();
|
||||
|
||||
@@ -18,8 +18,10 @@ String localFile(path) => Platform.script.resolve(path).toFilePath();
|
||||
|
||||
final SecurityContext serverContext = new SecurityContext()
|
||||
..useCertificateChain(localFile('certificates/server_chain.pem'))
|
||||
..usePrivateKey(localFile('certificates/server_key.pem'),
|
||||
password: 'dartdart');
|
||||
..usePrivateKey(
|
||||
localFile('certificates/server_key.pem'),
|
||||
password: 'dartdart',
|
||||
);
|
||||
|
||||
final SecurityContext clientContext = new SecurityContext()
|
||||
..setTrustedCertificates(localFile('certificates/trusted_certs.pem'));
|
||||
@@ -38,10 +40,10 @@ class Server {
|
||||
? HttpServer.bindSecure("localhost", 0, serverContext)
|
||||
: HttpServer.bind("localhost", 0))
|
||||
.then((s) {
|
||||
server = s;
|
||||
server.listen(requestHandler);
|
||||
return this;
|
||||
});
|
||||
server = s;
|
||||
server.listen(requestHandler);
|
||||
return this;
|
||||
});
|
||||
}
|
||||
|
||||
void requestHandler(HttpRequest request) {
|
||||
@@ -49,12 +51,16 @@ class Server {
|
||||
requestCount++;
|
||||
// Check whether a proxy or direct connection is expected.
|
||||
bool direct = directRequestPaths.fold(
|
||||
false, (prev, path) => prev ? prev : path == request.uri.path);
|
||||
false,
|
||||
(prev, path) => prev ? prev : path == request.uri.path,
|
||||
);
|
||||
if (!secure && !direct && proxyHops > 0) {
|
||||
Expect.isNotNull(request.headers[HttpHeaders.viaHeader]);
|
||||
Expect.equals(1, request.headers[HttpHeaders.viaHeader]!.length);
|
||||
Expect.equals(proxyHops,
|
||||
request.headers[HttpHeaders.viaHeader]![0].split(",").length);
|
||||
Expect.equals(
|
||||
proxyHops,
|
||||
request.headers[HttpHeaders.viaHeader]![0].split(",").length,
|
||||
);
|
||||
} else {
|
||||
Expect.isNull(request.headers[HttpHeaders.viaHeader]);
|
||||
}
|
||||
@@ -81,8 +87,11 @@ class Server {
|
||||
int get port => server.port;
|
||||
}
|
||||
|
||||
Future<Server> setupServer(int proxyHops,
|
||||
{List<String> directRequestPaths = const <String>[], secure = false}) {
|
||||
Future<Server> setupServer(
|
||||
int proxyHops, {
|
||||
List<String> directRequestPaths = const <String>[],
|
||||
secure = false,
|
||||
}) {
|
||||
Server server = new Server(proxyHops, directRequestPaths, secure);
|
||||
return server.start();
|
||||
}
|
||||
@@ -125,8 +134,10 @@ class ProxyServer {
|
||||
basicAuthenticationRequired(request) {
|
||||
request.fold(null, (x, y) {}).then((_) {
|
||||
var response = request.response;
|
||||
response.headers
|
||||
.set(HttpHeaders.proxyAuthenticateHeader, "Basic, realm=$realm");
|
||||
response.headers.set(
|
||||
HttpHeaders.proxyAuthenticateHeader,
|
||||
"Basic, realm=$realm",
|
||||
);
|
||||
response.statusCode = HttpStatus.proxyAuthenticationRequired;
|
||||
response.close();
|
||||
});
|
||||
@@ -167,8 +178,10 @@ class ProxyServer {
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
Expect.equals(1,
|
||||
request.headers[HttpHeaders.proxyAuthorizationHeader]!.length);
|
||||
Expect.equals(
|
||||
1,
|
||||
request.headers[HttpHeaders.proxyAuthorizationHeader]!.length,
|
||||
);
|
||||
String authorization =
|
||||
request.headers[HttpHeaders.proxyAuthorizationHeader]![0];
|
||||
if (authScheme == "Basic") {
|
||||
@@ -180,8 +193,10 @@ class ProxyServer {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
HeaderValue header =
|
||||
HeaderValue.parse(authorization, parameterSeparator: ",");
|
||||
HeaderValue header = HeaderValue.parse(
|
||||
authorization,
|
||||
parameterSeparator: ",",
|
||||
);
|
||||
Expect.equals("Digest", header.value);
|
||||
var uri = header.parameters["uri"];
|
||||
var qop = header.parameters["qop"];
|
||||
@@ -214,13 +229,17 @@ class ProxyServer {
|
||||
digest = md5.convert("$ha1:${nonce}:$ha2".codeUnits);
|
||||
} else {
|
||||
digest = md5.convert(
|
||||
"$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits);
|
||||
"$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits,
|
||||
);
|
||||
}
|
||||
Expect.equals(
|
||||
hex.encode(digest.bytes), header.parameters["response"]);
|
||||
hex.encode(digest.bytes),
|
||||
header.parameters["response"],
|
||||
);
|
||||
|
||||
// Add a bogus Proxy-Authentication-Info for testing.
|
||||
var info = 'rspauth="77180d1ab3d6c9de084766977790f482", '
|
||||
var info =
|
||||
'rspauth="77180d1ab3d6c9de084766977790f482", '
|
||||
'cnonce="8f971178", '
|
||||
'nc=000002c74, '
|
||||
'qop=auth';
|
||||
@@ -242,27 +261,30 @@ class ProxyServer {
|
||||
client
|
||||
.openUrl(request.method, request.uri)
|
||||
.then((HttpClientRequest clientRequest) {
|
||||
// Forward all headers.
|
||||
request.headers.forEach((String name, List<String> values) {
|
||||
values.forEach((String value) {
|
||||
if (name != "content-length" && name != "via") {
|
||||
clientRequest.headers.add(name, value);
|
||||
}
|
||||
// Forward all headers.
|
||||
request.headers.forEach((String name, List<String> values) {
|
||||
values.forEach((String value) {
|
||||
if (name != "content-length" && name != "via") {
|
||||
clientRequest.headers.add(name, value);
|
||||
}
|
||||
});
|
||||
});
|
||||
// Special handling of Content-Length and Via.
|
||||
clientRequest.contentLength = request.contentLength;
|
||||
List<String>? via = request.headers[HttpHeaders.viaHeader];
|
||||
String viaPrefix = via == null ? "" : "${via[0]}, ";
|
||||
clientRequest.headers.add(
|
||||
HttpHeaders.viaHeader,
|
||||
"${viaPrefix}1.1 localhost:$port",
|
||||
);
|
||||
// Copy all content.
|
||||
return request.cast<List<int>>().pipe(clientRequest);
|
||||
})
|
||||
.then((clientResponse) {
|
||||
(clientResponse as HttpClientResponse).cast<List<int>>().pipe(
|
||||
request.response,
|
||||
);
|
||||
});
|
||||
});
|
||||
// Special handling of Content-Length and Via.
|
||||
clientRequest.contentLength = request.contentLength;
|
||||
List<String>? via = request.headers[HttpHeaders.viaHeader];
|
||||
String viaPrefix = via == null ? "" : "${via[0]}, ";
|
||||
clientRequest.headers
|
||||
.add(HttpHeaders.viaHeader, "${viaPrefix}1.1 localhost:$port");
|
||||
// Copy all content.
|
||||
return request.cast<List<int>>().pipe(clientRequest);
|
||||
}).then((clientResponse) {
|
||||
(clientResponse as HttpClientResponse)
|
||||
.cast<List<int>>()
|
||||
.pipe(request.response);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -286,8 +308,9 @@ int testProxyIPV6DoneCount = 0;
|
||||
void testProxyIPV6() {
|
||||
setupProxyServer(ipV6: true).then((proxyServer) {
|
||||
setupServer(1, directRequestPaths: ["/4"]).then((server) {
|
||||
setupServer(1, directRequestPaths: ["/4"], secure: true)
|
||||
.then((secureServer) {
|
||||
setupServer(1, directRequestPaths: ["/4"], secure: true).then((
|
||||
secureServer,
|
||||
) {
|
||||
HttpClient client = new HttpClient(context: clientContext);
|
||||
|
||||
List<String> proxy = ["PROXY [::1]:${proxyServer.port}"];
|
||||
@@ -306,22 +329,26 @@ void testProxyIPV6() {
|
||||
client
|
||||
.postUrl(Uri.parse(url))
|
||||
.then((HttpClientRequest clientRequest) {
|
||||
String content = "$i$i$i";
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
testProxyIPV6DoneCount++;
|
||||
if (testProxyIPV6DoneCount == proxy.length * 2) {
|
||||
Expect.equals(proxy.length, server.requestCount);
|
||||
Expect.equals(proxy.length, secureServer.requestCount);
|
||||
proxyServer.shutdown();
|
||||
server.shutdown();
|
||||
secureServer.shutdown();
|
||||
client.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
String content = "$i$i$i";
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
testProxyIPV6DoneCount++;
|
||||
if (testProxyIPV6DoneCount == proxy.length * 2) {
|
||||
Expect.equals(proxy.length, server.requestCount);
|
||||
Expect.equals(proxy.length, secureServer.requestCount);
|
||||
proxyServer.shutdown();
|
||||
server.shutdown();
|
||||
secureServer.shutdown();
|
||||
client.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
test(false);
|
||||
@@ -340,10 +367,13 @@ void testProxyFromEnvironment() {
|
||||
HttpClient client = new HttpClient(context: clientContext);
|
||||
|
||||
client.findProxy = (Uri uri) {
|
||||
return HttpClient.findProxyFromEnvironment(uri, environment: {
|
||||
"http_proxy": "localhost:${proxyServer.port}",
|
||||
"https_proxy": "localhost:${proxyServer.port}"
|
||||
});
|
||||
return HttpClient.findProxyFromEnvironment(
|
||||
uri,
|
||||
environment: {
|
||||
"http_proxy": "localhost:${proxyServer.port}",
|
||||
"https_proxy": "localhost:${proxyServer.port}",
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const int loopCount = 5;
|
||||
@@ -356,22 +386,26 @@ void testProxyFromEnvironment() {
|
||||
client
|
||||
.postUrl(Uri.parse(url))
|
||||
.then((HttpClientRequest clientRequest) {
|
||||
String content = "$i$i$i";
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
testProxyFromEnvironmentDoneCount++;
|
||||
if (testProxyFromEnvironmentDoneCount == loopCount * 2) {
|
||||
Expect.equals(loopCount, server.requestCount);
|
||||
Expect.equals(loopCount, secureServer.requestCount);
|
||||
proxyServer.shutdown();
|
||||
server.shutdown();
|
||||
secureServer.shutdown();
|
||||
client.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
String content = "$i$i$i";
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
testProxyFromEnvironmentDoneCount++;
|
||||
if (testProxyFromEnvironmentDoneCount == loopCount * 2) {
|
||||
Expect.equals(loopCount, server.requestCount);
|
||||
Expect.equals(loopCount, secureServer.requestCount);
|
||||
proxyServer.shutdown();
|
||||
server.shutdown();
|
||||
secureServer.shutdown();
|
||||
client.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
test(false);
|
||||
@@ -384,7 +418,10 @@ void testProxyFromEnvironment() {
|
||||
|
||||
int testProxyAuthenticateCount = 0;
|
||||
Future testProxyAuthenticate(
|
||||
bool useDigestAuthentication, String username, String password) {
|
||||
bool useDigestAuthentication,
|
||||
String username,
|
||||
String password,
|
||||
) {
|
||||
testProxyAuthenticateCount = 0;
|
||||
var completer = new Completer();
|
||||
|
||||
@@ -417,19 +454,21 @@ Future testProxyAuthenticate(
|
||||
client
|
||||
.postUrl(Uri.parse(url))
|
||||
.then((HttpClientRequest clientRequest) {
|
||||
String content = "$i$i$i";
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
Expect.fail("No response expected");
|
||||
}).catchError((e) {
|
||||
testProxyAuthenticateCount++;
|
||||
if (testProxyAuthenticateCount == loopCount * 2) {
|
||||
Expect.equals(0, server.requestCount);
|
||||
Expect.equals(0, secureServer.requestCount);
|
||||
step1.complete(null);
|
||||
}
|
||||
});
|
||||
String content = "$i$i$i";
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
Expect.fail("No response expected");
|
||||
})
|
||||
.catchError((e) {
|
||||
testProxyAuthenticateCount++;
|
||||
if (testProxyAuthenticateCount == loopCount * 2) {
|
||||
Expect.equals(0, server.requestCount);
|
||||
Expect.equals(0, secureServer.requestCount);
|
||||
step1.complete(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
test(false);
|
||||
@@ -438,10 +477,14 @@ Future testProxyAuthenticate(
|
||||
step1.future.then((_) {
|
||||
testProxyAuthenticateCount = 0;
|
||||
if (useDigestAuthentication) {
|
||||
client.findProxy =
|
||||
(Uri uri) => "PROXY localhost:${proxyServer.port}";
|
||||
client.addProxyCredentials("localhost", proxyServer.port, "test",
|
||||
new HttpClientDigestCredentials(username, password));
|
||||
client.findProxy = (Uri uri) =>
|
||||
"PROXY localhost:${proxyServer.port}";
|
||||
client.addProxyCredentials(
|
||||
"localhost",
|
||||
proxyServer.port,
|
||||
"test",
|
||||
new HttpClientDigestCredentials(username, password),
|
||||
);
|
||||
} else {
|
||||
client.findProxy = (Uri uri) {
|
||||
return "PROXY ${username}:${password}@localhost:${proxyServer.port}";
|
||||
@@ -458,20 +501,24 @@ Future testProxyAuthenticate(
|
||||
client
|
||||
.postUrl(Uri.parse(url))
|
||||
.then((HttpClientRequest clientRequest) {
|
||||
String content = "$i$i$i";
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
testProxyAuthenticateCount++;
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
if (testProxyAuthenticateCount == loopCount * 2) {
|
||||
Expect.equals(loopCount, server.requestCount);
|
||||
Expect.equals(loopCount, secureServer.requestCount);
|
||||
step2.complete(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
String content = "$i$i$i";
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
testProxyAuthenticateCount++;
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
if (testProxyAuthenticateCount == loopCount * 2) {
|
||||
Expect.equals(loopCount, server.requestCount);
|
||||
Expect.equals(loopCount, secureServer.requestCount);
|
||||
step2.complete(null);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
test(false);
|
||||
@@ -486,8 +533,12 @@ Future testProxyAuthenticate(
|
||||
};
|
||||
|
||||
client.authenticateProxy = (host, port, scheme, realm) {
|
||||
client.addProxyCredentials("localhost", proxyServer.port, "realm",
|
||||
new HttpClientBasicCredentials(username, password));
|
||||
client.addProxyCredentials(
|
||||
"localhost",
|
||||
proxyServer.port,
|
||||
"realm",
|
||||
new HttpClientBasicCredentials(username, password),
|
||||
);
|
||||
return new Future.value(true);
|
||||
};
|
||||
|
||||
@@ -500,24 +551,31 @@ Future testProxyAuthenticate(
|
||||
client
|
||||
.postUrl(Uri.parse(url))
|
||||
.then((HttpClientRequest clientRequest) {
|
||||
String content = "$i$i$i";
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
testProxyAuthenticateCount++;
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
if (testProxyAuthenticateCount == loopCount * 2) {
|
||||
Expect.equals(loopCount * 2, server.requestCount);
|
||||
Expect.equals(loopCount * 2, secureServer.requestCount);
|
||||
proxyServer.shutdown();
|
||||
server.shutdown();
|
||||
secureServer.shutdown();
|
||||
client.close();
|
||||
completer.complete(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
String content = "$i$i$i";
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
testProxyAuthenticateCount++;
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
if (testProxyAuthenticateCount == loopCount * 2) {
|
||||
Expect.equals(loopCount * 2, server.requestCount);
|
||||
Expect.equals(
|
||||
loopCount * 2,
|
||||
secureServer.requestCount,
|
||||
);
|
||||
proxyServer.shutdown();
|
||||
server.shutdown();
|
||||
secureServer.shutdown();
|
||||
client.close();
|
||||
completer.complete(null);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
test(false);
|
||||
@@ -535,14 +593,18 @@ int testRealProxyDoneCount = 0;
|
||||
void testRealProxy() {
|
||||
setupServer(1).then((server) {
|
||||
HttpClient client = new HttpClient(context: clientContext);
|
||||
client.addProxyCredentials("localhost", 8080, "test",
|
||||
new HttpClientBasicCredentials("dart", "password"));
|
||||
client.addProxyCredentials(
|
||||
"localhost",
|
||||
8080,
|
||||
"test",
|
||||
new HttpClientBasicCredentials("dart", "password"),
|
||||
);
|
||||
|
||||
List<String> proxy = [
|
||||
"PROXY localhost:8080",
|
||||
"PROXY localhost:8080; PROXY hede.hule.hest:8080",
|
||||
"PROXY hede.hule.hest:8080; PROXY localhost:8080",
|
||||
"PROXY localhost:8080; DIRECT"
|
||||
"PROXY localhost:8080; DIRECT",
|
||||
];
|
||||
|
||||
client.findProxy = (Uri uri) {
|
||||
@@ -555,19 +617,23 @@ void testRealProxy() {
|
||||
client
|
||||
.getUrl(Uri.parse("http://localhost:${server.port}/$i"))
|
||||
.then((HttpClientRequest clientRequest) {
|
||||
String content = "$i$i$i";
|
||||
clientRequest.contentLength = content.length;
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
if (++testRealProxyDoneCount == proxy.length) {
|
||||
Expect.equals(proxy.length, server.requestCount);
|
||||
server.shutdown();
|
||||
client.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
String content = "$i$i$i";
|
||||
clientRequest.contentLength = content.length;
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
if (++testRealProxyDoneCount == proxy.length) {
|
||||
Expect.equals(proxy.length, server.requestCount);
|
||||
server.shutdown();
|
||||
client.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -581,7 +647,7 @@ void testRealProxyAuth() {
|
||||
"PROXY dart:password@localhost:8080",
|
||||
"PROXY dart:password@localhost:8080; PROXY hede.hule.hest:8080",
|
||||
"PROXY hede.hule.hest:8080; PROXY dart:password@localhost:8080",
|
||||
"PROXY dart:password@localhost:8080; DIRECT"
|
||||
"PROXY dart:password@localhost:8080; DIRECT",
|
||||
];
|
||||
|
||||
client.findProxy = (Uri uri) {
|
||||
@@ -594,19 +660,23 @@ void testRealProxyAuth() {
|
||||
client
|
||||
.getUrl(Uri.parse("http://localhost:${server.port}/$i"))
|
||||
.then((HttpClientRequest clientRequest) {
|
||||
String content = "$i$i$i";
|
||||
clientRequest.contentLength = content.length;
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
if (++testRealProxyAuthDoneCount == proxy.length) {
|
||||
Expect.equals(proxy.length, server.requestCount);
|
||||
server.shutdown();
|
||||
client.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
String content = "$i$i$i";
|
||||
clientRequest.contentLength = content.length;
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
if (++testRealProxyAuthDoneCount == proxy.length) {
|
||||
Expect.equals(proxy.length, server.requestCount);
|
||||
server.shutdown();
|
||||
client.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,16 +7,22 @@ import "package:expect/expect.dart";
|
||||
|
||||
expect(expected, String uri, environment) {
|
||||
Expect.equals(
|
||||
expected,
|
||||
HttpClient.findProxyFromEnvironment(Uri.parse(uri),
|
||||
environment: environment));
|
||||
expected,
|
||||
HttpClient.findProxyFromEnvironment(
|
||||
Uri.parse(uri),
|
||||
environment: environment,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
expectDirect(String uri, Map<String, String> environment) {
|
||||
Expect.equals(
|
||||
"DIRECT",
|
||||
HttpClient.findProxyFromEnvironment(Uri.parse(uri),
|
||||
environment: environment));
|
||||
"DIRECT",
|
||||
HttpClient.findProxyFromEnvironment(
|
||||
Uri.parse(uri),
|
||||
environment: environment,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
main() {
|
||||
@@ -24,111 +30,143 @@ main() {
|
||||
expectDirect("http://www.google.com", {"http_proxy": ""});
|
||||
expectDirect("http://www.google.com", {"http_proxy": " "});
|
||||
|
||||
expect("PROXY www.proxy.com:1080", "http://www.google.com",
|
||||
{"http_proxy": "www.proxy.com"});
|
||||
expect("PROXY www.proxys.com:1080", "https://www.google.com",
|
||||
{"https_proxy": "www.proxys.com"});
|
||||
expect("PROXY www.proxy.com:8080", "http://www.google.com",
|
||||
{"http_proxy": "www.proxy.com:8080"});
|
||||
expect("PROXY www.proxys.com:8080", "https://www.google.com",
|
||||
{"https_proxy": "www.proxys.com:8080"});
|
||||
expect("PROXY www.proxy.com:1080", "http://www.google.com", {
|
||||
"http_proxy": "www.proxy.com",
|
||||
});
|
||||
expect("PROXY www.proxys.com:1080", "https://www.google.com", {
|
||||
"https_proxy": "www.proxys.com",
|
||||
});
|
||||
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
|
||||
"http_proxy": "www.proxy.com:8080",
|
||||
"https_proxy": "www.proxys.com:8080"
|
||||
});
|
||||
expect("PROXY www.proxys.com:8080", "https://www.google.com", {
|
||||
"https_proxy": "www.proxys.com:8080",
|
||||
});
|
||||
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
|
||||
"http_proxy": "www.proxy.com:8080",
|
||||
"https_proxy": "www.proxys.com:8080",
|
||||
});
|
||||
expect("PROXY www.proxys.com:8080", "https://www.google.com", {
|
||||
"http_proxy": "www.proxy.com:8080",
|
||||
"https_proxy": "www.proxys.com:8080"
|
||||
"https_proxy": "www.proxys.com:8080",
|
||||
});
|
||||
|
||||
expect("PROXY [::ffff:1]:1080", "http://www.google.com",
|
||||
{"http_proxy": "[::ffff:1]"});
|
||||
expect("PROXY [::ffff:2]:1080", "https://www.google.com",
|
||||
{"https_proxy": "[::ffff:2]"});
|
||||
expect("PROXY [::ffff:1]:8080", "http://www.google.com",
|
||||
{"http_proxy": "[::ffff:1]:8080"});
|
||||
expect("PROXY [::ffff:2]:8080", "https://www.google.com",
|
||||
{"https_proxy": "[::ffff:2]:8080"});
|
||||
expect("PROXY [::ffff:1]:8080", "http://www.google.com",
|
||||
{"http_proxy": "[::ffff:1]:8080", "https_proxy": "[::ffff:2]:8080"});
|
||||
expect("PROXY [::ffff:2]:8080", "https://www.google.com",
|
||||
{"http_proxy": "[::ffff:1]:8080", "https_proxy": "[::ffff:2]:8080"});
|
||||
|
||||
expect("PROXY www.proxy.com:1080", "http://www.google.com",
|
||||
{"http_proxy": "http://www.proxy.com"});
|
||||
expect("PROXY www.proxy.com:1080", "http://www.google.com",
|
||||
{"http_proxy": "http://www.proxy.com/"});
|
||||
expect("PROXY www.proxy.com:8080", "http://www.google.com",
|
||||
{"http_proxy": "http://www.proxy.com:8080/"});
|
||||
expect("PROXY www.proxy.com:8080", "http://www.google.com",
|
||||
{"http_proxy": "http://www.proxy.com:8080/index.html"});
|
||||
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
|
||||
"http_proxy": "http://www.proxy.com:8080/",
|
||||
"https_proxy": "http://www.proxys.com:8080/"
|
||||
expect("PROXY [::ffff:1]:1080", "http://www.google.com", {
|
||||
"http_proxy": "[::ffff:1]",
|
||||
});
|
||||
expect("PROXY www.proxys.com:8080", "https://www.google.com", {
|
||||
"http_proxy": "http://www.proxy.com:8080/",
|
||||
"https_proxy": "http://www.proxys.com:8080/"
|
||||
expect("PROXY [::ffff:2]:1080", "https://www.google.com", {
|
||||
"https_proxy": "[::ffff:2]",
|
||||
});
|
||||
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
|
||||
"http_proxy": "[::ffff:1]:8080",
|
||||
});
|
||||
expect("PROXY [::ffff:2]:8080", "https://www.google.com", {
|
||||
"https_proxy": "[::ffff:2]:8080",
|
||||
});
|
||||
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
|
||||
"http_proxy": "[::ffff:1]:8080",
|
||||
"https_proxy": "[::ffff:2]:8080",
|
||||
});
|
||||
expect("PROXY [::ffff:2]:8080", "https://www.google.com", {
|
||||
"http_proxy": "[::ffff:1]:8080",
|
||||
"https_proxy": "[::ffff:2]:8080",
|
||||
});
|
||||
|
||||
expect("PROXY www.proxy.com:1080", "http://www.google.com", {
|
||||
"http_proxy": "http://www.proxy.com",
|
||||
});
|
||||
expect("PROXY www.proxy.com:1080", "http://www.google.com", {
|
||||
"http_proxy": "http://www.proxy.com/",
|
||||
});
|
||||
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
|
||||
"http_proxy": "http://www.proxy.com:8080/",
|
||||
"https_proxy": "http://www.proxys.com:8080/index.html"
|
||||
});
|
||||
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
|
||||
"http_proxy": "http://www.proxy.com:8080/index.html",
|
||||
});
|
||||
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
|
||||
"http_proxy": "http://www.proxy.com:8080/",
|
||||
"https_proxy": "http://www.proxys.com:8080/",
|
||||
});
|
||||
expect("PROXY www.proxys.com:8080", "https://www.google.com", {
|
||||
"http_proxy": "http://www.proxy.com:8080/",
|
||||
"https_proxy": "http://www.proxys.com:8080/index.html"
|
||||
"https_proxy": "http://www.proxys.com:8080/",
|
||||
});
|
||||
expect("PROXY www.proxy.com:8080", "http://www.google.com", {
|
||||
"http_proxy": "http://www.proxy.com:8080/",
|
||||
"https_proxy": "http://www.proxys.com:8080/index.html",
|
||||
});
|
||||
expect("PROXY www.proxys.com:8080", "https://www.google.com", {
|
||||
"http_proxy": "http://www.proxy.com:8080/",
|
||||
"https_proxy": "http://www.proxys.com:8080/index.html",
|
||||
});
|
||||
|
||||
expect("PROXY [::ffff:1]:1080", "http://www.google.com",
|
||||
{"http_proxy": "http://[::ffff:1]"});
|
||||
expect("PROXY [::ffff:1]:1080", "http://www.google.com",
|
||||
{"http_proxy": "http://[::ffff:1]/"});
|
||||
expect("PROXY [::ffff:1]:8080", "http://www.google.com",
|
||||
{"http_proxy": "http://[::ffff:1]:8080/"});
|
||||
expect("PROXY [::ffff:1]:8080", "http://www.google.com",
|
||||
{"http_proxy": "http://[::ffff:1]:8080/index.html"});
|
||||
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
|
||||
"http_proxy": "http://[::ffff:1]:8080/",
|
||||
"https_proxy": "http://[::ffff:1]:8080/"
|
||||
expect("PROXY [::ffff:1]:1080", "http://www.google.com", {
|
||||
"http_proxy": "http://[::ffff:1]",
|
||||
});
|
||||
expect("PROXY [::ffff:2]:8080", "https://www.google.com", {
|
||||
"http_proxy": "http://[::ffff:1]:8080/",
|
||||
"https_proxy": "http://[::ffff:2]:8080/"
|
||||
expect("PROXY [::ffff:1]:1080", "http://www.google.com", {
|
||||
"http_proxy": "http://[::ffff:1]/",
|
||||
});
|
||||
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
|
||||
"http_proxy": "http://[::ffff:1]:8080/",
|
||||
"https_proxy": "http://[::ffff:1]:8080/index.html"
|
||||
});
|
||||
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
|
||||
"http_proxy": "http://[::ffff:1]:8080/index.html",
|
||||
});
|
||||
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
|
||||
"http_proxy": "http://[::ffff:1]:8080/",
|
||||
"https_proxy": "http://[::ffff:1]:8080/",
|
||||
});
|
||||
expect("PROXY [::ffff:2]:8080", "https://www.google.com", {
|
||||
"http_proxy": "http://[::ffff:1]:8080/",
|
||||
"https_proxy": "http://[::ffff:2]:8080/index.html"
|
||||
"https_proxy": "http://[::ffff:2]:8080/",
|
||||
});
|
||||
expect("PROXY [::ffff:1]:8080", "http://www.google.com", {
|
||||
"http_proxy": "http://[::ffff:1]:8080/",
|
||||
"https_proxy": "http://[::ffff:1]:8080/index.html",
|
||||
});
|
||||
expect("PROXY [::ffff:2]:8080", "https://www.google.com", {
|
||||
"http_proxy": "http://[::ffff:1]:8080/",
|
||||
"https_proxy": "http://[::ffff:2]:8080/index.html",
|
||||
});
|
||||
|
||||
expectDirect("http://www.google.com",
|
||||
{"http_proxy": "www.proxy.com:8080", "no_proxy": "www.google.com"});
|
||||
expectDirect("http://www.google.com",
|
||||
{"http_proxy": "www.proxy.com:8080", "no_proxy": "google.com"});
|
||||
expectDirect("http://www.google.com",
|
||||
{"http_proxy": "www.proxy.com:8080", "no_proxy": ".com"});
|
||||
expectDirect("http://www.google.com", {
|
||||
"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": ",, , www.google.edu,,.com "
|
||||
"no_proxy": "www.google.com",
|
||||
});
|
||||
expectDirect("http://www.google.com", {
|
||||
"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": "google.com",
|
||||
});
|
||||
expectDirect("http://www.google.com", {
|
||||
"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": ".com",
|
||||
});
|
||||
expectDirect("http://www.google.com", {
|
||||
"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": ",, , www.google.edu,,.com ",
|
||||
});
|
||||
expectDirect("http://www.google.edu", {
|
||||
"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": ",, , www.google.edu,,.com "
|
||||
"no_proxy": ",, , www.google.edu,,.com ",
|
||||
});
|
||||
expectDirect("http://www.google.com", {"https_proxy": "www.proxy.com:8080"});
|
||||
|
||||
expect("PROXY www.proxy.com:8080", "http://[::ffff:1]",
|
||||
{"http_proxy": "www.proxy.com:8080", "no_proxy": "["});
|
||||
expect("PROXY www.proxy.com:8080", "http://[::ffff:1]",
|
||||
{"http_proxy": "www.proxy.com:8080", "no_proxy": "[]"});
|
||||
expect("PROXY www.proxy.com:8080", "http://[::ffff:1]", {
|
||||
"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": "[",
|
||||
});
|
||||
expect("PROXY www.proxy.com:8080", "http://[::ffff:1]", {
|
||||
"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": "[]",
|
||||
});
|
||||
|
||||
expectDirect("http://[::ffff:1]",
|
||||
{"http_proxy": "www.proxy.com:8080", "no_proxy": "[::ffff:1]"});
|
||||
expectDirect("http://[::ffff:1]", {
|
||||
"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": ",, , www.google.edu,,[::ffff:1] "
|
||||
"no_proxy": "[::ffff:1]",
|
||||
});
|
||||
expectDirect("http://[::ffff:1]", {
|
||||
"http_proxy": "www.proxy.com:8080",
|
||||
"no_proxy": ",, , www.google.edu,,[::ffff:1] ",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -18,8 +18,10 @@ String localFile(path) => Platform.script.resolve(path).toFilePath();
|
||||
|
||||
final SecurityContext serverContext = new SecurityContext()
|
||||
..useCertificateChain(localFile('certificates/server_chain.pem'))
|
||||
..usePrivateKey(localFile('certificates/server_key.pem'),
|
||||
password: 'dartdart');
|
||||
..usePrivateKey(
|
||||
localFile('certificates/server_key.pem'),
|
||||
password: 'dartdart',
|
||||
);
|
||||
|
||||
final SecurityContext clientContext = new SecurityContext()
|
||||
..setTrustedCertificates(localFile('certificates/trusted_certs.pem'));
|
||||
@@ -38,10 +40,10 @@ class Server {
|
||||
? HttpServer.bindSecure("localhost", 0, serverContext)
|
||||
: HttpServer.bind("localhost", 0))
|
||||
.then((s) {
|
||||
server = s;
|
||||
server.listen(requestHandler);
|
||||
return this;
|
||||
});
|
||||
server = s;
|
||||
server.listen(requestHandler);
|
||||
return this;
|
||||
});
|
||||
}
|
||||
|
||||
void requestHandler(HttpRequest request) {
|
||||
@@ -49,12 +51,16 @@ class Server {
|
||||
requestCount++;
|
||||
// Check whether a proxy or direct connection is expected.
|
||||
bool direct = directRequestPaths.fold(
|
||||
false, (prev, path) => prev ? prev : path == request.uri.path);
|
||||
false,
|
||||
(prev, path) => prev ? prev : path == request.uri.path,
|
||||
);
|
||||
if (!secure && !direct && proxyHops > 0) {
|
||||
Expect.isNotNull(request.headers[HttpHeaders.viaHeader]);
|
||||
Expect.equals(1, request.headers[HttpHeaders.viaHeader]!.length);
|
||||
Expect.equals(proxyHops,
|
||||
request.headers[HttpHeaders.viaHeader]![0].split(",").length);
|
||||
Expect.equals(
|
||||
proxyHops,
|
||||
request.headers[HttpHeaders.viaHeader]![0].split(",").length,
|
||||
);
|
||||
} else {
|
||||
Expect.isNull(request.headers[HttpHeaders.viaHeader]);
|
||||
}
|
||||
@@ -81,8 +87,11 @@ class Server {
|
||||
int get port => server.port;
|
||||
}
|
||||
|
||||
Future<Server> setupServer(int proxyHops,
|
||||
{List<String> directRequestPaths = const <String>[], secure = false}) {
|
||||
Future<Server> setupServer(
|
||||
int proxyHops, {
|
||||
List<String> directRequestPaths = const <String>[],
|
||||
secure = false,
|
||||
}) {
|
||||
Server server = new Server(proxyHops, directRequestPaths, secure);
|
||||
return server.start();
|
||||
}
|
||||
@@ -115,8 +124,10 @@ class ProxyServer {
|
||||
basicAuthenticationRequired(request) {
|
||||
request.fold(null, (x, y) {}).then((_) {
|
||||
var response = request.response;
|
||||
response.headers
|
||||
.set(HttpHeaders.proxyAuthenticateHeader, "Basic, realm=$realm");
|
||||
response.headers.set(
|
||||
HttpHeaders.proxyAuthenticateHeader,
|
||||
"Basic, realm=$realm",
|
||||
);
|
||||
response.statusCode = HttpStatus.proxyAuthenticationRequired;
|
||||
response.close();
|
||||
});
|
||||
@@ -157,8 +168,10 @@ class ProxyServer {
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
Expect.equals(1,
|
||||
request.headers[HttpHeaders.proxyAuthorizationHeader]!.length);
|
||||
Expect.equals(
|
||||
1,
|
||||
request.headers[HttpHeaders.proxyAuthorizationHeader]!.length,
|
||||
);
|
||||
String authorization =
|
||||
request.headers[HttpHeaders.proxyAuthorizationHeader]![0];
|
||||
if (authScheme == "Basic") {
|
||||
@@ -170,8 +183,10 @@ class ProxyServer {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
HeaderValue header =
|
||||
HeaderValue.parse(authorization, parameterSeparator: ",");
|
||||
HeaderValue header = HeaderValue.parse(
|
||||
authorization,
|
||||
parameterSeparator: ",",
|
||||
);
|
||||
Expect.equals("Digest", header.value);
|
||||
var uri = header.parameters["uri"];
|
||||
var qop = header.parameters["qop"];
|
||||
@@ -203,13 +218,17 @@ class ProxyServer {
|
||||
digest = md5.convert("$ha1:${nonce}:$ha2".codeUnits);
|
||||
} else {
|
||||
digest = md5.convert(
|
||||
"$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits);
|
||||
"$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits,
|
||||
);
|
||||
}
|
||||
Expect.equals(
|
||||
hex.encode(digest.bytes), header.parameters["response"]);
|
||||
hex.encode(digest.bytes),
|
||||
header.parameters["response"],
|
||||
);
|
||||
|
||||
// Add a bogus Proxy-Authentication-Info for testing.
|
||||
var info = 'rspauth="77180d1ab3d6c9de084766977790f482", '
|
||||
var info =
|
||||
'rspauth="77180d1ab3d6c9de084766977790f482", '
|
||||
'cnonce="8f971178", '
|
||||
'nc=000002c74, '
|
||||
'qop=auth';
|
||||
@@ -231,27 +250,30 @@ class ProxyServer {
|
||||
client
|
||||
.openUrl(request.method, request.uri)
|
||||
.then((HttpClientRequest clientRequest) {
|
||||
// Forward all headers.
|
||||
request.headers.forEach((String name, List<String> values) {
|
||||
values.forEach((String value) {
|
||||
if (name != "content-length" && name != "via") {
|
||||
clientRequest.headers.add(name, value);
|
||||
}
|
||||
// Forward all headers.
|
||||
request.headers.forEach((String name, List<String> values) {
|
||||
values.forEach((String value) {
|
||||
if (name != "content-length" && name != "via") {
|
||||
clientRequest.headers.add(name, value);
|
||||
}
|
||||
});
|
||||
});
|
||||
// Special handling of Content-Length and Via.
|
||||
clientRequest.contentLength = request.contentLength;
|
||||
List<String>? via = request.headers[HttpHeaders.viaHeader];
|
||||
String viaPrefix = via == null ? "" : "${via[0]}, ";
|
||||
clientRequest.headers.add(
|
||||
HttpHeaders.viaHeader,
|
||||
"${viaPrefix}1.1 localhost:$port",
|
||||
);
|
||||
// Copy all content.
|
||||
return request.cast<List<int>>().pipe(clientRequest);
|
||||
})
|
||||
.then((clientResponse) {
|
||||
(clientResponse as HttpClientResponse).cast<List<int>>().pipe(
|
||||
request.response,
|
||||
);
|
||||
});
|
||||
});
|
||||
// Special handling of Content-Length and Via.
|
||||
clientRequest.contentLength = request.contentLength;
|
||||
List<String>? via = request.headers[HttpHeaders.viaHeader];
|
||||
String viaPrefix = via == null ? "" : "${via[0]}, ";
|
||||
clientRequest.headers
|
||||
.add(HttpHeaders.viaHeader, "${viaPrefix}1.1 localhost:$port");
|
||||
// Copy all content.
|
||||
return request.cast<List<int>>().pipe(clientRequest);
|
||||
}).then((clientResponse) {
|
||||
(clientResponse as HttpClientResponse)
|
||||
.cast<List<int>>()
|
||||
.pipe(request.response);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -276,23 +298,23 @@ testInvalidProxy() {
|
||||
|
||||
client.findProxy = (Uri uri) => "";
|
||||
Future<HttpClientRequest?>.value(
|
||||
client.getUrl(Uri.parse("http://www.google.com/test")))
|
||||
.catchError((error) {}, test: (e) => e is HttpException);
|
||||
client.getUrl(Uri.parse("http://www.google.com/test")),
|
||||
).catchError((error) {}, test: (e) => e is HttpException);
|
||||
|
||||
client.findProxy = (Uri uri) => "XXX";
|
||||
Future<HttpClientRequest?>.value(
|
||||
client.getUrl(Uri.parse("http://www.google.com/test")))
|
||||
.catchError((error) {}, test: (e) => e is HttpException);
|
||||
client.getUrl(Uri.parse("http://www.google.com/test")),
|
||||
).catchError((error) {}, test: (e) => e is HttpException);
|
||||
|
||||
client.findProxy = (Uri uri) => "PROXY www.google.com";
|
||||
Future<HttpClientRequest?>.value(
|
||||
client.getUrl(Uri.parse("http://www.google.com/test")))
|
||||
.catchError((error) {}, test: (e) => e is HttpException);
|
||||
client.getUrl(Uri.parse("http://www.google.com/test")),
|
||||
).catchError((error) {}, test: (e) => e is HttpException);
|
||||
|
||||
client.findProxy = (Uri uri) => "PROXY www.google.com:http";
|
||||
Future<HttpClientRequest?>.value(
|
||||
client.getUrl(Uri.parse("http://www.google.com/test")))
|
||||
.catchError((error) {}, test: (e) => e is HttpException);
|
||||
client.getUrl(Uri.parse("http://www.google.com/test")),
|
||||
).catchError((error) {}, test: (e) => e is HttpException);
|
||||
}
|
||||
|
||||
int testDirectDoneCount = 0;
|
||||
@@ -306,7 +328,7 @@ void testDirectProxy() {
|
||||
" DIRECT ; ",
|
||||
";DIRECT",
|
||||
" ; DIRECT ",
|
||||
";;DIRECT;;"
|
||||
";;DIRECT;;",
|
||||
];
|
||||
|
||||
client.findProxy = (Uri uri) {
|
||||
@@ -318,20 +340,24 @@ void testDirectProxy() {
|
||||
client
|
||||
.getUrl(Uri.parse("http://localhost:${server.port}/$i"))
|
||||
.then((HttpClientRequest clientRequest) {
|
||||
String content = "$i$i$i";
|
||||
clientRequest.contentLength = content.length;
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
testDirectDoneCount++;
|
||||
if (testDirectDoneCount == proxy.length) {
|
||||
Expect.equals(proxy.length, server.requestCount);
|
||||
server.shutdown();
|
||||
client.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
String content = "$i$i$i";
|
||||
clientRequest.contentLength = content.length;
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
testDirectDoneCount++;
|
||||
if (testDirectDoneCount == proxy.length) {
|
||||
Expect.equals(proxy.length, server.requestCount);
|
||||
server.shutdown();
|
||||
client.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -340,8 +366,9 @@ int testProxyDoneCount = 0;
|
||||
void testProxy() {
|
||||
setupProxyServer().then((proxyServer) {
|
||||
setupServer(1, directRequestPaths: ["/4"]).then((server) {
|
||||
setupServer(1, directRequestPaths: ["/4"], secure: true)
|
||||
.then((secureServer) {
|
||||
setupServer(1, directRequestPaths: ["/4"], secure: true).then((
|
||||
secureServer,
|
||||
) {
|
||||
HttpClient client = new HttpClient(context: clientContext);
|
||||
|
||||
List<String> proxy;
|
||||
@@ -353,7 +380,7 @@ void testProxy() {
|
||||
""
|
||||
" PROXY localhost:${proxyServer.port}",
|
||||
"DIRECT",
|
||||
"PROXY localhost:${proxyServer.port}; DIRECT"
|
||||
"PROXY localhost:${proxyServer.port}; DIRECT",
|
||||
];
|
||||
} else {
|
||||
proxy = [
|
||||
@@ -363,7 +390,7 @@ void testProxy() {
|
||||
"PROXY hede.hule.hest:8080; PROXY hede.hule.hest:8181;"
|
||||
" PROXY localhost:${proxyServer.port}",
|
||||
"PROXY hede.hule.hest:8080; PROXY hede.hule.hest:8181; DIRECT",
|
||||
"PROXY localhost:${proxyServer.port}; DIRECT"
|
||||
"PROXY localhost:${proxyServer.port}; DIRECT",
|
||||
];
|
||||
}
|
||||
client.findProxy = (Uri uri) {
|
||||
@@ -381,22 +408,26 @@ void testProxy() {
|
||||
client
|
||||
.postUrl(Uri.parse(url))
|
||||
.then((HttpClientRequest clientRequest) {
|
||||
String content = "$i$i$i";
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
testProxyDoneCount++;
|
||||
if (testProxyDoneCount == proxy.length * 2) {
|
||||
Expect.equals(proxy.length, server.requestCount);
|
||||
Expect.equals(proxy.length, secureServer.requestCount);
|
||||
proxyServer.shutdown();
|
||||
server.shutdown();
|
||||
secureServer.shutdown();
|
||||
client.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
String content = "$i$i$i";
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
testProxyDoneCount++;
|
||||
if (testProxyDoneCount == proxy.length * 2) {
|
||||
Expect.equals(proxy.length, server.requestCount);
|
||||
Expect.equals(proxy.length, secureServer.requestCount);
|
||||
proxyServer.shutdown();
|
||||
server.shutdown();
|
||||
secureServer.shutdown();
|
||||
client.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
test(false);
|
||||
@@ -412,8 +443,8 @@ void testProxyChain() {
|
||||
// Setup two proxy servers having the first using the second as its proxy.
|
||||
setupProxyServer().then((proxyServer1) {
|
||||
setupProxyServer().then((proxyServer2) {
|
||||
proxyServer1.client.findProxy =
|
||||
(_) => "PROXY localhost:${proxyServer2.port}";
|
||||
proxyServer1.client.findProxy = (_) =>
|
||||
"PROXY localhost:${proxyServer2.port}";
|
||||
|
||||
setupServer(2, directRequestPaths: ["/4"]).then((server) {
|
||||
HttpClient client = new HttpClient(context: clientContext);
|
||||
@@ -426,7 +457,7 @@ void testProxyChain() {
|
||||
"PROXY localhost:${proxyServer1.port}",
|
||||
"PROXY localhost:${proxyServer1.port}",
|
||||
"DIRECT",
|
||||
"PROXY localhost:${proxyServer1.port}; DIRECT"
|
||||
"PROXY localhost:${proxyServer1.port}; DIRECT",
|
||||
];
|
||||
} else {
|
||||
proxy = [
|
||||
@@ -436,7 +467,7 @@ void testProxyChain() {
|
||||
"PROXY hede.hule.hest:8080; PROXY hede.hule.hest:8181;"
|
||||
" PROXY localhost:${proxyServer1.port}",
|
||||
"PROXY hede.hule.hest:8080; PROXY hede.hule.hest:8181; DIRECT",
|
||||
"PROXY localhost:${proxyServer1.port}; DIRECT"
|
||||
"PROXY localhost:${proxyServer1.port}; DIRECT",
|
||||
];
|
||||
}
|
||||
|
||||
@@ -450,22 +481,26 @@ void testProxyChain() {
|
||||
client
|
||||
.getUrl(Uri.parse("http://localhost:${server.port}/$i"))
|
||||
.then((HttpClientRequest clientRequest) {
|
||||
String content = "$i$i$i";
|
||||
clientRequest.contentLength = content.length;
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
testProxyChainDoneCount++;
|
||||
if (testProxyChainDoneCount == proxy.length) {
|
||||
Expect.equals(proxy.length, server.requestCount);
|
||||
proxyServer1.shutdown();
|
||||
proxyServer2.shutdown();
|
||||
server.shutdown();
|
||||
client.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
String content = "$i$i$i";
|
||||
clientRequest.contentLength = content.length;
|
||||
clientRequest.write(content);
|
||||
return clientRequest.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
testProxyChainDoneCount++;
|
||||
if (testProxyChainDoneCount == proxy.length) {
|
||||
Expect.equals(proxy.length, server.requestCount);
|
||||
proxyServer1.shutdown();
|
||||
proxyServer2.shutdown();
|
||||
server.shutdown();
|
||||
client.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@ class IsolatedHttpServer {
|
||||
// Send chunked encoding message to the server.
|
||||
port.send([
|
||||
new IsolatedHttpServerCommand.chunkedEncoding(),
|
||||
_statusPort.sendPort
|
||||
_statusPort.sendPort,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -47,8 +47,10 @@ class IsolatedHttpServer {
|
||||
|
||||
void shutdown() {
|
||||
// Send server stop message to the server.
|
||||
_serverPort
|
||||
.send([new IsolatedHttpServerCommand.stop(), _statusPort.sendPort]);
|
||||
_serverPort.send([
|
||||
new IsolatedHttpServerCommand.stop(),
|
||||
_statusPort.sendPort,
|
||||
]);
|
||||
_statusPort.close();
|
||||
}
|
||||
|
||||
@@ -173,29 +175,35 @@ void testRead(bool chunkedEncoding) {
|
||||
int count = 0;
|
||||
HttpClient httpClient = new HttpClient();
|
||||
void sendRequest() {
|
||||
httpClient.post("127.0.0.1", port, "/echo").then((request) {
|
||||
if (chunkedEncoding) {
|
||||
request.write(data.substring(0, 10));
|
||||
request.write(data.substring(10, data.length));
|
||||
} else {
|
||||
request.contentLength = data.length;
|
||||
request.add(data.codeUnits);
|
||||
}
|
||||
return request.close();
|
||||
}).then((response) {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
List<int> body = <int>[];
|
||||
response.listen(body.addAll, onDone: () {
|
||||
Expect.equals(data, new String.fromCharCodes(body));
|
||||
count++;
|
||||
if (count < kMessageCount) {
|
||||
sendRequest();
|
||||
} else {
|
||||
httpClient.close();
|
||||
server.shutdown();
|
||||
}
|
||||
});
|
||||
});
|
||||
httpClient
|
||||
.post("127.0.0.1", port, "/echo")
|
||||
.then((request) {
|
||||
if (chunkedEncoding) {
|
||||
request.write(data.substring(0, 10));
|
||||
request.write(data.substring(10, data.length));
|
||||
} else {
|
||||
request.contentLength = data.length;
|
||||
request.add(data.codeUnits);
|
||||
}
|
||||
return request.close();
|
||||
})
|
||||
.then((response) {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
List<int> body = <int>[];
|
||||
response.listen(
|
||||
body.addAll,
|
||||
onDone: () {
|
||||
Expect.equals(data, new String.fromCharCodes(body));
|
||||
count++;
|
||||
if (count < kMessageCount) {
|
||||
sendRequest();
|
||||
} else {
|
||||
httpClient.close();
|
||||
server.shutdown();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
sendRequest();
|
||||
|
||||
@@ -13,7 +13,9 @@ Future<HttpServer> setupServer({Uri? targetServer}) {
|
||||
HttpServer.bind("127.0.0.1", 0).then((server) {
|
||||
var handlers = new Map<String, Function>();
|
||||
addRequestHandler(
|
||||
String path, void handler(HttpRequest request, HttpResponse response)) {
|
||||
String path,
|
||||
void handler(HttpRequest request, HttpResponse response),
|
||||
) {
|
||||
handlers[path] = handler;
|
||||
}
|
||||
|
||||
@@ -21,34 +23,48 @@ Future<HttpServer> setupServer({Uri? targetServer}) {
|
||||
if (handlers.containsKey(request.uri.path)) {
|
||||
handlers[request.uri.path]!(request, request.response);
|
||||
} else {
|
||||
request.listen((_) {}, onDone: () {
|
||||
request.response.statusCode = 404;
|
||||
request.response.close();
|
||||
});
|
||||
request.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
request.response.statusCode = 404;
|
||||
request.response.close();
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
void addRedirectHandler(int number, int statusCode) {
|
||||
addRequestHandler("/$number",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/$number", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
response.redirect(
|
||||
Uri.parse("http://127.0.0.1:${server.port}/${number + 1}"));
|
||||
Uri.parse("http://127.0.0.1:${server.port}/${number + 1}"),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Setup simple redirect.
|
||||
addRequestHandler("/redirect",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
response.redirect(Uri.parse("http://127.0.0.1:${server.port}/location"),
|
||||
status: HttpStatus.movedPermanently);
|
||||
addRequestHandler("/redirect", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
response.redirect(
|
||||
Uri.parse("http://127.0.0.1:${server.port}/location"),
|
||||
status: HttpStatus.movedPermanently,
|
||||
);
|
||||
});
|
||||
addRequestHandler("/location",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/location", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
response.close();
|
||||
});
|
||||
|
||||
addRequestHandler("/redirect-no-location",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/redirect-no-location", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
response
|
||||
..statusCode = HttpStatus.movedPermanently
|
||||
..reasonPhrase = "Moved Permanently"
|
||||
@@ -56,55 +72,73 @@ Future<HttpServer> setupServer({Uri? targetServer}) {
|
||||
});
|
||||
|
||||
// Setup redirects with relative url.
|
||||
addRequestHandler("/redirectUrl",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/redirectUrl", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
response.headers.set(HttpHeaders.locationHeader, "/some/relativeUrl");
|
||||
response.statusCode = HttpStatus.movedPermanently;
|
||||
response.close();
|
||||
});
|
||||
|
||||
addRequestHandler("/some/redirectUrl",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/some/redirectUrl", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
response.headers.set(HttpHeaders.locationHeader, "relativeUrl");
|
||||
response.statusCode = HttpStatus.movedPermanently;
|
||||
response.close();
|
||||
});
|
||||
|
||||
addRequestHandler("/some/relativeUrl",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/some/relativeUrl", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
response.close();
|
||||
});
|
||||
|
||||
addRequestHandler("/some/relativeToAbsolute",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/some/relativeToAbsolute", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
response.redirect(Uri.parse("xxx"), status: HttpStatus.seeOther);
|
||||
});
|
||||
|
||||
addRequestHandler("/redirectUrl2",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/redirectUrl2", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
response.headers.set(HttpHeaders.locationHeader, "location");
|
||||
response.statusCode = HttpStatus.movedPermanently;
|
||||
response.close();
|
||||
});
|
||||
|
||||
addRequestHandler("/redirectUrl3",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/redirectUrl3", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
response.headers.set(HttpHeaders.locationHeader, "./location");
|
||||
response.statusCode = HttpStatus.movedPermanently;
|
||||
response.close();
|
||||
});
|
||||
|
||||
addRequestHandler("/redirectUrl4",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/redirectUrl4", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
response.headers.set(HttpHeaders.locationHeader, "./a/b/../../location");
|
||||
response.statusCode = HttpStatus.movedPermanently;
|
||||
response.close();
|
||||
});
|
||||
|
||||
addRequestHandler("/redirectUrl5",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/redirectUrl5", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
response.headers.set(
|
||||
HttpHeaders.locationHeader, "//127.0.0.1:${server.port}/location");
|
||||
HttpHeaders.locationHeader,
|
||||
"//127.0.0.1:${server.port}/location",
|
||||
);
|
||||
response.statusCode = HttpStatus.movedPermanently;
|
||||
response.close();
|
||||
});
|
||||
@@ -122,14 +156,18 @@ Future<HttpServer> setupServer({Uri? targetServer}) {
|
||||
|
||||
// Setup redirect loop.
|
||||
addRequestHandler("/A", (HttpRequest request, HttpResponse response) {
|
||||
response.headers
|
||||
.set(HttpHeaders.locationHeader, "http://127.0.0.1:${server.port}/B");
|
||||
response.headers.set(
|
||||
HttpHeaders.locationHeader,
|
||||
"http://127.0.0.1:${server.port}/B",
|
||||
);
|
||||
response.statusCode = HttpStatus.movedPermanently;
|
||||
response.close();
|
||||
});
|
||||
addRequestHandler("/B", (HttpRequest request, HttpResponse response) {
|
||||
response.headers
|
||||
.set(HttpHeaders.locationHeader, "http://127.0.0.1:${server.port}/A");
|
||||
response.headers.set(
|
||||
HttpHeaders.locationHeader,
|
||||
"http://127.0.0.1:${server.port}/A",
|
||||
);
|
||||
response.statusCode = HttpStatus.movedTemporarily;
|
||||
response.close();
|
||||
});
|
||||
@@ -137,28 +175,40 @@ Future<HttpServer> setupServer({Uri? targetServer}) {
|
||||
// Setup redirect checking headers.
|
||||
addRequestHandler("/src", (HttpRequest request, HttpResponse response) {
|
||||
Expect.equals("value", request.headers.value("X-Request-Header"));
|
||||
Expect.isNotNull(request.headers.value("Authorization"),
|
||||
"expected 'Authorization' header to be set");
|
||||
Expect.isNotNull(
|
||||
request.headers.value("Authorization"),
|
||||
"expected 'Authorization' header to be set",
|
||||
);
|
||||
response.headers.set(
|
||||
HttpHeaders.locationHeader, "http://127.0.0.1:${server.port}/target");
|
||||
HttpHeaders.locationHeader,
|
||||
"http://127.0.0.1:${server.port}/target",
|
||||
);
|
||||
response.statusCode = HttpStatus.movedPermanently;
|
||||
response.close();
|
||||
});
|
||||
addRequestHandler("/target", (HttpRequest request, HttpResponse response) {
|
||||
Expect.equals("value", request.headers.value("X-Request-Header"));
|
||||
Expect.isNotNull(request.headers.value("Authorization"),
|
||||
"expected 'Authorization' header to be set");
|
||||
Expect.isNotNull(
|
||||
request.headers.value("Authorization"),
|
||||
"expected 'Authorization' header to be set",
|
||||
);
|
||||
response.close();
|
||||
});
|
||||
|
||||
if (targetServer != null) {
|
||||
addRequestHandler("/src-crossdomain",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/src-crossdomain", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
Expect.equals("value", request.headers.value("X-Request-Header"));
|
||||
Expect.isNotNull(request.headers.value("Authorization"),
|
||||
"expected 'Authorization' header to be set");
|
||||
response.headers
|
||||
.set(HttpHeaders.locationHeader, targetServer.toString());
|
||||
Expect.isNotNull(
|
||||
request.headers.value("Authorization"),
|
||||
"expected 'Authorization' header to be set",
|
||||
);
|
||||
response.headers.set(
|
||||
HttpHeaders.locationHeader,
|
||||
targetServer.toString(),
|
||||
);
|
||||
response.statusCode = HttpStatus.movedPermanently;
|
||||
response.close();
|
||||
});
|
||||
@@ -167,38 +217,54 @@ Future<HttpServer> setupServer({Uri? targetServer}) {
|
||||
// Setup redirect for 301 where POST should not redirect.
|
||||
addRequestHandler("/301src", (HttpRequest request, HttpResponse response) {
|
||||
Expect.equals("POST", request.method);
|
||||
request.listen((_) {}, onDone: () {
|
||||
response.headers.set(HttpHeaders.locationHeader,
|
||||
"http://127.0.0.1:${server.port}/301target");
|
||||
response.statusCode = HttpStatus.movedPermanently;
|
||||
response.close();
|
||||
});
|
||||
request.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
response.headers.set(
|
||||
HttpHeaders.locationHeader,
|
||||
"http://127.0.0.1:${server.port}/301target",
|
||||
);
|
||||
response.statusCode = HttpStatus.movedPermanently;
|
||||
response.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
addRequestHandler("/301target",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/301target", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
Expect.fail("Redirect of POST should not happen");
|
||||
});
|
||||
|
||||
// Setup redirect for 303 where POST should turn into GET.
|
||||
addRequestHandler("/303src", (HttpRequest request, HttpResponse response) {
|
||||
request.listen((_) {}, onDone: () {
|
||||
Expect.equals("POST", request.method);
|
||||
response.headers.set(HttpHeaders.locationHeader,
|
||||
"http://127.0.0.1:${server.port}/303target");
|
||||
response.statusCode = HttpStatus.seeOther;
|
||||
response.close();
|
||||
});
|
||||
request.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
Expect.equals("POST", request.method);
|
||||
response.headers.set(
|
||||
HttpHeaders.locationHeader,
|
||||
"http://127.0.0.1:${server.port}/303target",
|
||||
);
|
||||
response.statusCode = HttpStatus.seeOther;
|
||||
response.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
addRequestHandler("/303target",
|
||||
(HttpRequest request, HttpResponse response) {
|
||||
addRequestHandler("/303target", (
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
) {
|
||||
Expect.equals("GET", request.method);
|
||||
response.close();
|
||||
});
|
||||
|
||||
// Setup redirect where we close the connection.
|
||||
addRequestHandler("/closing", (HttpRequest request, HttpResponse response) {
|
||||
response.headers
|
||||
.set(HttpHeaders.locationHeader, "http://127.0.0.1:${server.port}/");
|
||||
response.headers.set(
|
||||
HttpHeaders.locationHeader,
|
||||
"http://127.0.0.1:${server.port}/",
|
||||
);
|
||||
response.statusCode = HttpStatus.found;
|
||||
response.persistentConnection = false;
|
||||
response.close();
|
||||
@@ -216,21 +282,28 @@ Future<HttpServer> setupTargetServer() {
|
||||
HttpServer.bind("127.0.0.1", 0).then((server) {
|
||||
var handlers = new Map<String, Function>();
|
||||
addRequestHandler(
|
||||
String path, void handler(HttpRequest request, HttpResponse response)) {
|
||||
String path,
|
||||
void handler(HttpRequest request, HttpResponse response),
|
||||
) {
|
||||
handlers[path] = handler;
|
||||
}
|
||||
|
||||
server.listen((HttpRequest request) {
|
||||
if (request.uri.path == "/target") {
|
||||
Expect.equals("value", request.headers.value("X-Request-Header"));
|
||||
Expect.isNull(request.headers.value("Authorization"),
|
||||
"expected 'Authorization' header to be removed on redirect");
|
||||
Expect.isNull(
|
||||
request.headers.value("Authorization"),
|
||||
"expected 'Authorization' header to be removed on redirect",
|
||||
);
|
||||
request.response.close();
|
||||
} else {
|
||||
request.listen((_) {}, onDone: () {
|
||||
request.response.statusCode = 404;
|
||||
request.response.close();
|
||||
});
|
||||
request.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
request.response.statusCode = 404;
|
||||
request.response.close();
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -256,27 +329,30 @@ void testManualRedirect() {
|
||||
|
||||
int redirectCount = 0;
|
||||
handleResponse(HttpClientResponse response) {
|
||||
response.listen((_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
redirectCount++;
|
||||
if (redirectCount < 10) {
|
||||
Expect.isTrue(response.isRedirect);
|
||||
checkRedirects(redirectCount, response);
|
||||
response.redirect().then(handleResponse);
|
||||
} else {
|
||||
Expect.equals(HttpStatus.notFound, response.statusCode);
|
||||
server.close();
|
||||
client.close();
|
||||
}
|
||||
});
|
||||
response.listen(
|
||||
(_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
redirectCount++;
|
||||
if (redirectCount < 10) {
|
||||
Expect.isTrue(response.isRedirect);
|
||||
checkRedirects(redirectCount, response);
|
||||
response.redirect().then(handleResponse);
|
||||
} else {
|
||||
Expect.equals(HttpStatus.notFound, response.statusCode);
|
||||
server.close();
|
||||
client.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
client
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/1"))
|
||||
.then((HttpClientRequest request) {
|
||||
request.followRedirects = false;
|
||||
return request.close();
|
||||
}).then(handleResponse);
|
||||
request.followRedirects = false;
|
||||
return request.close();
|
||||
})
|
||||
.then(handleResponse);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -287,28 +363,31 @@ void testManualRedirectWithHeaders() {
|
||||
int redirectCount = 0;
|
||||
|
||||
handleResponse(HttpClientResponse response) {
|
||||
response.listen((_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
redirectCount++;
|
||||
if (redirectCount < 2) {
|
||||
Expect.isTrue(response.isRedirect);
|
||||
response.redirect().then(handleResponse);
|
||||
} else {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
server.close();
|
||||
client.close();
|
||||
}
|
||||
});
|
||||
response.listen(
|
||||
(_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
redirectCount++;
|
||||
if (redirectCount < 2) {
|
||||
Expect.isTrue(response.isRedirect);
|
||||
response.redirect().then(handleResponse);
|
||||
} else {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
server.close();
|
||||
client.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
client
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/src"))
|
||||
.then((HttpClientRequest request) {
|
||||
request.followRedirects = false;
|
||||
request.headers.add("X-Request-Header", "value");
|
||||
request.headers.add("Authorization", "Basic ...");
|
||||
return request.close();
|
||||
}).then(handleResponse);
|
||||
request.followRedirects = false;
|
||||
request.headers.add("X-Request-Header", "value");
|
||||
request.headers.add("Authorization", "Basic ...");
|
||||
return request.close();
|
||||
})
|
||||
.then(handleResponse);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -319,15 +398,18 @@ void testAutoRedirect() {
|
||||
client
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/redirect"))
|
||||
.then((HttpClientRequest request) {
|
||||
return request.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
response.listen((_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
Expect.equals(1, response.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
});
|
||||
return request.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
response.listen(
|
||||
(_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
Expect.equals(1, response.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -336,7 +418,8 @@ Future<void> testAutoRedirectNoLocationHeader() async {
|
||||
HttpClient client = new HttpClient();
|
||||
|
||||
final request = await client.getUrl(
|
||||
Uri.parse("http://127.0.0.1:${server.port}/redirect-no-location"));
|
||||
Uri.parse("http://127.0.0.1:${server.port}/redirect-no-location"),
|
||||
);
|
||||
|
||||
try {
|
||||
final response = await request.close();
|
||||
@@ -354,21 +437,25 @@ void testAutoRedirectZeroMaxRedirects() {
|
||||
client
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/redirect"))
|
||||
.then((HttpClientRequest request) {
|
||||
request
|
||||
..followRedirects = true
|
||||
..maxRedirects = 0;
|
||||
request
|
||||
..followRedirects = true
|
||||
..maxRedirects = 0;
|
||||
|
||||
return request.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
response.drain();
|
||||
Expect.fail("Response data not expected");
|
||||
}, onError: (error) {
|
||||
final httpException = error as HttpException;
|
||||
Expect.equals(httpException.message, "Redirect limit exceeded");
|
||||
Expect.equals(httpException.uri, null);
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
return request.close();
|
||||
})
|
||||
.then(
|
||||
(HttpClientResponse response) {
|
||||
response.drain();
|
||||
Expect.fail("Response data not expected");
|
||||
},
|
||||
onError: (error) {
|
||||
final httpException = error as HttpException;
|
||||
Expect.equals(httpException.message, "Redirect limit exceeded");
|
||||
Expect.equals(httpException.uri, null);
|
||||
server.close();
|
||||
client.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -379,17 +466,20 @@ void testAutoRedirectWithHeaders() {
|
||||
client
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/src"))
|
||||
.then((HttpClientRequest request) {
|
||||
request.headers.add("X-Request-Header", "value");
|
||||
request.headers.add("Authorization", "Basic ...");
|
||||
return request.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
response.listen((_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
Expect.equals(1, response.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
});
|
||||
request.headers.add("X-Request-Header", "value");
|
||||
request.headers.add("Authorization", "Basic ...");
|
||||
return request.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
response.listen(
|
||||
(_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
Expect.equals(1, response.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -398,113 +488,202 @@ void testShouldCopyHeadersOnRedirect() {
|
||||
final fnName = Symbol("shouldCopyHeaderOnRedirect");
|
||||
|
||||
shouldCopyHeaderOnRedirect(
|
||||
String headerKey, Uri originalUrl, Uri redirectUri) =>
|
||||
clientClass.invoke(
|
||||
fnName, [headerKey, originalUrl, redirectUri]).reflectee as bool;
|
||||
String headerKey,
|
||||
Uri originalUrl,
|
||||
Uri redirectUri,
|
||||
) =>
|
||||
clientClass.invoke(fnName, [
|
||||
headerKey,
|
||||
originalUrl,
|
||||
redirectUri,
|
||||
]).reflectee
|
||||
as bool;
|
||||
|
||||
checkShouldCopyHeader(
|
||||
String headerKey, String originalUrl, String redirectUri, bool expected) {
|
||||
String headerKey,
|
||||
String originalUrl,
|
||||
String redirectUri,
|
||||
bool expected,
|
||||
) {
|
||||
if (shouldCopyHeaderOnRedirect(
|
||||
headerKey, Uri.parse(originalUrl), Uri.parse(redirectUri)) !=
|
||||
headerKey,
|
||||
Uri.parse(originalUrl),
|
||||
Uri.parse(redirectUri),
|
||||
) !=
|
||||
expected) {
|
||||
Expect.fail(
|
||||
"shouldCopyHeaderOnRedirect($headerKey, $originalUrl, $redirectUri) => ${!expected}");
|
||||
"shouldCopyHeaderOnRedirect($headerKey, $originalUrl, $redirectUri) => ${!expected}",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Redirect on localhost.
|
||||
checkShouldCopyHeader(
|
||||
"authorization", "http://localhost", "http://localhost/foo", true);
|
||||
"authorization",
|
||||
"http://localhost",
|
||||
"http://localhost/foo",
|
||||
true,
|
||||
);
|
||||
checkShouldCopyHeader(
|
||||
"cat", "http://localhost", "http://localhost/foo", true);
|
||||
"cat",
|
||||
"http://localhost",
|
||||
"http://localhost/foo",
|
||||
true,
|
||||
);
|
||||
|
||||
// Redirect to same IP address.
|
||||
checkShouldCopyHeader("authorization", "http://192.168.20.20",
|
||||
"http://192.168.20.20/foo", true);
|
||||
checkShouldCopyHeader(
|
||||
"cat", "http://192.168.20.20", "http://192.168.20.20/foo", true);
|
||||
"authorization",
|
||||
"http://192.168.20.20",
|
||||
"http://192.168.20.20/foo",
|
||||
true,
|
||||
);
|
||||
checkShouldCopyHeader(
|
||||
"cat",
|
||||
"http://192.168.20.20",
|
||||
"http://192.168.20.20/foo",
|
||||
true,
|
||||
);
|
||||
|
||||
// Redirect to different IP address.
|
||||
checkShouldCopyHeader(
|
||||
"authorization", "http://192.168.20.20", "http://192.168.20.99", false);
|
||||
"authorization",
|
||||
"http://192.168.20.20",
|
||||
"http://192.168.20.99",
|
||||
false,
|
||||
);
|
||||
checkShouldCopyHeader(
|
||||
"cat", "http://192.168.20.20", "http://192.168.20.99", true);
|
||||
"cat",
|
||||
"http://192.168.20.20",
|
||||
"http://192.168.20.99",
|
||||
true,
|
||||
);
|
||||
|
||||
// Redirect to same domain.
|
||||
checkShouldCopyHeader(
|
||||
"authorization", "http://foo.com", "http://foo.com/foo", true);
|
||||
"authorization",
|
||||
"http://foo.com",
|
||||
"http://foo.com/foo",
|
||||
true,
|
||||
);
|
||||
checkShouldCopyHeader("cat", "http://foo.com", "http://foo.com/foo", true);
|
||||
|
||||
// Redirect to same domain with explicit ports.
|
||||
checkShouldCopyHeader(
|
||||
"authorization", "http://foo.com", "http://foo.com:80/foo", true);
|
||||
"authorization",
|
||||
"http://foo.com",
|
||||
"http://foo.com:80/foo",
|
||||
true,
|
||||
);
|
||||
checkShouldCopyHeader("cat", "http://foo.com", "http://foo.com:80/foo", true);
|
||||
|
||||
// Redirect to subdomain.
|
||||
checkShouldCopyHeader(
|
||||
"authorization", "https://foo.com", "https://www.foo.com", true);
|
||||
"authorization",
|
||||
"https://foo.com",
|
||||
"https://www.foo.com",
|
||||
true,
|
||||
);
|
||||
checkShouldCopyHeader("cat", "https://foo.com", "https://www.foo.com", true);
|
||||
|
||||
// Redirect to different domain.
|
||||
checkShouldCopyHeader(
|
||||
"authorization", "https://foo.com", "https://wwwfoo.com", false);
|
||||
"authorization",
|
||||
"https://foo.com",
|
||||
"https://wwwfoo.com",
|
||||
false,
|
||||
);
|
||||
checkShouldCopyHeader("cat", "https://foo.com", "https://wwwfoo.com", true);
|
||||
|
||||
// Redirect to different port.
|
||||
checkShouldCopyHeader(
|
||||
"authorization", "http://foo.com", "http://foo.com:81", false);
|
||||
"authorization",
|
||||
"http://foo.com",
|
||||
"http://foo.com:81",
|
||||
false,
|
||||
);
|
||||
checkShouldCopyHeader("cat", "http://foo.com", "http://foo.com:81", true);
|
||||
|
||||
// Redirect from secure to insecure.
|
||||
checkShouldCopyHeader(
|
||||
"authorization", "https://foo.com", "http://foo.com", false);
|
||||
"authorization",
|
||||
"https://foo.com",
|
||||
"http://foo.com",
|
||||
false,
|
||||
);
|
||||
checkShouldCopyHeader("cat", "https://foo.com", "http://foo.com", true);
|
||||
|
||||
// Redirect from secure to insecure, same port.
|
||||
checkShouldCopyHeader(
|
||||
"authorization", "https://foo.com:8888", "http://foo.com:8888", false);
|
||||
"authorization",
|
||||
"https://foo.com:8888",
|
||||
"http://foo.com:8888",
|
||||
false,
|
||||
);
|
||||
checkShouldCopyHeader(
|
||||
"cat", "https://foo.com:8888", "http://foo.com:8888", true);
|
||||
"cat",
|
||||
"https://foo.com:8888",
|
||||
"http://foo.com:8888",
|
||||
true,
|
||||
);
|
||||
|
||||
// Redirect from insecure to secure.
|
||||
checkShouldCopyHeader(
|
||||
"authorization", "http://foo.com", "https://foo.com", false);
|
||||
"authorization",
|
||||
"http://foo.com",
|
||||
"https://foo.com",
|
||||
false,
|
||||
);
|
||||
checkShouldCopyHeader("cat", "http://foo.com", "https://foo.com", true);
|
||||
|
||||
// Redirect to subdomain, different port.
|
||||
checkShouldCopyHeader(
|
||||
"authorization", "https://foo.com:80", "https://www.foo.com:81", false);
|
||||
"authorization",
|
||||
"https://foo.com:80",
|
||||
"https://www.foo.com:81",
|
||||
false,
|
||||
);
|
||||
checkShouldCopyHeader(
|
||||
"cat", "https://foo.com:80", "https://www.foo.com:81", true);
|
||||
"cat",
|
||||
"https://foo.com:80",
|
||||
"https://www.foo.com:81",
|
||||
true,
|
||||
);
|
||||
|
||||
// Different header casting:
|
||||
checkShouldCopyHeader(
|
||||
"AuThOrIzAtiOn", "https://foo.com", "https://bar.com", false);
|
||||
"AuThOrIzAtiOn",
|
||||
"https://foo.com",
|
||||
"https://bar.com",
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
void testCrossDomainAutoRedirectWithHeaders() {
|
||||
setupTargetServer().then((targetServer) {
|
||||
setupServer(
|
||||
targetServer:
|
||||
Uri.parse("http://127.0.0.1:${targetServer.port}/target"))
|
||||
.then((server) {
|
||||
targetServer: Uri.parse("http://127.0.0.1:${targetServer.port}/target"),
|
||||
).then((server) {
|
||||
HttpClient client = new HttpClient();
|
||||
|
||||
client
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/src-crossdomain"))
|
||||
.then((HttpClientRequest request) {
|
||||
request.headers.add("X-Request-Header", "value");
|
||||
request.headers.add("Authorization", "Basic ...");
|
||||
return request.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
response.listen((_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
Expect.equals(1, response.redirects.length);
|
||||
targetServer.close();
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
});
|
||||
request.headers.add("X-Request-Header", "value");
|
||||
request.headers.add("Authorization", "Basic ...");
|
||||
return request.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
response.listen(
|
||||
(_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
Expect.equals(1, response.redirects.length);
|
||||
targetServer.close();
|
||||
server.close();
|
||||
client.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -516,16 +695,19 @@ void testAutoRedirect301POST() {
|
||||
client
|
||||
.postUrl(Uri.parse("http://127.0.0.1:${server.port}/301src"))
|
||||
.then((HttpClientRequest request) {
|
||||
return request.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
Expect.equals(HttpStatus.movedPermanently, response.statusCode);
|
||||
response.listen((_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
Expect.equals(0, response.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
});
|
||||
return request.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
Expect.equals(HttpStatus.movedPermanently, response.statusCode);
|
||||
response.listen(
|
||||
(_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
Expect.equals(0, response.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -536,16 +718,19 @@ void testAutoRedirect303POST() {
|
||||
client
|
||||
.postUrl(Uri.parse("http://127.0.0.1:${server.port}/303src"))
|
||||
.then((HttpClientRequest request) {
|
||||
return request.close();
|
||||
}).then((HttpClientResponse response) {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
response.listen((_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
Expect.equals(1, response.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
});
|
||||
return request.close();
|
||||
})
|
||||
.then((HttpClientResponse response) {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
response.listen(
|
||||
(_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
Expect.equals(1, response.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -553,10 +738,11 @@ void testAutoRedirectLimit() {
|
||||
setupServer().then((server) {
|
||||
HttpClient client = new HttpClient();
|
||||
|
||||
Future<HttpClientResponse?>.value(client
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/1"))
|
||||
.then((HttpClientRequest request) => request.close()))
|
||||
.catchError((error) {
|
||||
Future<HttpClientResponse?>.value(
|
||||
client
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/1"))
|
||||
.then((HttpClientRequest request) => request.close()),
|
||||
).catchError((error) {
|
||||
Expect.equals(5, error.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
@@ -569,10 +755,11 @@ void testRedirectLoop() {
|
||||
HttpClient client = new HttpClient();
|
||||
|
||||
int redirectCount = 0;
|
||||
Future<HttpClientResponse?>.value(client
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/A"))
|
||||
.then((HttpClientRequest request) => request.close()))
|
||||
.catchError((error) {
|
||||
Future<HttpClientResponse?>.value(
|
||||
client
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/A"))
|
||||
.then((HttpClientRequest request) => request.close()),
|
||||
).catchError((error) {
|
||||
Expect.equals(2, error.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
@@ -588,12 +775,15 @@ void testRedirectClosingConnection() {
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}/closing"))
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
Expect.equals(1, response.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
});
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
Expect.equals(1, response.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -607,13 +797,16 @@ void testRedirectRelativeUrl() {
|
||||
.getUrl(Uri.parse("http://127.0.0.1:${server.port}$path"))
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
response.listen((_) {}, onDone: () {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
Expect.equals(1, response.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
});
|
||||
response.listen(
|
||||
(_) {},
|
||||
onDone: () {
|
||||
Expect.equals(HttpStatus.ok, response.statusCode);
|
||||
Expect.equals(1, response.redirects.length);
|
||||
server.close();
|
||||
client.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -631,23 +824,27 @@ void testRedirectRelativeToAbsolute() {
|
||||
|
||||
int redirectCount = 0;
|
||||
handleResponse(HttpClientResponse response) {
|
||||
response.listen((_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
Expect.equals(HttpStatus.seeOther, response.statusCode);
|
||||
Expect.equals("xxx", response.headers["Location"]![0]);
|
||||
Expect.isTrue(response.isRedirect);
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
response.listen(
|
||||
(_) => Expect.fail("Response data not expected"),
|
||||
onDone: () {
|
||||
Expect.equals(HttpStatus.seeOther, response.statusCode);
|
||||
Expect.equals("xxx", response.headers["Location"]![0]);
|
||||
Expect.isTrue(response.isRedirect);
|
||||
server.close();
|
||||
client.close();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
client
|
||||
.getUrl(Uri.parse(
|
||||
"http://127.0.0.1:${server.port}/some/relativeToAbsolute"))
|
||||
.getUrl(
|
||||
Uri.parse("http://127.0.0.1:${server.port}/some/relativeToAbsolute"),
|
||||
)
|
||||
.then((HttpClientRequest request) {
|
||||
request.followRedirects = false;
|
||||
return request.close();
|
||||
}).then(handleResponse);
|
||||
request.followRedirects = false;
|
||||
return request.close();
|
||||
})
|
||||
.then(handleResponse);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -55,12 +55,14 @@ void testAbsoluteUriInRequest() {
|
||||
socket.write("Host: google.com\r\n");
|
||||
socket.write("Connection: close\r\n");
|
||||
socket.write("\r\n");
|
||||
socket.flush().then((_) => socket.drain().then((_) {
|
||||
Expect.equals(Uri.http("google.com", "/"), requestedUri);
|
||||
socket.close();
|
||||
server.close();
|
||||
asyncEnd();
|
||||
}));
|
||||
socket.flush().then(
|
||||
(_) => socket.drain().then((_) {
|
||||
Expect.equals(Uri.http("google.com", "/"), requestedUri);
|
||||
socket.close();
|
||||
server.close();
|
||||
asyncEnd();
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,10 +22,12 @@ void testSimpleDeadline(int connections) {
|
||||
var futures = <Future>[];
|
||||
var client = new HttpClient();
|
||||
for (int i = 0; i < connections; i++) {
|
||||
futures.add(client
|
||||
.get('localhost', server.port, '/')
|
||||
.then((request) => request.close())
|
||||
.then((response) => response.drain()));
|
||||
futures.add(
|
||||
client
|
||||
.get('localhost', server.port, '/')
|
||||
.then((request) => request.close())
|
||||
.then((response) => response.drain()),
|
||||
);
|
||||
}
|
||||
Future.wait(futures).then((_) => server.close());
|
||||
});
|
||||
@@ -42,15 +44,20 @@ void testExceedDeadline(int connections) {
|
||||
var futures = <Future>[];
|
||||
var client = new HttpClient();
|
||||
for (int i = 0; i < connections; i++) {
|
||||
futures.add(client
|
||||
.get('localhost', server.port, '/')
|
||||
.then((request) => request.close())
|
||||
.then((response) => response.drain())
|
||||
.then((_) {
|
||||
Expect.fail("Expected error");
|
||||
}, onError: (e) {
|
||||
// Expect error.
|
||||
}));
|
||||
futures.add(
|
||||
client
|
||||
.get('localhost', server.port, '/')
|
||||
.then((request) => request.close())
|
||||
.then((response) => response.drain())
|
||||
.then(
|
||||
(_) {
|
||||
Expect.fail("Expected error");
|
||||
},
|
||||
onError: (e) {
|
||||
// Expect error.
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
Future.wait(futures).then((_) => server.close());
|
||||
});
|
||||
@@ -74,16 +81,21 @@ void testDeadlineAndDetach(int connections) {
|
||||
var futures = <Future>[];
|
||||
var client = new HttpClient();
|
||||
for (int i = 0; i < connections; i++) {
|
||||
futures.add(client
|
||||
.get('localhost', server.port, '/')
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
return response
|
||||
.fold<BytesBuilder>(new BytesBuilder(), (b, d) => b..add(d))
|
||||
.then((builder) {
|
||||
Expect.equals('stuff', new String.fromCharCodes(builder.takeBytes()));
|
||||
});
|
||||
}));
|
||||
futures.add(
|
||||
client
|
||||
.get('localhost', server.port, '/')
|
||||
.then((request) => request.close())
|
||||
.then((response) {
|
||||
return response
|
||||
.fold<BytesBuilder>(new BytesBuilder(), (b, d) => b..add(d))
|
||||
.then((builder) {
|
||||
Expect.equals(
|
||||
'stuff',
|
||||
new String.fromCharCodes(builder.takeBytes()),
|
||||
);
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
Future.wait(futures).then((_) => server.close());
|
||||
});
|
||||
|
||||
@@ -26,16 +26,18 @@ Future<int> runServer(int port, int connections, bool clean) {
|
||||
}
|
||||
});
|
||||
|
||||
Future.wait(new List.generate(connections, (_) {
|
||||
var client = new HttpClient();
|
||||
return client
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((response) => response.drain())
|
||||
.catchError((e) {
|
||||
if (clean) throw e;
|
||||
});
|
||||
})).then((_) {
|
||||
Future.wait(
|
||||
new List.generate(connections, (_) {
|
||||
var client = new HttpClient();
|
||||
return client
|
||||
.get("127.0.0.1", server.port, "/")
|
||||
.then((request) => request.close())
|
||||
.then((response) => response.drain())
|
||||
.catchError((e) {
|
||||
if (clean) throw e;
|
||||
});
|
||||
}),
|
||||
).then((_) {
|
||||
if (clean) {
|
||||
int port = server.port;
|
||||
server.close().then((_) => completer.complete(port));
|
||||
|
||||
@@ -16,19 +16,23 @@ const CLIENT_SCRIPT = "http_server_close_response_after_error_client.dart";
|
||||
void main() {
|
||||
HttpServer.bind("127.0.0.1", 0).then((server) {
|
||||
server.listen((request) {
|
||||
request.listen(null, onError: (e) {}, onDone: () {
|
||||
request.response.close();
|
||||
});
|
||||
request.listen(
|
||||
null,
|
||||
onError: (e) {},
|
||||
onDone: () {
|
||||
request.response.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
Process.run(
|
||||
Platform.executable,
|
||||
[]
|
||||
..addAll(Platform.executableArguments)
|
||||
..addAll([
|
||||
Platform.script.resolve(CLIENT_SCRIPT).toString(),
|
||||
server.port.toString()
|
||||
]))
|
||||
.then((result) {
|
||||
Platform.executable,
|
||||
[]
|
||||
..addAll(Platform.executableArguments)
|
||||
..addAll([
|
||||
Platform.script.resolve(CLIENT_SCRIPT).toString(),
|
||||
server.port.toString(),
|
||||
]),
|
||||
).then((result) {
|
||||
if (result.exitCode != 0) throw "Bad exit code";
|
||||
server.close();
|
||||
});
|
||||
|
||||
@@ -16,11 +16,11 @@ main() {
|
||||
HttpServer.bind("127.0.0.1", 0).then((server) {
|
||||
server.listen((request) {
|
||||
String name = Platform.script.toFilePath();
|
||||
new File(name)
|
||||
.openRead()
|
||||
.cast<List<int>>()
|
||||
.pipe(request.response)
|
||||
.catchError((e) {/* ignore */});
|
||||
new File(
|
||||
name,
|
||||
).openRead().cast<List<int>>().pipe(request.response).catchError((e) {
|
||||
/* ignore */
|
||||
});
|
||||
});
|
||||
|
||||
var count = 0;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user