Esempio n. 1
0
        private static async Task <Content> UploadInternalAsync(Stream binaryStream, UploadData uploadData, ODataRequest requestData, ServerContext server = null, Action <int> progressCallback = null)
        {
            server ??= ClientContext.Current.Server;

            // force set values
            uploadData.UseChunk = binaryStream.Length > ClientContext.Current.ChunkSizeInBytes;
            if (uploadData.FileLength == 0)
            {
                uploadData.FileLength = binaryStream.Length;
            }

            requestData.Parameters.Add("create", "1");

            dynamic uploadedContent = null;

            // Get ChunkToken
            try
            {
                SnTrace.Category(ClientContext.TraceCategory).Write("###>REQ: {0}", requestData);

                var retryCount = 0;

                await Retrier.RetryAsync(10, 1000, async() =>
                {
                    retryCount++;
                    var retryText = retryCount > 1 ? $" (retry {retryCount})" : string.Empty;
                    server.Logger?.LogTrace($"Uploading initial data of {uploadData.FileName}{retryText}.");

                    var httpContent = new StringContent(uploadData.ToString());
                    httpContent.Headers.ContentType = new MediaTypeHeaderValue(JsonContentMimeType);
                    await ProcessWebResponseAsync(requestData.ToString(), HttpMethod.Post, server, httpContent,
                                                  response =>
                    {
                        uploadData.ChunkToken = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                    }, CancellationToken.None).ConfigureAwait(false);
                }, (i, exception) =>
                {
                    // choose the exceptions when we can retry the operation
                    return(exception switch
                    {
                        null => true,
                        ClientException cex when
                            (int) cex.StatusCode == 429 ||
                        cex.ErrorData?.ExceptionType == "NodeIsOutOfDateException"
                        => false,
                        _ => throw exception
                    });
                });
Esempio n. 2
0
        private static WebRequest CreateInitUploadWebRequest(string url, ServerContext server, UploadData uploadData)
        {
            var myRequest = GetRequest(url, server);

            myRequest.Method = "POST";

            var postDataBytes = Encoding.ASCII.GetBytes(uploadData.ToString());

            myRequest.ContentLength = postDataBytes.Length;
            myRequest.ContentType   = UPLOAD_CONTENTTYPE;

            using (var reqStream = myRequest.GetRequestStream())
            {
                reqStream.Write(postDataBytes, 0, postDataBytes.Length);
            }

            return(myRequest);
        }
Esempio n. 3
0
        private static async Task <Content> UploadInternalAsync(Stream binaryStream, UploadData uploadData, ODataRequest requestData, ServerContext server = null, Action <int> progressCallback = null)
        {
            // force set values
            uploadData.UseChunk = binaryStream.Length > ClientContext.Current.ChunkSizeInBytes;
            if (uploadData.FileLength == 0)
            {
                uploadData.FileLength = binaryStream.Length;
            }

            requestData.Parameters.Add("create", "1");

            dynamic uploadedContent = null;

            // Get ChunkToken
            try
            {
                SnTrace.Category(ClientContext.TraceCategory).Write("###>REQ: {0}", requestData);

                var httpContent = new StringContent(uploadData.ToString());
                httpContent.Headers.ContentType = new MediaTypeHeaderValue(JsonContentMimeType);
                await ProcessWebResponseAsync(requestData.ToString(), HttpMethod.Post, server, httpContent,
                                              async response =>
                {
                    uploadData.ChunkToken = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                }, CancellationToken.None).ConfigureAwait(false);
            }
            catch (WebException ex)
            {
                var ce = new ClientException("Error during binary upload.", ex);

                ce.Data["SiteUrl"]     = requestData.SiteUrl;
                ce.Data["Parent"]      = requestData.ContentId != 0 ? requestData.ContentId.ToString() : requestData.Path;
                ce.Data["FileName"]    = uploadData.FileName;
                ce.Data["ContentType"] = uploadData.ContentType;

                throw ce;
            }

            // Reuse previous request data, but remove unnecessary parameters
            requestData.Parameters.Remove("create");

            // Send subsequent requests
            var boundary       = "---------------------------" + DateTime.UtcNow.Ticks.ToString("x");
            var uploadFormData = uploadData.ToKeyValuePairs();
            var contentDispositionHeaderValue = new ContentDispositionHeaderValue("attachment")
            {
                FileName = uploadData.FileName
            };
            var buffer = new byte[ClientContext.Current.ChunkSizeInBytes];
            int bytesRead;
            var start = 0;

            while ((bytesRead = binaryStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                // Prepare the current chunk request
                var httpContent = new MultipartFormDataContent(boundary);
                foreach (var item in uploadFormData)
                {
                    httpContent.Add(new StringContent(item.Value), item.Key);
                }
                httpContent.Headers.ContentDisposition = contentDispositionHeaderValue;

                if (uploadData.UseChunk)
                {
                    httpContent.Headers.ContentRange = new ContentRangeHeaderValue(start, start + bytesRead - 1, binaryStream.Length);
                }

                // Add the chunk as a stream into the request content
                var postedStream = new MemoryStream(buffer, 0, bytesRead);
                httpContent.Add(new StreamContent(postedStream), "files[]", uploadData.FileName);

                // Process
                await ProcessWebResponseAsync(requestData.ToString(), HttpMethod.Post, server,
                                              httpContent,
                                              async response =>
                {
                    var rs          = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                    uploadedContent = JsonHelper.Deserialize(rs);
                }, CancellationToken.None).ConfigureAwait(false);

                start += bytesRead;

                // Notify the caller about every chunk that was uploaded successfully
                progressCallback?.Invoke(start);
            }

            if (uploadedContent == null)
            {
                return(null);
            }

            int contentId = uploadedContent.Id;
            var content   = Content.Create(contentId);

            content.Name = uploadedContent.Name;
            content.Path = uploadedContent.Url;

            return(content);
        }