diff options
-rw-r--r-- | go.mod | 2 | ||||
-rw-r--r-- | go.sum | 4 | ||||
-rw-r--r-- | modules/caddyhttp/matchers.go | 29 | ||||
-rw-r--r-- | modules/caddyhttp/standard/imports.go | 1 | ||||
-rw-r--r-- | modules/caddyhttp/starlarkmw/example/caddy.json | 19 | ||||
-rw-r--r-- | modules/caddyhttp/starlarkmw/internal/lib/module.go | 165 | ||||
-rw-r--r-- | modules/caddyhttp/starlarkmw/starlarkmw.go | 172 | ||||
-rw-r--r-- | modules/caddyhttp/starlarkmw/tools/gen/example.star | 40 | ||||
-rw-r--r-- | pkg/caddyscript/lib/http.go | 111 | ||||
-rw-r--r-- | pkg/caddyscript/lib/regex.go | 64 | ||||
-rw-r--r-- | pkg/caddyscript/lib/time.go | 144 | ||||
-rw-r--r-- | pkg/caddyscript/matcherenv.go | 32 |
12 files changed, 0 insertions, 783 deletions
@@ -24,11 +24,9 @@ require ( github.com/naoina/toml v0.1.1 github.com/onsi/ginkgo v1.8.0 // indirect github.com/onsi/gomega v1.5.0 // indirect - github.com/starlight-go/starlight v0.0.0-20181207205707-b06f321544f3 github.com/vulcand/oxy v1.0.0 github.com/yuin/goldmark v1.1.17 github.com/yuin/goldmark-highlighting v0.0.0-20191202084645-78f32c8dd6d5 - go.starlark.net v0.0.0-20190919145610-979af19b165c go.uber.org/multierr v1.2.0 // indirect go.uber.org/zap v1.10.0 golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 @@ -309,8 +309,6 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/starlight-go/starlight v0.0.0-20181207205707-b06f321544f3 h1:/fBh1Ot84ILt/ociFHO98wJ9LxIMA3UG8B0unUJPFpY= -github.com/starlight-go/starlight v0.0.0-20181207205707-b06f321544f3/go.mod h1:pxOc2ZuBV+CNlQgzq/HJ9Z9G/eoEMHFeuGohOvva4Co= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -339,8 +337,6 @@ go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.starlark.net v0.0.0-20190919145610-979af19b165c h1:WR7X1xgXJlXhQBdorVc9Db3RhwG+J/kp6bLuMyJjfVw= -go.starlark.net v0.0.0-20190919145610-979af19b165c/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg= go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= diff --git a/modules/caddyhttp/matchers.go b/modules/caddyhttp/matchers.go index 49fe859..873b63d 100644 --- a/modules/caddyhttp/matchers.go +++ b/modules/caddyhttp/matchers.go @@ -28,8 +28,6 @@ import ( "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" - "github.com/caddyserver/caddy/v2/pkg/caddyscript" - "go.starlark.net/starlark" ) type ( @@ -105,9 +103,6 @@ type ( Matchers MatcherSet `json:"-"` } - // MatchStarlarkExpr matches requests by evaluating a Starlark expression. - MatchStarlarkExpr string - // MatchTable matches requests by values in the table. MatchTable string // TODO: finish implementing ) @@ -123,7 +118,6 @@ func init() { caddy.RegisterModule(new(MatchProtocol)) caddy.RegisterModule(MatchRemoteIP{}) caddy.RegisterModule(MatchNegate{}) - caddy.RegisterModule(new(MatchStarlarkExpr)) } // CaddyModule returns the Caddy module information. @@ -646,28 +640,6 @@ func (m MatchRemoteIP) Match(r *http.Request) bool { return false } -// CaddyModule returns the Caddy module information. -func (MatchStarlarkExpr) CaddyModule() caddy.ModuleInfo { - return caddy.ModuleInfo{ - ID: "http.matchers.starlark", - New: func() caddy.Module { return new(MatchStarlarkExpr) }, - } -} - -// Match returns true if r matches m. -func (m MatchStarlarkExpr) 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 { - // TODO: Can we detect this in Provision or Validate instead? - log.Printf("caddyscript for matcher is invalid: attempting to evaluate expression `%v` error `%v`", input, err) - return false - } - return val.String() == "True" -} - // MatchRegexp is an embeddable type for matching // using regular expressions. It adds placeholders // to the request's replacer. @@ -834,7 +806,6 @@ var ( _ caddy.Provisioner = (*MatchRemoteIP)(nil) _ RequestMatcher = (*MatchNegate)(nil) _ caddy.Provisioner = (*MatchNegate)(nil) - _ RequestMatcher = (*MatchStarlarkExpr)(nil) _ caddy.Provisioner = (*MatchRegexp)(nil) _ caddyfile.Unmarshaler = (*MatchHost)(nil) diff --git a/modules/caddyhttp/standard/imports.go b/modules/caddyhttp/standard/imports.go index b85a984..1effb5a 100644 --- a/modules/caddyhttp/standard/imports.go +++ b/modules/caddyhttp/standard/imports.go @@ -15,6 +15,5 @@ import ( _ "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy" _ "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy/fastcgi" _ "github.com/caddyserver/caddy/v2/modules/caddyhttp/rewrite" - _ "github.com/caddyserver/caddy/v2/modules/caddyhttp/starlarkmw" _ "github.com/caddyserver/caddy/v2/modules/caddyhttp/templates" ) diff --git a/modules/caddyhttp/starlarkmw/example/caddy.json b/modules/caddyhttp/starlarkmw/example/caddy.json deleted file mode 100644 index 9479d17..0000000 --- a/modules/caddyhttp/starlarkmw/example/caddy.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "apps": { - "http": { - "servers": { - "MY_SERVER": { - "listen": [":3001"], - "routes": [ - { - "handle": { - "handler": "starlark", - "script": "def setup(r):\n\t# create some middlewares specific to this request\n\ttemplates = loadModule('http.handlers.templates', {'file_root': './includes'})\n\tmidChain = execute([templates])\n\ndef serveHTTP (rw, r):\n\trw.Write('Hello world, from Starlark!')\n" - } - } - ] - } - } - } - } -}
\ No newline at end of file diff --git a/modules/caddyhttp/starlarkmw/internal/lib/module.go b/modules/caddyhttp/starlarkmw/internal/lib/module.go deleted file mode 100644 index 13c706c..0000000 --- a/modules/caddyhttp/starlarkmw/internal/lib/module.go +++ /dev/null @@ -1,165 +0,0 @@ -package lib - -import ( - "encoding/json" - "fmt" - "strings" - - "github.com/caddyserver/caddy/v2/modules/caddyhttp" - - "github.com/caddyserver/caddy/v2" - "go.starlark.net/starlark" -) - -// ResponderModule represents a module that satisfies the caddyhttp handler. -type ResponderModule struct { - Name string - Cfg json.RawMessage - Instance caddyhttp.Handler -} - -func (r ResponderModule) Freeze() {} -func (r ResponderModule) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: responder module") } -func (r ResponderModule) String() string { return "responder module" } -func (r ResponderModule) Type() string { return "responder module" } -func (r ResponderModule) Truth() starlark.Bool { return true } - -// Middleware represents a module that satisfies the starlark Value interface. -type Middleware struct { - Name string - Cfg json.RawMessage - Instance caddyhttp.MiddlewareHandler -} - -func (r Middleware) Freeze() {} -func (r Middleware) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: middleware") } -func (r Middleware) String() string { return "middleware" } -func (r Middleware) Type() string { return "middleware" } -func (r Middleware) Truth() starlark.Bool { return true } - -// LoadMiddleware represents the method exposed to starlark to load a Caddy module. -type LoadMiddleware struct { - Middleware Middleware - Ctx caddy.Context -} - -func (r LoadMiddleware) Freeze() {} -func (r LoadMiddleware) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: loadMiddleware") } -func (r LoadMiddleware) String() string { return "loadMiddleware" } -func (r LoadMiddleware) Type() string { return "function: loadMiddleware" } -func (r LoadMiddleware) Truth() starlark.Bool { return true } - -// Run is the method bound to the starlark loadMiddleware function. -func (r *LoadMiddleware) Run(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { - var name string - var cfg *starlark.Dict - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 2, &name, &cfg) - if err != nil { - return starlark.None, fmt.Errorf("unpacking arguments: %v", err.Error()) - } - - js := json.RawMessage(cfg.String()) - - if !strings.Contains(name, "http.handlers.") { - name = fmt.Sprintf("http.handlers.%s", name) - } - - inst, err := r.Ctx.LoadModuleByID(name, js) - if err != nil { - return starlark.None, err - } - - mid, ok := inst.(caddyhttp.MiddlewareHandler) - if !ok { - return starlark.None, fmt.Errorf("could not assert as middleware handler") - } - - m := Middleware{ - Name: name, - Cfg: js, - Instance: mid, - } - - r.Middleware = m - - return m, nil -} - -// LoadResponder represents the method exposed to starlark to load a Caddy middleware responder. -type LoadResponder struct { - Module ResponderModule - Ctx caddy.Context -} - -func (r LoadResponder) Freeze() {} -func (r LoadResponder) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: loadModule") } -func (r LoadResponder) String() string { return "loadModule" } -func (r LoadResponder) Type() string { return "function: loadModule" } -func (r LoadResponder) Truth() starlark.Bool { return true } - -// Run is the method bound to the starlark loadResponder function. -func (r *LoadResponder) Run(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { - var name string - var cfg *starlark.Dict - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 2, &name, &cfg) - if err != nil { - return starlark.None, fmt.Errorf("unpacking arguments: %v", err.Error()) - } - - js := json.RawMessage(cfg.String()) - - if !strings.Contains(name, "http.handlers.") { - name = fmt.Sprintf("http.handlers.%s", name) - } - - inst, err := r.Ctx.LoadModuleByID(name, js) - if err != nil { - return starlark.None, err - } - - res, ok := inst.(caddyhttp.Handler) - if !ok { - return starlark.None, fmt.Errorf("could not assert as responder") - } - - m := ResponderModule{ - Name: name, - Cfg: js, - Instance: res, - } - - r.Module = m - - return m, nil -} - -// Execute represents the method exposed to starlark to build a middleware chain. -type Execute struct { - Modules []Middleware -} - -func (r Execute) Freeze() {} -func (r Execute) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: execute") } -func (r Execute) String() string { return "execute" } -func (r Execute) Type() string { return "function: execute" } -func (r Execute) Truth() starlark.Bool { return true } - -// Run is the method bound to the starlark execute function. -func (r *Execute) Run(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { - var mids *starlark.List - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &mids) - if err != nil { - return starlark.None, fmt.Errorf("unpacking arguments: %v", err.Error()) - } - - for i := 0; i < mids.Len(); i++ { - val, ok := mids.Index(i).(Middleware) - if !ok { - return starlark.None, fmt.Errorf("cannot get module from execute") - } - - r.Modules = append(r.Modules, val) - } - - return starlark.None, nil -} diff --git a/modules/caddyhttp/starlarkmw/starlarkmw.go b/modules/caddyhttp/starlarkmw/starlarkmw.go deleted file mode 100644 index bd42e13..0000000 --- a/modules/caddyhttp/starlarkmw/starlarkmw.go +++ /dev/null @@ -1,172 +0,0 @@ -package starlarkmw - -import ( - "context" - "fmt" - "net/http" - - "github.com/caddyserver/caddy/v2" - "github.com/caddyserver/caddy/v2/modules/caddyhttp" - "github.com/caddyserver/caddy/v2/modules/caddyhttp/starlarkmw/internal/lib" - caddyscript "github.com/caddyserver/caddy/v2/pkg/caddyscript/lib" - "github.com/starlight-go/starlight/convert" - "go.starlark.net/starlark" -) - -func init() { - caddy.RegisterModule(StarlarkMW{}) -} - -// StarlarkMW represents a middleware responder written in starlark -type StarlarkMW struct { - Script string `json:"script"` - serveHTTP *starlark.Function - setup *starlark.Function - thread *starlark.Thread - loadMiddleware *lib.LoadMiddleware - execute *lib.Execute - globals *starlark.StringDict - gctx caddy.Context - rctx caddy.Context - rcancel context.CancelFunc -} - -// CaddyModule returns the Caddy module information. -func (StarlarkMW) CaddyModule() caddy.ModuleInfo { - return caddy.ModuleInfo{ - ID: "http.handlers.starlark", - New: func() caddy.Module { return new(StarlarkMW) }, - } -} - -// ServeHTTP responds to an http request with starlark. -func (s *StarlarkMW) ServeHTTP(w http.ResponseWriter, r *http.Request) error { - var mwcancel context.CancelFunc - var mwctx caddy.Context - - // call setup() to prepare the middleware chain if it is defined - if s.setup != nil { - mwctx, mwcancel = caddy.NewContext(s.gctx) - defer mwcancel() - - s.loadMiddleware.Ctx = mwctx - args := starlark.Tuple{caddyscript.HTTPRequest{Req: r}} - - _, err := starlark.Call(new(starlark.Thread), s.setup, args, nil) - if err != nil { - return fmt.Errorf("starlark setup(), %v", err) - } - } - - // dynamically build middleware chain for each request - var stack caddyhttp.Handler = caddyhttp.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error { - wr, err := convert.ToValue(w) - if err != nil { - return fmt.Errorf("cannot convert response writer to starlark value") - } - - args := starlark.Tuple{wr, caddyscript.HTTPRequest{Req: r}} - v, err := starlark.Call(new(starlark.Thread), s.serveHTTP, args, nil) - if err != nil { - return fmt.Errorf("starlark serveHTTP(), %v", err) - } - - // if a responder type was returned from starlark we should run it otherwise it - // is expected to handle the request - if resp, ok := v.(lib.ResponderModule); ok { - return resp.Instance.ServeHTTP(w, r) - } - - return nil - }) - - // TODO :- make middlewareResponseWriter exported and wrap w with that - var mid []caddyhttp.Middleware - for _, m := range s.execute.Modules { - mid = append(mid, func(next caddyhttp.Handler) caddyhttp.Handler { - return caddyhttp.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error { - return m.Instance.ServeHTTP(w, r, next) - }) - }) - } - - for i := len(mid) - 1; i >= 0; i-- { - stack = mid[i](stack) - } - - s.execute.Modules = nil - - return stack.ServeHTTP(w, r) -} - -// Cleanup cleans up any modules loaded during the creation of a starlark route. -func (s *StarlarkMW) Cleanup() error { - s.rcancel() - return nil -} - -// Provision sets up the starlark env. -func (s *StarlarkMW) Provision(ctx caddy.Context) error { - // store global context - s.gctx = ctx - - // setup context for cleaning up any modules loaded during starlark script parsing phase - rctx, cancel := caddy.NewContext(ctx) - s.rcancel = cancel - - // setup starlark global env - env := make(starlark.StringDict) - loadMiddleware := lib.LoadMiddleware{} - loadResponder := lib.LoadResponder{ - Ctx: rctx, - } - execute := lib.Execute{} - - lr := starlark.NewBuiltin("loadResponder", loadResponder.Run) - lr = lr.BindReceiver(&loadResponder) - env["loadResponder"] = lr - - lm := starlark.NewBuiltin("loadMiddleware", loadMiddleware.Run) - lm = lm.BindReceiver(&loadMiddleware) - env["loadMiddleware"] = lm - - ex := starlark.NewBuiltin("execute", execute.Run) - ex = ex.BindReceiver(&execute) - env["execute"] = ex - - // import caddyscript lib - env["time"] = caddyscript.Time{} - env["regexp"] = caddyscript.Regexp{} - - // configure starlark - thread := new(starlark.Thread) - s.thread = thread - - // run starlark script - globals, err := starlark.ExecFile(thread, "", s.Script, env) - if err != nil { - return fmt.Errorf("starlark exec file: %v", err.Error()) - } - - // extract defined methods to setup middleware chain and responder, setup is not required - var setup *starlark.Function - if _, ok := globals["setup"]; ok { - setup, ok = globals["setup"].(*starlark.Function) - if !ok { - return fmt.Errorf("setup function not defined in starlark script") - } - } - - serveHTTP, ok := globals["serveHTTP"].(*starlark.Function) - if !ok { - return fmt.Errorf("serveHTTP function not defined in starlark script") - } - - s.setup = setup - s.serveHTTP = serveHTTP - s.loadMiddleware = &loadMiddleware - s.execute = &execute - s.globals = &globals - - return nil -} diff --git a/modules/caddyhttp/starlarkmw/tools/gen/example.star b/modules/caddyhttp/starlarkmw/tools/gen/example.star deleted file mode 100644 index 6ccab32..0000000 --- a/modules/caddyhttp/starlarkmw/tools/gen/example.star +++ /dev/null @@ -1,40 +0,0 @@ -# any module that provisions resources -proxyConfig = { - 'load_balance_type': 'round_robin', - 'upstreams': [ - { - 'host': 'http://localhost:8080', - 'circuit_breaker': { - 'type': 'status_ratio', - 'threshold': 0.5 - } - }, - { - 'host': 'http://localhost:8081' - } - ] -} - -sfConfig = { - 'root': '/Users/dev/Desktop', - 'browse': {}, -} - -proxy = loadResponder('reverse_proxy', proxyConfig) -static_files = loadResponder('file_server', sfConfig) - -def setup(r): - # create some middlewares specific to this request - mid = [] - - if r.query.get('log') == 'true': - logMid = loadMiddleware('log', {'file': 'access.log'}) - mid.append(logMid) - - execute(mid) - -def serveHTTP(w, r): - if r.url.find('static') > 0: - return static_files - - return proxy diff --git a/pkg/caddyscript/lib/http.go b/pkg/caddyscript/lib/http.go deleted file mode 100644 index 5e47d94..0000000 --- a/pkg/caddyscript/lib/http.go +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2015 Matthew Holt and The Caddy Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package caddyscript - -import ( - "fmt" - "net/http" - - "github.com/starlight-go/starlight/convert" - "go.starlark.net/starlark" -) - -// HTTPRequest represents an http request type in caddyscript. -type HTTPRequest struct{ Req *http.Request } - -// AttrNames defines what properties and methods are available on the HTTPRequest type. -func (r HTTPRequest) AttrNames() []string { - return []string{"header", "query", "url", "method", "host", "tls", "redirect"} -} - -func (r HTTPRequest) Freeze() {} -func (r HTTPRequest) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: HTTPRequest") } -func (r HTTPRequest) String() string { return fmt.Sprint(r.Req) } -func (r HTTPRequest) Type() string { return "HTTPRequest" } -func (r HTTPRequest) Truth() starlark.Bool { return true } - -// Header handles returning a header key. -func (r HTTPRequest) Header(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { - var key string - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &key) - if err != nil { - return starlark.None, fmt.Errorf("get request header: %v", err.Error()) - } - - return starlark.String(r.Req.Header.Get(key)), nil -} - -// Redirect handles an http redirect from starlark code. -func (r HTTPRequest) Redirect(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { - var w starlark.Value - var req HTTPRequest - var newURL string - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 3, &w, &req, &newURL) - if err != nil { - return starlark.None, fmt.Errorf("unpacking arguments: %v", err.Error()) - } - - writer := convert.FromValue(w) - if w, ok := writer.(http.ResponseWriter); ok { - http.Redirect(w, req.Req, newURL, http.StatusSeeOther) - return starlark.None, nil - } - - return starlark.None, fmt.Errorf("first provided argument is not http.ResponseWriter") -} - -// Attr defines what happens when props or methods are called on the HTTPRequest type. -func (r HTTPRequest) Attr(name string) (starlark.Value, error) { - switch name { - case "redirect": - b := starlark.NewBuiltin("Redirect", r.Redirect) - b = b.BindReceiver(r) - - return b, nil - case "tls": - tls := new(starlark.Dict) - tls.SetKey(starlark.String("cipher_suite"), starlark.MakeUint(uint(r.Req.TLS.CipherSuite))) - tls.SetKey(starlark.String("did_resume"), starlark.Bool(r.Req.TLS.DidResume)) - tls.SetKey(starlark.String("handshake_complete"), starlark.Bool(r.Req.TLS.HandshakeComplete)) - tls.SetKey(starlark.String("negotiated_protocol"), starlark.String(r.Req.TLS.NegotiatedProtocol)) - tls.SetKey(starlark.String("negotiated_protocol_is_mutual"), starlark.Bool(r.Req.TLS.NegotiatedProtocolIsMutual)) - tls.SetKey(starlark.String("server_name"), starlark.String(r.Req.TLS.ServerName)) - tls.SetKey(starlark.String("version"), starlark.String(r.Req.TLS.Version)) - - return tls, nil - case "header": - b := starlark.NewBuiltin("Header", r.Header) - b = b.BindReceiver(r) - - return b, nil - case "query": - qVals := r.Req.URL.Query() - query := starlark.NewDict(len(qVals)) - - for k, v := range qVals { - query.SetKey(starlark.String(k), starlark.String(v[0])) - } - - return query, nil - case "url": - return starlark.String(r.Req.URL.Path), nil - case "method": - return starlark.String(r.Req.Method), nil - case "host": - return starlark.String(r.Req.Host), nil - } - - return nil, nil -} diff --git a/pkg/caddyscript/lib/regex.go b/pkg/caddyscript/lib/regex.go deleted file mode 100644 index cc69a36..0000000 --- a/pkg/caddyscript/lib/regex.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2015 Matthew Holt and The Caddy Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package caddyscript - -import ( - "fmt" - "regexp" - - "go.starlark.net/starlark" -) - -// Regexp represents a regexp type for caddyscript. -type Regexp struct{} - -// AttrNames defines what properties and methods are available on the Time type. -func (r Regexp) AttrNames() []string { - return []string{"match_string"} -} - -// Attr defines what happens when props or methods are called on the Time type. -func (r Regexp) Attr(name string) (starlark.Value, error) { - switch name { - case "match_string": - b := starlark.NewBuiltin("match_string", r.MatchString) - b = b.BindReceiver(r) - return b, nil - } - - return nil, nil -} - -// MatchString reports whether the string s contains any match of the regular expression pattern. More complicated queries need to use Compile and the full Regexp interface. -func (r Regexp) MatchString(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { - var pattern, match string - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 2, &pattern, &match) - if err != nil { - return starlark.None, fmt.Errorf("could not unpack args: %v", err.Error()) - } - - matched, err := regexp.MatchString(pattern, match) - if err != nil { - return starlark.False, fmt.Errorf("matchstring: %v", err.Error()) - } - - return starlark.Bool(matched), nil -} - -func (r Regexp) Freeze() {} -func (r Regexp) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: Regexp") } -func (r Regexp) String() string { return "Regexp" } -func (r Regexp) Type() string { return "Regexp" } -func (r Regexp) Truth() starlark.Bool { return true } diff --git a/pkg/caddyscript/lib/time.go b/pkg/caddyscript/lib/time.go deleted file mode 100644 index 0e2f4e4..0000000 --- a/pkg/caddyscript/lib/time.go +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2015 Matthew Holt and The Caddy Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package caddyscript - -import ( - "fmt" - ti "time" - - "go.starlark.net/starlark" -) - -// Time represents a time type for caddyscript. -type Time struct { - value int64 // time since epoch in nanoseconds -} - -// AttrNames defines what properties and methods are available on the Time type. -func (r Time) AttrNames() []string { - return []string{"now", "parse", "add", "subtract", "minute", "hour", "day", "value"} -} - -// Attr defines what happens when props or methods are called on the Time type. -func (r Time) Attr(name string) (starlark.Value, error) { - switch name { - case "now": - b := starlark.NewBuiltin("now", r.Now) - b = b.BindReceiver(r) - return b, nil - case "parse_duration": - b := starlark.NewBuiltin("parse_duration", r.ParseDuration) - b = b.BindReceiver(r) - return b, nil - case "add": - b := starlark.NewBuiltin("add", r.Add) - b = b.BindReceiver(r) - return b, nil - case "subtract": - b := starlark.NewBuiltin("subtract", r.Subtract) - b = b.BindReceiver(r) - return b, nil - case "minute": - b := starlark.NewBuiltin("minute", r.Minute) - b = b.BindReceiver(r) - return b, nil - case "hour": - b := starlark.NewBuiltin("hour", r.Hour) - b = b.BindReceiver(r) - return b, nil - case "day": - b := starlark.NewBuiltin("day", r.Day) - b = b.BindReceiver(r) - return b, nil - case "value": - return starlark.MakeInt64(r.value), nil - } - - return nil, nil -} - -func (r Time) Freeze() {} -func (r Time) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: Time") } -func (r Time) String() string { return fmt.Sprint(r.value) } -func (r Time) Type() string { return "Time" } -func (r Time) Truth() starlark.Bool { return true } - -// Hour returns the current hour of a unix timestamp in range [0, 23]. -func (r Time) Hour(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { - t := ti.Unix(0, r.value) - return starlark.MakeInt(t.Hour()), nil -} - -// Minute returns the current minute of the hour for a unix timestamp in range [0, 59]. -func (r Time) Minute(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { - t := ti.Unix(0, r.value) - return starlark.MakeInt(t.Minute()), nil -} - -// Day returns the current day in a week of a unix timestamp... [Sunday = 0...] -func (r Time) Day(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { - t := ti.Unix(0, r.value) - return starlark.MakeInt(int(t.Weekday())), nil -} - -// Now returns the current time as a unix timestamp. -func (r Time) Now(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { - val := ti.Now().UnixNano() - r.value = val - return r, nil -} - -// ParseDuration parses a go duration string to a time type. -func (r Time) ParseDuration(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { - var dur string - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &dur) - if err != nil { - return starlark.None, fmt.Errorf("could not unpack args: %v", err.Error()) - } - - if parsed, err := ti.ParseDuration(dur); err == nil { - val := parsed.Nanoseconds() - r.value = val - return r, nil - } - - return starlark.None, fmt.Errorf("time.parse_duration: argument cannot be parsed as a valid go time duration") -} - -// Add adds time to a time type. -func (r Time) Add(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { - var t Time - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &t) - if err != nil { - return starlark.None, fmt.Errorf("could not unpack args: %v", err.Error()) - } - - val := r.value + t.value - r.value = val - return r, nil -} - -// Subtract adds time to a time type. -func (r Time) Subtract(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { - var t Time - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &t) - if err != nil { - return starlark.None, fmt.Errorf("could not unpack args: %v", err.Error()) - } - - val := r.value - t.value - r.value = val - return r, nil -} diff --git a/pkg/caddyscript/matcherenv.go b/pkg/caddyscript/matcherenv.go deleted file mode 100644 index 6c9fb50..0000000 --- a/pkg/caddyscript/matcherenv.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2015 Matthew Holt and The Caddy Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package caddyscript - -import ( - "net/http" - - caddyscript "github.com/caddyserver/caddy/v2/pkg/caddyscript/lib" - "go.starlark.net/starlark" -) - -// MatcherEnv sets up the global context for the matcher caddyscript environment. -func MatcherEnv(r *http.Request) starlark.StringDict { - env := make(starlark.StringDict) - env["req"] = caddyscript.HTTPRequest{Req: r} - env["time"] = caddyscript.Time{} - env["regexp"] = caddyscript.Regexp{} - - return env -} |