diff --git a/README.md b/README.md index a253367..1ee22aa 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Library webhooks ================ ![Project status](https://img.shields.io/badge/version-3.1.0-green.svg) -[![Build Status](https://semaphoreci.com/api/v1/joeybloggs/webhooks/branches/v3/badge.svg)](https://semaphoreci.com/joeybloggs/webhooks) +[![Build Status](https://travis-ci.org/go-playground/webhooks.svg?branch=v3)](https://travis-ci.org/go-playground/webhooks) [![Coverage Status](https://coveralls.io/repos/go-playground/webhooks/badge.svg?branch=v3&service=github)](https://coveralls.io/github/go-playground/webhooks?branch=v3) [![Go Report Card](https://goreportcard.com/badge/go-playground/webhooks)](https://goreportcard.com/report/go-playground/webhooks) [![GoDoc](https://godoc.org/gopkg.in/go-playground/webhooks.v3?status.svg)](https://godoc.org/gopkg.in/go-playground/webhooks.v3) diff --git a/webhooks.go b/webhooks.go index 3dcc2b2..4d1a965 100644 --- a/webhooks.go +++ b/webhooks.go @@ -35,18 +35,27 @@ type Webhook interface { } type server struct { - hook Webhook - path string + hook Webhook + path string + includePathCheck bool } // ProcessPayloadFunc is a common function for payload return values type ProcessPayloadFunc func(payload interface{}, header Header) +// Handler returns the webhook http.Handler for use in your own Mux implementation +func Handler(hook Webhook) http.Handler { + return &server{ + hook: hook, + } +} + // Run runs a server func Run(hook Webhook, addr string, path string) error { srv := &server{ - hook: hook, - path: path, + hook: hook, + path: path, + includePathCheck: true, } s := &http.Server{Addr: addr, Handler: srv} @@ -58,8 +67,9 @@ func Run(hook Webhook, addr string, path string) error { func RunServer(s *http.Server, hook Webhook, path string) error { srv := &server{ - hook: hook, - path: path, + hook: hook, + path: path, + includePathCheck: true, } s.Handler = srv @@ -74,8 +84,9 @@ func RunServer(s *http.Server, hook Webhook, path string) error { func RunTLSServer(s *http.Server, hook Webhook, path string) error { srv := &server{ - hook: hook, - path: path, + hook: hook, + path: path, + includePathCheck: true, } s.Handler = srv @@ -91,9 +102,12 @@ func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, "405 Method not allowed", http.StatusMethodNotAllowed) return } - if r.URL.Path != s.path { - http.Error(w, "404 Not found", http.StatusNotFound) - return + + if s.includePathCheck { + if r.URL.Path != s.path { + http.Error(w, "404 Not found", http.StatusNotFound) + return + } } s.hook.ParsePayload(w, r) diff --git a/webhooks_test.go b/webhooks_test.go index 1bec132..b6c06fc 100644 --- a/webhooks_test.go +++ b/webhooks_test.go @@ -8,6 +8,8 @@ import ( "testing" "time" + "net/http/httptest" + . "gopkg.in/go-playground/assert.v1" ) @@ -47,6 +49,43 @@ func TestMain(m *testing.M) { // teardown } +func TestHandler(t *testing.T) { + + mux := http.NewServeMux() + mux.Handle("/webhooks", Handler(fakeHook)) + + s := httptest.NewServer(Handler(fakeHook)) + defer s.Close() + + payload := "{}" + + req, err := http.NewRequest("POST", s.URL+"/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + + Equal(t, err, nil) + + client := &http.Client{} + resp, err := client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusOK) + + // Test BAD METHOD + req, err = http.NewRequest("GET", s.URL+"/webhooks", bytes.NewBuffer([]byte(payload))) + req.Header.Set("Content-Type", "application/json") + + Equal(t, err, nil) + + resp, err = client.Do(req) + Equal(t, err, nil) + + defer resp.Body.Close() + + Equal(t, resp.StatusCode, http.StatusMethodNotAllowed) +} + func TestRun(t *testing.T) { go Run(fakeHook, "127.0.0.1:3006", "/webhooks")