How to cancel ongoing file upload sent with http.MultipartRequest() in Flutter?
Package http
uses HTTPClient
under the hood. It wraps that underlying client in an IOClient
. Most of http
's methods (like get
and post
) allow you to pass in your own client, but the MultipartRequest
doesn't (it creates one for each request).
The easiest solution seems to be to subclass it.
import 'dart:async';
import 'dart:io';
import 'package:http/http.dart' as http;
class CloseableMultipartRequest extends http.MultipartRequest {
http.IOClient client = http.IOClient(HttpClient());
CloseableMultipartRequest(String method, Uri uri) : super(method, uri);
void close() => client.close();
@override
Future<http.StreamedResponse> send() async {
try {
var response = await client.send(this);
var stream = onDone(response.stream, client.close);
return new http.StreamedResponse(
new 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 onDone()) =>
stream.transform(new StreamTransformer.fromHandlers(handleDone: (sink) {
sink.close();
onDone();
}));
}
Admin
Updated on December 08, 2022Comments
-
Admin over 1 year
I'm trying to add cancel functionality to file upload in my Flutter app. I'm currently using
http.MultipartRequest()
fromhttp package
to upload the file. I've tried wrapping the upload withCancelableOperation
but it only cancels the internal process within my Flutter app and the file still gets uploaded successfully to my Firebase Storage server.I read the README.md on http package about using
http.Client()
and closing it after the http request is completed. I'm thinking about usinghttp.Client()
to upload the file and then closing it with thehttp.Client().close()
to cancel the http request.But, I haven't found the right way to upload file with
http.Client
yet. I browsed about it on Google and stackoverflow but all the posts recommend usinghttp.MultipartRequest()
. One of the postsSo, my questions are: 1. Is it possible to cancel upload file sent with
http.MultipartRequest()
from http package in Flutter? 2. Am I in the right track with trying to usehttp.Client()
? Or is there any better way to do this? 3. If usinghttp.Client()
is the only way, then can you please show me how to upload file withhttp.Client()
? since it only haspost()
and nomultipartrequest()
.Sorry for the long text. Please help. Thanks!
-
Admin over 5 yearsThank you so much @Richard Heap, it works like a charm! Thank you for taking your time to give me such detailed answer. I really appreciated it :)
-
Jon Scalet about 4 years@Richard This solution works if the http client is recreated with every new instance of CloseableMultipartRequest. However, it wouldn't support a reference to a client instance, in that case, it's not a good idea to close the connection to cancel the request.