package main import ( "fmt" "log" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-plugin" "github.com/tus/tusd/cmd/tusd/cli/hooks" ) // Here is the implementation of our hook handler type MyHookHandler struct { logger hclog.Logger } // Setup is called once the plugin has been loaded by tusd. func (g *MyHookHandler) Setup() error { // Use the log package or the g.logger field to write debug messages. // Do not write to stdout directly, as this is used for communication between // tusd and the plugin. log.Println("MyHookHandler.Setup is invoked") return nil } // InvokeHook is called for every hook that tusd fires. func (g *MyHookHandler) InvokeHook(req hooks.HookRequest) (res hooks.HookResponse, err error) { log.Println("MyHookHandler.InvokeHook is invoked") // // Prepare hook response structure // res.HTTPResponse.Headers = make(map[string]string) // // Example: Use the pre-create hook to check if a filename has been supplied // // using metadata. If not, the upload is rejected with a custom HTTP response. // if req.Type == hooks.HookPreCreate { // if _, ok := req.Event.Upload.MetaData["filename"]; !ok { // res.RejectUpload = true // res.HTTPResponse.StatusCode = 400 // res.HTTPResponse.Body = "no filename provided" // res.HTTPResponse.Headers["X-Some-Header"] = "yes" // } // } // // Example: Use the post-finish hook to print information about a completed upload, // // including its storage location. // if req.Type == hooks.HookPreFinish { // id := req.Event.Upload.ID // size := req.Event.Upload.Size // storage := req.Event.Upload.Storage // log.Printf("Upload %s (%d bytes) is finished. Find the file at:\n", id, size) // log.Println(storage) // } // Return the hook response to tusd. return res, nil } // handshakeConfigs are used to just do a basic handshake between // a plugin and tusd. If the handshake fails, a user friendly error is shown. // This prevents users from executing bad plugins or executing a plugin // directory. It is a UX feature, not a security feature. var handshakeConfig = plugin.HandshakeConfig{ ProtocolVersion: 1, MagicCookieKey: "TUSD_PLUGIN", MagicCookieValue: "yes", } func main() { // 1. Initialize our handler. myHandler := &MyHookHandler{} // 2. Construct the plugin map. The key must be "hookHandler". var pluginMap = map[string]plugin.Plugin{ "hookHandler": &hooks.HookHandlerPlugin{Impl: myHandler}, } // 3. Expose the plugin to tusd. plugin.Serve(&plugin.ServeConfig{ HandshakeConfig: handshakeConfig, Plugins: pluginMap, }) fmt.Println("DOONE") }