public UploadFileChunksTask(UploadInfo file, IUploadProgressReporter progressReporter, CancellationToken token, IApiHelper apiHelper)
			: base(apiHelper)
		{
			_file = file;
			_filePath = file.FilePath;
			_fileSize = file.FileSize;
			_progressReporter = progressReporter;
			_token = token;
			_deckCloudFileResponse = file.DeckCloudFileResponse;
		}
		public UploadFileChunksTask(string filePath, long fileSize, DeckCloudFileResponse response, CancellationToken token, IApiHelper apiHelper)
			: base(apiHelper)
		{
			_file = null;
			_filePath = filePath;
			_fileSize = fileSize;
			_progressReporter = null;
			_token = token;
			_deckCloudFileResponse = response;
		}
Exemple #3
0
		public void Restart()
		{
			Stage = AttachmentStage.Pending;
			CurrentChunk = 0;
			UploadedBytes = 0;
			DeckCloudFileResponse = null;
			DeckVersionResponse = null;
			Status = AttachmentStatus.Pending;
			DownloadLink = null;
		}
Exemple #4
0
		public void FinishChunking(DeckCloudFileResponse initiateChunkingResponse)
		{
			if (string.IsNullOrEmpty(_deviceToken))
			{
				throw new Exception("Device token is blank.");
			}

			// Finishing file chunk uploading.
			Logger.LogDebug("Finishing file chunk uploading.");

			string uri = string.Format("{0}/cloud_files/{1}.xml", m_hostServer, initiateChunkingResponse.FileDataId);

			var parameters = new List<NamedData>
             	{
             		new NamedData("complete_multipart", "true"),
             		new NamedData("multipart_upload_id", initiateChunkingResponse.UploadId)
             	};

			// Specify a schema to ensure the response is as expected.
			string xmlSchema = Resources.DeckCloudFileXmlSchema;
			DataSet dset = MultipartFormDataPut(uri, parameters, xmlSchema);
			var finishChunkingResponse = new DeckCloudFileResponse(dset, DeckCloudFileResponse.RequestType.FinishChunking);
			if (finishChunkingResponse.FileDataId != initiateChunkingResponse.FileDataId)
			{
				throw new InvalidResponseException("The finish chunking response \"file data ID\" does not match the initiate chunking response.");
			}
		}
Exemple #5
0
		public int UploadChunk(FileStream file, DeckCloudFileResponse deckResponse, long? position = null)
		{
			try
			{
				// Upload a file chunk.
				Logger.LogDebug("Upload a file chunk.");

				// Reposition file stream to chunk position if provided
				if (position.HasValue)
				{
					file.Position = position.Value;
				}

				// Read from the file into a buffer. It's either the full chunk size or the last chunk's remaining size.
				long remainingBytesLength = file.Length - file.Position;
				int chunkSize = (remainingBytesLength < FILE_UPLOAD_CHUNK_SIZE) ? (int) remainingBytesLength : FILE_UPLOAD_CHUNK_SIZE;
				Logger.LogInfo(string.Format("Read {0} bytes from the file into a buffer.", chunkSize));

				file.Read(m_buffer, 0, chunkSize);

				// Creating HTTP web request to Amazon Web Services (AWS).
				Logger.LogDebug("Creating HTTP web request.");
                var request = CreateWebRequest(deckResponse.DeckCloudUploadInfo.Action);
				request.Method = WebRequestMethods.Http.Put;
				request.ContentType = deckResponse.DeckCloudUploadInfo.ContentType;
				request.AllowAutoRedirect = false;
				request.AllowWriteStreamBuffering = true;
				request.ContentLength = chunkSize;

				// Add headers specific to AWS.
				request.Headers.Add("authorization", deckResponse.DeckCloudUploadInfo.Authorization);
				request.Headers.Add("x-amz-date", deckResponse.DeckCloudUploadInfo.XAmzDate);

				// Get request stream.
				Logger.LogDebug("Getting request stream.");
				using (Stream requestStream = request.GetRequestStream())
				{
					// Writing to request stream.
					Logger.LogDebug("Writing to request stream.");
					requestStream.Write(m_buffer, 0, chunkSize);
				}

				// The schema here is null because the AWS web service call just responds
				// with an OK when successful and there is no XML data returned.
				CompleteMultipartFormData(false, null, request);

				return chunkSize;
			}
			finally
			{
				Array.Clear(m_buffer, 0, m_buffer.Length);
			}

		}
Exemple #6
0
		public DeckCloudFileResponse RequestChunkParameters(DeckCloudFileResponse initiateChunkingResponse, long partNumber)
		{
			// Request file chunk parameters.
			Logger.LogDebug("Request file chunk parameters.");

			string uri = string.Format("{0}/cloud_files/{1}.xml", m_hostServer, initiateChunkingResponse.FileDataId);

			var parameters = new List<NamedData>
             	{
             		new NamedData("multipart_upload_id", initiateChunkingResponse.UploadId),
             		new NamedData("part_number", partNumber)
             	};

			// Specify a schema to ensure the response is as expected.
			string xmlSchema = Resources.DeckCloudFileXmlSchema;
			DataSet dset = MultipartFormDataGet(uri, parameters, true, false, xmlSchema);
			return new DeckCloudFileResponse(dset, DeckCloudFileResponse.RequestType.RequestChunk);
		}
Exemple #7
0
		public void UploadFileChunks(Action<long, double> callbackIncrementProgress, string filePath, DeckCloudFileResponse initiateChunkingResponse)
		{
			if (string.IsNullOrEmpty(_deviceToken))
			{
				throw new Exception("Device token is blank.");
			}

			Logger.LogDebug(string.Format("Opening file \"{0}\" to be uploaded in chunks.", filePath));

			// Open the file as a stream.
			using (FileStream file = File.OpenRead(filePath))
			{
				// Determine how many chunks will need to be sent.
				long totalChunks = file.Length / FILE_UPLOAD_CHUNK_SIZE;
				if (file.Length % FILE_UPLOAD_CHUNK_SIZE != 0)
				{
					// There was a remainder to the division, so add one to account for it.
					totalChunks++;
				}

				Logger.LogDebug(string.Format("Uploading file in {0} chunks (max chunk length: {1}MB).", totalChunks, FILE_UPLOAD_CHUNK_SIZE / 1024 / 1024));

				for (int partNumber = 1; partNumber <= totalChunks; partNumber++)
				{
					DeckCloudFileResponse requestChunkResponse = RequestChunkParameters(initiateChunkingResponse, partNumber);
					DateTime start = DateTime.Now;
					int bytesUploaded = UploadChunk(file, requestChunkResponse);
					TimeSpan duration = DateTime.Now - start;
					var byteRate = (double) bytesUploaded / duration.TotalSeconds;
					if (callbackIncrementProgress != null)
					{
						Logger.LogDebug("Calling delegate to increment progress.");
						// The bytesUploaded will always be 5MB or less, thus
						// an int will suffice. The int is cast to a long here.
						callbackIncrementProgress(bytesUploaded, byteRate);
					}
				}
			}
		}