Skip to content
This repository has been archived by the owner on Sep 14, 2021. It is now read-only.

Commit

Permalink
Fix bug in readAsBytes via http when content-length is set. (#24)
Browse files Browse the repository at this point in the history
The `readAsBytes` method returns twice as much data as expected,
with the first half all zeroes. This comes from pre-allocating
the buffer, then appending to it (similar to issue 21, but with
`readAsBytes` instead of `readAsString`).

Updated the tests to also catch this case.

BUG: #23
  • Loading branch information
lyceel authored and lrhn committed Jun 6, 2017
1 parent 3b1ee7b commit d012b2c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 21 deletions.
19 changes: 11 additions & 8 deletions lib/src/io_io.dart
Expand Up @@ -4,13 +4,15 @@

import "dart:async" show Future, Stream;
import "dart:convert" show Encoding, LATIN1, UTF8;
import "dart:io" show File,
HttpStatus,
HttpClient,
HttpClientResponse,
HttpClientRequest,
HttpException,
HttpHeaders;
import "dart:io"
show
File,
HttpStatus,
HttpClient,
HttpClientResponse,
HttpClientRequest,
HttpException,
HttpHeaders;

import "package:typed_data/typed_buffers.dart" show Uint8Buffer;

Expand Down Expand Up @@ -43,7 +45,8 @@ Future<List<int>> readAsBytes(Uri uri) async {
_throwIfFailed(response, uri);
int length = response.contentLength;
if (length < 0) length = 0;
var buffer = new Uint8Buffer(length);
// Create empty buffer with capacity matching contentLength.
var buffer = new Uint8Buffer(length)..length = 0;
await for (var bytes in response) {
buffer.addAll(bytes);
}
Expand Down
41 changes: 28 additions & 13 deletions test/loader_http_test.dart
Expand Up @@ -31,10 +31,12 @@ main() {
request.response.headers.contentType =
new ContentType("text", "plain", charset: encoding.name);
if (request.uri.query.contains("length")) {
request.response.headers.contentLength = content.length;
request.response.headers.contentLength =
encoding.encode(content).length;
}
request.response..write(content)
..close();
request.response
..write(content)
..close();
}).catchError(print);
});

Expand All @@ -53,47 +55,61 @@ main() {
test("Latin-1 encoding w/ length", () async {
// Regression test for issue #21.
var loader = ResourceLoader.defaultLoader;
var newUri = uri.replace(query: "length"); // Request length set.
var newUri = uri.replace(query: "length"); // Request length set.
String string = await loader.readAsString(newUri, encoding: LATIN1);
expect(string, content);
});

test("UTF-8 encoding", () async {
var loader = ResourceLoader.defaultLoader;
var newUri = uri.replace(query: "length"); // Request length set.
String string = await loader.readAsString(newUri, encoding: UTF8);
expect(string, content);
});

test("UTF-8 encoding w/ length", () async {
var loader = ResourceLoader.defaultLoader;
String string = await loader.readAsString(uri, encoding: UTF8);
expect(string, content);
});

test("bytes", () async {
var loader = ResourceLoader.defaultLoader;
List<int> bytes = await loader.readAsBytes(uri); // Sender uses Latin-1.
List<int> bytes = await loader.readAsBytes(uri); // Sender uses Latin-1.
expect(bytes, content.codeUnits);
});

test("bytes w/ length", () async {
var loader = ResourceLoader.defaultLoader;
var newUri = uri.replace(query: "length"); // Request length set.
List<int> bytes = await loader.readAsBytes(newUri); // Sender uses Latin-1.
expect(bytes, content.codeUnits);
});

test("byte stream", () async {
var loader = ResourceLoader.defaultLoader;
var bytes = loader.openRead(uri); // Sender uses Latin-1.
var bytes = loader.openRead(uri); // Sender uses Latin-1.
var buffer = [];
await bytes.forEach(buffer.addAll);
expect(buffer, content.codeUnits);
});

test("not found - String", () async {
var loader = ResourceLoader.defaultLoader;
var badUri = uri.resolve("file.not"); // .not makes server fail.
expect(loader.readAsString(badUri), throws);
var badUri = uri.resolve("file.not"); // .not makes server fail.
expect(loader.readAsString(badUri), throwsException);
});

test("not found - bytes", () async {
var loader = ResourceLoader.defaultLoader;
var badUri = uri.resolve("file.not"); // .not makes server fail.
expect(loader.readAsBytes(badUri), throws);
var badUri = uri.resolve("file.not"); // .not makes server fail.
expect(loader.readAsBytes(badUri), throwsException);
});

test("not found - byte stream", () async {
var loader = ResourceLoader.defaultLoader;
var badUri = uri.resolve("file.not"); // .not makes server fail.
expect(loader.openRead(badUri).length, throws);
var badUri = uri.resolve("file.not"); // .not makes server fail.
expect(loader.openRead(badUri).length, throwsException);
});

tearDown(() {
Expand All @@ -102,7 +118,6 @@ main() {
});
}


Encoding parseAcceptCharset(List<String> headers) {
var encoding = LATIN1;
if (headers != null) {
Expand Down

0 comments on commit d012b2c

Please sign in to comment.