Skip to content

Commit a131e56

Browse files
authored
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.
1 parent 3b6ab5e commit a131e56

File tree

5 files changed

+58
-5
lines changed

5 files changed

+58
-5
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
## 0.12.1-dev
22

3+
* Add `IOStreamedResponse` which includes the ability to detach the socket.
4+
When sending a request with an `IOClient` the response will be an
5+
`IOStreamedResponse`.
36
* Remove dependency on `package:async`.
47

58
## 0.12.0+4

lib/io_client.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
export 'src/io_client.dart' show IOClient;
6+
export 'src/io_streamed_response.dart' show IOStreamedResponse;

lib/src/io_client.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import 'dart:io';
88
import 'base_client.dart';
99
import 'base_request.dart';
1010
import 'exception.dart';
11-
import 'streamed_response.dart';
11+
import 'io_streamed_response.dart';
1212

1313
/// Create an [IOClient].
1414
///
@@ -24,7 +24,7 @@ class IOClient extends BaseClient {
2424

2525
/// Sends an HTTP request and asynchronously returns the response.
2626
@override
27-
Future<StreamedResponse> send(BaseRequest request) async {
27+
Future<IOStreamedResponse> send(BaseRequest request) async {
2828
var stream = request.finalize();
2929

3030
try {
@@ -44,7 +44,7 @@ class IOClient extends BaseClient {
4444
headers[key] = values.join(',');
4545
});
4646

47-
return StreamedResponse(
47+
return IOStreamedResponse(
4848
response.handleError(
4949
(HttpException error) =>
5050
throw ClientException(error.message, error.uri),
@@ -56,7 +56,8 @@ class IOClient extends BaseClient {
5656
headers: headers,
5757
isRedirect: response.isRedirect,
5858
persistentConnection: response.persistentConnection,
59-
reasonPhrase: response.reasonPhrase);
59+
reasonPhrase: response.reasonPhrase,
60+
inner: response);
6061
} on HttpException catch (error) {
6162
throw ClientException(error.message, error.uri);
6263
}

lib/src/io_streamed_response.dart

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:io';
6+
7+
import 'base_request.dart';
8+
import 'streamed_response.dart';
9+
10+
/// An HTTP response where the response body is received asynchronously after
11+
/// the headers have been received.
12+
class IOStreamedResponse extends StreamedResponse {
13+
final HttpClientResponse _inner;
14+
15+
/// Creates a new streaming response.
16+
///
17+
/// [stream] should be a single-subscription stream.
18+
IOStreamedResponse(Stream<List<int>> stream, int statusCode,
19+
{int contentLength,
20+
BaseRequest request,
21+
Map<String, String> headers = const {},
22+
bool isRedirect = false,
23+
bool persistentConnection = true,
24+
String reasonPhrase,
25+
HttpClientResponse inner})
26+
: _inner = inner,
27+
super(stream, statusCode,
28+
contentLength: contentLength,
29+
request: request,
30+
headers: headers,
31+
isRedirect: isRedirect,
32+
persistentConnection: persistentConnection,
33+
reasonPhrase: reasonPhrase);
34+
35+
/// Detaches the underlying socket from the HTTP server.
36+
Future<Socket> detachSocket() async => _inner.detachSocket();
37+
}

test/io/client_test.dart

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import 'dart:convert';
88
import 'dart:io';
99

1010
import 'package:http/http.dart' as http;
11-
import 'package:http/src/io_client.dart' as http_io;
11+
import 'package:http/io_client.dart' as http_io;
1212
import 'package:test/test.dart';
1313

1414
import 'utils.dart';
@@ -121,4 +121,15 @@ void main() {
121121
var contentType = (headers['content-type'] as List).single;
122122
expect(contentType, startsWith('multipart/form-data; boundary='));
123123
});
124+
125+
test('detachSocket returns a socket from an IOStreamedResponse', () async {
126+
var ioClient = HttpClient();
127+
var client = http_io.IOClient(ioClient);
128+
var request = http.Request('GET', serverUrl);
129+
130+
var response = await client.send(request);
131+
var socket = await response.detachSocket();
132+
133+
expect(socket, isNotNull);
134+
});
124135
}

0 commit comments

Comments
 (0)