1 回答
TA贡献1909条经验 获得超7个赞
最后,我得到了一种方法,通过使用 AWS 开发工具包构建请求并使用未签名的有效负载对其进行签名,通过流处理反向代理传入的 UploadPart。
下面是一个基本示例:
type AwsService struct {
Region string
S3Client s3iface.S3API
Signer *v4.Signer
}
func NewAwsService(region string, accessKey string, secretKey string, sessionToken string) (*AwsService, error) {
creds := credentials.NewStaticCredentials(accessKey, secretKey, sessionToken)
awsConfig := aws.NewConfig().
WithRegion(region).
WithCredentials(creds).
WithCredentialsChainVerboseErrors(true)
sess, err := session.NewSession(awsConfig)
if err != nil {
return nil, err
}
svc := s3.New(sess)
signer := v4.NewSigner(creds)
v4.WithUnsignedPayload(signer)
return &AwsService{
Region: region,
S3Client: svc,
Signer: signer,
}, nil
}
func (s *AwsService) UploadPart(bucket string, key string, part int, uploadID string, payloadReader io.Reader, contentLength int64) (string, error) {
input := &s3.UploadPartInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
UploadId: aws.String(uploadID),
PartNumber: aws.Int64(int64(part)),
ContentLength: aws.Int64(contentLength),
Body: aws.ReadSeekCloser(payloadReader),
}
req, output := s.S3Client.UploadPartRequest(input)
_, err := s.Signer.Sign(req.HTTPRequest, req.Body, s3.ServiceName, s.Region, time.Now())
err = req.Send()
if err != nil {
return "", err
}
return *output.ETag, nil
}
然后,可以从处理程序调用它:
func HandleUploadPart(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
region := query.Get("region")
bucket := query.Get("bucket")
key := query.Get("key")
part, err := strconv.Atoi(query.Get("part"))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
uploadID := query.Get("upload-id")
payloadReader := r.Body
contentLength, err := strconv.ParseInt(r.Header.Get("Content-Length"), 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
etag, err := awsService.UploadPart(region, bucket, key, part, uploadID, payloadReader, contentLength)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("ETag", etag)
}
缺点:
客户端必须提前知道内容长度并发送。
无法对有效负载进行签名。
- 1 回答
- 0 关注
- 212 浏览
添加回答
举报