private void ProcessChunk(Uri uploadUrl, byte[] buffer, long uploadedByteCount, int bytesRead, int sendTry = 1) { ApiUploadChunkResult chunkResult = UploadChunkWebClient(uploadUrl, buffer, uploadedByteCount, bytesRead); if (!FileHash.CompareFileHashes(chunkResult.Hash, buffer, bytesRead)) { if (sendTry <= 3) { ProcessChunk(uploadUrl, buffer, uploadedByteCount, bytesRead, sendTry + 1); } else { throw new DracoonNetIOException("The uploaded chunk hash and local chunk hash are not equal!"); } } }
private string ProcessEncryptedChunk(Uri uploadUrl, EncryptedDataContainer encryptedContainer, long uploadedByteCount, FileEncryptionCipher cipher, bool isFinalBlock, int sendTry = 1) { ApiUploadChunkResult chunkResult = UploadChunkWebClient(uploadUrl, encryptedContainer.Content, uploadedByteCount, encryptedContainer.Content.Length); if (!FileHash.CompareFileHashes(chunkResult.Hash, encryptedContainer.Content, encryptedContainer.Content.Length)) { if (sendTry <= 3) { return(ProcessEncryptedChunk(uploadUrl, encryptedContainer, uploadedByteCount, cipher, isFinalBlock, sendTry + 1)); } else { throw new DracoonNetIOException("The uploaded chunk hash and local chunk hash are not equal!"); } } return(isFinalBlock ? Convert.ToBase64String(encryptedContainer.Tag) : null); }
protected ApiUploadChunkResult UploadChunkWebClient(Uri uploadUrl, byte[] buffer, long uploadedByteCount, int bytesRead) { #region Build multipart string formDataBoundary = "---------------------------" + Guid.NewGuid(); byte[] packageHeader = ApiConfig.ENCODING.GetBytes( $"--{formDataBoundary}\r\nContent-Disposition: form-data; name=\"{"file"}\"; filename=\"{FileUploadRequest.Name}\"\r\n\r\n"); byte[] packageFooter = ApiConfig.ENCODING.GetBytes(string.Format("\r\n--" + formDataBoundary + "--")); byte[] multipartFormatedChunkData = new byte[packageHeader.Length + packageFooter.Length + bytesRead]; Buffer.BlockCopy(packageHeader, 0, multipartFormatedChunkData, 0, packageHeader.Length); Buffer.BlockCopy(buffer, 0, multipartFormatedChunkData, packageHeader.Length, bytesRead); Buffer.BlockCopy(packageFooter, 0, multipartFormatedChunkData, packageHeader.Length + bytesRead, packageFooter.Length); #endregion long headerLength = packageFooter.LongLength + packageHeader.LongLength; using (WebClient requestClient = Client.Builder.ProvideChunkUploadWebClient(bytesRead, uploadedByteCount, formDataBoundary, OptionalFileSize == -1 ? "*" : OptionalFileSize.ToString())) { long currentUploadedByteCount = uploadedByteCount; requestClient.UploadProgressChanged += (sender, e) => { lock (ProgressReportTimer) { long increaseWithoutHeader = e.BytesSent - headerLength; if (ProgressReportTimer.ElapsedMilliseconds > PROGRESS_UPDATE_INTERVAL && increaseWithoutHeader > 0) { LastNotifiedProgressValue = currentUploadedByteCount + increaseWithoutHeader; NotifyProgress(ActionId, LastNotifiedProgressValue, OptionalFileSize); ProgressReportTimer.Restart(); } } }; ProgressReportTimer = Stopwatch.StartNew(); byte[] chunkUploadResultBytes = Client.Executor.ExecuteWebClientChunkUpload(requestClient, uploadUrl, multipartFormatedChunkData, RequestType.PostUploadChunk, RunningThread); ApiUploadChunkResult chunkUploadResult = JsonConvert.DeserializeObject <ApiUploadChunkResult>(ApiConfig.ENCODING.GetString(chunkUploadResultBytes)); return(chunkUploadResult); } }