【解决了一个小问题】aws s3 sdk 中的自定义header设置哪些不参与aws v4 签名
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!
在通过代理访问 s3 服务端的时候,s3 服务端返回类似的错误信息:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Error><Code>AuthorizationQueryParametersError</Code><RequestId>c28ddaf3c273308066f3c273-a6a4663</RequestId><HostId>RRHYUYpDsFKJfyJhAcRMVmMCHGnSHjcN</HostId><Message>no signed header: x-xxxx</Message></Error>
说明签名中使用了 header x-xxxx
, 但是实际传输的过程中又没有带上对应 header。
那么,aws s3 sdk 的 client 中,如何才能让某些header参与签名计算,而不让某些header参与签名计算呢?
下面是我找到的解决办法:
cli, err := s3Endpoint.NewClient()
if err != nil {
log.Fatal(err)
}
input := &s3.GetObjectInput{ // 从 s3 查询
Bucket: aws.String(*bucket),
Key: aws.String(*file),
}
req, output := cli.GetObjectRequest(input)
// 签名前移除自定义 header
req.Handlers.Sign.PushFront(func(r *request.Request) {
for k := range s3Endpoint.Headers {
r.HTTPRequest.Header.Del(k)
}
})
// 签名后再添加自定义 header
req.Handlers.Send.PushFront(func(r *request.Request) {
for k, v := range s3Endpoint.Headers {
r.HTTPRequest.Header.Set(k, v)
}
})
//
err = req.Send()
if err != nil {
log.Fatalf("cfg=%+v, err=%s", s3Endpoint, err.Error())
}
defer output.Body.Close()
if output.ContentLength == nil {
output.ContentLength = aws.Int64(0)
}
str := strings.Builder{}
str.Grow(1024 * 4)
str.WriteString(fmt.Sprintf("LastModified: %s\n", output.LastModified.String()))
核心是这两行:
- req.Handlers.Sign.PushFront() 签名之前干点啥
- req.Handlers.Send.PushFront() 发送之前干点啥
The End. 希望对其他人有用。