Загрузка медиафайлов через VMware API приводит к увеличению размера передаваемого файла по сравнению с размером файла

Мы используем V Cloud API для взаимодействия с виртуальными машинами (создание машин, выполнение действий, переключение носителей и т. Д.). Одна из запрашиваемых функций - возможность загружать мультимедиа (особенно ISO) в определенный каталог. Руководство по API (стр. 67) довольно простое, и наши многокомпонентные запросы к URL-адресу, который предоставляется при запуске загрузки, проходят без проблем.

Примечание: мы должны объявить размер файла перед началом загрузки

Единственной вещью, которая кажется неправильной во время самой загрузки, является то, что "переданный размер" оказывается больше, чем "размер файла" в конце процесса. Это несколько странно, потому что наш диапазон содержимого никогда не превышает ожидаемый размер файла (мы предполагаем, что метаданные включаются без нашего права голоса). Как только этот переданный размер превышает размер файла, состояние загрузки файла изменяется на "Ошибка", но все равно возвращает 200 OK

    {
  "name": "J Small 4",
  "description": "",
  "files": [{
    "name": "file",
    "totalSize": 50696192,
    "status": "Error",
    "link": "https://cloud01.cs2cloud.com/transfer/27b8f93c-8319-419e-9e8c-15622097670b/file",
    "transferredSize": 54293177
  }],
  "id": "urn:vcloud:media:1cec68ef-f22e-4ec7-ae5d-dfbc4f7137d9",
  "catalogId": "urn:vcloud:catalogitem:19dbfdd8-ea70-4355-abc7-96e34dccb869"
}

Не уверен, с чего начать отладку, поскольку все вызовы API возвращаются с 200 OK файл.ISO выглядит нормально, наши заголовки диапазона содержимого никогда не выходят за пределы установленного размера файла, а метаданные, по-видимому, находятся вне нашего контроля с точки зрения их редактирования или измерения.

Надеясь, что какая-то душа уже сталкивалась с этой проблемой раньше и может дать некоторое представление о работе над решением

1 ответ

Решение

Оказывается, проблема была вовсе не в vmware, а в том, как мы разбивали медиафайл. Изначально мы использовали FileReader(), чтобы упаковать файл и отправить его в API VMware.

Теоретически, мы выбирали размер фрагмента, а затем могли генерировать и устанавливать диапазон содержимого, но в действительности мы выбирали диапазон содержимого, но длина содержимого отличалась от размера фрагмента. Мы до сих пор не совсем уверены, почему это произошло (возможно, добавляются дополнительные метаданные), но мы нашли решение.

Исправление: мы полностью удалили FileReader() и просто поместили кусочки файлов прямо в большой двоичный объект (вы можете увидеть ниже)

$scope.parseMediaFile = function(url, file, catalogId) {
         $scope.uploadingMediaFile = true;

         var fileSize = file.size;
         var chunkSize = 1024 * 1024 * 5; // bytes
         var offset = 0;
         var self = this; // we need a reference to the current object
         var chunkReaderBlock = null;
         var chunkNum = 0;

         if (fileSize < chunkSize) {
            chunkSize = fileSize;
         }

         chunkReaderBlock = function(_offset, length, _file) {
            var blob = _file.slice(_offset, length + _offset);
            var beginRange = _offset;
            var endRange = _offset + length;

            if(endRange > _file.size) {
              endRange = _file.size
            }

            var contentRange = beginRange + "-" + endRange;

            vdcServices.uploadMediaFile(url, blob, fileSize, contentRange).then(
              function(resp) {
                vdcServices.getUploadStatus($scope.company, catalogId).then(function(resp) {
                  var uploaded = resp.data.files[0].transferredSize;
                  $scope.mediaPercentLoaded = $scope.trunc((uploaded / fileSize) * 100);

                  if (endRange == _file.size) {
                    $scope.closeModal();
                    return;
                  }

                  chunkReaderBlock(_offset+length, chunkSize, file);
                }, function(err) {
                  $scope.errorMsg = err;
                  chunkReaderBlock(_offset-length, chunkSize, file);
                })
              },
              function(err) {
                $scope.errorMsg = err;
              }
            )
         }

         // Starts the read with the first block
         if (offset < fileSize) {
            chunkReaderBlock(offset, chunkSize, file)
         }

      }

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

Другие вопросы по тегам