mirror of
https://github.com/adnanh/webhook.git
synced 2026-07-27 17:49:50 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aeacb6dac7 | |||
| 1039151a16 | |||
| db928228c8 | |||
| 6896a34aab | |||
| 5f853d8aba | |||
| 12c48f87cb | |||
| acf38c3210 | |||
| d3f368cb8f | |||
| 943bc258f7 |
@@ -48,6 +48,8 @@ var extractParameterTests = []struct {
|
|||||||
{"a.500.b", map[string]interface{}{"a": map[string]interface{}{"b": "z"}}, "", false}, // non-existent slice
|
{"a.500.b", map[string]interface{}{"a": map[string]interface{}{"b": "z"}}, "", false}, // non-existent slice
|
||||||
{"a.501.b", map[string]interface{}{"a": []interface{}{map[string]interface{}{"b": "y"}, map[string]interface{}{"b": "z"}}}, "", false}, // non-existent slice index
|
{"a.501.b", map[string]interface{}{"a": []interface{}{map[string]interface{}{"b": "y"}, map[string]interface{}{"b": "z"}}}, "", false}, // non-existent slice index
|
||||||
{"a.502.b", map[string]interface{}{"a": []interface{}{}}, "", false}, // non-existent slice index
|
{"a.502.b", map[string]interface{}{"a": []interface{}{}}, "", false}, // non-existent slice index
|
||||||
|
{"a.b.503", map[string]interface{}{"a": map[string]interface{}{"b": []interface{}{"x", "y", "z"}}}, "", false}, // trailing, non-existent slice index
|
||||||
|
{"a.b", interface{}("a"), "", false}, // non-map, non-slice input
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractParameter(t *testing.T) {
|
func TestExtractParameter(t *testing.T) {
|
||||||
@@ -85,6 +87,30 @@ func TestArgumentGet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hookParseJSONParametersTests = []struct {
|
||||||
|
params []Argument
|
||||||
|
headers, query, payload *map[string]interface{}
|
||||||
|
rheaders, rquery, rpayload *map[string]interface{}
|
||||||
|
}{
|
||||||
|
{[]Argument{Argument{"header", "a"}}, &map[string]interface{}{"a": `{"b": "y"}`}, nil, nil, &map[string]interface{}{"a": map[string]interface{}{"b": "y"}}, nil, nil},
|
||||||
|
{[]Argument{Argument{"url", "a"}}, nil, &map[string]interface{}{"a": `{"b": "y"}`}, nil, nil, &map[string]interface{}{"a": map[string]interface{}{"b": "y"}}, nil},
|
||||||
|
{[]Argument{Argument{"payload", "a"}}, nil, nil, &map[string]interface{}{"a": `{"b": "y"}`}, nil, nil, &map[string]interface{}{"a": map[string]interface{}{"b": "y"}}},
|
||||||
|
{[]Argument{Argument{"header", "z"}}, &map[string]interface{}{"z": `{}`}, nil, nil, &map[string]interface{}{"z": map[string]interface{}{}}, nil, nil},
|
||||||
|
// failures
|
||||||
|
{[]Argument{Argument{"header", "z"}}, &map[string]interface{}{"z": ``}, nil, nil, &map[string]interface{}{"z": ``}, nil, nil}, // empty string
|
||||||
|
{[]Argument{Argument{"header", "y"}}, &map[string]interface{}{"X": `{}`}, nil, nil, &map[string]interface{}{"X": `{}`}, nil, nil}, // missing parameter
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHookParseJSONParameters(t *testing.T) {
|
||||||
|
for _, tt := range hookParseJSONParametersTests {
|
||||||
|
h := &Hook{JSONStringParameters: tt.params}
|
||||||
|
h.ParseJSONParameters(tt.headers, tt.query, tt.payload)
|
||||||
|
if !reflect.DeepEqual(tt.headers, tt.rheaders) {
|
||||||
|
t.Errorf("failed to parse %v:\nexpected %#v,\ngot %#v", tt.params, *tt.rheaders, *tt.headers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var hookExtractCommandArgumentsTests = []struct {
|
var hookExtractCommandArgumentsTests = []struct {
|
||||||
exec string
|
exec string
|
||||||
args []Argument
|
args []Argument
|
||||||
|
|||||||
+40
-10
@@ -10,7 +10,9 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"os/signal"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/adnanh/webhook/hook"
|
"github.com/adnanh/webhook/hook"
|
||||||
|
|
||||||
@@ -21,7 +23,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
version = "2.3.0"
|
version = "2.3.2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -36,6 +38,7 @@ var (
|
|||||||
key = flag.String("key", "key.pem", "path to the HTTPS certificate private key pem file")
|
key = flag.String("key", "key.pem", "path to the HTTPS certificate private key pem file")
|
||||||
|
|
||||||
watcher *fsnotify.Watcher
|
watcher *fsnotify.Watcher
|
||||||
|
signals chan os.Signal
|
||||||
|
|
||||||
hooks hook.Hooks
|
hooks hook.Hooks
|
||||||
)
|
)
|
||||||
@@ -54,6 +57,14 @@ func init() {
|
|||||||
|
|
||||||
log.Println("version " + version + " starting")
|
log.Println("version " + version + " starting")
|
||||||
|
|
||||||
|
// set os signal watcher
|
||||||
|
log.Printf("setting up os signal watcher\n")
|
||||||
|
|
||||||
|
signals = make(chan os.Signal, 1)
|
||||||
|
signal.Notify(signals, syscall.Signal(0xa))
|
||||||
|
|
||||||
|
go watchForSignals()
|
||||||
|
|
||||||
// load and parse hooks
|
// load and parse hooks
|
||||||
log.Printf("attempting to load hooks from %s\n", *hooksFilePath)
|
log.Printf("attempting to load hooks from %s\n", *hooksFilePath)
|
||||||
|
|
||||||
@@ -152,7 +163,7 @@ func hookHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
contentType := r.Header.Get("Content-Type")
|
contentType := r.Header.Get("Content-Type")
|
||||||
|
|
||||||
if contentType == "application/json" {
|
if strings.HasPrefix(contentType, "application/json") {
|
||||||
decoder := json.NewDecoder(strings.NewReader(string(body)))
|
decoder := json.NewDecoder(strings.NewReader(string(body)))
|
||||||
decoder.UseNumber()
|
decoder.UseNumber()
|
||||||
|
|
||||||
@@ -161,7 +172,7 @@ func hookHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error parsing JSON payload %+v\n", err)
|
log.Printf("error parsing JSON payload %+v\n", err)
|
||||||
}
|
}
|
||||||
} else if contentType == "application/x-www-form-urlencoded" {
|
} else if strings.HasPrefix(contentType, "application/x-www-form-urlencoded") {
|
||||||
fd, err := url.ParseQuery(string(body))
|
fd, err := url.ParseQuery(string(body))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error parsing form payload %+v\n", err)
|
log.Printf("error parsing form payload %+v\n", err)
|
||||||
@@ -206,13 +217,7 @@ func handleHook(hook *hook.Hook, headers, query, payload *map[string]interface{}
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func watchForFileChange() {
|
func reloadHooks() {
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case event := <-(*watcher).Events:
|
|
||||||
if event.Op&fsnotify.Write == fsnotify.Write {
|
|
||||||
log.Println("hooks file modified")
|
|
||||||
|
|
||||||
newHooks := hook.Hooks{}
|
newHooks := hook.Hooks{}
|
||||||
|
|
||||||
// parse and swap
|
// parse and swap
|
||||||
@@ -232,12 +237,37 @@ func watchForFileChange() {
|
|||||||
hooks = newHooks
|
hooks = newHooks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func watchForFileChange() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case event := <-(*watcher).Events:
|
||||||
|
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||||
|
log.Println("hooks file modified")
|
||||||
|
|
||||||
|
reloadHooks()
|
||||||
|
}
|
||||||
case err := <-(*watcher).Errors:
|
case err := <-(*watcher).Errors:
|
||||||
log.Println("watcher error:", err)
|
log.Println("watcher error:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func watchForSignals() {
|
||||||
|
log.Println("os signal watcher ready")
|
||||||
|
|
||||||
|
for {
|
||||||
|
sig := <-signals
|
||||||
|
if sig == syscall.Signal(0xa) {
|
||||||
|
log.Println("caught USR1 signal")
|
||||||
|
|
||||||
|
reloadHooks()
|
||||||
|
} else {
|
||||||
|
log.Printf("caught unhandled signal %+v\n", sig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// valuesToMap converts map[string][]string to a map[string]string object
|
// valuesToMap converts map[string][]string to a map[string]string object
|
||||||
func valuesToMap(values map[string][]string) map[string]interface{} {
|
func valuesToMap(values map[string][]string) map[string]interface{} {
|
||||||
ret := make(map[string]interface{})
|
ret := make(map[string]interface{})
|
||||||
|
|||||||
Reference in New Issue
Block a user