diff --git a/go.mod b/go.mod index 456aaa2248..b1af7fb1af 100644 --- a/go.mod +++ b/go.mod @@ -89,7 +89,7 @@ require ( github.com/thejerf/suture/v4 v4.0.6 github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 - github.com/tus/tusd/v2 v2.8.0 + github.com/tus/tusd/v2 v2.9.2 github.com/unrolled/secure v1.16.0 github.com/vmihailenco/msgpack/v5 v5.4.1 github.com/xhit/go-simple-mail/v2 v2.16.0 @@ -392,7 +392,7 @@ require ( golang.org/x/sys v0.42.0 // indirect golang.org/x/time v0.15.0 // indirect golang.org/x/tools v0.42.0 // indirect - google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect + google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect diff --git a/go.sum b/go.sum index d321a6dab8..24d52c967a 100644 --- a/go.sum +++ b/go.sum @@ -1230,8 +1230,8 @@ github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208/go.mod h1:BzWtXXrXz github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g= github.com/trustelem/zxcvbn v1.0.1 h1:mp4JFtzdDYGj9WYSD3KQSkwwUumWNFzXaAjckaTYpsc= github.com/trustelem/zxcvbn v1.0.1/go.mod h1:zonUyKeh7sw6psPf/e3DtRqkRyZvAbOfjNz/aO7YQ5s= -github.com/tus/tusd/v2 v2.8.0 h1:X2jGxQ05jAW4inDd2ogmOKqwnb4c/D0lw2yhgHayWyU= -github.com/tus/tusd/v2 v2.8.0/go.mod h1:3/zEOVQQIwmJhvNam8phV4x/UQt68ZmZiTzeuJUNhVo= +github.com/tus/tusd/v2 v2.9.2 h1:Dd/Dh0CG7+/wom4lDQnnhca+1p5qVwgnbyEBacj1v7c= +github.com/tus/tusd/v2 v2.9.2/go.mod h1:+a9uNLru2Qy+CUu7QUIshmQ+X0fLNw77eu8voKVxmgA= github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= @@ -1716,8 +1716,8 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE= -google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE= +google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM= +google.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM= google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= diff --git a/vendor/github.com/tus/tusd/v2/pkg/handler/config.go b/vendor/github.com/tus/tusd/v2/pkg/handler/config.go index 480fa243c2..4efa43598c 100644 --- a/vendor/github.com/tus/tusd/v2/pkg/handler/config.go +++ b/vendor/github.com/tus/tusd/v2/pkg/handler/config.go @@ -33,6 +33,9 @@ type Config struct { // DisableTermination indicates whether the server will refuse termination // requests of the uploaded file, by not mounting the DELETE handler. DisableTermination bool + // DisableConcatenation indicates whether the server will refuse POST requests + // for creating uploads that use the concatenation extension. + DisableConcatenation bool // Cors can be used to customize the handling of Cross-Origin Resource Sharing (CORS). // See the CorsConfig struct for more details. // Defaults to DefaultCorsConfig. diff --git a/vendor/github.com/tus/tusd/v2/pkg/handler/context.go b/vendor/github.com/tus/tusd/v2/pkg/handler/context.go index 892009bab5..3348a4cf58 100644 --- a/vendor/github.com/tus/tusd/v2/pkg/handler/context.go +++ b/vendor/github.com/tus/tusd/v2/pkg/handler/context.go @@ -80,18 +80,13 @@ func (h UnroutedHandler) getContext(w http.ResponseWriter, r *http.Request) *htt return c } -func (c httpContext) Value(key any) any { - // We overwrite the Value function to ensure that the values from the request - // context are returned because c.Context does not contain any values. - return c.req.Context().Value(key) -} - -// newDelayedContext returns a context that is cancelled with a delay. If the parent context +// newDelayedContext returns a context with delayed cancellation propagation. If the parent context // is done, the new context will also be cancelled but only after waiting the specified delay. // Note: The parent context MUST be cancelled or otherwise this will leak resources. In the // case of http.Request.Context, the net/http package ensures that the context is always cancelled. func newDelayedContext(parent context.Context, delay time.Duration) context.Context { - ctx, cancel := context.WithCancel(context.Background()) + // Use context.WithoutCancel to preserve the values. + ctx, cancel := context.WithCancel(context.WithoutCancel(parent)) go func() { <-parent.Done() <-time.After(delay) diff --git a/vendor/github.com/tus/tusd/v2/pkg/handler/hooks.go b/vendor/github.com/tus/tusd/v2/pkg/handler/hooks.go index c1c6f11333..1b0e274865 100644 --- a/vendor/github.com/tus/tusd/v2/pkg/handler/hooks.go +++ b/vendor/github.com/tus/tusd/v2/pkg/handler/hooks.go @@ -33,7 +33,8 @@ func newHookEvent(c *httpContext, info FileInfo) HookEvent { // > For incoming requests, the Host header is promoted to the // > Request.Host field and removed from the Header map. // That's why we add it back manually. - c.req.Header.Set("Host", c.req.Host) + copiedHeader := c.req.Header.Clone() + copiedHeader.Set("Host", c.req.Host) return HookEvent{ Context: c, @@ -42,7 +43,7 @@ func newHookEvent(c *httpContext, info FileInfo) HookEvent { Method: c.req.Method, URI: c.req.RequestURI, RemoteAddr: c.req.RemoteAddr, - Header: c.req.Header, + Header: copiedHeader, }, } } diff --git a/vendor/github.com/tus/tusd/v2/pkg/handler/http.go b/vendor/github.com/tus/tusd/v2/pkg/handler/http.go index d521fd1ac4..802ba97024 100644 --- a/vendor/github.com/tus/tusd/v2/pkg/handler/http.go +++ b/vendor/github.com/tus/tusd/v2/pkg/handler/http.go @@ -1,6 +1,7 @@ package handler import ( + "maps" "net/http" "strconv" ) @@ -67,13 +68,9 @@ func (resp1 HTTPResponse) MergeWith(resp2 HTTPResponse) HTTPResponse { // into the header map from response 1. newResp.Header = make(HTTPHeader, len(resp1.Header)+len(resp2.Header)) - for key, value := range resp1.Header { - newResp.Header[key] = value - } + maps.Copy(newResp.Header, resp1.Header) - for key, value := range resp2.Header { - newResp.Header[key] = value - } + maps.Copy(newResp.Header, resp2.Header) return newResp } diff --git a/vendor/github.com/tus/tusd/v2/pkg/handler/metrics.go b/vendor/github.com/tus/tusd/v2/pkg/handler/metrics.go index 1a2c6aad99..ddd7af3174 100644 --- a/vendor/github.com/tus/tusd/v2/pkg/handler/metrics.go +++ b/vendor/github.com/tus/tusd/v2/pkg/handler/metrics.go @@ -1,6 +1,7 @@ package handler import ( + "maps" "sync" "sync/atomic" ) @@ -123,9 +124,7 @@ func (e *ErrorsTotalMap) retrievePointerFor(err Error) *uint64 { func (e *ErrorsTotalMap) Load() map[ErrorsTotalMapEntry]*uint64 { m := make(map[ErrorsTotalMapEntry]*uint64, len(e.counter)) e.lock.RLock() - for err, ptr := range e.counter { - m[err] = ptr - } + maps.Copy(m, e.counter) e.lock.RUnlock() return m diff --git a/vendor/github.com/tus/tusd/v2/pkg/handler/unrouted_handler.go b/vendor/github.com/tus/tusd/v2/pkg/handler/unrouted_handler.go index 9cb7be6278..3053c7de6b 100644 --- a/vendor/github.com/tus/tusd/v2/pkg/handler/unrouted_handler.go +++ b/vendor/github.com/tus/tusd/v2/pkg/handler/unrouted_handler.go @@ -54,6 +54,7 @@ var ( ErrNotImplemented = NewError("ERR_NOT_IMPLEMENTED", "feature not implemented", http.StatusNotImplemented) ErrUploadNotFinished = NewError("ERR_UPLOAD_NOT_FINISHED", "one of the partial uploads is not finished", http.StatusBadRequest) ErrInvalidConcat = NewError("ERR_INVALID_CONCAT", "invalid Upload-Concat header", http.StatusBadRequest) + ErrConcatenationUnsupported = NewError("ERR_CONCATENATION_UNSUPPORTED", "Upload-Concat header is not supported by server", http.StatusBadRequest) ErrModifyFinal = NewError("ERR_MODIFY_FINAL", "modifying a final upload is not allowed", http.StatusForbidden) ErrUploadLengthAndUploadDeferLength = NewError("ERR_AMBIGUOUS_UPLOAD_LENGTH", "provided both Upload-Length and Upload-Defer-Length", http.StatusBadRequest) ErrInvalidUploadDeferLength = NewError("ERR_INVALID_UPLOAD_LENGTH_DEFER", "invalid Upload-Defer-Length header", http.StatusBadRequest) @@ -125,10 +126,10 @@ func NewUnroutedHandler(config Config) (*UnroutedHandler, error) { // Only promote extesions using the Tus-Extension header which are implemented extensions := "creation,creation-with-upload" - if config.StoreComposer.UsesTerminater { + if config.StoreComposer.UsesTerminater && !config.DisableTermination { extensions += ",termination" } - if config.StoreComposer.UsesConcater { + if config.StoreComposer.UsesConcater && !config.DisableConcatenation { extensions += ",concatenation" } if config.StoreComposer.UsesLengthDeferrer { @@ -299,6 +300,11 @@ func (handler *UnroutedHandler) PostFile(w http.ResponseWriter, r *http.Request) concatHeader = r.Header.Get("Upload-Concat") } + if concatHeader != "" && handler.config.DisableConcatenation { + handler.sendError(c, ErrConcatenationUnsupported) + return + } + // Parse Upload-Concat header isPartial, isFinal, partialUploadIDs, err := parseConcat(concatHeader, handler.basePath) if err != nil { @@ -1574,7 +1580,7 @@ func getIETFDraftUploadLength(r *http.Request) (length int64, lengthIsDeferred b func ParseMetadataHeader(header string) map[string]string { meta := make(map[string]string) - for _, element := range strings.Split(header, ",") { + for element := range strings.SplitSeq(header, ",") { element := strings.TrimSpace(element) parts := strings.Split(element, " ") @@ -1640,8 +1646,8 @@ func parseConcat(header string, basePath string) (isPartial bool, isFinal bool, if strings.HasPrefix(header, "final;") && len(header) > l { isFinal = true - list := strings.Split(header[l:], " ") - for _, value := range list { + list := strings.SplitSeq(header[l:], " ") + for value := range list { value := strings.TrimSpace(value) if value == "" { continue diff --git a/vendor/modules.txt b/vendor/modules.txt index 6008877a14..22f2d090a3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -2125,8 +2125,8 @@ github.com/trustelem/zxcvbn/internal/mathutils github.com/trustelem/zxcvbn/match github.com/trustelem/zxcvbn/matching github.com/trustelem/zxcvbn/scoring -# github.com/tus/tusd/v2 v2.8.0 -## explicit; go 1.23.0 +# github.com/tus/tusd/v2 v2.9.2 +## explicit; go 1.25.0 github.com/tus/tusd/v2/pkg/handler # github.com/unrolled/secure v1.16.0 => github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 ## explicit; go 1.13 @@ -2570,8 +2570,8 @@ golang.org/x/tools/internal/stdlib golang.org/x/tools/internal/typeparams golang.org/x/tools/internal/typesinternal golang.org/x/tools/internal/versions -# google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb -## explicit; go 1.23.0 +# google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 +## explicit; go 1.24.0 google.golang.org/genproto/protobuf/field_mask # google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 ## explicit; go 1.24.0