Repository: minio/minio (language: go)

Issue:
with mincache enabled `HEAD` request returns different `Content-Length` then matching `GET` on a KMS setup
I have enabled server-side encryption on my bucket and uploaded `Audi cabriolet 01.jpg` of 2,971,514 bytes to the `test` bucket. When I try to copy the file using `mc`, then I got the following error: `Input reader closed pre-maturely. Expected '2972986' bytes, but only received '2971514' bytes.`

I ran the `mc` command using the `--debug` flag and noticed that the `HEAD` request returns a different length then the `GET` request. This is the `HEAD` request:
```
HEAD /test/audi/Audi%20cabriolet%2001.jpg HTTP/1.1
Host: tenant-rdk-hl.tenant-rdk:9000
User-Agent: MinIO (linux; amd64) minio-go/v7.0.70 __debug_bin2996553503/DEVELOPMENT.GOGET
Authorization: AWS4-HMAC-SHA256 Credential=l5m7mQiwUi2GCSH3/20240612/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=**REDACTED**
X-Amz-Content-Sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
X-Amz-Date: 20240612T160723Z
```
`HEAD` response:
```
HTTP/1.1 200 OK
Content-Length: 2972986
Accept-Ranges: bytes
Content-Type: image/jpeg
Date: Wed, 12 Jun 2024 16:07:23 GMT
Etag: "efd738945e94f4dbb8588b788b2ea7c1"
Last-Modified: Wed, 12 Jun 2024 15:21:24 GMT
Server: MinIO
Strict-Transport-Security: max-age=31536000; includeSubDomains
Vary: Origin
Vary: Accept-Encoding
X-Amz-Id-2: d5a265f7265c149d31b79b2568737f9e0d97aab546838b9090d7403265887733
X-Amz-Request-Id: 17D84D79C009F04A
X-Content-Type-Options: nosniff
X-Xss-Protection: 1; mode=block
```
Then it performs the actual `GET` and that request looks like:
```
GET /test/audi/Audi%20cabriolet%2001.jpg HTTP/1.1
Host: tenant-rdk-hl.tenant-rdk:9000
User-Agent: MinIO (linux; amd64) minio-go/v7.0.70 __debug_bin2996553503/DEVELOPMENT.GOGET
Accept-Encoding: identity
Authorization: AWS4-HMAC-SHA256 Credential=l5m7mQiwUi2GCSH3/20240612/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=**REDACTED**
X-Amz-Content-Sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
X-Amz-Date: 20240612T160904Z
```
And the response is:
```
HTTP/1.1 200 OK
Content-Length: 2971514
Accept-Ranges: bytes
Content-Type: image/jpeg
Date: Wed, 12 Jun 2024 16:09:04 GMT
Etag: "efd738945e94f4dbb8588b788b2ea7c1"
Last-Modified: Wed, 12 Jun 2024 15:21:24 GMT
Server: MinIO
Strict-Transport-Security: max-age=31536000; includeSubDomains
Vary: Origin
Vary: Accept-Encoding
X-Amz-Id-2: d5a265f7265c149d31b79b2568737f9e0d97aab546838b9090d7403265887733
X-Amz-Request-Id: 17D84D916E7CC820
X-Amz-Server-Side-Encryption: aws:kms
X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id: arn:aws:kms:tenant-rdk-key
X-Content-Type-Options: nosniff
X-Xss-Protection: 1; mode=block
```
This seems to be a bug in Minio, because both the `HEAD` and `GET` requests should return the same content length. I never have seen this issue without encryption.



Discussion / hints:
There is a cache in-between `mc` and Minio. Disabling the cache fixes the issue and Minio does return the proper content-size and encryption headers.
You have uploaded different size at the same object. 
```
root@DESKTOP-QPDA04R:/mnt/c/workspace/go/src/minkms/dist# mc cp minio9000/mytest/dlv.exe dlv.exe 
mc: <ERROR> Failed to copy `http://192.168.2.6:9000/mytest/dlv.exe`. Input reader closed pre-maturely. Expected `19311104` bytes, but only received `10248344` bytes.
root@DESKTOP-QPDA04R:/mnt/c/workspace/go/src/minkms/dist# 
```
No @jiuker you are not understanding the issue. Please DM me.
Restarting mincache will fix the problem? @ramondeklein 

Fix patch:
diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go
index 4f6b5143ffe33..e0100249c1ccb 100644
--- a/cmd/object-handlers.go
+++ b/cmd/object-handlers.go
@@ -959,7 +959,6 @@ func (api objectAPIHandlers) headObjectHandler(ctx context.Context, objectAPI Ob
 		// No need to check cache for encrypted objects.
 		cachedResult = false
 	}
-	var update bool
 	if cachedResult {
 		rc := &cache.CondCheck{}
 		h := r.Header.Clone()
@@ -968,7 +967,7 @@ func (api objectAPIHandlers) headObjectHandler(ctx context.Context, objectAPI Ob
 		}
 		rc.Init(bucket, object, h)
 
-		ci, err := globalCacheConfig.Get(rc)
+		ci, _ := globalCacheConfig.Get(rc)
 		if ci != nil {
 			tgs, ok := ci.Metadata[xhttp.AmzObjectTagging]
 			if ok {
@@ -1027,9 +1026,6 @@ func (api objectAPIHandlers) headObjectHandler(ctx context.Context, objectAPI Ob
 				return
 			}
 		}
-		if errors.Is(err, cache.ErrKeyMissing) {
-			update = true
-		}
 	}
 
 	opts.FastGetObjInfo = true
@@ -1053,10 +1049,6 @@ func (api objectAPIHandlers) headObjectHandler(ctx context.Context, objectAPI Ob
 			}
 		}
 	}
-	if _, ok := crypto.IsEncrypted(objInfo.UserDefined); ok {
-		// Never store encrypted objects in cache.
-		update = false
-	}
 
 	if objInfo.UserTags != "" {
 		// Set this such that authorization policies can be applied on the object tags.
@@ -1137,24 +1129,6 @@ func (api objectAPIHandlers) headObjectHandler(ctx context.Context, objectAPI Ob
 		return
 	}
 
-	if update {
-		asize, err := objInfo.GetActualSize()
-		if err != nil {
-			asize = objInfo.Size
-		}
-
-		defer globalCacheConfig.Set(&cache.ObjectInfo{
-			Key:          objInfo.Name,
-			Bucket:       objInfo.Bucket,
-			ETag:         objInfo.ETag,
-			ModTime:      objInfo.ModTime,
-			Expires:      objInfo.ExpiresStr(),
-			CacheControl: objInfo.CacheControl,
-			Size:         asize,
-			Metadata:     cleanReservedKeys(objInfo.UserDefined),
-		})
-	}
-
 	// Validate pre-conditions if any.
 	if checkPreconditions(ctx, w, r, objInfo, opts) {
 		return


Test patch: