Commit Graph
46 Commits
Author SHA1 Message Date
dualfroz 0e3045b87f fix: drop the owner's FULL_CONTROL grant when grant headers set the bucket ACL
CreateBucket and PutBucketAcl with x-amz-grant-* headers stored the
requested grants plus a FULL_CONTROL grant for the bucket owner, so
GetBucketAcl returned a grant AWS doesn't. On AWS the headers replace the
whole ACL and the owner gets FULL_CONTROL only when a header names it.

UpdateACL now keeps just the header grants when there are any. A canned
ACL and a bucket created without grants still get the owner's FULL_CONTROL
grant. The owner keeps full access either way, since aclAllows lets the
bucket owner perform any action regardless of grants.

Fixes #1407
2026-10-14 19:40:59 +02:00
upstream 3fee7f49c9 Upstream versity/versitygw state of the touched files before 3d4c24e2e1 2026-10-14 19:40:59 +02:00
dualfroz deab0fc412 test: enable the missing Host header ListBuckets test
Since fasthttp v1.70.0 an HTTP/1.1 request without a Host header is
rejected and the gateway answers it with 400 BadRequest. Add a server
test that sends such requests over a raw connection and stop skipping
the REST missing host test against the gateway.

Fixes #1530
2026-10-14 18:55:47 +02:00
upstream cf6c64c93a Upstream versity/versitygw state of the touched files before 1ec04af468 2026-10-14 18:55:47 +02:00
dualfroz 276128b42b fix: reject an empty start-after and continuation-token in ListObjects (V1) 2026-10-12 14:30:16 +02:00
upstream 613c71290f Upstream versity/versitygw state of the touched files before aed4617372 2026-10-12 14:30:16 +02:00
dualfroz 7dce327c11 fix: return NextMarker in ListObjects only when a delimiter is set
Fixes #999
2026-10-10 11:50:51 +02:00
upstream 295bb05dd1 Upstream versity/versitygw state of the touched files before c02173db7a 2026-10-10 11:50:51 +02:00
dualfroz b8628c396f fix: reject the start-after query in ListObjects (V1)
Fixes #2004
2026-10-10 11:46:12 +02:00
upstream 485130eb9f Upstream versity/versitygw state of the touched files before 44dc2e71ec 2026-10-10 11:46:12 +02:00
dualfroz 86ff18f8c1 fix: reject unknown response-* query parameters in GetObject and HeadObject
getobject and headobject silently ignored any response-* query parameter outside the six overridable headers. they now return 400 InvalidArgument naming the parameter and its value, like s3, and the rest tests skipped for this issue are enabled.

Fixes #2075
2026-10-07 19:40:28 +02:00
upstream 5a14104c85 Upstream versity/versitygw state of the touched files before 3dc5e993d2 2026-10-07 19:40:28 +02:00
dualfroz b3bf48bdcb fix: reject start-after in ListObjects V1
listobjects v1 now returns InvalidArgument when the start-after query parameter is present, matching s3, which only accepts it with list-type=2. previously the parameter was silently ignored.

Fixes #2004
2026-10-07 19:38:54 +02:00
upstream 09e1b65724 Upstream versity/versitygw state of the touched files before 5128cc1624 2026-10-07 19:38:54 +02:00
dualfroz 8271bea5c1 fix: return full authorization header in unsupported authorization type error
the unsupported authorization type error only echoed the algorithm back in ArgumentValue, while s3 returns the whole Authorization header there. the parse error now carries the raw header and the s3 error mapping uses it, which also lets the bats test skipped for #1705 run again.

Fixes #2489
2026-10-07 19:37:46 +02:00
upstream 1b64a938ab Upstream versity/versitygw state of the touched files before 1a2bd1ad85 2026-10-07 19:37:46 +02:00
dualfroz cd3095d5b7 fix: reject ListMultipartUploads requests that also carry uploadId
* fix: reject ListMultipartUploads requests that also carry uploadId

A bucket GET with both the uploads and uploadId query parameters was
routed to ListMultipartUploads and answered with the upload listing.
S3 rejects the combination with 400 InvalidArgument, "Conflicting query
string parameters: uploadId, uploads".

Add an error route for the combination ahead of ListMultipartUploads,
the way the object level '?uploads' request is rejected, and enable
the REST test that covers it.

Fixes #2155

* fix: reject uploads with uploadId for every bucket and object operation

Requests carrying both the uploads and uploadId query parameters were
only rejected for a bucket GET, so DELETE, PUT, POST and HEAD on the
bucket or object paths still ran real operations. S3 rejects the
combination for every method on both paths, before authentication and
before checking that the bucket exists.

Register the error route for all methods on the bucket and object
routers right after the CORS middleware is set up, ahead of every other
route, and cover each method and path with an integration test.
2026-10-05 11:18:49 -07:00
upstream cc9a86ef08 Upstream versity/versitygw state of the touched files before 6c6b14f7e8 2026-10-05 20:18:49 +02:00
dualfroz 25ec56b451 test: use the upload's own key as key-marker in the truncation test
An upload-id-marker has to belong to the key-marker itself, S3 answers
key-marker=ba with an upload of bar with 400 Invalid uploadId marker.
2026-10-05 20:25:15 +02:00
dualfroz e1d2284906 fix: reject a ListBuckets bucket-region other than the gateway region
S3 never lists an empty result for another region: a valid region
other than the endpoint's own gets 400 InvalidArgument, "Requests with
bucket-region specified must be made to the corresponding regional
endpoint", with no ArgumentValue. The gateway is a single regional
endpoint, so it now does the same instead of clearing the listing.

Match the region case-insensitively like S3, and check an empty
bucket-region= too by looking for the query argument itself, since an
empty value is not a valid AWS region either.
2026-10-05 20:42:30 +02:00
dualfroz 5d293b1316 fix: reject uploads with uploadId for every bucket and object operation
Requests carrying both the uploads and uploadId query parameters were
only rejected for a bucket GET, so DELETE, PUT, POST and HEAD on the
bucket or object paths still ran real operations. S3 rejects the
combination for every method on both paths, before authentication and
before checking that the bucket exists.

Register the error route for all methods on the bucket and object
routers right after the CORS middleware is set up, ahead of every other
route, and cover each method and path with an integration test.
2026-10-05 09:47:50 +02:00
upstream 47b43ba5ea Upstream versity/versitygw state of the touched files before 535e4bbfc7 2026-10-05 09:47:50 +02:00
dualfroz 2f2ed7ae25 fix: compute IsTruncated from the absolute index in ListMultipartUploads
With an upload-id-marker the lister ranges over Uploads[startIndex:],
but passed the index of that subslice to hasMoreAfter, which indexes
the full list. A page that ended on the last remaining upload was still
reported as truncated, with next markers pointing at that upload, so a
client had to make one more request to get an empty page.

Iterate over the full list from startIndex, so hasMoreAfter gets the
real position of the next upload.
2026-10-05 20:25:15 +02:00
upstream a4aa4bb8d2 Upstream versity/versitygw state of the touched files before 592e91b10c 2026-10-02 16:41:50 +02:00
dualfroz cbe870a618 fix: accept upload-id-marker together with key-marker in ListMultipartUploads
The posix and azure backends dropped every upload with a key equal to
the key-marker before handing the list to the lister, which then looked
for the upload-id-marker under the next key. An upload-id-marker that
belongs to the key-marker could never be found, so the request failed
with "Invalid uploadId marker", including when a client paged with the
NextKeyMarker and NextUploadIdMarker the gateway returned.

Keep the uploads of the key-marker itself when an upload-id-marker is
set, so the listing continues right after the given upload, as S3 does.
Enable the REST test that covers it.

Fixes #2149
2026-10-03 16:41:32 +02:00
upstream f81c6a5acb Upstream versity/versitygw state of the touched files before daa25ed6bc 2026-10-02 16:40:16 +02:00
dualfroz 7a0b44c275 fix: drop upload-id-marker without key-marker in ListMultipartUploads
An upload-id-marker sent without a key-marker is ignored for the
listing, but the gateway still echoed it back in UploadIdMarker. S3
discards the parameter in that case and returns an empty
UploadIdMarker.

Clear the marker in the controller when no key-marker is given, so
every backend gets the same input and the response no longer reports
a marker that had no effect.

Fixes #2150
2026-10-03 17:49:52 +02:00
upstream 79e4cf7bca Upstream versity/versitygw state of the touched files before 070b030237 2026-10-02 16:40:10 +02:00
dualfroz 08d5acf963 fix: report the last upload in ListMultipartUploads next markers on a single page
NextKeyMarker and NextUploadIdMarker were only set for a truncated
listing, so a ListMultipartUploads response that fit in one page
returned them empty. S3 still sets them to the key and upload ID of
the last upload in the response.

Fill both markers from the last listed upload when the listing is not
truncated, including the case where the page ends exactly at
max-uploads. A page of common prefixes only keeps them empty, as
before. Enable the REST test that covers it.

Fixes #2144
2026-10-03 17:46:31 +02:00
upstream f12ba37b26 Upstream versity/versitygw state of the touched files before 95a6da83b9 2026-10-02 16:09:06 +02:00
dualfroz b7ff97181d fix: validate and apply the ListBuckets bucket-region query
ListBuckets ignored bucket-region: a value that is not a region was
accepted, and a region other than the gateway one still listed every
bucket. S3 rejects an invalid value with 400 InvalidArgument, "Argument
value abc is not a valid AWS Region", and lists only the buckets of the
requested region.

Check bucket-region against the AWS region code format, always
accepting the gateway region whatever its name, and return an empty
list for any other region, since every bucket lives in the gateway
region. Enable the REST tests that cover both cases.

Fixes #1923
Fixes #1930
2026-10-05 20:42:18 +02:00
upstream 2bb327ec69 Upstream versity/versitygw state of the touched files before aaf73219cd 2026-10-02 16:07:01 +02:00
dualfroz 62d77006d2 fix: return MalformedXML for a DeleteObjects request without objects
A DeleteObjects request whose Delete element names no objects was
answered with 200 and an empty DeleteResult. S3 rejects it with
MalformedXML, as the schema requires at least one Object.

Reject the empty list right after the body is parsed, next to the
1000 key limit check. Update the unit and integration tests that
expected the empty result and enable the REST test that covers it.

Fixes #2109
2026-10-03 16:01:57 +02:00
upstream edbb6c2d74 Upstream versity/versitygw state of the touched files before 63922ed89d 2026-10-02 16:02:57 +02:00
dualfroz 5f0e2e55ba fix: reject ListMultipartUploads requests that also carry uploadId
A bucket GET with both the uploads and uploadId query parameters was
routed to ListMultipartUploads and answered with the upload listing.
S3 rejects the combination with 400 InvalidArgument, "Conflicting query
string parameters: uploadId, uploads".

Add an error route for the combination ahead of ListMultipartUploads,
the way the object level '?uploads' request is rejected, and enable
the REST test that covers it.

Fixes #2155
2026-10-05 09:46:37 +02:00
upstream 6704314fea Upstream versity/versitygw state of the touched files before eecdc6b996 2026-10-02 16:01:08 +02:00
dualfroz e0fef79b7b fix: return InvalidURI for a malformed escape in the request path
A request path with an invalid percent escape, such as "/bucket/%zz",
failed url.PathUnescape in the DecodeURL middleware and the raw error
was answered with 500 InternalError. S3 rejects such a request with
400 InvalidURI.

Return InvalidURI from DecodeURL, so the s3 and admin routers answer
with it as well, and let the website handler pass the error through
instead of mapping it on its own.

Fixes #2070
2026-10-03 15:13:16 +02:00
upstream 59493b527e Upstream versity/versitygw state of the touched files before 5d5ee06ee6 2026-10-02 15:59:21 +02:00
dualfroz 1d06fadbbd Merge pull request #2389 from dualfroz/fix-illegal-location-constraint
Return IllegalLocationConstraintException for a mismatched LocationConstraint
2026-09-14 15:03:16 -07:00
upstream efecf29ac0 Upstream versity/versitygw state of the touched files before 91e4790870 2026-09-15 00:03:16 +02:00
dualfroz d5ed12db2b move location constraint validation to s3api/utils 2026-09-14 20:29:22 +02:00
upstream 87a4aee115 Upstream versity/versitygw state of the touched files before caf29a97fa 2026-09-14 20:28:40 +02:00
dualfroz 9abdd46f7b test: send the location constraint when creating buckets outside us-east-1 2026-09-14 02:17:22 +02:00
upstream 5207fe5e36 Upstream versity/versitygw state of the touched files before 61e5eb836d 2026-09-14 02:17:22 +02:00
dualfroz 2742fc2216 fix: return IllegalLocationConstraintException for a mismatched LocationConstraint
A region specific endpoint requires CreateBucket to name that same region
in `LocationConstraint`. The gateway reported a mismatch as
`InvalidLocationConstraint`, which AWS reserves for a constraint that is
not a valid location at all, and accepted a request that omitted the
constraint entirely.

Keep `InvalidLocationConstraint` for the global `us-east-1` endpoint,
which takes no constraint, and return
`IllegalLocationConstraintException` when a region specific endpoint gets
a constraint naming another region, or none.

Fixes #2246
2026-09-13 15:08:58 +02:00
upstream 2a5705ab02 Upstream versity/versitygw state of the touched files before b237f0cf7a 2026-09-11 23:12:57 +02:00