added post-create hook

added test for handler.UploadCreated

go fmt .
This commit is contained in:
Markus Kienast 2017-07-13 15:57:07 +02:00
parent ba0f004df7
commit 447aa9c485
6 changed files with 44 additions and 3 deletions

9
.hooks/post-create Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
id="$TUS_ID"
offset="$TUS_OFFSET"
size="$TUS_SIZE"
progress=$((100 * $offset/$size))
echo "Upload created with ID ${id} and size ${size}"
cat /dev/stdin | jq .

View File

@ -22,6 +22,7 @@ const (
HookPostFinish HookType = "post-finish" HookPostFinish HookType = "post-finish"
HookPostTerminate HookType = "post-terminate" HookPostTerminate HookType = "post-terminate"
HookPostReceive HookType = "post-receive" HookPostReceive HookType = "post-receive"
HookPostCreate HookType = "post-create"
HookPreCreate HookType = "pre-create" HookPreCreate HookType = "pre-create"
) )
@ -52,6 +53,8 @@ func SetupPostHooks(handler *tusd.Handler) {
invokeHook(HookPostTerminate, info) invokeHook(HookPostTerminate, info)
case info := <-handler.UploadProgress: case info := <-handler.UploadProgress:
invokeHook(HookPostReceive, info) invokeHook(HookPostReceive, info)
case info := <-handler.UploadCreated:
invokeHook(HookPostCreate, info)
} }
} }
}() }()
@ -66,6 +69,8 @@ func invokeHook(typ HookType, info tusd.FileInfo) {
func invokeHookSync(typ HookType, info tusd.FileInfo, captureOutput bool) ([]byte, error) { func invokeHookSync(typ HookType, info tusd.FileInfo, captureOutput bool) ([]byte, error) {
switch typ { switch typ {
case HookPostCreate:
logEv("UploadCreated", "id", info.ID, "size", strconv.FormatInt(info.Size, 10))
case HookPostFinish: case HookPostFinish:
logEv("UploadFinished", "id", info.ID, "size", strconv.FormatInt(info.Size, 10)) logEv("UploadFinished", "id", info.ID, "size", strconv.FormatInt(info.Size, 10))
case HookPostTerminate: case HookPostTerminate:

View File

@ -18,6 +18,7 @@ func Serve() {
NotifyCompleteUploads: true, NotifyCompleteUploads: true,
NotifyTerminatedUploads: true, NotifyTerminatedUploads: true,
NotifyUploadProgress: true, NotifyUploadProgress: true,
NotifyUploadCreated: true,
}) })
if err != nil { if err != nil {
stderr.Fatalf("Unable to create handler: %s", err) stderr.Fatalf("Unable to create handler: %s", err)

View File

@ -34,6 +34,9 @@ type Config struct {
// NotifyUploadProgress indicates whether sending notifications about // NotifyUploadProgress indicates whether sending notifications about
// the upload progress using the UploadProgress channel should be enabled. // the upload progress using the UploadProgress channel should be enabled.
NotifyUploadProgress bool NotifyUploadProgress bool
// NotifyUploadCreated indicates whether sending notifications about
// the upload having been created using the UploadCreated channel should be enabled.
NotifyUploadCreated bool
// Logger is the logger to use internally, mostly for printing requests. // Logger is the logger to use internally, mostly for printing requests.
Logger *log.Logger Logger *log.Logger
// Respect the X-Forwarded-Host, X-Forwarded-Proto and Forwarded headers // Respect the X-Forwarded-Host, X-Forwarded-Proto and Forwarded headers

View File

@ -7,8 +7,9 @@ import (
"testing" "testing"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
. "github.com/tus/tusd" . "github.com/tus/tusd"
"github.com/stretchr/testify/assert"
) )
func TestPost(t *testing.T) { func TestPost(t *testing.T) {
@ -22,10 +23,14 @@ func TestPost(t *testing.T) {
}).Return("foo", nil) }).Return("foo", nil)
handler, _ := NewHandler(Config{ handler, _ := NewHandler(Config{
DataStore: store, DataStore: store,
BasePath: "https://buy.art/files/", BasePath: "https://buy.art/files/",
NotifyUploadCreated: true,
}) })
c := make(chan FileInfo, 1)
handler.UploadCreated = c
(&httpTest{ (&httpTest{
Method: "POST", Method: "POST",
ReqHeader: map[string]string{ ReqHeader: map[string]string{
@ -39,6 +44,12 @@ func TestPost(t *testing.T) {
"Location": "https://buy.art/files/foo", "Location": "https://buy.art/files/foo",
}, },
}).Run(handler, t) }).Run(handler, t)
info := <-c
a := assert.New(t)
a.Equal("foo", info.ID)
a.Equal(int64(300), info.Size)
}) })
SubTest(t, "CreateExceedingMaxSizeFail", func(t *testing.T, store *MockFullDataStore) { SubTest(t, "CreateExceedingMaxSizeFail", func(t *testing.T, store *MockFullDataStore) {

View File

@ -94,6 +94,12 @@ type UnroutedHandler struct {
// happen if the NotifyUploadProgress field is set to true in the Config // happen if the NotifyUploadProgress field is set to true in the Config
// structure. // structure.
UploadProgress chan FileInfo UploadProgress chan FileInfo
// UploadCreated is used to send notifications about the uploads having been
// created. It triggers post creation and therefore has all the FileInfo incl.
// the ID available already. It facilitates the post-create hook. Sending to
// this channel will only happen if the NotifyUploadCreated field is set to
// true in the Config structure.
UploadCreated chan FileInfo
// Metrics provides numbers of the usage for this handler. // Metrics provides numbers of the usage for this handler.
Metrics Metrics Metrics Metrics
} }
@ -124,6 +130,7 @@ func NewUnroutedHandler(config Config) (*UnroutedHandler, error) {
CompleteUploads: make(chan FileInfo), CompleteUploads: make(chan FileInfo),
TerminatedUploads: make(chan FileInfo), TerminatedUploads: make(chan FileInfo),
UploadProgress: make(chan FileInfo), UploadProgress: make(chan FileInfo),
UploadCreated: make(chan FileInfo),
logger: config.Logger, logger: config.Logger,
extensions: extensions, extensions: extensions,
Metrics: newMetrics(), Metrics: newMetrics(),
@ -284,6 +291,11 @@ func (handler *UnroutedHandler) PostFile(w http.ResponseWriter, r *http.Request)
go handler.Metrics.incUploadsCreated() go handler.Metrics.incUploadsCreated()
handler.log("UploadCreated", "id", id, "size", i64toa(size), "url", url) handler.log("UploadCreated", "id", id, "size", i64toa(size), "url", url)
if handler.config.NotifyUploadCreated {
info.ID = id
handler.UploadCreated <- info
}
if isFinal { if isFinal {
if err := handler.composer.Concater.ConcatUploads(id, partialUploads); err != nil { if err := handler.composer.Concater.ConcatUploads(id, partialUploads); err != nil {
handler.sendError(w, r, err) handler.sendError(w, r, err)