diff options
author | dev <navdgo@gmail.com> | 2019-04-03 11:47:27 -0400 |
---|---|---|
committer | dev <navdgo@gmail.com> | 2019-04-08 09:58:11 -0400 |
commit | 27ecc7f384bbfc98b28dc73881968897fb8c9a8a (patch) | |
tree | 1c579149528c26884c04e0daba3c9f320271b7a7 /modules | |
parent | 402f423693d86d3e37daf64f369dbf54f69338b3 (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')
-rw-r--r-- | modules/caddyhttp/caddyhttp.go | 2 | ||||
-rw-r--r-- | modules/caddyhttp/matchers.go | 62 |
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) ) |