简体   繁体   中英

How to cancel ongoing file upload sent with http.MultipartRequest() in Flutter?

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();
      }));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM