upload method

dynamic upload({
  1. dynamic onProgress(
    1. double
    )?,
  2. dynamic onComplete()?,
})

Start or resume an upload in chunks of maxChunkSize throwing ProtocolException on server error

Implementation

upload({
  Function(double)? onProgress,
  Function()? onComplete,
}) async {
  if (!await resume()) {
    await create();
  }

  // get offset from server
  _offset = await _getOffset();

  int totalBytes = _fileSize as int;

  // start upload
  final client = getHttpClient();

  while (!_pauseUpload && (_offset ?? 0) < totalBytes) {
    final uploadHeaders = Map<String, String>.from(headers ?? {})
      ..addAll({
        "Tus-Resumable": tusVersion,
        "Upload-Offset": "$_offset",
        "Content-Type": "application/offset+octet-stream"
      });
    _chunkPatchFuture = client.patch(
      _uploadUrl as Uri,
      headers: uploadHeaders,
      body: await _getData(),
    );
    final response = await _chunkPatchFuture;
    _chunkPatchFuture = null;

    // check if correctly uploaded
    if (!(response.statusCode >= 200 && response.statusCode < 300)) {
      throw ProtocolException(
          "unexpected status code (${response.statusCode}) while uploading chunk");
    }

    int? serverOffset = _parseOffset(response.headers["upload-offset"]);
    if (serverOffset == null) {
      throw ProtocolException(
          "response to PATCH request contains no or invalid Upload-Offset header");
    }
    if (_offset != serverOffset) {
      throw ProtocolException(
          "response contains different Upload-Offset value ($serverOffset) than expected ($_offset)");
    }

    // update progress
    if (onProgress != null) {
      onProgress((_offset ?? 0) / totalBytes * 100);
    }

    if (_offset == totalBytes) {
      this.onComplete();
      if (onComplete != null) {
        onComplete();
      }
    }
  }
}