Skip to content

Commit 7ce228c

Browse files
committed
Setup callback for send data progress
1 parent 9d4db9d commit 7ce228c

File tree

9 files changed

+233
-47
lines changed

9 files changed

+233
-47
lines changed

lib/http.dart

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'dart:typed_data';
88

99
import 'src/client.dart';
1010
import 'src/exception.dart';
11+
import 'src/progress.dart';
1112
import 'src/request.dart';
1213
import 'src/response.dart';
1314
import 'src/streamed_request.dart';
@@ -20,6 +21,7 @@ export 'src/client.dart';
2021
export 'src/exception.dart';
2122
export 'src/multipart_file.dart';
2223
export 'src/multipart_request.dart';
24+
export 'src/progress.dart';
2325
export 'src/request.dart';
2426
export 'src/response.dart';
2527
export 'src/streamed_request.dart';
@@ -61,12 +63,25 @@ Future<Response> get(Uri url, {Map<String, String>? headers}) =>
6163
///
6264
/// [encoding] defaults to [utf8].
6365
///
66+
/// If [onSendProgress] is provided it will be called to indicate
67+
/// the upload progress
68+
///
6469
/// For more fine-grained control over the request, use [Request] or
6570
/// [StreamedRequest] instead.
66-
Future<Response> post(Uri url,
67-
{Map<String, String>? headers, Object? body, Encoding? encoding}) =>
68-
_withClient((client) =>
69-
client.post(url, headers: headers, body: body, encoding: encoding));
71+
Future<Response> post(
72+
Uri url, {
73+
Map<String, String>? headers,
74+
Object? body,
75+
Encoding? encoding,
76+
Progress? onSendProgress,
77+
}) =>
78+
_withClient((client) => client.post(
79+
url,
80+
headers: headers,
81+
body: body,
82+
encoding: encoding,
83+
onSendProgress: onSendProgress,
84+
));
7085

7186
/// Sends an HTTP PUT request with the given headers and body to the given URL.
7287
///
@@ -84,12 +99,25 @@ Future<Response> post(Uri url,
8499
///
85100
/// [encoding] defaults to [utf8].
86101
///
102+
/// If [onSendProgress] is provided it will be called to indicate
103+
/// the upload progress
104+
///
87105
/// For more fine-grained control over the request, use [Request] or
88106
/// [StreamedRequest] instead.
89-
Future<Response> put(Uri url,
90-
{Map<String, String>? headers, Object? body, Encoding? encoding}) =>
91-
_withClient((client) =>
92-
client.put(url, headers: headers, body: body, encoding: encoding));
107+
Future<Response> put(
108+
Uri url, {
109+
Map<String, String>? headers,
110+
Object? body,
111+
Encoding? encoding,
112+
Progress? onSendProgress,
113+
}) =>
114+
_withClient((client) => client.put(
115+
url,
116+
headers: headers,
117+
body: body,
118+
encoding: encoding,
119+
onSendProgress: onSendProgress,
120+
));
93121

94122
/// Sends an HTTP PATCH request with the given headers and body to the given
95123
/// URL.
@@ -108,24 +136,50 @@ Future<Response> put(Uri url,
108136
///
109137
/// [encoding] defaults to [utf8].
110138
///
139+
/// If [onSendProgress] is provided it will be called to indicate
140+
/// the upload progress
141+
///
111142
/// For more fine-grained control over the request, use [Request] or
112143
/// [StreamedRequest] instead.
113-
Future<Response> patch(Uri url,
114-
{Map<String, String>? headers, Object? body, Encoding? encoding}) =>
115-
_withClient((client) =>
116-
client.patch(url, headers: headers, body: body, encoding: encoding));
144+
Future<Response> patch(
145+
Uri url, {
146+
Map<String, String>? headers,
147+
Object? body,
148+
Encoding? encoding,
149+
Progress? onSendProgress,
150+
}) =>
151+
_withClient((client) => client.patch(
152+
url,
153+
headers: headers,
154+
body: body,
155+
encoding: encoding,
156+
onSendProgress: onSendProgress,
157+
));
117158

118159
/// Sends an HTTP DELETE request with the given headers to the given URL.
119160
///
120161
/// This automatically initializes a new [Client] and closes that client once
121162
/// the request is complete. If you're planning on making multiple requests to
122163
/// the same server, you should use a single [Client] for all of those requests.
123164
///
165+
/// If [onSendProgress] is provided it will be called to indicate
166+
/// the upload progress
167+
///
124168
/// For more fine-grained control over the request, use [Request] instead.
125-
Future<Response> delete(Uri url,
126-
{Map<String, String>? headers, Object? body, Encoding? encoding}) =>
127-
_withClient((client) =>
128-
client.delete(url, headers: headers, body: body, encoding: encoding));
169+
Future<Response> delete(
170+
Uri url, {
171+
Map<String, String>? headers,
172+
Object? body,
173+
Encoding? encoding,
174+
Progress? onSendProgress,
175+
}) =>
176+
_withClient((client) => client.delete(
177+
url,
178+
headers: headers,
179+
body: body,
180+
encoding: encoding,
181+
onSendProgress: onSendProgress,
182+
));
129183

130184
/// Sends an HTTP GET request with the given headers to the given URL and
131185
/// returns a Future that completes to the body of the response as a [String].

lib/retry.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,20 @@ class RetryClient extends BaseClient {
9999
);
100100

101101
@override
102-
Future<StreamedResponse> send(BaseRequest request) async {
102+
Future<StreamedResponse> send(
103+
BaseRequest request, {
104+
Progress? onSendProgress,
105+
}) async {
103106
final splitter = StreamSplitter(request.finalize());
104107

105108
var i = 0;
106109
for (;;) {
107110
StreamedResponse? response;
108111
try {
109-
response = await _inner.send(_copyRequest(request, splitter.split()));
112+
response = await _inner.send(
113+
_copyRequest(request, splitter.split()),
114+
onSendProgress: onSendProgress,
115+
);
110116
} catch (error, stackTrace) {
111117
if (i == _retries || !_whenError(error, stackTrace)) rethrow;
112118
}

lib/src/base_client.dart

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'base_request.dart';
99
import 'byte_stream.dart';
1010
import 'client.dart';
1111
import 'exception.dart';
12+
import 'progress.dart';
1213
import 'request.dart';
1314
import 'response.dart';
1415
import 'streamed_response.dart';
@@ -27,24 +28,72 @@ abstract class BaseClient implements Client {
2728
_sendUnstreamed('GET', url, headers);
2829

2930
@override
30-
Future<Response> post(Uri url,
31-
{Map<String, String>? headers, Object? body, Encoding? encoding}) =>
32-
_sendUnstreamed('POST', url, headers, body, encoding);
31+
Future<Response> post(
32+
Uri url, {
33+
Map<String, String>? headers,
34+
Object? body,
35+
Encoding? encoding,
36+
Progress? onSendProgress,
37+
}) =>
38+
_sendUnstreamed(
39+
'POST',
40+
url,
41+
headers,
42+
body,
43+
encoding,
44+
onSendProgress,
45+
);
3346

3447
@override
35-
Future<Response> put(Uri url,
36-
{Map<String, String>? headers, Object? body, Encoding? encoding}) =>
37-
_sendUnstreamed('PUT', url, headers, body, encoding);
48+
Future<Response> put(
49+
Uri url, {
50+
Map<String, String>? headers,
51+
Object? body,
52+
Encoding? encoding,
53+
Progress? onSendProgress,
54+
}) =>
55+
_sendUnstreamed(
56+
'PUT',
57+
url,
58+
headers,
59+
body,
60+
encoding,
61+
onSendProgress,
62+
);
3863

3964
@override
40-
Future<Response> patch(Uri url,
41-
{Map<String, String>? headers, Object? body, Encoding? encoding}) =>
42-
_sendUnstreamed('PATCH', url, headers, body, encoding);
65+
Future<Response> patch(
66+
Uri url, {
67+
Map<String, String>? headers,
68+
Object? body,
69+
Encoding? encoding,
70+
Progress? onSendProgress,
71+
}) =>
72+
_sendUnstreamed(
73+
'PATCH',
74+
url,
75+
headers,
76+
body,
77+
encoding,
78+
onSendProgress,
79+
);
4380

4481
@override
45-
Future<Response> delete(Uri url,
46-
{Map<String, String>? headers, Object? body, Encoding? encoding}) =>
47-
_sendUnstreamed('DELETE', url, headers, body, encoding);
82+
Future<Response> delete(
83+
Uri url, {
84+
Map<String, String>? headers,
85+
Object? body,
86+
Encoding? encoding,
87+
Progress? onSendProgress,
88+
}) =>
89+
_sendUnstreamed(
90+
'DELETE',
91+
url,
92+
headers,
93+
body,
94+
encoding,
95+
onSendProgress,
96+
);
4897

4998
@override
5099
Future<String> read(Uri url, {Map<String, String>? headers}) async {
@@ -68,12 +117,20 @@ abstract class BaseClient implements Client {
68117
/// later point, or it could already be closed when it's returned. Any
69118
/// internal HTTP errors should be wrapped as [ClientException]s.
70119
@override
71-
Future<StreamedResponse> send(BaseRequest request);
120+
Future<StreamedResponse> send(
121+
BaseRequest request, {
122+
Progress? onSendProgress,
123+
});
72124

73125
/// Sends a non-streaming [Request] and returns a non-streaming [Response].
74126
Future<Response> _sendUnstreamed(
75-
String method, Uri url, Map<String, String>? headers,
76-
[body, Encoding? encoding]) async {
127+
String method,
128+
Uri url,
129+
Map<String, String>? headers, [
130+
body,
131+
Encoding? encoding,
132+
Progress? onSendProgress,
133+
]) async {
77134
var request = Request(method, url);
78135

79136
if (headers != null) request.headers.addAll(headers);
@@ -90,7 +147,10 @@ abstract class BaseClient implements Client {
90147
}
91148
}
92149

93-
return Response.fromStream(await send(request));
150+
return Response.fromStream(await send(
151+
request,
152+
onSendProgress: onSendProgress,
153+
));
94154
}
95155

96156
/// Throws an error if [response] is not successful.

lib/src/base_request.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import 'base_client.dart';
1111
import 'base_response.dart';
1212
import 'byte_stream.dart';
1313
import 'client.dart';
14+
import 'progress.dart';
1415
import 'streamed_response.dart';
1516
import 'utils.dart';
1617

@@ -27,6 +28,9 @@ abstract class BaseRequest {
2728
/// Non-standard method names are also supported.
2829
final String method;
2930

31+
/// The callback to call for data send progress.
32+
Progress? onSendProgress;
33+
3034
/// The URL to which the request will be sent.
3135
final Uri url;
3236

@@ -130,7 +134,10 @@ abstract class BaseRequest {
130134
var client = Client();
131135

132136
try {
133-
var response = await client.send(this);
137+
var response = await client.send(
138+
this,
139+
onSendProgress: onSendProgress,
140+
);
134141
var stream = onDone(response.stream, client.close);
135142
return StreamedResponse(ByteStream(stream), response.statusCode,
136143
contentLength: response.contentLength,

lib/src/browser_client.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import 'base_client.dart';
1212
import 'base_request.dart';
1313
import 'byte_stream.dart';
1414
import 'exception.dart';
15+
import 'progress.dart';
1516
import 'streamed_response.dart';
1617

1718
/// Create a [BrowserClient].
@@ -41,7 +42,10 @@ class BrowserClient extends BaseClient {
4142

4243
/// Sends an HTTP request and asynchronously returns the response.
4344
@override
44-
Future<StreamedResponse> send(BaseRequest request) async {
45+
Future<StreamedResponse> send(
46+
BaseRequest request, {
47+
Progress? onSendProgress,
48+
}) async {
4549
var bytes = await request.finalize().toBytes();
4650
var xhr = HttpRequest();
4751
_xhrs.add(xhr);

0 commit comments

Comments
 (0)