handler, cli: Add a flag to disable downloads and termination of uploads (#668)
* Add a flag to disable downloads of uploaded files * Add a flag to disable deletion of uploaded files * Fix spelling error * Rename `DisableDelete` to `DisableTermination` * Also rename CLI flag * Conditionally build the `Access-Control-Allow-Methods` headers * Update tests with new order of allowed methods header * Add test for checking conditional `Access-Control-Allow-Methods` header
This commit is contained in:
parent
374404c26c
commit
3feef174fd
|
@ -21,6 +21,8 @@ var Flags struct {
|
|||
UploadDir string
|
||||
Basepath string
|
||||
ShowGreeting bool
|
||||
DisableDownload bool
|
||||
DisableTermination bool
|
||||
Timeout int64
|
||||
S3Bucket string
|
||||
S3ObjectPrefix string
|
||||
|
@ -68,6 +70,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")
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
},
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
@ -221,8 +221,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")
|
||||
|
||||
|
|
Loading…
Reference in New Issue