a323c55162
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>
182 lines
4.6 KiB
Dart
182 lines
4.6 KiB
Dart
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
//
|
|
// VMOptions=
|
|
// VMOptions=--short_socket_read
|
|
// VMOptions=--short_socket_write
|
|
// VMOptions=--short_socket_read --short_socket_write
|
|
|
|
import "dart:async";
|
|
import "dart:io";
|
|
import "dart:isolate";
|
|
import "package:expect/expect.dart";
|
|
|
|
Future sendData(List<int> data, int port) {
|
|
return Socket.connect("127.0.0.1", port).then((socket) {
|
|
socket.listen((data) {
|
|
Expect.fail("No data response was expected");
|
|
});
|
|
socket.add(data);
|
|
return socket.close().then((_) {
|
|
socket.destroy();
|
|
});
|
|
});
|
|
}
|
|
|
|
class EarlyCloseTest {
|
|
EarlyCloseTest(this.data, [this.exception, this.expectRequest = false]);
|
|
|
|
Future execute() {
|
|
return HttpServer.bind("127.0.0.1", 0).then((server) {
|
|
Completer c = new Completer();
|
|
|
|
bool calledOnRequest = false;
|
|
bool calledOnError = false;
|
|
bool calledOnDone = false;
|
|
ReceivePort port = new ReceivePort();
|
|
var requestCompleter = new Completer();
|
|
server.listen(
|
|
(request) {
|
|
Expect.isTrue(expectRequest);
|
|
Expect.isFalse(calledOnError);
|
|
Expect.isFalse(calledOnRequest, "onRequest called multiple times");
|
|
calledOnRequest = true;
|
|
request.listen(
|
|
(_) {},
|
|
onDone: () {
|
|
requestCompleter.complete();
|
|
},
|
|
onError: (error) {
|
|
Expect.isFalse(calledOnError);
|
|
Expect.equals(exception, error.message);
|
|
calledOnError = true;
|
|
if (exception != null) port.close();
|
|
},
|
|
);
|
|
},
|
|
onDone: () {
|
|
Expect.equals(expectRequest, calledOnRequest);
|
|
calledOnDone = true;
|
|
if (exception == null) port.close();
|
|
c.complete(null);
|
|
},
|
|
);
|
|
|
|
List<int>? d;
|
|
if (data is List<int>) d = data;
|
|
if (data is String) d = data.codeUnits;
|
|
if (d == null) Expect.fail("Invalid data");
|
|
sendData(d!, server.port).then((_) {
|
|
if (!expectRequest) requestCompleter.complete();
|
|
requestCompleter.future.then((_) => server.close());
|
|
});
|
|
|
|
return c.future;
|
|
});
|
|
}
|
|
|
|
final data;
|
|
final String? exception;
|
|
final bool expectRequest;
|
|
}
|
|
|
|
void testEarlyClose1() {
|
|
List<EarlyCloseTest> tests = <EarlyCloseTest>[];
|
|
void add(Object data, [String? exception, bool expectRequest = false]) {
|
|
tests.add(new EarlyCloseTest(data, exception, expectRequest));
|
|
}
|
|
// The empty packet is valid.
|
|
|
|
// Close while sending header
|
|
add("G");
|
|
add("GET /");
|
|
add("GET / HTTP/1.1");
|
|
add("GET / HTTP/1.1\r\n");
|
|
|
|
// Close while sending content
|
|
add(
|
|
"GET / HTTP/1.1\r\nContent-Length: 100\r\n\r\n",
|
|
"Connection closed while receiving data",
|
|
true,
|
|
);
|
|
add(
|
|
"GET / HTTP/1.1\r\nContent-Length: 100\r\n\r\n1",
|
|
"Connection closed while receiving data",
|
|
true,
|
|
);
|
|
|
|
void runTest(Iterator it) {
|
|
if (it.moveNext()) {
|
|
it.current.execute().then((_) {
|
|
runTest(it);
|
|
});
|
|
}
|
|
}
|
|
|
|
runTest(tests.iterator);
|
|
}
|
|
|
|
testEarlyClose2() {
|
|
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 */
|
|
});
|
|
});
|
|
|
|
var count = 0;
|
|
makeRequest() {
|
|
Socket.connect("127.0.0.1", server.port).then((socket) {
|
|
var data = "GET / HTTP/1.1\r\nContent-Length: 0\r\n\r\n";
|
|
socket.write(data);
|
|
socket.close();
|
|
socket.done.then((_) {
|
|
socket.destroy();
|
|
if (++count < 10) {
|
|
makeRequest();
|
|
} else {
|
|
scheduleMicrotask(server.close);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
makeRequest();
|
|
});
|
|
}
|
|
|
|
void testEarlyClose3() {
|
|
HttpServer.bind("127.0.0.1", 0).then((server) {
|
|
server.listen((request) {
|
|
var subscription;
|
|
subscription = request.listen(
|
|
(_) {},
|
|
onError: (error) {
|
|
// subscription.cancel should not trigger an error.
|
|
subscription.cancel();
|
|
server.close();
|
|
},
|
|
);
|
|
});
|
|
Socket.connect("127.0.0.1", server.port).then((socket) {
|
|
socket.write("GET / HTTP/1.1\r\n");
|
|
socket.write("Content-Length: 10\r\n");
|
|
socket.write("\r\n");
|
|
socket.write("data");
|
|
socket.close();
|
|
socket.listen((_) {}, onError: (_) {});
|
|
socket.done.catchError((_) {});
|
|
});
|
|
});
|
|
}
|
|
|
|
void main() {
|
|
testEarlyClose1();
|
|
testEarlyClose2();
|
|
testEarlyClose3();
|
|
}
|