Browse Source
S3: fix silent PutObject failure and enforce 1024-byte key limit (#8764)
S3: fix silent PutObject failure and enforce 1024-byte key limit (#8764)
* S3: add KeyTooLongError error code Add ErrKeyTooLongError (HTTP 400, code "KeyTooLongError") to match the standard AWS S3 error for object keys that exceed length limits. * S3: fix silent PutObject failure when entry name exceeds max_file_name_length putToFiler called client.CreateEntry() directly and discarded the gRPC response. The filer embeds application errors like "entry name too long" in resp.Error (not as gRPC transport errors), so the error was silently swallowed and clients received HTTP 200 with an ETag for objects that were never stored. Switch to the filer_pb.CreateEntry() helper which properly checks resp.Error, and map "entry name too long" to KeyTooLongError (HTTP 400). To avoid fragile string parsing across the gRPC boundary, define shared error message constants in weed/util/constants and use them in both the filer (producing errors) and S3 API (matching errors). Switch filerErrorToS3Error to use strings.Contains/HasSuffix with these constants so matches work regardless of any wrapper prefix. Apply filerErrorToS3Error to the mkdir path for directory markers. Fixes #8759 * S3: enforce 1024-byte maximum object key length AWS S3 limits object keys to 1024 bytes. Add early validation on write paths (PutObject, CopyObject, CreateMultipartUpload) to reject keys exceeding the limit with the standard KeyTooLongError (HTTP 400). The key length check runs before bucket auto-creation to prevent overlong keys from triggering unnecessary side effects. Also use filerErrorToS3Error for CopyObject's mkFile error paths so name-too-long errors from the filer return KeyTooLongError instead of InternalError. Ref #8758 * S3: add handler-level tests for key length validation and error mapping Add tests for filerErrorToS3Error mapping "entry name too long" to KeyTooLongError, including a regression test for the CreateEntry-prefixed "existing ... is a directory" form. Add handler-level integration tests that exercise PutObjectHandler, CopyObjectHandler, and NewMultipartUploadHandler via httptest, verifying HTTP 400 and KeyTooLongError XML response for overlong keys and acceptance of keys at the 1024-byte limit.pull/8765/head
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 177 additions and 17 deletions
-
9weed/filer/filer.go
-
5weed/s3api/s3_constants/header.go
-
8weed/s3api/s3api_object_handlers_copy.go
-
5weed/s3api/s3api_object_handlers_multipart.go
-
22weed/s3api/s3api_object_handlers_put.go
-
126weed/s3api/s3api_object_handlers_put_test.go
-
9weed/s3api/s3err/s3api_errors.go
-
10weed/util/constants/filer.go
@ -1,7 +1,15 @@ |
|||
package constants |
|||
|
|||
// Filer error messages
|
|||
// Filer error messages — shared between filer (producing) and S3 API (matching).
|
|||
// These cross a gRPC boundary as strings in CreateEntryResponse.Error, so typed
|
|||
// errors cannot be used. Keeping the strings in one place prevents mismatches.
|
|||
const ( |
|||
ErrMsgOperationNotPermitted = "operation not permitted" |
|||
ErrMsgBadDigest = "The Content-Md5 you specified did not match what we received." |
|||
ErrMsgEntryNameTooLong = "entry name too long" |
|||
// Suffix appended to a path, e.g. "/buckets/b/foo/bar is a file"
|
|||
ErrMsgIsAFile = " is a file" |
|||
// Prefix + suffix, e.g. "existing /buckets/b/foo is a directory"
|
|||
ErrMsgExistingPrefix = "existing " |
|||
ErrMsgIsADirectory = " is a directory" |
|||
) |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue