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 關注
- 250 瀏覽
添加回答
舉報