1package cbreaker 2 3import ( 4 "bytes" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "net/http" 9 "net/url" 10 "strings" 11 12 log "github.com/sirupsen/logrus" 13 "github.com/vulcand/oxy/utils" 14) 15 16// SideEffect a side effect 17type SideEffect interface { 18 Exec() error 19} 20 21// Webhook Web hook 22type Webhook struct { 23 URL string 24 Method string 25 Headers http.Header 26 Form url.Values 27 Body []byte 28} 29 30// WebhookSideEffect a web hook side effect 31type WebhookSideEffect struct { 32 w Webhook 33 34 log *log.Logger 35} 36 37// NewWebhookSideEffectsWithLogger creates a new WebhookSideEffect 38func NewWebhookSideEffectsWithLogger(w Webhook, l *log.Logger) (*WebhookSideEffect, error) { 39 if w.Method == "" { 40 return nil, fmt.Errorf("Supply method") 41 } 42 _, err := url.Parse(w.URL) 43 if err != nil { 44 return nil, err 45 } 46 47 return &WebhookSideEffect{w: w, log: l}, nil 48} 49 50// NewWebhookSideEffect creates a new WebhookSideEffect 51func NewWebhookSideEffect(w Webhook) (*WebhookSideEffect, error) { 52 return NewWebhookSideEffectsWithLogger(w, log.StandardLogger()) 53} 54 55func (w *WebhookSideEffect) getBody() io.Reader { 56 if len(w.w.Form) != 0 { 57 return strings.NewReader(w.w.Form.Encode()) 58 } 59 if len(w.w.Body) != 0 { 60 return bytes.NewBuffer(w.w.Body) 61 } 62 return nil 63} 64 65// Exec execute the side effect 66func (w *WebhookSideEffect) Exec() error { 67 r, err := http.NewRequest(w.w.Method, w.w.URL, w.getBody()) 68 if err != nil { 69 return err 70 } 71 if len(w.w.Headers) != 0 { 72 utils.CopyHeaders(r.Header, w.w.Headers) 73 } 74 if len(w.w.Form) != 0 { 75 r.Header.Set("Content-Type", "application/x-www-form-urlencoded") 76 } 77 re, err := http.DefaultClient.Do(r) 78 if err != nil { 79 return err 80 } 81 if re.Body != nil { 82 defer re.Body.Close() 83 } 84 body, err := ioutil.ReadAll(re.Body) 85 if err != nil { 86 return err 87 } 88 w.log.Debugf("%v got response: (%s): %s", w, re.Status, string(body)) 89 return nil 90} 91