mirror of
https://github.com/versity/versitygw.git
synced 2026-04-17 11:21:03 +00:00
Closes #1648 Fixes #1980 Fixes #1981 This PR implements browser-based POST object uploads for S3-compatible form uploads. It adds support for handling `multipart/form-data` object uploads submitted from browsers, including streaming multipart parsing so file content is not buffered in memory, POST policy decoding and evaluation, SigV4-based form authorization, and integration with the existing `PutObject` backend flow. The implementation covers the full browser POST upload path, including validation of required form fields, credential scope and request date checks, signature verification, metadata extraction from `x-amz-meta-*` fields, checksum field parsing, object tagging conversion from XML into the query-string format expected by `PutObject`, and browser-compatible success handling through `success_action_status` and `success_action_redirect`. It also wires the new flow into the router and metrics layer and adds POST-specific error handling and debug logging across policy parsing, multipart parsing, and POST authorization. AWS S3 also accepts the `redirect` form field alongside `success_action_redirect`, but since AWS has marked `redirect` as deprecated and is planning to remove it, this gateway intentionally does not support it.
75 lines
2.3 KiB
Go
75 lines
2.3 KiB
Go
// Copyright 2023 Versity Software
|
|
// This file is licensed under the Apache License, Version 2.0
|
|
// (the "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
package utils
|
|
|
|
import (
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
// Region, StartTime, IsRoot, Account, AccessKey context locals
|
|
// are set to default values in middlewares.SetDefaultValues
|
|
// to avoid the nil interface conversions
|
|
type ContextKey string
|
|
|
|
const (
|
|
ContextKeyRegion ContextKey = "region"
|
|
ContextKeyStartTime ContextKey = "start-time"
|
|
ContextKeyIsRoot ContextKey = "is-root"
|
|
ContextKeyRootAccessKey ContextKey = "root-access-key"
|
|
ContextKeyAccount ContextKey = "account"
|
|
ContextKeyAuthenticated ContextKey = "authenticated"
|
|
ContextKeyPublicBucket ContextKey = "public-bucket"
|
|
ContextKeyParsedAcl ContextKey = "parsed-acl"
|
|
ContextKeySkipResBodyLog ContextKey = "skip-res-body-log"
|
|
ContextKeyBodyReader ContextKey = "body-reader"
|
|
ContextKeySkip ContextKey = "__skip"
|
|
ContextKeyStack ContextKey = "stack"
|
|
ContextKeyBucketOwner ContextKey = "bucket-owner"
|
|
ContextKeyObjectPostResult ContextKey = "object-post-result"
|
|
)
|
|
|
|
func (ck ContextKey) Values() []ContextKey {
|
|
return []ContextKey{
|
|
ContextKeyRegion,
|
|
ContextKeyStartTime,
|
|
ContextKeyIsRoot,
|
|
ContextKeyRootAccessKey,
|
|
ContextKeyAccount,
|
|
ContextKeyAuthenticated,
|
|
ContextKeyPublicBucket,
|
|
ContextKeyParsedAcl,
|
|
ContextKeySkipResBodyLog,
|
|
ContextKeyBodyReader,
|
|
ContextKeyBucketOwner,
|
|
}
|
|
}
|
|
|
|
func (ck ContextKey) Set(ctx *fiber.Ctx, val any) {
|
|
ctx.Locals(string(ck), val)
|
|
}
|
|
|
|
func (ck ContextKey) IsSet(ctx *fiber.Ctx) bool {
|
|
val := ctx.Locals(string(ck))
|
|
return val != nil
|
|
}
|
|
|
|
func (ck ContextKey) Delete(ctx *fiber.Ctx) {
|
|
ctx.Locals(string(ck), nil)
|
|
}
|
|
|
|
func (ck ContextKey) Get(ctx *fiber.Ctx) any {
|
|
return ctx.Locals(string(ck))
|
|
}
|