2019-06-11 16:23:20 +00:00
|
|
|
package handler
|
2016-02-21 22:25:35 +00:00
|
|
|
|
|
|
|
import (
|
2016-03-11 19:46:34 +00:00
|
|
|
"errors"
|
2016-02-21 22:25:35 +00:00
|
|
|
"log"
|
|
|
|
"net/url"
|
|
|
|
"os"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Config provides a way to configure the Handler depending on your needs.
|
|
|
|
type Config struct {
|
2016-03-12 15:51:00 +00:00
|
|
|
// StoreComposer points to the store composer from which the core data store
|
|
|
|
// and optional dependencies should be taken. May only be nil if DataStore is
|
|
|
|
// set.
|
2019-08-20 14:16:05 +00:00
|
|
|
// TODO: Remove pointer?
|
2016-02-21 22:25:35 +00:00
|
|
|
StoreComposer *StoreComposer
|
|
|
|
// MaxSize defines how many bytes may be stored in one single upload. If its
|
|
|
|
// value is is 0 or smaller no limit will be enforced.
|
|
|
|
MaxSize int64
|
|
|
|
// BasePath defines the URL path used for handling uploads, e.g. "/files/".
|
|
|
|
// If no trailing slash is presented it will be added. You may specify an
|
|
|
|
// absolute URL containing a scheme, e.g. "http://tus.io"
|
|
|
|
BasePath string
|
|
|
|
isAbs bool
|
2022-03-28 21:43:35 +00:00
|
|
|
// 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
|
2023-03-26 22:11:41 +00:00
|
|
|
// Disable cors headers. If set to true, tusd will not send any CORS related header.
|
|
|
|
// This is useful if you have a proxy sitting in front of tusd that handles CORS.
|
|
|
|
DisableCors bool
|
2016-03-12 21:28:24 +00:00
|
|
|
// NotifyCompleteUploads indicates whether sending notifications about
|
|
|
|
// completed uploads using the CompleteUploads channel should be enabled.
|
2016-02-21 22:25:35 +00:00
|
|
|
NotifyCompleteUploads bool
|
2016-03-12 21:24:57 +00:00
|
|
|
// NotifyTerminatedUploads indicates whether sending notifications about
|
|
|
|
// terminated uploads using the TerminatedUploads channel should be enabled.
|
|
|
|
NotifyTerminatedUploads bool
|
2017-02-21 22:17:07 +00:00
|
|
|
// NotifyUploadProgress indicates whether sending notifications about
|
|
|
|
// the upload progress using the UploadProgress channel should be enabled.
|
|
|
|
NotifyUploadProgress bool
|
2017-07-19 15:45:16 +00:00
|
|
|
// NotifyCreatedUploads indicates whether sending notifications about
|
|
|
|
// the upload having been created using the CreatedUploads channel should be enabled.
|
|
|
|
NotifyCreatedUploads bool
|
2016-03-12 21:28:24 +00:00
|
|
|
// Logger is the logger to use internally, mostly for printing requests.
|
2016-02-21 22:25:35 +00:00
|
|
|
Logger *log.Logger
|
2021-09-04 23:13:55 +00:00
|
|
|
// Explicitly set Access-Control-Allow-Origin in cases where RespectForwardedHeaders
|
|
|
|
// doesn't give you the desired result. This can be the case with some reverse proxies
|
|
|
|
// or a kubernetes setup with complex network routing rules
|
|
|
|
CorsOrigin string
|
2016-02-21 22:25:35 +00:00
|
|
|
// Respect the X-Forwarded-Host, X-Forwarded-Proto and Forwarded headers
|
|
|
|
// potentially set by proxies when generating an absolute URL in the
|
2016-09-27 20:10:16 +00:00
|
|
|
// response to POST requests.
|
2016-02-21 22:25:35 +00:00
|
|
|
RespectForwardedHeaders bool
|
2020-05-15 15:27:09 +00:00
|
|
|
// PreUploadCreateCallback will be invoked before a new upload is created, if the
|
2019-09-19 09:15:48 +00:00
|
|
|
// property is supplied. If the callback returns nil, the upload will be created.
|
|
|
|
// Otherwise the HTTP request will be aborted. This can be used to implement
|
|
|
|
// validation of upload metadata etc.
|
|
|
|
PreUploadCreateCallback func(hook HookEvent) error
|
2020-05-15 15:27:09 +00:00
|
|
|
// PreFinishResponseCallback will be invoked after an upload is completed but before
|
|
|
|
// a response is returned to the client. Error responses from the callback will be passed
|
|
|
|
// back to the client. This can be used to implement post-processing validation.
|
|
|
|
PreFinishResponseCallback func(hook HookEvent) error
|
2016-02-21 22:25:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (config *Config) validate() error {
|
|
|
|
if config.Logger == nil {
|
2022-09-09 16:34:18 +00:00
|
|
|
config.Logger = log.New(os.Stdout, "[tusd] ", log.Ldate|log.Lmicroseconds)
|
2016-02-21 22:25:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
base := config.BasePath
|
|
|
|
uri, err := url.Parse(base)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure base path ends with slash to remove logic from absFileURL
|
|
|
|
if base != "" && string(base[len(base)-1]) != "/" {
|
|
|
|
base += "/"
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure base path begins with slash if not absolute (starts with scheme)
|
|
|
|
if !uri.IsAbs() && len(base) > 0 && string(base[0]) != "/" {
|
|
|
|
base = "/" + base
|
|
|
|
}
|
|
|
|
config.BasePath = base
|
|
|
|
config.isAbs = uri.IsAbs()
|
|
|
|
|
|
|
|
if config.StoreComposer == nil {
|
2019-08-20 14:16:05 +00:00
|
|
|
return errors.New("tusd: StoreComposer must no be nil")
|
2016-03-11 19:46:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if config.StoreComposer.Core == nil {
|
|
|
|
return errors.New("tusd: StoreComposer in Config needs to contain a non-nil core")
|
2016-02-21 22:25:35 +00:00
|
|
|
}
|
|
|
|
|
2021-09-04 23:13:55 +00:00
|
|
|
if config.CorsOrigin != "" && config.CorsOrigin != "*" && config.CorsOrigin != "null" {
|
|
|
|
_, err := url.ParseRequestURI(config.CorsOrigin)
|
|
|
|
if err != nil {
|
2023-05-08 09:16:11 +00:00
|
|
|
return errors.New("tusd: CorsOrigin is not a valid URL")
|
2021-09-04 23:13:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-21 22:25:35 +00:00
|
|
|
return nil
|
|
|
|
}
|