Rename context-provider-command
to pre-hook-command
and refactor the code to be more readable.
This commit is contained in:
parent
3ec7da2b15
commit
54cfc6bcbd
16
hook/hook.go
16
hook/hook.go
@ -14,7 +14,9 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
|
"net/http"
|
||||||
"net/textproto"
|
"net/textproto"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -423,11 +425,23 @@ func (h *HooksFiles) Set(value string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PreHookContext is a structure consisted of request context data that will be passed to the pre-hook command
|
||||||
|
type PreHookContext struct {
|
||||||
|
HookID string `json:"hookID"`
|
||||||
|
Method string `json:"method"`
|
||||||
|
Base64EncodedBody string `json:"base64EncodedBody"`
|
||||||
|
RemoteAddress string `json:"remoteAddress"`
|
||||||
|
URI string `json:"URI"`
|
||||||
|
Host string `json:"host"`
|
||||||
|
Headers http.Header `json:"headers"`
|
||||||
|
Query url.Values `json:"query"`
|
||||||
|
}
|
||||||
|
|
||||||
// Hook type is a structure containing details for a single hook
|
// Hook type is a structure containing details for a single hook
|
||||||
type Hook struct {
|
type Hook struct {
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
ExecuteCommand string `json:"execute-command,omitempty"`
|
ExecuteCommand string `json:"execute-command,omitempty"`
|
||||||
ContextProviderCommand string `json:"context-provider-command,omitempty"`
|
PreHookCommand string `json:"pre-hook-command,omitempty"`
|
||||||
CommandWorkingDirectory string `json:"command-working-directory,omitempty"`
|
CommandWorkingDirectory string `json:"command-working-directory,omitempty"`
|
||||||
ResponseMessage string `json:"response-message,omitempty"`
|
ResponseMessage string `json:"response-message,omitempty"`
|
||||||
ResponseHeaders ResponseHeaders `json:"response-headers,omitempty"`
|
ResponseHeaders ResponseHeaders `json:"response-headers,omitempty"`
|
||||||
|
91
webhook.go
91
webhook.go
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -16,7 +17,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/adnanh/webhook/hook"
|
"github.com/adnanh/webhook/hook"
|
||||||
|
|
||||||
"github.com/codegangsta/negroni"
|
"github.com/codegangsta/negroni"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/satori/go.uuid"
|
"github.com/satori/go.uuid"
|
||||||
@ -222,7 +222,7 @@ func hookHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
body, err := ioutil.ReadAll(r.Body)
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[%s] error reading the request body. %+v\n", rid, err)
|
log.Printf("[%s] error reading the request body: %+v\n", rid, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse headers
|
// parse headers
|
||||||
@ -234,77 +234,60 @@ func hookHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
// parse context
|
// parse context
|
||||||
var context map[string]interface{}
|
var context map[string]interface{}
|
||||||
|
|
||||||
if matchedHook.ContextProviderCommand != "" {
|
if matchedHook.PreHookCommand != "" {
|
||||||
// check the command exists
|
// check the command exists
|
||||||
cmdPath, err := exec.LookPath(matchedHook.ContextProviderCommand)
|
preHookCommandPath, err := exec.LookPath(matchedHook.PreHookCommand)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// give a last chance, maybe it's a relative path
|
// give a last chance, maybe it's a relative path
|
||||||
relativeToCwd := filepath.Join(matchedHook.CommandWorkingDirectory, matchedHook.ContextProviderCommand)
|
preHookCommandPathRelativeToCurrentWorkingDirectory := filepath.Join(matchedHook.CommandWorkingDirectory, matchedHook.PreHookCommand)
|
||||||
// check the command exists
|
// check the command exists
|
||||||
cmdPath, err = exec.LookPath(relativeToCwd)
|
preHookCommandPath, err = exec.LookPath(preHookCommandPathRelativeToCurrentWorkingDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[%s] unable to locate context provider command: '%s', %+v\n", rid, matchedHook.ContextProviderCommand, err)
|
log.Printf("[%s] unable to locate pre-hook command: '%s', %+v\n", rid, matchedHook.PreHookCommand, err)
|
||||||
// check if parameters specified in context-provider-command by mistake
|
// check if parameters specified in pre-hook command by mistake
|
||||||
if strings.IndexByte(matchedHook.ContextProviderCommand, ' ') != -1 {
|
if strings.IndexByte(matchedHook.PreHookCommand, ' ') != -1 {
|
||||||
s := strings.Fields(matchedHook.ContextProviderCommand)[0]
|
s := strings.Fields(matchedHook.PreHookCommand)[0]
|
||||||
log.Printf("[%s] please use a wrapper script to provide arguments to context provider command for '%s'\n", rid, s)
|
log.Printf("[%s] please use a wrapper script to provide arguments to pre-hook command for '%s'\n", rid, s)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
contextProviderCommandStdin := struct {
|
preHookCommandStdin := hook.PreHookContext{
|
||||||
HookID string `json:"hookID"`
|
HookID: matchedHook.ID,
|
||||||
Method string `json:"method"`
|
Method: r.Method,
|
||||||
Body string `json:"body"`
|
Base64EncodedBody: base64.StdEncoding.EncodeToString(body),
|
||||||
RemoteAddress string `json:"remoteAddress"`
|
RemoteAddress: r.RemoteAddr,
|
||||||
URI string `json:"URI"`
|
URI: r.RequestURI,
|
||||||
Host string `json:"host"`
|
Host: r.Host,
|
||||||
Headers http.Header `json:"headers"`
|
Headers: r.Header,
|
||||||
Query url.Values `json:"query"`
|
Query: r.URL.Query(),
|
||||||
}{
|
|
||||||
HookID: matchedHook.ID,
|
|
||||||
Method: r.Method,
|
|
||||||
Body: string(body),
|
|
||||||
RemoteAddress: r.RemoteAddr,
|
|
||||||
URI: r.RequestURI,
|
|
||||||
Host: r.Host,
|
|
||||||
Headers: r.Header,
|
|
||||||
Query: r.URL.Query(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stdinJSON, err := json.Marshal(contextProviderCommandStdin)
|
if preHookCommandStdinJSONString, err := json.Marshal(preHookCommandStdin); err != nil {
|
||||||
|
log.Printf("[%s] unable to encode pre-hook context as JSON string for the pre-hook command: %+v\n", rid, err)
|
||||||
if err != nil {
|
|
||||||
log.Printf("[%s] unable to encode context as JSON string for the context provider command: %+v\n", rid, err)
|
|
||||||
} else {
|
} else {
|
||||||
cmd := exec.Command(cmdPath)
|
preHookCommand := exec.Command(preHookCommandPath)
|
||||||
cmd.Dir = matchedHook.CommandWorkingDirectory
|
preHookCommand.Dir = matchedHook.CommandWorkingDirectory
|
||||||
cmd.Env = append(os.Environ())
|
preHookCommand.Env = append(os.Environ())
|
||||||
stdin, err := cmd.StdinPipe()
|
|
||||||
|
|
||||||
if err != nil {
|
if preHookCommandStdinPipe, err := preHookCommand.StdinPipe(); err != nil {
|
||||||
log.Printf("[%s] unable to acquire stdin pipe for the context provider command: %+v\n", rid, err)
|
log.Printf("[%s] unable to acquire stdin pipe for the pre-hook command: %+v\n", rid, err)
|
||||||
} else {
|
} else {
|
||||||
_, err := io.WriteString(stdin, string(stdinJSON))
|
_, err := io.WriteString(preHookCommandStdinPipe, string(preHookCommandStdinJSONString))
|
||||||
stdin.Close()
|
preHookCommandStdinPipe.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[%s] unable to write to context provider command stdin: %+v\n", rid, err)
|
log.Printf("[%s] unable to write to pre-hook command stdin: %+v\n", rid, err)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[%s] executing context provider command %s (%s) using %s as cwd\n", rid, matchedHook.ContextProviderCommand, cmd.Path, cmd.Dir)
|
log.Printf("[%s] executing pre-hook command %s (%s) using %s as cwd\n", rid, matchedHook.PreHookCommand, preHookCommand.Path, preHookCommand.Dir)
|
||||||
out, err := cmd.CombinedOutput()
|
|
||||||
|
|
||||||
if err != nil {
|
if preHookCommandOutput, err := preHookCommand.CombinedOutput(); err != nil {
|
||||||
log.Printf("[%s] unable to execute context provider command: %+v\n", rid, err)
|
log.Printf("[%s] unable to execute pre-hook command: %+v\n", rid, err)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[%s] got context provider command output: %+v\n", rid, string(out))
|
JSONDecoder := json.NewDecoder(strings.NewReader(string(preHookCommandOutput)))
|
||||||
|
JSONDecoder.UseNumber()
|
||||||
|
|
||||||
decoder := json.NewDecoder(strings.NewReader(string(out)))
|
if err := JSONDecoder.Decode(&context); err != nil {
|
||||||
decoder.UseNumber()
|
log.Printf("[%s] unable to parse pre-hook command output: %+v\npre-hook command output was: %+v\n", rid, err, string(preHookCommandOutput))
|
||||||
|
|
||||||
err := decoder.Decode(&context)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("[%s] unable to parse context provider command output: %+v\n", rid, err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user