diff --git a/pkg/s3-proxy/bucket/client.go b/pkg/s3-proxy/bucket/client.go index f30917ef..0207bb36 100644 --- a/pkg/s3-proxy/bucket/client.go +++ b/pkg/s3-proxy/bucket/client.go @@ -53,7 +53,7 @@ type ErrorHandlers struct { // nolint:whitespace func NewClient( tgt *config.TargetConfig, tplConfig *config.TemplateConfig, logger log.Logger, - mountPath string, httpRW http.ResponseWriter, + mountPath string, httpRW http.ResponseWriter, httpReq *http.Request, metricsCtx metrics.Client, errorHandlers *ErrorHandlers, parentTrace tracing.Trace, @@ -69,6 +69,7 @@ func NewClient( targetCfg: tgt, mountPath: mountPath, httpRW: httpRW, + httpReq: httpReq, tplConfig: tplConfig, errorsHandlers: errorHandlers, }, nil diff --git a/pkg/s3-proxy/bucket/requestContext.go b/pkg/s3-proxy/bucket/requestContext.go index 589ea42a..a5b3402c 100644 --- a/pkg/s3-proxy/bucket/requestContext.go +++ b/pkg/s3-proxy/bucket/requestContext.go @@ -29,6 +29,7 @@ type requestContext struct { tplConfig *config.TemplateConfig mountPath string httpRW http.ResponseWriter + httpReq *http.Request errorsHandlers *ErrorHandlers } @@ -182,6 +183,25 @@ func (rctx *requestContext) Get(requestPath string) { if err != nil { // Check if error is a not found error if err == s3client.ErrNotFound { + // Test that redirect with trailing slash isn't asked and possible on this request + if rctx.targetCfg.Actions != nil && rctx.targetCfg.Actions.GET != nil && + rctx.targetCfg.Actions.GET.RedirectWithTrailingSlashForNotFoundFile && + !strings.HasSuffix(requestPath, "/") { + // Get path + p := rctx.httpReq.URL.Path + // Check if path doesn't start with / + if !strings.HasPrefix(p, "/") { + p = "/" + p + } + // Check if path doesn't end with / + if !strings.HasSuffix(p, "/") { + p += "/" + } + // Redirect + http.Redirect(rctx.httpRW, rctx.httpReq, p, http.StatusFound) + + return + } // Not found rctx.HandleNotFound(requestPath) // Stop diff --git a/pkg/s3-proxy/config/config.go b/pkg/s3-proxy/config/config.go index 5d2850b0..bc2bcd4a 100644 --- a/pkg/s3-proxy/config/config.go +++ b/pkg/s3-proxy/config/config.go @@ -226,7 +226,8 @@ type PutActionConfigConfig struct { // GetActionConfig Get action configuration type GetActionConfig struct { - Enabled bool `mapstructure:"enabled"` + Enabled bool `mapstructure:"enabled"` + RedirectWithTrailingSlashForNotFoundFile bool `mapstructure:"redirectWithTrailingSlashForNotFoundFile"` } // Resource Resource diff --git a/pkg/s3-proxy/server/middlewares/bucket-request-context.go b/pkg/s3-proxy/server/middlewares/bucket-request-context.go index 6a25428d..241161c1 100644 --- a/pkg/s3-proxy/server/middlewares/bucket-request-context.go +++ b/pkg/s3-proxy/server/middlewares/bucket-request-context.go @@ -41,7 +41,7 @@ func BucketRequestContext( // Get request trace trace := tracing.GetTraceFromRequest(req) // Generate new bucket client - brctx, err := bucket.NewClient(tgt, tplConfig, logEntry, path, rw, metricsCli, errorhandlers, trace) + brctx, err := bucket.NewClient(tgt, tplConfig, logEntry, path, rw, req, metricsCli, errorhandlers, trace) if err != nil { logEntry.Error(err) utils.HandleInternalServerError(logEntry, rw, tplConfig, requestURI, err)