-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathmulti_part_request.dart
More file actions
70 lines (59 loc) · 2.07 KB
/
multi_part_request.dart
File metadata and controls
70 lines (59 loc) · 2.07 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
import 'dart:async';
import 'package:http/http.dart' as http;
import '../../uploader/uploader_response.dart';
import '../../models/upload_result.dart';
typedef ProgressCallback = void Function(int bytesUploaded, int totalBytes);
typedef CompletionCallback = void Function(
UploaderResponse<UploadResult> response);
class CldMultipartRequest extends http.MultipartRequest {
final ProgressCallback? onProgress;
Map<String, String> headers;
/// Creates a new [CldMultipartRequest].
CldMultipartRequest(String method, Uri url, this.headers, {this.onProgress})
: super(method, url);
/// Freezes all mutable fields and returns a single-subscription [ByteStream]
/// that will emit the request body.
@override
http.ByteStream finalize() {
final byteStream = super.finalize();
if (onProgress == null) return byteStream;
final total = contentLength;
int bytes = 0;
final t = StreamTransformer.fromHandlers(
handleData: (List<int> data, EventSink<List<int>> sink) {
bytes += data.length;
if (onProgress != null) {
onProgress!(bytes, total);
}
if (total >= bytes) {
sink.add(data);
}
},
);
final stream = byteStream.transform(t);
return http.ByteStream(stream);
}
@override
Future<http.StreamedResponse> send() async {
var client = http.Client();
try {
var response = await client.send(this);
var stream = onDone(response.stream, client.close);
return http.StreamedResponse(http.ByteStream(stream), response.statusCode,
contentLength: response.contentLength,
request: response.request,
headers: response.headers,
isRedirect: response.isRedirect,
persistentConnection: response.persistentConnection,
reasonPhrase: response.reasonPhrase);
} catch (_) {
client.close();
rethrow;
}
}
Stream<T> onDone<T>(Stream<T> stream, void Function() onDone) =>
stream.transform(StreamTransformer.fromHandlers(handleDone: (sink) {
sink.close();
onDone();
}));
}