mirror of
https://github.com/versity/versitygw.git
synced 2026-08-28 03:46:17 +00:00
feat: fiber migration v2 -> v3
Fiber has released a new major version, **v3.0.0**, introducing several breaking changes. As part of the gateway migration from Fiber v2 to v3, the `filesystem` middleware has been deprecated and replaced with the `static` middleware for serving web assets. Currently, Fiber’s `static` middleware contains a bug in how it resolves the filesystem root path. Because of this, `fs.Sub` is used to set the embedded `web` directory as the effective root of the filesystem.
This commit is contained in:
@@ -959,12 +959,15 @@ func runGateway(ctx context.Context, be backend.Backend) error {
|
||||
webOpts = append(webOpts, webui.WithQuiet())
|
||||
}
|
||||
|
||||
webSrv = webui.NewServer(&webui.ServerConfig{
|
||||
webSrv, err = webui.NewServer(&webui.ServerConfig{
|
||||
ListenAddr: webuiAddr,
|
||||
Gateways: gateways,
|
||||
AdminGateways: adminGateways,
|
||||
Region: region,
|
||||
}, webOpts...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("initialize webui: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if !quiet {
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
type Color string
|
||||
@@ -60,7 +60,7 @@ func printError(prefix prefix, er error) {
|
||||
}
|
||||
|
||||
// Logs http request details: headers, body, params, query args
|
||||
func LogFiberRequestDetails(ctx *fiber.Ctx) {
|
||||
func LogFiberRequestDetails(ctx fiber.Ctx) {
|
||||
// Log the full request url
|
||||
fullURL := ctx.Protocol() + "://" + ctx.Hostname() + ctx.OriginalURL()
|
||||
fmt.Printf("%s[URL]: %s%s\n", green, fullURL, reset)
|
||||
@@ -90,7 +90,7 @@ func LogFiberRequestDetails(ctx *fiber.Ctx) {
|
||||
}
|
||||
|
||||
// Logs http response details: body, headers
|
||||
func LogFiberResponseDetails(ctx *fiber.Ctx) {
|
||||
func LogFiberResponseDetails(ctx fiber.Ctx) {
|
||||
wrapInBox(green, "RESPONSE HEADERS", boxWidth, func() {
|
||||
for key, value := range ctx.Response().Header.All() {
|
||||
printWrappedLine(yellow, string(key), string(value))
|
||||
@@ -265,7 +265,7 @@ func wrapText(text string, width int) []string {
|
||||
|
||||
// TODO: remove this and use utils.IsBidDataAction after refactoring
|
||||
// and creating 'internal' package
|
||||
func isLargeDataAction(ctx *fiber.Ctx) bool {
|
||||
func isLargeDataAction(ctx fiber.Ctx) bool {
|
||||
if ctx.Method() == http.MethodPut && len(strings.Split(ctx.Path(), "/")) >= 3 {
|
||||
if !ctx.Request().URI().QueryArgs().Has("tagging") && ctx.Get("X-Amz-Copy-Source") == "" && !ctx.Request().URI().QueryArgs().Has("acl") {
|
||||
return true
|
||||
|
||||
@@ -14,7 +14,7 @@ require (
|
||||
github.com/aws/smithy-go v1.24.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/go-ldap/ldap/v3 v3.4.12
|
||||
github.com/gofiber/fiber/v2 v2.52.11
|
||||
github.com/gofiber/fiber/v3 v3.0.0
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/hashicorp/vault-client-go v0.4.3
|
||||
@@ -33,6 +33,11 @@ require (
|
||||
golang.org/x/sys v0.40.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
|
||||
github.com/Azure/go-ntlmssp v0.1.0 // indirect
|
||||
@@ -56,10 +61,10 @@ require (
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 // indirect
|
||||
github.com/clipperhouse/stringish v0.1.1 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.5.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
|
||||
github.com/gofiber/schema v1.6.0 // indirect
|
||||
github.com/gofiber/utils/v2 v2.0.0 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
||||
@@ -70,14 +75,15 @@ require (
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.19 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/nats-io/nuid v1.0.1 // indirect
|
||||
github.com/philhofer/fwd v1.2.0 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.25 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||
github.com/tinylib/msgp v1.6.3 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
||||
golang.org/x/crypto v0.47.0 // indirect
|
||||
|
||||
@@ -65,10 +65,6 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 h1:5fFjR/ToSOzB2OQ/XqWpZBmNvmP/
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6/go.mod h1:qgFDZQSD/Kys7nJnVqYlWKnh0SSdMjAi0uSwON4wgYQ=
|
||||
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
|
||||
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
|
||||
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
|
||||
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
|
||||
github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U=
|
||||
github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -76,12 +72,18 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-ldap/ldap/v3 v3.4.12 h1:1b81mv7MagXZ7+1r7cLTWmyuTqVqdwbtJSjC0DAp9s4=
|
||||
github.com/go-ldap/ldap/v3 v3.4.12/go.mod h1:+SPAGcTtOfmGsCb3h1RFiq4xpp4N636G75OEace8lNo=
|
||||
github.com/gofiber/fiber/v2 v2.52.11 h1:5f4yzKLcBcF8ha1GQTWB+mpblWz3Vz6nSAbTL31HkWs=
|
||||
github.com/gofiber/fiber/v2 v2.52.11/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
||||
github.com/gofiber/fiber/v3 v3.0.0 h1:GPeCG8X60L42wLKrzgeewDHBr6pE6veAvwaXsqD3Xjk=
|
||||
github.com/gofiber/fiber/v3 v3.0.0/go.mod h1:kVZiO/AwyT5Pq6PgC8qRCJ+j/BHrMy5jNw1O9yH38aY=
|
||||
github.com/gofiber/schema v1.6.0 h1:rAgVDFwhndtC+hgV7Vu5ItQCn7eC2mBA4Eu1/ZTiEYY=
|
||||
github.com/gofiber/schema v1.6.0/go.mod h1:WNZWpQx8LlPSK7ZaX0OqOh+nQo/eW2OevsXs1VZfs/s=
|
||||
github.com/gofiber/utils/v2 v2.0.0 h1:SCC3rpsEDWupFSHtc0RKxg/BKgV0s1qKfZg9Jv6D0sM=
|
||||
github.com/gofiber/utils/v2 v2.0.0/go.mod h1:xF9v89FfmbrYqI/bQUGN7gR8ZtXot2jxnZvmAUtiavE=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
@@ -131,8 +133,6 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
|
||||
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
|
||||
github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI=
|
||||
github.com/minio/crc64nvme v1.1.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
@@ -146,6 +146,8 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
|
||||
github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s=
|
||||
github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
|
||||
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
|
||||
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
|
||||
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
|
||||
github.com/pierrec/lz4/v4 v4.1.25 h1:kocOqRffaIbU5djlIBr7Wh+cx82C0vtFb0fOurZHqD0=
|
||||
github.com/pierrec/lz4/v4 v4.1.25/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
@@ -165,6 +167,8 @@ github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkB
|
||||
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||
github.com/segmentio/kafka-go v0.4.50 h1:mcyC3tT5WeyWzrFbd6O374t+hmcu1NKt2Pu1L3QaXmc=
|
||||
github.com/segmentio/kafka-go v0.4.50/go.mod h1:Y1gn60kzLEEaW28YshXyk2+VCUKbJ3Qr6DrnT3i4+9E=
|
||||
github.com/shamaton/msgpack/v3 v3.0.0 h1:xl40uxWkSpwBCSTvS5wyXvJRsC6AcVcYeox9PspKiZg=
|
||||
github.com/shamaton/msgpack/v3 v3.0.0/go.mod h1:DcQG8jrdrQCIxr3HlMYkiXdMhK+KfN2CitkyzsQV4uc=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smira/go-statsd v1.3.4 h1:kBYWcLSGT+qC6JVbvfz48kX7mQys32fjDOPrfmsSx2c=
|
||||
github.com/smira/go-statsd v1.3.4/go.mod h1:RjdsESPgDODtg1VpVVf9MJrEW2Hw0wtRNbmB1CAhu6A=
|
||||
@@ -179,6 +183,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/tinylib/msgp v1.6.3 h1:bCSxiTz386UTgyT1i0MSCvdbWjVW+8sG3PjkGsZQt4s=
|
||||
github.com/tinylib/msgp v1.6.3/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA=
|
||||
github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU=
|
||||
github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
@@ -187,6 +193,8 @@ github.com/valyala/fasthttp v1.69.0 h1:fNLLESD2SooWeh2cidsuFtOcrEi4uB4m1mPrkJMZy
|
||||
github.com/valyala/fasthttp v1.69.0/go.mod h1:4wA4PfAraPlAsJ5jMSqCE2ug5tqUPwKXxVj8oNECGcw=
|
||||
github.com/versity/scoutfs-go v0.0.0-20240625221833-95fd765b760b h1:kuqsuYRMG1c6YXBAQvWO7CiurlpYtjDJWI6oZ2K/ZZE=
|
||||
github.com/versity/scoutfs-go v0.0.0-20240625221833-95fd765b760b/go.mod h1:gJsq73k+4685y+rbDIpPY8i/5GbsiwP6JFoFyUDB1fQ=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
|
||||
+3
-3
@@ -23,7 +23,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
)
|
||||
|
||||
@@ -43,7 +43,7 @@ type Tag struct {
|
||||
|
||||
// Manager is the interface definition for metrics manager
|
||||
type Manager interface {
|
||||
Send(ctx *fiber.Ctx, err error, action string, count int64, status int)
|
||||
Send(ctx fiber.Ctx, err error, action string, count int64, status int)
|
||||
Close()
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ func NewManager(ctx context.Context, conf Config) (Manager, error) {
|
||||
return mgr, nil
|
||||
}
|
||||
|
||||
func (m *manager) Send(ctx *fiber.Ctx, err error, action string, count int64, status int) {
|
||||
func (m *manager) Send(ctx fiber.Ctx, err error, action string, count int64, status int) {
|
||||
// In case of Authentication failures, url parsing ...
|
||||
if action == "" {
|
||||
action = ActionUndetected
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
package s3api
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/metrics"
|
||||
|
||||
+21
-15
@@ -15,9 +15,9 @@
|
||||
package s3api
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||
"github.com/gofiber/fiber/v2/middleware/recover"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/middleware/logger"
|
||||
"github.com/gofiber/fiber/v3/middleware/recover"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
@@ -52,16 +52,14 @@ func NewAdminServer(be backend.Backend, root middlewares.RootUserConfig, port, r
|
||||
}
|
||||
|
||||
app := fiber.New(fiber.Config{
|
||||
AppName: "versitygw",
|
||||
ServerHeader: "VERSITYGW",
|
||||
Network: fiber.NetworkTCP,
|
||||
DisableStartupMessage: true,
|
||||
ErrorHandler: globalErrorHandler,
|
||||
AppName: "versitygw",
|
||||
ServerHeader: "VERSITYGW",
|
||||
ErrorHandler: globalErrorHandler,
|
||||
})
|
||||
|
||||
server.app = app
|
||||
|
||||
app.Use(recover.New(
|
||||
app.Use("*", recover.New(
|
||||
recover.Config{
|
||||
EnableStackTrace: true,
|
||||
StackTraceHandler: stackTraceHandler,
|
||||
@@ -69,15 +67,15 @@ func NewAdminServer(be backend.Backend, root middlewares.RootUserConfig, port, r
|
||||
|
||||
// Logging middlewares
|
||||
if !server.quiet {
|
||||
app.Use(logger.New(logger.Config{
|
||||
app.Use("*", logger.New(logger.Config{
|
||||
Format: "${time} | adm | ${status} | ${latency} | ${ip} | ${method} | ${path} | ${error} | ${queryParams}\n",
|
||||
}))
|
||||
}
|
||||
app.Use(controllers.WrapMiddleware(middlewares.DecodeURL, l, nil))
|
||||
app.Use("*", controllers.WrapMiddleware(middlewares.DecodeURL, l, nil))
|
||||
|
||||
// initialize the debug logger in debug mode
|
||||
if debuglogger.IsDebugEnabled() {
|
||||
app.Use(middlewares.DebugLogger())
|
||||
app.Use("*", middlewares.DebugLogger())
|
||||
}
|
||||
|
||||
server.router.Init(app, be, iam, l, root, region, server.debug, server.corsAllowOrigin)
|
||||
@@ -109,14 +107,22 @@ func WithAdminCORSAllowOrigin(origin string) AdminOpt {
|
||||
|
||||
func (sa *S3AdminServer) Serve() (err error) {
|
||||
if sa.CertStorage != nil {
|
||||
ln, err := utils.NewTLSListener(sa.app.Config().Network, sa.port, sa.CertStorage.GetCertificate)
|
||||
ln, err := utils.NewTLSListener(fiber.NetworkTCP, sa.port, sa.CertStorage.GetCertificate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sa.app.Listener(ln)
|
||||
return sa.app.Listener(ln,
|
||||
fiber.ListenConfig{
|
||||
ListenerNetwork: fiber.NetworkTCP,
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
}
|
||||
return sa.app.Listen(sa.port)
|
||||
return sa.app.Listen(sa.port,
|
||||
fiber.ListenConfig{
|
||||
ListenerNetwork: fiber.NetworkTCP,
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
}
|
||||
|
||||
// ShutDown gracefully shuts down the server with a context timeout
|
||||
|
||||
+13
-13
@@ -19,7 +19,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
@@ -38,9 +38,9 @@ func NewAdminController(iam auth.IAMService, be backend.Backend, l s3log.AuditLo
|
||||
return AdminController{iam: iam, be: be, l: l, s3api: s3api}
|
||||
}
|
||||
|
||||
func (c AdminController) CreateUser(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c AdminController) CreateUser(ctx fiber.Ctx) (*Response, error) {
|
||||
var usr auth.Account
|
||||
err := xml.Unmarshal(ctx.Body(), &usr)
|
||||
err := xml.Unmarshal(ctx.BodyRaw(), &usr)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{},
|
||||
@@ -71,7 +71,7 @@ func (c AdminController) CreateUser(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c AdminController) UpdateUser(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c AdminController) UpdateUser(ctx fiber.Ctx) (*Response, error) {
|
||||
access := ctx.Query("access")
|
||||
if access == "" {
|
||||
return &Response{
|
||||
@@ -80,7 +80,7 @@ func (c AdminController) UpdateUser(ctx *fiber.Ctx) (*Response, error) {
|
||||
}
|
||||
|
||||
var props auth.MutableProps
|
||||
if err := xml.Unmarshal(ctx.Body(), &props); err != nil {
|
||||
if err := xml.Unmarshal(ctx.BodyRaw(), &props); err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{},
|
||||
}, s3err.GetAPIError(s3err.ErrMalformedXML)
|
||||
@@ -109,7 +109,7 @@ func (c AdminController) UpdateUser(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c AdminController) DeleteUser(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c AdminController) DeleteUser(ctx fiber.Ctx) (*Response, error) {
|
||||
access := ctx.Query("access")
|
||||
if access == "" {
|
||||
return &Response{
|
||||
@@ -123,7 +123,7 @@ func (c AdminController) DeleteUser(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c AdminController) ListUsers(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c AdminController) ListUsers(ctx fiber.Ctx) (*Response, error) {
|
||||
accs, err := c.iam.ListUserAccounts()
|
||||
return &Response{
|
||||
Data: auth.ListUserAccountsResult{Accounts: accs},
|
||||
@@ -131,7 +131,7 @@ func (c AdminController) ListUsers(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c AdminController) ChangeBucketOwner(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c AdminController) ChangeBucketOwner(ctx fiber.Ctx) (*Response, error) {
|
||||
owner := ctx.Query("owner")
|
||||
bucket := ctx.Query("bucket")
|
||||
|
||||
@@ -147,14 +147,14 @@ func (c AdminController) ChangeBucketOwner(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, s3err.GetAPIError(s3err.ErrAdminUserNotFound)
|
||||
}
|
||||
|
||||
err = c.be.ChangeBucketOwner(ctx.Context(), bucket, owner)
|
||||
err = c.be.ChangeBucketOwner(ctx.RequestCtx(), bucket, owner)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{},
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c AdminController) ListBuckets(ctx *fiber.Ctx) (*Response, error) {
|
||||
buckets, err := c.be.ListBucketsAndOwners(ctx.Context())
|
||||
func (c AdminController) ListBuckets(ctx fiber.Ctx) (*Response, error) {
|
||||
buckets, err := c.be.ListBucketsAndOwners(ctx.RequestCtx())
|
||||
return &Response{
|
||||
Data: s3response.ListBucketsResult{
|
||||
Buckets: buckets,
|
||||
@@ -163,7 +163,7 @@ func (c AdminController) ListBuckets(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c AdminController) CreateBucket(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c AdminController) CreateBucket(ctx fiber.Ctx) (*Response, error) {
|
||||
owner := ctx.Get("x-vgw-owner")
|
||||
if owner == "" {
|
||||
return &Response{
|
||||
@@ -183,7 +183,7 @@ func (c AdminController) CreateBucket(ctx *fiber.Ctx) (*Response, error) {
|
||||
}
|
||||
|
||||
// store the owner access key id in context
|
||||
ctx.Context().SetUserValue("bucket-owner", acc)
|
||||
ctx.RequestCtx().SetUserValue("bucket-owner", acc)
|
||||
|
||||
_, err = c.s3api.CreateBucket(ctx)
|
||||
if err != nil {
|
||||
|
||||
+10
-10
@@ -21,7 +21,7 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
@@ -72,7 +72,7 @@ func New(be backend.Backend, iam auth.IAMService, logger s3log.AuditLogger, evs
|
||||
|
||||
// Returns MethodNotAllowed for unmatched routes
|
||||
func (c S3ApiController) HandleErrorRoute(err error) Controller {
|
||||
return func(ctx *fiber.Ctx) (*Response, error) {
|
||||
return func(ctx fiber.Ctx) (*Response, error) {
|
||||
return &Response{}, err
|
||||
}
|
||||
}
|
||||
@@ -107,11 +107,11 @@ type Services struct {
|
||||
}
|
||||
|
||||
// Controller is the type definition for an s3api controller
|
||||
type Controller func(ctx *fiber.Ctx) (*Response, error)
|
||||
type Controller func(ctx fiber.Ctx) (*Response, error)
|
||||
|
||||
// ProcessHandlers groups a controller and multiple middlewares into a single fiber handler
|
||||
func ProcessHandlers(controller Controller, s3action string, svc *Services, handlers ...fiber.Handler) fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
// if skip locals is set, skip to the next rout handler
|
||||
if utils.ContextKeySkip.IsSet(ctx) {
|
||||
utils.ContextKeySkip.Delete(ctx)
|
||||
@@ -121,7 +121,7 @@ func ProcessHandlers(controller Controller, s3action string, svc *Services, hand
|
||||
for _, handler := range handlers {
|
||||
err := handler(ctx)
|
||||
if err != nil {
|
||||
return ProcessController(ctx, func(ctx *fiber.Ctx) (*Response, error) {
|
||||
return ProcessController(ctx, func(ctx fiber.Ctx) (*Response, error) {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{},
|
||||
}, err
|
||||
@@ -136,14 +136,14 @@ func ProcessHandlers(controller Controller, s3action string, svc *Services, hand
|
||||
// WrapMiddleware executes the given middleware and handles sending the audit logs
|
||||
// and metrics. It also handles the error parsing
|
||||
func WrapMiddleware(handler fiber.Handler, logger s3log.AuditLogger, mm metrics.Manager) fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
err := handler(ctx)
|
||||
if err != nil {
|
||||
if mm != nil {
|
||||
mm.Send(ctx, err, metrics.ActionUndetected, 0, 0)
|
||||
}
|
||||
if logger != nil {
|
||||
logger.Log(ctx, err, ctx.Body(), s3log.LogMeta{
|
||||
logger.Log(ctx, err, ctx.BodyRaw(), s3log.LogMeta{
|
||||
Action: metrics.ActionUndetected,
|
||||
})
|
||||
}
|
||||
@@ -168,7 +168,7 @@ func WrapMiddleware(handler fiber.Handler, logger s3log.AuditLogger, mm metrics.
|
||||
|
||||
// ProcessController executes the given s3api controller and handles the metrics
|
||||
// access logs and s3 events
|
||||
func ProcessController(ctx *fiber.Ctx, controller Controller, s3action string, svc *Services) error {
|
||||
func ProcessController(ctx fiber.Ctx, controller Controller, s3action string, svc *Services) error {
|
||||
response, err := controller(ctx)
|
||||
|
||||
// Set the response headers
|
||||
@@ -316,7 +316,7 @@ func ProcessController(ctx *fiber.Ctx, controller Controller, s3action string, s
|
||||
return ctx.Send(res)
|
||||
}
|
||||
|
||||
func ensureExposeMetaHeaders(ctx *fiber.Ctx) {
|
||||
func ensureExposeMetaHeaders(ctx fiber.Ctx) {
|
||||
// Only attempt to modify expose headers when CORS is actually in use.
|
||||
if len(ctx.Response().Header.Peek("Access-Control-Allow-Origin")) == 0 {
|
||||
return
|
||||
@@ -388,7 +388,7 @@ func ensureExposeMetaHeaders(ctx *fiber.Ctx) {
|
||||
}
|
||||
|
||||
// Sets the response headers
|
||||
func SetResponseHeaders(ctx *fiber.Ctx, headers map[string]*string) {
|
||||
func SetResponseHeaders(ctx fiber.Ctx, headers map[string]*string) {
|
||||
if headers == nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/valyala/fasthttp"
|
||||
"github.com/versity/versitygw/auth"
|
||||
@@ -92,7 +92,7 @@ type ctxInputs struct {
|
||||
func testController(t *testing.T, ctrl Controller, resp *Response, expectedErr error, input ctxInputs) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Post("/:bucket/*", func(ctx *fiber.Ctx) error {
|
||||
app.Post("/:bucket/*", func(ctx fiber.Ctx) error {
|
||||
// set the request body
|
||||
ctx.Request().SetBody(input.body)
|
||||
// set the request locals
|
||||
@@ -256,23 +256,23 @@ func TestEnsureExposeMetaHeaders_AddsActualMetaHeaderNames(t *testing.T) {
|
||||
type mockAuditLogger struct {
|
||||
}
|
||||
|
||||
func (m *mockAuditLogger) Log(_ *fiber.Ctx, _ error, _ []byte, _ s3log.LogMeta) {}
|
||||
func (m *mockAuditLogger) HangUp() error { return nil }
|
||||
func (m *mockAuditLogger) Shutdown() error { return nil }
|
||||
func (m *mockAuditLogger) Log(_ fiber.Ctx, _ error, _ []byte, _ s3log.LogMeta) {}
|
||||
func (m *mockAuditLogger) HangUp() error { return nil }
|
||||
func (m *mockAuditLogger) Shutdown() error { return nil }
|
||||
|
||||
// mock S3 event sender
|
||||
type mockEvSender struct {
|
||||
}
|
||||
|
||||
func (m *mockEvSender) SendEvent(_ *fiber.Ctx, _ s3event.EventMeta) {}
|
||||
func (m *mockEvSender) Close() error { return nil }
|
||||
func (m *mockEvSender) SendEvent(_ fiber.Ctx, _ s3event.EventMeta) {}
|
||||
func (m *mockEvSender) Close() error { return nil }
|
||||
|
||||
// mock metrics manager
|
||||
|
||||
type mockMetricsManager struct{}
|
||||
|
||||
func (m *mockMetricsManager) Send(_ *fiber.Ctx, _ error, _ string, _ int64, _ int) {}
|
||||
func (m *mockMetricsManager) Close() {}
|
||||
func (m *mockMetricsManager) Send(_ fiber.Ctx, _ error, _ string, _ int64, _ int) {}
|
||||
func (m *mockMetricsManager) Close() {}
|
||||
|
||||
func TestProcessController(t *testing.T) {
|
||||
payload, err := xml.Marshal(s3response.Bucket{
|
||||
@@ -305,7 +305,7 @@ func TestProcessController(t *testing.T) {
|
||||
name: "no services successfull response",
|
||||
args: args{
|
||||
svc: &Services{},
|
||||
controller: func(ctx *fiber.Ctx) (*Response, error) {
|
||||
controller: func(ctx fiber.Ctx) (*Response, error) {
|
||||
return &Response{}, nil
|
||||
},
|
||||
},
|
||||
@@ -317,7 +317,7 @@ func TestProcessController(t *testing.T) {
|
||||
name: "handle api error",
|
||||
args: args{
|
||||
svc: services,
|
||||
controller: func(ctx *fiber.Ctx) (*Response, error) {
|
||||
controller: func(ctx fiber.Ctx) (*Response, error) {
|
||||
return &Response{}, s3err.GetAPIError(s3err.ErrInvalidRequest)
|
||||
},
|
||||
},
|
||||
@@ -330,7 +330,7 @@ func TestProcessController(t *testing.T) {
|
||||
name: "handle custom error",
|
||||
args: args{
|
||||
svc: services,
|
||||
controller: func(ctx *fiber.Ctx) (*Response, error) {
|
||||
controller: func(ctx fiber.Ctx) (*Response, error) {
|
||||
return &Response{}, errors.New("custom error")
|
||||
},
|
||||
},
|
||||
@@ -343,7 +343,7 @@ func TestProcessController(t *testing.T) {
|
||||
name: "body parsing fails",
|
||||
args: args{
|
||||
svc: services,
|
||||
controller: func(ctx *fiber.Ctx) (*Response, error) {
|
||||
controller: func(ctx fiber.Ctx) (*Response, error) {
|
||||
return &Response{
|
||||
Data: make(chan int),
|
||||
}, nil
|
||||
@@ -358,7 +358,7 @@ func TestProcessController(t *testing.T) {
|
||||
name: "no data payload",
|
||||
args: args{
|
||||
svc: services,
|
||||
controller: func(ctx *fiber.Ctx) (*Response, error) {
|
||||
controller: func(ctx fiber.Ctx) (*Response, error) {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
ObjectCount: 2,
|
||||
@@ -374,7 +374,7 @@ func TestProcessController(t *testing.T) {
|
||||
name: "should return 204 http status",
|
||||
args: args{
|
||||
svc: services,
|
||||
controller: func(ctx *fiber.Ctx) (*Response, error) {
|
||||
controller: func(ctx fiber.Ctx) (*Response, error) {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
Status: http.StatusNoContent,
|
||||
@@ -390,7 +390,7 @@ func TestProcessController(t *testing.T) {
|
||||
name: "already encoded payload",
|
||||
args: args{
|
||||
svc: services,
|
||||
controller: func(ctx *fiber.Ctx) (*Response, error) {
|
||||
controller: func(ctx fiber.Ctx) (*Response, error) {
|
||||
return &Response{
|
||||
Data: []byte("encoded_data"),
|
||||
}, nil
|
||||
@@ -408,7 +408,7 @@ func TestProcessController(t *testing.T) {
|
||||
name: "should set response headers",
|
||||
args: args{
|
||||
svc: services,
|
||||
controller: func(ctx *fiber.Ctx) (*Response, error) {
|
||||
controller: func(ctx fiber.Ctx) (*Response, error) {
|
||||
return &Response{
|
||||
Headers: map[string]*string{
|
||||
"X-Amz-My-Custom-Header": utils.GetStringPtr("my_value"),
|
||||
@@ -429,7 +429,7 @@ func TestProcessController(t *testing.T) {
|
||||
name: "large paylod: should return internal error",
|
||||
args: args{
|
||||
svc: services,
|
||||
controller: func(ctx *fiber.Ctx) (*Response, error) {
|
||||
controller: func(ctx fiber.Ctx) (*Response, error) {
|
||||
type Item struct {
|
||||
Value string `xml:"value"`
|
||||
}
|
||||
@@ -472,7 +472,7 @@ func TestProcessController(t *testing.T) {
|
||||
name: "not encoded payload",
|
||||
args: args{
|
||||
svc: services,
|
||||
controller: func(ctx *fiber.Ctx) (*Response, error) {
|
||||
controller: func(ctx fiber.Ctx) (*Response, error) {
|
||||
return &Response{
|
||||
Data: s3response.Bucket{
|
||||
Name: "something",
|
||||
@@ -546,10 +546,10 @@ func TestProcessHandlers(t *testing.T) {
|
||||
name: "handler returns error",
|
||||
args: args{
|
||||
handlers: []fiber.Handler{
|
||||
func(ctx *fiber.Ctx) error {
|
||||
func(ctx fiber.Ctx) error {
|
||||
return nil
|
||||
},
|
||||
func(ctx *fiber.Ctx) error {
|
||||
func(ctx fiber.Ctx) error {
|
||||
return s3err.GetAPIError(s3err.ErrAccessDenied)
|
||||
},
|
||||
},
|
||||
@@ -563,15 +563,15 @@ func TestProcessHandlers(t *testing.T) {
|
||||
name: "should process the controller",
|
||||
args: args{
|
||||
handlers: []fiber.Handler{
|
||||
func(ctx *fiber.Ctx) error {
|
||||
func(ctx fiber.Ctx) error {
|
||||
return nil
|
||||
},
|
||||
func(ctx *fiber.Ctx) error {
|
||||
func(ctx fiber.Ctx) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
svc: &Services{},
|
||||
controller: func(ctx *fiber.Ctx) (*Response, error) {
|
||||
controller: func(ctx fiber.Ctx) (*Response, error) {
|
||||
return &Response{
|
||||
Data: s3response.Checksum{
|
||||
CRC32: utils.GetStringPtr("crc32"),
|
||||
@@ -590,7 +590,7 @@ func TestProcessHandlers(t *testing.T) {
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Post("/:bucket/*", func(ctx *fiber.Ctx) error {
|
||||
app.Post("/:bucket/*", func(ctx fiber.Ctx) error {
|
||||
// set the request locals
|
||||
if tt.args.locals != nil {
|
||||
for key, val := range tt.args.locals {
|
||||
@@ -610,7 +610,7 @@ func TestProcessHandlers(t *testing.T) {
|
||||
return nil
|
||||
})
|
||||
|
||||
app.All("*", func(ctx *fiber.Ctx) error {
|
||||
app.All("*", func(ctx fiber.Ctx) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -639,7 +639,7 @@ func TestWrapMiddleware(t *testing.T) {
|
||||
{
|
||||
name: "handler returns no error",
|
||||
args: args{
|
||||
handler: func(ctx *fiber.Ctx) error {
|
||||
handler: func(ctx fiber.Ctx) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
@@ -647,7 +647,7 @@ func TestWrapMiddleware(t *testing.T) {
|
||||
{
|
||||
name: "handler returns api error",
|
||||
args: args{
|
||||
handler: func(ctx *fiber.Ctx) error {
|
||||
handler: func(ctx fiber.Ctx) error {
|
||||
return s3err.GetAPIError(s3err.ErrAclNotSupported)
|
||||
},
|
||||
mm: &mockMetricsManager{},
|
||||
@@ -660,7 +660,7 @@ func TestWrapMiddleware(t *testing.T) {
|
||||
{
|
||||
name: "handler returns custom error",
|
||||
args: args{
|
||||
handler: func(ctx *fiber.Ctx) error {
|
||||
handler: func(ctx fiber.Ctx) error {
|
||||
return errors.New("custom error")
|
||||
},
|
||||
},
|
||||
@@ -674,7 +674,7 @@ func TestWrapMiddleware(t *testing.T) {
|
||||
mdlwr := WrapMiddleware(tt.args.handler, tt.args.logger, tt.args.mm)
|
||||
app := fiber.New()
|
||||
|
||||
app.Post("/:bucket/*", func(ctx *fiber.Ctx) error {
|
||||
app.Post("/:bucket/*", func(ctx fiber.Ctx) error {
|
||||
// call the controller by passing the ctx
|
||||
err := mdlwr(ctx)
|
||||
assert.NoError(t, err)
|
||||
@@ -687,7 +687,7 @@ func TestWrapMiddleware(t *testing.T) {
|
||||
return nil
|
||||
})
|
||||
|
||||
app.All("*", func(ctx *fiber.Ctx) error {
|
||||
app.All("*", func(ctx fiber.Ctx) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
|
||||
@@ -17,19 +17,19 @@ package controllers
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
)
|
||||
|
||||
func (c S3ApiController) DeleteBucketTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) DeleteBucketTagging(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
IsBucketPublic := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -48,7 +48,7 @@ func (c S3ApiController) DeleteBucketTagging(ctx *fiber.Ctx) (*Response, error)
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.DeleteBucketTagging(ctx.Context(), bucket)
|
||||
err = c.be.DeleteBucketTagging(ctx.RequestCtx(), bucket)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
@@ -57,13 +57,13 @@ func (c S3ApiController) DeleteBucketTagging(ctx *fiber.Ctx) (*Response, error)
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) DeleteBucketOwnershipControls(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) DeleteBucketOwnershipControls(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -81,7 +81,7 @@ func (c S3ApiController) DeleteBucketOwnershipControls(ctx *fiber.Ctx) (*Respons
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.DeleteBucketOwnershipControls(ctx.Context(), bucket)
|
||||
err = c.be.DeleteBucketOwnershipControls(ctx.RequestCtx(), bucket)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
@@ -90,13 +90,13 @@ func (c S3ApiController) DeleteBucketOwnershipControls(ctx *fiber.Ctx) (*Respons
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) DeleteBucketPolicy(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) DeleteBucketPolicy(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -114,7 +114,7 @@ func (c S3ApiController) DeleteBucketPolicy(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.DeleteBucketPolicy(ctx.Context(), bucket)
|
||||
err = c.be.DeleteBucketPolicy(ctx.RequestCtx(), bucket)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
@@ -123,14 +123,14 @@ func (c S3ApiController) DeleteBucketPolicy(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) DeleteBucketCors(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) DeleteBucketCors(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
IsBucketPublic := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -149,7 +149,7 @@ func (c S3ApiController) DeleteBucketCors(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.DeleteBucketCors(ctx.Context(), bucket)
|
||||
err = c.be.DeleteBucketCors(ctx.RequestCtx(), bucket)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
@@ -158,14 +158,14 @@ func (c S3ApiController) DeleteBucketCors(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) DeleteBucket(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) DeleteBucket(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
IsBucketPublic := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -184,7 +184,7 @@ func (c S3ApiController) DeleteBucket(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.DeleteBucket(ctx.Context(), bucket)
|
||||
err = c.be.DeleteBucket(ctx.RequestCtx(), bucket)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
|
||||
@@ -19,20 +19,20 @@ import (
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
"github.com/versity/versitygw/s3response"
|
||||
)
|
||||
|
||||
func (c S3ApiController) GetBucketTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetBucketTagging(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -50,7 +50,7 @@ func (c S3ApiController) GetBucketTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
tags, err := c.be.GetBucketTagging(ctx.Context(), bucket)
|
||||
tags, err := c.be.GetBucketTagging(ctx.RequestCtx(), bucket)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -77,14 +77,14 @@ func (c S3ApiController) GetBucketTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) GetBucketOwnershipControls(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetBucketOwnershipControls(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -102,7 +102,7 @@ func (c S3ApiController) GetBucketOwnershipControls(ctx *fiber.Ctx) (*Response,
|
||||
}, err
|
||||
}
|
||||
|
||||
data, err := c.be.GetBucketOwnershipControls(ctx.Context(), bucket)
|
||||
data, err := c.be.GetBucketOwnershipControls(ctx.RequestCtx(), bucket)
|
||||
return &Response{
|
||||
Data: s3response.OwnershipControls{
|
||||
Rules: []types.OwnershipControlsRule{
|
||||
@@ -117,14 +117,14 @@ func (c S3ApiController) GetBucketOwnershipControls(ctx *fiber.Ctx) (*Response,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) GetBucketVersioning(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetBucketVersioning(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -150,7 +150,7 @@ func (c S3ApiController) GetBucketVersioning(ctx *fiber.Ctx) (*Response, error)
|
||||
}, err
|
||||
}
|
||||
|
||||
data, err := c.be.GetBucketVersioning(ctx.Context(), bucket)
|
||||
data, err := c.be.GetBucketVersioning(ctx.RequestCtx(), bucket)
|
||||
return &Response{
|
||||
Data: data,
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -159,14 +159,14 @@ func (c S3ApiController) GetBucketVersioning(ctx *fiber.Ctx) (*Response, error)
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) GetBucketCors(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetBucketCors(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -184,7 +184,7 @@ func (c S3ApiController) GetBucketCors(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
data, err := c.be.GetBucketCors(ctx.Context(), bucket)
|
||||
data, err := c.be.GetBucketCors(ctx.RequestCtx(), bucket)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -202,14 +202,14 @@ func (c S3ApiController) GetBucketCors(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) GetBucketPolicy(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetBucketPolicy(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -227,7 +227,7 @@ func (c S3ApiController) GetBucketPolicy(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
data, err := c.be.GetBucketPolicy(ctx.Context(), bucket)
|
||||
data, err := c.be.GetBucketPolicy(ctx.RequestCtx(), bucket)
|
||||
return &Response{
|
||||
Data: data,
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -236,14 +236,14 @@ func (c S3ApiController) GetBucketPolicy(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) GetBucketPolicyStatus(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetBucketPolicyStatus(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -261,7 +261,7 @@ func (c S3ApiController) GetBucketPolicyStatus(ctx *fiber.Ctx) (*Response, error
|
||||
}, err
|
||||
}
|
||||
|
||||
policyRaw, err := c.be.GetBucketPolicy(ctx.Context(), bucket)
|
||||
policyRaw, err := c.be.GetBucketPolicy(ctx.RequestCtx(), bucket)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -290,7 +290,7 @@ func (c S3ApiController) GetBucketPolicyStatus(ctx *fiber.Ctx) (*Response, error
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c S3ApiController) ListObjectVersions(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) ListObjectVersions(ctx fiber.Ctx) (*Response, error) {
|
||||
// url values
|
||||
bucket := ctx.Params("bucket")
|
||||
prefix := ctx.Query("prefix")
|
||||
@@ -304,7 +304,7 @@ func (c S3ApiController) ListObjectVersions(ctx *fiber.Ctx) (*Response, error) {
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -331,7 +331,7 @@ func (c S3ApiController) ListObjectVersions(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
data, err := c.be.ListObjectVersions(ctx.Context(),
|
||||
data, err := c.be.ListObjectVersions(ctx.RequestCtx(),
|
||||
&s3.ListObjectVersionsInput{
|
||||
Bucket: &bucket,
|
||||
Delimiter: &delimiter,
|
||||
@@ -348,7 +348,7 @@ func (c S3ApiController) ListObjectVersions(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) GetObjectLockConfiguration(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetObjectLockConfiguration(ctx fiber.Ctx) (*Response, error) {
|
||||
// url values
|
||||
bucket := ctx.Params("bucket")
|
||||
// context keys
|
||||
@@ -357,7 +357,7 @@ func (c S3ApiController) GetObjectLockConfiguration(ctx *fiber.Ctx) (*Response,
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -375,7 +375,7 @@ func (c S3ApiController) GetObjectLockConfiguration(ctx *fiber.Ctx) (*Response,
|
||||
}, err
|
||||
}
|
||||
|
||||
data, err := c.be.GetObjectLockConfiguration(ctx.Context(), bucket)
|
||||
data, err := c.be.GetObjectLockConfiguration(ctx.RequestCtx(), bucket)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -393,7 +393,7 @@ func (c S3ApiController) GetObjectLockConfiguration(ctx *fiber.Ctx) (*Response,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) GetBucketAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetBucketAcl(ctx fiber.Ctx) (*Response, error) {
|
||||
// url values
|
||||
bucket := ctx.Params("bucket")
|
||||
// context keys
|
||||
@@ -402,7 +402,7 @@ func (c S3ApiController) GetBucketAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionReadAcp,
|
||||
@@ -420,7 +420,7 @@ func (c S3ApiController) GetBucketAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
data, err := c.be.GetBucketAcl(ctx.Context(),
|
||||
data, err := c.be.GetBucketAcl(ctx.RequestCtx(),
|
||||
&s3.GetBucketAclInput{Bucket: &bucket})
|
||||
if err != nil {
|
||||
return &Response{
|
||||
@@ -439,7 +439,7 @@ func (c S3ApiController) GetBucketAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) ListMultipartUploads(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) ListMultipartUploads(ctx fiber.Ctx) (*Response, error) {
|
||||
// url values
|
||||
bucket := ctx.Params("bucket")
|
||||
prefix := ctx.Query("prefix")
|
||||
@@ -453,7 +453,7 @@ func (c S3ApiController) ListMultipartUploads(ctx *fiber.Ctx) (*Response, error)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -478,7 +478,7 @@ func (c S3ApiController) ListMultipartUploads(ctx *fiber.Ctx) (*Response, error)
|
||||
},
|
||||
}, err
|
||||
}
|
||||
res, err := c.be.ListMultipartUploads(ctx.Context(),
|
||||
res, err := c.be.ListMultipartUploads(ctx.RequestCtx(),
|
||||
&s3.ListMultipartUploadsInput{
|
||||
Bucket: &bucket,
|
||||
Delimiter: &delimiter,
|
||||
@@ -495,7 +495,7 @@ func (c S3ApiController) ListMultipartUploads(ctx *fiber.Ctx) (*Response, error)
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) ListObjectsV2(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) ListObjectsV2(ctx fiber.Ctx) (*Response, error) {
|
||||
// url values
|
||||
bucket := ctx.Params("bucket")
|
||||
prefix := ctx.Query("prefix")
|
||||
@@ -510,7 +510,7 @@ func (c S3ApiController) ListObjectsV2(ctx *fiber.Ctx) (*Response, error) {
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -536,7 +536,7 @@ func (c S3ApiController) ListObjectsV2(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
res, err := c.be.ListObjectsV2(ctx.Context(),
|
||||
res, err := c.be.ListObjectsV2(ctx.RequestCtx(),
|
||||
&s3.ListObjectsV2Input{
|
||||
Bucket: &bucket,
|
||||
Prefix: &prefix,
|
||||
@@ -554,7 +554,7 @@ func (c S3ApiController) ListObjectsV2(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) ListObjects(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) ListObjects(ctx fiber.Ctx) (*Response, error) {
|
||||
// url values
|
||||
bucket := ctx.Params("bucket")
|
||||
prefix := ctx.Query("prefix")
|
||||
@@ -567,7 +567,7 @@ func (c S3ApiController) ListObjects(ctx *fiber.Ctx) (*Response, error) {
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -594,7 +594,7 @@ func (c S3ApiController) ListObjects(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
res, err := c.be.ListObjects(ctx.Context(),
|
||||
res, err := c.be.ListObjects(ctx.RequestCtx(),
|
||||
&s3.ListObjectsInput{
|
||||
Bucket: &bucket,
|
||||
Prefix: &prefix,
|
||||
@@ -611,14 +611,14 @@ func (c S3ApiController) ListObjects(ctx *fiber.Ctx) (*Response, error) {
|
||||
}
|
||||
|
||||
// GetBucketLocation handles GET /:bucket?location
|
||||
func (c S3ApiController) GetBucketLocation(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetBucketLocation(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -637,7 +637,7 @@ func (c S3ApiController) GetBucketLocation(ctx *fiber.Ctx) (*Response, error) {
|
||||
}
|
||||
|
||||
// verify bucket existence/access via backend HeadBucket
|
||||
_, err = c.be.HeadBucket(ctx.Context(), &s3.HeadBucketInput{Bucket: &bucket})
|
||||
_, err = c.be.HeadBucket(ctx.RequestCtx(), &s3.HeadBucketInput{Bucket: &bucket})
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
|
||||
@@ -18,13 +18,13 @@ import (
|
||||
"errors"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
)
|
||||
|
||||
func (c S3ApiController) HeadBucket(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) HeadBucket(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
@@ -32,7 +32,7 @@ func (c S3ApiController) HeadBucket(ctx *fiber.Ctx) (*Response, error) {
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -54,7 +54,7 @@ func (c S3ApiController) HeadBucket(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
_, err = c.be.HeadBucket(ctx.Context(),
|
||||
_, err = c.be.HeadBucket(ctx.RequestCtx(),
|
||||
&s3.HeadBucketInput{
|
||||
Bucket: &bucket,
|
||||
})
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
"github.com/versity/versitygw/s3response"
|
||||
)
|
||||
|
||||
func (c S3ApiController) ListBuckets(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) ListBuckets(ctx fiber.Ctx) (*Response, error) {
|
||||
cToken := ctx.Query("continuation-token")
|
||||
prefix := ctx.Query("prefix")
|
||||
maxBucketsStr := ctx.Query("max-buckets")
|
||||
@@ -38,7 +38,7 @@ func (c S3ApiController) ListBuckets(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
res, err := c.be.ListBuckets(ctx.Context(),
|
||||
res, err := c.be.ListBuckets(ctx.RequestCtx(),
|
||||
s3response.ListBucketsInput{
|
||||
Owner: acct.Access,
|
||||
IsAdmin: acct.Role == auth.RoleAdmin,
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
"github.com/versity/versitygw/s3response"
|
||||
)
|
||||
|
||||
func (c S3ApiController) DeleteObjects(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) DeleteObjects(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
bypass := strings.EqualFold(ctx.Get("X-Amz-Bypass-Governance-Retention"), "true")
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
@@ -37,7 +37,7 @@ func (c S3ApiController) DeleteObjects(ctx *fiber.Ctx) (*Response, error) {
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
IsBucketPublic := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -57,7 +57,7 @@ func (c S3ApiController) DeleteObjects(ctx *fiber.Ctx) (*Response, error) {
|
||||
}
|
||||
|
||||
var dObj s3response.DeleteObjects
|
||||
err = xml.Unmarshal(ctx.Body(), &dObj)
|
||||
err = xml.Unmarshal(ctx.BodyRaw(), &dObj)
|
||||
if err != nil {
|
||||
debuglogger.Logf("error unmarshalling delete objects: %v", err)
|
||||
return &Response{
|
||||
@@ -67,7 +67,7 @@ func (c S3ApiController) DeleteObjects(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, s3err.GetAPIError(s3err.ErrInvalidRequest)
|
||||
}
|
||||
|
||||
err = auth.CheckObjectAccess(ctx.Context(), bucket, acct.Access, dObj.Objects, bypass, IsBucketPublic, c.be, false)
|
||||
err = auth.CheckObjectAccess(ctx.RequestCtx(), bucket, acct.Access, dObj.Objects, bypass, IsBucketPublic, c.be, false)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -76,7 +76,7 @@ func (c S3ApiController) DeleteObjects(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
res, err := c.be.DeleteObjects(ctx.Context(),
|
||||
res, err := c.be.DeleteObjects(ctx.RequestCtx(),
|
||||
&s3.DeleteObjectsInput{
|
||||
Bucket: &bucket,
|
||||
Delete: &types.Delete{
|
||||
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
@@ -31,14 +31,14 @@ import (
|
||||
"github.com/versity/versitygw/s3response"
|
||||
)
|
||||
|
||||
func (c S3ApiController) PutBucketTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) PutBucketTagging(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionWrite,
|
||||
@@ -56,7 +56,7 @@ func (c S3ApiController) PutBucketTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
tagging, err := utils.ParseTagging(ctx.Body(), utils.TagLimitBucket)
|
||||
tagging, err := utils.ParseTagging(ctx.BodyRaw(), utils.TagLimitBucket)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -65,7 +65,7 @@ func (c S3ApiController) PutBucketTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.PutBucketTagging(ctx.Context(), bucket, tagging)
|
||||
err = c.be.PutBucketTagging(ctx.RequestCtx(), bucket, tagging)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
@@ -74,13 +74,13 @@ func (c S3ApiController) PutBucketTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) PutBucketOwnershipControls(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) PutBucketOwnershipControls(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
|
||||
if err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
if err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionWrite,
|
||||
@@ -97,7 +97,7 @@ func (c S3ApiController) PutBucketOwnershipControls(ctx *fiber.Ctx) (*Response,
|
||||
}
|
||||
|
||||
var ownershipControls s3response.OwnershipControls
|
||||
if err := xml.Unmarshal(ctx.Body(), &ownershipControls); err != nil {
|
||||
if err := xml.Unmarshal(ctx.BodyRaw(), &ownershipControls); err != nil {
|
||||
debuglogger.Logf("failed to unmarshal request body: %v", err)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -119,7 +119,7 @@ func (c S3ApiController) PutBucketOwnershipControls(ctx *fiber.Ctx) (*Response,
|
||||
}, s3err.GetAPIError(s3err.ErrMalformedXML)
|
||||
}
|
||||
|
||||
err := c.be.PutBucketOwnershipControls(ctx.Context(), bucket, ownershipControls.Rules[0].ObjectOwnership)
|
||||
err := c.be.PutBucketOwnershipControls(ctx.RequestCtx(), bucket, ownershipControls.Rules[0].ObjectOwnership)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
@@ -127,14 +127,14 @@ func (c S3ApiController) PutBucketOwnershipControls(ctx *fiber.Ctx) (*Response,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) PutBucketVersioning(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) PutBucketVersioning(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionWrite,
|
||||
@@ -153,7 +153,7 @@ func (c S3ApiController) PutBucketVersioning(ctx *fiber.Ctx) (*Response, error)
|
||||
}
|
||||
|
||||
var versioningConf types.VersioningConfiguration
|
||||
err = xml.Unmarshal(ctx.Body(), &versioningConf)
|
||||
err = xml.Unmarshal(ctx.BodyRaw(), &versioningConf)
|
||||
if err != nil {
|
||||
debuglogger.Logf("error unmarshalling versioning configuration: %v", err)
|
||||
return &Response{
|
||||
@@ -173,7 +173,7 @@ func (c S3ApiController) PutBucketVersioning(ctx *fiber.Ctx) (*Response, error)
|
||||
}, s3err.GetAPIError(s3err.ErrMalformedXML)
|
||||
}
|
||||
|
||||
err = c.be.PutBucketVersioning(ctx.Context(), bucket, versioningConf.Status)
|
||||
err = c.be.PutBucketVersioning(ctx.RequestCtx(), bucket, versioningConf.Status)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
@@ -181,14 +181,14 @@ func (c S3ApiController) PutBucketVersioning(ctx *fiber.Ctx) (*Response, error)
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) PutObjectLockConfiguration(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) PutObjectLockConfiguration(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
|
||||
if err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
if err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionWrite,
|
||||
@@ -205,7 +205,7 @@ func (c S3ApiController) PutObjectLockConfiguration(ctx *fiber.Ctx) (*Response,
|
||||
}, err
|
||||
}
|
||||
|
||||
config, err := auth.ParseBucketLockConfigurationInput(ctx.Body())
|
||||
config, err := auth.ParseBucketLockConfigurationInput(ctx.BodyRaw())
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -214,7 +214,7 @@ func (c S3ApiController) PutObjectLockConfiguration(ctx *fiber.Ctx) (*Response,
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.PutObjectLockConfiguration(ctx.Context(), bucket, config)
|
||||
err = c.be.PutObjectLockConfiguration(ctx.RequestCtx(), bucket, config)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
@@ -222,14 +222,14 @@ func (c S3ApiController) PutObjectLockConfiguration(ctx *fiber.Ctx) (*Response,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) PutBucketCors(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) PutBucketCors(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionWrite,
|
||||
@@ -247,7 +247,7 @@ func (c S3ApiController) PutBucketCors(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
body := ctx.Body()
|
||||
body := ctx.BodyRaw()
|
||||
|
||||
var corsConfig auth.CORSConfiguration
|
||||
err = xml.Unmarshal(body, &corsConfig)
|
||||
@@ -270,7 +270,7 @@ func (c S3ApiController) PutBucketCors(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.PutBucketCors(ctx.Context(), bucket, body)
|
||||
err = c.be.PutBucketCors(ctx.RequestCtx(), bucket, body)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
@@ -278,13 +278,13 @@ func (c S3ApiController) PutBucketCors(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) PutBucketPolicy(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) PutBucketPolicy(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionWrite,
|
||||
@@ -301,7 +301,7 @@ func (c S3ApiController) PutBucketPolicy(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = auth.ValidatePolicyDocument(ctx.Body(), bucket, c.iam)
|
||||
err = auth.ValidatePolicyDocument(ctx.BodyRaw(), bucket, c.iam)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -310,7 +310,7 @@ func (c S3ApiController) PutBucketPolicy(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.PutBucketPolicy(ctx.Context(), bucket, ctx.Body())
|
||||
err = c.be.PutBucketPolicy(ctx.RequestCtx(), bucket, ctx.BodyRaw())
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
@@ -319,7 +319,7 @@ func (c S3ApiController) PutBucketPolicy(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) PutBucketAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) PutBucketAcl(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acl := ctx.Get("X-Amz-Acl")
|
||||
grantFullControl := ctx.Get("X-Amz-Grant-Full-Control")
|
||||
@@ -335,7 +335,7 @@ func (c S3ApiController) PutBucketAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
grants := grantFullControl + grantRead + grantReadACP + grantWrite + grantWriteACP
|
||||
var input *auth.PutBucketAclInput
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -362,7 +362,7 @@ func (c S3ApiController) PutBucketAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
ownership, err := c.be.GetBucketOwnershipControls(ctx.Context(), bucket)
|
||||
ownership, err := c.be.GetBucketOwnershipControls(ctx.RequestCtx(), bucket)
|
||||
if err != nil && !errors.Is(err, s3err.GetAPIError(s3err.ErrOwnershipControlsNotFound)) {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -379,9 +379,9 @@ func (c S3ApiController) PutBucketAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, s3err.GetAPIError(s3err.ErrAclNotSupported)
|
||||
}
|
||||
|
||||
if len(ctx.Body()) > 0 {
|
||||
if len(ctx.BodyRaw()) > 0 {
|
||||
var accessControlPolicy auth.AccessControlPolicy
|
||||
err := xml.Unmarshal(ctx.Body(), &accessControlPolicy)
|
||||
err := xml.Unmarshal(ctx.BodyRaw(), &accessControlPolicy)
|
||||
if err != nil {
|
||||
debuglogger.Logf("error unmarshalling access control policy: %v", err)
|
||||
return &Response{
|
||||
@@ -470,7 +470,7 @@ func (c S3ApiController) PutBucketAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.PutBucketAcl(ctx.Context(), bucket, updAcl)
|
||||
err = c.be.PutBucketAcl(ctx.RequestCtx(), bucket, updAcl)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
@@ -478,7 +478,7 @@ func (c S3ApiController) PutBucketAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) CreateBucket(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) CreateBucket(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
acl := ctx.Get("X-Amz-Acl")
|
||||
grantFullControl := ctx.Get("X-Amz-Grant-Full-Control")
|
||||
@@ -561,9 +561,9 @@ func (c S3ApiController) CreateBucket(ctx *fiber.Ctx) (*Response, error) {
|
||||
}
|
||||
|
||||
var body s3response.CreateBucketConfiguration
|
||||
if len(ctx.Body()) != 0 {
|
||||
if len(ctx.BodyRaw()) != 0 {
|
||||
// request body is optional for CreateBucket
|
||||
err := xml.Unmarshal(ctx.Body(), &body)
|
||||
err := xml.Unmarshal(ctx.BodyRaw(), &body)
|
||||
if err != nil {
|
||||
debuglogger.Logf("failed to parse the request body: %v", err)
|
||||
return &Response{
|
||||
@@ -611,7 +611,7 @@ func (c S3ApiController) CreateBucket(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.CreateBucket(ctx.Context(), &s3.CreateBucketInput{
|
||||
err = c.be.CreateBucket(ctx.RequestCtx(), &s3.CreateBucketInput{
|
||||
Bucket: &bucket,
|
||||
ObjectOwnership: objectOwnership,
|
||||
ObjectLockEnabledForBucket: &lockEnabled,
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/s3api/middlewares"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
)
|
||||
@@ -36,7 +36,7 @@ func TestApplyBucketCORS_FallbackOrigin_NoBucketCors_NoRequestOrigin(t *testing.
|
||||
app := fiber.New()
|
||||
app.Get("/:bucket/test",
|
||||
middlewares.ApplyBucketCORS(mockedBackend, origin),
|
||||
func(c *fiber.Ctx) error {
|
||||
func(c fiber.Ctx) error {
|
||||
return c.SendStatus(http.StatusOK)
|
||||
},
|
||||
)
|
||||
@@ -71,7 +71,7 @@ func TestApplyBucketCORS_FallbackOrigin_NotAppliedWhenBucketCorsExists(t *testin
|
||||
app := fiber.New()
|
||||
app.Get("/:bucket/test",
|
||||
middlewares.ApplyBucketCORS(mockedBackend, origin),
|
||||
func(c *fiber.Ctx) error {
|
||||
func(c fiber.Ctx) error {
|
||||
return c.SendStatus(http.StatusOK)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -21,13 +21,13 @@ import (
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
"github.com/versity/versitygw/s3event"
|
||||
)
|
||||
|
||||
func (c S3ApiController) DeleteObjectTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) DeleteObjectTagging(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
versionId := ctx.Query("versionId")
|
||||
@@ -41,7 +41,7 @@ func (c S3ApiController) DeleteObjectTagging(ctx *fiber.Ctx) (*Response, error)
|
||||
action = auth.DeleteObjectVersionTaggingAction
|
||||
}
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -70,7 +70,7 @@ func (c S3ApiController) DeleteObjectTagging(ctx *fiber.Ctx) (*Response, error)
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.DeleteObjectTagging(ctx.Context(), bucket, key, versionId)
|
||||
err = c.be.DeleteObjectTagging(ctx.RequestCtx(), bucket, key, versionId)
|
||||
return &Response{
|
||||
Headers: map[string]*string{
|
||||
"x-amz-version-id": &versionId,
|
||||
@@ -83,7 +83,7 @@ func (c S3ApiController) DeleteObjectTagging(ctx *fiber.Ctx) (*Response, error)
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) AbortMultipartUpload(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) AbortMultipartUpload(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
uploadId := ctx.Query("uploadId")
|
||||
@@ -93,7 +93,7 @@ func (c S3ApiController) AbortMultipartUpload(ctx *fiber.Ctx) (*Response, error)
|
||||
isBucketPublic := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -113,7 +113,7 @@ func (c S3ApiController) AbortMultipartUpload(ctx *fiber.Ctx) (*Response, error)
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.AbortMultipartUpload(ctx.Context(),
|
||||
err = c.be.AbortMultipartUpload(ctx.RequestCtx(),
|
||||
&s3.AbortMultipartUploadInput{
|
||||
UploadId: &uploadId,
|
||||
Bucket: &bucket,
|
||||
@@ -128,7 +128,7 @@ func (c S3ApiController) AbortMultipartUpload(ctx *fiber.Ctx) (*Response, error)
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) DeleteObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) DeleteObject(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
versionId := ctx.Query("versionId")
|
||||
@@ -147,7 +147,7 @@ func (c S3ApiController) DeleteObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
action = auth.DeleteObjectVersionAction
|
||||
}
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -177,7 +177,7 @@ func (c S3ApiController) DeleteObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
}
|
||||
|
||||
err = auth.CheckObjectAccess(
|
||||
ctx.Context(),
|
||||
ctx.RequestCtx(),
|
||||
bucket,
|
||||
acct.Access,
|
||||
[]types.ObjectIdentifier{
|
||||
@@ -199,7 +199,7 @@ func (c S3ApiController) DeleteObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
res, err := c.be.DeleteObject(ctx.Context(),
|
||||
res, err := c.be.DeleteObject(ctx.RequestCtx(),
|
||||
&s3.DeleteObjectInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
"github.com/versity/versitygw/s3response"
|
||||
)
|
||||
|
||||
func (c S3ApiController) GetObjectTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetObjectTagging(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
versionId := ctx.Query("versionId")
|
||||
@@ -45,7 +45,7 @@ func (c S3ApiController) GetObjectTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
action = auth.GetObjectVersionTaggingAction
|
||||
}
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -73,7 +73,7 @@ func (c S3ApiController) GetObjectTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
data, err := c.be.GetObjectTagging(ctx.Context(), bucket, key, versionId)
|
||||
data, err := c.be.GetObjectTagging(ctx.RequestCtx(), bucket, key, versionId)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -101,7 +101,7 @@ func (c S3ApiController) GetObjectTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c S3ApiController) GetObjectRetention(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetObjectRetention(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
versionId := ctx.Query("versionId")
|
||||
@@ -111,7 +111,7 @@ func (c S3ApiController) GetObjectRetention(ctx *fiber.Ctx) (*Response, error) {
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -139,7 +139,7 @@ func (c S3ApiController) GetObjectRetention(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
data, err := c.be.GetObjectRetention(ctx.Context(), bucket, key, versionId)
|
||||
data, err := c.be.GetObjectRetention(ctx.RequestCtx(), bucket, key, versionId)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -157,7 +157,7 @@ func (c S3ApiController) GetObjectRetention(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) GetObjectLegalHold(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetObjectLegalHold(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
versionId := ctx.Query("versionId")
|
||||
@@ -167,7 +167,7 @@ func (c S3ApiController) GetObjectLegalHold(ctx *fiber.Ctx) (*Response, error) {
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -195,7 +195,7 @@ func (c S3ApiController) GetObjectLegalHold(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
data, err := c.be.GetObjectLegalHold(ctx.Context(), bucket, key, versionId)
|
||||
data, err := c.be.GetObjectLegalHold(ctx.RequestCtx(), bucket, key, versionId)
|
||||
return &Response{
|
||||
Data: auth.ParseObjectLegalHoldOutput(data),
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -204,7 +204,7 @@ func (c S3ApiController) GetObjectLegalHold(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) GetObjectAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetObjectAcl(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
// context locals
|
||||
@@ -213,7 +213,7 @@ func (c S3ApiController) GetObjectAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionReadAcp,
|
||||
@@ -231,7 +231,7 @@ func (c S3ApiController) GetObjectAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
},
|
||||
}, err
|
||||
}
|
||||
res, err := c.be.GetObjectAcl(ctx.Context(), &s3.GetObjectAclInput{
|
||||
res, err := c.be.GetObjectAcl(ctx.RequestCtx(), &s3.GetObjectAclInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
})
|
||||
@@ -243,7 +243,7 @@ func (c S3ApiController) GetObjectAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) ListParts(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) ListParts(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
uploadId := ctx.Query("uploadId")
|
||||
@@ -255,7 +255,7 @@ func (c S3ApiController) ListParts(ctx *fiber.Ctx) (*Response, error) {
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -294,7 +294,7 @@ func (c S3ApiController) ListParts(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
res, err := c.be.ListParts(ctx.Context(), &s3.ListPartsInput{
|
||||
res, err := c.be.ListParts(ctx.RequestCtx(), &s3.ListPartsInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
UploadId: &uploadId,
|
||||
@@ -309,7 +309,7 @@ func (c S3ApiController) ListParts(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) GetObjectAttributes(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetObjectAttributes(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
versionId := ctx.Query("versionId")
|
||||
@@ -326,7 +326,7 @@ func (c S3ApiController) GetObjectAttributes(ctx *fiber.Ctx) (*Response, error)
|
||||
action = auth.GetObjectVersionAttributesAction
|
||||
}
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -371,7 +371,7 @@ func (c S3ApiController) GetObjectAttributes(ctx *fiber.Ctx) (*Response, error)
|
||||
}, err
|
||||
}
|
||||
|
||||
res, err := c.be.GetObjectAttributes(ctx.Context(),
|
||||
res, err := c.be.GetObjectAttributes(ctx.RequestCtx(),
|
||||
&s3.GetObjectAttributesInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
@@ -411,13 +411,13 @@ func (c S3ApiController) GetObjectAttributes(ctx *fiber.Ctx) (*Response, error)
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) GetObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) GetObject(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
versionId := ctx.Query("versionId")
|
||||
acceptRange := ctx.Get("Range")
|
||||
checksumMode := types.ChecksumMode(strings.ToUpper(ctx.Get("x-amz-checksum-mode")))
|
||||
partNumberQuery := int32(ctx.QueryInt("partNumber", -1))
|
||||
partNumberQuery := int32(fiber.Query[int](ctx, "partNumber", -1))
|
||||
|
||||
// Extract response override query parameters
|
||||
responseOverrides := map[string]*string{
|
||||
@@ -459,7 +459,7 @@ func (c S3ApiController) GetObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
action = auth.GetObjectVersionAction
|
||||
}
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionRead,
|
||||
@@ -513,7 +513,7 @@ func (c S3ApiController) GetObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
|
||||
conditionalHeaders := utils.ParsePreconditionHeaders(ctx)
|
||||
|
||||
res, err := c.be.GetObject(ctx.Context(), &s3.GetObjectInput{
|
||||
res, err := c.be.GetObject(ctx.RequestCtx(), &s3.GetObjectInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
Range: &acceptRange,
|
||||
|
||||
@@ -21,14 +21,14 @@ import (
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
)
|
||||
|
||||
func (c S3ApiController) HeadObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) HeadObject(ctx fiber.Ctx) (*Response, error) {
|
||||
// context locals
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
@@ -36,7 +36,7 @@ func (c S3ApiController) HeadObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
isPublicBucket := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
// url values
|
||||
bucket := ctx.Params("bucket")
|
||||
partNumberQuery := int32(ctx.QueryInt("partNumber", -1))
|
||||
partNumberQuery := int32(fiber.Query[int](ctx, "partNumber", -1))
|
||||
versionId := ctx.Query("versionId")
|
||||
objRange := ctx.Get("Range")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
@@ -46,7 +46,7 @@ func (c S3ApiController) HeadObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
action = auth.GetObjectVersionAction
|
||||
}
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -101,7 +101,7 @@ func (c S3ApiController) HeadObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
|
||||
conditionalHeaders := utils.ParsePreconditionHeaders(ctx)
|
||||
|
||||
res, err := c.be.HeadObject(ctx.Context(),
|
||||
res, err := c.be.HeadObject(ctx.RequestCtx(),
|
||||
&s3.HeadObjectInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
"github.com/versity/versitygw/s3response"
|
||||
)
|
||||
|
||||
func (c S3ApiController) RestoreObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) RestoreObject(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
@@ -39,7 +39,7 @@ func (c S3ApiController) RestoreObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
isBucketPublic := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -60,7 +60,7 @@ func (c S3ApiController) RestoreObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
}
|
||||
|
||||
var restoreRequest types.RestoreRequest
|
||||
if err := xml.Unmarshal(ctx.Body(), &restoreRequest); err != nil {
|
||||
if err := xml.Unmarshal(ctx.BodyRaw(), &restoreRequest); err != nil {
|
||||
debuglogger.Logf("failed to parse the request body: %v", err)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -69,7 +69,7 @@ func (c S3ApiController) RestoreObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, s3err.GetAPIError(s3err.ErrMalformedXML)
|
||||
}
|
||||
|
||||
err = c.be.RestoreObject(ctx.Context(), &s3.RestoreObjectInput{
|
||||
err = c.be.RestoreObject(ctx.RequestCtx(), &s3.RestoreObjectInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
RestoreRequest: &restoreRequest,
|
||||
@@ -82,7 +82,7 @@ func (c S3ApiController) RestoreObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) SelectObjectContent(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) SelectObjectContent(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
@@ -90,7 +90,7 @@ func (c S3ApiController) SelectObjectContent(ctx *fiber.Ctx) (*Response, error)
|
||||
isBucketPublic := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -111,7 +111,7 @@ func (c S3ApiController) SelectObjectContent(ctx *fiber.Ctx) (*Response, error)
|
||||
}
|
||||
|
||||
var payload s3response.SelectObjectContentPayload
|
||||
err = xml.Unmarshal(ctx.Body(), &payload)
|
||||
err = xml.Unmarshal(ctx.BodyRaw(), &payload)
|
||||
if err != nil {
|
||||
debuglogger.Logf("error unmarshalling select object content: %v", err)
|
||||
return &Response{
|
||||
@@ -121,7 +121,7 @@ func (c S3ApiController) SelectObjectContent(ctx *fiber.Ctx) (*Response, error)
|
||||
}, s3err.GetAPIError(s3err.ErrMalformedXML)
|
||||
}
|
||||
|
||||
sw := c.be.SelectObjectContent(ctx.Context(),
|
||||
sw := c.be.SelectObjectContent(ctx.RequestCtx(),
|
||||
&s3.SelectObjectContentInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
@@ -133,7 +133,7 @@ func (c S3ApiController) SelectObjectContent(ctx *fiber.Ctx) (*Response, error)
|
||||
ScanRange: payload.ScanRange,
|
||||
})
|
||||
|
||||
ctx.Context().SetBodyStreamWriter(sw)
|
||||
ctx.RequestCtx().SetBodyStreamWriter(sw)
|
||||
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -142,7 +142,7 @@ func (c S3ApiController) SelectObjectContent(ctx *fiber.Ctx) (*Response, error)
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c S3ApiController) CreateMultipartUpload(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) CreateMultipartUpload(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
contentType := ctx.Get("Content-Type")
|
||||
@@ -167,7 +167,7 @@ func (c S3ApiController) CreateMultipartUpload(ctx *fiber.Ctx) (*Response, error
|
||||
}, err
|
||||
}
|
||||
|
||||
err = auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err = auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -204,7 +204,7 @@ func (c S3ApiController) CreateMultipartUpload(ctx *fiber.Ctx) (*Response, error
|
||||
}, err
|
||||
}
|
||||
|
||||
res, err := c.be.CreateMultipartUpload(ctx.Context(),
|
||||
res, err := c.be.CreateMultipartUpload(ctx.RequestCtx(),
|
||||
s3response.CreateMultipartUploadInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
@@ -238,7 +238,7 @@ func (c S3ApiController) CreateMultipartUpload(ctx *fiber.Ctx) (*Response, error
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) CompleteMultipartUpload(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) CompleteMultipartUpload(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
uploadId := ctx.Query("uploadId")
|
||||
@@ -250,7 +250,7 @@ func (c S3ApiController) CompleteMultipartUpload(ctx *fiber.Ctx) (*Response, err
|
||||
isBucketPublic := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -271,7 +271,7 @@ func (c S3ApiController) CompleteMultipartUpload(ctx *fiber.Ctx) (*Response, err
|
||||
}
|
||||
|
||||
var body s3response.CompleteMultipartUploadRequestBody
|
||||
err = xml.Unmarshal(ctx.Body(), &body)
|
||||
err = xml.Unmarshal(ctx.BodyRaw(), &body)
|
||||
if err != nil {
|
||||
debuglogger.Logf("error unmarshalling complete multipart upload: %v", err)
|
||||
return &Response{
|
||||
@@ -334,7 +334,7 @@ func (c S3ApiController) CompleteMultipartUpload(ctx *fiber.Ctx) (*Response, err
|
||||
|
||||
ifMatch, ifNoneMatch := utils.ParsePreconditionMatchHeaders(ctx)
|
||||
|
||||
err = auth.CheckObjectAccess(ctx.Context(), bucket, acct.Access, []types.ObjectIdentifier{{Key: &key}}, true, isBucketPublic, c.be, true)
|
||||
err = auth.CheckObjectAccess(ctx.RequestCtx(), bucket, acct.Access, []types.ObjectIdentifier{{Key: &key}}, true, isBucketPublic, c.be, true)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -343,7 +343,7 @@ func (c S3ApiController) CompleteMultipartUpload(ctx *fiber.Ctx) (*Response, err
|
||||
}, err
|
||||
}
|
||||
|
||||
res, versid, err := c.be.CompleteMultipartUpload(ctx.Context(),
|
||||
res, versid, err := c.be.CompleteMultipartUpload(ctx.RequestCtx(),
|
||||
&s3.CompleteMultipartUploadInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
"github.com/versity/versitygw/s3response"
|
||||
)
|
||||
|
||||
func (c S3ApiController) PutObjectTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) PutObjectTagging(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
versionId := ctx.Query("versionId")
|
||||
@@ -47,7 +47,7 @@ func (c S3ApiController) PutObjectTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
action = auth.PutObjectVersionTaggingAction
|
||||
}
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionWrite,
|
||||
@@ -75,7 +75,7 @@ func (c S3ApiController) PutObjectTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
tagging, err := utils.ParseTagging(ctx.Body(), utils.TagLimitObject)
|
||||
tagging, err := utils.ParseTagging(ctx.BodyRaw(), utils.TagLimitObject)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -84,7 +84,7 @@ func (c S3ApiController) PutObjectTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.PutObjectTagging(ctx.Context(), bucket, key, versionId, tagging)
|
||||
err = c.be.PutObjectTagging(ctx.RequestCtx(), bucket, key, versionId, tagging)
|
||||
return &Response{
|
||||
Headers: map[string]*string{
|
||||
"x-amz-version-id": &versionId,
|
||||
@@ -96,7 +96,7 @@ func (c S3ApiController) PutObjectTagging(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) PutObjectRetention(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) PutObjectRetention(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
versionId := ctx.Query("versionId")
|
||||
@@ -106,7 +106,7 @@ func (c S3ApiController) PutObjectRetention(ctx *fiber.Ctx) (*Response, error) {
|
||||
IsBucketPublic := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionWrite,
|
||||
@@ -135,7 +135,7 @@ func (c S3ApiController) PutObjectRetention(ctx *fiber.Ctx) (*Response, error) {
|
||||
}
|
||||
|
||||
// parse the request body bytes into a go struct and validate
|
||||
retention, err := auth.ParseObjectLockRetentionInput(ctx.Body())
|
||||
retention, err := auth.ParseObjectLockRetentionInput(ctx.BodyRaw())
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -145,7 +145,7 @@ func (c S3ApiController) PutObjectRetention(ctx *fiber.Ctx) (*Response, error) {
|
||||
}
|
||||
|
||||
// check if the operation is allowed
|
||||
err = auth.IsObjectLockRetentionPutAllowed(ctx.Context(), c.be, bucket, key, versionId, acct.Access, retention, bypass)
|
||||
err = auth.IsObjectLockRetentionPutAllowed(ctx.RequestCtx(), c.be, bucket, key, versionId, acct.Access, retention, bypass)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -164,7 +164,7 @@ func (c S3ApiController) PutObjectRetention(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.PutObjectRetention(ctx.Context(), bucket, key, versionId, data)
|
||||
err = c.be.PutObjectRetention(ctx.RequestCtx(), bucket, key, versionId, data)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
@@ -172,7 +172,7 @@ func (c S3ApiController) PutObjectRetention(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) PutObjectLegalHold(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) PutObjectLegalHold(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
versionId := ctx.Query("versionId")
|
||||
@@ -181,7 +181,7 @@ func (c S3ApiController) PutObjectLegalHold(ctx *fiber.Ctx) (*Response, error) {
|
||||
IsBucketPublic := utils.ContextKeyPublicBucket.IsSet(ctx)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be, auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionWrite,
|
||||
@@ -210,7 +210,7 @@ func (c S3ApiController) PutObjectLegalHold(ctx *fiber.Ctx) (*Response, error) {
|
||||
}
|
||||
|
||||
var legalHold types.ObjectLockLegalHold
|
||||
if err := xml.Unmarshal(ctx.Body(), &legalHold); err != nil {
|
||||
if err := xml.Unmarshal(ctx.BodyRaw(), &legalHold); err != nil {
|
||||
debuglogger.Logf("failed to parse request body: %v", err)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -228,7 +228,7 @@ func (c S3ApiController) PutObjectLegalHold(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, s3err.GetAPIError(s3err.ErrMalformedXML)
|
||||
}
|
||||
|
||||
err = c.be.PutObjectLegalHold(ctx.Context(), bucket, key, versionId, legalHold.Status == types.ObjectLockLegalHoldStatusOn)
|
||||
err = c.be.PutObjectLegalHold(ctx.RequestCtx(), bucket, key, versionId, legalHold.Status == types.ObjectLockLegalHoldStatusOn)
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
BucketOwner: parsedAcl.Owner,
|
||||
@@ -236,10 +236,10 @@ func (c S3ApiController) PutObjectLegalHold(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) UploadPart(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) UploadPart(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
partNumber := int32(ctx.QueryInt("partNumber", -1))
|
||||
partNumber := int32(fiber.Query[int](ctx, "partNumber", -1))
|
||||
uploadId := ctx.Query("uploadId")
|
||||
// context locals
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
@@ -258,7 +258,7 @@ func (c S3ApiController) UploadPart(ctx *fiber.Ctx) (*Response, error) {
|
||||
contentLengthStr = decodedLength
|
||||
}
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -315,7 +315,7 @@ func (c S3ApiController) UploadPart(ctx *fiber.Ctx) (*Response, error) {
|
||||
body = bytes.NewReader([]byte{})
|
||||
}
|
||||
|
||||
res, err := c.be.UploadPart(ctx.Context(),
|
||||
res, err := c.be.UploadPart(ctx.RequestCtx(),
|
||||
&s3.UploadPartInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
@@ -351,12 +351,12 @@ func (c S3ApiController) UploadPart(ctx *fiber.Ctx) (*Response, error) {
|
||||
|
||||
}
|
||||
|
||||
func (c S3ApiController) UploadPartCopy(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) UploadPartCopy(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
copySource := strings.TrimPrefix(ctx.Get("X-Amz-Copy-Source"), "/")
|
||||
copySrcRange := ctx.Get("X-Amz-Copy-Source-Range")
|
||||
partNumber := int32(ctx.QueryInt("partNumber", -1))
|
||||
partNumber := int32(fiber.Query[int](ctx, "partNumber", -1))
|
||||
uploadId := ctx.Query("uploadId")
|
||||
// context locals
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
@@ -373,7 +373,7 @@ func (c S3ApiController) UploadPartCopy(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = auth.VerifyObjectCopyAccess(ctx.Context(), c.be, copySource,
|
||||
err = auth.VerifyObjectCopyAccess(ctx.RequestCtx(), c.be, copySource,
|
||||
auth.AccessOptions{
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionWrite,
|
||||
@@ -412,7 +412,7 @@ func (c S3ApiController) UploadPartCopy(ctx *fiber.Ctx) (*Response, error) {
|
||||
|
||||
preconditionHdrs := utils.ParsePreconditionHeaders(ctx, utils.WithCopySource())
|
||||
|
||||
resp, err := c.be.UploadPartCopy(ctx.Context(),
|
||||
resp, err := c.be.UploadPartCopy(ctx.RequestCtx(),
|
||||
&s3.UploadPartCopyInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
@@ -440,7 +440,7 @@ func (c S3ApiController) UploadPartCopy(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) PutObjectAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) PutObjectAcl(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
acl := ctx.Get("X-Amz-Acl")
|
||||
@@ -454,7 +454,7 @@ func (c S3ApiController) PutObjectAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
isRoot := utils.ContextKeyIsRoot.Get(ctx).(bool)
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
|
||||
err := auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err := auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -473,7 +473,7 @@ func (c S3ApiController) PutObjectAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = c.be.PutObjectAcl(ctx.Context(), &s3.PutObjectAclInput{
|
||||
err = c.be.PutObjectAcl(ctx.RequestCtx(), &s3.PutObjectAclInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
GrantFullControl: &grantFullControl,
|
||||
@@ -491,7 +491,7 @@ func (c S3ApiController) PutObjectAcl(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) CopyObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) CopyObject(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
copySource := strings.TrimPrefix(ctx.Get("X-Amz-Copy-Source"), "/")
|
||||
@@ -528,7 +528,7 @@ func (c S3ApiController) CopyObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = auth.VerifyObjectCopyAccess(ctx.Context(), c.be, copySource,
|
||||
err = auth.VerifyObjectCopyAccess(ctx.RequestCtx(), c.be, copySource,
|
||||
auth.AccessOptions{
|
||||
Acl: parsedAcl,
|
||||
AclPermission: auth.PermissionWrite,
|
||||
@@ -596,7 +596,7 @@ func (c S3ApiController) CopyObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
|
||||
preconditionHdrs := utils.ParsePreconditionHeaders(ctx, utils.WithCopySource())
|
||||
|
||||
err = auth.CheckObjectAccess(ctx.Context(), bucket, acct.Access, []types.ObjectIdentifier{{Key: &key}}, true, false, c.be, true)
|
||||
err = auth.CheckObjectAccess(ctx.RequestCtx(), bucket, acct.Access, []types.ObjectIdentifier{{Key: &key}}, true, false, c.be, true)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -605,7 +605,7 @@ func (c S3ApiController) CopyObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
res, err := c.be.CopyObject(ctx.Context(),
|
||||
res, err := c.be.CopyObject(ctx.RequestCtx(),
|
||||
s3response.CopyObjectInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
@@ -652,7 +652,7 @@ func (c S3ApiController) CopyObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
func (c S3ApiController) PutObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (c S3ApiController) PutObject(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
key := strings.TrimPrefix(ctx.Path(), fmt.Sprintf("/%s/", bucket))
|
||||
contentType := ctx.Get("Content-Type")
|
||||
@@ -692,7 +692,7 @@ func (c S3ApiController) PutObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
// load the meta headers
|
||||
metadata := utils.GetUserMetaData(&ctx.Request().Header)
|
||||
|
||||
err = auth.VerifyAccess(ctx.Context(), c.be,
|
||||
err = auth.VerifyAccess(ctx.RequestCtx(), c.be,
|
||||
auth.AccessOptions{
|
||||
Readonly: c.readonly,
|
||||
Acl: parsedAcl,
|
||||
@@ -712,7 +712,7 @@ func (c S3ApiController) PutObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
err = auth.CheckObjectAccess(ctx.Context(), bucket, acct.Access, []types.ObjectIdentifier{{Key: &key}}, true, IsBucketPublic, c.be, true)
|
||||
err = auth.CheckObjectAccess(ctx.RequestCtx(), bucket, acct.Access, []types.ObjectIdentifier{{Key: &key}}, true, IsBucketPublic, c.be, true)
|
||||
if err != nil {
|
||||
return &Response{
|
||||
MetaOpts: &MetaOptions{
|
||||
@@ -759,7 +759,7 @@ func (c S3ApiController) PutObject(ctx *fiber.Ctx) (*Response, error) {
|
||||
|
||||
ifMatch, ifNoneMatch := utils.ParsePreconditionMatchHeaders(ctx)
|
||||
|
||||
res, err := c.be.PutObject(ctx.Context(),
|
||||
res, err := c.be.PutObject(ctx.RequestCtx(),
|
||||
s3response.PutObjectInput{
|
||||
Bucket: &bucket,
|
||||
Key: &key,
|
||||
|
||||
@@ -17,7 +17,7 @@ package controllers
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
"github.com/versity/versitygw/s3api/middlewares"
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
"github.com/versity/versitygw/s3err"
|
||||
)
|
||||
|
||||
func (s S3ApiController) CORSOptions(ctx *fiber.Ctx) (*Response, error) {
|
||||
func (s S3ApiController) CORSOptions(ctx fiber.Ctx) (*Response, error) {
|
||||
bucket := ctx.Params("bucket")
|
||||
parsedAcl := utils.ContextKeyParsedAcl.Get(ctx).(auth.ACL)
|
||||
// get headers
|
||||
@@ -63,7 +63,7 @@ func (s S3ApiController) CORSOptions(ctx *fiber.Ctx) (*Response, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
cors, err := s.be.GetBucketCors(ctx.Context(), bucket)
|
||||
cors, err := s.be.GetBucketCors(ctx.RequestCtx(), bucket)
|
||||
if err != nil {
|
||||
debuglogger.Logf("failed to get bucket cors: %v", err)
|
||||
if errors.Is(err, s3err.GetAPIError(s3err.ErrNoSuchCORSConfiguration)) {
|
||||
|
||||
@@ -16,7 +16,7 @@ package middlewares
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
@@ -26,9 +26,9 @@ import (
|
||||
// ParseAcl retreives the bucket acl and stores in the context locals
|
||||
// if no bucket is found, it returns 'NoSuchBucket'
|
||||
func ParseAcl(be backend.Backend) fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
bucket := ctx.Params("bucket")
|
||||
data, err := be.GetBucketAcl(ctx.Context(), &s3.GetBucketAclInput{Bucket: &bucket})
|
||||
data, err := be.GetBucketAcl(ctx.RequestCtx(), &s3.GetBucketAclInput{Bucket: &bucket})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
|
||||
// IsAdmin is a middleware that restricts access to admin APIs, allowing only admin users
|
||||
func IsAdmin(action string) fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
acct := utils.ContextKeyAccount.Get(ctx).(auth.Account)
|
||||
if acct.Role != auth.RoleAdmin {
|
||||
return s3err.GetAPIError(s3err.ErrAdminAccessDenied)
|
||||
|
||||
@@ -17,7 +17,7 @@ package middlewares
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
)
|
||||
@@ -36,12 +36,12 @@ import (
|
||||
func ApplyBucketCORSPreflightFallback(be backend.Backend, fallbackOrigin string) fiber.Handler {
|
||||
fallbackOrigin = strings.TrimSpace(fallbackOrigin)
|
||||
if fallbackOrigin == "" {
|
||||
return func(ctx *fiber.Ctx) error { return ctx.Next() }
|
||||
return func(ctx fiber.Ctx) error { return ctx.Next() }
|
||||
}
|
||||
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
bucket := ctx.Params("bucket")
|
||||
_, err := be.GetBucketCors(ctx.Context(), bucket)
|
||||
_, err := be.GetBucketCors(ctx.RequestCtx(), bucket)
|
||||
if err != nil {
|
||||
if s3Err, ok := err.(s3err.APIError); ok && (s3Err.Code == "NoSuchCORSConfiguration" || s3Err.Code == "NoSuchBucket") {
|
||||
if len(ctx.Response().Header.Peek("Access-Control-Allow-Origin")) == 0 {
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
)
|
||||
@@ -43,7 +43,7 @@ func TestApplyBucketCORSPreflightFallback_NoBucketCors_Responds204(t *testing.T)
|
||||
app := fiber.New()
|
||||
app.Options("/:bucket",
|
||||
ApplyBucketCORSPreflightFallback(be, "https://example.com"),
|
||||
func(c *fiber.Ctx) error {
|
||||
func(c fiber.Ctx) error {
|
||||
// Should not be reached if fallback triggers
|
||||
return c.SendStatus(http.StatusTeapot)
|
||||
},
|
||||
@@ -86,7 +86,7 @@ func TestApplyBucketCORSPreflightFallback_NoSuchBucket_Responds204(t *testing.T)
|
||||
app := fiber.New()
|
||||
app.Options("/:bucket",
|
||||
ApplyBucketCORSPreflightFallback(be, "https://example.com"),
|
||||
func(c *fiber.Ctx) error {
|
||||
func(c fiber.Ctx) error {
|
||||
return c.SendStatus(http.StatusTeapot)
|
||||
},
|
||||
)
|
||||
@@ -125,7 +125,7 @@ func TestApplyBucketCORSPreflightFallback_BucketHasCors_CallsNext(t *testing.T)
|
||||
app := fiber.New()
|
||||
app.Options("/:bucket",
|
||||
ApplyBucketCORSPreflightFallback(be, "https://example.com"),
|
||||
func(c *fiber.Ctx) error {
|
||||
func(c fiber.Ctx) error {
|
||||
return c.SendStatus(http.StatusOK)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
@@ -35,7 +35,7 @@ var VaryHdr = "Origin, Access-Control-Request-Headers, Access-Control-Request-Me
|
||||
func ApplyBucketCORS(be backend.Backend, fallbackOrigin string) fiber.Handler {
|
||||
fallbackOrigin = strings.TrimSpace(fallbackOrigin)
|
||||
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
bucket := ctx.Params("bucket")
|
||||
origin := ctx.Get("Origin")
|
||||
// If neither Origin is present nor a fallback is configured, skip CORS entirely.
|
||||
@@ -44,7 +44,7 @@ func ApplyBucketCORS(be backend.Backend, fallbackOrigin string) fiber.Handler {
|
||||
}
|
||||
|
||||
// if bucket cors is not set, skip the check
|
||||
data, err := be.GetBucketCors(ctx.Context(), bucket)
|
||||
data, err := be.GetBucketCors(ctx.RequestCtx(), bucket)
|
||||
if err != nil {
|
||||
// If CORS is not configured, S3Error will have code NoSuchCORSConfiguration.
|
||||
// In this case, we can safely continue. For any other error, we should log it.
|
||||
|
||||
@@ -17,7 +17,7 @@ package middlewares
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
// ApplyDefaultCORSPreflight responds to CORS preflight (OPTIONS) requests for routes
|
||||
@@ -29,10 +29,10 @@ import (
|
||||
func ApplyDefaultCORSPreflight(fallbackOrigin string) fiber.Handler {
|
||||
fallbackOrigin = strings.TrimSpace(fallbackOrigin)
|
||||
if fallbackOrigin == "" {
|
||||
return func(ctx *fiber.Ctx) error { return nil }
|
||||
return func(ctx fiber.Ctx) error { return nil }
|
||||
}
|
||||
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
if len(ctx.Response().Header.Peek("Access-Control-Allow-Origin")) == 0 {
|
||||
ctx.Response().Header.Add("Access-Control-Allow-Origin", fallbackOrigin)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func TestApplyDefaultCORSPreflight_OptionsSetsPreflightHeaders(t *testing.T) {
|
||||
@@ -28,7 +28,7 @@ func TestApplyDefaultCORSPreflight_OptionsSetsPreflightHeaders(t *testing.T) {
|
||||
app.Options("/admin",
|
||||
ApplyDefaultCORSPreflight(origin),
|
||||
ApplyDefaultCORS(origin),
|
||||
func(c *fiber.Ctx) error { return nil },
|
||||
func(c fiber.Ctx) error { return nil },
|
||||
)
|
||||
|
||||
req, err := http.NewRequest(http.MethodOptions, "/admin", nil)
|
||||
|
||||
@@ -17,10 +17,10 @@ package middlewares
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func ensureExposeETag(ctx *fiber.Ctx) {
|
||||
func ensureExposeETag(ctx fiber.Ctx) {
|
||||
existing := strings.TrimSpace(string(ctx.Response().Header.Peek("Access-Control-Expose-Headers")))
|
||||
defaults := []string{"ETag"}
|
||||
if existing == "" {
|
||||
@@ -57,10 +57,10 @@ func ensureExposeETag(ctx *fiber.Ctx) {
|
||||
func ApplyDefaultCORS(fallbackOrigin string) fiber.Handler {
|
||||
fallbackOrigin = strings.TrimSpace(fallbackOrigin)
|
||||
if fallbackOrigin == "" {
|
||||
return func(ctx *fiber.Ctx) error { return nil }
|
||||
return func(ctx fiber.Ctx) error { return nil }
|
||||
}
|
||||
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
if len(ctx.Response().Header.Peek("Access-Control-Allow-Origin")) == 0 {
|
||||
ctx.Response().Header.Add("Access-Control-Allow-Origin", fallbackOrigin)
|
||||
}
|
||||
|
||||
@@ -18,14 +18,14 @@ import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func TestApplyDefaultCORS_AddsHeaderWhenOriginSet(t *testing.T) {
|
||||
origin := "https://example.com"
|
||||
|
||||
app := fiber.New()
|
||||
app.Get("/admin", ApplyDefaultCORS(origin), func(c *fiber.Ctx) error {
|
||||
app.Get("/admin", ApplyDefaultCORS(origin), func(c fiber.Ctx) error {
|
||||
return c.SendStatus(http.StatusOK)
|
||||
})
|
||||
|
||||
@@ -51,10 +51,10 @@ func TestApplyDefaultCORS_DoesNotOverrideExistingHeader(t *testing.T) {
|
||||
origin := "https://example.com"
|
||||
|
||||
app := fiber.New()
|
||||
app.Get("/admin", func(c *fiber.Ctx) error {
|
||||
app.Get("/admin", func(c fiber.Ctx) error {
|
||||
c.Response().Header.Add("Access-Control-Allow-Origin", "https://already-set.com")
|
||||
return nil
|
||||
}, ApplyDefaultCORS(origin), func(c *fiber.Ctx) error {
|
||||
}, ApplyDefaultCORS(origin), func(c fiber.Ctx) error {
|
||||
return c.SendStatus(http.StatusOK)
|
||||
})
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
@@ -40,7 +40,7 @@ type RootUserConfig struct {
|
||||
func VerifyV4Signature(root RootUserConfig, iam auth.IAMService, region string, streamBody bool, requireContentSha256 bool) fiber.Handler {
|
||||
acct := accounts{root: root, iam: iam}
|
||||
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
// The bucket is public, no need to check this signature
|
||||
if utils.ContextKeyPublicBucket.IsSet(ctx) {
|
||||
return nil
|
||||
@@ -159,7 +159,7 @@ func VerifyV4Signature(root RootUserConfig, iam auth.IAMService, region string,
|
||||
|
||||
if !utils.IsSpecialPayload(hashPayload) {
|
||||
// Calculate the hash of the request payload
|
||||
hashedPayload := sha256.Sum256(ctx.Body())
|
||||
hashedPayload := sha256.Sum256(ctx.BodyRaw())
|
||||
hexPayload := hex.EncodeToString(hashedPayload[:])
|
||||
|
||||
// Compare the calculated hash with the hash provided
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
)
|
||||
|
||||
@@ -85,7 +85,7 @@ func (rr *MockChecksumReader) Checksum() string {
|
||||
|
||||
var _ ChecksumReader = &MockChecksumReader{}
|
||||
|
||||
func wrapBodyReader(ctx *fiber.Ctx, wr func(io.Reader) io.Reader) {
|
||||
func wrapBodyReader(ctx fiber.Ctx, wr func(io.Reader) io.Reader) {
|
||||
rdr, ok := utils.ContextKeyBodyReader.Get(ctx).(io.Reader)
|
||||
if !ok {
|
||||
rdr = ctx.Request().BodyStream()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
)
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
// BucketObjectNameValidator extracts and validates
|
||||
// the bucket and object names from the request URI.
|
||||
func BucketObjectNameValidator() fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
bucket, object := parsePath(ctx.Path())
|
||||
|
||||
// check if the provided bucket name is valid
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
)
|
||||
@@ -32,7 +32,7 @@ import (
|
||||
// it wraps the body reader to handle Content-MD5:
|
||||
// the x-amz-checksum-* headers are explicitly processed by the backend.
|
||||
func VerifyChecksums(streamBody bool, requireBody bool, requireChecksum bool) fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
md5sum := ctx.Get("Content-Md5")
|
||||
|
||||
if streamBody {
|
||||
@@ -58,7 +58,7 @@ func VerifyChecksums(streamBody bool, requireBody bool, requireChecksum bool) fi
|
||||
return nil
|
||||
}
|
||||
|
||||
body := ctx.Body()
|
||||
body := ctx.BodyRaw()
|
||||
if requireBody && len(body) == 0 {
|
||||
return s3err.GetAPIError(s3err.ErrMissingRequestBody)
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
// HostStyleParser is a middleware which parses the bucket name
|
||||
// from the 'Host' header and appends in the request URL path
|
||||
func HostStyleParser(virtualDomain string) fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
host := string(ctx.Request().Host())
|
||||
// the host should match this pattern: '<bucket_name>.<virtual_domain>'
|
||||
bucket, _, found := strings.Cut(host, "."+virtualDomain)
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
)
|
||||
|
||||
func DebugLogger() fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
debuglogger.LogFiberRequestDetails(ctx)
|
||||
err := ctx.Next()
|
||||
debuglogger.LogFiberResponseDetails(ctx)
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
func VerifyPresignedV4Signature(root RootUserConfig, iam auth.IAMService, region string, streamBody bool) fiber.Handler {
|
||||
acct := accounts{root: root, iam: iam}
|
||||
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
// The bucket is public, no need to check this signature
|
||||
if utils.ContextKeyPublicBucket.IsSet(ctx) {
|
||||
return nil
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/metrics"
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
// AuthorizePublicBucketAccess checks if the bucket grants public
|
||||
// access to anonymous requesters
|
||||
func AuthorizePublicBucketAccess(be backend.Backend, s3action string, policyPermission auth.Action, permission auth.Permission, region string, streamBody bool) fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
// skip for authenticated requests
|
||||
if utils.IsPresignedURLAuth(ctx) || ctx.Get("Authorization") != "" {
|
||||
return nil
|
||||
@@ -57,7 +57,7 @@ func AuthorizePublicBucketAccess(be backend.Backend, s3action string, policyPerm
|
||||
}
|
||||
|
||||
bucket, object := parsePath(ctx.Path())
|
||||
err := auth.VerifyPublicAccess(ctx.Context(), be, policyPermission, permission, bucket, object)
|
||||
err := auth.VerifyPublicAccess(ctx.RequestCtx(), be, policyPermission, permission, bucket, object)
|
||||
if err != nil {
|
||||
if s3action == metrics.ActionHeadBucket {
|
||||
// add the bucket region header for HeadBucket
|
||||
@@ -114,7 +114,7 @@ func AuthorizePublicBucketAccess(be backend.Backend, s3action string, policyPerm
|
||||
|
||||
if payloadHash != "" {
|
||||
// Calculate the hash of the request payload
|
||||
hashedPayload := sha256.Sum256(ctx.Body())
|
||||
hashedPayload := sha256.Sum256(ctx.BodyRaw())
|
||||
hexPayload := hex.EncodeToString(hashedPayload[:])
|
||||
|
||||
// Compare the calculated hash with the hash provided
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
)
|
||||
|
||||
// Evaluates/Matches the provided requst query params
|
||||
func MatchQueryArgs(args ...string) fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
if utils.ContextKeySkip.IsSet(ctx) {
|
||||
return ctx.Next()
|
||||
}
|
||||
@@ -37,7 +37,7 @@ func MatchQueryArgs(args ...string) fiber.Handler {
|
||||
|
||||
// Evaluates/Matches the requst header
|
||||
func MatchHeader(key string) fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
if utils.ContextKeySkip.IsSet(ctx) {
|
||||
return ctx.Next()
|
||||
}
|
||||
@@ -53,7 +53,7 @@ func MatchHeader(key string) fiber.Handler {
|
||||
|
||||
// Evaluates/Matches the requst query param and value
|
||||
func MatchQueryArgWithValue(key, val string) fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
if utils.ContextKeySkip.IsSet(ctx) {
|
||||
return ctx.Next()
|
||||
}
|
||||
|
||||
@@ -17,13 +17,13 @@ package middlewares
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
)
|
||||
|
||||
func SetDefaultValues(root RootUserConfig, region string) fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
return func(ctx fiber.Ctx) error {
|
||||
// These are necessary for the server access logs
|
||||
utils.ContextKeyRegion.Set(ctx, region)
|
||||
utils.ContextKeyStartTime.Set(ctx, time.Now())
|
||||
|
||||
@@ -17,12 +17,12 @@ package middlewares
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
// DecodeURL url path unescapes the request url for the gateway
|
||||
// to handle some special characters
|
||||
func DecodeURL(ctx *fiber.Ctx) error {
|
||||
func DecodeURL(ctx fiber.Ctx) error {
|
||||
unescp, err := url.PathUnescape(string(ctx.Request().URI().PathOriginal()))
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
package s3api
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/metrics"
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/s3api/middlewares"
|
||||
|
||||
@@ -17,7 +17,7 @@ package s3api
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/s3api/middlewares"
|
||||
|
||||
+27
-22
@@ -20,9 +20,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||
"github.com/gofiber/fiber/v2/middleware/recover"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/middleware/logger"
|
||||
"github.com/gofiber/fiber/v3/middleware/recover"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
@@ -75,19 +75,17 @@ func New(
|
||||
}
|
||||
|
||||
app := fiber.New(fiber.Config{
|
||||
AppName: "versitygw",
|
||||
ServerHeader: "VERSITYGW",
|
||||
StreamRequestBody: true,
|
||||
DisableKeepalive: !server.keepAlive,
|
||||
Network: fiber.NetworkTCP,
|
||||
DisableStartupMessage: true,
|
||||
ErrorHandler: globalErrorHandler,
|
||||
AppName: "versitygw",
|
||||
ServerHeader: "VERSITYGW",
|
||||
StreamRequestBody: true,
|
||||
DisableKeepalive: !server.keepAlive,
|
||||
ErrorHandler: globalErrorHandler,
|
||||
})
|
||||
|
||||
server.app = app
|
||||
|
||||
// initialize the panic recovery middleware
|
||||
app.Use(recover.New(
|
||||
app.Use("*", recover.New(
|
||||
recover.Config{
|
||||
EnableStackTrace: true,
|
||||
StackTraceHandler: stackTraceHandler,
|
||||
@@ -95,32 +93,32 @@ func New(
|
||||
|
||||
// Logging middlewares
|
||||
if !server.quiet {
|
||||
app.Use(logger.New(logger.Config{
|
||||
app.Use("*", logger.New(logger.Config{
|
||||
Format: "${time} | vgw | ${status} | ${latency} | ${ip} | ${method} | ${path} | ${error} | ${queryParams}\n",
|
||||
}))
|
||||
}
|
||||
// Set up health endpoint if specified
|
||||
if server.health != "" {
|
||||
app.Get(server.health, func(ctx *fiber.Ctx) error {
|
||||
app.Get(server.health, func(ctx fiber.Ctx) error {
|
||||
return ctx.SendStatus(http.StatusOK)
|
||||
})
|
||||
}
|
||||
|
||||
// initilaze the default value setter middleware
|
||||
app.Use(middlewares.SetDefaultValues(root, region))
|
||||
app.Use("*", middlewares.SetDefaultValues(root, region))
|
||||
|
||||
// initialize the 'DecodeURL' middleware which
|
||||
// path unescapes the url
|
||||
app.Use(controllers.WrapMiddleware(middlewares.DecodeURL, l, mm))
|
||||
app.Use("*", controllers.WrapMiddleware(middlewares.DecodeURL, l, mm))
|
||||
|
||||
// initialize host-style parser in virtual domain is specified
|
||||
if server.virtualDomain != "" {
|
||||
app.Use(middlewares.HostStyleParser(server.virtualDomain))
|
||||
app.Use("*", middlewares.HostStyleParser(server.virtualDomain))
|
||||
}
|
||||
|
||||
// initialize the debug logger in debug mode
|
||||
if debuglogger.IsDebugEnabled() {
|
||||
app.Use(middlewares.DebugLogger())
|
||||
app.Use("*", middlewares.DebugLogger())
|
||||
}
|
||||
|
||||
server.Router.Init(app, be, iam, l, adminLogger, evs, mm, server.readonly, region, server.virtualDomain, root, server.corsAllowOrigin)
|
||||
@@ -173,14 +171,21 @@ func WithCORSAllowOrigin(origin string) Option {
|
||||
|
||||
func (sa *S3ApiServer) Serve() (err error) {
|
||||
if sa.CertStorage != nil {
|
||||
ln, err := utils.NewTLSListener(sa.app.Config().Network, sa.port, sa.CertStorage.GetCertificate)
|
||||
ln, err := utils.NewTLSListener(fiber.NetworkTCP, sa.port, sa.CertStorage.GetCertificate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sa.app.Listener(ln)
|
||||
return sa.app.Listener(ln,
|
||||
fiber.ListenConfig{
|
||||
ListenerNetwork: fiber.NetworkTCP,
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
}
|
||||
return sa.app.Listen(sa.port)
|
||||
return sa.app.Listen(sa.port, fiber.ListenConfig{
|
||||
ListenerNetwork: fiber.NetworkTCP,
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
}
|
||||
|
||||
// ShutDown gracefully shuts down the server with a context timeout
|
||||
@@ -190,13 +195,13 @@ func (sa *S3ApiServer) ShutDown() error {
|
||||
|
||||
// stackTraceHandler stores the system panics
|
||||
// in the context locals
|
||||
func stackTraceHandler(ctx *fiber.Ctx, e any) {
|
||||
func stackTraceHandler(ctx fiber.Ctx, e any) {
|
||||
utils.ContextKeyStack.Set(ctx, e)
|
||||
}
|
||||
|
||||
// globalErrorHandler catches the errors before reaching to
|
||||
// the handlers and any system panics
|
||||
func globalErrorHandler(ctx *fiber.Ctx, er error) error {
|
||||
func globalErrorHandler(ctx fiber.Ctx, er error) error {
|
||||
if utils.ContextKeyStack.IsSet(ctx) {
|
||||
// if stack is set, it means the stack trace
|
||||
// has caught a panic
|
||||
|
||||
@@ -17,7 +17,7 @@ package s3api
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/smithy-go/logging"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
v4 "github.com/versity/versitygw/aws/signer/v4"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
@@ -41,7 +41,7 @@ const (
|
||||
// data requests where the data size and checksum are not known until
|
||||
// the data is completely read.
|
||||
type AuthReader struct {
|
||||
ctx *fiber.Ctx
|
||||
ctx fiber.Ctx
|
||||
auth AuthData
|
||||
secret string
|
||||
size int
|
||||
@@ -52,7 +52,7 @@ type AuthReader struct {
|
||||
// v4 auth when the underlying reader returns io.EOF. This postpones the
|
||||
// authorization check until the reader is consumed. So it is important that
|
||||
// the consumer of this reader checks for the auth errors while reading.
|
||||
func NewAuthReader(ctx *fiber.Ctx, r io.Reader, auth AuthData, secret string) *AuthReader {
|
||||
func NewAuthReader(ctx fiber.Ctx, r io.Reader, auth AuthData, secret string) *AuthReader {
|
||||
var hr *HashReader
|
||||
hashPayload := ctx.Get("X-Amz-Content-Sha256")
|
||||
if !IsSpecialPayload(hashPayload) {
|
||||
@@ -114,7 +114,7 @@ const (
|
||||
)
|
||||
|
||||
// CheckValidSignature validates the ctx v4 auth signature
|
||||
func CheckValidSignature(ctx *fiber.Ctx, auth AuthData, secret, checksum string, tdate time.Time, contentLen int64, streamBody bool) error {
|
||||
func CheckValidSignature(ctx fiber.Ctx, auth AuthData, secret, checksum string, tdate time.Time, contentLen int64, streamBody bool) error {
|
||||
signedHdrs := strings.Split(auth.SignedHeaders, ";")
|
||||
|
||||
// Create a new http request instance from fasthttp request
|
||||
|
||||
+12
-11
@@ -15,12 +15,13 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/client"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/valyala/fasthttp/fasthttputil"
|
||||
v4 "github.com/versity/versitygw/aws/signer/v4"
|
||||
)
|
||||
@@ -84,14 +85,14 @@ func Test_Client_UserAgent(t *testing.T) {
|
||||
expectedSig := "37a35d96998d786113ad420c57c22c5433f6aca74f88f26566caa047fc3601c6"
|
||||
dateStr := "20240206T210328Z"
|
||||
|
||||
app := fiber.New(fiber.Config{DisableStartupMessage: true})
|
||||
app := fiber.New(fiber.Config{})
|
||||
|
||||
tdate, err := time.Parse(iso8601Format, dateStr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
req, err := createHttpRequestFromCtx(c, signedHdrs, int64(c.Request().Header.ContentLength()), true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -129,16 +130,16 @@ func Test_Client_UserAgent(t *testing.T) {
|
||||
|
||||
ln := fasthttputil.NewInmemoryListener()
|
||||
go func() {
|
||||
err := app.Listener(ln)
|
||||
err := app.Listener(ln, fiber.ListenConfig{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
c := fiber.AcquireClient()
|
||||
c.UserAgent = agent
|
||||
a := c.Get("http://example.com")
|
||||
a.HostClient.Dial = func(_ string) (net.Conn, error) { return ln.Dial() }
|
||||
a.String()
|
||||
fiber.ReleaseClient(c)
|
||||
c := client.New()
|
||||
c.SetUserAgent(agent)
|
||||
_, err = c.Get("http://example.com")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
)
|
||||
@@ -90,7 +90,7 @@ func (c checksumType) isValid() bool {
|
||||
}
|
||||
|
||||
// Extracts and validates the checksum type from the 'X-Amz-Trailer' header
|
||||
func ExtractChecksumType(ctx *fiber.Ctx) (checksumType, error) {
|
||||
func ExtractChecksumType(ctx fiber.Ctx) (checksumType, error) {
|
||||
trailer := ctx.Get("X-Amz-Trailer")
|
||||
chType := checksumType(strings.ToLower(trailer))
|
||||
if chType != "" && !chType.isValid() {
|
||||
@@ -162,7 +162,7 @@ func IsStreamingPayload(str string) bool {
|
||||
|
||||
// ParseDecodedContentLength extracts and validates the
|
||||
// 'x-amz-decoded-content-length' from fiber context
|
||||
func ParseDecodedContentLength(ctx *fiber.Ctx) (int64, error) {
|
||||
func ParseDecodedContentLength(ctx fiber.Ctx) (int64, error) {
|
||||
decContLengthStr := ctx.Get("X-Amz-Decoded-Content-Length")
|
||||
if decContLengthStr == "" {
|
||||
debuglogger.Logf("missing required header 'X-Amz-Decoded-Content-Length'")
|
||||
@@ -182,7 +182,7 @@ func ParseDecodedContentLength(ctx *fiber.Ctx) (int64, error) {
|
||||
return decContLength, nil
|
||||
}
|
||||
|
||||
func NewChunkReader(ctx *fiber.Ctx, r io.Reader, authdata AuthData, secret string, date time.Time) (io.Reader, error) {
|
||||
func NewChunkReader(ctx fiber.Ctx, r io.Reader, authdata AuthData, secret string, date time.Time) (io.Reader, error) {
|
||||
cLength, err := ParseDecodedContentLength(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
// Region, StartTime, IsRoot, Account, AccessKey context locals
|
||||
@@ -55,19 +55,19 @@ func (ck ContextKey) Values() []ContextKey {
|
||||
}
|
||||
}
|
||||
|
||||
func (ck ContextKey) Set(ctx *fiber.Ctx, val any) {
|
||||
func (ck ContextKey) Set(ctx fiber.Ctx, val any) {
|
||||
ctx.Locals(string(ck), val)
|
||||
}
|
||||
|
||||
func (ck ContextKey) IsSet(ctx *fiber.Ctx) bool {
|
||||
func (ck ContextKey) IsSet(ctx fiber.Ctx) bool {
|
||||
val := ctx.Locals(string(ck))
|
||||
return val != nil
|
||||
}
|
||||
|
||||
func (ck ContextKey) Delete(ctx *fiber.Ctx) {
|
||||
func (ck ContextKey) Delete(ctx fiber.Ctx) {
|
||||
ctx.Locals(string(ck), nil)
|
||||
}
|
||||
|
||||
func (ck ContextKey) Get(ctx *fiber.Ctx) any {
|
||||
func (ck ContextKey) Get(ctx fiber.Ctx) any {
|
||||
return ctx.Locals(string(ck))
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
)
|
||||
|
||||
@@ -45,7 +45,7 @@ func WithCopySource() preconditionOpt {
|
||||
// - If-None-Match
|
||||
// - If-Modified-Since
|
||||
// - If-Unmodified-Since
|
||||
func ParsePreconditionHeaders(ctx *fiber.Ctx, opts ...preconditionOpt) ConditionalHeaders {
|
||||
func ParsePreconditionHeaders(ctx fiber.Ctx, opts ...preconditionOpt) ConditionalHeaders {
|
||||
ifMatch, ifNoneMatch := ParsePreconditionMatchHeaders(ctx, opts...)
|
||||
ifModSince, ifUnmodeSince := ParsePreconditionDateHeaders(ctx, opts...)
|
||||
|
||||
@@ -58,7 +58,7 @@ func ParsePreconditionHeaders(ctx *fiber.Ctx, opts ...preconditionOpt) Condition
|
||||
}
|
||||
|
||||
// ParsePreconditionMatchHeaders extracts "If-Match" and "If-None-Match" headers from fiber Ctx
|
||||
func ParsePreconditionMatchHeaders(ctx *fiber.Ctx, opts ...preconditionOpt) (*string, *string) {
|
||||
func ParsePreconditionMatchHeaders(ctx fiber.Ctx, opts ...preconditionOpt) (*string, *string) {
|
||||
cfg := new(precondtionCfg)
|
||||
for _, opt := range opts {
|
||||
opt(cfg)
|
||||
@@ -75,7 +75,7 @@ func ParsePreconditionMatchHeaders(ctx *fiber.Ctx, opts ...preconditionOpt) (*st
|
||||
|
||||
// ParsePreconditionDateHeaders parses the "If-Modified-Since" and "If-Unmodified-Since"
|
||||
// headers from fiber context to *time.Time
|
||||
func ParsePreconditionDateHeaders(ctx *fiber.Ctx, opts ...preconditionOpt) (*time.Time, *time.Time) {
|
||||
func ParsePreconditionDateHeaders(ctx fiber.Ctx, opts ...preconditionOpt) (*time.Time, *time.Time) {
|
||||
cfg := new(precondtionCfg)
|
||||
for _, opt := range opts {
|
||||
opt(cfg)
|
||||
@@ -129,7 +129,7 @@ func ParsePreconditionDateHeader(date string) *time.Time {
|
||||
|
||||
// ParseIfMatchSize parses the 'x-amz-if-match-size' to *int64
|
||||
// if parsing fails, returns nil
|
||||
func ParseIfMatchSize(ctx *fiber.Ctx) *int64 {
|
||||
func ParseIfMatchSize(ctx fiber.Ctx) *int64 {
|
||||
ifMatchSizeHdr := ctx.Get("x-amz-if-match-size")
|
||||
if ifMatchSizeHdr == "" {
|
||||
return nil
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
|
||||
"github.com/aws/smithy-go/logging"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
)
|
||||
@@ -44,13 +44,13 @@ const (
|
||||
// data requests where the data size is not known until
|
||||
// the data is completely read.
|
||||
type PresignedAuthReader struct {
|
||||
ctx *fiber.Ctx
|
||||
ctx fiber.Ctx
|
||||
auth AuthData
|
||||
secret string
|
||||
r io.Reader
|
||||
}
|
||||
|
||||
func NewPresignedAuthReader(ctx *fiber.Ctx, r io.Reader, auth AuthData, secret string) *PresignedAuthReader {
|
||||
func NewPresignedAuthReader(ctx fiber.Ctx, r io.Reader, auth AuthData, secret string) *PresignedAuthReader {
|
||||
return &PresignedAuthReader{
|
||||
ctx: ctx,
|
||||
r: r,
|
||||
@@ -74,7 +74,7 @@ func (pr *PresignedAuthReader) Read(p []byte) (int, error) {
|
||||
}
|
||||
|
||||
// CheckPresignedSignature validates presigned request signature
|
||||
func CheckPresignedSignature(ctx *fiber.Ctx, auth AuthData, secret string, streamBody bool) error {
|
||||
func CheckPresignedSignature(ctx fiber.Ctx, auth AuthData, secret string, streamBody bool) error {
|
||||
signedHdrs := strings.Split(auth.SignedHeaders, ";")
|
||||
|
||||
var contentLength int64
|
||||
@@ -96,7 +96,7 @@ func CheckPresignedSignature(ctx *fiber.Ctx, auth AuthData, secret string, strea
|
||||
date, _ := time.Parse(iso8601Format, auth.Date)
|
||||
|
||||
signer := v4.NewSigner()
|
||||
uri, _, signErr := signer.PresignHTTP(ctx.Context(), aws.Credentials{
|
||||
uri, _, signErr := signer.PresignHTTP(ctx.RequestCtx(), aws.Credentials{
|
||||
AccessKeyID: auth.Access,
|
||||
SecretAccessKey: secret,
|
||||
}, req, unsignedPayload, service, auth.Region, date, func(options *v4.SignerOptions) {
|
||||
@@ -133,7 +133,7 @@ func CheckPresignedSignature(ctx *fiber.Ctx, auth AuthData, secret string, strea
|
||||
// &X-Amz-Expires=86400
|
||||
// &X-Amz-SignedHeaders=host
|
||||
// &X-Amz-Signature=1e68ad45c1db540284a4a1eca3884c293ba1a0ff63ab9db9a15b5b29dfa02cd8
|
||||
func ParsePresignedURIParts(ctx *fiber.Ctx) (AuthData, error) {
|
||||
func ParsePresignedURIParts(ctx fiber.Ctx) (AuthData, error) {
|
||||
a := AuthData{}
|
||||
|
||||
// Get and verify algorithm query parameter
|
||||
@@ -267,7 +267,7 @@ func validateAlgorithm(algo string) error {
|
||||
|
||||
// IsPresignedURLAuth determines if the request is presigned:
|
||||
// which is authorization with query params
|
||||
func IsPresignedURLAuth(ctx *fiber.Ctx) bool {
|
||||
func IsPresignedURLAuth(ctx fiber.Ctx) bool {
|
||||
algo := ctx.Query("X-Amz-Algorithm")
|
||||
creds := ctx.Query("X-Amz-Credential")
|
||||
signature := ctx.Query("X-Amz-Signature")
|
||||
|
||||
+18
-18
@@ -32,7 +32,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/oklog/ulid/v2"
|
||||
"github.com/valyala/fasthttp"
|
||||
"github.com/versity/versitygw/debuglogger"
|
||||
@@ -71,7 +71,7 @@ func GetUserMetaData(headers *fasthttp.RequestHeader) (metadata map[string]strin
|
||||
return
|
||||
}
|
||||
|
||||
func createHttpRequestFromCtx(ctx *fiber.Ctx, signedHdrs []string, contentLength int64, streamBody bool) (*http.Request, error) {
|
||||
func createHttpRequestFromCtx(ctx fiber.Ctx, signedHdrs []string, contentLength int64, streamBody bool) (*http.Request, error) {
|
||||
req := ctx.Request()
|
||||
var body io.Reader
|
||||
if streamBody {
|
||||
@@ -126,7 +126,7 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func createPresignedHttpRequestFromCtx(ctx *fiber.Ctx, signedHdrs []string, contentLength int64, streamBody bool) (*http.Request, error) {
|
||||
func createPresignedHttpRequestFromCtx(ctx fiber.Ctx, signedHdrs []string, contentLength int64, streamBody bool) (*http.Request, error) {
|
||||
req := ctx.Request()
|
||||
var body io.Reader
|
||||
if streamBody {
|
||||
@@ -177,7 +177,7 @@ func createPresignedHttpRequestFromCtx(ctx *fiber.Ctx, signedHdrs []string, cont
|
||||
return httpReq, nil
|
||||
}
|
||||
|
||||
func SetMetaHeaders(ctx *fiber.Ctx, meta map[string]string) {
|
||||
func SetMetaHeaders(ctx fiber.Ctx, meta map[string]string) {
|
||||
ctx.Response().Header.DisableNormalizing()
|
||||
for key, val := range meta {
|
||||
ctx.Response().Header.Set(fmt.Sprintf("x-amz-meta-%s", key), val)
|
||||
@@ -267,17 +267,17 @@ type CustomHeader struct {
|
||||
Value string
|
||||
}
|
||||
|
||||
func SetResponseHeaders(ctx *fiber.Ctx, headers []CustomHeader) {
|
||||
func SetResponseHeaders(ctx fiber.Ctx, headers []CustomHeader) {
|
||||
for _, header := range headers {
|
||||
ctx.Set(header.Key, header.Value)
|
||||
}
|
||||
}
|
||||
|
||||
// Streams the response body by chunks
|
||||
func StreamResponseBody(ctx *fiber.Ctx, rdr io.ReadCloser, bodysize int) {
|
||||
func StreamResponseBody(ctx fiber.Ctx, rdr io.ReadCloser, bodysize int) {
|
||||
// SetBodyStream will call Close() on the reader when the stream is done
|
||||
// since rdr is a ReadCloser
|
||||
ctx.Context().SetBodyStream(rdr, bodysize)
|
||||
ctx.RequestCtx().SetBodyStream(rdr, bodysize)
|
||||
}
|
||||
|
||||
func IsValidBucketName(bucket string) bool {
|
||||
@@ -361,7 +361,7 @@ func FilterObjectAttributes(attrs map[s3response.ObjectAttributes]struct{}, outp
|
||||
return output
|
||||
}
|
||||
|
||||
func ParseObjectAttributes(ctx *fiber.Ctx) (map[s3response.ObjectAttributes]struct{}, error) {
|
||||
func ParseObjectAttributes(ctx fiber.Ctx) (map[s3response.ObjectAttributes]struct{}, error) {
|
||||
attrs := map[s3response.ObjectAttributes]struct{}{}
|
||||
var err error
|
||||
for key, value := range ctx.Request().Header.All() {
|
||||
@@ -400,7 +400,7 @@ type objLockCfg struct {
|
||||
LegalHoldStatus types.ObjectLockLegalHoldStatus
|
||||
}
|
||||
|
||||
func ParsObjectLockHdrs(ctx *fiber.Ctx) (*objLockCfg, error) {
|
||||
func ParsObjectLockHdrs(ctx fiber.Ctx) (*objLockCfg, error) {
|
||||
legalHoldHdr := ctx.Get("X-Amz-Object-Lock-Legal-Hold")
|
||||
objLockModeHdr := ctx.Get("X-Amz-Object-Lock-Mode")
|
||||
objLockDate := ctx.Get("X-Amz-Object-Lock-Retain-Until-Date")
|
||||
@@ -482,7 +482,7 @@ func (cv ChecksumValues) Headers() string {
|
||||
|
||||
// ParseCalculatedChecksumHeaders parses and validates x-amz-checksum-x header keys
|
||||
// e.g x-amz-checksum-crc32, x-amz-checksum-sha256 ...
|
||||
func ParseCalculatedChecksumHeaders(ctx *fiber.Ctx) (ChecksumValues, error) {
|
||||
func ParseCalculatedChecksumHeaders(ctx fiber.Ctx) (ChecksumValues, error) {
|
||||
checksums := ChecksumValues{}
|
||||
|
||||
var hdrErr error
|
||||
@@ -525,7 +525,7 @@ func ParseCalculatedChecksumHeaders(ctx *fiber.Ctx) (ChecksumValues, error) {
|
||||
// ParseCompleteMpChecksumHeaders parses and validates
|
||||
// the 'CompleteMultipartUpload' x-amz-checksum-x headers
|
||||
// by supporting both 'checksum' and 'checksum-<part_length>' formats
|
||||
func ParseCompleteMpChecksumHeaders(ctx *fiber.Ctx) (ChecksumValues, error) {
|
||||
func ParseCompleteMpChecksumHeaders(ctx fiber.Ctx) (ChecksumValues, error) {
|
||||
// first parse/validate 'x-amz-checksum-x' headers
|
||||
checksums, err := ParseCalculatedChecksumHeaders(ctx)
|
||||
if err != nil {
|
||||
@@ -559,7 +559,7 @@ func ParseCompleteMpChecksumHeaders(ctx *fiber.Ctx) (ChecksumValues, error) {
|
||||
|
||||
// ParseChecksumHeadersAndSdkAlgo parses/validates 'x-amz-sdk-checksum-algorithm' and
|
||||
// 'x-amz-checksum-x' precalculated request headers
|
||||
func ParseChecksumHeadersAndSdkAlgo(ctx *fiber.Ctx) (types.ChecksumAlgorithm, ChecksumValues, error) {
|
||||
func ParseChecksumHeadersAndSdkAlgo(ctx fiber.Ctx) (types.ChecksumAlgorithm, ChecksumValues, error) {
|
||||
sdkAlgorithm := types.ChecksumAlgorithm(strings.ToUpper(ctx.Get("X-Amz-Sdk-Checksum-Algorithm")))
|
||||
err := IsChecksumAlgorithmValid(sdkAlgorithm)
|
||||
if err != nil {
|
||||
@@ -718,7 +718,7 @@ func checkChecksumTypeAndAlgo(algo types.ChecksumAlgorithm, t types.ChecksumType
|
||||
}
|
||||
|
||||
// Parses and validates the x-amz-checksum-algorithm and x-amz-checksum-type headers
|
||||
func ParseCreateMpChecksumHeaders(ctx *fiber.Ctx) (types.ChecksumAlgorithm, types.ChecksumType, error) {
|
||||
func ParseCreateMpChecksumHeaders(ctx fiber.Ctx) (types.ChecksumAlgorithm, types.ChecksumType, error) {
|
||||
algo := types.ChecksumAlgorithm(strings.ToUpper(ctx.Get("x-amz-checksum-algorithm")))
|
||||
if err := IsChecksumAlgorithmValid(algo); err != nil {
|
||||
return "", "", err
|
||||
@@ -918,7 +918,7 @@ func ValidateCopySource(copysource string) error {
|
||||
}
|
||||
|
||||
// GetQueryParam returns a pointer to the query parameter value if it exists
|
||||
func GetQueryParam(ctx *fiber.Ctx, key string) *string {
|
||||
func GetQueryParam(ctx fiber.Ctx, key string) *string {
|
||||
value := ctx.Query(key)
|
||||
if value == "" {
|
||||
return nil
|
||||
@@ -950,9 +950,9 @@ func ValidateVersionId(versionId string) error {
|
||||
|
||||
// GenerateObjectLocation generates the object location path-styled or host-styled
|
||||
// depending on the gateway configuration
|
||||
func GenerateObjectLocation(ctx *fiber.Ctx, virtualDomain, bucket, object string) string {
|
||||
scheme := ctx.Protocol()
|
||||
host := ctx.Hostname()
|
||||
func GenerateObjectLocation(ctx fiber.Ctx, virtualDomain, bucket, object string) string {
|
||||
scheme := ctx.Scheme()
|
||||
host := ctx.Host()
|
||||
|
||||
// escape the object name
|
||||
obj := url.PathEscape(object)
|
||||
@@ -1011,7 +1011,7 @@ func NewTLSListener(network string, address string, getCertificateFunc func(*tls
|
||||
// since ACL operations are not supported on objects, the presence of any ACL headers
|
||||
// results in a NotImplemented error. It returns nil only when all ACL headers
|
||||
// are absent.
|
||||
func ValidateNoACLHeaders(ctx *fiber.Ctx) error {
|
||||
func ValidateNoACLHeaders(ctx fiber.Ctx) error {
|
||||
for _, header := range []string{
|
||||
"x-amz-acl",
|
||||
"x-amz-grant-full-control",
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/valyala/fasthttp"
|
||||
"github.com/versity/versitygw/backend"
|
||||
@@ -35,7 +35,7 @@ import (
|
||||
|
||||
func TestCreateHttpRequestFromCtx(t *testing.T) {
|
||||
type args struct {
|
||||
ctx *fiber.Ctx
|
||||
ctx fiber.Ctx
|
||||
}
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
+3
-3
@@ -20,13 +20,13 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
)
|
||||
|
||||
type S3EventSender interface {
|
||||
SendEvent(ctx *fiber.Ctx, meta EventMeta)
|
||||
SendEvent(ctx fiber.Ctx, meta EventMeta)
|
||||
Close() error
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ func InitEventSender(cfg *EventConfig) (S3EventSender, error) {
|
||||
return evSender, err
|
||||
}
|
||||
|
||||
func createEventSchema(ctx *fiber.Ctx, meta EventMeta, configId ConfigurationId) EventSchema {
|
||||
func createEventSchema(ctx fiber.Ctx, meta EventMeta, configId ConfigurationId) EventSchema {
|
||||
path := strings.Split(ctx.Path(), "/")
|
||||
|
||||
var bucket, object string
|
||||
|
||||
+3
-3
@@ -23,7 +23,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/segmentio/kafka-go"
|
||||
"github.com/versity/versitygw/s3response"
|
||||
)
|
||||
@@ -73,7 +73,7 @@ func InitKafkaEventService(url, topic, key string, filter EventFilter) (S3EventS
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ks *Kafka) SendEvent(ctx *fiber.Ctx, meta EventMeta) {
|
||||
func (ks *Kafka) SendEvent(ctx fiber.Ctx, meta EventMeta) {
|
||||
ks.mu.Lock()
|
||||
defer ks.mu.Unlock()
|
||||
|
||||
@@ -84,7 +84,7 @@ func (ks *Kafka) SendEvent(ctx *fiber.Ctx, meta EventMeta) {
|
||||
if meta.EventName == EventObjectRemovedDeleteObjects {
|
||||
var dObj s3response.DeleteObjects
|
||||
|
||||
if err := xml.Unmarshal(ctx.Body(), &dObj); err != nil {
|
||||
if err := xml.Unmarshal(ctx.BodyRaw(), &dObj); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to parse delete objects input payload: %v\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
+3
-3
@@ -21,7 +21,7 @@ import (
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/nats-io/nats.go"
|
||||
"github.com/versity/versitygw/s3response"
|
||||
)
|
||||
@@ -60,7 +60,7 @@ func InitNatsEventService(url, topic string, filter EventFilter) (S3EventSender,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ns *NatsEventSender) SendEvent(ctx *fiber.Ctx, meta EventMeta) {
|
||||
func (ns *NatsEventSender) SendEvent(ctx fiber.Ctx, meta EventMeta) {
|
||||
ns.mu.Lock()
|
||||
defer ns.mu.Unlock()
|
||||
|
||||
@@ -71,7 +71,7 @@ func (ns *NatsEventSender) SendEvent(ctx *fiber.Ctx, meta EventMeta) {
|
||||
if meta.EventName == EventObjectRemovedDeleteObjects {
|
||||
var dObj s3response.DeleteObjects
|
||||
|
||||
if err := xml.Unmarshal(ctx.Body(), &dObj); err != nil {
|
||||
if err := xml.Unmarshal(ctx.BodyRaw(), &dObj); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to parse delete objects input payload: %v\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/google/uuid"
|
||||
amqp "github.com/rabbitmq/amqp091-go"
|
||||
"github.com/versity/versitygw/s3response"
|
||||
@@ -87,7 +87,7 @@ func InitRabbitmqEventService(url, exchange, routingKey string, filter EventFilt
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (rs *RabbitmqEventSender) SendEvent(ctx *fiber.Ctx, meta EventMeta) {
|
||||
func (rs *RabbitmqEventSender) SendEvent(ctx fiber.Ctx, meta EventMeta) {
|
||||
rs.mu.Lock()
|
||||
defer rs.mu.Unlock()
|
||||
|
||||
@@ -97,7 +97,7 @@ func (rs *RabbitmqEventSender) SendEvent(ctx *fiber.Ctx, meta EventMeta) {
|
||||
|
||||
if meta.EventName == EventObjectRemovedDeleteObjects {
|
||||
var dObj s3response.DeleteObjects
|
||||
if err := xml.Unmarshal(ctx.Body(), &dObj); err != nil {
|
||||
if err := xml.Unmarshal(ctx.BodyRaw(), &dObj); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to parse delete objects input payload: %v\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
+3
-3
@@ -25,7 +25,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/s3response"
|
||||
)
|
||||
|
||||
@@ -72,7 +72,7 @@ func InitWebhookEventSender(url string, filter EventFilter) (S3EventSender, erro
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (w *Webhook) SendEvent(ctx *fiber.Ctx, meta EventMeta) {
|
||||
func (w *Webhook) SendEvent(ctx fiber.Ctx, meta EventMeta) {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
|
||||
@@ -83,7 +83,7 @@ func (w *Webhook) SendEvent(ctx *fiber.Ctx, meta EventMeta) {
|
||||
if meta.EventName == EventObjectRemovedDeleteObjects {
|
||||
var dObj s3response.DeleteObjects
|
||||
|
||||
if err := xml.Unmarshal(ctx.Body(), &dObj); err != nil {
|
||||
if err := xml.Unmarshal(ctx.BodyRaw(), &dObj); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to parse delete objects input payload: %v\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -22,11 +22,11 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
type AuditLogger interface {
|
||||
Log(ctx *fiber.Ctx, err error, body []byte, meta LogMeta)
|
||||
Log(ctx fiber.Ctx, err error, body []byte, meta LogMeta)
|
||||
HangUp() error
|
||||
Shutdown() error
|
||||
}
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
@@ -56,7 +56,7 @@ func InitFileLogger(logname string) (AuditLogger, error) {
|
||||
}
|
||||
|
||||
// Log sends log message to file logger
|
||||
func (f *FileLogger) Log(ctx *fiber.Ctx, err error, body []byte, meta LogMeta) {
|
||||
func (f *FileLogger) Log(ctx fiber.Ctx, err error, body []byte, meta LogMeta) {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
|
||||
@@ -79,7 +79,7 @@ func (f *FileLogger) Log(ctx *fiber.Ctx, err error, body []byte, meta LogMeta) {
|
||||
if !ok {
|
||||
startTime = time.Now()
|
||||
}
|
||||
tlsConnState := ctx.Context().TLSConnectionState()
|
||||
tlsConnState := ctx.RequestCtx().TLSConnectionState()
|
||||
if tlsConnState != nil {
|
||||
lf.CipherSuite = tls.CipherSuiteName(tlsConnState.CipherSuite)
|
||||
lf.TLSVersion = getTLSVersionName(tlsConnState.Version)
|
||||
|
||||
+3
-3
@@ -20,7 +20,7 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
)
|
||||
@@ -45,7 +45,7 @@ func InitAdminFileLogger(logname string) (AuditLogger, error) {
|
||||
}
|
||||
|
||||
// Log sends log message to file logger
|
||||
func (f *AdminFileLogger) Log(ctx *fiber.Ctx, err error, body []byte, meta LogMeta) {
|
||||
func (f *AdminFileLogger) Log(ctx fiber.Ctx, err error, body []byte, meta LogMeta) {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
|
||||
@@ -62,7 +62,7 @@ func (f *AdminFileLogger) Log(ctx *fiber.Ctx, err error, body []byte, meta LogMe
|
||||
if !ok {
|
||||
startTime = time.Now()
|
||||
}
|
||||
tlsConnState := ctx.Context().TLSConnectionState()
|
||||
tlsConnState := ctx.RequestCtx().TLSConnectionState()
|
||||
if tlsConnState != nil {
|
||||
lf.CipherSuite = tls.CipherSuiteName(tlsConnState.CipherSuite)
|
||||
lf.TLSVersion = getTLSVersionName(tlsConnState.Version)
|
||||
|
||||
+3
-3
@@ -26,7 +26,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/versity/versitygw/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
@@ -57,7 +57,7 @@ func InitWebhookLogger(url string) (AuditLogger, error) {
|
||||
}
|
||||
|
||||
// Log sends log message to webhook
|
||||
func (wl *WebhookLogger) Log(ctx *fiber.Ctx, err error, body []byte, meta LogMeta) {
|
||||
func (wl *WebhookLogger) Log(ctx fiber.Ctx, err error, body []byte, meta LogMeta) {
|
||||
wl.mu.Lock()
|
||||
defer wl.mu.Unlock()
|
||||
|
||||
@@ -76,7 +76,7 @@ func (wl *WebhookLogger) Log(ctx *fiber.Ctx, err error, body []byte, meta LogMet
|
||||
if !ok {
|
||||
startTime = time.Now()
|
||||
}
|
||||
tlsConnState := ctx.Context().TLSConnectionState()
|
||||
tlsConnState := ctx.RequestCtx().TLSConnectionState()
|
||||
if tlsConnState != nil {
|
||||
lf.CipherSuite = tls.CipherSuiteName(tlsConnState.CipherSuite)
|
||||
lf.TLSVersion = getTLSVersionName(tlsConnState.Version)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
branch 'sis/fiber-mgration-v2-' set up to track 'origin/sis/fiber-mgration-v2-'.
|
||||
+44
-25
@@ -16,13 +16,13 @@ package webui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"io/fs"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||
"github.com/gofiber/fiber/v2/middleware/recover"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/middleware/logger"
|
||||
"github.com/gofiber/fiber/v3/middleware/recover"
|
||||
"github.com/gofiber/fiber/v3/middleware/static"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
)
|
||||
|
||||
@@ -57,11 +57,10 @@ func WithTLS(cs *utils.CertStorage) Option {
|
||||
}
|
||||
|
||||
// NewServer creates a new GUI server instance
|
||||
func NewServer(cfg *ServerConfig, opts ...Option) *Server {
|
||||
func NewServer(cfg *ServerConfig, opts ...Option) (*Server, error) {
|
||||
app := fiber.New(fiber.Config{
|
||||
AppName: "versitygw",
|
||||
ServerHeader: "VERSITYGW",
|
||||
DisableStartupMessage: true,
|
||||
AppName: "versitygw",
|
||||
ServerHeader: "VERSITYGW",
|
||||
})
|
||||
|
||||
server := &Server{
|
||||
@@ -74,43 +73,55 @@ func NewServer(cfg *ServerConfig, opts ...Option) *Server {
|
||||
}
|
||||
|
||||
server.setupMiddleware()
|
||||
server.setupRoutes()
|
||||
err := server.setupRoutes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Printf("initializing web dashboard on %s\n", cfg.ListenAddr)
|
||||
|
||||
return server
|
||||
return server, nil
|
||||
}
|
||||
|
||||
// setupMiddleware configures middleware
|
||||
func (s *Server) setupMiddleware() {
|
||||
// Panic recovery
|
||||
s.app.Use(recover.New())
|
||||
s.app.Use("*", recover.New())
|
||||
|
||||
// Request logging
|
||||
if !s.quiet {
|
||||
s.app.Use(logger.New(logger.Config{
|
||||
s.app.Use("*", logger.New(logger.Config{
|
||||
Format: "${time} | web | ${status} | ${latency} | ${ip} | ${method} | ${path}\n",
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
// setupRoutes configures all routes
|
||||
func (s *Server) setupRoutes() {
|
||||
func (s *Server) setupRoutes() error {
|
||||
// API endpoint to get configured gateways
|
||||
s.app.Get("/api/gateways", s.handleGetGateways)
|
||||
|
||||
// Serve embedded static files from web/
|
||||
s.app.Use("/", filesystem.New(filesystem.Config{
|
||||
Root: http.FS(webFS),
|
||||
PathPrefix: "web",
|
||||
Index: "index.html",
|
||||
NotFoundFile: "index.html", // SPA fallback
|
||||
Browse: false,
|
||||
// create a subtree from 'web' directory
|
||||
// so that routing works correctly
|
||||
// currently there's a bug in fasthttp resolving fs root
|
||||
// https://github.com/valyala/fasthttp/issues/2141
|
||||
// TODO: remove sub fs after the bug fix
|
||||
subFS, err := fs.Sub(webFS, "web")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.app.Use("/", static.New("", static.Config{
|
||||
FS: subFS,
|
||||
Browse: false,
|
||||
IndexNames: []string{"index.html"},
|
||||
}))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// handleGetGateways returns the configured gateway URLs (both S3 and Admin)
|
||||
func (s *Server) handleGetGateways(c *fiber.Ctx) error {
|
||||
func (s *Server) handleGetGateways(c fiber.Ctx) error {
|
||||
adminGateways := s.config.AdminGateways
|
||||
if len(adminGateways) == 0 {
|
||||
// Fallback to S3 gateways if admin gateways not configured
|
||||
@@ -133,15 +144,23 @@ func (s *Server) Serve() error {
|
||||
|
||||
// Check if TLS is configured
|
||||
if s.CertStorage != nil {
|
||||
ln, err := utils.NewTLSListener(s.app.Config().Network, addr, s.CertStorage.GetCertificate)
|
||||
ln, err := utils.NewTLSListener(fiber.NetworkTCP, addr, s.CertStorage.GetCertificate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.app.Listener(ln)
|
||||
return s.app.Listener(ln,
|
||||
fiber.ListenConfig{
|
||||
ListenerNetwork: fiber.NetworkTCP,
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
}
|
||||
|
||||
return s.app.Listen(addr)
|
||||
return s.app.Listen(addr,
|
||||
fiber.ListenConfig{
|
||||
ListenerNetwork: fiber.NetworkTCP,
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
}
|
||||
|
||||
// Shutdown gracefully shuts down the server
|
||||
|
||||
Reference in New Issue
Block a user