diff --git a/changelog/unreleased/thumbnail-request-limit.md b/changelog/unreleased/thumbnail-request-limit.md index 8c1ea0f85d7..4bbaed32c8d 100644 --- a/changelog/unreleased/thumbnail-request-limit.md +++ b/changelog/unreleased/thumbnail-request-limit.md @@ -4,3 +4,4 @@ The number of concurrent requests to the thumbnail service can be limited now to have more control over the consumed system resources. https://github.com/owncloud/ocis/pull/9199 +https://github.com/owncloud/ocis/pull/9240 diff --git a/ocis-pkg/middleware/throttle.go b/ocis-pkg/middleware/throttle.go index 2e331b9b05b..4b1416eb9ed 100644 --- a/ocis-pkg/middleware/throttle.go +++ b/ocis-pkg/middleware/throttle.go @@ -2,14 +2,28 @@ package middleware import ( "net/http" + "time" "github.com/go-chi/chi/v5/middleware" ) +func retryAfterFn(ctxDone bool) time.Duration { + if ctxDone { + return time.Minute + } + return time.Minute * 5 +} + // Throttle limits the number of concurrent requests. func Throttle(limit int) func(http.Handler) http.Handler { if limit > 0 { - return middleware.Throttle(limit) + opts := middleware.ThrottleOpts{ + RetryAfterFn: retryAfterFn, + Limit: limit, + BacklogLimit: 0, + BacklogTimeout: time.Minute, + } + return middleware.ThrottleWithOpts(opts) } return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/services/webdav/pkg/service/v0/service.go b/services/webdav/pkg/service/v0/service.go index ad914752725..6a92caf83e4 100644 --- a/services/webdav/pkg/service/v0/service.go +++ b/services/webdav/pkg/service/v0/service.go @@ -33,11 +33,6 @@ import ( "github.com/owncloud/ocis/v2/services/webdav/pkg/dav/requests" ) -func init() { - // register method with chi before any routing is set up - chi.RegisterMethod("REPORT") -} - var ( codesEnum = map[int]string{ http.StatusBadRequest: "Sabre\\DAV\\Exception\\BadRequest", @@ -58,6 +53,9 @@ func NewService(opts ...Option) (Service, error) { options := newOptions(opts...) conf := options.Config + // register method with chi before any routing is set up + chi.RegisterMethod("REPORT") + m := chi.NewMux() m.Use( otelchi.Middleware( @@ -454,13 +452,13 @@ func (g Webdav) sendThumbnailResponse(rsp *thumbnailssvc.GetThumbnailResponse, w // Timeout: time.Second * 5, } - dlReq, err := http.NewRequest(http.MethodGet, rsp.DataEndpoint, http.NoBody) + dlReq, err := http.NewRequest(http.MethodGet, rsp.GetDataEndpoint(), http.NoBody) if err != nil { renderError(w, r, errInternalError(err.Error())) logger.Error().Err(err).Msg("could not create download thumbnail request") return } - dlReq.Header.Set("Transfer-Token", rsp.TransferToken) + dlReq.Header.Set("Transfer-Token", rsp.GetTransferToken()) dlRsp, err := client.Do(dlReq) if err != nil { @@ -470,6 +468,15 @@ func (g Webdav) sendThumbnailResponse(rsp *thumbnailssvc.GetThumbnailResponse, w } defer dlRsp.Body.Close() + if dlRsp.StatusCode == http.StatusTooManyRequests { + retryAfter := dlRsp.Header.Get("Retry-After") + if retryAfter != "" { + w.Header().Set("Retry-After", retryAfter) + } + w.WriteHeader(http.StatusTooManyRequests) + return + } + if dlRsp.StatusCode != http.StatusOK { logger.Debug(). Str("transfer_token", rsp.GetTransferToken()).