Merge pull request #69 from adnanh/development

version 2.3.8
This commit is contained in:
Adnan Hajdarević 2016-03-24 16:55:34 +01:00
commit ec42679305
4 changed files with 72 additions and 11 deletions

View file

@ -59,6 +59,9 @@ However, hook defined like that could pose a security threat to your system, bec
# Using HTTPS
[webhook](https://github.com/adnanh/webhook/) by default serves hooks using http. If you want [webhook](https://github.com/adnanh/webhook/) to serve secure content using https, you can use the `-secure` flag while starting [webhook](https://github.com/adnanh/webhook/). Files containing a certificate and matching private key for the server must be provided using the `-cert /path/to/cert.pem` and `-key /path/to/key.pem` flags. If the certificate is signed by a certificate authority, the cert file should be the concatenation of the server's certificate followed by the CA's certificate.
# CORS Headers
If you want to set CORS headers, you can use the `-header name=value` flag while starting [webhook](https://github.com/adnanh/webhook/) to set the appropriate CORS headers that will be returned with each response.
# Interested in running webhook inside of a Docker container?
You can use [almir/webhook](https://hub.docker.com/r/almir/webhook/) docker image, or create your own (please read [this discussion](https://github.com/adnanh/webhook/issues/63)).

View file

@ -5,6 +5,7 @@ import (
"crypto/sha1"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"reflect"
@ -246,12 +247,49 @@ func (ha *Argument) Get(headers, query, payload *map[string]interface{}) (string
return "", false
}
// Header is a structure containing header name and it's value
type Header struct {
Name string `json:"name"`
Value string `json:"value"`
}
// ResponseHeaders is a slice of Header objects
type ResponseHeaders []Header
func (h *ResponseHeaders) String() string {
// a 'hack' to display name=value in flag usage listing
if len(*h) == 0 {
return "name=value"
}
result := make([]string, len(*h))
for idx, responseHeader := range *h {
result[idx] = fmt.Sprintf("%s=%s", responseHeader.Name, responseHeader.Value)
}
return fmt.Sprint(strings.Join(result, ", "))
}
// Set method appends new Header object from header=value notation
func (h *ResponseHeaders) Set(value string) error {
splitResult := strings.SplitN(value, "=", 2)
if len(splitResult) != 2 {
return errors.New("header flag must be in name=value format")
}
*h = append(*h, Header{Name: splitResult[0], Value: splitResult[1]})
return nil
}
// Hook type is a structure containing details for a single hook
type Hook struct {
ID string `json:"id,omitempty"`
ExecuteCommand string `json:"execute-command,omitempty"`
CommandWorkingDirectory string `json:"command-working-directory,omitempty"`
ResponseMessage string `json:"response-message,omitempty"`
ResponseHeaders ResponseHeaders `json:"response-headers,omitempty"`
CaptureCommandOutput bool `json:"include-command-output-in-response,omitempty"`
PassEnvironmentToCommand []Argument `json:"pass-environment-to-command,omitempty"`
PassArgumentsToCommand []Argument `json:"pass-arguments-to-command,omitempty"`

View file

@ -4,6 +4,13 @@
"execute-command": "/home/adnan/redeploy-go-webhook.sh",
"command-working-directory": "/home/adnan/go",
"response-message": "I got the payload!",
"response-headers":
[
{
"name": "Access-Control-Allow-Origin",
"value": "*"
}
],
"pass-arguments-to-command":
[
{

View file

@ -21,7 +21,7 @@ import (
)
const (
version = "2.3.7"
version = "2.3.8"
)
var (
@ -36,6 +36,8 @@ var (
cert = flag.String("cert", "cert.pem", "path to the HTTPS certificate pem file")
key = flag.String("key", "key.pem", "path to the HTTPS certificate private key pem file")
responseHeaders hook.ResponseHeaders
watcher *fsnotify.Watcher
signals chan os.Signal
@ -45,6 +47,8 @@ var (
func main() {
hooks = hook.Hooks{}
flag.Var(&responseHeaders, "header", "response header to return, specified in format name=value, use multiple times to set multiple headers")
flag.Parse()
log.SetPrefix("[webhook] ")
@ -137,6 +141,10 @@ func main() {
}
func hookHandler(w http.ResponseWriter, r *http.Request) {
for _, responseHeader := range responseHeaders {
w.Header().Set(responseHeader.Name, responseHeader.Value)
}
id := mux.Vars(r)["id"]
matchedHooks := hooks.MatchAll(id)
@ -180,6 +188,7 @@ func hookHandler(w http.ResponseWriter, r *http.Request) {
// handle hook
for _, h := range matchedHooks {
err := h.ParseJSONParameters(&headers, &query, &payload)
if err != nil {
msg := fmt.Sprintf("error parsing JSON: %s", err)
@ -207,6 +216,10 @@ func hookHandler(w http.ResponseWriter, r *http.Request) {
if ok {
log.Printf("%s hook triggered successfully\n", h.ID)
for _, responseHeader := range h.ResponseHeaders {
w.Header().Set(responseHeader.Name, responseHeader.Value)
}
if h.CaptureCommandOutput {
response := handleHook(h, &headers, &query, &payload, &body)
fmt.Fprintf(w, response)