Commit Graph

581 Commits

Author SHA1 Message Date
Luke McCrone
4629eab44c test: add fix 2026-05-13 11:40:30 -03:00
Luke McCrone
aa3889ef87 test: fix imports 2026-05-12 19:16:53 -03:00
Luke McCrone
b607eff2f6 test: list buckets util cleanup 2026-05-12 19:16:53 -03:00
Luke McCrone
a69520c64e test: HeadObject query tests 2026-05-12 19:16:53 -03:00
Luke McCrone
9d42e918c8 test: temp 2026-05-12 19:16:53 -03:00
Luke McCrone
0907819121 test: temp 2026-05-12 19:16:53 -03:00
Luke McCrone
37d6ca03ed test: util code cleanup 2026-05-11 16:34:54 -03:00
Luke McCrone
6608c53612 test: DeleteObjects payload testing 2026-05-08 14:46:54 -03:00
Ben McClelland
12f3d3a1e2 Merge pull request #2117 from versity/test/dockerfile_prep
test: dockerfile, run script updates, README updates
2026-05-06 13:39:00 -07:00
Ben McClelland
c6e795f91f Merge pull request #2114 from versity/sis/unsupported-sigv2
fix: reject SigV2 requests
2026-05-06 13:38:14 -07:00
niksis02
e69d073273 fix: reject SigV2 requests
The gateway currently supports only Signature Version 4 (SigV4) authorization. Deprecated AWS SigV2 requests are now rejected with an AWS-specific `InvalidRequest` error for both Authorization-header requests and query-string requests(presigned URLs).

This also fixes SigV4 Authorization-header handling for date headers. SigV4 accepts two date headers: `Date` and `X-Amz-Date`. `X-Amz-Date` takes precedence, but when it is missing, `Date` should be used. The gateway now uses the `Date` header with lower precedence when `X-Amz-Date` is not present. No SDK integration test was added for this case because the SDK always sets `X-Amz-Date`, and this behavior is not configurable.
2026-05-06 23:43:10 +04:00
Luke McCrone
0136a0ba84 test: dockerfile, run script updates, README updates 2026-05-06 14:44:50 -03:00
Luke McCrone
317767b15b test: add test tags 2026-05-05 19:07:56 -03:00
Ben McClelland
21da1d7e70 Merge pull request #2097 from versity/dependabot/go_modules/dev-dependencies-3789651bc5
chore(deps): bump the dev-dependencies group with 7 updates
2026-05-04 16:24:32 -07:00
Ben McClelland
bb3cdd9cb6 fix: skip integration tests not compatible in sidecar
A few tests are not yet compatible with sidecar mode. Add a test
option to skip these when running sidecar tests.
2026-05-04 16:05:29 -07:00
niksis02
d2fa265fb8 feat: support sha512, md5, xxhash3, xxhash64, xxhash128 data integrity checksums
Integrate the new S3 checksum types in the gateway, including `SHA512`, `MD5`, `XXHASH64`, `XXHASH3`, and `XXHASH128`. This adds checksum calculation, validation, schema handling, and test coverage for the expanded checksum support.

These external packages have been used:
- `github.com/zeebo/xxh3` for `XXHASH3` and `XXHASH128`
- `github.com/cespare/xxhash/v2` for `XXHASH64`

Adjust integration tests because `aws-sdk-go-v2/service/s3` does not support automatic checksum calculation for the new checksum algorithms and returns an SDK-level error when only the checksum algorithm is provided. Only precalculated checksum values are acceptable for these checksum types.

References:
- `https://github.com/aws/aws-sdk-go-v2/issues/3404`
- `https://github.com/aws/aws-sdk-go-v2/issues/3403`
2026-05-04 08:50:39 -07:00
Luke McCrone
9a21c5a1e0 test: GetObject - add query tests, go/bats improved header/object reply handling 2026-04-28 21:10:09 -03:00
niksis02
8d5b2be0b2 fix: check PutObjectTagging/LegalHold/Retention permissions on PutObject,CopyObject and CreateMultipartUpload
Fixes #1986

When a client includes tagging, legal hold, or retention headers in a PutObject, CopyObject or CreateMultipartUpload request, the corresponding bucket policy permissions must be verified in addition to s3:PutObject:

`X-Amz-Tagging` - `s3:PutObjectTagging`
`X-Amz-Object-Lock-Legal-Hold` - `s3:PutObjectLegalHold`
`X-Amz-Object-Lock-Mode` - `s3:PutObjectRetention`

Previously, only s3:PutObject was checked, allowing users to set tagging, legal hold, and retention without having the required permissions. Now each action permission is check, if user tries to add them.

For CopyObject these permissions are checked on destination object.
2026-04-28 01:05:34 +04:00
alice nodelman
79d03b2cb4 Merge branch 'main' into test/bats_tagging 2026-04-22 15:00:49 -07:00
Ben McClelland
0767d87387 test: add github actions functional tests for posix sidecar option
Enough people are making use of sidecar that we need to add
a CI test to make sure we have some coverage with this mode.

This add a couple small functional test fixes found wtih
enabling sidecar tests as well.
2026-04-22 13:23:46 -07:00
Ben McClelland
db77882ec6 test: disable mc client tests from test matrix
The dl.min.io download site has been having stability issues
possibly related to github action runners getting rate limited.
Disable these for now until we can find a better place to host
this client.
2026-04-22 11:29:26 -07:00
Luke McCrone
29f378ea5e test: initial bats test tagging system, shellcheck fix 2026-04-21 18:48:40 -03:00
niksis02
d6fb9547b8 fix: correct 206 Partial Content response status for ranged GetObject and HeadObject
Fixes #2052
Fixes #2056
Fixes #2057

Previously, GetObject and HeadObject used the request's `Range` header to determine the response status code, which caused incorrect 206 responses for invalid Range header values.

The status is now driven by whether res.ContentRange is set in the response, rather than by the presence of a range in the request. Backends (posix and azure) now set Content-Range for PartNumber=1 on non-multipart objects, skipping zero-size objects where no range applies.

HeadObject was also fixed to return 206 when Content-Range is present, and to only return checksums when the full object is requested.
2026-04-21 02:13:04 +04:00
Ben McClelland
8533bc1b60 Merge pull request #2054 from versity/sis/racing-complete-mp
fix: make CompleteMultipartUpload idempotent and add part-number support to GetObject/HeadObject
2026-04-20 10:23:09 -07:00
niksis02
62e8cddbc7 fix: make CompleteMultipartUpload idempotent and add part-number support to GetObject/HeadObject
Closes #1064

Use the multipart ETag as the in-progress directory suffix instead of the static `.inprogress` marker so that concurrent CompleteMultipartUpload calls for the same upload ID are all treated as successful (idempotent) rather than racing, where only one succeeded and the rest returned NoSuchUpload.

After finalizing the multipart upload, store an `mp-metadata` xattr on the assembled object that records the upload ID and cumulative byte offsets for each part. GetObject and HeadObject now use this metadata to serve individual part ranges via the `partNumber` query parameter, returning a successful response instead of returning NotImplemented.

Add two new S3 error codes:
- `ErrInvalidPartNumberRange` (416 RequestedRangeNotSatisfiable) — returned
  when the requested part number exceeds the number of parts in the upload.
- `ErrRangeAndPartNumber` (400 BadRequest) — returned when both a Range header
  and a partNumber query parameter are specified on the same request.
2026-04-20 20:45:58 +04:00
niksis02
b905554e06 fix: fix azure multipart upload objects masking
As multipart uploads are translated to blobs in azure blob storage, they were visible in ListObjects(V2) as complete objects. Now the blobs with multipart prefix are filtered out during listing.

The listing logic is rewritten client-side to implement proper S3 semantics: flat blob enumeration with manual delimiter handling, correct truncation (IsTruncated only set when more items genuinely exist beyond maxKeys), and StartAfter/Marker/ContinuationToken applied via the lexicographic max of both constraints in ListObjectsV2.

For the same reason bucket deletion was not allowed. Now multipart objects are explicitly checked on bucket deletion and any pending multipart upload doesn't block the bucket deletion anymore.
2026-04-16 23:56:18 +04:00
Ben McClelland
6d3688adf9 Merge pull request #2013 from versity/test/rest_list_objects_v2_queries
Test/rest list objects v2 queries
2026-04-15 13:32:40 -07:00
Ben McClelland
2b918d585e chore: fix spellings and unused function args
No logic changes, just janitorial cleanup
2026-04-15 10:32:14 -07:00
Luke McCrone
1632c8c006 test: ListObjectsV2 query updates, file updates, bash cleanup 2026-04-14 18:50:10 -03:00
Ben McClelland
efd1885d21 Merge pull request #2023 from versity/sis/move-versionid-validation-backend
fix: move versionId validation to backend
2026-04-10 11:23:20 -07:00
Luke McCrone
d7d9179db0 test: ListObjectsV1 updates, file code changes, multipart updates 2026-04-07 15:24:20 -03:00
niksis02
b473aa0545 fix: move versionId validation to backend
Closes #1813

We use a specific `versionId` format(`ulid` package) to generate versionIds in posix, which is not compatible to S3. The versionId validation was performed in frontend which is a potential source of failure for s3 proxy configured on an s3 service which doesn't use ulid for versionId generation(e.g. aws S3). These changes move the specific `ulid` versionId validation to posix to not force any specific versionId format in the gateway.
2026-04-07 01:56:51 +04:00
Ben McClelland
1fca33e738 Merge pull request #2006 from versity/ben/racing-put-delete
fix: retry link on ENOENT caused by racing DeleteObject
2026-04-02 09:57:48 -07:00
Ben McClelland
98a186cc4e Merge pull request #2008 from versity/sis/object-post-boundary-prefix
fix: remove POST object multipart boundary prefix trimming
2026-04-02 08:27:02 -07:00
Ben McClelland
71ae9bf045 Merge pull request #2005 from versity/sis/copyobject-expected-source-bucket-owner
feat: implement x-amz-source-expected-bucket-owner for CopyObject and UploadPartCopy
2026-04-02 08:25:50 -07:00
Ben McClelland
c26012905c fix: retry link on ENOENT caused by racing DeleteObject
A concurrent PutObject and DeleteObject on the same prefix directory
can race:
PutObject opens an O_TMPFILE in MetaTmpDir (not yet visible in the fs)
DeleteObject removes the last visible object in the prefix directory
and calls removeParents(), which rmdir's the now-empty prefix
directory
PutObject's link() tries to link the fd into a parent directory that
no longer exists

Fix by detecting ENOENT in the final link step (Linkat, Rename, and
MoveFile) and retrying after recreating the parent directory.

Also extract linkatOTmpfile() to consolidate the Linkat+EEXIST→Renameat
logic that was previously inline in link().

Fixes #1988
2026-04-02 08:14:44 -07:00
niksis02
a25408c225 fix: remove POST object multipart boundary prefix trimming
Fixes the [comment](https://github.com/versity/versitygw/issues/1648#issuecomment-4175425099)

Removes the unnecessary multipart/form-data boundary normalizing. The boundary prefix(`--`) was trimmed in `NewMultipartParser`, which caused incorrect boundary check for the boundaries starting with 2 dashes(e.g. `----WebKitFormBoundaryABC123`).
2026-04-02 17:20:23 +04:00
Luke McCrone
6b93190922 test: fix response code 2026-04-01 15:13:58 -03:00
niksis02
052f2364cc feat: implement x-amz-source-expected-bucket-owner for CopyObject and UploadPartCopy
Closes #1897

Extract the `X-Amz-Source-Expected-Bucket-Owner` header for CopyObject and UploadPartCopy. Verify the source bucket owner in the backend and if the provided access key id doesn't match, return an `AccessDenied` error.
2026-04-01 21:44:33 +04:00
Ben McClelland
89ab7a4f2b Merge pull request #1982 from versity/sis/POST-object
feat: add browser-based POST object upload support
2026-03-31 12:25:00 -07:00
niksis02
59002b2650 feat: implement integration tests for browser-based POST object 2026-03-31 22:47:04 +04:00
niksis02
285d130a47 feat: add browser-based POST object upload support
Closes #1648
Fixes #1980
Fixes #1981

This PR implements browser-based POST object uploads for S3-compatible form uploads. It adds support for handling `multipart/form-data` object uploads submitted from browsers, including streaming multipart parsing so file content is not buffered in memory, POST policy decoding and evaluation, SigV4-based form authorization, and integration with the existing `PutObject` backend flow. The implementation covers the full browser POST upload path, including validation of required form fields, credential scope and request date checks, signature verification, metadata extraction from `x-amz-meta-*` fields, checksum field parsing, object tagging conversion from XML into the query-string format expected by `PutObject`, and browser-compatible success handling through `success_action_status` and `success_action_redirect`. It also wires the new flow into the router and metrics layer and adds POST-specific error handling and debug logging across policy parsing, multipart parsing, and POST authorization. AWS S3 also accepts the `redirect` form field alongside `success_action_redirect`, but since AWS has marked `redirect` as deprecated and is planning to remove it, this gateway intentionally does not support it.
2026-03-31 22:44:54 +04:00
niksis02
3b17f05d17 feat: support response header overrides in HeadObject
Closes #1967

Add support for response header override query parameters(`response-cache-control`, `response-content-disposition`, `response-content-encoding`, `response-content-language`, `response-content-type`, `response-expires`) in `HeadObject`. Anonymous requests with override params are rejected with `ErrAnonymousResponseHeaders`.
2026-03-31 17:19:03 +04:00
Ben McClelland
2b12a5b81c Merge pull request #1989 from versity/test/rest_list_objects_encoding
test: REST ListObjects encoding
2026-03-30 14:43:12 -07:00
Luke McCrone
8feed3b333 test: ListObjects encoding-type tests 2026-03-30 10:24:03 -03:00
Ben McClelland
13b3dc5267 fix: serialize concurrent CompleteMultipartUpload calls via rename
When two requests raced to complete the same multipart upload, the first
caller to finish would remove the part files and upload directory. The
second caller, already past the initial existence check, would then fail
mid-flight with confusing errors such as ErrInvalidPart or an I/O error
when trying to open a part that no longer exists.

Fix this by atomically renaming the upload directory from <uploadID> to
<uploadID>.inprogress at the very start of CompleteMultipartUploadWithCopy,
before any part data is read. A concurrent caller will now find the
original directory absent and receive a clean NoSuchUpload error. A
deferred rename restores the original name if the complete does not
succeed, allowing the client to retry.

ListMultipartUploads is updated to skip any directories whose name ends
in .inprogress so in-flight completes do not appear as pending uploads.
2026-03-27 16:14:20 -07:00
Luke McCrone
ccd0ba2762 test: remove eval, go command generation overhaul 2026-03-27 15:00:56 -03:00
Luke McCrone
a96def085d test: test_common.sh updates, bucket/file creation updates, hardcode fixes 2026-03-20 14:09:00 -03:00
Luke McCrone
7975b9bbaa test: listobjects delimiter/prefix test, skips removal, go query improvement 2026-03-17 16:07:47 -03:00
Luke McCrone
7308c65591 test: ListBuckets - bucket region, more default param tests 2026-03-13 09:30:39 -03:00