skip to Main Content

I am using flutter http https://pub.dev/packages/http package to download a file from my own webserver.

Below is the download function:

  download(String url, {String filename}) async {
    var client = http.Client();
    var request = new http.Request('GET', Uri.parse(url));
    var response = client.send(request);
    String dir = (await getApplicationDocumentsDirectory()).path;

    List<List<int>> chunks = new List();
    int downloaded = 0;

    response.asStream().listen((http.StreamedResponse r) {
      r.stream.listen((List<int> chunk) {
        // Display percentage of completion
        debugPrint('downloadPercentage: ${downloaded / r.contentLength * 100}');

        chunks.add(chunk);
        downloaded += chunk.length;
      }, onDone: () async {
        // Display percentage of completion
        debugPrint('downloadPercentage: ${downloaded / r.contentLength * 100}');

        // Save the file
        File file = new File('$dir/$filename');
        final Uint8List bytes = Uint8List(r.contentLength);
        int offset = 0;
        for (List<int> chunk in chunks) {
          bytes.setRange(offset, offset + chunk.length, chunk);
          offset += chunk.length;
        }
        await file.writeAsBytes(bytes);
        return;
      });
    });
  }

But StreamedResponse r is always null when I download the file from my webserver. I can download files from other web servers and it is not null.

For testing purpose, I used the link https://www.rarlab.com/rar/wrar590.exe

Therefore, I think the problem might be because of the settings on my webserver.

From WinRAR server

I/flutter (18386): IOStreamedResponse
I/flutter (18386): ResponseCode: 200
I/flutter (18386): {last-modified: Thu, 26 Mar 2020 10:03:25 GMT, date: Mon, 04 May 2020 11:47:34 GMT, accept-ranges: bytes, strict-transport-security: max-age=31536000;, content-length: 3007728, etag: "2de4f0-5a1bf18799540", content-type: application/octet-stream, server: Apache}

From my webserver:

I/flutter (29858): IOStreamedResponse
I/flutter (29858): ResponseCode: 200
I/flutter (29858): {connection: keep-alive, last-modified: Thu, 16 Apr 2020 20:22:20 GMT, set-cookie: __cfduid=d2789e7dce3f93d32c76e1d7874ffce1b1588599373; expires=Wed, 03-Jun-20 13:36:13 GMT; path=/; domain=.devoup.com; HttpOnly; SameSite=Lax, cf-request-id: 02817fd5a30000ddc752a1d200000001, transfer-encoding: chunked, date: Mon, 04 May 2020 13:36:13 GMT, access-control-allow-origin: *, vary: Accept-Encoding,User-Agent, content-encoding: gzip, cf-cache-status: DYNAMIC, content-type: application/zip, server: cloudflare, accept-ranges: bytes, cf-ray: 58e29c029952ddc7-SIN}

2

Answers


  1. Chosen as BEST ANSWER

    Added SetEnv no-gzip 1 to .htaccess file in webserver and it returns content-length


  2. Sometimes the server doesn’t return contentLength . If that’s the case, then contentLength will be null.

    If you have control of the server, like in your case, you can set the x-decompressed-content-length header with the file size before you send it. On the client side, you can retrieve contentLength like this:

    final contentLength = double.parse(response.headers['x-decompressed-content-length']);
    

    If you don’t have control of the server, you can just show the number of bytes that are being downloaded, or if you know the file size in advance, you can use it to help calculate the % number of bytes downloaded.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search