Skip to content

Commit

Permalink
Set Content-Digest header when uploading droplets
Browse files Browse the repository at this point in the history
Signed-off-by: Maria Shaldybin <maria.shaldybin@broadcom.com>
  • Loading branch information
dsabeti authored and mariash committed Jan 24, 2024
1 parent 7d84fd3 commit 2b9c1fb
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
27 changes: 17 additions & 10 deletions depot/uploader/uploader.go
Expand Up @@ -2,6 +2,7 @@ package uploader

import (
"crypto/md5"
"crypto/sha256"
"crypto/tls"
"encoding/base64"
"errors"
Expand Down Expand Up @@ -57,7 +58,7 @@ func New(logger lager.Logger, timeout time.Duration, tlsConfig *tls.Config) Uplo
func (uploader *URLUploader) Upload(fileLocation string, url *url.URL, cancel <-chan struct{}) (int64, error) {
logger := uploader.logger.WithData(lager.Data{"fileLocation": fileLocation})

sourceFile, bytesToUpload, contentMD5, err := uploader.prepareFileForUpload(fileLocation, logger)
sourceFile, bytesToUpload, contentMD5, contentSHA256, err := uploader.prepareFileForUpload(fileLocation, logger)
if err != nil {
return 0, err
}
Expand All @@ -71,6 +72,7 @@ UPLOAD_ATTEMPTS:
sourceFile,
bytesToUpload,
contentMD5,
contentSHA256,
url.String(),
cancel,
logger,
Expand All @@ -95,35 +97,39 @@ UPLOAD_ATTEMPTS:
return int64(bytesToUpload), nil
}

func (uploader *URLUploader) prepareFileForUpload(fileLocation string, logger lager.Logger) (*os.File, int64, string, error) {
func (uploader *URLUploader) prepareFileForUpload(fileLocation string, logger lager.Logger) (*os.File, int64, string, string, error) {
sourceFile, err := os.Open(fileLocation)
if err != nil {
logger.Error("failed-open", err)
return nil, 0, "", err
return nil, 0, "", "", err
}

fileInfo, err := sourceFile.Stat()
if err != nil {
logger.Error("failed-stat", err)
return nil, 0, "", err
return nil, 0, "", "", err
}

contentHash := md5.New()
_, err = io.Copy(contentHash, sourceFile)
contents, err := io.ReadAll(sourceFile)
if err != nil {
logger.Error("failed-copy", err)
return nil, 0, "", err
logger.Error("failed-read", err)
return nil, 0, "", "", err
}

contentMD5 := base64.StdEncoding.EncodeToString(contentHash.Sum(nil))
md5Checksum := md5.Sum(contents)
sha256Checksum := sha256.Sum256(contents)

return sourceFile, fileInfo.Size(), contentMD5, nil
contentMD5 := base64.StdEncoding.EncodeToString(md5Checksum[:])
contentSHA256 := base64.StdEncoding.EncodeToString(sha256Checksum[:])

return sourceFile, fileInfo.Size(), contentMD5, contentSHA256, nil
}

func (uploader *URLUploader) attemptUpload(
sourceFile *os.File,
bytesToUpload int64,
contentMD5 string,
contentSHA256 string,
url string,
cancelCh <-chan struct{},
logger lager.Logger,
Expand All @@ -143,6 +149,7 @@ func (uploader *URLUploader) attemptUpload(
request.ContentLength = bytesToUpload
request.Header.Set("Content-Type", "application/octet-stream")
request.Header.Set("Content-MD5", contentMD5)
request.Header.Set("Content-Digest", fmt.Sprintf("sha-256=:%s:", contentSHA256))

var resp *http.Response
reqComplete := make(chan error)
Expand Down
7 changes: 6 additions & 1 deletion depot/uploader/uploader_test.go
Expand Up @@ -2,6 +2,7 @@ package uploader_test

import (
"crypto/md5"
"crypto/sha256"
"crypto/tls"
"encoding/base64"
"fmt"
Expand Down Expand Up @@ -35,6 +36,7 @@ var _ = Describe("Uploader", func() {
file *os.File
expectedBytes int
expectedMD5 string
expectedSHA256 string
defaultTimeout time.Duration
)

Expand All @@ -49,6 +51,8 @@ var _ = Describe("Uploader", func() {
expectedBytes, _ = file.WriteString(contentString)
rawMD5 := md5.Sum([]byte(contentString))
expectedMD5 = base64.StdEncoding.EncodeToString(rawMD5[:])
rawSHA256 := sha256.Sum256([]byte(contentString))
expectedSHA256 = base64.StdEncoding.EncodeToString(rawSHA256[:])
file.Close()
defaultTimeout = 500 * time.Millisecond
})
Expand Down Expand Up @@ -88,7 +92,7 @@ var _ = Describe("Uploader", func() {
numBytes, err = upldr.Upload(file.Name(), url, nil)
})

It("uploads the file to the url", func() {
It("uploads the file to the url providing Content-MD5 and Content-Digest headers", func() {
Expect(len(serverRequests)).To(Equal(1))

request := serverRequests[0]
Expand All @@ -97,6 +101,7 @@ var _ = Describe("Uploader", func() {
Expect(request.URL.Path).To(Equal("/somepath"))
Expect(request.Header.Get("Content-Type")).To(Equal("application/octet-stream"))
Expect(request.Header.Get("Content-MD5")).To(Equal(expectedMD5))
Expect(request.Header.Get("Content-Digest")).To(Equal(fmt.Sprintf("sha-256=:%s:", expectedSHA256)))
Expect(strconv.Atoi(request.Header.Get("Content-Length"))).To(BeNumerically("==", 31))
Expect(string(data)).To(Equal("content that we can check later"))
})
Expand Down

0 comments on commit 2b9c1fb

Please sign in to comment.