|
7 | 7 | "io"
|
8 | 8 | "os"
|
9 | 9 | "path/filepath"
|
| 10 | + "strings" |
10 | 11 |
|
11 | 12 | "github.com/aws/aws-sdk-go/aws"
|
12 | 13 | "github.com/aws/aws-sdk-go/aws/awserr"
|
@@ -41,16 +42,18 @@ const (
|
41 | 42 | ConfigKeyCacheControl = "cache_control" // defaults to ""
|
42 | 43 | ConfigKeyContentType = "content_type" // defaults to "application/vnd.mapbox-vector-tile"
|
43 | 44 | ConfigKeyS3ForcePath = "force_path_style"
|
| 45 | + ConfigKeyReqSigningHost = "req_signing_host" |
44 | 46 | )
|
45 | 47 |
|
46 | 48 | const (
|
47 |
| - DefaultBasepath = "" |
48 |
| - DefaultRegion = "us-east-1" |
49 |
| - DefaultAccessKey = "" |
50 |
| - DefaultSecretKey = "" |
51 |
| - DefaultContentType = mvt.MimeType |
52 |
| - DefaultEndpoint = "" |
53 |
| - DefaultS3ForcePath = false |
| 49 | + DefaultBasepath = "" |
| 50 | + DefaultRegion = "us-east-1" |
| 51 | + DefaultAccessKey = "" |
| 52 | + DefaultSecretKey = "" |
| 53 | + DefaultContentType = mvt.MimeType |
| 54 | + DefaultEndpoint = "" |
| 55 | + DefaultS3ForcePath = false |
| 56 | + DefaultReqSigningHost = "" |
54 | 57 | )
|
55 | 58 |
|
56 | 59 | // testData is used during New() to confirm the ability to write, read and purge the cache
|
@@ -141,6 +144,19 @@ func New(config dict.Dicter) (cache.Interface, error) {
|
141 | 144 | return nil, err
|
142 | 145 | }
|
143 | 146 |
|
| 147 | + // If a Proxy/Sidecar/etc.. is used, the Host header needs to |
| 148 | + // be fixed to allow Request Signing to work. |
| 149 | + // More info: https://github.com/aws/aws-sdk-go/issues/1473 |
| 150 | + reqSigningHost := DefaultReqSigningHost |
| 151 | + reqSigningHost, err = config.String(ConfigKeyReqSigningHost, &reqSigningHost) |
| 152 | + if err != nil { |
| 153 | + return nil, err |
| 154 | + } |
| 155 | + |
| 156 | + if reqSigningHost != "" && endpoint == "" { |
| 157 | + return nil, errors.New("The endpoint needs to be set if req_signing_host is set.") |
| 158 | + } |
| 159 | + |
144 | 160 | // support for static credentials, this is not recommended by AWS but
|
145 | 161 | // necessary for some environments
|
146 | 162 | if accessKey != "" && secretKey != "" {
|
@@ -170,6 +186,23 @@ func New(config dict.Dicter) (cache.Interface, error) {
|
170 | 186 | }
|
171 | 187 | s3cache.Client = s3.New(sess)
|
172 | 188 |
|
| 189 | + // If req_signing_host is set, then the HTTP host header needs to be updated |
| 190 | + // for signing, but replaced with the original value before connecting |
| 191 | + // to the endpoint. |
| 192 | + // The code is inspired by |
| 193 | + // https://github.com/aws/aws-sdk-go/issues/1473#issuecomment-325509965 |
| 194 | + if reqSigningHost != "" { |
| 195 | + s3cache.Client.Handlers.Sign.PushFront(func(r *request.Request) { |
| 196 | + r.HTTPRequest.URL.Host = reqSigningHost |
| 197 | + }) |
| 198 | + s3cache.Client.Handlers.Sign.PushBack(func(r *request.Request) { |
| 199 | + // If the endpoint variable contains the http(s) protocol prefix, |
| 200 | + // we need to sanitize it before adding it back. |
| 201 | + endpoint = strings.TrimPrefix(strings.TrimPrefix(endpoint, "http://"), "https://") |
| 202 | + r.HTTPRequest.URL.Host = endpoint |
| 203 | + }) |
| 204 | + } |
| 205 | + |
173 | 206 | // check for control_access_list env var
|
174 | 207 | acl := os.Getenv("AWS_ACL")
|
175 | 208 | acl, err = config.String(ConfigKeyACL, &acl)
|
|
0 commit comments