Commit Graph

2546 Commits

Author SHA1 Message Date
Ben McClelland cb49670cb7 Merge pull request #2162 from versity/ben/webui-error
fix: replace misleading webui CORS error toast with generic network error message
2026-06-01 09:23:18 -07:00
Ben McClelland da6aa1c843 Merge pull request #2159 from versity/ben/webui-storageclass
fix: expose x-amz-storage-class in CORS response headers
2026-06-01 09:23:01 -07:00
Ben McClelland ba51c0a850 Merge pull request #2158 from versity/sis/presigned-urls-signed-headers
fix: enforce SignedHeaders validation for SigV4 requests
2026-06-01 09:22:43 -07:00
niksis02 577470214d fix: enforce required SignedHeaders validation for SigV4 requests
Validate required signed headers for both Authorization-header SigV4 requests and presigned URLs. The required signed header set is now `host` plus every incoming header with the `x-amz-` prefix.

During request reconstruction, signed headers and explicitly ignored headers are copied into the generated request used for signature verification. If an incoming `x-amz-*` header is present but missing from the client-provided `SignedHeaders`, return `AccessDenied` with a `HeadersNotSigned` field. The `host` header remains part of the canonical request and signed header calculation.

Previously, a client could sign a request without an S3 control header and then add that header after signing. For example, a presigned `PUT` URL could be generated with only `host` signed, then the actual request could include an unsigned `X-Amz-Tagging` or `X-Amz-Copy-Source` header. Because the verifier reconstructed the request only from `SignedHeaders`, that extra header was omitted from signature calculation and could pass authentication even though it changed the request semantics. This is now rejected with `AccessDenied`.

Expose v4 helper methods for checking required and ignored headers, and update canonical header signing so ignored headers can still be included when a client explicitly lists them in `SignedHeaders`, while `Authorization` remains excluded from signature calculation.
2026-05-30 21:16:26 +04:00
Ben McClelland d498d48497 fix: replace misleading webui CORS error toast with generic network error message
Browsers throw an opaque TypeError for all network-level failures — CORS
policy violations, TLS/certificate rejections (e.g. self-signed certs), DNS
failures, and unreachable hosts — with no way to distinguish between them.
Asserting "CORS blocked" on every TypeError caused users to chase a CORS
misconfiguration when the real problem was an untrusted certificate or
unreachable gateway. The error message now lists some plausible causes so users
have possible diagnostics regardless of the actual failure mode.

Fixes #2143
2026-05-29 21:10:22 -07:00
Ben McClelland 0e165edfb1 fix: expose x-amz-storage-class in CORS response headers
The object info modal in the WebUI was always displaying STANDARD as the
storage class regardless of the actual value. The root cause is a browser
CORS restriction: when the WebUI makes a cross-origin HEAD request to the
S3 endpoint, the browser silently drops any response header not listed in
Access-Control-Expose-Headers, causing response.headers.get('x-amz-storage-class')
to return null and the UI to fall back to the hardcoded STANDARD default.

Adding x-amz-storage-class to the default set of exposed headers ensures
the browser makes it available to JavaScript, allowing storage classes such
as GLACIER to be correctly reflected in the UI.
2026-05-29 20:17:56 -07:00
Ben McClelland f7cc70b157 Merge pull request #2157 from versity/test/list_multipart_uploads
test: ListMultipartUpload query tests
2026-05-28 16:02:30 -07:00
Luke McCrone 179fdc0352 test: ListMultipartUpload query tests, related cleanup 2026-05-28 09:30:59 -03:00
Ben McClelland 2bc4da944f Merge pull request #2153 from versity/sis/policy-key-normalization
fix: normalize object keys during bucket policy evaluation
2026-05-27 20:17:25 -07:00
niksis02 cd0b4e6d9d fix: normalize object keys during bucket policy evaluation
Object key validation allowed internal parent-directory segments such as `public/../private.txt`. Bucket policy and auth checks evaluated the raw key, so a policy allowing bucket/public/* could match the request while posix backend later resolved the key with `filepath.Join` and accessed `bucket/private.txt`.

Add backend-specific object key normalization to close that mismatch. The Backend interface now exposes `NormalizeObjectKey` so authorization can evaluate resources using the same key shape a backend will use for storage access.

Backends that do not collapse object paths, including Azure and the S3 proxy, inherit `BackendUnsupported.NormalizeObjectKey`. That implementation returns the input key unchanged, avoiding unnecessary normalization and keeping policy evaluation unpolluted for object stores where ../ is part of the key name.

posix/scoutfs normalize keys with filepath.Join so policy resources and request keys are compared after internal dot segments are collapsed.

Bucket policy evaluation now normalizes both the incoming object key and object resource patterns from the policy before matching. Object lock governance bypass policy checks use the same backend normalizer as well, so retention and legal hold authorization cannot diverge from backend path resolution.
2026-05-27 22:20:39 +04:00
Ben McClelland d62a11f62c Merge pull request #2151 from versity/ben/embed
feat: extract gateway runtime into embeddable package
2026-05-26 20:33:30 -07:00
Ben McClelland 20939bd7b4 feat: extract gateway runtime into embeddable package
Move the runGateway implementation from cmd/versitygw/main.go into a
new embedgw package, exposing RunVersityGW(ctx, Backend, *Config) and a
Config struct. This allows external applications to embed and run the
VersityGW S3 gateway as a library.
2026-05-26 15:08:28 -07:00
Ben McClelland 7dadbc0277 Merge pull request #2154 from versity/sis/empty-ownership-control-rules
fix: fix empty ownership control rules panic
2026-05-26 11:44:39 -07:00
niksis02 4ef090dbfc fix: fix empty ownership control rules panic
Fix the gateway panic when validating malformed bucket ownership controls bodies with no rules. The handler now checks the rules count before indexing the first rule.
2026-05-23 04:18:06 +04:00
Ben McClelland 6c643db58e Merge pull request #2152 from versity/ben/vulnchk
chore: update go package dependencies
2026-05-22 16:49:58 -07:00
Ben McClelland db3478d8b8 chore: update go package dependencies
Fixes govulncheck report:
Vulnerability #1: GO-2026-5026
    Invoking failure to reject ASCII-only Punycode-encoded labels in
    golang.org/x/net/idna
  More info: https://pkg.go.dev/vuln/GO-2026-5026
  Module: golang.org/x/net
    Found in: golang.org/x/net@v0.54.0
    Fixed in: golang.org/x/net@v0.55.0
2026-05-22 15:26:30 -07:00
Ben McClelland f4e5df3b0f Merge pull request #2147 from versity/sis/post-object-key-validation
fix: reject invalid PostObject keys
2026-05-22 11:53:24 -07:00
niksis02 eecc1a779c fix: reject invalid PostObject keys
Validate multipart PostObject key fields with the existing object name rules so path traversal and degenerate names return BadRequest. This prevents crafted object keys from escaping the gateway root.
2026-05-22 14:48:31 +04:00
Ben McClelland 81c9d4ed2f Merge pull request #2148 from versity/sis/public-bucket-policy-deny
fix: honor explicit public bucket policy deny
2026-05-21 15:07:26 -07:00
Ben McClelland 2a8b15a1c2 Merge pull request #2141 from versity/sis/global-error-refactoring
feat: global error refactoring
2026-05-21 15:05:45 -07:00
niksis02 ed1ad6b623 fix: honor explicit public bucket policy deny
Distinguish public bucket policy no-match from explicit deny during anonymous access checks. This preserves ACL fallback only for requests that are not allowed by policy, while ensuring a matching Deny statement short-circuits authorization and returns AccessDenied even when a public ACL would otherwise grant access.
2026-05-22 00:01:24 +04:00
niksis02 9f786b3c2c feat: global error refactoring
Fixes #2123
Fixes #2120
Fixes #2116
Fixes #2111
Fixes #2108
Fixes #2086
Fixes #2085
Fixes #2083
Fixes #2081
Fixes #2080
Fixes #2073
Fixes #2072
Fixes #2071
Fixes #2069
Fixes #2044
Fixes #2043
Fixes #2042
Fixes #2041
Fixes #2040
Fixes #2039
Fixes #2036
Fixes #2035
Fixes #2034
Fixes #2028
Fixes #2020
Fixes #1842
Fixes #1810
Fixes #1780
Fixes #1775
Fixes #1736
Fixes #1705
Fixes #1663
Fixes #1645
Fixes #1583
Fixes #1526
Fixes #1514
Fixes #1493
Fixes #1487
Fixes #959
Fixes #779
Closes #823
Closes #85

Refactor global S3 error handling around structured error types and centralized XML response generation.

All S3 errors now share the common APIError base for the fields every error has: Code, HTTP status code, and Message. Non-traditional errors that need AWS-compatible XML fields now have dedicated typed errors in the s3err package. Each typed error implements the shared S3Error behavior so controllers and middleware can handle errors consistently while still emitting error-specific XML fields.

Add a dedicated InvalidArgumentError type because InvalidArgument is used widely across request validation, auth, copy source handling, object lock validation, multipart validation, and header parsing. The new InvalidArgument path uses explicit InvalidArgErrorCode constants with predefined descriptions and ArgumentName values, keeping call sites readable while preserving the correct InvalidArgument XML shape and optional ArgumentValue.

New structured errors added in s3err:
- `AccessForbiddenError`: Method, ResourceType
- `BadDigestError`: CalculatedDigest, ExpectedDigest
- `BucketError`: BucketName
- `ContentSHA256MismatchError`: ClientComputedContentSHA256, S3ComputedContentSHA256
- `EntityTooLargeError`: ProposedSize, MaxSizeAllowed
- `EntityTooSmallError`: ProposedSize, MinSizeAllowed
- `ExpiredPresignedURLError`: ServerTime, XAmzExpires, Expires
- `InvalidAccessKeyIdError`: AWSAccessKeyId
- `InvalidArgumentError`: Description, ArgumentName, ArgumentValue
- `InvalidChunkSizeError`: Chunk, BadChunkSize
- `InvalidDigestError`: ContentMD5
- `InvalidLocationConstraintError`: LocationConstraint
- `InvalidPartError`: UploadId, PartNumber, ETag
- `InvalidRangeError`: RangeRequested, ActualObjectSize
- `InvalidTagError`: TagKey, TagValue
- `KeyTooLongError`: Size, MaxSizeAllowed
- `MetadataTooLargeError`: Size, MaxSizeAllowed
- `MethodNotAllowedError`: Method, ResourceType, AllowedMethods
- `NoSuchUploadError`: UploadId
- `NoSuchVersionError`: Key, VersionId
- `NotImplementedError`: Header, AdditionalMessage
- `PreconditionFailedError`: Condition
- `RequestTimeTooSkewedError`: RequestTime, ServerTime, MaxAllowedSkewMilliseconds
- `SignatureDoesNotMatchError`: AWSAccessKeyId, StringToSign, SignatureProvided, StringToSignBytes, CanonicalRequest, CanonicalRequestBytes

Fix CompleteMultipartUpload validation in the Azure backend so missing or empty `ETag` values return the appropriate S3 error instead of allowing a gateway panic.

Fix presigned authentication expiration validation to compare server time in `UTC`, matching the `UTC` timestamp used by presigned URL signing.

Add request ID and host ID support across S3 requests. Each request now receives AWS S3-like identifiers, returned in response headers as `x-amz-request-id` and `x-amz-id-2` and included in all XML error responses as RequestId and HostId. The generated ID structure is designed to resemble AWS S3 request IDs and host IDs.

The request signature calculation/validation for streaming uploads was previously delayed until the request body was fully read, both for Authorization header authentication and presigned URLs.
Now, the signature is validated immediately in the authorization middlewares without reading the request body, since the signature calculation itself does not depend on the request body. Instead, only the `x-amz-content-sha256` SHA-256 hash calculation is delayed.
2026-05-21 23:49:34 +04:00
Ben McClelland eade1e3a71 Merge pull request #2140 from versity/test/util_list_objects
test: ListObjects util code cleanup, multipart updates
2026-05-21 08:14:21 -07:00
Ben McClelland 6fd0b1395e Merge pull request #2145 from versity/dependabot/go_modules/dev-dependencies-a5fc3ebefd
chore(deps): bump github.com/Azure/azure-sdk-for-go/sdk/storage/azblob from 1.6.4 to 1.7.0 in the dev-dependencies group
2026-05-21 08:13:47 -07:00
Luke McCrone 48f79a6171 test: ListObjects util code reorg, return value/multipart fixes 2026-05-20 14:30:41 -03:00
dependabot[bot] 3cf10d8392 chore(deps): bump github.com/Azure/azure-sdk-for-go/sdk/storage/azblob
Bumps the dev-dependencies group with 1 update: [github.com/Azure/azure-sdk-for-go/sdk/storage/azblob](https://github.com/Azure/azure-sdk-for-go).


Updates `github.com/Azure/azure-sdk-for-go/sdk/storage/azblob` from 1.6.4 to 1.7.0
- [Release notes](https://github.com/Azure/azure-sdk-for-go/releases)
- [Commits](https://github.com/Azure/azure-sdk-for-go/compare/sdk/storage/azblob/v1.6.4...sdk/azcore/v1.7.0)

---
updated-dependencies:
- dependency-name: github.com/Azure/azure-sdk-for-go/sdk/storage/azblob
  dependency-version: 1.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-19 05:58:47 +00:00
Ben McClelland 57beab26c8 Merge pull request #2137 from versity/test/test_rest_head_object 2026-05-14 15:03:18 -07:00
Luke McCrone fd8e4cd69c test: HeadObject query tests, more util code changes 2026-05-14 11:15:15 -03:00
Ben McClelland 6fe0841cc3 Merge pull request #2125 from versity/sis/compress-mp-metadata
fix: store object multipart upload metadata compressed
2026-05-13 11:54:17 -07:00
Ben McClelland 9fffac1297 Merge pull request #2139 from versity/ben/webui-space-encode
fix: decode URL hash in webui before parsing bucket/prefix
2026-05-13 11:48:11 -07:00
Ben McClelland acedcda2e8 Merge pull request #2138 from versity/ben/implicit-dir-objs
fix: ignore implicit directories for  Get/HeadObject
2026-05-13 11:47:15 -07:00
Ben McClelland a5fc7c1ee5 fix: decode URL hash in webui before parsing bucket/prefix
window.location.hash returns the hash percent-encoded by the browser,
so a prefix like "X Y/" is read back as "X%20Y/" (literal %20).
Without decoding, all subsequent operations (list, upload, create
folder) used the encoded string, causing the server to look
for a directory named "X%20Y/" instead of "X Y/" — resulting in empty
listings and uploads landing in a newly created "X%20Y/" directory.

Fix by calling decodeURIComponent() on the hash before splitting into
bucket and prefix parts.

Fixes #2098
2026-05-12 19:45:31 -07:00
Ben McClelland 2c0844ad88 fix: ignore implicit directories for Get/HeadObject
Directories that exist on the filesystem but were not explicitly created
via S3 (put-object with a key ending in '/') do not have an etag
value. ListObjectsV2 already uses the presence of this attribute to
decide whether to include a directory as an object. GetObject and
HeadObject were not performing this check, so they would successfully
return directories that ListObjectsV2 would not list.

Add the etag attribute check in GetObject and HeadObject: if a
directory path is requested but has no etag xattr, return 404. This
makes all three operations agree on which directories are S3 objects.

Fixes #2130
2026-05-12 18:56:00 -07:00
Ben McClelland 67c50ffa0e Merge pull request #2133 from versity/dependabot/github_actions/sigstore/cosign-installer-4.1.2
chore(deps): bump sigstore/cosign-installer from 4.1.1 to 4.1.2
2026-05-12 11:05:06 -07:00
Ben McClelland 9556e5b4e6 Merge pull request #2132 from versity/dependabot/go_modules/dev-dependencies-d72d03fc52 2026-05-11 21:52:08 -07:00
dependabot[bot] deda805c7d chore(deps): bump sigstore/cosign-installer from 4.1.1 to 4.1.2
Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 4.1.1 to 4.1.2.
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v4.1.1...v4.1.2)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-version: 4.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 03:32:57 +00:00
dependabot[bot] 2ed8b7873e chore(deps): bump the dev-dependencies group with 9 updates
Bumps the dev-dependencies group with 9 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager](https://github.com/aws/aws-sdk-go-v2) | `0.1.20` | `0.1.21` |
| [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) | `1.100.1` | `1.101.0` |
| [github.com/nats-io/nats.go](https://github.com/nats-io/nats.go) | `1.51.0` | `1.52.0` |
| [github.com/valyala/fasthttp](https://github.com/valyala/fasthttp) | `1.70.0` | `1.71.0` |
| [golang.org/x/sys](https://github.com/golang/sys) | `0.43.0` | `0.44.0` |
| [github.com/AzureAD/microsoft-authentication-library-for-go](https://github.com/AzureAD/microsoft-authentication-library-for-go) | `1.7.1` | `1.7.2` |
| [golang.org/x/crypto](https://github.com/golang/crypto) | `0.50.0` | `0.51.0` |
| [golang.org/x/net](https://github.com/golang/net) | `0.53.0` | `0.54.0` |
| [golang.org/x/text](https://github.com/golang/text) | `0.36.0` | `0.37.0` |


Updates `github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager` from 0.1.20 to 0.1.21
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/feature/s3/transfermanager/v0.1.20...feature/s3/transfermanager/v0.1.21)

Updates `github.com/aws/aws-sdk-go-v2/service/s3` from 1.100.1 to 1.101.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.100.1...service/s3/v1.101.0)

Updates `github.com/nats-io/nats.go` from 1.51.0 to 1.52.0
- [Release notes](https://github.com/nats-io/nats.go/releases)
- [Commits](https://github.com/nats-io/nats.go/compare/v1.51.0...v1.52.0)

Updates `github.com/valyala/fasthttp` from 1.70.0 to 1.71.0
- [Release notes](https://github.com/valyala/fasthttp/releases)
- [Commits](https://github.com/valyala/fasthttp/compare/v1.70.0...v1.71.0)

Updates `golang.org/x/sys` from 0.43.0 to 0.44.0
- [Commits](https://github.com/golang/sys/compare/v0.43.0...v0.44.0)

Updates `github.com/AzureAD/microsoft-authentication-library-for-go` from 1.7.1 to 1.7.2
- [Release notes](https://github.com/AzureAD/microsoft-authentication-library-for-go/releases)
- [Changelog](https://github.com/AzureAD/microsoft-authentication-library-for-go/blob/main/changelog.md)
- [Commits](https://github.com/AzureAD/microsoft-authentication-library-for-go/compare/v1.7.1...v1.7.2)

Updates `golang.org/x/crypto` from 0.50.0 to 0.51.0
- [Commits](https://github.com/golang/crypto/compare/v0.50.0...v0.51.0)

Updates `golang.org/x/net` from 0.53.0 to 0.54.0
- [Commits](https://github.com/golang/net/compare/v0.53.0...v0.54.0)

Updates `golang.org/x/text` from 0.36.0 to 0.37.0
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.36.0...v0.37.0)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager
  dependency-version: 0.1.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/s3
  dependency-version: 1.101.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/nats-io/nats.go
  dependency-version: 1.52.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/valyala/fasthttp
  dependency-version: 1.71.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/sys
  dependency-version: 0.44.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/AzureAD/microsoft-authentication-library-for-go
  dependency-version: 1.7.2
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/crypto
  dependency-version: 0.51.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/net
  dependency-version: 0.54.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/text
  dependency-version: 0.37.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-12 03:30:00 +00:00
Ben McClelland a0ab3f744d Merge pull request #2126 from versity/test/util_removal
test: more util code cleanup
2026-05-11 19:10:29 -07:00
Luke McCrone 37d6ca03ed test: util code cleanup 2026-05-11 16:34:54 -03:00
alexgalie fe3cfbfce9 fix: forward slash url encoded used as bucket/key separator
handle %2F ("/") url encoded separator for bucket/key

Fixes #2024

---------

Co-authored-by: Galie Alexandru MTANA <alexandru.galie@mt.com>
2026-05-11 10:31:02 -07:00
Ben McClelland e49bb1d76a Merge pull request #2121 from versity/test/test_rest_delete_objects 2026-05-09 09:14:52 -07:00
niksis02 5cb5541006 fix: store object multipart upload metadata compressed
Store multipart upload metadata through shared backend helpers so POSIX and Azure use the same encode/decode path. POSIX stores raw gzipped JSON in metadata stores, while Azure stores base64-encoded gzip for string metadata. Retrieval falls back to the legacy raw JSON format for existing objects. Storing the mp metadata compressed in posix will guarantee that for any allowed number of parts, the metadata won't exceed the xattr threshold(64KB).
2026-05-08 22:59:34 +04:00
Luke McCrone 6608c53612 test: DeleteObjects payload testing 2026-05-08 14:46:54 -03:00
Ben McClelland d94b2da5b7 Merge pull request #2118 from versity/ben/bucket-tags
feat: add bucket metrics tag when request specifies a bucket
2026-05-08 08:12:53 -07:00
Ben McClelland ff0cea3f83 Merge pull request #2094 from versity/ben/webui-search
feat: replace webui client-side name filter with server-side prefix filter
2026-05-06 16:30:02 -07:00
Ben McClelland 861c5f5d97 feat: add bucket metrics tag when request specifies a bucket
If the incoming request specifies a bucket name, add a tag
bucket=<bucketname> to the metric.

Fixes #2103
2026-05-06 13:46:08 -07: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
Ben McClelland cb609e40a6 feat: replace webui client-side name filter with server-side prefix filter
Remove the client-side search that filtered already-loaded objects by
name. Replace it with a prefix input that is appended to the current
path prefix and passed directly to the S3 ListObjectsV2 API, so
filtering is performed server-side and works correctly across all pages.

Fixes #2091
2026-05-06 12:34:52 -07:00