initial changes

This commit is contained in:
benito 2021-05-27 15:57:32 +08:00 committed by benitogf
parent 84faa14987
commit d00435048d
7 changed files with 39 additions and 2 deletions

View File

@ -43,6 +43,10 @@ func preFinishCallback(info handler.HookEvent) error {
return hookCallback(hooks.HookPreFinish, info)
}
func preGetCallback(info handler.HookEvent) error {
return hookCallback(hooks.HookPreGet, info)
}
func SetupHookMetrics() {
MetricsHookErrorsTotal.WithLabelValues(string(hooks.HookPostFinish)).Add(0)
MetricsHookErrorsTotal.WithLabelValues(string(hooks.HookPostTerminate)).Add(0)
@ -50,6 +54,7 @@ func SetupHookMetrics() {
MetricsHookErrorsTotal.WithLabelValues(string(hooks.HookPostCreate)).Add(0)
MetricsHookErrorsTotal.WithLabelValues(string(hooks.HookPreCreate)).Add(0)
MetricsHookErrorsTotal.WithLabelValues(string(hooks.HookPreFinish)).Add(0)
MetricsHookErrorsTotal.WithLabelValues(string(hooks.HookPreGet)).Add(0)
}
func SetupPreHooks(config *handler.Config) error {
@ -99,6 +104,7 @@ func SetupPreHooks(config *handler.Config) error {
config.PreUploadCreateCallback = preCreateCallback
config.PreFinishResponseCallback = preFinishCallback
config.PreGetResponseCallback = preGetCallback
return nil
}
@ -115,6 +121,8 @@ func SetupPostHooks(handler *handler.Handler) {
invokeHookAsync(hooks.HookPostReceive, info)
case info := <-handler.CreatedUploads:
invokeHookAsync(hooks.HookPostCreate, info)
case info := <-handler.GetUploads:
invokeHookAsync(hooks.HookPreGet, info)
}
}
}()

View File

@ -18,9 +18,10 @@ const (
HookPostCreate HookType = "post-create"
HookPreCreate HookType = "pre-create"
HookPreFinish HookType = "pre-finish"
HookPreGet HookType = "pre-get"
)
var AvailableHooks []HookType = []HookType{HookPreCreate, HookPostCreate, HookPostReceive, HookPostTerminate, HookPostFinish, HookPreFinish}
var AvailableHooks []HookType = []HookType{HookPreCreate, HookPostCreate, HookPostReceive, HookPostTerminate, HookPostFinish, HookPreFinish, HookPreGet}
type hookDataStore struct {
handler.DataStore

View File

@ -14,6 +14,7 @@ type PluginHookHandler interface {
PostFinish(info handler.HookEvent) error
PostTerminate(info handler.HookEvent) error
PreFinish(info handler.HookEvent) error
PreGet(info handler.HookEvent) error
}
type PluginHook struct {
@ -57,6 +58,8 @@ func (h PluginHook) InvokeHook(typ HookType, info handler.HookEvent, captureOutp
err = h.handler.PreCreate(info)
case HookPreFinish:
err = h.handler.PreFinish(info)
case HookPreGet:
err = h.handler.PreGet(info)
default:
err = fmt.Errorf("hooks: unknown hook named %s", typ)
}

View File

@ -13,7 +13,7 @@ If not otherwise noted, all hooks are invoked in a *non-blocking* way, meaning t
## Blocking Hooks
On the other hand, there are a few *blocking* hooks, such as caused by the `pre-create` and `pre-finish` events. Because their exit code will dictate whether tusd will accept the current incoming request, tusd will wait until the hook process has exited. Therefore, in order to keep the response times low, one should avoid to make time-consuming operations inside the processes for blocking hooks.
On the other hand, there are a few *blocking* hooks, such as caused by the `pre-create`, `pre-get` and `pre-finish` events. Because their exit code will dictate whether tusd will accept the current incoming request, tusd will wait until the hook process has exited. Therefore, in order to keep the response times low, one should avoid to make time-consuming operations inside the processes for blocking hooks.
### Blocking File Hooks
@ -39,6 +39,12 @@ This event will be triggered after an upload is fully finished but before a resp
This is a blocking hook, as such it can be used to validate or post-process an uploaded file.
A non-zero exit code or HTTP response greater than `400` will return a HTTP 500 error to the client.
### pre-get
This event will be triggered before an upload read returned to the client.
This is a blocking hook, as such it can be used to validate access limits.
A non-zero exit code or HTTP response greater than `400` will return a HTTP 500 error to the client.
### 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.

7
examples/hooks/pre-get Normal file
View File

@ -0,0 +1,7 @@
#!/bin/sh
filename=$(cat /dev/stdin | jq .MetaData.filename)
if [[ $filename != "public" ]; then
echo "Error: access unauthorized"
exit 1
fi

View File

@ -40,6 +40,11 @@ type Config struct {
// potentially set by proxies when generating an absolute URL in the
// response to POST requests.
RespectForwardedHeaders bool
// PreGetCallback will be invoked before an upload is read, if the
// property is supplied. If the callback returns nil, the upload will be sent.
// Otherwise the HTTP request will be aborted. This can be used to implement
// accesss limits.
PreGetCallback func(hook HookEvent) error
// PreUploadCreateCallback will be invoked before a new upload is created, if the
// property is supplied. If the callback returns nil, the upload will be created.
// Otherwise the HTTP request will be aborted. This can be used to implement

View File

@ -741,6 +741,13 @@ func (handler *UnroutedHandler) GetFile(w http.ResponseWriter, r *http.Request)
return
}
if handler.config.PreGetCallback != nil {
if err := handler.config.PreGetCallback(newHookEvent(info, r)); err != nil {
handler.sendError(w, r, err)
return
}
}
// Set headers before sending responses
w.Header().Set("Content-Length", strconv.FormatInt(info.Offset, 10))