diff --git a/cmd/tusd/cli/flags.go b/cmd/tusd/cli/flags.go index efd2f62..84f4e8d 100644 --- a/cmd/tusd/cli/flags.go +++ b/cmd/tusd/cli/flags.go @@ -9,34 +9,35 @@ import ( ) var Flags struct { - HttpHost string - HttpPort string - HttpSock string - MaxSize int64 - UploadDir string - Basepath string - Timeout int64 - S3Bucket string - S3ObjectPrefix string - S3Endpoint string - GCSBucket string - GCSObjectPrefix string - EnabledHooksString string - FileHooksDir string - HttpHooksEndpoint string - HttpHooksRetry int - HttpHooksBackoff int - GrpcHooksEndpoint string - GrpcHooksRetry int - GrpcHooksBackoff int - HooksStopUploadCode int - PluginHookPath string - EnabledHooks []hooks.HookType - ShowVersion bool - ExposeMetrics bool - MetricsPath string - BehindProxy bool - VerboseOutput bool + HttpHost string + HttpPort string + HttpSock string + MaxSize int64 + UploadDir string + Basepath string + Timeout int64 + S3Bucket string + S3ObjectPrefix string + S3Endpoint string + GCSBucket string + GCSObjectPrefix string + EnabledHooksString string + FileHooksDir string + HttpHooksEndpoint string + HttpHooksForwardHeaders string + HttpHooksRetry int + HttpHooksBackoff int + GrpcHooksEndpoint string + GrpcHooksRetry int + GrpcHooksBackoff int + HooksStopUploadCode int + PluginHookPath string + EnabledHooks []hooks.HookType + ShowVersion bool + ExposeMetrics bool + MetricsPath string + BehindProxy bool + VerboseOutput bool } func ParseFlags() { @@ -55,6 +56,7 @@ func ParseFlags() { flag.StringVar(&Flags.EnabledHooksString, "hooks-enabled-events", "", "Comma separated list of enabled hook events (e.g. post-create,post-finish). Leave empty to enable all events") flag.StringVar(&Flags.FileHooksDir, "hooks-dir", "", "Directory to search for available hooks scripts") flag.StringVar(&Flags.HttpHooksEndpoint, "hooks-http", "", "An HTTP endpoint to which hook events will be sent to") + flag.StringVar(&Flags.HttpHooksForwardHeaders, "hooks-http-forward-headers", "", "List of HTTP request headers to be forwarded from the client request to the hook endpoint") flag.IntVar(&Flags.HttpHooksRetry, "hooks-http-retry", 3, "Number of times to retry on a 500 or network timeout") flag.IntVar(&Flags.HttpHooksBackoff, "hooks-http-backoff", 1, "Number of seconds to wait before retrying each retry") flag.StringVar(&Flags.GrpcHooksEndpoint, "hooks-grpc", "", "An gRPC endpoint to which hook events will be sent to") diff --git a/cmd/tusd/cli/hooks.go b/cmd/tusd/cli/hooks.go index a9fde10..5c22541 100644 --- a/cmd/tusd/cli/hooks.go +++ b/cmd/tusd/cli/hooks.go @@ -54,9 +54,10 @@ func SetupPreHooks(config *handler.Config) error { stdout.Printf("Using '%s' as the endpoint for hooks", Flags.HttpHooksEndpoint) hookHandler = &hooks.HttpHook{ - Endpoint: Flags.HttpHooksEndpoint, - MaxRetries: Flags.HttpHooksRetry, - Backoff: Flags.HttpHooksBackoff, + Endpoint: Flags.HttpHooksEndpoint, + MaxRetries: Flags.HttpHooksRetry, + Backoff: Flags.HttpHooksBackoff, + ForwardHeaders: strings.Split(Flags.HttpHooksForwardHeaders, ","), } } else if Flags.GrpcHooksEndpoint != "" { stdout.Printf("Using '%s' as the endpoint for gRPC hooks", Flags.GrpcHooksEndpoint) diff --git a/cmd/tusd/cli/hooks/http.go b/cmd/tusd/cli/hooks/http.go index 104d75a..4cc3b87 100644 --- a/cmd/tusd/cli/hooks/http.go +++ b/cmd/tusd/cli/hooks/http.go @@ -14,9 +14,10 @@ import ( ) type HttpHook struct { - Endpoint string - MaxRetries int - Backoff int + Endpoint string + MaxRetries int + Backoff int + ForwardHeaders []string } func (_ HttpHook) Setup() error { @@ -34,6 +35,14 @@ func (h HttpHook) InvokeHook(typ HookType, info handler.HookEvent, captureOutput return nil, 0, err } + for _, k := range h.ForwardHeaders { + // Lookup the Canonicalised version of the specified header + if vals, ok := info.HTTPRequest.Header[http.CanonicalHeaderKey(k)]; ok { + // but set the case specified by the user + req.Header[k] = vals + } + } + req.Header.Set("Hook-Name", string(typ)) req.Header.Set("Content-Type", "application/json") diff --git a/docs/hooks.md b/docs/hooks.md index a6015ee..7b7e392 100644 --- a/docs/hooks.md +++ b/docs/hooks.md @@ -137,6 +137,8 @@ Note that the URL must include the `http://` prefix! In case of a blocking hook, HTTP Status Code 400 or greater tells tusd to reject the request (in the same way as non-zero exit code for File Hooks). See also [issue #170](https://github.com/tus/tusd/issues/170) regarding further improvements. +Headers from the client's upload request can be copied to the hook request with the `-hooks-http-forward-headers` flag. +This is particularly useful for including authentication headers such as `Authorization` or `Cookie`. ### Usage