Skip to content

Commit c5ff0aa

Browse files
authored
Merge pull request #184 from liketic/support-v4
Support signature v4
2 parents bd4d56f + 8a624ff commit c5ff0aa

11 files changed

+619
-96
lines changed

Diff for: client.go

+28
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ var InvalidCompressError = errors.New("Invalid Compress Type")
3535

3636
const DefaultLogUserAgent = "golang-sdk-v0.1.0"
3737

38+
// AuthVersionType the version of auth
39+
type AuthVersionType string
40+
41+
const (
42+
// AuthV1 v1
43+
AuthV1 AuthVersionType = "v1"
44+
// AuthV4 v4
45+
AuthV4 AuthVersionType = "v4"
46+
)
47+
3848
// Error defines sls error
3949
type Error struct {
4050
HTTPCode int32 `json:"httpCode"`
@@ -93,6 +103,8 @@ type Client struct {
93103
RequestTimeOut time.Duration
94104
RetryTimeOut time.Duration
95105
HTTPClient *http.Client
106+
Region string
107+
AuthVersion AuthVersionType // v1 or v4 signature,default is v1
96108

97109
accessKeyLock sync.RWMutex
98110
}
@@ -107,6 +119,8 @@ func convertLocked(c *Client, projName string) *LogProject {
107119
p, _ := NewLogProject(projName, c.Endpoint, c.AccessKeyID, c.AccessKeySecret)
108120
p.SecurityToken = c.SecurityToken
109121
p.UserAgent = c.UserAgent
122+
p.AuthVersion = c.AuthVersion
123+
p.Region = c.Region
110124
if c.HTTPClient != nil {
111125
p.httpClient = c.HTTPClient
112126
}
@@ -130,6 +144,20 @@ func (c *Client) SetHTTPClient(client *http.Client) {
130144
c.HTTPClient = client
131145
}
132146

147+
// SetAuthVersion set signature version that the client used
148+
func (c *Client) SetAuthVersion(version AuthVersionType) {
149+
c.accessKeyLock.Lock()
150+
c.AuthVersion = version
151+
c.accessKeyLock.Unlock()
152+
}
153+
154+
// SetRegion set a region, must be set if using signature version v4
155+
func (c *Client) SetRegion(region string) {
156+
c.accessKeyLock.Lock()
157+
c.Region = region
158+
c.accessKeyLock.Unlock()
159+
}
160+
133161
// ResetAccessKeyToken reset client's access key token
134162
func (c *Client) ResetAccessKeyToken(accessKeyID, accessKeySecret, securityToken string) {
135163
c.accessKeyLock.Lock()

Diff for: client_interface.go

+4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ type ClientInterface interface {
4848
// #################### Client Operations #####################
4949
// ResetAccessKeyToken reset client's access key token
5050
ResetAccessKeyToken(accessKeyID, accessKeySecret, securityToken string)
51+
// SetRegion Set region for signature v4
52+
SetRegion(region string)
53+
// SetAuthVersion Set signature version
54+
SetAuthVersion(version AuthVersionType)
5155
// Close the client
5256
Close() error
5357

Diff for: client_request.go

+18-19
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package sls
33
// request sends a request to SLS.
44
import (
55
"bytes"
6-
"crypto/md5"
76
"encoding/json"
87
"fmt"
98

@@ -19,7 +18,7 @@ import (
1918
// @note if error is nil, you must call http.Response.Body.Close() to finalize reader
2019
func (c *Client) request(project, method, uri string, headers map[string]string, body []byte) (*http.Response, error) {
2120
// The caller should provide 'x-log-bodyrawsize' header
22-
if _, ok := headers["x-log-bodyrawsize"]; !ok {
21+
if _, ok := headers[HTTPHeaderBodyRawSize]; !ok {
2322
return nil, fmt.Errorf("Can't find 'x-log-bodyrawsize' header")
2423
}
2524

@@ -41,44 +40,44 @@ func (c *Client) request(project, method, uri string, headers map[string]string,
4140
} else {
4241
hostStr = project + "." + endpoint
4342
}
44-
headers["Host"] = hostStr
45-
headers["Date"] = nowRFC1123()
46-
headers["x-log-apiversion"] = version
47-
headers["x-log-signaturemethod"] = signatureMethod
43+
headers[HTTPHeaderHost] = hostStr
44+
headers[HTTPHeaderAPIVersion] = version
4845

4946
if len(c.UserAgent) > 0 {
50-
headers["User-Agent"] = c.UserAgent
47+
headers[HTTPHeaderUserAgent] = c.UserAgent
5148
} else {
52-
headers["User-Agent"] = DefaultLogUserAgent
49+
headers[HTTPHeaderUserAgent] = DefaultLogUserAgent
5350
}
5451

5552
c.accessKeyLock.RLock()
5653
stsToken := c.SecurityToken
5754
accessKeyID := c.AccessKeyID
5855
accessKeySecret := c.AccessKeySecret
56+
region := c.Region
57+
authVersion := c.AuthVersion
5958
c.accessKeyLock.RUnlock()
6059

6160
// Access with token
6261
if stsToken != "" {
63-
headers["x-acs-security-token"] = stsToken
62+
headers[HTTPHeaderAcsSecurityToken] = stsToken
6463
}
6564

6665
if body != nil {
67-
bodyMD5 := fmt.Sprintf("%X", md5.Sum(body))
68-
headers["Content-MD5"] = bodyMD5
69-
if _, ok := headers["Content-Type"]; !ok {
66+
if _, ok := headers[HTTPHeaderContentType]; !ok {
7067
return nil, fmt.Errorf("Can't find 'Content-Type' header")
7168
}
7269
}
73-
74-
// Calc Authorization
75-
// Authorization = "SLS <AccessKeyId>:<Signature>"
76-
digest, err := signature(accessKeySecret, method, uri, headers)
77-
if err != nil {
70+
var signer Signer
71+
if authVersion == AuthV4 {
72+
headers[HTTPHeaderLogDate] = dateTimeISO8601()
73+
signer = NewSignerV4(accessKeyID, accessKeySecret, region)
74+
} else {
75+
headers[HTTPHeaderDate] = nowRFC1123()
76+
signer = NewSignerV1(accessKeyID, accessKeySecret)
77+
}
78+
if err := signer.Sign(method, uri, headers, body); err != nil {
7879
return nil, err
7980
}
80-
auth := fmt.Sprintf("SLS %v:%v", accessKeyID, digest)
81-
headers["Authorization"] = auth
8281

8382
// Initialize http request
8483
reader := bytes.NewReader(body)

Diff for: go.sum

+2-7
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFG
7474
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
7575
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
7676
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
77-
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
78-
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
7977
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
8078
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
8179
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -146,7 +144,6 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
146144
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
147145
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
148146
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
149-
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
150147
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
151148
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
152149
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -293,6 +290,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
293290
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
294291
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
295292
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
293+
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
296294
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
297295
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
298296
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -311,8 +309,6 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
311309
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
312310
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
313311
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
314-
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
315-
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
316312
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
317313
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
318314
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -339,7 +335,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
339335
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
340336
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
341337
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
342-
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
343338
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
344339
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
345340
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -349,7 +344,6 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb
349344
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
350345
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
351346
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
352-
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
353347
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
354348
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
355349
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -369,6 +363,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
369363
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
370364
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
371365
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
366+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
372367
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
373368
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
374369
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=

Diff for: log_project.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7-
87
"io/ioutil"
98
"net/http"
109
"net/url"
@@ -44,6 +43,7 @@ type LogProject struct {
4443
SecurityToken string
4544
UsingHTTP bool // default https
4645
UserAgent string // default defaultLogUserAgent
46+
AuthVersion AuthVersionType
4747
baseURL string
4848
retryTimeout time.Duration
4949
httpClient *http.Client

Diff for: request.go

+18-28
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package sls
22

33
import (
44
"bytes"
5-
"crypto/md5"
65
"encoding/json"
76
"fmt"
87
"io/ioutil"
@@ -11,9 +10,8 @@ import (
1110
"net/url"
1211
"time"
1312

14-
"github.com/go-kit/kit/log/level"
15-
1613
"github.com/cenkalti/backoff"
14+
"github.com/go-kit/kit/log/level"
1715
"golang.org/x/net/context"
1816
)
1917

@@ -141,50 +139,42 @@ func realRequest(ctx context.Context, project *LogProject, method, uri string, h
141139
body []byte) (*http.Response, error) {
142140

143141
// The caller should provide 'x-log-bodyrawsize' header
144-
if _, ok := headers["x-log-bodyrawsize"]; !ok {
142+
if _, ok := headers[HTTPHeaderBodyRawSize]; !ok {
145143
return nil, NewClientError(fmt.Errorf("Can't find 'x-log-bodyrawsize' header"))
146144
}
147145

148146
// SLS public request headers
149-
// var hostStr string
150-
// if len(project.Name) == 0 {
151-
// hostStr = project.Endpoint
152-
// } else {
153-
// hostStr = project.Name + "." + project.Endpoint
154-
// }
155147
baseURL := project.getBaseURL()
156-
headers["Host"] = baseURL
157-
headers["Date"] = nowRFC1123()
158-
headers["x-log-apiversion"] = version
159-
headers["x-log-signaturemethod"] = signatureMethod
148+
headers[HTTPHeaderHost] = baseURL
149+
headers[HTTPHeaderAPIVersion] = version
160150
if len(project.UserAgent) > 0 {
161-
headers["User-Agent"] = project.UserAgent
151+
headers[HTTPHeaderUserAgent] = project.UserAgent
162152
} else {
163-
headers["User-Agent"] = DefaultLogUserAgent
153+
headers[HTTPHeaderUserAgent] = DefaultLogUserAgent
164154
}
165155

166156
// Access with token
167157
if project.SecurityToken != "" {
168-
headers["x-acs-security-token"] = project.SecurityToken
158+
headers[HTTPHeaderAcsSecurityToken] = project.SecurityToken
169159
}
170160

171161
if body != nil {
172-
bodyMD5 := fmt.Sprintf("%X", md5.Sum(body))
173-
headers["Content-MD5"] = bodyMD5
174-
if _, ok := headers["Content-Type"]; !ok {
162+
if _, ok := headers[HTTPHeaderContentType]; !ok {
175163
return nil, NewClientError(fmt.Errorf("Can't find 'Content-Type' header"))
176164
}
177165
}
178166

179-
// Calc Authorization
180-
// Authorization = "SLS <AccessKeyId>:<Signature>"
181-
digest, err := signature(project.AccessKeySecret, method, uri, headers)
182-
if err != nil {
183-
return nil, NewClientError(err)
167+
var signer Signer
168+
if project.AuthVersion == AuthV4 {
169+
headers[HTTPHeaderLogDate] = dateTimeISO8601()
170+
signer = NewSignerV4(project.AccessKeyID, project.AccessKeySecret, project.Region)
171+
} else {
172+
headers[HTTPHeaderDate] = nowRFC1123()
173+
signer = NewSignerV1(project.AccessKeyID, project.AccessKeySecret)
174+
}
175+
if err := signer.Sign(method, uri, headers, body); err != nil {
176+
return nil, err
184177
}
185-
auth := fmt.Sprintf("SLS %v:%v", project.AccessKeyID, digest)
186-
headers["Authorization"] = auth
187-
188178
// Initialize http request
189179
reader := bytes.NewReader(body)
190180

0 commit comments

Comments
 (0)