From a51f5994bba6c22369023de55acf15071ee3c69b Mon Sep 17 00:00:00 2001 From: Marius Date: Wed, 19 Jul 2017 17:45:16 +0200 Subject: [PATCH] Squashed commit of the following: commit d6ba86b7c300122af52e5be71b5fade4bb88d77c Author: Marius Date: Wed Jul 19 17:44:56 2017 +0200 Add documentation for post-create commit 1d1605f98036e6cfd7e2695cf2e4f8510a220326 Author: Marius Date: Wed Jul 19 13:21:01 2017 +0200 Remove duplicated log for created uploads commit 1f5c6d22bb62e1251297db9b10f78f6db363759d Author: Marius Date: Wed Jul 19 13:08:11 2017 +0200 Rename UploadsCreated to CreatedUploads to match other names commit 5c67ea7548548986c4bce79b7eea311a02a4c541 Author: Marius Date: Wed Jul 19 13:07:14 2017 +0200 Remove unused variable from hook script commit e21d7f5824ce533d80d74e75835ddc33de2184fb Merge: 028ba57 447aa9c Author: Marius Date: Wed Jul 19 12:47:52 2017 +0200 Merge branch 'f-post-create-hook' of https://github.com/flaneurtv/tusd into flaneurtv-f-post-create-hook commit 447aa9c48546d4f160b8f01235b28fdd39796ed8 Author: Markus Kienast Date: Thu Jul 13 15:57:07 2017 +0200 added post-create hook added test for handler.UploadCreated go fmt . --- .hooks/post-create | 8 ++++++++ cmd/tusd/cli/hooks.go | 3 +++ cmd/tusd/cli/serve.go | 1 + config.go | 3 +++ docs/hooks.md | 4 ++++ post_test.go | 15 +++++++++++++-- unrouted_handler.go | 12 ++++++++++++ 7 files changed, 44 insertions(+), 2 deletions(-) create mode 100755 .hooks/post-create diff --git a/.hooks/post-create b/.hooks/post-create new file mode 100755 index 0000000..f25d9d5 --- /dev/null +++ b/.hooks/post-create @@ -0,0 +1,8 @@ +#!/bin/bash + +id="$TUS_ID" +offset="$TUS_OFFSET" +size="$TUS_SIZE" + +echo "Upload created with ID ${id} and size ${size}" +cat /dev/stdin | jq . diff --git a/cmd/tusd/cli/hooks.go b/cmd/tusd/cli/hooks.go index 602636f..3c64afe 100644 --- a/cmd/tusd/cli/hooks.go +++ b/cmd/tusd/cli/hooks.go @@ -22,6 +22,7 @@ const ( HookPostFinish HookType = "post-finish" HookPostTerminate HookType = "post-terminate" HookPostReceive HookType = "post-receive" + HookPostCreate HookType = "post-create" HookPreCreate HookType = "pre-create" ) @@ -52,6 +53,8 @@ func SetupPostHooks(handler *tusd.Handler) { invokeHook(HookPostTerminate, info) case info := <-handler.UploadProgress: invokeHook(HookPostReceive, info) + case info := <-handler.CreatedUploads: + invokeHook(HookPostCreate, info) } } }() diff --git a/cmd/tusd/cli/serve.go b/cmd/tusd/cli/serve.go index 594d66e..e01b9d7 100644 --- a/cmd/tusd/cli/serve.go +++ b/cmd/tusd/cli/serve.go @@ -18,6 +18,7 @@ func Serve() { NotifyCompleteUploads: true, NotifyTerminatedUploads: true, NotifyUploadProgress: true, + NotifyCreatedUploads: true, }) if err != nil { stderr.Fatalf("Unable to create handler: %s", err) diff --git a/config.go b/config.go index 94b4f7e..9c8d454 100644 --- a/config.go +++ b/config.go @@ -34,6 +34,9 @@ type Config struct { // NotifyUploadProgress indicates whether sending notifications about // the upload progress using the UploadProgress channel should be enabled. NotifyUploadProgress bool + // NotifyCreatedUploads indicates whether sending notifications about + // the upload having been created using the CreatedUploads channel should be enabled. + NotifyCreatedUploads bool // Logger is the logger to use internally, mostly for printing requests. Logger *log.Logger // Respect the X-Forwarded-Host, X-Forwarded-Proto and Forwarded headers diff --git a/docs/hooks.md b/docs/hooks.md index 67d60f4..cfa3e47 100644 --- a/docs/hooks.md +++ b/docs/hooks.md @@ -19,6 +19,10 @@ On the other hand, there are a few *blocking* hooks, such as caused by the `pre- This event will be triggered before an upload is created, allowing you to run certain routines. For example, validating that specific metadata values are set, or verifying that a corresponding entity belonging to the upload (e.g. a user) exists. Because this event will result in a blocking hook, you can determine whether the upload should be created or rejected using the exit code. An exit code of `0` will allow the upload to be created and continued as usual. A non-zero exit code will reject an upload creation request, making it a good place for authentication and authorization. Please be aware, that during this stage the upload ID will be an empty string as the entity has not been created and therefore this piece of information is not yet available. +### post-create + +This event will be triggered after an upload is created, allowing you to run certain routines. For example, notifying other parts of your system that a new upload has to be handled. At this point the upload may have received some data already since the invocation of these hooks may be delayed by a short duration. + ### post-finish This event will be triggered after an upload is fully finished, meaning that all chunks have been transfered and saved in the storage. After this point, no further modifications, except possible deletion, can be made to the upload entity and it may be desirable to use the file for further processing or notify other applications of the completions of this upload. diff --git a/post_test.go b/post_test.go index 605ad7c..b7ffcc7 100644 --- a/post_test.go +++ b/post_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" . "github.com/tus/tusd" ) @@ -22,10 +23,14 @@ func TestPost(t *testing.T) { }).Return("foo", nil) handler, _ := NewHandler(Config{ - DataStore: store, - BasePath: "https://buy.art/files/", + DataStore: store, + BasePath: "https://buy.art/files/", + NotifyCreatedUploads: true, }) + c := make(chan FileInfo, 1) + handler.CreatedUploads = c + (&httpTest{ Method: "POST", ReqHeader: map[string]string{ @@ -39,6 +44,12 @@ func TestPost(t *testing.T) { "Location": "https://buy.art/files/foo", }, }).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) { diff --git a/unrouted_handler.go b/unrouted_handler.go index 0cd6c6a..2285e58 100644 --- a/unrouted_handler.go +++ b/unrouted_handler.go @@ -94,6 +94,12 @@ type UnroutedHandler struct { // happen if the NotifyUploadProgress field is set to true in the Config // structure. UploadProgress chan FileInfo + // CreatedUploads 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 NotifyCreatedUploads field is set to + // true in the Config structure. + CreatedUploads chan FileInfo // Metrics provides numbers of the usage for this handler. Metrics Metrics } @@ -124,6 +130,7 @@ func NewUnroutedHandler(config Config) (*UnroutedHandler, error) { CompleteUploads: make(chan FileInfo), TerminatedUploads: make(chan FileInfo), UploadProgress: make(chan FileInfo), + CreatedUploads: make(chan FileInfo), logger: config.Logger, extensions: extensions, Metrics: newMetrics(), @@ -284,6 +291,11 @@ func (handler *UnroutedHandler) PostFile(w http.ResponseWriter, r *http.Request) go handler.Metrics.incUploadsCreated() handler.log("UploadCreated", "id", id, "size", i64toa(size), "url", url) + if handler.config.NotifyCreatedUploads { + info.ID = id + handler.CreatedUploads <- info + } + if isFinal { if err := handler.composer.Concater.ConcatUploads(id, partialUploads); err != nil { handler.sendError(w, r, err)