disconnect context in a dedicated middleware

This commit is contained in:
Jörn Friedrich Dreyer 2019-10-10 11:30:10 +02:00
parent 898f3fe72a
commit dc1a2b6206
2 changed files with 19 additions and 6 deletions

View File

@ -35,7 +35,9 @@ func NewHandler(config Config) (*Handler, error) {
mux := pat.New() mux := pat.New()
routedHandler.Handler = handler.Middleware(mux) disconnectedHandler := handler.DisconnectMiddleware(mux)
routedHandler.Handler = handler.Middleware(disconnectedHandler)
mux.Post("", http.HandlerFunc(handler.PostFile)) mux.Post("", http.HandlerFunc(handler.PostFile))
mux.Head(":id", http.HandlerFunc(handler.HeadFile)) mux.Head(":id", http.HandlerFunc(handler.HeadFile))

View File

@ -271,10 +271,21 @@ func (handler *UnroutedHandler) Middleware(h http.Handler) http.Handler {
}) })
} }
// DisconnectMiddleware does a deep clone of the request with an empty context so tusd
// can continue to finish the file upload, even if the request aborts
func (handler *UnroutedHandler) DisconnectMiddleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// disconnect the existing context to ignore cancels
r.Clone(context.Background())
// Proceed with routing the request
h.ServeHTTP(w, r)
})
}
// PostFile creates a new file upload using the datastore after validating the // PostFile creates a new file upload using the datastore after validating the
// length and parsing the metadata. // length and parsing the metadata.
func (handler *UnroutedHandler) PostFile(w http.ResponseWriter, r *http.Request) { func (handler *UnroutedHandler) PostFile(w http.ResponseWriter, r *http.Request) {
ctx := context.Background() ctx := r.Context()
// Check for presence of application/offset+octet-stream. If another content // Check for presence of application/offset+octet-stream. If another content
// type is defined, it will be ignored and treated as none was set because // type is defined, it will be ignored and treated as none was set because
@ -414,7 +425,7 @@ func (handler *UnroutedHandler) PostFile(w http.ResponseWriter, r *http.Request)
// HeadFile returns the length and offset for the HEAD request // HeadFile returns the length and offset for the HEAD request
func (handler *UnroutedHandler) HeadFile(w http.ResponseWriter, r *http.Request) { func (handler *UnroutedHandler) HeadFile(w http.ResponseWriter, r *http.Request) {
ctx := context.Background() ctx := r.Context()
id, err := extractIDFromPath(r.URL.Path) id, err := extractIDFromPath(r.URL.Path)
if err != nil { if err != nil {
@ -478,7 +489,7 @@ func (handler *UnroutedHandler) HeadFile(w http.ResponseWriter, r *http.Request)
// PatchFile adds a chunk to an upload. This operation is only allowed // PatchFile adds a chunk to an upload. This operation is only allowed
// if enough space in the upload is left. // if enough space in the upload is left.
func (handler *UnroutedHandler) PatchFile(w http.ResponseWriter, r *http.Request) { func (handler *UnroutedHandler) PatchFile(w http.ResponseWriter, r *http.Request) {
ctx := context.Background() ctx := r.Context()
// Check for presence of application/offset+octet-stream // Check for presence of application/offset+octet-stream
if r.Header.Get("Content-Type") != "application/offset+octet-stream" { if r.Header.Get("Content-Type") != "application/offset+octet-stream" {
@ -693,7 +704,7 @@ func (handler *UnroutedHandler) finishUploadIfComplete(ctx context.Context, uplo
// GetFile handles requests to download a file using a GET request. This is not // GetFile handles requests to download a file using a GET request. This is not
// part of the specification. // part of the specification.
func (handler *UnroutedHandler) GetFile(w http.ResponseWriter, r *http.Request) { func (handler *UnroutedHandler) GetFile(w http.ResponseWriter, r *http.Request) {
ctx := context.Background() ctx := r.Context()
id, err := extractIDFromPath(r.URL.Path) id, err := extractIDFromPath(r.URL.Path)
if err != nil { if err != nil {
@ -814,7 +825,7 @@ func filterContentType(info FileInfo) (contentType string, contentDisposition st
// DelFile terminates an upload permanently. // DelFile terminates an upload permanently.
func (handler *UnroutedHandler) DelFile(w http.ResponseWriter, r *http.Request) { func (handler *UnroutedHandler) DelFile(w http.ResponseWriter, r *http.Request) {
ctx := context.Background() ctx := r.Context()
// Abort the request handling if the required interface is not implemented // Abort the request handling if the required interface is not implemented
if !handler.composer.UsesTerminater { if !handler.composer.UsesTerminater {