diff --git a/Dockerfile b/Dockerfile index 1c9a157..498e386 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,7 @@ RUN set -xe \ -o /go/bin/tusd ./cmd/tusd/main.go # start a new stage that copies in the binary built in the previous stage -FROM alpine:3.15.1 +FROM alpine:3.15.3 WORKDIR /srv/tusd-data RUN apk add --no-cache ca-certificates jq \ diff --git a/cmd/tusd/cli/flags.go b/cmd/tusd/cli/flags.go index 4f149ab..b584917 100644 --- a/cmd/tusd/cli/flags.go +++ b/cmd/tusd/cli/flags.go @@ -21,6 +21,8 @@ var Flags struct { UploadDir string Basepath string ShowGreeting bool + DisableDownload bool + DisableTermination bool Timeout int64 S3Bucket string S3ObjectPrefix string @@ -73,6 +75,8 @@ func ParseFlags() { flag.StringVar(&Flags.UploadDir, "upload-dir", "./data", "Directory to store uploads in") flag.StringVar(&Flags.Basepath, "base-path", "/files/", "Basepath of the HTTP server") flag.BoolVar(&Flags.ShowGreeting, "show-greeting", true, "Show the greeting message") + flag.BoolVar(&Flags.DisableDownload, "disable-download", false, "Disable the download endpoint") + flag.BoolVar(&Flags.DisableTermination, "disable-termination", false, "Disable the termination endpoint") flag.Int64Var(&Flags.Timeout, "timeout", 6*1000, "Read timeout for connections in milliseconds. A zero value means that reads will not timeout") flag.StringVar(&Flags.S3Bucket, "s3-bucket", "", "Use AWS S3 with this bucket as storage backend (requires the AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_REGION environment variables to be set)") flag.StringVar(&Flags.S3ObjectPrefix, "s3-object-prefix", "", "Prefix for S3 object names") diff --git a/cmd/tusd/cli/serve.go b/cmd/tusd/cli/serve.go index fac6b0e..77ed125 100644 --- a/cmd/tusd/cli/serve.go +++ b/cmd/tusd/cli/serve.go @@ -27,6 +27,8 @@ func Serve() { MaxSize: Flags.MaxSize, BasePath: Flags.Basepath, RespectForwardedHeaders: Flags.BehindProxy, + DisableDownload: Flags.DisableDownload, + DisableTermination: Flags.DisableTermination, StoreComposer: Composer, NotifyCompleteUploads: true, NotifyTerminatedUploads: true, diff --git a/docs/hooks.md b/docs/hooks.md index cce914d..c0f8657 100644 --- a/docs/hooks.md +++ b/docs/hooks.md @@ -43,7 +43,7 @@ A non-zero exit code or HTTP response greater than `400` will return a HTTP 500 ### post-finish -This event will be triggered after an upload is fully finished, meaning that all chunks have been transfered and saved in the storage. After this point, no further modifications, except possible deletion, can be made to the upload entity and it may be desirable to use the file for further processing or notify other applications of the completions of this upload. +This event will be triggered after an upload is fully finished, meaning that all chunks have been transferred and saved in the storage. After this point, no further modifications, except possible deletion, can be made to the upload entity and it may be desirable to use the file for further processing or notify other applications of the completions of this upload. ### post-terminate @@ -51,7 +51,7 @@ This event will be triggered after an upload has been terminated, meaning that t ### post-receive -This event will be triggered for every running upload to indicate its current progress. It will be emitted whenever the server has received more data from the client but at most every second. The offset property will be set to the number of bytes which have been transfered to the server, at the time in total. Please be aware that this number may be higher than the number of bytes which have been stored by the data store! +This event will be triggered for every running upload to indicate its current progress. It will be emitted whenever the server has received more data from the client but at most every second. The offset property will be set to the number of bytes which have been transferred to the server, at the time in total. Please be aware that this number may be higher than the number of bytes which have been stored by the data store! ## Whitelisting Hook Events @@ -95,7 +95,7 @@ The process of the hook files are provided with information about the event and // If the upload is a final one, this value will be an array of upload IDs // which are concatenated to produce the upload. "PartialUploads": null, - // The upload's meta data which can be supplied by the clients as it wishes. + // The upload's metadata which can be supplied by the clients as it wishes. // All keys and values in this object will be strings. // Be aware that it may contain maliciously crafted values and you must not // trust it without escaping it first! @@ -103,7 +103,7 @@ The process of the hook files are provided with information about the event and "filename": "transloadit.png" }, // Details about where the data store saved the uploaded file. The different - // availabl keys vary depending on the used data store. + // available keys vary depending on the used data store. "Storage": { // For example, the filestore supplies the absolute file path: "Type": "filestore", @@ -170,7 +170,7 @@ Tusd will issue a `POST` request to the specified URL endpoint, specifying the h // If the upload is a final one, this value will be an array of upload IDs // which are concatenated to produce the upload. "PartialUploads": null, - // The upload's meta data which can be supplied by the clients as it wishes. + // The upload's metadata which can be supplied by the clients as it wishes. // All keys and values in this object will be strings. // Be aware that it may contain maliciously crafted values and you must not // trust it without escaping it first! @@ -178,7 +178,7 @@ Tusd will issue a `POST` request to the specified URL endpoint, specifying the h "filename": "transloadit.png" }, // Details about where the data store saved the uploaded file. The different - // availabl keys vary depending on the used data store. + // available keys vary depending on the used data store. "Storage": { // For example, the filestore supplies the absolute file path: "Type": "filestore", @@ -247,7 +247,7 @@ Tusd will issue a `gRPC` request to the specified endpoint, specifying the hook // If the upload is a final one, this value will be an array of upload IDs // which are concatenated to produce the upload. "PartialUploads": null, - // The upload's meta data which can be supplied by the clients as it wishes. + // The upload's metadata which can be supplied by the clients as it wishes. // All keys and values in this object will be strings. // Be aware that it may contain maliciously crafted values and you must not // trust it without escaping it first! @@ -255,7 +255,7 @@ Tusd will issue a `gRPC` request to the specified endpoint, specifying the hook "filename": "transloadit.png" }, // Details about where the data store saved the uploaded file. The different - // availabl keys vary depending on the used data store. + // available keys vary depending on the used data store. "Storage": { // For example, the filestore supplies the absolute file path: "Type": "filestore", diff --git a/go.mod b/go.mod index 88fbc97..000915d 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ go 1.16 require ( cloud.google.com/go/storage v1.21.0 github.com/Azure/azure-storage-blob-go v0.14.0 - github.com/aws/aws-sdk-go v1.43.21 + github.com/aws/aws-sdk-go v1.43.31 github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.2 @@ -20,7 +20,7 @@ require ( github.com/stretchr/testify v1.7.1 github.com/vimeo/go-util v1.4.1 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - google.golang.org/api v0.73.0 + google.golang.org/api v0.74.0 google.golang.org/grpc v1.45.0 gopkg.in/Acconut/lockfile.v1 v1.1.0 gopkg.in/h2non/gock.v1 v1.1.2 diff --git a/go.sum b/go.sum index f3f4ff5..9379f18 100644 --- a/go.sum +++ b/go.sum @@ -80,8 +80,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/aws/aws-sdk-go v1.43.21 h1:E4S2eX3d2gKJyI/ISrcIrSwXwqjIvCK85gtBMt4sAPE= -github.com/aws/aws-sdk-go v1.43.21/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0= +github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -216,8 +216,9 @@ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -430,8 +431,9 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de h1:pZB1TWnKi+o4bENlbzAgLrEbY4RMYmUIRobMcSmfeYc= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -449,6 +451,7 @@ golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -527,8 +530,9 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 h1:eJv7u3ksNXoLbGSKuv2s/SIO4tJVxc/A+MTpzxDgz/Q= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -638,8 +642,9 @@ google.golang.org/api v0.66.0/go.mod h1:I1dmXYpX7HGwz/ejRxwQp2qj5bFAz93HiCU1C1oY google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= google.golang.org/api v0.69.0/go.mod h1:boanBiw+h5c3s+tBPgEzLDRHfFLWV0qXxRHz3ws7C80= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.73.0 h1:O9bThUh35K1rvUrQwTUQ1eqLC/IYyzUpWavYIO2EXvo= -google.golang.org/api v0.73.0/go.mod h1:lbd/q6BRFJbdpV6OUCXstVeiI5mL/d3/WifG7iNKnjI= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -727,8 +732,10 @@ google.golang.org/genproto v0.0.0-20220211171837-173942840c17/go.mod h1:kGP+zUP2 google.golang.org/genproto v0.0.0-20220216160803-4663080d8bc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6 h1:FglFEfyj61zP3c6LgjmVHxYxZWXYul9oiS1EZqD5gLc= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb h1:0m9wktIpOxGw+SSKmydXWB3Z3GTfcPP6+q75HCQa6HI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= diff --git a/pkg/handler/config.go b/pkg/handler/config.go index 04accc7..bb3f610 100644 --- a/pkg/handler/config.go +++ b/pkg/handler/config.go @@ -22,6 +22,12 @@ type Config struct { // absolute URL containing a scheme, e.g. "http://tus.io" BasePath string isAbs bool + // DisableDownload indicates whether the server will refuse downloads of the + // uploaded file, by not mounting the GET handler. + DisableDownload bool + // DisableTermination indicates whether the server will refuse termination + // requests of the uploaded file, by not mounting the DELETE handler. + DisableTermination bool // NotifyCompleteUploads indicates whether sending notifications about // completed uploads using the CompleteUploads channel should be enabled. NotifyCompleteUploads bool diff --git a/pkg/handler/cors_test.go b/pkg/handler/cors_test.go index 209b525..e464916 100644 --- a/pkg/handler/cors_test.go +++ b/pkg/handler/cors_test.go @@ -22,7 +22,29 @@ func TestCORS(t *testing.T) { Code: http.StatusOK, ResHeader: map[string]string{ "Access-Control-Allow-Headers": "Authorization, Origin, X-Requested-With, X-Request-ID, X-HTTP-Method-Override, Content-Type, Upload-Length, Upload-Offset, Tus-Resumable, Upload-Metadata, Upload-Defer-Length, Upload-Concat", - "Access-Control-Allow-Methods": "POST, GET, HEAD, PATCH, DELETE, OPTIONS", + "Access-Control-Allow-Methods": "POST, HEAD, PATCH, OPTIONS, GET, DELETE", + "Access-Control-Max-Age": "86400", + "Access-Control-Allow-Origin": "tus.io", + }, + }).Run(handler, t) + }) + + SubTest(t, "Conditional allow methods", func(t *testing.T, store *MockFullDataStore, composer *StoreComposer) { + handler, _ := NewHandler(Config{ + StoreComposer: composer, + DisableTermination: true, + DisableDownload: true, + }) + + (&httpTest{ + Method: "OPTIONS", + ReqHeader: map[string]string{ + "Origin": "tus.io", + }, + Code: http.StatusOK, + ResHeader: map[string]string{ + "Access-Control-Allow-Headers": "Authorization, Origin, X-Requested-With, X-Request-ID, X-HTTP-Method-Override, Content-Type, Upload-Length, Upload-Offset, Tus-Resumable, Upload-Metadata, Upload-Defer-Length, Upload-Concat", + "Access-Control-Allow-Methods": "POST, HEAD, PATCH, OPTIONS", "Access-Control-Max-Age": "86400", "Access-Control-Allow-Origin": "tus.io", }, diff --git a/pkg/handler/handler.go b/pkg/handler/handler.go index 067841f..c5030a6 100644 --- a/pkg/handler/handler.go +++ b/pkg/handler/handler.go @@ -40,10 +40,12 @@ func NewHandler(config Config) (*Handler, error) { mux.Post("", http.HandlerFunc(handler.PostFile)) mux.Head(":id", http.HandlerFunc(handler.HeadFile)) mux.Add("PATCH", ":id", http.HandlerFunc(handler.PatchFile)) - mux.Get(":id", http.HandlerFunc(handler.GetFile)) + if !config.DisableDownload { + mux.Get(":id", http.HandlerFunc(handler.GetFile)) + } // Only attach the DELETE handler if the Terminate() method is provided - if config.StoreComposer.UsesTerminater { + if config.StoreComposer.UsesTerminater && !config.DisableTermination { mux.Del(":id", http.HandlerFunc(handler.DelFile)) } diff --git a/pkg/handler/unrouted_handler.go b/pkg/handler/unrouted_handler.go index 3433e70..c715e9a 100644 --- a/pkg/handler/unrouted_handler.go +++ b/pkg/handler/unrouted_handler.go @@ -162,8 +162,17 @@ func (handler *UnroutedHandler) Middleware(h http.Handler) http.Handler { header.Set("Access-Control-Allow-Origin", origin) if r.Method == "OPTIONS" { + allowedMethods := "POST, HEAD, PATCH, OPTIONS" + if !handler.config.DisableDownload { + allowedMethods += ", GET" + } + + if !handler.config.DisableTermination { + allowedMethods += ", DELETE" + } + // Preflight request - header.Add("Access-Control-Allow-Methods", "POST, GET, HEAD, PATCH, DELETE, OPTIONS") + header.Add("Access-Control-Allow-Methods", allowedMethods) header.Add("Access-Control-Allow-Headers", "Authorization, Origin, X-Requested-With, X-Request-ID, X-HTTP-Method-Override, Content-Type, Upload-Length, Upload-Offset, Tus-Resumable, Upload-Metadata, Upload-Defer-Length, Upload-Concat") header.Set("Access-Control-Max-Age", "86400")