2
2
// for details. All rights reserved. Use of this source code is governed by a
3
3
// BSD-style license that can be found in the LICENSE file.
4
4
5
- import 'dart:async' ;
6
- import 'dart:convert' ;
7
- import 'dart:io' ;
8
-
5
+ import 'package:async/async.dart' ;
9
6
import 'package:http/http.dart' ;
7
+ import 'package:stream_channel/stream_channel.dart' ;
10
8
import 'package:test/test.dart' ;
11
9
12
10
/// Tests that the [Client] correctly implements HTTP responses with bodies.
@@ -17,78 +15,40 @@ import 'package:test/test.dart';
17
15
void testResponseBody (Client client,
18
16
{bool canStreamResponseBody = true }) async {
19
17
group ('response body' , () {
18
+ late final String host;
19
+ late final StreamChannel <Object ?> httpServerChannel;
20
+ late final StreamQueue <Object ?> httpServerQueue;
21
+ const message = 'Hello World!' ;
22
+
23
+ setUpAll (() async {
24
+ httpServerChannel =
25
+ spawnHybridUri ('../lib/src/response_body_server.dart' );
26
+ httpServerQueue = StreamQueue (httpServerChannel.stream);
27
+ host = 'localhost:${await httpServerQueue .next }' ;
28
+ });
29
+ tearDownAll (() => httpServerChannel.sink.add (null ));
30
+
20
31
test ('small response with content length' , () async {
21
- const message = 'Hello World!' ;
22
- final server = (await HttpServer .bind ('localhost' , 0 ))
23
- ..listen ((request) async {
24
- await request.drain <void >();
25
- request.response.headers.set ('Content-Type' , 'text/plain' );
26
- request.response.write (message);
27
- await request.response.close ();
28
- });
29
- final response =
30
- await client.get (Uri .http ('localhost:${server .port }' , '' ));
32
+ final response = await client.get (Uri .http (host, '' ));
31
33
expect (response.body, message);
32
34
expect (response.bodyBytes, message.codeUnits);
33
35
expect (response.contentLength, message.length);
34
36
expect (response.headers['content-type' ], 'text/plain' );
35
- await server.close ();
36
37
});
37
38
38
39
test ('small response streamed without content length' , () async {
39
- const message = 'Hello World!' ;
40
- final server = (await HttpServer .bind ('localhost' , 0 ))
41
- ..listen ((request) async {
42
- await request.drain <void >();
43
- request.response.headers.set ('Content-Type' , 'text/plain' );
44
- request.response.write (message);
45
- await request.response.close ();
46
- });
47
- final request = Request ('GET' , Uri .http ('localhost:${server .port }' , '' ));
40
+ final request = Request ('GET' , Uri .http (host, '' ));
48
41
final response = await client.send (request);
49
42
expect (await response.stream.bytesToString (), message);
50
- expect (response.contentLength, null );
43
+ if (canStreamResponseBody) {
44
+ expect (response.contentLength, null );
45
+ } else {
46
+ // If the response body is small then the Client can emulate a streamed
47
+ // response without streaming. But `response.contentLength` may or
48
+ // may not be set.
49
+ expect (response.contentLength, isIn ([null , 12 ]));
50
+ }
51
51
expect (response.headers['content-type' ], 'text/plain' );
52
- await server.close ();
53
52
});
54
-
55
- test ('large response streamed without content length' , () async {
56
- // The server continuously streams data to the client until
57
- // instructed to stop (by setting `serverWriting` to `false`).
58
- // The client sets `serverWriting` to `false` after it has
59
- // already received some data.
60
- //
61
- // This ensures that the client supports streamed responses.
62
- var serverWriting = false ;
63
- final server = (await HttpServer .bind ('localhost' , 0 ))
64
- ..listen ((request) async {
65
- await request.drain <void >();
66
- request.response.headers.set ('Content-Type' , 'text/plain' );
67
- serverWriting = true ;
68
- for (var i = 0 ; serverWriting; ++ i) {
69
- request.response.write ('$i \n ' );
70
- await request.response.flush ();
71
- // Let the event loop run.
72
- await Future <void >.delayed (const Duration ());
73
- }
74
- await request.response.close ();
75
- });
76
- final request = Request ('GET' , Uri .http ('localhost:${server .port }' , '' ));
77
- final response = await client.send (request);
78
- var lastReceived = 0 ;
79
- await const LineSplitter ()
80
- .bind (const Utf8Decoder ().bind (response.stream))
81
- .forEach ((s) {
82
- lastReceived = int .parse (s.trim ());
83
- if (lastReceived < 1000 ) {
84
- expect (serverWriting, true );
85
- } else {
86
- serverWriting = false ;
87
- }
88
- });
89
- expect (response.headers['content-type' ], 'text/plain' );
90
- expect (lastReceived, greaterThanOrEqualTo (1000 ));
91
- await server.close ();
92
- }, skip: canStreamResponseBody ? false : 'does not stream response bodies' );
93
53
});
94
54
}
0 commit comments