Skip to content

Commit

Permalink
Merge pull request #184 from liketic/support-v4
Browse files Browse the repository at this point in the history
Support signature v4
  • Loading branch information
shabicheng authored Dec 8, 2022
2 parents bd4d56f + 8a624ff commit c5ff0aa
Show file tree
Hide file tree
Showing 11 changed files with 619 additions and 96 deletions.
28 changes: 28 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ var InvalidCompressError = errors.New("Invalid Compress Type")

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

// AuthVersionType the version of auth
type AuthVersionType string

const (
// AuthV1 v1
AuthV1 AuthVersionType = "v1"
// AuthV4 v4
AuthV4 AuthVersionType = "v4"
)

// Error defines sls error
type Error struct {
HTTPCode int32 `json:"httpCode"`
Expand Down Expand Up @@ -93,6 +103,8 @@ type Client struct {
RequestTimeOut time.Duration
RetryTimeOut time.Duration
HTTPClient *http.Client
Region string
AuthVersion AuthVersionType // v1 or v4 signature,default is v1

accessKeyLock sync.RWMutex
}
Expand All @@ -107,6 +119,8 @@ func convertLocked(c *Client, projName string) *LogProject {
p, _ := NewLogProject(projName, c.Endpoint, c.AccessKeyID, c.AccessKeySecret)
p.SecurityToken = c.SecurityToken
p.UserAgent = c.UserAgent
p.AuthVersion = c.AuthVersion
p.Region = c.Region
if c.HTTPClient != nil {
p.httpClient = c.HTTPClient
}
Expand All @@ -130,6 +144,20 @@ func (c *Client) SetHTTPClient(client *http.Client) {
c.HTTPClient = client
}

// SetAuthVersion set signature version that the client used
func (c *Client) SetAuthVersion(version AuthVersionType) {
c.accessKeyLock.Lock()
c.AuthVersion = version
c.accessKeyLock.Unlock()
}

// SetRegion set a region, must be set if using signature version v4
func (c *Client) SetRegion(region string) {
c.accessKeyLock.Lock()
c.Region = region
c.accessKeyLock.Unlock()
}

// ResetAccessKeyToken reset client's access key token
func (c *Client) ResetAccessKeyToken(accessKeyID, accessKeySecret, securityToken string) {
c.accessKeyLock.Lock()
Expand Down
4 changes: 4 additions & 0 deletions client_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ type ClientInterface interface {
// #################### Client Operations #####################
// ResetAccessKeyToken reset client's access key token
ResetAccessKeyToken(accessKeyID, accessKeySecret, securityToken string)
// SetRegion Set region for signature v4
SetRegion(region string)
// SetAuthVersion Set signature version
SetAuthVersion(version AuthVersionType)
// Close the client
Close() error

Expand Down
37 changes: 18 additions & 19 deletions client_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package sls
// request sends a request to SLS.
import (
"bytes"
"crypto/md5"
"encoding/json"
"fmt"

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

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

if len(c.UserAgent) > 0 {
headers["User-Agent"] = c.UserAgent
headers[HTTPHeaderUserAgent] = c.UserAgent
} else {
headers["User-Agent"] = DefaultLogUserAgent
headers[HTTPHeaderUserAgent] = DefaultLogUserAgent
}

c.accessKeyLock.RLock()
stsToken := c.SecurityToken
accessKeyID := c.AccessKeyID
accessKeySecret := c.AccessKeySecret
region := c.Region
authVersion := c.AuthVersion
c.accessKeyLock.RUnlock()

// Access with token
if stsToken != "" {
headers["x-acs-security-token"] = stsToken
headers[HTTPHeaderAcsSecurityToken] = stsToken
}

if body != nil {
bodyMD5 := fmt.Sprintf("%X", md5.Sum(body))
headers["Content-MD5"] = bodyMD5
if _, ok := headers["Content-Type"]; !ok {
if _, ok := headers[HTTPHeaderContentType]; !ok {
return nil, fmt.Errorf("Can't find 'Content-Type' header")
}
}

// Calc Authorization
// Authorization = "SLS <AccessKeyId>:<Signature>"
digest, err := signature(accessKeySecret, method, uri, headers)
if err != nil {
var signer Signer
if authVersion == AuthV4 {
headers[HTTPHeaderLogDate] = dateTimeISO8601()
signer = NewSignerV4(accessKeyID, accessKeySecret, region)
} else {
headers[HTTPHeaderDate] = nowRFC1123()
signer = NewSignerV1(accessKeyID, accessKeySecret)
}
if err := signer.Sign(method, uri, headers, body); err != nil {
return nil, err
}
auth := fmt.Sprintf("SLS %v:%v", accessKeyID, digest)
headers["Authorization"] = auth

// Initialize http request
reader := bytes.NewReader(body)
Expand Down
9 changes: 2 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFG
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
Expand Down Expand Up @@ -146,7 +144,6 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand Down Expand Up @@ -293,6 +290,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand All @@ -311,8 +309,6 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
Expand All @@ -339,7 +335,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
Expand All @@ -349,7 +344,6 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
Expand All @@ -369,6 +363,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
Expand Down
2 changes: 1 addition & 1 deletion log_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"fmt"

"io/ioutil"
"net/http"
"net/url"
Expand Down Expand Up @@ -44,6 +43,7 @@ type LogProject struct {
SecurityToken string
UsingHTTP bool // default https
UserAgent string // default defaultLogUserAgent
AuthVersion AuthVersionType
baseURL string
retryTimeout time.Duration
httpClient *http.Client
Expand Down
46 changes: 18 additions & 28 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package sls

import (
"bytes"
"crypto/md5"
"encoding/json"
"fmt"
"io/ioutil"
Expand All @@ -11,9 +10,8 @@ import (
"net/url"
"time"

"github.com/go-kit/kit/log/level"

"github.com/cenkalti/backoff"
"github.com/go-kit/kit/log/level"
"golang.org/x/net/context"
)

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

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

// SLS public request headers
// var hostStr string
// if len(project.Name) == 0 {
// hostStr = project.Endpoint
// } else {
// hostStr = project.Name + "." + project.Endpoint
// }
baseURL := project.getBaseURL()
headers["Host"] = baseURL
headers["Date"] = nowRFC1123()
headers["x-log-apiversion"] = version
headers["x-log-signaturemethod"] = signatureMethod
headers[HTTPHeaderHost] = baseURL
headers[HTTPHeaderAPIVersion] = version
if len(project.UserAgent) > 0 {
headers["User-Agent"] = project.UserAgent
headers[HTTPHeaderUserAgent] = project.UserAgent
} else {
headers["User-Agent"] = DefaultLogUserAgent
headers[HTTPHeaderUserAgent] = DefaultLogUserAgent
}

// Access with token
if project.SecurityToken != "" {
headers["x-acs-security-token"] = project.SecurityToken
headers[HTTPHeaderAcsSecurityToken] = project.SecurityToken
}

if body != nil {
bodyMD5 := fmt.Sprintf("%X", md5.Sum(body))
headers["Content-MD5"] = bodyMD5
if _, ok := headers["Content-Type"]; !ok {
if _, ok := headers[HTTPHeaderContentType]; !ok {
return nil, NewClientError(fmt.Errorf("Can't find 'Content-Type' header"))
}
}

// Calc Authorization
// Authorization = "SLS <AccessKeyId>:<Signature>"
digest, err := signature(project.AccessKeySecret, method, uri, headers)
if err != nil {
return nil, NewClientError(err)
var signer Signer
if project.AuthVersion == AuthV4 {
headers[HTTPHeaderLogDate] = dateTimeISO8601()
signer = NewSignerV4(project.AccessKeyID, project.AccessKeySecret, project.Region)
} else {
headers[HTTPHeaderDate] = nowRFC1123()
signer = NewSignerV1(project.AccessKeyID, project.AccessKeySecret)
}
if err := signer.Sign(method, uri, headers, body); err != nil {
return nil, err
}
auth := fmt.Sprintf("SLS %v:%v", project.AccessKeyID, digest)
headers["Authorization"] = auth

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

Expand Down
Loading

0 comments on commit c5ff0aa

Please sign in to comment.