using COSXML.Common; using System.IO; using COSXML.Model.Tag; using COSXML.Utils; using COSXML.CosException; using COSXML.Network; namespace COSXML.Model.Object { /// <summary> /// 简单上传对象 /// <see href="https://cloud.tencent.com/document/product/436/7749"/> /// </summary> public sealed class PutObjectRequest : ObjectRequest { private static string TAG = typeof(PutObjectRequest).FullName; /// <summary> /// 本地文件路径 /// </summary> private string srcPath; /// <summary> /// 上传文件指定起始位置 /// </summary> private long fileOffset = 0L; /// <summary> /// 上传data数据 /// </summary> private byte[] data; /// <summary> /// 上传指定内容的长度 /// </summary> private long contentLength = -1L; /// <summary> /// 上传流 /// </summary> private Stream stream; /// <summary> /// 上传回调 /// </summary> private COSXML.Callback.OnProgressCallback progressCallback; /// <summary> /// 上传整个文件 /// </summary> /// <param name="bucket"></param> /// <param name="key"></param> /// <param name="srcPath"></param> public PutObjectRequest(string bucket, string key, string srcPath) : this(bucket, key, srcPath, -1L, -1L) { } /// <summary> /// 上传文件的指定内容 /// </summary> /// <param name="bucket"></param> /// <param name="key"></param> /// <param name="srcPath"></param> /// <param name="fileOffset">文件指定起始位置</param> /// <param name="needSendLength">文件指定内容长度</param> public PutObjectRequest(string bucket, string key, string srcPath, long fileOffset, long needSendLength) : base(bucket, key) { this.method = CosRequestMethod.PUT; this.srcPath = srcPath; this.fileOffset = fileOffset < 0 ? 0 : fileOffset; this.contentLength = needSendLength < 0 ? -1L : needSendLength; } /// <summary> /// 上传data数据 /// </summary> /// <param name="bucket"></param> /// <param name="key"></param> /// <param name="data"></param> public PutObjectRequest(string bucket, string key, byte[] data) : base(bucket, key) { this.method = CosRequestMethod.PUT; this.data = data; } /// <summary> /// 流式上传 /// </summary> /// <param name="bucket"></param> /// <param name="key"></param> /// <param name="stream"></param> public PutObjectRequest(string bucket, string key, Stream stream) : base(bucket, key) { this.stream = stream; this.method = CosRequestMethod.PUT; } /// <summary> /// 指定 offset 的流式上传 /// </summary> /// <param name="bucket"></param> /// <param name="key"></param> /// <param name="stream"></param> /// <param name="offset"></param> public PutObjectRequest(string bucket, string key, Stream stream, long offset) : this(bucket, key, stream) { this.fileOffset = offset; } /// <summary> /// 指定 offset + content-length 的流式上传 /// </summary> /// <param name="bucket"></param> /// <param name="key"></param> /// <param name="stream"></param> /// <param name="offset"></param> /// <param name="needSendLength"></param> public PutObjectRequest(string bucket, string key, Stream stream, long offset, long needSendLength) : this(bucket, key, stream, offset) { this.contentLength = needSendLength < 0 ? -1L : needSendLength; } /// <summary> /// 上传回调 /// </summary> /// <param name="progressCallback"></param> public void SetCosProgressCallback(COSXML.Callback.OnProgressCallback progressCallback) { this.progressCallback = progressCallback; } /// <summary> /// 设置 Object 的存储级别 /// <see href="Common.CosStorageClass"/> /// </summary> /// <param name="cosStorageClass"></param> public void SetCosStorageClass(string cosStorageClass) { SetRequestHeader(CosRequestHeaderKey.X_COS_STORAGE_CLASS, cosStorageClass); } public override void CheckParameters() { if (srcPath == null && data == null && stream == null) { throw new CosClientException((int)(CosClientError.InvalidArgument), "data source = null"); } if (srcPath != null) { if (!File.Exists(srcPath)) { throw new CosClientException((int)(CosClientError.InvalidArgument), "file not exist"); } } if (stream != null) { if (stream.Length <= fileOffset || !stream.CanRead || !stream.CanSeek) { throw new CosClientException((int)(CosClientError.InvalidArgument), "stream invalid"); } } base.CheckParameters(); } public override Network.RequestBody GetRequestBody() { RequestBody body = null; if (srcPath != null) { FileInfo fileInfo = new FileInfo(srcPath); if (contentLength == -1 || contentLength + fileOffset > fileInfo.Length) { contentLength = fileInfo.Length - fileOffset; } body = new FileRequestBody(srcPath, fileOffset, contentLength); body.ProgressCallback = progressCallback; } else if (data != null) { body = new ByteRequestBody(data); body.ProgressCallback = progressCallback; } else if (stream != null) { if (fileOffset < 0) { fileOffset = 0L; } if (contentLength == -1L) { contentLength = stream.Length - fileOffset; } if (fileOffset + contentLength > stream.Length) { throw new CosException.CosClientException( (int)COSXML.Common.CosClientError.InvalidArgument, "stream offset + contentLength greater than stream.Length"); } body = new StreamRequestBody(stream, fileOffset, contentLength); } return body; } /// <summary> /// 定义 Object 的 acl 属性。有效值:private,public-read-write,public-read;默认值:private /// <see href="Common.CosACL"/> /// </summary> /// <param name="cosACL"></param> public void SetCosACL(string cosACL) { if (cosACL != null) { SetRequestHeader(CosRequestHeaderKey.X_COS_ACL, cosACL); } } /// <summary> /// 最大上传速度,单位是 bit/s /// </summary> /// <param name="rate"></param> public void LimitTraffic(long rate) { SetRequestHeader(CosRequestHeaderKey.X_COS_TRAFFIC_LIMIT, rate.ToString()); } /// <summary> /// 定义 Object 的 acl 属性。有效值:private,public-read-write,public-read;默认值:private /// <see href="Common.CosACL"/> /// </summary> /// <param name="cosACL"></param> public void SetCosACL(CosACL cosACL) { SetCosACL(EnumUtils.GetValue(cosACL)); } /// <summary> /// 赋予被授权者读的权限 /// <see href="Model.Tag.GrantAccount"/> /// </summary> /// <param name="grantAccount"></param> public void SetXCosGrantRead(GrantAccount grantAccount) { if (grantAccount != null) { SetRequestHeader(CosRequestHeaderKey.X_COS_GRANT_READ, grantAccount.GetGrantAccounts()); } } /// <summary> /// 赋予被授权者所有的权限 /// <see href="Model.Tag.GrantAccount"/> /// </summary> /// <param name="grantAccount"></param> public void SetXCosReadWrite(GrantAccount grantAccount) { if (grantAccount != null) { SetRequestHeader(CosRequestHeaderKey.X_COS_GRANT_FULL_CONTROL, grantAccount.GetGrantAccounts()); } } } }