blob: a6ea742d6f49725e123b9f588def45f1cb5d659b [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:utf';
import 'package:expect/expect.dart';
void testHttpClientResponseBody() {
void test(String mimeType,
List<int> content,
dynamic expectedBody,
String type,
[bool shouldFail = false]) {
HttpServer.bind("127.0.0.1", 0).then((server) {
server.listen((request) {
request.listen(
(_) {},
onDone: () {
request.response.headers.contentType =
ContentType.parse(mimeType);
request.response.add(content);
request.response.close();
});
});
var client = new HttpClient();
client.get("127.0.0.1", server.port, "/")
.then((request) => request.close())
.then(HttpBodyHandler.processResponse)
.then((body) {
if (shouldFail) Expect.fail("Error expected");
Expect.equals(type, body.type);
Expect.isNotNull(body.response);
switch (type) {
case "text":
Expect.equals(expectedBody, body.body);
break;
case "json":
Expect.mapEquals(expectedBody, body.body);
break;
default:
Expect.fail("bad body type");
}
}, onError: (error) {
if (!shouldFail) Expect.fail("Error unexpected");
})
.whenComplete(() {
client.close();
server.close();
});
});
}
test("text/plain", "body".codeUnits, "body", "text");
test("text/plain; charset=utf-8",
"body".codeUnits,
"body",
"text");
test("text/plain; charset=iso-8859-1",
"body".codeUnits,
"body",
"text");
test("text/plain; charset=us-ascii",
"body".codeUnits,
"body",
"text");
test("text/plain; charset=utf-8", [42], "*", "text");
test("text/plain; charset=us-ascii", [142], "?", "text");
test("text/plain; charset=utf-8",
[142],
new String.fromCharCodes([UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]),
"text");
test("application/json",
'{"val": 5}'.codeUnits,
{ "val" : 5 },
"json");
test("application/json",
'{ bad json }'.codeUnits,
null,
"json",
true);
}
void testHttpServerRequestBody() {
void test(String mimeType,
List<int> content,
dynamic expectedBody,
String type,
{bool shouldFail: false}) {
HttpServer.bind("127.0.0.1", 0).then((server) {
server.transform(new HttpBodyHandler())
.listen((body) {
if (shouldFail) Expect.fail("Error expected");
Expect.equals(type, body.type);
switch (type) {
case "text":
Expect.equals(body.contentType.mimeType, "text/plain");
Expect.equals(expectedBody, body.body);
break;
case "json":
Expect.equals(body.contentType.mimeType, "application/json");
Expect.mapEquals(expectedBody, body.body);
break;
case "binary":
Expect.equals(body.contentType, null);
Expect.listEquals(expectedBody, body.body);
break;
case "form":
var mimeType = body.contentType.mimeType;
Expect.isTrue(
mimeType == 'multipart/form-data' ||
mimeType == 'application/x-www-form-urlencoded');
Expect.setEquals(expectedBody.keys.toSet(),
body.body.keys.toSet());
for (var key in expectedBody.keys) {
if (body.body[key] is HttpBodyFileUpload) {
Expect.equals(expectedBody[key]['contentType'],
body.body[key].contentType.toString());
Expect.equals(expectedBody[key]['filename'],
body.body[key].filename);
if (body.body[key].content is String) {
Expect.equals(expectedBody[key]['content'],
body.body[key].content);
} else {
Expect.listEquals(expectedBody[key]['content'],
body.body[key].content);
}
} else {
Expect.equals(expectedBody[key], body.body[key]);
}
}
break;
default:
Expect.fail("bad body type");
}
body.response.close();
}, onError: (error) {
if (!shouldFail) throw error;
});
var client = new HttpClient();
client.post("127.0.0.1", server.port, "/")
.then((request) {
if (mimeType != null) {
request.headers.contentType =
ContentType.parse(mimeType);
}
request.add(content);
return request.close();
})
.then((response) {
if (shouldFail) {
Expect.equals(HttpStatus.BAD_REQUEST, response.statusCode);
}
response.fold(null, (x, y) {});
client.close();
server.close();
});
});
}
test("text/plain", "body".codeUnits, "body", "text");
test("text/plain; charset=utf-8",
"body".codeUnits,
"body",
"text");
test("text/plain; charset=utf-8", [42], "*", "text");
test("text/plain; charset=us-ascii", [142], "?", "text");
test("text/plain; charset=utf-8",
[142],
new String.fromCharCodes([UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]),
"text");
test("application/json",
'{"val": 5}'.codeUnits,
{ "val" : 5 },
"json");
test("application/json",
'{ bad json }'.codeUnits,
null,
"json",
shouldFail: true);
test(null, "body".codeUnits, "body".codeUnits, "binary");
test("multipart/form-data; boundary=AaB03x",
'''
--AaB03x\r
Content-Disposition: form-data; name="name"\r
\r
Larry\r
--AaB03x--\r\n'''.codeUnits,
{ "name": "Larry" },
"form");
test("multipart/form-data; boundary=AaB03x",
'''
--AaB03x\r
Content-Disposition: form-data; name="files"; filename="myfile"\r
Content-Type: application/octet-stream\r
\r
File content\r
--AaB03x--\r\n'''.codeUnits,
{ "files": { 'filename': 'myfile',
'contentType': 'application/octet-stream',
'content': 'File content'.codeUnits} },
"form");
test("multipart/form-data; boundary=AaB03x",
'''
--AaB03x\r
Content-Disposition: form-data; name="files"; filename="myfile"\r
Content-Type: application/octet-stream\r
\r
File content\r
--AaB03x\r
Content-Disposition: form-data; name="files"; filename="myfile"\r
Content-Type: text/plain\r
\r
File content\r
--AaB03x--\r\n'''.codeUnits,
{ "files": { 'filename': 'myfile',
'contentType': 'text/plain',
'content': 'File content'} },
"form");
test("multipart/form-data; boundary=AaB03x",
'''
--AaB03x\r
Content-Disposition: form-data; name="files"; filename="myfile"\r
Content-Type: application/json\r
\r
File content\r
--AaB03x--\r\n'''.codeUnits,
{ "files": { 'filename': 'myfile',
'contentType': 'application/json',
'content': 'File content'} },
"form");
test('application/x-www-form-urlencoded',
'%E5%B9%B3%3D%E4%BB%AE%E5%90%8D=%26%2324179%3B%26%2320206%3B%26%'
'2321517%3B&b=%26%2324179%3B%26%2320206%3B%26%2321517%3B'.codeUnits,
{ 'b' : '平仮名',
'平=仮名' : '平仮名'},
"form");
}
void main() {
testHttpClientResponseBody();
testHttpServerRequestBody();
}