Commit Graph

539 Commits

Author SHA1 Message Date
Luke McCrone
1b8768b5df test: minor fix 2026-03-27 14:30:26 -03:00
Luke McCrone
a05620e1f5 test: add skips 2026-03-27 11:58:17 -03:00
Luke McCrone
10a6b101d3 test: ListObjects encoding-type tests 2026-03-27 11:18:54 -03:00
Luke McCrone
2fa3b3d62b test: test_common.sh updates, bucket/file creation updates, hardcode fixes 2026-03-27 11:17:39 -03:00
Luke McCrone
97296e80eb test: remove eval, go command generation overhaul 2026-03-27 10:18:17 -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
Ben McClelland
97cc6bf23b chore: run go modernize tool
This is a fixup of the codebase using:
go run golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest -fix ./...

This has no bahvior changes, and only updates safe changes for
modern go features.
2026-03-10 09:47:37 -07:00
Ben McClelland
6c79f26625 Merge pull request #1931 from versity/sis/object-metadata-limits
fix: add request headers and metadata headers limit
2026-03-06 13:17:14 -08:00
niksis02
21a636b3b5 fix: add request headers and metadata headers limit
Fixes #1606

According to AWS documentation:
> *“The PUT request header is limited to 8 KB in size. Within the PUT request header, the user-defined metadata is limited to 2 KB in size. The size of user-defined metadata is measured by taking the sum of the number of bytes in the UTF-8 encoding of each key and value.”*

Based on this, object metadata size is now limited to **2 KB** for all object upload operations (`PutObject`, `CopyObject`, and `CreateMultipartUpload`).

Fixes handling of metadata HTTP headers when the same header appears multiple times with different casing or even if they are identical. According to S3 behavior, these headers must be merged into a single lower-cased metadata key, with values concatenated using commas.

Example:

```
x-amz-meta-Key: value1
x-amz-meta-kEy: value2
x-amz-meta-keY: value3
```

Translated to:

```
key: value1,value2,value3
```

This PR also introduces an **8 KB limit for request headers**. Although the S3 documentation explicitly mentions the 8 KB limit only for **PUT requests**, in practice this limit applies to **all requests**.

To enforce the header size limit, the Fiber configuration option `ReadBufferSize` is used. This parameter defines the maximum number of bytes read when parsing an incoming request. Note that this limit does not apply strictly to request headers only, since request parsing also includes other parts of the request line (e.g., the HTTP method, protocol string, and version such as `HTTP/1.1`). So `ReadBufferSize` is effectively a limit for request headers size, but not the exact limit.
2026-03-06 23:25:49 +04:00
Ben McClelland
bcb7bc5f9a Merge pull request #1922 from versity/test/update_remove_some_utils
test: some util file updates, changes, removals
2026-03-05 17:07:25 -08:00
Ben McClelland
6281391bb9 Merge pull request #1920 from versity/sis/posix-object-metadata
fix: change the way object metadata is stored in posix
2026-03-05 17:07:05 -08:00
niksis02
97bb70509f fix: change the way object metadata is stored in posix
Fixes #1909

Previously, the mapping between object metadata and posix object was as follows: for each metadata key, we stored a separate xattr with the `user.X-Amz-Meta.<key>` prefix. This resulted in syscall overhead when storing and deleting large numbers of metadata keys.
In addition, very long metadata keys caused failures because most posix filesystems limit xattr key lengths to 127–255 bytes, while S3 does not enforce such a per-key limit.

The logic has now been changed so that all object metadata is stored in a single xattr, `user.metadata`, as a JSON key/value object. For backward compatibility, metadata GET operations still fall back to the old mechanism (`metadata key -> xattr key`) when `user.metadata` is not present.

A new CLI utility has been added to convert all legacy object metadata to the new metadata format within the provided directory.

**Example usage:**

```
versitygw utils convert-xattr-metadata path/to/bucket
```

or

```
versitygw utils cxm path/to/bucket
```

It is recommended to run this command on bucket directories to convert all legacy metadata for every object in the bucket.
2026-03-06 01:44:14 +04:00
Luke McCrone
038ae5e1ea test: update functions, transfer/remove some utils files 2026-03-04 14:15:00 -03:00
Luke McCrone
7b201777c3 test: CORS response header tests 2026-03-03 10:54:21 -03:00
Ben McClelland
8c648b5294 Merge pull request #1911 from versity/sis/revert-acl-headers-validation
feat: revert ignore object ACL behavior
2026-03-02 13:10:27 -08:00
niksis02
5c918f3682 feat: revert ignore object ACL behavior
The logic to return a `NotImplemented` error on object upload operations, when any ACL header is present has been removed. Now all object ACL headers are by default ignored. The `-noacl` flag is preserved to disabled bucket ACLs.

**Testing**
The Put/Get object ACL tests are moved to `NotImplemented` integration tests group as a default gateway behavior. The existing `_acl_not_supported` tests are modified to expect no error, when ACLs are used on object uploads.
2026-03-02 19:30:57 +04:00
niksis02
8550dba36f feat: add tagging support for directory objects in posix
Closes #1857

Adds object Tagging support for directory objects in `PutObject` posix. Updates the integration tests to test object metadata and tagging both for file and directory objects.
2026-03-02 18:56:50 +04:00
Ben McClelland
da82e5e247 fix: add missing tests to group-tests map
These tests were missing in the tests map to run the individual
tests:
ListBuckets_empty_success
CompleteMultipartUpload_incorrect_part_number
2026-02-28 16:39:43 -08:00
Ben McClelland
98acad9c99 Merge pull request #1887 from versity/sis/complete-mp-checksum
fix: store final checksum on CompleteMultipartUpload
2026-02-28 09:54:55 -08:00
Ben McClelland
0ad928a4d8 Merge pull request #1894 from versity/sis/getobject-directory-object-checksum
feat: adds checksums for directory objects in posix
2026-02-28 09:39:51 -08:00
Ben McClelland
1e5f803cab Merge pull request #1875 from versity/sis/disable-acl-option
feat: configuration option to disable ACLs
2026-02-28 09:32:23 -08:00
niksis02
5ae791b154 feat: configuration option to disable ACLs
Closes #1847

This PR introduces a global optional gateway CLI flag `--disable-acl` (`VGW_DISABLE_ACL`) to disable ACL handling. When this flag is enabled, the gateway ignores all ACL-related headers, particularly in `CreateBucket`, `PutObject`, `CopyObject`, and `CreateMultipartUpload`.

`GetBucketAcl` behavior is unchanged simply returning the bucket ACL config.
There's no change in object ACL actions(`PutObjectACL`, `GetObjectACL`). They return a`NotImplemented` error as before.

A new custom error is added for PutBucketAcl calls when ACLs are disabled at the gateway level. Its HTTP status code and error code match AWS S3’s behavior, with only a slightly different error message.

In the access-control checker, ACL evaluation is fully bypassed. If ACLs are disabled only the bucket owner gets access to the bucket and all grantee checks are ignored.

The PR also includes minor refactoring of the S3 API server and router. The growing list of parameters passed to the router’s Init method has been consolidated into fields within the router struct, initialized during router construction. Parameters not needed by the S3 server are no longer stored in the server configuration and are instead forwarded directly to the router.
2026-02-27 20:04:13 +04:00
niksis02
4ebe40829e fix: store final checksum on CompleteMultipartUpload
Previously, if no object checksum type/algorithm was specified when initiating a multipart upload, the CompleteMultipartUpload request would compute the final object’s CRC64NVME checksum but not persist it. This logic has now been fixed, and in the scenario described above the checksum is stored on the final object. There should no longer be any case where a CompleteMultipartUpload request finishes without persisting the final object checksum.
2026-02-27 15:12:57 +04:00
niksis02
24364754fd feat: adds checksums for directory objects in posix
Add data-integrity checksum support in `PutObject` in the POSIX backend for directory objects. Since the only way to upload a directory object is via `PutObject`, this logic validates and stores the checksum of the empty payload. Support for `GetObject` has also been added to retrieve and return directory-object checksums.
2026-02-26 22:36:56 +04:00
Luke McCrone
05ace90683 test: README, some test updates 2026-02-25 19:26:34 -03:00
Luke McCrone
2bd5ffe8bc test: remove obsolete recording code 2026-02-24 15:15:06 -03:00
niksis02
6fafc15d08 fix: fixes PutBucketCors CORSRules validation
Fixes #1870
Fixes #1863

A validation has been added to **PutBucketCors** for `CORSRule.AllowedOrigins`. The `AllowedOrigins` list can no longer be empty—otherwise a **MalformedXML** error is returned. Additionally, each origin is now validated to ensure it does not contain more than one wildcard.

A similar validation has been added for `AllowedMethods`. The list must not be empty, or a **MalformedXML** error is returned. Previously, empty method values (e.g., `[]string{""}`) were incorrectly treated as valid. This has been fixed, and an **UnsupportedCORSMethod** error is now returned.
2026-02-24 16:59:38 +04:00
Ben McClelland
ab80ac6e26 Merge pull request #1876 from versity/sis/create-bucket-response
feat: adds `Location`, `x-amz-bucket-arn` response headers in CreateBucket
2026-02-23 12:34:05 -08:00
niksis02
7fb3dedecc feat: adds Location, x-amz-bucket-arn response headers in CreateBucket
Closes #1873
2026-02-20 13:02:51 +04:00
Luke McCrone
5fc7357a03 test: REST CORS - initial tests 2026-02-19 20:19:05 -03:00
Ben McClelland
a81f9e5152 Merge pull request #1871 from versity/sis/create-bucket-private-canned-acl
fix: correct private canned ACL behavior on bucket creation
2026-02-18 09:55:36 -08:00
niksis02
f1577fd00b fix: correct private canned ACL behavior on bucket creation
Fixes #1869

Generally, when object ownership is not explicitly specified during bucket creation, it defaults to `BucketOwnerEnforced`. With `BucketOwnerEnforced`, ACLs are disabled and any attempt to set one results in an `InvalidBucketAclWithObjectOwnership` error.

However, there is an edge case. When the `private` canned ACL is used during bucket creation—which is effectively the default ACL for all buckets—`BucketOwnerEnforced` is still permitted. Moreover, if no explicit object ownership is specified together with the `private` canned ACL, the ownership defaults to `BucketOwnerPreferred`.

This fix also resolves the issue with rclone bucket creation, since rclone sends `x-amz-acl: private` by default:

```
rclone mkdir vgw:test
```
2026-02-18 20:32:05 +04:00
niksis02
46bcc8af35 fix: fixes object default Content-Type
Fixes #1849

If no `Content-Type` is provided during object upload, S3 defaults it to `application/octet-stream`. This behavior was missing in the gateway, causing backends to persist an empty `Content-Type`, which Fiber then overrides with its default `text/plain`. The behavior has now been corrected for the object upload operations: `PutObject`, `CreateMultipartUpload`, and `CopyObject`.
2026-02-18 01:44:52 +04:00
Luke McCrone
e810d4204d test: not-implemented type test, first template usage 2026-02-11 16:52:20 -03:00
Ben McClelland
3e26175265 feat: replace aws-sdk-go-v2 s3 manager with transfermanager
The latest version of the go sdk has deprecate the s3 manager in
favor of the new transfermanager. This updates to the new
transfermanager functionality for the two places we were using
the manager, iam s3 and integration tests.

This also removes the pinning of nats nkeys since they have fixed
the tags in their repo now. And general cleanup of the go.mod.
2026-02-11 09:58:15 -08:00
Ben McClelland
3856f99904 Merge pull request #1839 from versity/sis/deleteobject-if-match-etag-quotes
fix: fixes DeleteObject if-match quoted comparison
2026-02-11 08:18:35 -08:00
niksis02
89aa822a40 fix: fixes DeleteObject if-match quoted comparison
Fixes #1835

If-Match in DeleteObject is a precondition header that compares the client-provided ETag with the server-side ETag before deleting the object. Previously, the comparison failed when the client sent an unquoted ETag, because server ETags are stored with quotes. The implementation now trims quotes from both the input ETag and the server ETag before comparison to avoid mismatches. Both quoted and unquoted ETags are valid according to S3.
2026-02-11 16:45:36 +04:00
Ben McClelland
e702a4860a fix: CopyObject with URL-encoded special chars
CopyObject was failing with NoSuchKey when source keys contained special
characters like {} or spaces. The X-Amz-Copy-Source header is URL-encoded
by clients, but ParseCopySource wasn't decoding before filesystem access.

Added url.QueryUnescape() to properly decode bucket and object names,
fixing copy operations for keys with special characters.

Fixing this also uncovered an errors with azure blob url encoding with
similar special character handling. Added this fix in for the integration
tests to pass.

Fixes #1832
Fixes #1637
2026-02-10 14:55:18 -08:00
Ben McClelland
e805003872 Merge pull request #1816 from versity/sis/max-limiter-errors
fix: fixes list-limiters parsing and validation
2026-02-06 09:28:18 -08:00
Ben McClelland
b2a9b383ae Merge pull request #1803 from versity/sis/list-mp-delimiter
feat: adds delimiter support in ListMultipartUploads
2026-02-06 09:27:32 -08:00
niksis02
2365f9f1ae fix: fixes list-limiters parsing and validation
Fixes #1809
Fixes #1806
Fixes #1804
Fixes #1794

This PR focuses on correcting so-called "list-limiter" parsing and validation. The affected limiters include: `max-keys`, `max-uploads`, `max-parts`, `max-buckets`, `max-uploads` and `part-number-marker`. When a limiter value is outside the integer range, a specific `InvalidArgument` error is now returned. If the value is a valid integer but negative, a different `InvalidArgument` error is produced.

`max-buckets` has its own validation rules: completely invalid values and values outside the allowed range (`1 <= input <= 10000`) return distinct errors. For `ListObjectVersions`, negative `max-keys` values follow S3’s special-case behavior and return a different `InvalidArgument` error message.

Additionally, `GetObjectAttributes` now follows S3 semantics for `x-amz-max-parts`: S3 ignores invalid values, so the gateway now matches that behavior.
2026-02-06 14:21:56 +04:00
niksis02
2e6794007c feat: adds delimiter support in ListMultipartUploads
Fixes #1792
Fixes #1747
Fixes #1797
Fixes #1799

This PR primarily introduces delimiter support and several bug fixes for the `ListMultipartUploads` action in the POSIX and Azure backends. Delimiter handling is now implemented — when a delimiter is present in multipart-upload object key names, the backend collects and returns the appropriate common prefixes.
This functionality is achieved by introducing a common multipart-upload lister in the backend package. All backends (Azure, POSIX) now use this lister. The lister accepts a list that is already sorted and filtered by `KeyMarker` and `Prefix`.

Previously, the `KeyMarker` was required to exactly match an existing multipart-upload object key. This restriction is removed. The listing now relies on a lexicographical comparison between the provided `KeyMarker` and existing multipart-upload object keys.

Validation for `UploadIdMarker` is also added to correctly return an `InvalidArgument` error for invalid upload IDs. If `KeyMarker` is missing, the `UploadIdMarker` is ignored entirely. If `KeyMarker` is provided, a valid upload ID is one that matches an upload belonging to *the first object key after the KeyMarker*. For example, if the `KeyMarker` is `foo`, but the provided `UploadIdMarker` corresponds to an upload under `quxx`, it is invalid. It must match one of the uploads for the next object key equal to `foo`.

Finally, this PR fixes multipart-upload sorting. Multipart uploads must be sorted primarily lexicographically by their object key, and secondarily—when multiple uploads share the same object key—by their initiation time in ascending order.
2026-02-06 14:16:16 +04:00
Luke McCrone
44fa5fa178 test: some not-implemented's, add list-object-v2 working test 2026-02-05 10:14:08 -03:00
Luke McCrone
17adbeca9e test: S3 command coverage reporting 2026-01-30 18:51:02 -03:00
Luke McCrone
1f9856110d test: PutObject object lock tests and updates, delete bucket test 2026-01-26 16:58:49 -03:00
niksis02
8569b158f0 fix: return not implemented in object actions, if acl header is present
Fixes #1767
Fixes #1773

As object ACLs are not supported in the gateway, any attempt to set an ACL during object creation must return a NotImplemented error. A check has now been added to `PutObject`, `CopyObject`, and `CreateMultipartUpload` to detect any ACL-related headers and return a NotImplemented error accordingly.
2026-01-23 17:03:03 +04:00
Luke McCrone
a4d341fc4e test: speed up/reorganize REST tests, openssl logging 2026-01-22 15:54:47 -03:00
Luke McCrone
bfc753b302 test: test fix 2026-01-20 11:29:41 -03:00