blob: 4df9782b8ec0c3de39b553d2f9cb6935c74976d4 [file] [log] [blame]
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
import "dart:io";
import "dart:uri";
HttpServer setupServer() {
HttpServer server = new HttpServer();
server.listen("127.0.0.1", 0, backlog: 5);
void addRedirectHandler(int number, int statusCode) {
server.addRequestHandler(
(HttpRequest request) => request.path == "/$number",
(HttpRequest request, HttpResponse response) {
response.headers.set(HttpHeaders.LOCATION,
"http://127.0.0.1:${server.port}/${number + 1}");
response.statusCode = statusCode;
response.outputStream.close();
});
}
// Setup simple redirect.
server.addRequestHandler(
(HttpRequest request) => request.path == "/redirect",
(HttpRequest request, HttpResponse response) {
response.headers.set(HttpHeaders.LOCATION,
"http://127.0.0.1:${server.port}/location");
response.statusCode = HttpStatus.MOVED_PERMANENTLY;
response.outputStream.close();
}
);
server.addRequestHandler(
(HttpRequest request) => request.path == "/location",
(HttpRequest request, HttpResponse response) {
response.outputStream.close();
}
);
// Setup redirect chain.
int n = 1;
addRedirectHandler(n++, HttpStatus.MOVED_PERMANENTLY);
addRedirectHandler(n++, HttpStatus.MOVED_TEMPORARILY);
addRedirectHandler(n++, HttpStatus.SEE_OTHER);
addRedirectHandler(n++, HttpStatus.TEMPORARY_REDIRECT);
for (int i = n; i < 10; i++) {
addRedirectHandler(i, HttpStatus.MOVED_PERMANENTLY);
}
// Setup redirect loop.
server.addRequestHandler(
(HttpRequest request) => request.path == "/A",
(HttpRequest request, HttpResponse response) {
response.headers.set(HttpHeaders.LOCATION,
"http://127.0.0.1:${server.port}/B");
response.statusCode = HttpStatus.MOVED_PERMANENTLY;
response.outputStream.close();
}
);
server.addRequestHandler(
(HttpRequest request) => request.path == "/B",
(HttpRequest request, HttpResponse response) {
response.headers.set(HttpHeaders.LOCATION,
"http://127.0.0.1:${server.port}/A");
response.statusCode = HttpStatus.MOVED_TEMPORARILY;
response.outputStream.close();
}
);
// Setup redirect checking headers.
server.addRequestHandler(
(HttpRequest request) => request.path == "/src",
(HttpRequest request, HttpResponse response) {
Expect.equals("value", request.headers.value("X-Request-Header"));
response.headers.set(HttpHeaders.LOCATION,
"http://127.0.0.1:${server.port}/target");
response.statusCode = HttpStatus.MOVED_PERMANENTLY;
response.outputStream.close();
}
);
server.addRequestHandler(
(HttpRequest request) => request.path == "/target",
(HttpRequest request, HttpResponse response) {
Expect.equals("value", request.headers.value("X-Request-Header"));
response.outputStream.close();
}
);
// Setup redirect for 301 where POST should not redirect.
server.addRequestHandler(
(HttpRequest request) => request.path == "/301src",
(HttpRequest request, HttpResponse response) {
Expect.equals("POST", request.method);
response.headers.set(HttpHeaders.LOCATION,
"http://127.0.0.1:${server.port}/301target");
response.statusCode = HttpStatus.MOVED_PERMANENTLY;
response.outputStream.close();
}
);
server.addRequestHandler(
(HttpRequest request) => request.path == "/301target",
(HttpRequest request, HttpResponse response) {
Expect.fail("Redirect of POST should not happen");
}
);
// Setup redirect for 303 where POST should turn into GET.
server.addRequestHandler(
(HttpRequest request) => request.path == "/303src",
(HttpRequest request, HttpResponse response) {
Expect.equals("POST", request.method);
Expect.equals(10, request.contentLength);
request.inputStream.onData = request.inputStream.read;
request.inputStream.onClosed = () {
response.headers.set(HttpHeaders.LOCATION,
"http://127.0.0.1:${server.port}/303target");
response.statusCode = HttpStatus.SEE_OTHER;
response.outputStream.close();
};
}
);
server.addRequestHandler(
(HttpRequest request) => request.path == "/303target",
(HttpRequest request, HttpResponse response) {
Expect.equals("GET", request.method);
response.outputStream.close();
}
);
// Setup redirect where we close the connection.
server.addRequestHandler(
(HttpRequest request) => request.path == "/closing",
(HttpRequest request, HttpResponse response) {
response.headers.set(HttpHeaders.LOCATION,
"http://127.0.0.1:${server.port}/");
response.statusCode = HttpStatus.FOUND;
response.persistentConnection = false;
response.outputStream.close();
}
);
return server;
}
void checkRedirects(int redirectCount, HttpClientConnection conn) {
if (redirectCount < 2) {
Expect.isNull(conn.redirects);
} else {
Expect.equals(redirectCount - 1, conn.redirects.length);
for (int i = 0; i < redirectCount - 2; i++) {
Expect.equals(conn.redirects[i].location.path, "/${i + 2}");
}
}
}
void testManualRedirect() {
HttpServer server = setupServer();
HttpClient client = new HttpClient();
int redirectCount = 0;
HttpClientConnection conn =
client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/1"));
conn.followRedirects = false;
conn.onResponse = (HttpClientResponse response) {
response.inputStream.onData = response.inputStream.read;
response.inputStream.onClosed = () {
redirectCount++;
if (redirectCount < 10) {
Expect.isTrue(response.isRedirect);
checkRedirects(redirectCount, conn);
conn.redirect();
} else {
Expect.equals(HttpStatus.NOT_FOUND, response.statusCode);
server.close();
client.shutdown();
}
};
};
}
void testManualRedirectWithHeaders() {
HttpServer server = setupServer();
HttpClient client = new HttpClient();
int redirectCount = 0;
HttpClientConnection conn =
client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/src"));
conn.followRedirects = false;
conn.onRequest = (HttpClientRequest request) {
request.headers.add("X-Request-Header", "value");
request.outputStream.close();
};
conn.onResponse = (HttpClientResponse response) {
response.inputStream.onData = response.inputStream.read;
response.inputStream.onClosed = () {
redirectCount++;
if (redirectCount < 2) {
Expect.isTrue(response.isRedirect);
conn.redirect();
} else {
Expect.equals(HttpStatus.OK, response.statusCode);
server.close();
client.shutdown();
}
};
};
}
void testAutoRedirect() {
HttpServer server = setupServer();
HttpClient client = new HttpClient();
var requestCount = 0;
void onRequest(HttpClientRequest request) {
requestCount++;
request.outputStream.close();
}
void onResponse(HttpClientResponse response) {
response.inputStream.onData =
() => Expect.fail("Response data not expected");
response.inputStream.onClosed = () {
Expect.equals(1, requestCount);
server.close();
client.shutdown();
};
};
HttpClientConnection conn =
client.getUrl(
Uri.parse("http://127.0.0.1:${server.port}/redirect"));
conn.onRequest = onRequest;
conn.onResponse = onResponse;
conn.onError = (e) => Expect.fail("Error not expected ($e)");
}
void testAutoRedirectWithHeaders() {
HttpServer server = setupServer();
HttpClient client = new HttpClient();
var requestCount = 0;
void onRequest(HttpClientRequest request) {
requestCount++;
request.headers.add("X-Request-Header", "value");
request.outputStream.close();
};
void onResponse(HttpClientResponse response) {
response.inputStream.onData =
() => Expect.fail("Response data not expected");
response.inputStream.onClosed = () {
Expect.equals(1, requestCount);
server.close();
client.shutdown();
};
};
HttpClientConnection conn =
client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/src"));
conn.onRequest = onRequest;
conn.onResponse = onResponse;
conn.onError = (e) => Expect.fail("Error not expected ($e)");
}
void testAutoRedirect301POST() {
HttpServer server = setupServer();
HttpClient client = new HttpClient();
var requestCount = 0;
void onRequest(HttpClientRequest request) {
requestCount++;
request.outputStream.close();
};
void onResponse(HttpClientResponse response) {
Expect.equals(HttpStatus.MOVED_PERMANENTLY, response.statusCode);
response.inputStream.onData =
() => Expect.fail("Response data not expected");
response.inputStream.onClosed = () {
Expect.equals(1, requestCount);
server.close();
client.shutdown();
};
};
HttpClientConnection conn =
client.postUrl(
Uri.parse("http://127.0.0.1:${server.port}/301src"));
conn.onRequest = onRequest;
conn.onResponse = onResponse;
conn.onError = (e) => Expect.fail("Error not expected ($e)");
}
void testAutoRedirect303POST() {
HttpServer server = setupServer();
HttpClient client = new HttpClient();
var requestCount = 0;
void onRequest(HttpClientRequest request) {
requestCount++;
request.contentLength = 10;
request.outputStream.write(new List<int>.fixedLength(10, fill: 0));
request.outputStream.close();
};
void onResponse(HttpClientResponse response) {
Expect.equals(HttpStatus.OK, response.statusCode);
response.inputStream.onData =
() => Expect.fail("Response data not expected");
response.inputStream.onClosed = () {
Expect.equals(1, requestCount);
server.close();
client.shutdown();
};
};
HttpClientConnection conn =
client.postUrl(
Uri.parse("http://127.0.0.1:${server.port}/303src"));
conn.onRequest = onRequest;
conn.onResponse = onResponse;
conn.onError = (e) => Expect.fail("Error not expected ($e)");
}
void testAutoRedirectLimit() {
HttpServer server = setupServer();
HttpClient client = new HttpClient();
HttpClientConnection conn =
client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/1"));
conn.onResponse = (HttpClientResponse response) {
response.inputStream.onData = () => Expect.fail("Response not expected");
response.inputStream.onClosed = () => Expect.fail("Response not expected");
};
conn.onError = (e) {
Expect.isTrue(e is RedirectLimitExceededException);
Expect.equals(5, e.redirects.length);
server.close();
client.shutdown();
};
}
void testRedirectLoop() {
HttpServer server = setupServer();
HttpClient client = new HttpClient();
int redirectCount = 0;
HttpClientConnection conn =
client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/A"));
conn.onResponse = (HttpClientResponse response) {
response.inputStream.onData = () => Expect.fail("Response not expected");
response.inputStream.onClosed = () => Expect.fail("Response not expected");
};
conn.onError = (e) {
Expect.isTrue(e is RedirectLoopException);
Expect.equals(2, e.redirects.length);
server.close();
client.shutdown();
};
}
void testRedirectClosingConnection() {
HttpServer server = setupServer();
HttpClient client = new HttpClient();
int redirectCount = 0;
HttpClientConnection conn =
client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/closing"));
conn.followRedirects = true;
conn.onResponse = (HttpClientResponse response) {
response.inputStream.onData = () => Expect.fail("Response not expected");
response.inputStream.onClosed = () => Expect.fail("Response not expected");
};
conn.onError = (e) {
Expect.isTrue(e is RedirectException);
Expect.isNull(e.redirects);
server.close();
client.shutdown();
};
}
main() {
testManualRedirect();
testManualRedirectWithHeaders();
testAutoRedirect();
testAutoRedirectWithHeaders();
testAutoRedirect301POST();
testAutoRedirect303POST();
testAutoRedirectLimit();
testRedirectLoop();
testRedirectClosingConnection();
}