|
|
@@ -5,6 +5,7 @@ import (
|
|
|
"crypto/md5"
|
|
|
"encoding/base64"
|
|
|
"encoding/xml"
|
|
|
+ "fmt"
|
|
|
"hash"
|
|
|
"hash/crc64"
|
|
|
"io"
|
|
|
@@ -13,6 +14,7 @@ import (
|
|
|
"net/url"
|
|
|
"os"
|
|
|
"strconv"
|
|
|
+ "time"
|
|
|
)
|
|
|
|
|
|
// Bucket implements the operations of object.
|
|
|
@@ -96,7 +98,8 @@ func (bucket Bucket) DoPutObject(request *PutObjectRequest, options []Option) (*
|
|
|
|
|
|
listener := getProgressListener(options)
|
|
|
|
|
|
- resp, err := bucket.do("PUT", request.ObjectKey, "", "", options, request.Reader, listener)
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ resp, err := bucket.do("PUT", request.ObjectKey, params, options, request.Reader, listener)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
@@ -188,7 +191,8 @@ func (bucket Bucket) GetObjectToFile(objectKey, filePath string, options ...Opti
|
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
|
//
|
|
|
func (bucket Bucket) DoGetObject(request *GetObjectRequest, options []Option) (*GetObjectResult, error) {
|
|
|
- resp, err := bucket.do("GET", request.ObjectKey, "", "", options, nil, nil)
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ resp, err := bucket.do("GET", request.ObjectKey, params, options, nil, nil)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
@@ -231,7 +235,8 @@ func (bucket Bucket) DoGetObject(request *GetObjectRequest, options []Option) (*
|
|
|
func (bucket Bucket) CopyObject(srcObjectKey, destObjectKey string, options ...Option) (CopyObjectResult, error) {
|
|
|
var out CopyObjectResult
|
|
|
options = append(options, CopySource(bucket.BucketName, url.QueryEscape(srcObjectKey)))
|
|
|
- resp, err := bucket.do("PUT", destObjectKey, "", "", options, nil, nil)
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ resp, err := bucket.do("PUT", destObjectKey, params, options, nil, nil)
|
|
|
if err != nil {
|
|
|
return out, err
|
|
|
}
|
|
|
@@ -284,7 +289,8 @@ func (bucket Bucket) copy(srcObjectKey, destBucketName, destObjectKey string, op
|
|
|
if err != nil {
|
|
|
return out, err
|
|
|
}
|
|
|
- resp, err := bucket.Client.Conn.Do("PUT", destBucketName, destObjectKey, "", "", headers, nil, 0, nil)
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ resp, err := bucket.Client.Conn.Do("PUT", destBucketName, destObjectKey, params, headers, nil, 0, nil)
|
|
|
if err != nil {
|
|
|
return out, err
|
|
|
}
|
|
|
@@ -319,6 +325,9 @@ func (bucket Bucket) AppendObject(objectKey string, reader io.Reader, appendPosi
|
|
|
}
|
|
|
|
|
|
result, err := bucket.DoAppendObject(request, options)
|
|
|
+ if err != nil {
|
|
|
+ return appendPosition, err
|
|
|
+ }
|
|
|
|
|
|
return result.NextPosition, err
|
|
|
}
|
|
|
@@ -333,7 +342,9 @@ func (bucket Bucket) AppendObject(objectKey string, reader io.Reader, appendPosi
|
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
|
//
|
|
|
func (bucket Bucket) DoAppendObject(request *AppendObjectRequest, options []Option) (*AppendObjectResult, error) {
|
|
|
- params := "append&position=" + strconv.FormatInt(request.Position, 10)
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ params["append"] = nil
|
|
|
+ params["position"] = strconv.FormatInt(request.Position, 10)
|
|
|
headers := make(map[string]string)
|
|
|
|
|
|
opts := addContentType(options, request.ObjectKey)
|
|
|
@@ -348,7 +359,7 @@ func (bucket Bucket) DoAppendObject(request *AppendObjectRequest, options []Opti
|
|
|
listener := getProgressListener(options)
|
|
|
|
|
|
handleOptions(headers, opts)
|
|
|
- resp, err := bucket.Client.Conn.Do("POST", bucket.BucketName, request.ObjectKey, params, params, headers,
|
|
|
+ resp, err := bucket.Client.Conn.Do("POST", bucket.BucketName, request.ObjectKey, params, headers,
|
|
|
request.Reader, initCRC, listener)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -379,7 +390,8 @@ func (bucket Bucket) DoAppendObject(request *AppendObjectRequest, options []Opti
|
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
|
//
|
|
|
func (bucket Bucket) DeleteObject(objectKey string) error {
|
|
|
- resp, err := bucket.do("DELETE", objectKey, "", "", nil, nil, nil)
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ resp, err := bucket.do("DELETE", objectKey, params, nil, nil, nil)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
@@ -404,7 +416,6 @@ func (bucket Bucket) DeleteObjects(objectKeys []string, options ...Option) (Dele
|
|
|
}
|
|
|
isQuiet, _ := findOption(options, deleteObjectsQuiet, false)
|
|
|
dxml.Quiet = isQuiet.(bool)
|
|
|
- encode := "&encoding-type=url"
|
|
|
|
|
|
bs, err := xml.Marshal(dxml)
|
|
|
if err != nil {
|
|
|
@@ -418,7 +429,12 @@ func (bucket Bucket) DeleteObjects(objectKeys []string, options ...Option) (Dele
|
|
|
sum := md5.Sum(bs)
|
|
|
b64 := base64.StdEncoding.EncodeToString(sum[:])
|
|
|
options = append(options, ContentMD5(b64))
|
|
|
- resp, err := bucket.do("POST", "", "delete"+encode, "delete", options, buffer, nil)
|
|
|
+
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ params["delete"] = nil
|
|
|
+ params["encoding-type"] = "url"
|
|
|
+
|
|
|
+ resp, err := bucket.do("POST", "", params, options, buffer, nil)
|
|
|
if err != nil {
|
|
|
return out, err
|
|
|
}
|
|
|
@@ -478,12 +494,12 @@ func (bucket Bucket) ListObjects(options ...Option) (ListObjectsResult, error) {
|
|
|
var out ListObjectsResult
|
|
|
|
|
|
options = append(options, EncodingType("url"))
|
|
|
- params, err := handleParams(options)
|
|
|
+ params, err := getRawParams(options)
|
|
|
if err != nil {
|
|
|
return out, err
|
|
|
}
|
|
|
|
|
|
- resp, err := bucket.do("GET", "", params, "", nil, nil, nil)
|
|
|
+ resp, err := bucket.do("GET", "", params, nil, nil, nil)
|
|
|
if err != nil {
|
|
|
return out, err
|
|
|
}
|
|
|
@@ -524,7 +540,8 @@ func (bucket Bucket) SetObjectMeta(objectKey string, options ...Option) error {
|
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
|
//
|
|
|
func (bucket Bucket) GetObjectDetailedMeta(objectKey string, options ...Option) (http.Header, error) {
|
|
|
- resp, err := bucket.do("HEAD", objectKey, "", "", options, nil, nil)
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ resp, err := bucket.do("HEAD", objectKey, params, options, nil, nil)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
@@ -545,7 +562,10 @@ func (bucket Bucket) GetObjectDetailedMeta(objectKey string, options ...Option)
|
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
|
//
|
|
|
func (bucket Bucket) GetObjectMeta(objectKey string) (http.Header, error) {
|
|
|
- resp, err := bucket.do("GET", objectKey, "?objectMeta", "", nil, nil, nil)
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ params["objectMeta"] = nil
|
|
|
+ //resp, err := bucket.do("GET", objectKey, "?objectMeta", "", nil, nil, nil)
|
|
|
+ resp, err := bucket.do("GET", objectKey, params, nil, nil, nil)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
@@ -573,7 +593,9 @@ func (bucket Bucket) GetObjectMeta(objectKey string) (http.Header, error) {
|
|
|
//
|
|
|
func (bucket Bucket) SetObjectACL(objectKey string, objectACL ACLType) error {
|
|
|
options := []Option{ObjectACL(objectACL)}
|
|
|
- resp, err := bucket.do("PUT", objectKey, "acl", "acl", options, nil, nil)
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ params["acl"] = nil
|
|
|
+ resp, err := bucket.do("PUT", objectKey, params, options, nil, nil)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
@@ -591,7 +613,9 @@ func (bucket Bucket) SetObjectACL(objectKey string, objectACL ACLType) error {
|
|
|
//
|
|
|
func (bucket Bucket) GetObjectACL(objectKey string) (GetObjectACLResult, error) {
|
|
|
var out GetObjectACLResult
|
|
|
- resp, err := bucket.do("GET", objectKey, "acl", "acl", nil, nil, nil)
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ params["acl"] = nil
|
|
|
+ resp, err := bucket.do("GET", objectKey, params, nil, nil, nil)
|
|
|
if err != nil {
|
|
|
return out, err
|
|
|
}
|
|
|
@@ -617,7 +641,9 @@ func (bucket Bucket) GetObjectACL(objectKey string) (GetObjectACLResult, error)
|
|
|
//
|
|
|
func (bucket Bucket) PutSymlink(symObjectKey string, targetObjectKey string, options ...Option) error {
|
|
|
options = append(options, symlinkTarget(url.QueryEscape(targetObjectKey)))
|
|
|
- resp, err := bucket.do("PUT", symObjectKey, "symlink", "symlink", options, nil, nil)
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ params["symlink"] = nil
|
|
|
+ resp, err := bucket.do("PUT", symObjectKey, params, options, nil, nil)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
@@ -634,7 +660,9 @@ func (bucket Bucket) PutSymlink(symObjectKey string, targetObjectKey string, opt
|
|
|
// error 操作无错误为nil,非nil为错误信息。当error为nil时,返回的string为目标文件,否则该值无效。
|
|
|
//
|
|
|
func (bucket Bucket) GetSymlink(objectKey string) (http.Header, error) {
|
|
|
- resp, err := bucket.do("GET", objectKey, "symlink", "symlink", nil, nil, nil)
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ params["symlink"] = nil
|
|
|
+ resp, err := bucket.do("GET", objectKey, params, nil, nil, nil)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
@@ -652,16 +680,20 @@ func (bucket Bucket) GetSymlink(objectKey string) (http.Header, error) {
|
|
|
//
|
|
|
// RestoreObject 恢复处于冷冻状态的归档类型Object进入读就绪状态。
|
|
|
//
|
|
|
-// 如果是针对该Object第一次调用restore接口,则返回成功。
|
|
|
-// 如果已经成功调用过restore接口,且restore没有完全完成,再次调用时返回409,错误码:RestoreAlreadyInProgress。
|
|
|
-// 如果已经成功调用过restore接口,且restore已经完成,再次调用时返回成功,且会将object的可下载时间延长一天,最多延长7天。
|
|
|
+// 一个Archive类型的object初始时处于冷冻状态。
|
|
|
+//
|
|
|
+// 针对处于冷冻状态的object调用restore命令,返回成功。object处于解冻中,服务端执行解冻,在此期间再次调用restore命令,同样成功,且不会延长object可读状态持续时间。
|
|
|
+// 待服务端执行完成解冻任务后,object就进入了解冻状态,此时用户可以读取object。
|
|
|
+// 解冻状态默认持续1天,对于解冻状态的object调用restore命令,会将object的解冻状态延长一天,最多可以延长到7天,之后object又回到初始时的冷冻状态。
|
|
|
//
|
|
|
// objectKey 需要恢复状态的object名称。
|
|
|
//
|
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
|
//
|
|
|
func (bucket Bucket) RestoreObject(objectKey string) error {
|
|
|
- resp, err := bucket.do("POST", objectKey, "restore", "restore", nil, nil, nil)
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ params["restore"] = nil
|
|
|
+ resp, err := bucket.do("POST", objectKey, params, nil, nil, nil)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
@@ -669,8 +701,219 @@ func (bucket Bucket) RestoreObject(objectKey string) error {
|
|
|
return checkRespCode(resp.StatusCode, []int{http.StatusOK, http.StatusAccepted})
|
|
|
}
|
|
|
|
|
|
+//
|
|
|
+// SignURL 获取签名URL。
|
|
|
+//
|
|
|
+// objectKey 获取URL的object。
|
|
|
+// signURLConfig 获取URL的配置。
|
|
|
+//
|
|
|
+// 返回URL字符串,error为nil时有效。
|
|
|
+// error 操作无错误为nil,非nil为错误信息。
|
|
|
+//
|
|
|
+func (bucket Bucket) SignURL(objectKey string, method HTTPMethod, expiredInSec int64, options ...Option) (string, error) {
|
|
|
+ if expiredInSec < 0 {
|
|
|
+ return "", fmt.Errorf("invalid expires: %d, expires must bigger than 0", expiredInSec)
|
|
|
+ }
|
|
|
+ expiration := time.Now().Unix() + expiredInSec
|
|
|
+
|
|
|
+ params, err := getRawParams(options)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ headers := make(map[string]string)
|
|
|
+ err = handleOptions(headers, options)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ return bucket.Client.Conn.signURL(method, bucket.BucketName, objectKey, expiration, params, headers), nil
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// PutObjectWithURL 新建Object,如果Object已存在,覆盖原有Object。
|
|
|
+// PutObjectWithURL 不会根据key生成minetype。
|
|
|
+//
|
|
|
+// signedURL 签名的URL。
|
|
|
+// reader io.Reader读取object的数据。
|
|
|
+// options 上传对象时可以指定对象的属性,可用选项有CacheControl、ContentDisposition、ContentEncoding、
|
|
|
+// Expires、ServerSideEncryption、ObjectACL、Meta,具体含义请参看
|
|
|
+// https://help.aliyun.com/document_detail/oss/api-reference/object/PutObject.html
|
|
|
+//
|
|
|
+// error 操作无错误为nil,非nil为错误信息。
|
|
|
+//
|
|
|
+func (bucket Bucket) PutObjectWithURL(signedURL string, reader io.Reader, options ...Option) error {
|
|
|
+ resp, err := bucket.DoPutObjectWithURL(signedURL, reader, options)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer resp.Body.Close()
|
|
|
+
|
|
|
+ return err
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// PutObjectFromFileWithURL 新建Object,内容从本地文件中读取。
|
|
|
+// PutObjectFromFileWithURL 不会根据key、filePath生成minetype。
|
|
|
+//
|
|
|
+// signedURL 签名的URL。
|
|
|
+// filePath 本地文件,如 dir/file.txt,上传对象的值为该文件内容。
|
|
|
+// options 上传对象时可以指定对象的属性。详见PutObject的options。
|
|
|
+//
|
|
|
+// error 操作无错误为nil,非nil为错误信息。
|
|
|
+//
|
|
|
+func (bucket Bucket) PutObjectFromFileWithURL(signedURL, filePath string, options ...Option) error {
|
|
|
+ fd, err := os.Open(filePath)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer fd.Close()
|
|
|
+
|
|
|
+ resp, err := bucket.DoPutObjectWithURL(signedURL, fd, options)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer resp.Body.Close()
|
|
|
+
|
|
|
+ return err
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// DoPutObjectWithURL 上传文件。
|
|
|
+//
|
|
|
+// signedURL 签名的URL。
|
|
|
+// reader io.Reader读取object的数据。
|
|
|
+// options 上传选项。
|
|
|
+//
|
|
|
+// Response 上传请求返回值。
|
|
|
+// error 操作无错误为nil,非nil为错误信息。
|
|
|
+//
|
|
|
+func (bucket Bucket) DoPutObjectWithURL(signedURL string, reader io.Reader, options []Option) (*Response, error) {
|
|
|
+ listener := getProgressListener(options)
|
|
|
+
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ resp, err := bucket.doURL("PUT", signedURL, params, options, reader, listener)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ if bucket.getConfig().IsEnableCRC {
|
|
|
+ err = checkCRC(resp, "DoPutObjectWithURL")
|
|
|
+ if err != nil {
|
|
|
+ return resp, err
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ err = checkRespCode(resp.StatusCode, []int{http.StatusOK})
|
|
|
+
|
|
|
+ return resp, err
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// GetObjectWithURL 下载文件。
|
|
|
+//
|
|
|
+// signedURL 签名的URL。
|
|
|
+// options 对象的属性限制项,可选值有Range、IfModifiedSince、IfUnmodifiedSince、IfMatch、
|
|
|
+// IfNoneMatch、AcceptEncoding,详细请参考
|
|
|
+// https://help.aliyun.com/document_detail/oss/api-reference/object/GetObject.html
|
|
|
+//
|
|
|
+// io.ReadCloser reader,读取数据后需要close。error为nil时有效。
|
|
|
+// error 操作无错误为nil,非nil为错误信息。
|
|
|
+//
|
|
|
+func (bucket Bucket) GetObjectWithURL(signedURL string, options ...Option) (io.ReadCloser, error) {
|
|
|
+ result, err := bucket.DoGetObjectWithURL(signedURL, options)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return result.Response.Body, nil
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// GetObjectToFile 下载文件。
|
|
|
+//
|
|
|
+// signedURL 签名的URL。
|
|
|
+// filePath 下载对象的内容写到该本地文件。
|
|
|
+// options 对象的属性限制项。详见GetObject的options。
|
|
|
+//
|
|
|
+// error 操作无错误时返回error为nil,非nil为错误说明。
|
|
|
+//
|
|
|
+func (bucket Bucket) GetObjectToFileWithURL(signedURL, filePath string, options ...Option) error {
|
|
|
+ tempFilePath := filePath + TempFileSuffix
|
|
|
+
|
|
|
+ // 读取Object内容
|
|
|
+ result, err := bucket.DoGetObjectWithURL(signedURL, options)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer result.Response.Body.Close()
|
|
|
+
|
|
|
+ // 如果文件不存在则创建,存在则清空
|
|
|
+ fd, err := os.OpenFile(tempFilePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, FilePermMode)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ // 存储数据到文件
|
|
|
+ _, err = io.Copy(fd, result.Response.Body)
|
|
|
+ fd.Close()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ // 比较CRC值
|
|
|
+ hasRange, _, _ := isOptionSet(options, HTTPHeaderRange)
|
|
|
+ if bucket.getConfig().IsEnableCRC && !hasRange {
|
|
|
+ result.Response.ClientCRC = result.ClientCRC.Sum64()
|
|
|
+ err = checkCRC(result.Response, "GetObjectToFileWithURL")
|
|
|
+ if err != nil {
|
|
|
+ os.Remove(tempFilePath)
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return os.Rename(tempFilePath, filePath)
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// DoGetObjectWithURL 下载文件
|
|
|
+//
|
|
|
+// signedURL 签名的URL。
|
|
|
+// options 对象的属性限制项。详见GetObject的options。
|
|
|
+//
|
|
|
+// GetObjectResult 下载请求返回值。
|
|
|
+// error 操作无错误为nil,非nil为错误信息。
|
|
|
+//
|
|
|
+func (bucket Bucket) DoGetObjectWithURL(signedURL string, options []Option) (*GetObjectResult, error) {
|
|
|
+ params := map[string]interface{}{}
|
|
|
+ resp, err := bucket.doURL("GET", signedURL, params, options, nil, nil)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ result := &GetObjectResult{
|
|
|
+ Response: resp,
|
|
|
+ }
|
|
|
+
|
|
|
+ // crc
|
|
|
+ var crcCalc hash.Hash64
|
|
|
+ hasRange, _, _ := isOptionSet(options, HTTPHeaderRange)
|
|
|
+ if bucket.getConfig().IsEnableCRC && !hasRange {
|
|
|
+ crcCalc = crc64.New(crcTable())
|
|
|
+ result.ServerCRC = resp.ServerCRC
|
|
|
+ result.ClientCRC = crcCalc
|
|
|
+ }
|
|
|
+
|
|
|
+ // progress
|
|
|
+ listener := getProgressListener(options)
|
|
|
+
|
|
|
+ contentLen, _ := strconv.ParseInt(resp.Headers.Get(HTTPHeaderContentLength), 10, 64)
|
|
|
+ resp.Body = ioutil.NopCloser(TeeReader(resp.Body, crcCalc, contentLen, listener, nil))
|
|
|
+
|
|
|
+ return result, nil
|
|
|
+}
|
|
|
+
|
|
|
// Private
|
|
|
-func (bucket Bucket) do(method, objectName, urlParams, subResource string, options []Option,
|
|
|
+func (bucket Bucket) do(method, objectName string, params map[string]interface{}, options []Option,
|
|
|
data io.Reader, listener ProgressListener) (*Response, error) {
|
|
|
headers := make(map[string]string)
|
|
|
err := handleOptions(headers, options)
|
|
|
@@ -678,7 +921,17 @@ func (bucket Bucket) do(method, objectName, urlParams, subResource string, optio
|
|
|
return nil, err
|
|
|
}
|
|
|
return bucket.Client.Conn.Do(method, bucket.BucketName, objectName,
|
|
|
- urlParams, subResource, headers, data, 0, listener)
|
|
|
+ params, headers, data, 0, listener)
|
|
|
+}
|
|
|
+
|
|
|
+func (bucket Bucket) doURL(method HTTPMethod, signedURL string, params map[string]interface{}, options []Option,
|
|
|
+ data io.Reader, listener ProgressListener) (*Response, error) {
|
|
|
+ headers := make(map[string]string)
|
|
|
+ err := handleOptions(headers, options)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return bucket.Client.Conn.DoURL(method, signedURL, headers, data, 0, listener)
|
|
|
}
|
|
|
|
|
|
func (bucket Bucket) getConfig() *Config {
|