public static PutObjectCommand Create(IServiceClient client, Uri endpoint,
                                              ExecutionContext context,
                                              PutObjectRequest putObjectRequest)
        {
            OssUtils.CheckBucketName(putObjectRequest.BucketName);
            OssUtils.CheckObjectKey(putObjectRequest.Key);

            if (putObjectRequest.Content == null)
            {
                throw new ArgumentNullException("content");
            }

            // handle upload callback error 203
            if (putObjectRequest.IsCallbackRequest())
            {
                context.ResponseHandlers.Add(new CallbackResponseHandler());
            }

            var conf           = OssUtils.GetClientConfiguration(client);
            var originalStream = putObjectRequest.Content;

            // setup progress
            var callback = putObjectRequest.StreamTransferProgress;

            if (callback != null)
            {
                originalStream           = OssUtils.SetupProgressListeners(originalStream, conf.ProgressUpdateInterval, client, callback);
                putObjectRequest.Content = originalStream;
            }

            // wrap input stream in MD5Stream
            if (conf.EnalbeMD5Check)
            {
                var streamLength = originalStream.CanSeek ? originalStream.Length : -1;
                var hashStream   = new MD5Stream(originalStream, null, streamLength);
                putObjectRequest.Content = hashStream;
                context.ResponseHandlers.Add(new MD5DigestCheckHandler(hashStream));
            }
            else if (conf.EnableCrcCheck)
            {
                var streamLength = originalStream.CanSeek ? originalStream.Length : -1;
                var hashStream   = new Crc64Stream(originalStream, null, streamLength);
                putObjectRequest.Content = hashStream;
                context.ResponseHandlers.Add(new Crc64CheckHandler(hashStream));
            }

            return(new PutObjectCommand(client, endpoint, context,
                                        DeserializerFactory.GetFactory().CreatePutObjectReusltDeserializer(putObjectRequest),
                                        putObjectRequest));
        }