feat(): transmit HTTP headers as env variables to the script

This commit is contained in:
Nicolas Carlier 2018-01-05 15:47:34 +00:00
parent c2a17414f9
commit 2e803598d2
6 changed files with 80 additions and 39 deletions

View File

@ -87,11 +87,17 @@ data: done
### Webhook parameters
You can add query parameters to the webhook URL.
Those parameters will be available as environment variables into the shell
script.
You can also send a payload (text/plain or application/json) as request body.
This payload will be transmit to the shell script as first parameter.
You have several way to provide parameters to your webhook script:
- URL query parameters and HTTP headers are converted into environment
variables.
Variable names follows "snakecase" naming convention.
Therefore the name can be altered.
*ex: `CONTENT-TYPE` will become `content_type`.*
- Body content (text/plain or application/json) is transmit to the script as
parameter.
*Example:*
@ -100,7 +106,8 @@ The script:
```bash
#!/bin/bash
echo "Environment parameters: foo=$foo"
echo "Query parameter: foo=$foo"
echo "Header parameter: user-agent=$user_agent"
echo "Script parameters: $1"
```
@ -110,9 +117,11 @@ data: Hook work request "echo" queued...
data: Running echo script...
data: Environment parameters: foo=bar
data: Query parameter: foo=bar
data: Script parameters: {"foo": "bar"}
data: Header parameter: user-agent=curl/7.52.1
data: Script parameter: {"foo": "bar"}
data: done
```

View File

@ -43,6 +43,7 @@ func WebhookHandler(w http.ResponseWriter, r *http.Request) {
params := tools.QueryParamsToShellVars(r.URL.Query())
log.Printf("Calling hook script \"%s\" with params %s...\n", script, params)
params = append(params, tools.HTTPHeadersToShellVars(r.Header)...)
// Create work
work := new(worker.WorkRequest)

59
pkg/tools/http.go Normal file
View File

@ -0,0 +1,59 @@
package tools
import (
"bytes"
"net/http"
"net/url"
"strings"
"unicode"
)
// ToSnakeCase convert string to snakecase.
func ToSnakeCase(in string) string {
runes := []rune(in)
length := len(runes)
var out []rune
for i := 0; i < length; i++ {
if i > 0 && unicode.IsUpper(runes[i]) && ((i+1 < length && unicode.IsLower(runes[i+1])) || unicode.IsLower(runes[i-1])) {
out = append(out, '_')
}
out = append(out, unicode.ToLower(runes[i]))
}
return strings.Replace(string(out), "-", "", -1)
}
// QueryParamsToShellVars convert URL query parameters to shell vars.
func QueryParamsToShellVars(q url.Values) []string {
var params []string
for k, v := range q {
var buf bytes.Buffer
value, err := url.QueryUnescape(strings.Join(v[:], ","))
if err != nil {
continue
}
buf.WriteString(ToSnakeCase(k))
buf.WriteString("=")
buf.WriteString(value)
params = append(params, buf.String())
}
return params
}
// HTTPHeadersToShellVars convert HTTP headers to shell vars.
func HTTPHeadersToShellVars(h http.Header) []string {
var params []string
for k, v := range h {
var buf bytes.Buffer
value, err := url.QueryUnescape(strings.Join(v[:], ","))
if err != nil {
continue
}
buf.WriteString(ToSnakeCase(k))
buf.WriteString("=")
buf.WriteString(value)
params = append(params, buf.String())
}
return params
}

View File

@ -1,31 +0,0 @@
package tools
import (
"bytes"
"net/url"
"regexp"
"strings"
)
var matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)")
var matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])")
// ToSnakeCase convert string to snakecase.
func ToSnakeCase(str string) string {
snake := matchFirstCap.ReplaceAllString(str, "${1}_${2}")
snake = matchAllCap.ReplaceAllString(snake, "${1}_${2}")
return strings.ToLower(snake)
}
// QueryParamsToShellVars convert URL query parameters to shell vars.
func QueryParamsToShellVars(q url.Values) []string {
var params []string
for k, v := range q {
var buf bytes.Buffer
buf.WriteString(ToSnakeCase(k))
buf.WriteString("=")
buf.WriteString(url.QueryEscape(strings.Join(v[:], ",")))
params = append(params, buf.String())
}
return params
}

View File

@ -5,6 +5,8 @@ echo "Running test script..."
echo "Environment parameters:"
echo "firstname: $firstname"
echo "lastname: $lastname"
echo "user-agent: $user_agent"
echo "x-api-key: $x_api_key"
echo "Script parameters: $1"

View File

@ -10,5 +10,6 @@ curl -H "Content-Type: application/json" \
echo "Test hook"
curl -H "Content-Type: application/json" \
-H "X-API-Key: test" \
--data @test.json \
$URL/test?firstname=obi-wan\&lastname=kenobi