Make failing HTTP requests thrown when using dart:io.
Previous behavior was to expose the response content anyway,
which was generally empty on a 404 error.
R=sgjesse@google.com
Review-Url: https://codereview.chromium.org//2638403002 .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa4ec0f..faf031d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,8 @@
# Changelog
+## 2.1.0
+- Make failing HTTP requests throw an `HttpException`.
+
## 2.0.2
- Update README.md.
diff --git a/lib/src/io_io.dart b/lib/src/io_io.dart
index d4edfea..1056d75 100644
--- a/lib/src/io_io.dart
+++ b/lib/src/io_io.dart
@@ -4,8 +4,12 @@
import "dart:async" show Future, Stream;
import "dart:convert" show Encoding, LATIN1, UTF8;
-import "dart:io" show
- File, HttpClient, HttpClientResponse, HttpClientRequest, HttpHeaders;
+import "dart:io" show File,
+ HttpStatus,
+ HttpClient,
+ HttpClientResponse,
+ HttpClientRequest,
+ HttpHeaders;
import "package:typed_data/typed_buffers.dart" show Uint8Buffer;
@@ -17,6 +21,7 @@
}
if (uri.scheme == "http" || uri.scheme == "https") {
HttpClientResponse response = await _httpGetBytes(uri);
+ _throwIfFailed(response, uri);
yield* response;
return;
}
@@ -34,6 +39,7 @@
}
if (uri.scheme == "http" || uri.scheme == "https") {
HttpClientResponse response = await _httpGetBytes(uri);
+ _throwIfFailed(response, uri);
int length = response.contentLength;
if (length < 0) length = 0;
var buffer = new Uint8Buffer(length);
@@ -62,6 +68,7 @@
request.headers.set(HttpHeaders.ACCEPT_CHARSET, encoding.name);
}
HttpClientResponse response = await request.close();
+ _throwIfFailed(response, uri);
encoding ??= Encoding.getByName(response.headers.contentType?.charset);
if (encoding == null || encoding == LATIN1) {
// Default to LATIN-1 if no encoding found.
@@ -88,3 +95,10 @@
request.headers.set(HttpHeaders.ACCEPT, "application/octet-stream, */*");
return request.close();
}
+
+void _throwIfFailed(HttpClientResponse response, Uri uri) {
+ var statusCode = response.statusCode;
+ if (statusCode < HttpStatus.OK || statusCode > HttpStatus.NO_CONTENT) {
+ throw new HttpException(response.reasonPhrase, uri: uri);
+ }
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index 460b422..7a182b2 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: resource
-version: 2.0.2
+version: 2.1.0
description: Reading resource data from (package and other) files.
author: Dart Team <misc@dartlang.org>
homepage: https://github.com/dart-lang/resource
diff --git a/test/loader_http_test.dart b/test/loader_http_test.dart
index 114ec6a..7795f58 100644
--- a/test/loader_http_test.dart
+++ b/test/loader_http_test.dart
@@ -20,6 +20,12 @@
int port = server.port;
uri = Uri.parse("http://localhost:$port/default.html");
server.forEach((HttpRequest request) {
+ if (request.uri.path.endsWith(".not")) {
+ request.response
+ ..statusCode = HttpStatus.NOT_FOUND
+ ..close();
+ return;
+ }
var encodings = request.headers[HttpHeaders.ACCEPT_CHARSET];
var encoding = parseAcceptCharset(encodings);
request.response.headers.contentType =
@@ -61,6 +67,24 @@
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);
+ });
+
+ test("not found - bytes", () async {
+ var loader = ResourceLoader.defaultLoader;
+ var badUri = uri.resolve("file.not"); // .not makes server fail.
+ expect(loader.readAsBytes(badUri), throws);
+ });
+
+ 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);
+ });
+
tearDown(() {
server.close();
server = null;