/// <summary> /// Initiates a file upload asynchronously /// </summary> /// <param name="initiateFileUploadInfo">The information needed to build an initiate file upload request</param> /// <returns>The response from the file upload initiation</returns> private async Task <InitiateFileUploadResponse> InitiateFileUploadAsync(InitiateFileUploadInfo initiateFileUploadInfo) { var requestBody = BuildInitiateFileUploadRequestBody(initiateFileUploadInfo); var json = await _proKnow.Requestor.PostAsync($"/workspaces/{initiateFileUploadInfo.WorkspaceId}/uploads/", null, requestBody); return(JsonSerializer.Deserialize <InitiateFileUploadResponse>(json)); }
/// <summary> /// Split a file into chunks /// </summary> /// <param name="initiateFileUploadInfo">The information used to initiate a file upload</param> /// <param name="initiateFileUploadResponse">The response to the request to initiate a file upload</param> /// <returns>Information to upload each chunk</returns> private IList <UploadChunkInfo> ChunkFile(InitiateFileUploadInfo initiateFileUploadInfo, InitiateFileUploadResponse initiateFileUploadResponse) { var chunks = new List <UploadChunkInfo>(); using (var inputFileStream = File.OpenRead(initiateFileUploadInfo.Path)) { for (int chunkIndex = 0; chunkIndex < initiateFileUploadInfo.NumberOfChunks; chunkIndex++) { string chunkPath; long chunkSize; if (initiateFileUploadInfo.NumberOfChunks > 1) { chunkPath = Path.GetTempFileName(); // When chunking, chunk size can NOT be smaller than UPLOAD_CHUNK_SIZE_IN_BYTES, i.e., the last chunk will // be between UPLOAD_CHUNK_SIZE_IN_BYTES and 2 * UPLOAD_CHUNK_SIZE_IN_BYTES chunkSize = chunkIndex < initiateFileUploadInfo.NumberOfChunks - 1 ? UPLOAD_CHUNK_SIZE_IN_BYTES : initiateFileUploadInfo.FileSize - chunkIndex * UPLOAD_CHUNK_SIZE_IN_BYTES; using (var outputFileStream = File.OpenWrite(chunkPath)) { var totalNumberOfBytesCopied = CopyStream(inputFileStream, outputFileStream, chunkSize); if (totalNumberOfBytesCopied != chunkSize) { var message = $"Error creating chunk {chunkIndex + 1} of {initiateFileUploadInfo.NumberOfChunks} for file {initiateFileUploadInfo.Path}. Only {totalNumberOfBytesCopied} of {chunkSize} bytes were copied."; _logger.LogError(message); throw new ProKnowException(message); } } } else { chunkPath = initiateFileUploadInfo.Path; chunkSize = initiateFileUploadInfo.FileSize; } var chunk = new UploadChunkInfo { InitiateFileUploadInfo = initiateFileUploadInfo, InitiateFileUploadResponse = initiateFileUploadResponse, ChunkIndex = chunkIndex, ChunkPath = chunkPath, ChunkSize = chunkSize }; chunks.Add(chunk); } } return(chunks); }
/// <summary> /// Builds the body for an initiate file upload request /// </summary> /// <param name="initiateFileUploadInfo">The information to initiate the file upload</param> /// <returns>The content for the body</returns> private HttpContent BuildInitiateFileUploadRequestBody(InitiateFileUploadInfo initiateFileUploadInfo) { var uploadFileRequest = new InitiateFileUploadRequestBody { Checksum = initiateFileUploadInfo.Checksum, Path = initiateFileUploadInfo.Path, Filesize = initiateFileUploadInfo.FileSize, IsMultipart = initiateFileUploadInfo.NumberOfChunks > 1, Overrides = initiateFileUploadInfo.Overrides }; var json = JsonSerializer.Serialize(uploadFileRequest, _jsonSerializerOptions); return(new StringContent(json, Encoding.UTF8, "application/json")); }