【解决了一个小问题】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. 希望对其他人有用。

posted on 2024-09-25 18:45  ahfuzhang  阅读(35)  评论(0编辑  收藏  举报