Commit Graph

2519 Commits

Author SHA1 Message Date
Ben McClelland fa789478d2 Merge pull request #2163 from versity/test/jailing
test: jailing (all code)
2026-06-10 20:24:13 -07:00
Luke McCrone 3a35e37b5c test: jailing, logging, executable cleanups 2026-06-10 12:46:27 -03:00
Ben McClelland 619fdb8dce Merge pull request #2171 from versity/sis/static-website-hosting
Static website hosting
2026-06-10 08:10:18 -07:00
Ben McClelland df6ee64ad6 Merge pull request #2175 from SebTardif/fix/nil-panic-ownership-controls
fix: prevent index-out-of-range panic in s3proxy GetBucketOwnershipControls
2026-06-10 08:07:25 -07:00
niksis02 f08f76fea4 feat: support x-amz-website-redirect-location
Integrate x-amz-website-redirect-location across object metadata flows so uploads, copies, multipart creation, HEAD, and GET preserve and return redirect locations, and website hosting applies object-level redirects from the stored value.
2026-06-10 12:41:55 +04:00
niksis02 1625c5963e feat: improve static website hosting support
Enhances the static website hosting implementation with more complete S3-compatible behavior across request handling, backend storage, validation, CORS, and errors.

Adds dedicated website endpoint handling for GET, HEAD, and OPTIONS requests, including index document resolution, error document serving, redirect-all support, pre-fetch and post-error routing rules, query string preservation in redirects, public access checks before object reads, and method-not-allowed responses.

Improves error handling for website responses by returning S3-compatible HTML error bodies with request IDs, host IDs, x-amz-error-code, x-amz-error-message, and specialized error fields. This also fixes website-related validation errors to return more accurate S3-style error codes and messages, including invalid redirect protocols, invalid HTTP redirect/error codes, conflicting routing rule replacements, routing rule limits, and oversized website configuration requests.

Adds website CORS support for GET, HEAD, and OPTIONS preflight requests, including bucket CORS lookup through website host bucket resolution, allowed origin/method/header validation, exposed header handling, ETag exposure, Vary headers, max-age handling, and CORS access-denied responses.

Adds debug logging around website configuration parsing, validation failures, CORS checks, backend lookup failures, and internal website error paths to make failures easier to diagnose.

Adds compressed website configuration storage so larger configs fit backend metadata limits, including gzip storage for POSIX extended attributes and base64-encoded compressed metadata for Azure. Also adds Azure PutBucketWebsite, GetBucketWebsite, and DeleteBucketWebsite support.

Adds and expands test coverage for website config validation, S3-compatible HTML error bodies, website routing behavior, public access enforcement, HEAD behavior, CORS handling, PutBucketWebsite limits, and end-to-end website hosting through a Docker-based dnsmasq test setup and CI workflow.
2026-06-10 12:41:55 +04:00
Marc Singer 375c2764d5 Add website integration tests and remove NotImplemented stubs
Replace PutBucketWebsite, GetBucketWebsite, DeleteBucketWebsite
NotImplemented test stubs with comprehensive integration tests covering:
- non-existing bucket errors
- validation (empty suffix, suffix with slash, invalid protocol, mutual
  exclusion of RedirectAllRequestsTo and IndexDocument)
- successful put/get round-trips for both index+error and redirect-all configs
- delete idempotency and verification

Signed-off-by: Marc Singer <marc@singer.gg>

Add error document serving, routing rules, and integration tests

Implement Features 1 and 2 of S3 static website hosting:

- WebsiteErrorDocument controller wrapper intercepts 4xx errors on
  website-enabled buckets and serves the configured error document or
  evaluates post-request routing rules (error code match redirects)
- ResolveWebsiteIndex middleware now caches parsed WebsiteConfiguration
  in context, handles RedirectAllRequestsTo, evaluates pre-request
  routing rules (key prefix match redirects), and rewrites directory
  keys for index document
- MatchPreRequestRule and MatchPostRequestRule methods on
  WebsiteConfiguration for routing rule evaluation
- 14 unit tests for routing rule matching
- 7 integration tests covering error document, routing rules,
  redirect-all, and index document behavior

Signed-off-by: Marc Singer <marc@singer.gg>

Add separate website hosting endpoint with virtual-host routing

Signed-off-by: Marc Singer <marc@singer.gg>

Support catch-all mode for website endpoint when --website-domain is omitted

Signed-off-by: Marc Singer <marc@singer.gg>
2026-06-10 12:41:51 +04:00
Marc Singer ac5c3b4a86 Add WebsiteConfiguration types, validation, and S3 error codes
Add S3 bucket website configuration types with XML serialization support
in s3response/website.go. Includes IndexDocument, ErrorDocument,
RedirectAllRequestsTo, and RoutingRules with full validation matching
AWS S3 behavior.

Add corresponding S3 error codes: ErrNoSuchWebsiteConfiguration,
ErrInvalidWebsiteConfiguration, ErrInvalidWebsiteSuffix, and
ErrInvalidWebsiteRedirectCode.

Unit tests cover validation logic, XML round-trip, and parsing.

Signed-off-by: Marc Singer <marc@singer.gg>

Add website backend interface and implementations for posix and s3proxy

Add PutBucketWebsite, GetBucketWebsite, and DeleteBucketWebsite methods
to the Backend interface with BackendUnsupported stubs that return
ErrNotImplemented.

Posix backend stores website config as a metadata attribute (key:
'website') following the same pattern as CORS. ScoutFS inherits via
embedding.

S3Proxy backend stores website config in the metadata bucket with
prefix 'vgw-meta-website-', consistent with existing ACL/policy/CORS
metadata storage. Returns ErrNoSuchWebsiteConfiguration when not found.

Signed-off-by: Marc Singer <marc@singer.gg>

Add website API controllers and wire into router

Add PutBucketWebsite, GetBucketWebsite, and DeleteBucketWebsite
controller methods following the same pattern as CORS. Controllers
parse and validate WebsiteConfiguration XML, check IAM authorization,
and delegate to the backend.

Replace the three HandleErrorRoute(ErrNotImplemented) stubs in the
router with the new controller methods. Regenerate the backend mock
to include the new interface methods.

Signed-off-by: Marc Singer <marc@singer.gg>

Add website index document middleware and wire into router

Add ResolveWebsiteIndex middleware that rewrites directory-like object keys
(empty or ending with /) to include the IndexDocument suffix when website
hosting is enabled. Also handles RedirectAllRequestsTo by returning 301.

Wire the middleware into both GetObject and HeadObject handler chains in
the router, positioned after BucketObjectNameValidator and before auth.

Signed-off-by: Marc Singer <marc@singer.gg>
2026-06-10 12:40:45 +04:00
Sebastien Tardif cf4bc65570 fix: prevent index-out-of-range panic in s3proxy GetBucketOwnershipControls
Add nil and length checks before accessing
resp.OwnershipControls.Rules[0]. If the upstream S3 backend returns
a response with nil OwnershipControls or empty Rules, the server
panics with an index-out-of-range error. Return
OwnershipControlsNotFoundError instead, matching the behavior of
the posix and azure backends.

This bug was introduced in commit 7545e623 (2024-06-28) when bucket
ownership controls were first implemented for the s3proxy backend.

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
2026-06-09 19:49:07 -07:00
Ben McClelland 8ae0d36d80 Merge pull request #2173 from SebTardif/fix/webhook-sendlog-nil-panic
fix: prevent nil pointer panic in webhook sendLog
2026-06-09 16:43:24 -07:00
Ben McClelland e871c4044f Merge pull request #2168 from versity/test/jailing_base
test: jailing work (base)
2026-06-09 16:04:14 -07:00
Luke McCrone f826f13a64 test: jailing work (base) 2026-06-09 14:55:47 -03:00
Sebastien Tardif 50e64f7e78 fix: prevent nil pointer panic in webhook sendLog
Add missing return statements after error checks in sendLog. When
json.Marshal or http.NewRequest fails, the error is logged but
execution continues. If http.NewRequest returns a nil *Request,
the subsequent req.Header.Set call panics with a nil pointer
dereference.

This bug was introduced in PR #129 (2023-07-14) and has been
present for nearly 3 years.

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
2026-06-08 18:45:53 -07:00
Ben McClelland b348ff29f0 Merge pull request #2170 from SebTardif/fix/parse-copy-source-empty-panic
fix: prevent panic in ParseCopySource on empty input
2026-06-08 16:21:20 -07:00
Ben McClelland 2a622fcc05 Merge pull request #2172 from versity/dependabot/go_modules/dev-dependencies-f0a335229e
chore(deps): bump the dev-dependencies group with 24 updates
2026-06-08 15:41:47 -07:00
dependabot[bot] 2a40e19ef5 chore(deps): bump the dev-dependencies group with 24 updates
Bumps the dev-dependencies group with 24 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/Azure/azure-sdk-for-go/sdk/azcore](https://github.com/Azure/azure-sdk-for-go) | `1.21.1` | `1.22.0` |
| [github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2) | `1.41.11` | `1.42.0` |
| [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2) | `1.32.22` | `1.32.24` |
| [github.com/aws/aws-sdk-go-v2/credentials](https://github.com/aws/aws-sdk-go-v2) | `1.19.21` | `1.19.23` |
| [github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager](https://github.com/aws/aws-sdk-go-v2) | `0.2.5` | `0.2.9` |
| [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) | `1.103.1` | `1.103.3` |
| [github.com/aws/smithy-go](https://github.com/aws/smithy-go) | `1.27.0` | `1.27.1` |
| [golang.org/x/sync](https://github.com/golang/sync) | `0.20.0` | `0.21.0` |
| [golang.org/x/sys](https://github.com/golang/sys) | `0.45.0` | `0.46.0` |
| [github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream](https://github.com/aws/aws-sdk-go-v2) | `1.7.12` | `1.7.13` |
| [github.com/aws/aws-sdk-go-v2/feature/ec2/imds](https://github.com/aws/aws-sdk-go-v2) | `1.18.27` | `1.18.29` |
| [github.com/aws/aws-sdk-go-v2/internal/configsources](https://github.com/aws/aws-sdk-go-v2) | `1.4.27` | `1.4.29` |
| [github.com/aws/aws-sdk-go-v2/internal/endpoints/v2](https://github.com/aws/aws-sdk-go-v2) | `2.7.27` | `2.7.29` |
| [github.com/aws/aws-sdk-go-v2/internal/v4a](https://github.com/aws/aws-sdk-go-v2) | `1.4.28` | `1.4.30` |
| [github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding](https://github.com/aws/aws-sdk-go-v2) | `1.13.11` | `1.13.12` |
| [github.com/aws/aws-sdk-go-v2/service/internal/checksum](https://github.com/aws/aws-sdk-go-v2) | `1.9.20` | `1.9.22` |
| [github.com/aws/aws-sdk-go-v2/service/internal/presigned-url](https://github.com/aws/aws-sdk-go-v2) | `1.13.27` | `1.13.29` |
| [github.com/aws/aws-sdk-go-v2/service/internal/s3shared](https://github.com/aws/aws-sdk-go-v2) | `1.19.27` | `1.19.29` |
| [github.com/aws/aws-sdk-go-v2/service/signin](https://github.com/aws/aws-sdk-go-v2) | `1.1.3` | `1.1.5` |
| [github.com/aws/aws-sdk-go-v2/service/sso](https://github.com/aws/aws-sdk-go-v2) | `1.31.1` | `1.31.3` |
| [github.com/aws/aws-sdk-go-v2/service/ssooidc](https://github.com/aws/aws-sdk-go-v2) | `1.36.4` | `1.36.6` |
| [github.com/aws/aws-sdk-go-v2/service/sts](https://github.com/aws/aws-sdk-go-v2) | `1.43.1` | `1.43.3` |
| [golang.org/x/crypto](https://github.com/golang/crypto) | `0.52.0` | `0.53.0` |
| [golang.org/x/text](https://github.com/golang/text) | `0.37.0` | `0.38.0` |


Updates `github.com/Azure/azure-sdk-for-go/sdk/azcore` from 1.21.1 to 1.22.0
- [Release notes](https://github.com/Azure/azure-sdk-for-go/releases)
- [Commits](https://github.com/Azure/azure-sdk-for-go/compare/sdk/azcore/v1.21.1...sdk/azcore/v1.22.0)

Updates `github.com/aws/aws-sdk-go-v2` from 1.41.11 to 1.42.0
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.41.11...v1.42.0)

Updates `github.com/aws/aws-sdk-go-v2/config` from 1.32.22 to 1.32.24
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.32.22...config/v1.32.24)

Updates `github.com/aws/aws-sdk-go-v2/credentials` from 1.19.21 to 1.19.23
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/credentials/v1.19.21...credentials/v1.19.23)

Updates `github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager` from 0.2.5 to 0.2.9
- [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.2.5...feature/s3/transfermanager/v0.2.9)

Updates `github.com/aws/aws-sdk-go-v2/service/s3` from 1.103.1 to 1.103.3
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.103.1...service/s3/v1.103.3)

Updates `github.com/aws/smithy-go` from 1.27.0 to 1.27.1
- [Release notes](https://github.com/aws/smithy-go/releases)
- [Changelog](https://github.com/aws/smithy-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/aws/smithy-go/compare/v1.27.0...v1.27.1)

Updates `golang.org/x/sync` from 0.20.0 to 0.21.0
- [Commits](https://github.com/golang/sync/compare/v0.20.0...v0.21.0)

Updates `golang.org/x/sys` from 0.45.0 to 0.46.0
- [Commits](https://github.com/golang/sys/compare/v0.45.0...v0.46.0)

Updates `github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream` from 1.7.12 to 1.7.13
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/account/v1.7.12...service/account/v1.7.13)

Updates `github.com/aws/aws-sdk-go-v2/feature/ec2/imds` from 1.18.27 to 1.18.29
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.18.27...config/v1.18.29)

Updates `github.com/aws/aws-sdk-go-v2/internal/configsources` from 1.4.27 to 1.4.29
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/internal/v4a/v1.4.27...internal/v4a/v1.4.29)

Updates `github.com/aws/aws-sdk-go-v2/internal/endpoints/v2` from 2.7.27 to 2.7.29
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/internal/endpoints/v2.7.27...internal/endpoints/v2.7.29)

Updates `github.com/aws/aws-sdk-go-v2/internal/v4a` from 1.4.28 to 1.4.30
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/internal/v4a/v1.4.28...internal/v4a/v1.4.30)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding` from 1.13.11 to 1.13.12
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/mq/v1.13.11...service/mq/v1.13.12)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/checksum` from 1.9.20 to 1.9.22
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/memorydb/v1.9.20...feature/cloudfront/sign/v1.9.22)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/presigned-url` from 1.13.27 to 1.13.29
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/credentials/v1.13.27...credentials/v1.13.29)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/s3shared` from 1.19.27 to 1.19.29
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/internal/s3shared/v1.19.27...service/internal/s3shared/v1.19.29)

Updates `github.com/aws/aws-sdk-go-v2/service/signin` from 1.1.3 to 1.1.5
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.1.3...config/v1.1.5)

Updates `github.com/aws/aws-sdk-go-v2/service/sso` from 1.31.1 to 1.31.3
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.31.1...config/v1.31.3)

Updates `github.com/aws/aws-sdk-go-v2/service/ssooidc` from 1.36.4 to 1.36.6
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.36.4...v1.36.6)

Updates `github.com/aws/aws-sdk-go-v2/service/sts` from 1.43.1 to 1.43.3
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.43.1...service/amp/v1.43.3)

Updates `golang.org/x/crypto` from 0.52.0 to 0.53.0
- [Commits](https://github.com/golang/crypto/compare/v0.52.0...v0.53.0)

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

---
updated-dependencies:
- dependency-name: github.com/Azure/azure-sdk-for-go/sdk/azcore
  dependency-version: 1.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2
  dependency-version: 1.42.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/config
  dependency-version: 1.32.24
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/credentials
  dependency-version: 1.19.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager
  dependency-version: 0.2.9
  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.103.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/smithy-go
  dependency-version: 1.27.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/sync
  dependency-version: 0.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/sys
  dependency-version: 0.46.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream
  dependency-version: 1.7.13
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/feature/ec2/imds
  dependency-version: 1.18.29
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/internal/configsources
  dependency-version: 1.4.29
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/internal/endpoints/v2
  dependency-version: 2.7.29
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/internal/v4a
  dependency-version: 1.4.30
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding
  dependency-version: 1.13.12
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/checksum
  dependency-version: 1.9.22
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/presigned-url
  dependency-version: 1.13.29
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/s3shared
  dependency-version: 1.19.29
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/signin
  dependency-version: 1.1.5
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/sso
  dependency-version: 1.31.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/ssooidc
  dependency-version: 1.36.6
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/sts
  dependency-version: 1.43.3
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/crypto
  dependency-version: 0.53.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: golang.org/x/text
  dependency-version: 0.38.0
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-08 21:27:20 +00:00
Sebastien Tardif 422b5a7024 fix: prevent panic in ParseCopySource on empty input
ParseCopySource indexes into copySourceHeader[0] without checking
for an empty string, causing an index-out-of-range panic.

The three backend callers (azure, posix) pass the x-amz-copy-source
header value directly, so a malformed or missing header propagates
an empty string into ParseCopySource.

Add an empty-string guard at the top of the function that returns
an InvalidArgCopySourceBucket error, consistent with the existing
error returned when the source path has no bucket/object separator.

Add a table-driven test case that reproduces the panic without the
fix and verifies the correct error with the fix.

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
2026-06-08 12:04:03 -07:00
Ben McClelland aa52aa08d7 Merge pull request #2167 from miretskiy/add-on-listen-hook
s3api: add WithOnListen option for server readiness notification
2026-06-06 09:11:04 -07:00
Ben McClelland 2eb3736906 Merge pull request #2166 from versity/dependabot/go_modules/dev-dependencies-e023225741
chore(deps): bump the dev-dependencies group with 23 updates
2026-06-05 15:24:21 -07:00
Yevgeniy Miretskiy 8495cf42b6 s3api: add WithOnListen option for server readiness notification
WithOnListen registers a callback invoked once the server is bound and
ready to accept connections. It wraps fiber's existing OnListen hook,
which fires immediately before the first connection is served.

This allows callers to detect readiness deterministically rather than
relying on a fixed sleep or polling a health endpoint.

Example use in tests:

    ready := make(chan struct{})
    srv, _ := s3api.New(..., s3api.WithOnListen(func() { close(ready) }))
    go srv.ServeMultiPort([]string{addr})
    <-ready // blocks until the server is accepting connections
2026-06-05 07:24:33 -04:00
dependabot[bot] 8453a5b7e0 chore(deps): bump the dev-dependencies group with 23 updates
Bumps the dev-dependencies group with 23 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2) | `1.41.7` | `1.41.11` |
| [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2) | `1.32.18` | `1.32.22` |
| [github.com/aws/aws-sdk-go-v2/credentials](https://github.com/aws/aws-sdk-go-v2) | `1.19.17` | `1.19.21` |
| [github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager](https://github.com/aws/aws-sdk-go-v2) | `0.1.22` | `0.2.5` |
| [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) | `1.101.0` | `1.103.1` |
| [github.com/aws/smithy-go](https://github.com/aws/smithy-go) | `1.25.1` | `1.27.0` |
| [github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream](https://github.com/aws/aws-sdk-go-v2) | `1.7.10` | `1.7.12` |
| [github.com/aws/aws-sdk-go-v2/feature/ec2/imds](https://github.com/aws/aws-sdk-go-v2) | `1.18.23` | `1.18.27` |
| [github.com/aws/aws-sdk-go-v2/internal/configsources](https://github.com/aws/aws-sdk-go-v2) | `1.4.23` | `1.4.27` |
| [github.com/aws/aws-sdk-go-v2/internal/endpoints/v2](https://github.com/aws/aws-sdk-go-v2) | `2.7.23` | `2.7.27` |
| [github.com/aws/aws-sdk-go-v2/internal/v4a](https://github.com/aws/aws-sdk-go-v2) | `1.4.24` | `1.4.28` |
| [github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding](https://github.com/aws/aws-sdk-go-v2) | `1.13.9` | `1.13.11` |
| [github.com/aws/aws-sdk-go-v2/service/internal/checksum](https://github.com/aws/aws-sdk-go-v2) | `1.9.15` | `1.9.20` |
| [github.com/aws/aws-sdk-go-v2/service/internal/presigned-url](https://github.com/aws/aws-sdk-go-v2) | `1.13.23` | `1.13.27` |
| [github.com/aws/aws-sdk-go-v2/service/internal/s3shared](https://github.com/aws/aws-sdk-go-v2) | `1.19.23` | `1.19.27` |
| [github.com/aws/aws-sdk-go-v2/service/signin](https://github.com/aws/aws-sdk-go-v2) | `1.0.11` | `1.1.3` |
| [github.com/aws/aws-sdk-go-v2/service/sso](https://github.com/aws/aws-sdk-go-v2) | `1.30.17` | `1.31.1` |
| [github.com/aws/aws-sdk-go-v2/service/ssooidc](https://github.com/aws/aws-sdk-go-v2) | `1.36.0` | `1.36.4` |
| [github.com/aws/aws-sdk-go-v2/service/sts](https://github.com/aws/aws-sdk-go-v2) | `1.42.1` | `1.43.1` |
| [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable) | `0.1.14` | `0.1.15` |
| [github.com/mattn/go-runewidth](https://github.com/mattn/go-runewidth) | `0.0.23` | `0.0.24` |
| [github.com/nats-io/nkeys](https://github.com/nats-io/nkeys) | `0.4.15` | `0.4.16` |
| [github.com/pierrec/lz4/v4](https://github.com/pierrec/lz4) | `4.1.26` | `4.1.27` |


Updates `github.com/aws/aws-sdk-go-v2` from 1.41.7 to 1.41.11
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.41.7...v1.41.11)

Updates `github.com/aws/aws-sdk-go-v2/config` from 1.32.18 to 1.32.22
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.32.18...config/v1.32.22)

Updates `github.com/aws/aws-sdk-go-v2/credentials` from 1.19.17 to 1.19.21
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/credentials/v1.19.17...credentials/v1.19.21)

Updates `github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager` from 0.1.22 to 0.2.5
- [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.22...feature/s3/transfermanager/v0.2.5)

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

Updates `github.com/aws/smithy-go` from 1.25.1 to 1.27.0
- [Release notes](https://github.com/aws/smithy-go/releases)
- [Changelog](https://github.com/aws/smithy-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/aws/smithy-go/compare/v1.25.1...v1.27.0)

Updates `github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream` from 1.7.10 to 1.7.12
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/account/v1.7.10...service/account/v1.7.12)

Updates `github.com/aws/aws-sdk-go-v2/feature/ec2/imds` from 1.18.23 to 1.18.27
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.18.23...config/v1.18.27)

Updates `github.com/aws/aws-sdk-go-v2/internal/configsources` from 1.4.23 to 1.4.27
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/internal/v4a/v1.4.23...internal/v4a/v1.4.27)

Updates `github.com/aws/aws-sdk-go-v2/internal/endpoints/v2` from 2.7.23 to 2.7.27
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/internal/endpoints/v2.7.23...internal/endpoints/v2.7.27)

Updates `github.com/aws/aws-sdk-go-v2/internal/v4a` from 1.4.24 to 1.4.28
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/internal/v4a/v1.4.24...internal/v4a/v1.4.28)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding` from 1.13.9 to 1.13.11
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/mq/v1.13.9...service/mq/v1.13.11)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/checksum` from 1.9.15 to 1.9.20
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/grafana/v1.9.15...service/memorydb/v1.9.20)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/presigned-url` from 1.13.23 to 1.13.27
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/credentials/v1.13.23...credentials/v1.13.27)

Updates `github.com/aws/aws-sdk-go-v2/service/internal/s3shared` from 1.19.23 to 1.19.27
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/simspaceweaver/v1.19.23...service/internal/s3shared/v1.19.27)

Updates `github.com/aws/aws-sdk-go-v2/service/signin` from 1.0.11 to 1.1.3
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/internal/v4a/v1.0.11...config/v1.1.3)

Updates `github.com/aws/aws-sdk-go-v2/service/sso` from 1.30.17 to 1.31.1
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/acm/v1.30.17...config/v1.31.1)

Updates `github.com/aws/aws-sdk-go-v2/service/ssooidc` from 1.36.0 to 1.36.4
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.36.0...v1.36.4)

Updates `github.com/aws/aws-sdk-go-v2/service/sts` from 1.42.1 to 1.43.1
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.42.1...service/s3/v1.43.1)

Updates `github.com/mattn/go-colorable` from 0.1.14 to 0.1.15
- [Commits](https://github.com/mattn/go-colorable/compare/v0.1.14...v0.1.15)

Updates `github.com/mattn/go-runewidth` from 0.0.23 to 0.0.24
- [Commits](https://github.com/mattn/go-runewidth/compare/v0.0.23...v0.0.24)

Updates `github.com/nats-io/nkeys` from 0.4.15 to 0.4.16
- [Release notes](https://github.com/nats-io/nkeys/releases)
- [Commits](https://github.com/nats-io/nkeys/compare/v0.4.15...v0.4.16)

Updates `github.com/pierrec/lz4/v4` from 4.1.26 to 4.1.27
- [Release notes](https://github.com/pierrec/lz4/releases)
- [Commits](https://github.com/pierrec/lz4/compare/v4.1.26...v4.1.27)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go-v2
  dependency-version: 1.41.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/config
  dependency-version: 1.32.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/credentials
  dependency-version: 1.19.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager
  dependency-version: 0.2.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/s3
  dependency-version: 1.103.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/smithy-go
  dependency-version: 1.27.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream
  dependency-version: 1.7.12
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/feature/ec2/imds
  dependency-version: 1.18.27
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/internal/configsources
  dependency-version: 1.4.27
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/internal/endpoints/v2
  dependency-version: 2.7.27
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/internal/v4a
  dependency-version: 1.4.28
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding
  dependency-version: 1.13.11
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/checksum
  dependency-version: 1.9.20
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/presigned-url
  dependency-version: 1.13.27
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/internal/s3shared
  dependency-version: 1.19.27
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/signin
  dependency-version: 1.1.3
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/sso
  dependency-version: 1.31.1
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/ssooidc
  dependency-version: 1.36.4
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/aws/aws-sdk-go-v2/service/sts
  dependency-version: 1.43.1
  dependency-type: indirect
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: github.com/mattn/go-colorable
  dependency-version: 0.1.15
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/mattn/go-runewidth
  dependency-version: 0.0.24
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/nats-io/nkeys
  dependency-version: 0.4.16
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
- dependency-name: github.com/pierrec/lz4/v4
  dependency-version: 4.1.27
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-03 08:50:56 +00:00
Ben McClelland 31ae498609 Merge pull request #2160 from versity/ben/eof-err
fix: connection early termination resulting in internal error
v1.5.0
2026-06-01 14:02:21 -07:00
Ben McClelland e137e8d375 fix: connection early termination resulting in internal error
When the connection terminates before all bytes read, we were
getting an io.ErrUnexpectedEOF that was not being handled as
a standard io.EOF resulting in an internal error being raised.
Translate io.ErrUnexpectedEOF to io.EOF so that we return the
normal errors for unexpected content. Add a log message so
that its clear the error is due to the connection being
terminated before all data sent and not the fault of the
gateway.
2026-06-01 10:12:41 -07:00
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