Add post-terminate hook
This commit is contained in:
parent
5aa7928111
commit
3ee1c61d80
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "Upload $TUS_ID terminated"
|
||||
cat /dev/stdin | jq .
|
|
@ -138,6 +138,7 @@ func main() {
|
|||
BasePath: basepath,
|
||||
StoreComposer: composer,
|
||||
NotifyCompleteUploads: true,
|
||||
NotifyTerminatedUploads: true,
|
||||
})
|
||||
if err != nil {
|
||||
stderr.Fatalf("Unable to create handler: %s", err)
|
||||
|
@ -152,7 +153,9 @@ func main() {
|
|||
for {
|
||||
select {
|
||||
case info := <-handler.CompleteUploads:
|
||||
invokeHook(info)
|
||||
invokeHook("post-finish", info)
|
||||
case info := <-handler.TerminatedUploads:
|
||||
invokeHook("post-terminate", info)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
@ -176,16 +179,21 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
func invokeHook(info tusd.FileInfo) {
|
||||
func invokeHook(name string, info tusd.FileInfo) {
|
||||
switch name {
|
||||
case "post-finish":
|
||||
stdout.Printf("Upload %s (%d bytes) finished\n", info.ID, info.Size)
|
||||
case "post-terminate":
|
||||
stdout.Printf("Upload %s terminated\n", info.ID)
|
||||
}
|
||||
|
||||
if !hookInstalled {
|
||||
return
|
||||
}
|
||||
|
||||
stdout.Println("Invoking hooks…")
|
||||
stdout.Printf("Invoking %s hook…\n", name)
|
||||
|
||||
cmd := exec.Command(hooksDir + "/post-finish")
|
||||
cmd := exec.Command(hooksDir + "/" + name)
|
||||
env := os.Environ()
|
||||
env = append(env, "TUS_ID="+info.ID)
|
||||
env = append(env, "TUS_SIZE="+strconv.FormatInt(info.Size, 10))
|
||||
|
@ -206,7 +214,7 @@ func invokeHook(info tusd.FileInfo) {
|
|||
go func() {
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
stderr.Printf("Error running postfinish hook for %s: %s", info.ID, err)
|
||||
stderr.Printf("Error running %s hook for %s: %s", name, info.ID, err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@ type Config struct {
|
|||
// Initiate the CompleteUploads channel in the Handler struct in order to
|
||||
// be notified about complete uploads
|
||||
NotifyCompleteUploads bool
|
||||
// NotifyTerminatedUploads indicates whether sending notifications about
|
||||
// terminated uploads using the TerminatedUploads channel should be enabled.
|
||||
NotifyTerminatedUploads bool
|
||||
// Logger the logger to use internally
|
||||
Logger *log.Logger
|
||||
// Respect the X-Forwarded-Host, X-Forwarded-Proto and Forwarded headers
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"testing"
|
||||
|
||||
. "github.com/tus/tusd"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type terminateStore struct {
|
||||
|
@ -12,6 +14,13 @@ type terminateStore struct {
|
|||
zeroStore
|
||||
}
|
||||
|
||||
func (s terminateStore) GetInfo(id string) (FileInfo, error) {
|
||||
return FileInfo{
|
||||
ID: id,
|
||||
Size: 10,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s terminateStore) Terminate(id string) error {
|
||||
if id != "foo" {
|
||||
s.t.Fatal("unexpected id")
|
||||
|
@ -24,8 +33,12 @@ func TestTerminate(t *testing.T) {
|
|||
DataStore: terminateStore{
|
||||
t: t,
|
||||
},
|
||||
NotifyTerminatedUploads: true,
|
||||
})
|
||||
|
||||
c := make(chan FileInfo, 1)
|
||||
handler.TerminatedUploads = c
|
||||
|
||||
(&httpTest{
|
||||
Name: "Successful OPTIONS request",
|
||||
Method: "OPTIONS",
|
||||
|
@ -45,6 +58,12 @@ func TestTerminate(t *testing.T) {
|
|||
},
|
||||
Code: http.StatusNoContent,
|
||||
}).Run(handler, t)
|
||||
|
||||
info := <-c
|
||||
|
||||
a := assert.New(t)
|
||||
a.Equal("foo", info.ID)
|
||||
a.Equal(int64(10), info.Size)
|
||||
}
|
||||
|
||||
func TestTerminateNotImplemented(t *testing.T) {
|
||||
|
|
|
@ -66,6 +66,12 @@ type UnroutedHandler struct {
|
|||
// this unbuffered channel. The NotifyCompleteUploads property in the Config
|
||||
// struct must be set to true in order to work.
|
||||
CompleteUploads chan FileInfo
|
||||
// TerminatedUploads is used to send notifications whenever an upload is
|
||||
// terminated by a user. The FileInfo will contain information about This
|
||||
// upload gathered before the termination. Sending to this channel will only
|
||||
// happen if the NotifyTerminatedUploads field is set to true in the Config
|
||||
// structure.
|
||||
TerminatedUploads chan FileInfo
|
||||
}
|
||||
|
||||
// NewUnroutedHandler creates a new handler without routing using the given
|
||||
|
@ -92,6 +98,7 @@ func NewUnroutedHandler(config Config) (*UnroutedHandler, error) {
|
|||
basePath: config.BasePath,
|
||||
isBasePathAbs: config.isAbs,
|
||||
CompleteUploads: make(chan FileInfo),
|
||||
TerminatedUploads: make(chan FileInfo),
|
||||
logger: config.Logger,
|
||||
extensions: extensions,
|
||||
}
|
||||
|
@ -461,6 +468,15 @@ func (handler *UnroutedHandler) DelFile(w http.ResponseWriter, r *http.Request)
|
|||
defer locker.UnlockUpload(id)
|
||||
}
|
||||
|
||||
var info FileInfo
|
||||
if handler.config.NotifyTerminatedUploads {
|
||||
info, err = handler.composer.Core.GetInfo(id)
|
||||
if err != nil {
|
||||
handler.sendError(w, r, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = handler.composer.Terminater.Terminate(id)
|
||||
if err != nil {
|
||||
handler.sendError(w, r, err)
|
||||
|
@ -468,6 +484,10 @@ func (handler *UnroutedHandler) DelFile(w http.ResponseWriter, r *http.Request)
|
|||
}
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
|
||||
if handler.config.NotifyTerminatedUploads {
|
||||
handler.TerminatedUploads <- info
|
||||
}
|
||||
}
|
||||
|
||||
// Send the error in the response body. The status code will be looked up in
|
||||
|
|
Loading…
Reference in New Issue