Skip to content

Commit

Permalink
allow disabling sha256 completely for PUT requests (#1668)
Browse files Browse the repository at this point in the history
  • Loading branch information
harshavardhana committed Jun 23, 2022
1 parent cd2a9ac commit 40b13d9
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 10 deletions.
9 changes: 6 additions & 3 deletions api-put-object-multipart.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (c *Client) putObjectMultipartNoStream(ctx context.Context, bucketName, obj
// Choose hash algorithms to be calculated by hashCopyN,
// avoid sha256 with non-v4 signature request or
// HTTPS connection.
hashAlgos, hashSums := c.hashMaterials(opts.SendContentMd5)
hashAlgos, hashSums := c.hashMaterials(opts.SendContentMd5, !opts.DisableContentSha256)

length, rErr := readFull(reader, buf)
if rErr == io.EOF && partNumber > 1 {
Expand Down Expand Up @@ -140,7 +140,9 @@ func (c *Client) putObjectMultipartNoStream(ctx context.Context, bucketName, obj

// Proceed to upload the part.
objPart, uerr := c.uploadPart(ctx, bucketName, objectName, uploadID, rd, partNumber,
md5Base64, sha256Hex, int64(length), opts.ServerSideEncryption)
md5Base64, sha256Hex, int64(length),
opts.ServerSideEncryption,
!opts.DisableContentSha256)
if uerr != nil {
return UploadInfo{}, uerr
}
Expand Down Expand Up @@ -241,7 +243,7 @@ func (c *Client) initiateMultipartUpload(ctx context.Context, bucketName, object

// uploadPart - Uploads a part in a multipart upload.
func (c *Client) uploadPart(ctx context.Context, bucketName, objectName, uploadID string, reader io.Reader,
partNumber int, md5Base64, sha256Hex string, size int64, sse encrypt.ServerSide,
partNumber int, md5Base64, sha256Hex string, size int64, sse encrypt.ServerSide, streamSha256 bool,
) (ObjectPart, error) {
// Input validation.
if err := s3utils.CheckValidBucketName(bucketName); err != nil {
Expand Down Expand Up @@ -289,6 +291,7 @@ func (c *Client) uploadPart(ctx context.Context, bucketName, objectName, uploadI
contentLength: size,
contentMD5Base64: md5Base64,
contentSHA256Hex: sha256Hex,
streamSha256: streamSha256,
}

// Execute PUT on each part.
Expand Down
11 changes: 9 additions & 2 deletions api-put-object-streaming.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,10 @@ func (c *Client) putObjectMultipartStreamFromReadAt(ctx context.Context, bucketN
// Proceed to upload the part.
objPart, err := c.uploadPart(ctx, bucketName, objectName,
uploadID, hookReader, uploadReq.PartNum,
"", "", partSize, opts.ServerSideEncryption)
"", "", partSize,
opts.ServerSideEncryption,
!opts.DisableContentSha256,
)
if err != nil {
uploadedPartsCh <- uploadedPartRes{
Error: err,
Expand Down Expand Up @@ -322,7 +325,10 @@ func (c *Client) putObjectMultipartStreamOptionalChecksum(ctx context.Context, b

objPart, uerr := c.uploadPart(ctx, bucketName, objectName, uploadID,
io.LimitReader(hookReader, partSize),
partNumber, md5Base64, "", partSize, opts.ServerSideEncryption)
partNumber, md5Base64, "", partSize,
opts.ServerSideEncryption,
!opts.DisableContentSha256,
)
if uerr != nil {
return UploadInfo{}, uerr
}
Expand Down Expand Up @@ -452,6 +458,7 @@ func (c *Client) putObjectDo(ctx context.Context, bucketName, objectName string,
contentLength: size,
contentMD5Base64: md5Base64,
contentSHA256Hex: sha256Hex,
streamSha256: !opts.DisableContentSha256,
}
if opts.Internal.SourceVersionID != "" {
if opts.Internal.SourceVersionID != nullVersionID {
Expand Down
6 changes: 5 additions & 1 deletion api-put-object.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type PutObjectOptions struct {
PartSize uint64
LegalHold LegalHoldStatus
SendContentMd5 bool
DisableContentSha256 bool
DisableMultipart bool
Internal AdvancedPutOptions
}
Expand Down Expand Up @@ -344,7 +345,10 @@ func (c *Client) putObjectMultipartStreamNoLength(ctx context.Context, bucketNam

// Proceed to upload the part.
objPart, uerr := c.uploadPart(ctx, bucketName, objectName, uploadID, rd, partNumber,
md5Base64, "", int64(length), opts.ServerSideEncryption)
md5Base64, "", int64(length),
opts.ServerSideEncryption,
!opts.DisableContentSha256,
)
if uerr != nil {
return UploadInfo{}, uerr
}
Expand Down
9 changes: 6 additions & 3 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,14 +315,16 @@ func (c *Client) SetS3TransferAccelerate(accelerateEndpoint string) {
// - For signature v4 request if the connection is insecure compute only sha256.
// - For signature v4 request if the connection is secure compute only md5.
// - For anonymous request compute md5.
func (c *Client) hashMaterials(isMd5Requested bool) (hashAlgos map[string]md5simd.Hasher, hashSums map[string][]byte) {
func (c *Client) hashMaterials(isMd5Requested, isSha256Requested bool) (hashAlgos map[string]md5simd.Hasher, hashSums map[string][]byte) {
hashSums = make(map[string][]byte)
hashAlgos = make(map[string]md5simd.Hasher)
if c.overrideSignerType.IsV4() {
if c.secure {
hashAlgos["md5"] = c.md5Hasher()
} else {
hashAlgos["sha256"] = c.sha256Hasher()
if isSha256Requested {
hashAlgos["sha256"] = c.sha256Hasher()
}
}
} else {
if c.overrideSignerType.IsAnonymous() {
Expand Down Expand Up @@ -417,6 +419,7 @@ type requestMetadata struct {
contentLength int64
contentMD5Base64 string // carries base64 encoded md5sum
contentSHA256Hex string // carries hex encoded sha256sum
streamSha256 bool
}

// dumpHTTP - dump HTTP request and response.
Expand Down Expand Up @@ -812,7 +815,7 @@ func (c *Client) newRequest(ctx context.Context, method string, metadata request
case signerType.IsV2():
// Add signature version '2' authorization header.
req = signer.SignV2(*req, accessKeyID, secretAccessKey, isVirtualHost)
case metadata.objectName != "" && metadata.queryValues == nil && method == http.MethodPut && metadata.customHeader.Get("X-Amz-Copy-Source") == "" && !c.secure:
case metadata.streamSha256 && !c.secure:
// Streaming signature is used by default for a PUT object request. Additionally we also
// look if the initialized client is secure, if yes then we don't need to perform
// streaming signature.
Expand Down
3 changes: 2 additions & 1 deletion core.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ func (c Core) ListMultipartUploads(ctx context.Context, bucket, prefix, keyMarke

// PutObjectPart - Upload an object part.
func (c Core) PutObjectPart(ctx context.Context, bucket, object, uploadID string, partID int, data io.Reader, size int64, md5Base64, sha256Hex string, sse encrypt.ServerSide) (ObjectPart, error) {
return c.uploadPart(ctx, bucket, object, uploadID, data, partID, md5Base64, sha256Hex, size, sse)
streamSha256 := true
return c.uploadPart(ctx, bucket, object, uploadID, data, partID, md5Base64, sha256Hex, size, sse, streamSha256)
}

// ListObjectParts - List uploaded parts of an incomplete upload.x
Expand Down

0 comments on commit 40b13d9

Please sign in to comment.