I'm trying to add cancel functionality to file upload in my Flutter app. I'm currently using http.MultipartRequest()
from http package
to upload the file. I've tried wrapping the upload with CancelableOperation
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 using http.Client()
to upload the file and then closing it with the http.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 using http.MultipartRequest()
. One of the posts
So, 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 use http.Client()
? Or is there any better way to do this?
3. If using http.Client()
is the only way, then can you please show me how to upload file with http.Client()
? since it only has post()
and no multipartrequest()
.
Sorry for the long text. Please help. Thanks!
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();
}));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With