// ------------------------------------------------------------------------------
// 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);
}
}
}
}