blob: c2a19bad06f2f9290d459edd6f9c74f209ef98af [file] [log] [blame]
// (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import "dart:io" hide HttpServer, HttpClient, HttpRequest, HttpException;
import "package:http_io/http_io.dart";
import "package:test/test.dart";
// Client makes a HTTP 1.0 request without connection keep alive. The
// server sets a content length but still needs to close the
// connection as there is no keep alive.
Future<Null> testHttp10NoKeepAlive() {
Completer<Null> completer = new Completer();
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((HttpRequest request) {
expect(request.headers.value('content-length'), isNull);
expect(-1, equals(request.contentLength));
var response = request.response;
response.contentLength = 1;
expect("1.0", equals(request.protocolVersion));
response.done
.then((_) => fail("Unexpected response completion"))
.catchError((error) => expect((error is HttpException), isTrue));
response.write("Z");
response.write("Z");
response.close();
}, onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
fail(msg);
});
int count = 0;
makeRequest() {
Socket.connect("127.0.0.1", server.port).then((socket) {
socket.write("GET / HTTP/1.0\r\n\r\n");
List<int> response = [];
socket.listen(response.addAll, onDone: () {
count++;
socket.destroy();
String s = new String.fromCharCodes(response).toLowerCase();
expect(-1, equals(s.indexOf("keep-alive")));
if (count < 10) {
makeRequest();
} else {
server.close();
completer.complete(null);
}
});
});
}
makeRequest();
});
return completer.future;
}
// Client makes a HTTP 1.0 request and the server does not set a
// content length so it has to close the connection to mark the end of
// the response.
Future<Null> testHttp10ServerClose() {
Completer<Null> completer = new Completer();
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((HttpRequest request) {
expect(request.headers.value('content-length'), isNull);
expect(-1, equals(request.contentLength));
request.listen((_) {}, onDone: () {
var response = request.response;
expect("1.0", equals(request.protocolVersion));
response.write("Z");
response.close();
});
}, onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
fail(msg);
});
int count = 0;
makeRequest() {
Socket.connect("127.0.0.1", server.port).then((socket) {
socket.write("GET / HTTP/1.0\r\n");
socket.write("Connection: Keep-Alive\r\n\r\n");
List<int> response = [];
socket.listen(response.addAll,
onDone: () {
socket.destroy();
count++;
String s = new String.fromCharCodes(response).toLowerCase();
expect("z", equals(s[s.length - 1]));
expect(-1, equals(s.indexOf("content-length:")));
expect(-1, equals(s.indexOf("keep-alive")));
if (count < 10) {
makeRequest();
} else {
server.close();
completer.complete(null);
}
},
onError: (e) => print(e));
});
}
makeRequest();
});
return completer.future;
}
// Client makes a HTTP 1.0 request with connection keep alive. The
// server sets a content length so the persistent connection can be
// used.
Future<Null> testHttp10KeepAlive() {
Completer<Null> completer = new Completer();
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((HttpRequest request) {
expect(request.headers.value('content-length'), isNull);
expect(-1, equals(request.contentLength));
var response = request.response;
response.contentLength = 1;
response.persistentConnection = true;
expect("1.0", equals(request.protocolVersion));
response.write("Z");
response.close();
}, onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
fail(msg);
});
Socket.connect("127.0.0.1", server.port).then((socket) {
void sendRequest() {
socket.write("GET / HTTP/1.0\r\n");
socket.write("Connection: Keep-Alive\r\n\r\n");
}
List<int> response = [];
int count = 0;
socket.listen((d) {
response.addAll(d);
if (response[response.length - 1] == "Z".codeUnitAt(0)) {
String s = new String.fromCharCodes(response).toLowerCase();
expect(s.indexOf("\r\nconnection: keep-alive\r\n") > 0, isTrue);
expect(s.indexOf("\r\ncontent-length: 1\r\n") > 0, isTrue);
count++;
if (count < 10) {
response = [];
sendRequest();
} else {
socket.close();
}
}
}, onDone: () {
socket.destroy();
server.close();
completer.complete(null);
});
sendRequest();
});
});
return completer.future;
}
// Client makes a HTTP 1.0 request with connection keep alive. The
// server does not set a content length so it cannot honor connection
// keep alive.
Future<Null> testHttp10KeepAliveServerCloses() {
Completer<Null> completer = new Completer();
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((HttpRequest request) {
expect(request.headers.value('content-length'), isNull);
expect(-1, equals(request.contentLength));
var response = request.response;
expect("1.0", equals(request.protocolVersion));
response.write("Z");
response.close();
}, onError: (e, trace) {
String msg = "Unexpected error $e";
if (trace != null) msg += "\nStackTrace: $trace";
fail(msg);
});
int count = 0;
makeRequest() {
Socket.connect("127.0.0.1", server.port).then((socket) {
socket.write("GET / HTTP/1.0\r\n");
socket.write("Connection: Keep-Alive\r\n\r\n");
List<int> response = [];
socket.listen(response.addAll, onDone: () {
socket.destroy();
count++;
String s = new String.fromCharCodes(response).toLowerCase();
expect("z", equals(s[s.length - 1]));
expect(-1, equals(s.indexOf("content-length")));
expect(-1, equals(s.indexOf("connection")));
if (count < 10) {
makeRequest();
} else {
server.close();
completer.complete(null);
}
});
});
}
makeRequest();
});
return completer.future;
}
void main() {
test("Http10NoKeepAlive", () async {
await testHttp10NoKeepAlive();
});
test("Http10ServerClose", () async {
await testHttp10ServerClose();
});
test("Http10KeepAlive", () async {
await testHttp10KeepAlive();
});
test("Http10KeepAliveServerCloses", () async {
await testHttp10KeepAliveServerCloses();
});
}