public async Task CancelUploadSession(OneDriveUploadSession session) { // If the session is already cancelled, nothing to do if (session.State == OneDriveFileUploadState.Cancelled) { return; } CounterManager.LogSyncJobCounter( Constants.CounterNames.ApiCall, 1, new CounterDimension( Constants.DimensionNames.OperationName, "CancelUploadSession")); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, session.UploadUrl); HttpResponseMessage response = await this.SendOneDriveRequest(request).ConfigureAwait(false); if (response.StatusCode == HttpStatusCode.NoContent) { session.State = OneDriveFileUploadState.Cancelled; return; } Logger.Warning( "Failed to cancel upload session for file {0} (ParenId={1})", session.ItemName, session.ParentId); LogRequest(request, this.oneDriveHttpClient.BaseAddress, true); LogResponse(response, true); throw new OneDriveHttpException("Failed to cancel the upload session.", response.StatusCode); }
// See https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createuploadsession public async Task <OneDriveUploadSession> CreateUploadSession(string parentItemId, string name, long length) { if (string.IsNullOrWhiteSpace(parentItemId)) { throw new ArgumentNullException(nameof(parentItemId)); } if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException(nameof(name)); } // TODO: Check for the maximum file size limit if (length <= 0) { throw new ArgumentOutOfRangeException(nameof(length)); } if (this.uploadSessions.Any(s => s.ParentId == parentItemId && s.ItemName == name)) { throw new InvalidOperationException("An upload session for this item already exists."); } HttpRequestMessage request = new HttpRequestMessage( HttpMethod.Post, string.Format("/v1.0/drive/items/{0}:/{1}:/upload.createSession", parentItemId, HttpUtility.UrlEncode(name))); CounterManager.LogSyncJobCounter( Constants.CounterNames.ApiCall, 1, new CounterDimension( Constants.DimensionNames.OperationName, "CreateUploadSession")); HttpResponseMessage response = await this.SendOneDriveRequest(request).ConfigureAwait(false); JObject responseObject = await response.Content.ReadAsJObjectAsync().ConfigureAwait(false); var newSession = new OneDriveUploadSession( parentItemId, name, responseObject["uploadUrl"].Value <string>(), responseObject["expirationDateTime"].Value <DateTime>(), length); Logger.Info( "Created OneDrive upload session with parentItemId={0}, name={1}, expirationDateTime={2}", parentItemId, name, newSession.ExpirationDateTime); this.uploadSessions.Add(newSession); return(newSession); }
public override Stream GetWriteStreamForEntry(SyncEntry entry, long length) { // Get the adapter entry for the parent entry var parentAdapterEntry = entry.ParentEntry.AdapterEntries.First(e => e.AdapterId == this.Configuration.Id); // Create the upload sessiond OneDriveUploadSession session = this.oneDriveClient.CreateUploadSession(parentAdapterEntry.AdapterEntryId, entry.Name, length).Result; return(new OneDriveFileUploadStream(this.oneDriveClient, session)); }
public async Task SendUploadFragment(OneDriveUploadSession uploadSession, byte[] fragmentBuffer, long offset) { switch (uploadSession.State) { case OneDriveFileUploadState.NotStarted: uploadSession.State = OneDriveFileUploadState.InProgress; break; case OneDriveFileUploadState.Completed: throw new OneDriveException("Cannot upload fragment to completed upload session."); case OneDriveFileUploadState.Faulted: throw new OneDriveException("Cannot upload fragment to faulted upload session."); case OneDriveFileUploadState.Cancelled: throw new OneDriveException("Cannot upload fragment to cancelled upload session."); } HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Put, uploadSession.UploadUrl) { Content = new ByteArrayContent(fragmentBuffer) }; request.Content.Headers.ContentLength = fragmentBuffer.LongLength; request.Content.Headers.ContentRange = new ContentRangeHeaderValue( offset, offset + fragmentBuffer.Length - 1, uploadSession.Length); CounterManager.LogSyncJobCounter( Constants.CounterNames.ApiCall, 1, new CounterDimension( Constants.DimensionNames.OperationName, "SendUploadFragment")); var response = await this.SendOneDriveRequest(request).ConfigureAwait(false); if (!response.IsSuccessStatusCode) { uploadSession.State = OneDriveFileUploadState.Faulted; } if (response.StatusCode == HttpStatusCode.Created || response.StatusCode == HttpStatusCode.OK) { // 201 indicates that the upload is complete. uploadSession.State = OneDriveFileUploadState.Completed; uploadSession.Item = await response.Content.ReadAsJsonAsync <Item>().ConfigureAwait(false); this.uploadSessions.Remove(uploadSession); } }
public OneDriveFileUploadStream(OneDriveClient client, OneDriveUploadSession uploadSession, int fragmentSize) { Pre.ThrowIfArgumentNull(client, nameof(client)); Pre.ThrowIfArgumentNull(uploadSession, nameof(uploadSession)); if (fragmentSize < fragmentSizeBase) { throw new ArgumentOutOfRangeException("The fragement size must be at least " + fragmentSizeBase); } if (fragmentSize % fragmentSizeBase != 0) { throw new ArgumentException("The segement size must be a multiple of " + fragmentSizeBase, nameof(fragmentSize)); } this.client = client; this.UploadSession = uploadSession; this.fragmentSize = fragmentSize; this.bytesRemaining = uploadSession.Length; }
public OneDriveFileUploadStream(OneDriveClient client, OneDriveUploadSession uploadSession) : this(client, uploadSession, DefaultFragmentSize) { }