request.dart
2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import '../http.dart';
import '../multipart/form_data.dart';
class Request<T> {
/// Headers attach to this [Request]
final Map<String, String> headers;
/// The [Uri] from request
final Uri url;
final Decoder<T> decoder;
/// The Http Method from this [Request]
/// ex: `GET`,`POST`,`PUT`,`DELETE`
final String method;
final int contentLength;
/// The BodyBytesStream of body from this [Request]
final BodyBytesStream bodyBytes;
/// When true, the client will follow redirects to resolves this [Request]
final bool followRedirects;
/// The maximum number of redirects if [followRedirects] is true.
final int maxRedirects;
final bool persistentConnection;
final FormData files;
const Request._({
@required this.method,
@required this.bodyBytes,
@required this.url,
@required this.headers,
@required this.contentLength,
@required this.followRedirects,
@required this.maxRedirects,
@required this.files,
@required this.persistentConnection,
@required this.decoder,
});
factory Request({
@required Uri url,
@required String method,
@required Map<String, String> headers,
BodyBytesStream bodyBytes,
bool followRedirects = true,
int maxRedirects = 4,
int contentLength,
FormData files,
bool persistentConnection = true,
Decoder<T> decoder,
}) {
assert(url != null);
assert(method != null);
assert(followRedirects != null);
if (followRedirects) {
assert(maxRedirects != null);
assert(maxRedirects > 0);
}
return Request._(
url: url,
method: method,
bodyBytes: bodyBytes ??= BodyBytesStream.fromBytes(const []),
headers: Map.from(headers ??= <String, String>{}),
followRedirects: followRedirects,
maxRedirects: maxRedirects,
contentLength: contentLength,
files: files,
persistentConnection: persistentConnection,
decoder: decoder,
);
}
}
class BodyBytesStream extends StreamView<List<int>> {
BodyBytesStream(Stream<List<int>> stream) : super(stream);
factory BodyBytesStream.fromBytes(List<int> bytes) =>
BodyBytesStream(Stream.fromIterable([bytes]));
Future<Uint8List> toBytes() {
var completer = Completer<Uint8List>();
var sink = ByteConversionSink.withCallback(
(bytes) => completer.complete(
Uint8List.fromList(bytes),
),
);
listen(sink.add,
onError: completer.completeError,
onDone: sink.close,
cancelOnError: true);
return completer.future;
}
Future<String> bytesToString([Encoding encoding = utf8]) =>
encoding.decodeStream(this);
}