add io_streamed_response (#388)
Closes #387
Adds `IOStreamedResponse` which is now the type returned by `IOClient`.
It adds a `detachSocket` method forwarding to the inner client.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 747ea8d..50fa3f6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,8 @@
## 0.12.1-dev
+* Add `IOStreamedResponse` which includes the ability to detach the socket.
+ When sending a request with an `IOClient` the response will be an
+ `IOStreamedResponse`.
* Remove dependency on `package:async`.
## 0.12.0+4
diff --git a/lib/io_client.dart b/lib/io_client.dart
index 170acfb..4c92b94 100644
--- a/lib/io_client.dart
+++ b/lib/io_client.dart
@@ -3,3 +3,4 @@
// BSD-style license that can be found in the LICENSE file.
export 'src/io_client.dart' show IOClient;
+export 'src/io_streamed_response.dart' show IOStreamedResponse;
diff --git a/lib/src/io_client.dart b/lib/src/io_client.dart
index f60aafe..85821e9 100644
--- a/lib/src/io_client.dart
+++ b/lib/src/io_client.dart
@@ -8,7 +8,7 @@
import 'base_client.dart';
import 'base_request.dart';
import 'exception.dart';
-import 'streamed_response.dart';
+import 'io_streamed_response.dart';
/// Create an [IOClient].
///
@@ -24,7 +24,7 @@
/// Sends an HTTP request and asynchronously returns the response.
@override
- Future<StreamedResponse> send(BaseRequest request) async {
+ Future<IOStreamedResponse> send(BaseRequest request) async {
var stream = request.finalize();
try {
@@ -44,7 +44,7 @@
headers[key] = values.join(',');
});
- return StreamedResponse(
+ return IOStreamedResponse(
response.handleError(
(HttpException error) =>
throw ClientException(error.message, error.uri),
@@ -56,7 +56,8 @@
headers: headers,
isRedirect: response.isRedirect,
persistentConnection: response.persistentConnection,
- reasonPhrase: response.reasonPhrase);
+ reasonPhrase: response.reasonPhrase,
+ inner: response);
} on HttpException catch (error) {
throw ClientException(error.message, error.uri);
}
diff --git a/lib/src/io_streamed_response.dart b/lib/src/io_streamed_response.dart
new file mode 100644
index 0000000..fc69837
--- /dev/null
+++ b/lib/src/io_streamed_response.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, 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 'base_request.dart';
+import 'streamed_response.dart';
+
+/// An HTTP response where the response body is received asynchronously after
+/// the headers have been received.
+class IOStreamedResponse extends StreamedResponse {
+ final HttpClientResponse _inner;
+
+ /// Creates a new streaming response.
+ ///
+ /// [stream] should be a single-subscription stream.
+ IOStreamedResponse(Stream<List<int>> stream, int statusCode,
+ {int contentLength,
+ BaseRequest request,
+ Map<String, String> headers = const {},
+ bool isRedirect = false,
+ bool persistentConnection = true,
+ String reasonPhrase,
+ HttpClientResponse inner})
+ : _inner = inner,
+ super(stream, statusCode,
+ contentLength: contentLength,
+ request: request,
+ headers: headers,
+ isRedirect: isRedirect,
+ persistentConnection: persistentConnection,
+ reasonPhrase: reasonPhrase);
+
+ /// Detaches the underlying socket from the HTTP server.
+ Future<Socket> detachSocket() async => _inner.detachSocket();
+}
diff --git a/test/io/client_test.dart b/test/io/client_test.dart
index 25bbd6b..e5bd66f 100644
--- a/test/io/client_test.dart
+++ b/test/io/client_test.dart
@@ -8,7 +8,7 @@
import 'dart:io';
import 'package:http/http.dart' as http;
-import 'package:http/src/io_client.dart' as http_io;
+import 'package:http/io_client.dart' as http_io;
import 'package:test/test.dart';
import 'utils.dart';
@@ -121,4 +121,15 @@
var contentType = (headers['content-type'] as List).single;
expect(contentType, startsWith('multipart/form-data; boundary='));
});
+
+ test('detachSocket returns a socket from an IOStreamedResponse', () async {
+ var ioClient = HttpClient();
+ var client = http_io.IOClient(ioClient);
+ var request = http.Request('GET', serverUrl);
+
+ var response = await client.send(request);
+ var socket = await response.detachSocket();
+
+ expect(socket, isNotNull);
+ });
}