Repository: adnanh/webhook (go)

Issue:
webhook IDs can't be paths?

I'm confused why I can't get webhook id's with paths in them to work?

```
[webhook] 2020/05/19 01:46:46 found 3 hook(s) in file
[webhook] 2020/05/19 01:46:46   loaded: test
[webhook] 2020/05/19 01:46:46   loaded: test_2
[webhook] 2020/05/19 01:46:46   loaded: test_2/canwepath
```

You can see all three hooks are found; however, the only ones that I can actually `POST` to are `test` and `test_2`. If I try to send a request to `test_2/canwepath` I get  `404 Not Found`

Would appreciate any help here; not sure what I'm missing. Kind of a bummer because the API I'm trying to receive requests from uses paths in their IDs

Pull request description:
Add support for slashes in hook IDs
When matching variables in routes, gorilla/mux uses a default pattern of
"[^/]+", thereby prohibiting slashes in variable matching.  Override the
default pattern to remove this restriction.

See https://github.com/gorilla/mux/blob/v1.8.0/regexp.go#L50

Fixes #421

Patch:
diff --git a/webhook.go b/webhook.go
index ea6a9f2..922e326 100644
--- a/webhook.go
+++ b/webhook.go
@@ -262,7 +262,7 @@ func main() {
 	// Clean up input
 	*httpMethods = strings.ToUpper(strings.ReplaceAll(*httpMethods, " ", ""))
 
-	hooksURL := makeURL(hooksURLPrefix)
+	hooksURL := makeRoutePattern(hooksURLPrefix)
 
 	r.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
 		fmt.Fprint(w, "OK")
@@ -278,7 +278,7 @@ func main() {
 
 	// Serve HTTP
 	if !*secure {
-		log.Printf("serving hooks on http://%s%s", addr, hooksURL)
+		log.Printf("serving hooks on http://%s%s", addr, makeHumanPattern(hooksURLPrefix))
 		log.Print(svr.Serve(ln))
 
 		return
@@ -293,7 +293,7 @@ func main() {
 	}
 	svr.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler)) // disable http/2
 
-	log.Printf("serving hooks on https://%s%s", addr, hooksURL)
+	log.Printf("serving hooks on https://%s%s", addr, makeHumanPattern(hooksURLPrefix))
 	log.Print(svr.ServeTLS(ln, *cert, *key))
 }
 
@@ -763,10 +763,21 @@ func valuesToMap(values map[string][]string) map[string]interface{} {
 	return ret
 }
 
-// makeURL builds a hook URL with or without a prefix.
-func makeURL(prefix *string) string {
+// makeRoutePattern builds a pattern matching URL for the mux.
+func makeRoutePattern(prefix *string) string {
+	return makeBaseURL(prefix) + "/{id:.*}"
+}
+
+// makeHumanPattern builds a human-friendly URL for display.
+func makeHumanPattern(prefix *string) string {
+	return makeBaseURL(prefix) + "/{id}"
+}
+
+// makeBaseURL creates the base URL before any mux pattern matching.
+func makeBaseURL(prefix *string) string {
 	if prefix == nil || *prefix == "" {
-		return "/{id}"
+		return ""
 	}
-	return "/" + *prefix + "/{id}"
+
+	return "/" + *prefix
 }


Test patch:
diff --git a/test/hooks.json.tmpl b/test/hooks.json.tmpl
index fd5cb83..4c40eba 100644
--- a/test/hooks.json.tmpl
+++ b/test/hooks.json.tmpl
@@ -184,6 +184,22 @@
       }
     }
   },
+  {
+    "id": "sendgrid/dir",
+    "execute-command": "{{ .Hookecho }}",
+    "command-working-directory": "/",
+    "response-message": "success",
+    "trigger-rule": {
+      "match": {
+        "type": "value",
+        "parameter": {
+          "source": "payload",
+          "name": "root.0.event"
+        },
+        "value": "it worked!"
+      }
+    }
+  },
   {
     "id": "plex",
     "execute-command": "{{ .Hookecho }}",
diff --git a/test/hooks.yaml.tmpl b/test/hooks.yaml.tmpl
index 82833dc..127016e 100644
--- a/test/hooks.yaml.tmpl
+++ b/test/hooks.yaml.tmpl
@@ -109,6 +109,18 @@
         name: root.0.event
       value: processed
 
+- id: sendgrid/dir
+  execute-command: '{{ .Hookecho }}'
+  command-working-directory: /
+  response-message: success
+  trigger-rule:
+    match:
+      type: value
+      parameter:
+        source: payload
+        name: root.0.event
+      value: it worked!
+
 - id: plex
   trigger-rule:
     match:
diff --git a/webhook_test.go b/webhook_test.go
index 885efb6..6364f1a 100644
--- a/webhook_test.go
+++ b/webhook_test.go
@@ -589,6 +589,29 @@ env: HOOK_head_commit.timestamp=2013-03-12T08:14:29-07:00
     "sg_event_id": "sg_event_id",
     "sg_message_id": "sg_message_id"
   }
+]`,
+		false,
+		http.StatusOK,
+		`success`,
+		``,
+	},
+	{
+		"slash-in-hook-id",
+		"sendgrid/dir",
+		nil,
+		"POST",
+		nil,
+		"application/json",
+		`[
+  {
+    "email": "example@test.com",
+    "timestamp": 1513299569,
+    "smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>",
+    "event": "it worked!",
+    "category": "cat facts",
+    "sg_event_id": "sg_event_id",
+    "sg_message_id": "sg_message_id"
+  }
 ]`,
 		false,
 		http.StatusOK,