aboutsummaryrefslogtreecommitdiff
path: root/weed/s3api/s3_sse_c.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/s3api/s3_sse_c.go')
-rw-r--r--weed/s3api/s3_sse_c.go25
1 files changed, 24 insertions, 1 deletions
diff --git a/weed/s3api/s3_sse_c.go b/weed/s3api/s3_sse_c.go
index 733ae764e..3394a3ba6 100644
--- a/weed/s3api/s3_sse_c.go
+++ b/weed/s3api/s3_sse_c.go
@@ -16,6 +16,20 @@ import (
"github.com/seaweedfs/seaweedfs/weed/s3api/s3err"
)
+// decryptReaderCloser wraps a cipher.StreamReader with proper Close() support
+// This ensures the underlying io.ReadCloser (like http.Response.Body) is properly closed
+type decryptReaderCloser struct {
+ io.Reader
+ underlyingCloser io.Closer
+}
+
+func (d *decryptReaderCloser) Close() error {
+ if d.underlyingCloser != nil {
+ return d.underlyingCloser.Close()
+ }
+ return nil
+}
+
// SSECCopyStrategy represents different strategies for copying SSE-C objects
type SSECCopyStrategy int
@@ -197,8 +211,17 @@ func CreateSSECDecryptedReader(r io.Reader, customerKey *SSECustomerKey, iv []by
// Create CTR mode cipher using the IV from metadata
stream := cipher.NewCTR(block, iv)
+ decryptReader := &cipher.StreamReader{S: stream, R: r}
+
+ // Wrap with closer if the underlying reader implements io.Closer
+ if closer, ok := r.(io.Closer); ok {
+ return &decryptReaderCloser{
+ Reader: decryptReader,
+ underlyingCloser: closer,
+ }, nil
+ }
- return &cipher.StreamReader{S: stream, R: r}, nil
+ return decryptReader, nil
}
// CreateSSECEncryptedReaderWithOffset creates an encrypted reader with a specific counter offset