예제 #1
0
        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);
        }
예제 #2
0
        // 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);
        }
예제 #3
0
        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));
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
        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;
        }
예제 #6
0
 public OneDriveFileUploadStream(OneDriveClient client, OneDriveUploadSession uploadSession)
     : this(client, uploadSession, DefaultFragmentSize)
 {
 }