cli: add header forwarding in HTTP hooks (#371)

* cli: add header forwarding in HTTP hooks

* docs: Reword header forwarding flag, add documentation
This commit is contained in:
Hamish Forbes 2020-05-07 13:31:44 +01:00 committed by GitHub
parent c9dc9e6c06
commit a4a733fb39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 34 deletions

View File

@ -9,34 +9,35 @@ import (
) )
var Flags struct { var Flags struct {
HttpHost string HttpHost string
HttpPort string HttpPort string
HttpSock string HttpSock string
MaxSize int64 MaxSize int64
UploadDir string UploadDir string
Basepath string Basepath string
Timeout int64 Timeout int64
S3Bucket string S3Bucket string
S3ObjectPrefix string S3ObjectPrefix string
S3Endpoint string S3Endpoint string
GCSBucket string GCSBucket string
GCSObjectPrefix string GCSObjectPrefix string
EnabledHooksString string EnabledHooksString string
FileHooksDir string FileHooksDir string
HttpHooksEndpoint string HttpHooksEndpoint string
HttpHooksRetry int HttpHooksForwardHeaders string
HttpHooksBackoff int HttpHooksRetry int
GrpcHooksEndpoint string HttpHooksBackoff int
GrpcHooksRetry int GrpcHooksEndpoint string
GrpcHooksBackoff int GrpcHooksRetry int
HooksStopUploadCode int GrpcHooksBackoff int
PluginHookPath string HooksStopUploadCode int
EnabledHooks []hooks.HookType PluginHookPath string
ShowVersion bool EnabledHooks []hooks.HookType
ExposeMetrics bool ShowVersion bool
MetricsPath string ExposeMetrics bool
BehindProxy bool MetricsPath string
VerboseOutput bool BehindProxy bool
VerboseOutput bool
} }
func ParseFlags() { 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.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.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.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.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.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") flag.StringVar(&Flags.GrpcHooksEndpoint, "hooks-grpc", "", "An gRPC endpoint to which hook events will be sent to")

View File

@ -54,9 +54,10 @@ func SetupPreHooks(config *handler.Config) error {
stdout.Printf("Using '%s' as the endpoint for hooks", Flags.HttpHooksEndpoint) stdout.Printf("Using '%s' as the endpoint for hooks", Flags.HttpHooksEndpoint)
hookHandler = &hooks.HttpHook{ hookHandler = &hooks.HttpHook{
Endpoint: Flags.HttpHooksEndpoint, Endpoint: Flags.HttpHooksEndpoint,
MaxRetries: Flags.HttpHooksRetry, MaxRetries: Flags.HttpHooksRetry,
Backoff: Flags.HttpHooksBackoff, Backoff: Flags.HttpHooksBackoff,
ForwardHeaders: strings.Split(Flags.HttpHooksForwardHeaders, ","),
} }
} else if Flags.GrpcHooksEndpoint != "" { } else if Flags.GrpcHooksEndpoint != "" {
stdout.Printf("Using '%s' as the endpoint for gRPC hooks", Flags.GrpcHooksEndpoint) stdout.Printf("Using '%s' as the endpoint for gRPC hooks", Flags.GrpcHooksEndpoint)

View File

@ -14,9 +14,10 @@ import (
) )
type HttpHook struct { type HttpHook struct {
Endpoint string Endpoint string
MaxRetries int MaxRetries int
Backoff int Backoff int
ForwardHeaders []string
} }
func (_ HttpHook) Setup() error { func (_ HttpHook) Setup() error {
@ -34,6 +35,14 @@ func (h HttpHook) InvokeHook(typ HookType, info handler.HookEvent, captureOutput
return nil, 0, err 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("Hook-Name", string(typ))
req.Header.Set("Content-Type", "application/json") req.Header.Set("Content-Type", "application/json")

View File

@ -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. 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 ### Usage