Skip to content
This repository was archived by the owner on Mar 18, 2025. It is now read-only.

Commit f36001e

Browse files
committed
- Added attributions for ported code
- Added config validations for tripper - Added comment for aps - Removed noEscape to signer internal state
1 parent 1e27c9e commit f36001e

File tree

4 files changed

+36
-12
lines changed

4 files changed

+36
-12
lines changed

pkg/sigv4/const.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package sigv4
22

33
const (
4-
awsServiceName = "aps"
4+
// Amazon Managed Service for Prometheus
5+
awsServiceName = "aps"
6+
57
signingAlgorithm = "AWS4-HMAC-SHA256"
68

79
authorizationHeaderKey = "Authorization"

pkg/sigv4/sigv4.go

+15-7
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,20 @@ type Signer interface {
2121

2222
type DefaultSigner struct {
2323
config *Config
24+
25+
// noEscape represents the characters that AWS doesn't escape
26+
noEscape [256]bool
2427
}
2528

2629
func NewDefaultSigner(config *Config) Signer {
27-
// initialize noEscape array. This way we can avoid using init() functions
28-
for i := 0; i < len(noEscape); i++ {
30+
ds := &DefaultSigner{
31+
config: config,
32+
noEscape: [256]bool{},
33+
}
34+
35+
for i := 0; i < len(ds.noEscape); i++ {
2936
// AWS expects every character except these to be escaped
30-
noEscape[i] = (i >= 'A' && i <= 'Z') ||
37+
ds.noEscape[i] = (i >= 'A' && i <= 'Z') ||
3138
(i >= 'a' && i <= 'z') ||
3239
(i >= '0' && i <= '9') ||
3340
i == '-' ||
@@ -36,7 +43,7 @@ func NewDefaultSigner(config *Config) Signer {
3643
i == '~'
3744
}
3845

39-
return &DefaultSigner{config: config}
46+
return ds
4047
}
4148

4249
func (d *DefaultSigner) Sign(req *http.Request) error {
@@ -59,7 +66,7 @@ func (d *DefaultSigner) Sign(req *http.Request) error {
5966
canonicalQueryString := getCanonicalQueryString(req.URL)
6067
canonicalReq := buildCanonicalString(
6168
req.Method,
62-
getCanonicalURI(req.URL),
69+
getCanonicalURI(req.URL, d.noEscape),
6370
canonicalQueryString,
6471
canonicalHeaderStr,
6572
signedHeadersStr,
@@ -136,6 +143,7 @@ var ignoredHeaders = map[string]struct{}{
136143
"Expect": struct{}{},
137144
}
138145

146+
// buildCanonicalHeaders is mostly ported from https://github.com/aws/aws-sdk-go-v2/aws/signer/v4 buildCanonicalHeaders
139147
func buildCanonicalHeaders(req *http.Request) (signed http.Header, signedHeaders, canonicalHeadersStr string) {
140148
host, header, length := req.Host, req.Header, req.ContentLength
141149

@@ -203,8 +211,8 @@ func buildCanonicalHeaders(req *http.Request) (signed http.Header, signedHeaders
203211
return signed, signedHeaders, canonicalHeadersStr
204212
}
205213

206-
func getCanonicalURI(u *url.URL) string {
207-
return escapePath(getURIPath(u), false)
214+
func getCanonicalURI(u *url.URL, noEscape [256]bool) string {
215+
return escapePath(getURIPath(u), false, noEscape)
208216
}
209217

210218
func getCanonicalQueryString(u *url.URL) string {

pkg/sigv4/tripper.go

+14-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package sigv4
33
import (
44
"errors"
55
"net/http"
6+
"strings"
67
)
78

89
type Tripper struct {
@@ -22,10 +23,22 @@ func NewRoundTripper(config *Config, next http.RoundTripper) (*Tripper, error) {
2223
return nil, errors.New("can't initialize a sigv4 round tripper with nil config")
2324
}
2425

26+
if len(strings.TrimSpace(config.Region)) == 0 {
27+
return nil, errors.New("sigV4 config `Region` must be set")
28+
}
29+
30+
if len(strings.TrimSpace(config.AwsSecretAccessKey)) == 0 {
31+
return nil, errors.New("sigV4 config `AwsSecretAccessKey` must be set")
32+
}
33+
34+
if len(strings.TrimSpace(config.AwsAccessKeyID)) == 0 {
35+
return nil, errors.New("sigV4 config `AwsAccessKeyID` must be set")
36+
}
37+
2538
if next == nil {
2639
next = http.DefaultTransport
2740
}
28-
41+
2942
tripper := &Tripper{
3043
config: config,
3144
next: next,

pkg/sigv4/utils.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ import (
77
"strings"
88
)
99

10-
var noEscape [256]bool
11-
1210
// escapePath escapes part of a URL path in Amazon style.
13-
func escapePath(path string, encodeSep bool) string {
11+
// inspired by github.com/aws/smithy-go/encoding/httpbinding EscapePath method
12+
func escapePath(path string, encodeSep bool, noEscape [256]bool) string {
1413
var buf bytes.Buffer
1514
for i := 0; i < len(path); i++ {
1615
c := path[i]
@@ -25,6 +24,7 @@ func escapePath(path string, encodeSep bool) string {
2524

2625
// stripExcessSpaces will rewrite the passed in slice's string values to not
2726
// contain multiple side-by-side spaces.
27+
// Ported from github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4 StripExcessSpaces
2828
func stripExcessSpaces(str string) string {
2929
const doubleSpace = " "
3030

@@ -65,6 +65,7 @@ func stripExcessSpaces(str string) string {
6565
}
6666

6767
// getURIPath returns the escaped URI component from the provided URL.
68+
// Ported from github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4 GetURIPath
6869
func getURIPath(u *url.URL) string {
6970
var uriPath string
7071

0 commit comments

Comments
 (0)