virtual public bool FromString(string value)
        {
            var tokens = value.Split(ContextSeparator);

            if (tokens.Length != 3)
            {
                return(false);
            }

            UploadId   = tokens[0];
            ContentMd5 = tokens[1];
            var partStr = tokens[2];

            var partTokens = partStr.Split(PartContextSeparator);

            if (partTokens.Length <= 1)
            {
                return(false);
            }

            PartContextList = PartContextList ?? new List <ResumablePartContext>();
            for (int i = 0; i < partTokens.Length; i++)
            {
                var partContext = new ResumablePartContext();
                if (!partContext.FromString(partTokens[i]))
                {
                    return(false);
                }

                PartContextList.Add(partContext);
            }
            return(true);
        }
Exemple #2
0
        public override bool FromString(string value)
        {
            var tokens = value.Split(ContextSeparator);

            if (tokens.Length != 4)
            {
                return(false);
            }

            ETag = tokens[0];
            if (!string.IsNullOrEmpty(tokens[1]))
            {
                ContentMd5 = tokens[1];
            }

            if (!string.IsNullOrEmpty(tokens[2]))
            {
                Crc64 = tokens[2];
            }

            var partStr    = tokens[3];
            var partTokens = partStr.Split(PartContextSeparator);

            if (partTokens.Length <= 1)
            {
                return(false);
            }

            PartContextList = PartContextList ?? new List <ResumablePartContext>();
            for (int i = 0; i < partTokens.Length; i++)
            {
                var partContext = new ResumablePartContext();
                if (!partContext.FromString(partTokens[i]))
                {
                    return(false);
                }

                PartContextList.Add(partContext);
            }
            return(true);
        }
        private void UploadPart(object state)
        {
            UploadTask taskParam = state as UploadTask;

            if (taskParam == null)
            {
                throw new ClientException("Internal error. The state object should be an instance of class UploadTaskParam");
            }

            try
            {
                ResumablePartContext part = taskParam.ResumableUploadPartContext;
                if (part.IsCompleted)
                {
                    return;
                }

                const int retryCount = 3;
                Stream    stream     = taskParam.InputStream;
                for (int i = 0; i < retryCount; i++)
                {
                    if (stream is FileStream)
                    {
                        stream.Seek(part.Position, SeekOrigin.Begin);
                    }
                    else
                    {
                        stream.Seek(0, SeekOrigin.Begin);
                    }

                    Stream progressCallbackStream = null;
                    try
                    {
                        if (taskParam.UploadProgressCallback != null)
                        {
                            progressCallbackStream = _ossClient.SetupProgressListeners(stream,
                                                                                       taskParam.UploadFileStream.Length, // does not matter
                                                                                       _uploadedBytes,                    // does not matter
                                                                                       Math.Min(taskParam.ProgressUpdateInterval, 1024 * 4),
                                                                                       this.ProcessCallbackInternal);
                        }

                        var request = new UploadPartRequest(taskParam.ResumableUploadContext.BucketName, taskParam.ResumableUploadContext.Key, taskParam.ResumableUploadContext.UploadId)
                        {
                            InputStream  = progressCallbackStream ?? stream,
                            PartSize     = part.Length,
                            PartNumber   = part.PartId,
                            RequestPayer = _request.RequestPayer,
                            TrafficLimit = _request.TrafficLimit
                        };

                        var partResult = _ossClient.UploadPart(request);
                        part.PartETag = partResult.PartETag;
                        if (partResult.ResponseMetadata.ContainsKey(HttpHeaders.HashCrc64Ecma))
                        {
                            part.Crc64 = ulong.Parse(partResult.ResponseMetadata[HttpHeaders.HashCrc64Ecma]);
                        }

                        part.IsCompleted = true;
                        break;
                    }
                    catch (Exception ex) // when the connection is closed while sending the data, it will run into ObjectDisposedException.
                    {
                        if (!(ex is ObjectDisposedException || ex is WebException) || i == retryCount - 1)
                        {
                            throw;
                        }
                    }
                    finally
                    {
                        if (progressCallbackStream != null)
                        {
                            progressCallbackStream.Dispose();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                taskParam.Error = e;
            }
            finally
            {
                taskParam.Finished.Set();
            }
        }
        private void DownloadPart(object state)
        {
            DownloadTaskParam taskParam = state as DownloadTaskParam;

            if (taskParam == null)
            {
                throw new ClientException("Internal error. The taskParam should be type of DownloadTaskParam");
            }
            DownloadObjectRequest request = taskParam.Request;
            ResumablePartContext  part    = taskParam.Part;
            EventHandler <StreamTransferProgressArgs> downloadProgressCallback = taskParam.DownloadProgressCallback;

            try
            {
                string fileName = GetTempDownloadFile(request);
                if (part.IsCompleted && File.Exists(fileName))
                {
                    // is CRC is enabled and part.Crc64 is 0, then redownload the data
                    if (!_conf.EnableCrcCheck || part.Crc64 != 0)
                    {
                        return;
                    }
                }

                const int retryCount = 3;
                for (int i = 0; i < retryCount; i++)
                {
                    try
                    {
                        GetObjectRequest partRequest = request.ToGetObjectRequest();
                        partRequest.SetRange(part.Position, part.Position + part.Length - 1);
                        using (var partResult = _ossClient.GetObject(partRequest))
                        {
                            Crc64Stream crcStream = null;
                            if (_conf.EnableCrcCheck)
                            {
                                crcStream = new Crc64Stream(partResult.Content, null, part.Length, 0);
                            }

                            using (var fs = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
                            {
                                fs.Seek(part.Position, SeekOrigin.Begin);

                                long totalBytes = WriteTo(crcStream ?? partResult.Content, fs);
                                if (totalBytes != part.Length)
                                {
                                    throw new OssException(string.Format("Part {0} returns {1} bytes. Expected size is {2} bytes",
                                                                         part.PartId, totalBytes, part.Length));
                                }
                                Interlocked.Add(ref _downloadedBytes, partResult.ContentLength);
                            }

                            part.IsCompleted = true;
                            if (crcStream != null)
                            {
                                if (crcStream.CalculatedHash == null)
                                {
                                    crcStream.CalculateHash();
                                }
                                part.Crc64 = BitConverter.ToUInt64(crcStream.CalculatedHash, 0);
                            }

                            return;
                        }
                    }
                    catch (Exception ex) // when the connection is closed while sending the data, it will run into ObjectDisposedException.
                    {
                        if (!(ex is ObjectDisposedException || ex is WebException) || i == retryCount - 1)
                        {
                            throw;
                        }
                    }
                }

                throw new ClientException("DownloadPart runs into internal error");
            }
            catch (Exception e)
            {
                taskParam.Error = e;
            }
            finally
            {
                taskParam.DownloadFinished.Set();
            }
        }
        private DownloadTaskParam StartDownloadPartTask(DownloadObjectRequest request, ResumablePartContext part, EventHandler <StreamTransferProgressArgs> downloadProgressCallback)
        {
            DownloadTaskParam taskParam = new DownloadTaskParam();

            taskParam.Request = request;
            taskParam.Part    = part;
            taskParam.DownloadProgressCallback = downloadProgressCallback;
            taskParam.DownloadFinished         = new ManualResetEvent(false);
            ThreadPool.QueueUserWorkItem(DownloadPart, taskParam);
            return(taskParam);
        }
        virtual public bool FromString(string value)
        {
            var tokens = value.Split(ContextSeparator);
            if (tokens.Length != 3)
            {
                return false;
            }

            UploadId = tokens[0];
            ContentMd5 = tokens[1];
            var partStr = tokens[2];

            var partTokens = partStr.Split(PartContextSeparator);
            if (partTokens.Length <= 1)
            {
                return false;
            }

            PartContextList = PartContextList ?? new List<ResumablePartContext>();
            for (int i = 0; i < partTokens.Length; i++)
            {
                var partContext = new ResumablePartContext();
                if (!partContext.FromString(partTokens[i]))
                {
                    return false;
                }
                 
                PartContextList.Add(partContext);
            }
            return true;
        }