| @@ -46,7 +46,10 @@ func (p *RequestParam) MakeRequest(baseURL string) (*http.Request, error) { | |||||
| } | } | ||||
| req.ContentLength = bodyLen | req.ContentLength = bodyLen | ||||
| req.URL.RawQuery = p.Query.Encode() | req.URL.RawQuery = p.Query.Encode() | ||||
| req.Header = p.Header | |||||
| if p.Header != nil { | |||||
| req.Header = p.Header | |||||
| } | |||||
| return req, nil | return req, nil | ||||
| } | } | ||||
| @@ -87,11 +90,11 @@ type StringBody struct { | |||||
| Value string | Value string | ||||
| } | } | ||||
| func (s StringBody) Length() int64 { | |||||
| func (s *StringBody) Length() int64 { | |||||
| return int64(len(s.Value)) | return int64(len(s.Value)) | ||||
| } | } | ||||
| func (s StringBody) IntoStream() io.ReadCloser { | |||||
| func (s *StringBody) IntoStream() io.ReadCloser { | |||||
| return io.NopCloser(bytes.NewReader([]byte(s.Value))) | return io.NopCloser(bytes.NewReader([]byte(s.Value))) | ||||
| } | } | ||||
| @@ -99,11 +102,11 @@ type BytesBody struct { | |||||
| Value []byte | Value []byte | ||||
| } | } | ||||
| func (b BytesBody) Length() int64 { | |||||
| func (b *BytesBody) Length() int64 { | |||||
| return int64(len(b.Value)) | return int64(len(b.Value)) | ||||
| } | } | ||||
| func (b BytesBody) IntoStream() io.ReadCloser { | |||||
| func (b *BytesBody) IntoStream() io.ReadCloser { | |||||
| return io.NopCloser(bytes.NewReader(b.Value)) | return io.NopCloser(bytes.NewReader(b.Value)) | ||||
| } | } | ||||
| @@ -112,11 +115,11 @@ type StreamBody struct { | |||||
| LengthHint int64 // 长度提示,如果长度未知,可以设置为-1 | LengthHint int64 // 长度提示,如果长度未知,可以设置为-1 | ||||
| } | } | ||||
| func (s StreamBody) Length() int64 { | |||||
| func (s *StreamBody) Length() int64 { | |||||
| return s.LengthHint | return s.LengthHint | ||||
| } | } | ||||
| func (s StreamBody) IntoStream() io.ReadCloser { | |||||
| func (s *StreamBody) IntoStream() io.ReadCloser { | |||||
| return s.Stream | return s.Stream | ||||
| } | } | ||||
| @@ -134,7 +137,7 @@ func MakeJSONParam(method string, path string, body any) *RequestParam { | |||||
| return &RequestParam{ | return &RequestParam{ | ||||
| Method: method, | Method: method, | ||||
| Path: path, | Path: path, | ||||
| Body: BytesBody{Value: data}, | |||||
| Body: &BytesBody{Value: data}, | |||||
| } | } | ||||
| } | } | ||||
| @@ -41,6 +41,9 @@ func Sign(req *http.Request, accessKey, secretKey string) error { | |||||
| hasher := sha256.New() | hasher := sha256.New() | ||||
| hasher.Write(data) | hasher.Write(data) | ||||
| payloadHash = hex.EncodeToString(hasher.Sum(nil)) | payloadHash = hex.EncodeToString(hasher.Sum(nil)) | ||||
| } else { | |||||
| hash := sha256.Sum256([]byte("")) | |||||
| payloadHash = hex.EncodeToString(hash[:]) | |||||
| } | } | ||||
| signer := v4.NewSigner() | signer := v4.NewSigner() | ||||
| @@ -52,9 +55,7 @@ func Sign(req *http.Request, accessKey, secretKey string) error { | |||||
| return nil | return nil | ||||
| } | } | ||||
| // 对一个请求进行签名,并将签名信息添加到请求头中。 | |||||
| // | |||||
| // 不计算请求体的哈希,适合上传文件接口。 | |||||
| // 对一个请求进行签名,不计算请求体的哈希,适合上传文件接口。 | |||||
| func SignWithoutBody(req *http.Request, accessKey, secretKey string) error { | func SignWithoutBody(req *http.Request, accessKey, secretKey string) error { | ||||
| prod := credentials.NewStaticCredentialsProvider(accessKey, secretKey, "") | prod := credentials.NewStaticCredentialsProvider(accessKey, secretKey, "") | ||||
| cred, err := prod.Retrieve(context.TODO()) | cred, err := prod.Retrieve(context.TODO()) | ||||
| @@ -245,3 +245,59 @@ func Test_Cache(t *testing.T) { | |||||
| So(err, ShouldBeNil) | So(err, ShouldBeNil) | ||||
| }) | }) | ||||
| } | } | ||||
| func Test_Sign(t *testing.T) { | |||||
| Convey("签名接口", t, func() { | |||||
| cli := NewClient(&Config{ | |||||
| URL: "http://localhost:7890/v1", | |||||
| AccessKey: "123456", | |||||
| SecretKey: "123456", | |||||
| }) | |||||
| fileData := make([]byte, 4096) | |||||
| for i := 0; i < len(fileData); i++ { | |||||
| fileData[i] = byte(i) | |||||
| } | |||||
| pkgName := uuid.NewString() | |||||
| createResp, err := cli.Package().Create(PackageCreate{ | |||||
| UserID: 1, | |||||
| BucketID: 1, | |||||
| Name: pkgName, | |||||
| }) | |||||
| So(err, ShouldBeNil) | |||||
| _, err = cli.Object().Upload(ObjectUpload{ | |||||
| ObjectUploadInfo: ObjectUploadInfo{ | |||||
| UserID: 1, | |||||
| PackageID: createResp.Package.PackageID, | |||||
| }, | |||||
| Files: iterator.Array( | |||||
| &UploadingObject{ | |||||
| Path: "abc/test", | |||||
| File: io.NopCloser(bytes.NewBuffer(fileData)), | |||||
| }, | |||||
| &UploadingObject{ | |||||
| Path: "test4", | |||||
| File: io.NopCloser(bytes.NewBuffer(fileData)), | |||||
| }, | |||||
| ), | |||||
| }) | |||||
| So(err, ShouldBeNil) | |||||
| getResp, err := cli.Package().Get(PackageGetReq{ | |||||
| UserID: 1, | |||||
| PackageID: createResp.Package.PackageID, | |||||
| }) | |||||
| So(err, ShouldBeNil) | |||||
| So(getResp.PackageID, ShouldEqual, createResp.Package.PackageID) | |||||
| So(getResp.Package.Name, ShouldEqual, pkgName) | |||||
| err = cli.Package().Delete(PackageDelete{ | |||||
| UserID: 1, | |||||
| PackageID: createResp.Package.PackageID, | |||||
| }) | |||||
| So(err, ShouldBeNil) | |||||
| }) | |||||
| } | |||||
| @@ -54,7 +54,7 @@ func JSONAPI[Resp sdks.APIResponse, Req sdks.APIRequest](cfg *Config, cli *http. | |||||
| } | } | ||||
| if cfg.AccessKey != "" && cfg.SecretKey != "" { | if cfg.AccessKey != "" && cfg.SecretKey != "" { | ||||
| err = SignWithPayloadHash(httpReq, cfg.AccessKey, cfg.SecretKey, calcSha256(param.Body)) | |||||
| err = SignWithPayloadHash(httpReq, calcSha256(param.Body), cfg.AccessKey, cfg.SecretKey) | |||||
| if err != nil { | if err != nil { | ||||
| return resp, err | return resp, err | ||||
| } | } | ||||
| @@ -78,7 +78,7 @@ func JSONAPINoData[Req sdks.APIRequest](cfg *Config, cli *http.Client, req Req) | |||||
| } | } | ||||
| if cfg.AccessKey != "" && cfg.SecretKey != "" { | if cfg.AccessKey != "" && cfg.SecretKey != "" { | ||||
| err = SignWithPayloadHash(httpReq, cfg.AccessKey, cfg.SecretKey, calcSha256(param.Body)) | |||||
| err = SignWithPayloadHash(httpReq, calcSha256(param.Body), cfg.AccessKey, cfg.SecretKey) | |||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| @@ -103,8 +103,12 @@ func calcSha256(body sdks.RequestBody) string { | |||||
| hasher.Write(body.Value) | hasher.Write(body.Value) | ||||
| return hex.EncodeToString(hasher.Sum(nil)) | return hex.EncodeToString(hasher.Sum(nil)) | ||||
| default: | |||||
| case *sdks.StreamBody: | |||||
| return "" | return "" | ||||
| default: | |||||
| hash := sha256.Sum256([]byte("")) | |||||
| return hex.EncodeToString(hash[:]) | |||||
| } | } | ||||
| } | } | ||||