Exemplo n.º 1
0
            public async Task PauseAsync()
            {
                switch (Status)
                {
                case DownloadStatus.Downloading:
                {
                    pauseRequest = true;
                    MessageAppended?.Invoke("Pausing...");
                    while (Status == DownloadStatus.Downloading)
                    {
                        await Task.Delay(100);
                    }
                    MessageAppended?.Invoke("Paused");
                    pauseRequest = false;
                    return;
                }

                case DownloadStatus.Completed:
                case DownloadStatus.ErrorNeedRestart:
                case DownloadStatus.ErrorNeedResume:
                case DownloadStatus.NotStarted:
                case DownloadStatus.Paused:
                default:
                {
                    throw new Exception($"Status: {Status}");
                }
                }
            }
 public async Task Start()
 {
     int timeToWait = 500;
     while(true)
     {
         await StartPrivate();
         switch (Status)
         {
             case FileCreatorStatus.ErrorNeedRestart:
                 {
                     if (timeToWait >Constants.MaxTimeToWait) return;
                     MessageAppended?.Invoke($"Waiting for {timeToWait} and try again...");
                     timeToWait *= 2;
                 }break;
             case FileCreatorStatus.Completed:
                 {
                     return;
                 }
             default:
                 {
                     throw new Exception($"Status: {Status}");
                 }
         }
     }
 }
 private async Task StartPrivate()
 {
     Status = FileCreatorStatus.Creating;
     MessageAppended?.Invoke("Creating Folder...");
     string json = $"{{\"name\":\"{name}\",\"parents\":[\"{cloudId}\"]";
     if(isFolder)
     {
         json += ",\"mimeType\": \"application/vnd.google-apps.folder\"";
     }
     json += "}";
     MessageAppended?.Invoke(json);
     HttpWebRequest request = WebRequest.CreateHttp("https://www.googleapis.com/drive/v3/files");
     var bytes = Encoding.UTF8.GetBytes(json);
     request.Headers["Content-Type"] = "application /json; charset=UTF-8";
     request.Headers["Content-Length"] = bytes.Length.ToString();
     request.Headers["Authorization"] = "Bearer " + (await Drive.GetAccessTokenAsync());
     request.Method = "POST";
     using (System.IO.Stream requestStream = await request.GetRequestStreamAsync())
     {
         await requestStream.WriteAsync(bytes, 0, bytes.Length);
     }
     using (var response = await GetHttpResponseAsync(request))
     {
         if (response == null)
         {
             MessageAppended?.Invoke("Null response");
             Status = FileCreatorStatus.ErrorNeedRestart;
             return;
         }
         MessageAppended?.Invoke($"Http response: {response.StatusCode} ({(int)response.StatusCode})");
         if (response.StatusCode == HttpStatusCode.OK)
         {
             using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
             {
                 var jsonObj = JsonConvert.DeserializeObject<Dictionary<string, string>>(await reader.ReadToEndAsync());
                 if (!jsonObj.ContainsKey("id"))
                 {
                     MessageAppended?.Invoke("response.Headers doesn't contain a key for \"id\"!");
                     MessageAppended?.Invoke(await LogHttpWebResponse(response, true));
                     Status = FileCreatorStatus.ErrorNeedRestart;
                     return;
                 }
                 Result= jsonObj["id"];
                 MessageAppended?.Invoke($"Folder {name} ({Result}) created!");
                 Status = FileCreatorStatus.Completed;
                 return;
             }
         }
         else
         {
             MessageAppended?.Invoke("Http response isn't OK!");
             MessageAppended?.Invoke(await LogHttpWebResponse(response, true));
             Status = FileCreatorStatus.ErrorNeedRestart;
             return;
         }
     }
 }
Exemplo n.º 4
0
        private void AddMessage(ScriptMessageType type, string message)
        {
            var msg_info = new ScriptMessageData(DateTime.UtcNow, type, message);

            lock (message_list_sync_) {
                message_list_.Add(msg_info);
            }

            MessageAppended?.Invoke(this, msg_info);
        }
Exemplo n.º 5
0
            private async Task StartDownloadAsync()
            {
                Status = DownloadStatus.Downloading;
                MyLogger.Assert(fileStream != null && resumableUri != null);
                try
                {
                    if (!await CreateResumableDownloadAsync())
                    {
                        Status = DownloadStatus.ErrorNeedRestart; MessageAppended?.Invoke("Error create resumable download async"); return;
                    }
                    var fileSize = bytesReceivedSoFar + serverStreamLength;
                    MyLogger.Log($"File size = {fileSize}");
                    fileStream.Position = bytesReceivedSoFar;
                    int chunkSize = MinChunkSize;
                    for (; bytesReceivedSoFar != fileSize;)
                    {
                        DateTime startTime  = DateTime.Now;
                        var      bufferSize = (int)Math.Min(chunkSize, fileSize - bytesReceivedSoFar);
                        if (pauseRequest)
                        {
                            Status = DownloadStatus.Paused;
                            return;
                        }
                        var bytesRead = await DoResumableDownloadAsync(bufferSize);

                        if (Status == DownloadStatus.ErrorNeedResume)
                        {
                            MessageAppended?.Invoke($"Failed! Chunk range: {bytesReceivedSoFar}-{bytesReceivedSoFar + bufferSize - 1}");
                            return;
                        }
                        MyLogger.Assert(Status == DownloadStatus.Downloading && bytesRead != -1);
                        bytesReceivedSoFar += bytesRead;
                        if ((DateTime.Now - startTime).TotalSeconds < 0.2)
                        {
                            chunkSize = (int)Math.Min((long)chunkSize + chunkSize / 2, int.MaxValue);
                        }
                        else
                        {
                            chunkSize = Math.Max(MinChunkSize, chunkSize / 2);
                        }
                        OnProgressChanged(bytesReceivedSoFar, fileSize);
                    }
                    OnProgressChanged(fileSize, fileSize);
                    Status = DownloadStatus.Completed;
                }
                catch (Exception error)
                {
                    Status = DownloadStatus.ErrorNeedResume;
                    MessageAppended?.Invoke(error.ToString());
                }
            }
Exemplo n.º 6
0
            public async Task <string> GetNextPageWithFieldsAsync(string fields, int pageSize = 100)
            {
                Status = Networker.NetworkStatus.Networking;
                if (searchListGetter == null)
                {
                    searchListGetter = new RestRequests.SearchListGetter(searchPattern);
                    searchListGetter.MessageAppended += (msg) => { MessageAppended?.Invoke($"[Rest]{msg}"); };
                    pageNumber = 0;
                }
                MessageAppended?.Invoke($"Getting page #{++pageNumber}");
                if (searchListGetter.Status == RestRequests.SearchListGetter.SearchStatus.Completed)
                {
                    Status = Networker.NetworkStatus.Completed;
                    return(null);
                }
                searchListGetter.PageSize = pageSize;
                int timeToWait = 500;

                index_tryAgain :;
                await searchListGetter.GetNextPageAsync(fields);

                if (searchListGetter.Status == RestRequests.SearchListGetter.SearchStatus.Paused)
                {
                    Status = Networker.NetworkStatus.Paused;
                    return(searchListGetter.NextPageString);
                }
                else if (searchListGetter.Status == RestRequests.SearchListGetter.SearchStatus.Completed)
                {
                    Status = Networker.NetworkStatus.Completed;
                    return(searchListGetter.NextPageString);
                }
                else
                {
                    MessageAppended?.Invoke($"searchListGetter.Status: {searchListGetter.Status}");
                    if (searchListGetter.Status == RestRequests.SearchListGetter.SearchStatus.ErrorNeedResume)
                    {
                        if (timeToWait > Constants.MaxTimeToWait)
                        {
                            Status = Networker.NetworkStatus.ErrorNeedRestart;
                            return(null);
                        }
                        MessageAppended?.Invoke($"Waiting for {timeToWait} milisecs and try again...");
                        await Task.Delay(timeToWait);

                        timeToWait *= 2;
                        goto index_tryAgain;
                    }
                    Status = Networker.NetworkStatus.ErrorNeedRestart;
                    return(null);
                }
            }
Exemplo n.º 7
0
            public async Task PauseAsync()
            {
                switch (Status)
                {
                case UploadStatus.Uploading:
                case UploadStatus.Creating:
                case UploadStatus.Created:
                {
                    MessageAppended?.Invoke("Pausing...");
                    pauseRequest = true;
                    await semaphoreSlim.WaitAsync(10000);

                    //MyLogger.Assert(Status != UploadStatus.Uploading);
                    //while (Status == UploadStatus.Uploading) await Task.Delay(100);
                    pauseRequest = false;
                    if (Status == UploadStatus.Uploading)
                    {
                        var msg = $"Status: {Status}, failed to pause";
                        MyLogger.Log(msg);
                        MessageAppended?.Invoke(msg);
                    }
                    //MessageAppended?.Invoke($"Status after paused: {Status}");
                    //if () await MyLogger.Alert($"Status after paused: {Status}");
                    return;
                }

                case UploadStatus.Completed:
                case UploadStatus.ErrorNeedRestart:
                case UploadStatus.ErrorNeedResume:
                case UploadStatus.NotStarted:
                case UploadStatus.Paused:
                {
                    MyLogger.Log($"Status: {Status}, no action take to pause");
                    return;
                }

                default:
                {
                    throw new Exception($"Status: {Status}");
                }
                }
            }
Exemplo n.º 8
0
            private async Task <long> DoResumableDownloadAsync(int bufferSize)
            {
                try
                {
                    var buffer    = new byte[bufferSize];
                    var bytesRead = await serverStream.ReadAsync(buffer, 0, bufferSize);

                    await fileStream.WriteAsync(buffer, 0, bytesRead);

                    await fileStream.FlushAsync();

                    return(bytesRead);
                }
                catch (Exception error)
                {
                    MessageAppended?.Invoke(error.ToString());
                    Status = DownloadStatus.ErrorNeedResume;
                    return(-1);
                }
            }
Exemplo n.º 9
0
            public async Task StartAsync()
            {
                pauseRequest = false;
                while (true)
                {
                    if (pauseRequest)
                    {
                        MessageAppended?.Invoke("Paused.");
                        Status = Networker.NetworkStatus.Paused;
                        return;
                    }
                    var ans = await GetNextPageAsync();

                    if (ans == null)
                    {
                        break;
                    }
                    NewFileListGot?.Invoke(ans);
                }
                MessageAppended?.Invoke("Done.");
            }
            public async Task GetNextPageAsync(string fields = "nextPageToken,incompleteSearch,files(id,name,mimeType)")
            {
                string url = $"https://www.googleapis.com/drive/v3/files?corpora=user&fields={fields}";

                url += $"&pageSize={pageSize}";
                if (pageToken != null)
                {
                    url += $"&pageToken={pageToken}";
                }
                url += $"&q={System.Net.WebUtility.UrlEncode(searchPattern)}";
                HttpWebRequest request = WebRequest.CreateHttp(url);

                //MessageAppended?.Invoke($"url: {url}");
                request.Headers["Authorization"] = "Bearer " + (await Drive.GetAccessTokenAsync());
                request.Method = "GET";
                using (var response = await GetHttpResponseAsync(request))
                {
                    if (response == null)
                    {
                        MessageAppended?.Invoke("Null response");
                        Status = SearchStatus.ErrorNeedResume;
                        return;
                    }
                    MessageAppended?.Invoke($"Http response: {response.StatusCode} ({(int)response.StatusCode})");
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        string resultText;
                        using (var responseStream = response.GetResponseStream())
                        {
                            using (var reader = new System.IO.StreamReader(responseStream))
                            {
                                resultText = await reader.ReadToEndAsync();
                            }
                        }
                        NextPageString = resultText;
                        var result = JsonConvert.DeserializeObject <temporaryClassForResponseBody>(resultText);
                        if (result.incompleteSearch)
                        {
                            MessageAppended?.Invoke("Warning! This is an Incomplete Search");
                            MyLogger.Log("Warning! This is an Incomplete Search");
                        }
                        FileListGot.Clear();
                        if (result.files != null)
                        {
                            foreach (var file in result.files)
                            {
                                FileListGot.Add(new Tuple <string, string, string>(file.id, file.name, file.mimeType));
                            }
                        }
                        NewFileListGot?.Invoke(FileListGot);
                        if (result.nextPageToken == null)
                        {
                            Status = SearchStatus.Completed;
                        }
                        else
                        {
                            pageToken = result.nextPageToken;
                            Status    = SearchStatus.Paused;
                        }
                        return;
                    }
                    else
                    {
                        MessageAppended?.Invoke("Http response isn't OK!");
                        MessageAppended?.Invoke(await LogHttpWebResponse(response, true));
                        Status = SearchStatus.ErrorNeedResume;
                        return;
                    }
                }
            }
Exemplo n.º 11
0
 protected void OnMessageAppended(string msg)
 {
     messages.Add(msg); MessageAppended?.Invoke(msg);
 }
Exemplo n.º 12
0
            public async Task <List <CloudFile> > GetNextPageAsync(int pageSize = 100)
            {
                Status = Networker.NetworkStatus.Networking;
                if (searchListGetter == null)
                {
                    searchListGetter = new RestRequests.SearchListGetter(searchPattern);
                    searchListGetter.MessageAppended += (msg) => { MessageAppended?.Invoke($"[Rest]{msg}"); };
                    MessageAppended?.Invoke("Getting first page...");
                }
                else
                {
                    MessageAppended?.Invoke("Getting next page...");
                }
                if (searchListGetter.Status == RestRequests.SearchListGetter.SearchStatus.Completed)
                {
                    Status = Networker.NetworkStatus.Completed;
                    return(null);
                }
                searchListGetter.PageSize = pageSize;
                int timeToWait = 500;

                index_tryAgain :;
                await searchListGetter.GetNextPageAsync();

                if (searchListGetter.Status == RestRequests.SearchListGetter.SearchStatus.Paused)
                {
                    var ans = searchListGetter.FileListGot.Select((file) =>
                    {
                        return(new CloudFile(file.Item1, file.Item2, file.Item3 == Constants.FolderMimeType, parent));
                    }).ToList();
                    Status = Networker.NetworkStatus.Paused;
                    return(ans);
                }
                else if (searchListGetter.Status == RestRequests.SearchListGetter.SearchStatus.Completed)
                {
                    var ans = searchListGetter.FileListGot.Select((file) =>
                    {
                        return(new CloudFile(file.Item1, file.Item2, file.Item3 == Constants.FolderMimeType, parent));
                    }).ToList();
                    Status = Networker.NetworkStatus.Completed;
                    return(ans);
                }
                else
                {
                    MessageAppended?.Invoke($"searchListGetter.Status: {searchListGetter.Status}");
                    if (searchListGetter.Status == RestRequests.SearchListGetter.SearchStatus.ErrorNeedResume)
                    {
                        if (timeToWait > Constants.MaxTimeToWait)
                        {
                            Status = Networker.NetworkStatus.ErrorNeedRestart;
                            return(null);
                        }
                        MessageAppended?.Invoke($"Waiting for {timeToWait} milisecs and try again...");
                        await Task.Delay(timeToWait);

                        timeToWait *= 2;
                        goto index_tryAgain;
                    }
                    Status = Networker.NetworkStatus.ErrorNeedRestart;
                    return(null);
                }
            }
Exemplo n.º 13
0
            private async Task CreateResumableUploadAsync()
            {
                Status = UploadStatus.Creating;
                string json = $"{{\"name\":\"{fileName}\"";

                if (parents.Count > 0)
                {
                    json += ",\"parents\":[";
                    foreach (string parent in parents)
                    {
                        json += $"\"{parent}\",";
                    }
                    json = json.Remove(json.Length - 1) + "]";
                }
                json += "}";
                MessageAppended?.Invoke(json);
                long           totalBytes = fileStream.Length;
                HttpWebRequest request    = WebRequest.CreateHttp("https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable");
                var            bytes      = Encoding.UTF8.GetBytes(json);

                request.Headers["Content-Type"]   = "application /json; charset=UTF-8";
                request.Headers["Content-Length"] = bytes.Length.ToString(); // Convert.FromBase64String(json).Length.ToString();
                //request.Headers["X-Upload-Content-Type"]= Constants.GetMimeType(System.IO.Path.GetExtension(filePath));
                request.Headers["X-Upload-Content-Length"] = totalBytes.ToString();
                request.Headers["Authorization"]           = "Bearer " + (await Drive.GetAccessTokenAsync());
                request.Method = "POST";
                using (System.IO.Stream requestStream = await request.GetRequestStreamAsync())
                {
                    await requestStream.WriteAsync(bytes, 0, bytes.Length);

                    //using (System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(requestStream))
                    //{
                    //    await streamWriter.WriteAsync(json);
                    //}
                }
                using (var response = await GetHttpResponseAsync(request))
                {
                    if (response == null)
                    {
                        MessageAppended?.Invoke("Null response");
                        Status = UploadStatus.ErrorNeedRestart;
                        return;
                    }
                    MessageAppended?.Invoke($"Http response: {response.StatusCode} ({(int)response.StatusCode})");
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        if (Array.IndexOf(response.Headers.AllKeys, "location") == -1)
                        {
                            MessageAppended?.Invoke("response.Headers doesn't contain a key for \"location\"!");
                            Status = UploadStatus.ErrorNeedRestart;
                            return;
                        }
                        var resumableUri = JsonConvert.SerializeObject(response.Headers["location"]);
                        MessageAppended?.Invoke($"Resumable Uri: {resumableUri}");
                        this.resumableUri = resumableUri;
                        Status            = UploadStatus.Created;
                        return;
                    }
                    else
                    {
                        MessageAppended?.Invoke("Http response isn't OK!");
                        MessageAppended?.Invoke(await LogHttpWebResponse(response, true));
                        Status = UploadStatus.ErrorNeedRestart;
                        return;
                    }
                }
            }
Exemplo n.º 14
0
 private void Runner_MessageAppended(object sender, ScriptMessageData msg)
 {
     MessageAppended?.Invoke(this, msg);
 }
Exemplo n.º 15
0
            //private async Task<UploadStatus> VerifyCheckSum()
            //{
            //    MessageAppended?.Invoke("Calculating checksum...");
            //    string cloudCheckSum = await Libraries.GetSha256ForCloudFileById(CloudFileId);
            //    MessageAppended?.Invoke($"Cloud: {cloudCheckSum}");
            //    fileStream.Position = 0;
            //    string localCheckSum = await Libraries.GetSha256ForWindowsStorageFile(fileStream);
            //    MessageAppended?.Invoke($"Local: {localCheckSum}");
            //    if (cloudCheckSum != null && cloudCheckSum == localCheckSum)
            //    {
            //        MessageAppended?.Invoke("Checksum matched!");
            //        return UploadStatus.Completed;
            //    }
            //    else
            //    {
            //        MessageAppended?.Invoke("Failed: Checksum not matched");
            //        return UploadStatus.ErrorNeedRestart;
            //    }
            //}
            private async Task StartUploadAsync(long position)
            {
                if (pauseRequest)
                {
                    Status = UploadStatus.Paused;
                    lock (semaphoreSlim) semaphoreSlim.Release();
                    return;
                }
                Status = UploadStatus.Uploading;
                long chunkSize           = MinChunkSize;
                long bytesLeftStatistics = fileStream.Length - position;

                CloudFile.Networker.OnTotalAmountRemainChanged(bytesLeftStatistics);
                try
                {
                    for (; position != fileStream.Length;)
                    {
                        var    bufferSize   = Math.Min(chunkSize, fileStream.Length - position);
                        byte[] buffer       = new byte[bufferSize];
                        int    actualLength = 0;
                        while (actualLength < Math.Min(bufferSize, MinChunkSize))
                        {
                            fileStream.Position = position + actualLength;
                            actualLength       += await fileStream.ReadAsync(buffer, actualLength, (int)bufferSize - actualLength);
                        }
                        Array.Resize <byte>(ref buffer, actualLength);
                        DateTime startTime = DateTime.Now;
                        await DoResumableUploadAsync(position, buffer);

                        OnProgressChanged(position = byteReceivedSoFar, fileStream.Length);
                        if (Status == UploadStatus.Completed)
                        {
                            OnChunkSent(buffer.Length);
                            bytesLeftStatistics -= buffer.Length;
                            CloudFile.Networker.OnTotalAmountRemainChanged(-buffer.Length);
                            return;
                        }
                        else if (Status != UploadStatus.Uploading)
                        {
                            MessageAppended?.Invoke($"Failed! Chunk range: {position}-{position + buffer.Length - 1}");
                            return;
                        }
                        else
                        {
                            OnChunkSent(buffer.Length);
                            bytesLeftStatistics -= buffer.Length;
                            CloudFile.Networker.OnTotalAmountRemainChanged(-buffer.Length);
                        }
                        if ((DateTime.Now - startTime).TotalSeconds < 0.2)
                        {
                            chunkSize += chunkSize / 2;
                        }
                        else
                        {
                            chunkSize = Math.Max(MinChunkSize, chunkSize / 2);
                        }
                        //MyLogger.Log($"Sent: {i + chunkSize}/{fileStream.Length} bytes");
                        if (pauseRequest)
                        {
                            Status = UploadStatus.Paused;
                            lock (semaphoreSlim) semaphoreSlim.Release();
                            return;
                        }
                    }
                }
                finally
                {
                    CloudFile.Networker.OnTotalAmountRemainChanged(-bytesLeftStatistics);
                }
            }
Exemplo n.º 16
0
            private async Task DoResumableUploadAsync(long startByte, byte[] dataBytes)
            {
                var request = WebRequest.CreateHttp(resumableUri);

                request.Headers["Content-Length"] = dataBytes.Length.ToString();
                request.Headers["Content-Range"]  = $"bytes {startByte}-{startByte + dataBytes.Length - 1}/{fileStream.Length}";
                request.Method = "PUT";
                using (System.IO.Stream requestStream = await request.GetRequestStreamAsync())
                {
                    await requestStream.WriteAsync(dataBytes, 0, dataBytes.Length);
                }
                using (var response = await GetHttpResponseAsync(request))
                {
                    if (response == null)
                    {
                        MyLogger.Log("b");
                        Status = UploadStatus.ErrorNeedResume;
                        return;
                    }
                    if ((int)response.StatusCode == 308)
                    {
                        if (Array.IndexOf(response.Headers.AllKeys, "range") == -1)
                        {
                            MessageAppended?.Invoke("No bytes have been received by the server yet, starting from the first byte...");
                            byteReceivedSoFar = 0;
                        }
                        else
                        {
                            //bytes=0-42
                            string s = response.Headers["range"];
                            //MyLogger.Log($"Range received by server: {s}");
                            string pattern = "bytes=0-";
                            MyLogger.Assert(s.StartsWith(pattern));
                            byteReceivedSoFar = long.Parse(s.Substring(pattern.Length)) + 1;
                        }
                        return;
                    }
                    else if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Created)
                    {
                        using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
                        {
                            var data = await reader.ReadToEndAsync();

                            //MyLogger.Log($"{data}");
                            var jsonObject = JsonConvert.DeserializeObject <Newtonsoft.Json.Linq.JObject>(data);
                            MyLogger.Assert(fileName == (string)jsonObject["name"]);
                            CloudFileId = (string)jsonObject["id"];
                        }
                        byteReceivedSoFar = fileStream.Length;
                        Status            = UploadStatus.Completed;
                        return;
                    }
                    else
                    {
                        MessageAppended?.Invoke("Http response isn't 308!");
                        MessageAppended?.Invoke(await LogHttpWebResponse(response, true));
                        Status = UploadStatus.ErrorNeedResume;
                        return;
                    }
                }
            }
Exemplo n.º 17
0
            public async Task UploadAsync()
            {
                try
                {
                    switch (Status)
                    {
                    case UploadStatus.ErrorNeedResume:
                    case UploadStatus.Paused:
                    {
                        MyLogger.Assert(resumableUri != null);
                        //indexRetry:;
                        MessageAppended?.Invoke($"Resuming... Uri: {resumableUri}");
                        var request = WebRequest.CreateHttp(resumableUri);
                        request.Headers["Content-Length"] = "0";
                        request.Headers["Content-Range"]  = $"bytes */{fileStream.Length}";
                        request.Method = "PUT";
                        using (var response = await GetHttpResponseAsync(request))
                        {
                            if (response == null)
                            {
                                MyLogger.Log("c");
                                MessageAppended?.Invoke("Null response");
                                Status = UploadStatus.ErrorNeedResume;
                                return;
                            }
                            MessageAppended?.Invoke($"Http response: {response.StatusCode} ({response.StatusCode})");
                            if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Created)
                            {
                                MessageAppended?.Invoke("The upload was already completed");
                                MessageAppended?.Invoke(await LogHttpWebResponse(response, false));
                                using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
                                {
                                    var data = await reader.ReadToEndAsync();

                                    var jsonObject = JsonConvert.DeserializeObject <Newtonsoft.Json.Linq.JObject>(data);
                                    MyLogger.Assert(fileName == (string)jsonObject["name"]);
                                    CloudFileId = (string)jsonObject["id"];
                                }
                                response.Dispose();
                                Status = UploadStatus.Completed;
                                return;
                            }
                            else if ((int)response.StatusCode == 308)
                            {
                                long position;
                                if (Array.IndexOf(response.Headers.AllKeys, "range") == -1)
                                {
                                    MessageAppended?.Invoke("No bytes have been received by the server yet, starting from the first byte...");
                                    position = 0;
                                }
                                else
                                {
                                    //bytes=0-42
                                    string s = response.Headers["range"];
                                    MessageAppended?.Invoke($"Range received by server: {s}");
                                    string pattern = "bytes=0-";
                                    MyLogger.Assert(s.StartsWith(pattern));
                                    position = long.Parse(s.Substring(pattern.Length));
                                }
                                response.Dispose();
                                await StartUploadAsync(position);

                                return;
                            }
                            else if (response.StatusCode == HttpStatusCode.NotFound)
                            {
                                MessageAppended?.Invoke("The upload session has expired and the upload needs to be restarted from the beginning.");
                                MessageAppended?.Invoke(await LogHttpWebResponse(response, true));
                                response.Dispose();
                                Status = UploadStatus.ErrorNeedRestart;
                                return;
                            }
                            else
                            {
                                MessageAppended?.Invoke("Http response isn't OK, Created or 308!");
                                MessageAppended?.Invoke(await LogHttpWebResponse(response, true));
                                response.Dispose();
                                Status = UploadStatus.ErrorNeedResume;
                                return;
                            }
                        }
                    }

                    case UploadStatus.NotStarted:
                    {
                        if (fileStream.Length < MinChunkSize)
                        {
                            MessageAppended?.Invoke($"File too small ({fileStream.Length}), using multipart upload instead");
                            await DoMultipartUploadAsync();
                        }
                        else
                        {
                            await CreateResumableUploadAsync();

                            if (Status != UploadStatus.Created)
                            {
                                return;
                            }
                            MyLogger.Assert(resumableUri.StartsWith("\"") && resumableUri.EndsWith("\""));
                            resumableUri = resumableUri.Substring(1, resumableUri.Length - 2);
                            await StartUploadAsync(0);
                        }
                        return;
                    }

                    case UploadStatus.Completed:
                    case UploadStatus.Created:
                    case UploadStatus.Creating:
                    case UploadStatus.ErrorNeedRestart:
                    case UploadStatus.Uploading:
                    default: throw new Exception($"Status: {Status}");
                    }
                }
                finally
                {
                    if (pauseRequest)
                    {
                        MyLogger.Assert(Status != UploadStatus.Uploading);
                        lock (semaphoreSlim) semaphoreSlim.Release();
                    }
                }
            }
Exemplo n.º 18
0
 private async Task DoMultipartUploadAsync()
 {
     Status = UploadStatus.Uploading;
     OnProgressChanged(0, fileStream.Length);
     CloudFile.Networker.OnTotalAmountRemainChanged(fileStream.Length);
     try
     {
         var body = MergeMetadataAndFileContent(new Func <byte[]>(() =>
         {
             string json = $"Content-Type: application/json; charset=UTF-8\n\n{{\"name\":\"{fileName}\"";
             if (parents.Count > 0)
             {
                 json += ",\"parents\":[";
                 foreach (string parent in parents)
                 {
                     json += $"\"{parent}\",";
                 }
                 json = json.Remove(json.Length - 1) + "]";
             }
             json += "}";
             MessageAppended?.Invoke(json);
             return(Encoding.UTF8.GetBytes(json));
         })(), await new Func <Task <byte[]> >(async() =>
         {
             byte[] buffer = new byte[fileStream.Length];
             for (int i = 0; i < buffer.Length;)
             {
                 i += await fileStream.ReadAsync(buffer, i, buffer.Length - i);
             }
             return(buffer);
         })());
         //MessageAppended?.Invoke($"Request to send:\r\n{Encoding.UTF8.GetString(body.Item2)}");
         //long totalBytes = fileStream.Length;
         HttpWebRequest request = WebRequest.CreateHttp("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart");
         request.Headers["Content-Type"]   = "multipart/related; charset=UTF-8; boundary=" + body.Item1;
         request.Headers["Content-Length"] = body.Item2.Length.ToString(); // Convert.FromBase64String(json).Length.ToString();
                                                                           //request.Headers["X-Upload-Content-Type"]= Constants.GetMimeType(System.IO.Path.GetExtension(filePath));
                                                                           //request.Headers["X-Upload-Content-Length"] = totalBytes.ToString();
         request.Headers["Authorization"] = "Bearer " + (await Drive.GetAccessTokenAsync());
         request.Method = "POST";
         using (System.IO.Stream requestStream = await request.GetRequestStreamAsync())
         {
             await requestStream.WriteAsync(body.Item2, 0, body.Item2.Length);
         }
         using (var response = await GetHttpResponseAsync(request))
         {
             if (response == null)
             {
                 MessageAppended?.Invoke("Null response");
                 Status = UploadStatus.ErrorNeedRestart;
                 return;
             }
             MessageAppended?.Invoke($"Http response: {response.StatusCode} ({(int)response.StatusCode})");
             if (response.StatusCode == HttpStatusCode.OK)
             {
                 OnProgressChanged(fileStream.Length, fileStream.Length);
                 OnChunkSent(fileStream.Length);
                 Status = UploadStatus.Completed;
                 return;
             }
             else
             {
                 MessageAppended?.Invoke("Http response isn't OK!");
                 MessageAppended?.Invoke(await LogHttpWebResponse(response, true));
                 Status = UploadStatus.ErrorNeedRestart;
                 return;
             }
         }
     }
     finally
     {
         CloudFile.Networker.OnTotalAmountRemainChanged(-fileStream.Length);
     }
 }