http.StreamedResponse contentLength возвращает значение NULL - PullRequest
0 голосов
/ 04 мая 2020

Я использую пакет flutter http https://pub.dev/packages/http для загрузки файла с моего собственного веб-сервера.

Ниже приведена функция загрузки:

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

Но StreamedResponse r всегда null, когда я загружаю файл с моего веб-сервера. Я могу загружать файлы с других веб-серверов, и это не null.

Для целей тестирования я использовал ссылку https://www.rarlab.com/rar/wrar590.exe

Поэтому, я думаю, проблема может быть из-за настроек на моем веб-сервере.

с сервера WinRAR

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}

с моего веб-сервера:

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}

1 Ответ

0 голосов
/ 11 мая 2020

Иногда сервер не возвращает contentLength. Если это так, то contentLength будет нулевым.

Если у вас есть контроль над сервером, как в вашем случае, вы можете установить заголовок x-decompressed-content-length с размером файла перед отправкой. На стороне клиента вы можете извлечь contentLength следующим образом:

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

Если у вас нет контроля над сервером, вы можете просто показать количество загружаемых байтов или, если вы знаете размер файла заранее, вы можете использовать его для расчета% загруженного байта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...