content_md5.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. package checksum
  2. import (
  3. "crypto/md5"
  4. "encoding/base64"
  5. "fmt"
  6. "github.com/aws/aws-sdk-go/aws"
  7. "github.com/aws/aws-sdk-go/aws/awserr"
  8. "github.com/aws/aws-sdk-go/aws/request"
  9. )
  10. const contentMD5Header = "Content-Md5"
  11. // AddBodyContentMD5Handler computes and sets the HTTP Content-MD5 header for requests that
  12. // require it.
  13. func AddBodyContentMD5Handler(r *request.Request) {
  14. // if Content-MD5 header is already present, return
  15. if v := r.HTTPRequest.Header.Get(contentMD5Header); len(v) != 0 {
  16. return
  17. }
  18. // if S3DisableContentMD5Validation flag is set, return
  19. if aws.BoolValue(r.Config.S3DisableContentMD5Validation) {
  20. return
  21. }
  22. // if request is presigned, return
  23. if r.IsPresigned() {
  24. return
  25. }
  26. // if body is not seekable, return
  27. if !aws.IsReaderSeekable(r.Body) {
  28. if r.Config.Logger != nil {
  29. r.Config.Logger.Log(fmt.Sprintf(
  30. "Unable to compute Content-MD5 for unseekable body, S3.%s",
  31. r.Operation.Name))
  32. }
  33. return
  34. }
  35. h := md5.New()
  36. if _, err := aws.CopySeekableBody(h, r.Body); err != nil {
  37. r.Error = awserr.New("ContentMD5", "failed to compute body MD5", err)
  38. return
  39. }
  40. // encode the md5 checksum in base64 and set the request header.
  41. v := base64.StdEncoding.EncodeToString(h.Sum(nil))
  42. r.HTTPRequest.Header.Set(contentMD5Header, v)
  43. }