fix: send the SSE-KMS context as a JSON object on federated copies

putOptsFromReq handed the parsed kms.Context straight to
encrypt.NewSSEKMS. kms.Context implements encoding.TextMarshaler, so the
SDK serialized it as a JSON string, and a request without a context
still produced one because the nil Context is a typed nil inside the
interface value and marshals to "{}". The receiving ParseHTTP rejects
both forms, so every federated CopyObject to an SSE-KMS destination
failed with InvalidArgument once the forwarded stream was correct.

Pass a plain map, or nothing when no context was requested, and cover
SSE-KMS destinations with and without an explicit context.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FodsDpa6VkghaeRE6WjmEe
Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
Feng Ruohang
2026-09-09 17:35:50 +08:00
parent af56d17630
commit cfefc049c1
2 changed files with 25 additions and 10 deletions
+10 -1
View File
@@ -433,7 +433,16 @@ func putOptsFromHeaders(ctx context.Context, hdr http.Header, metadata map[strin
if err != nil {
return ObjectOptions{}, err
}
sseKms, err := encrypt.NewSSEKMS(keyID, context)
// kms.Context implements encoding.TextMarshaler, so handing it to the
// SDK's interface{} parameter would serialize the context as a JSON
// string, which the receiving ParseHTTP rejects; a nil Context is a
// typed nil there and would be sent as "{}". Pass a plain map, or
// nothing when no context was requested.
var sdkContext any
if context != nil {
sdkContext = map[string]string(context)
}
sseKms, err := encrypt.NewSSEKMS(keyID, sdkContext)
if err != nil {
return ObjectOptions{}, err
}