// ------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. // ------------------------------------------------------------------------------ namespace Microsoft.Graph { using System.IO; using System.Net.Http; using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; /// /// The UploadSliceRequest class to help with uploading file slices /// /// The type to be uploaded internal class UploadSliceRequest : BaseRequest { private UploadResponseHandler responseHandler; /// /// The beginning of the slice range to send. /// public long RangeBegin { get; private set; } /// /// The end of the slice range to send. /// public long RangeEnd { get; private set; } /// /// The length in bytes of the session. /// public long TotalSessionLength { get; private set; } /// /// The range length of the slice to send. /// public int RangeLength => (int)(this.RangeEnd - this.RangeBegin + 1); /// /// Request for uploading one slice of a session /// /// URL to upload the slice. /// Client used for sending the slice. /// Beginning of range of this slice /// End of range of this slice /// Total session length. This MUST be consistent /// across all slice. public UploadSliceRequest( string sessionUrl, IBaseClient client, long rangeBegin, long rangeEnd, long totalSessionLength) : base(sessionUrl, client, null) { this.RangeBegin = rangeBegin; this.RangeEnd = rangeEnd; this.TotalSessionLength = totalSessionLength; this.responseHandler = new UploadResponseHandler(); } /// /// Uploads the slice using PUT. /// /// Stream of data to be sent in the request. /// The status of the upload. public Task> PutAsync(Stream stream) { return this.PutAsync(stream, CancellationToken.None); } /// /// Uploads the slice using PUT. /// /// Stream of data to be sent in the request. Length must be equal to the length /// of this slice (as defined by this.RangeLength) /// The cancellation token /// The status of the upload. If UploadSession.AdditionalData.ContainsKey("successResponse") /// is true, then the item has completed, and the value is the created item from the server. public virtual async Task> PutAsync(Stream stream, CancellationToken cancellationToken) { this.Method = "PUT"; this.ContentType = "application/octet-stream"; using (var response = await this.SendRequestAsync(stream, cancellationToken).ConfigureAwait(false)) { return await this.responseHandler.HandleResponse(response); } } /// /// Send the Sliced Upload request /// /// Stream of data to be sent in the request. /// The cancellation token /// The completion option for the request. Defaults to ResponseContentRead. /// private async Task SendRequestAsync( Stream stream, CancellationToken cancellationToken, HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead) { // Append the relevant headers for the range upload request using (var request = this.GetHttpRequestMessage()) { request.Content = new StreamContent(stream); request.Content.Headers.ContentRange = new ContentRangeHeaderValue(this.RangeBegin, this.RangeEnd, this.TotalSessionLength); request.Content.Headers.ContentLength = this.RangeLength; return await this.Client.HttpProvider.SendAsync(request, completionOption, cancellationToken).ConfigureAwait(false); } } } }