summaryrefslogtreecommitdiff
path: root/modules/caddyhttp
diff options
context:
space:
mode:
authordev <navdgo@gmail.com>2019-04-03 11:47:27 -0400
committerdev <navdgo@gmail.com>2019-04-08 09:58:11 -0400
commit27ecc7f384bbfc98b28dc73881968897fb8c9a8a (patch)
tree1c579149528c26884c04e0daba3c9f320271b7a7 /modules/caddyhttp
parent402f423693d86d3e37daf64f369dbf54f69338b3 (diff)
Protocol and Caddyscript matchers
* Added matcher to determine what protocol the request is being made by - grpc, tls, http * Added ability to run caddyscript in a matcher to evaluate the http request * Added TLS field to caddyscript request time * Added a library to manipulate and compare a new caddyscript time type * Library for regex in starlark
Diffstat (limited to 'modules/caddyhttp')
-rw-r--r--modules/caddyhttp/caddyhttp.go2
-rw-r--r--modules/caddyhttp/matchers.go62
2 files changed, 54 insertions, 10 deletions
diff --git a/modules/caddyhttp/caddyhttp.go b/modules/caddyhttp/caddyhttp.go
index 059af62..179ad50 100644
--- a/modules/caddyhttp/caddyhttp.go
+++ b/modules/caddyhttp/caddyhttp.go
@@ -32,9 +32,7 @@ type httpModuleConfig struct {
func (hc *httpModuleConfig) Run() error {
// TODO: Either prevent overlapping listeners on different servers, or combine them into one
-
// TODO: A way to loop requests back through, so have them start the matching over again, but keeping any mutations
-
for _, srv := range hc.Servers {
// set up the routes
for i, route := range srv.Routes {
diff --git a/modules/caddyhttp/matchers.go b/modules/caddyhttp/matchers.go
index 59f1838..ab179d8 100644
--- a/modules/caddyhttp/matchers.go
+++ b/modules/caddyhttp/matchers.go
@@ -1,10 +1,24 @@
package caddyhttp
import (
+ "log"
"net/http"
"strings"
"bitbucket.org/lightcodelabs/caddy2"
+ "bitbucket.org/lightcodelabs/caddy2/internal/caddyscript"
+ "go.starlark.net/starlark"
+)
+
+// TODO: Matchers should probably support regex of some sort... performance trade-offs?
+type (
+ matchHost []string
+ matchPath []string
+ matchMethod []string
+ matchQuery map[string][]string
+ matchHeader map[string][]string
+ matchProtocol string
+ matchScript string
)
func init() {
@@ -28,17 +42,47 @@ func init() {
Name: "http.matchers.header",
New: func() (interface{}, error) { return matchHeader{}, nil },
})
+ caddy2.RegisterModule(caddy2.Module{
+ Name: "http.matchers.protocol",
+ New: func() (interface{}, error) { return new(matchProtocol), nil },
+ })
+ caddy2.RegisterModule(caddy2.Module{
+ Name: "http.matchers.caddyscript",
+ New: func() (interface{}, error) { return new(matchScript), nil },
+ })
}
-// TODO: Matchers should probably support regex of some sort... performance trade-offs?
+func (m matchScript) Match(r *http.Request) bool {
+ input := string(m)
+ thread := new(starlark.Thread)
+ env := caddyscript.MatcherEnv(r)
+ val, err := starlark.Eval(thread, "", input, env)
+ if err != nil {
+ log.Printf("caddyscript for matcher is invalid: attempting to evaluate expression `%v` error `%v`", input, err)
+ return false
+ }
-type (
- matchHost []string
- matchPath []string
- matchMethod []string
- matchQuery map[string][]string
- matchHeader map[string][]string
-)
+ return val.String() == "True"
+}
+
+func (m matchProtocol) Match(r *http.Request) bool {
+ switch string(m) {
+ case "grpc":
+ if r.Header.Get("content-type") == "application/grpc" {
+ return true
+ }
+ case "https":
+ if r.TLS != nil {
+ return true
+ }
+ case "http":
+ if r.TLS == nil {
+ return true
+ }
+ }
+
+ return false
+}
func (m matchHost) Match(r *http.Request) bool {
for _, host := range m {
@@ -99,4 +143,6 @@ var (
_ RouteMatcher = matchMethod{}
_ RouteMatcher = matchQuery{}
_ RouteMatcher = matchHeader{}
+ _ RouteMatcher = new(matchProtocol)
+ _ RouteMatcher = new(matchScript)
)