@marcel91200 / caddy Mirror · read-only / commits / 8b28c36d
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 05:15 UTC

Remove Starlark, for now

This is temporary as we prepare for a stable v2 release. We don't want to make promises we don't know we can keep, and the Starlark integration deserves much more focused attention which resources and funding do not currently permit. When the project is financially stable, I will be able to revisit this properly and add flexible, robust Starlark scripting support to Caddy 2.

Matthew Holt committed Feb 6, 2020 at 18:46 UTC 8b28c36d480070c8cf954cb27bec3b44bd7d12ca
12 files changed -783
go.mod
-2
@@ -24,11 +24,9 @@ require (
24 github.com/naoina/toml v0.1.1
25 github.com/onsi/ginkgo v1.8.0 // indirect
26 github.com/onsi/gomega v1.5.0 // indirect
27 - github.com/starlight-go/starlight v0.0.0-20181207205707-b06f321544f3
27 github.com/vulcand/oxy v1.0.0
28 github.com/yuin/goldmark v1.1.17
29 github.com/yuin/goldmark-highlighting v0.0.0-20191202084645-78f32c8dd6d5
31 - go.starlark.net v0.0.0-20190919145610-979af19b165c
30 go.uber.org/multierr v1.2.0 // indirect
31 go.uber.org/zap v1.10.0
32 golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
go.sum
-4
@@ -309,8 +309,6 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1
309 github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
310 github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
311 github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
312 -github.com/starlight-go/starlight v0.0.0-20181207205707-b06f321544f3 h1:/fBh1Ot84ILt/ociFHO98wJ9LxIMA3UG8B0unUJPFpY=
313 -github.com/starlight-go/starlight v0.0.0-20181207205707-b06f321544f3/go.mod h1:pxOc2ZuBV+CNlQgzq/HJ9Z9G/eoEMHFeuGohOvva4Co=
312 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
313 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
314 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=
337 go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
338 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
339 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
342 -go.starlark.net v0.0.0-20190919145610-979af19b165c h1:WR7X1xgXJlXhQBdorVc9Db3RhwG+J/kp6bLuMyJjfVw=
343 -go.starlark.net v0.0.0-20190919145610-979af19b165c/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
340 go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
341 go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
342 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
modules/caddyhttp/matchers.go
-29
@@ -28,8 +28,6 @@ import (
28
29 "github.com/caddyserver/caddy/v2"
30 "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
31 - "github.com/caddyserver/caddy/v2/pkg/caddyscript"
32 - "go.starlark.net/starlark"
31 )
32
33 type (
@@ -105,9 +103,6 @@ type (
103 Matchers MatcherSet `json:"-"`
104 }
105
108 - // MatchStarlarkExpr matches requests by evaluating a Starlark expression.
109 - MatchStarlarkExpr string
110 -
106 // MatchTable matches requests by values in the table.
107 MatchTable string // TODO: finish implementing
108 )
@@ -123,7 +118,6 @@ func init() {
118 caddy.RegisterModule(new(MatchProtocol))
119 caddy.RegisterModule(MatchRemoteIP{})
120 caddy.RegisterModule(MatchNegate{})
126 - caddy.RegisterModule(new(MatchStarlarkExpr))
121 }
122
123 // CaddyModule returns the Caddy module information.
@@ -646,28 +640,6 @@ func (m MatchRemoteIP) Match(r *http.Request) bool {
640 return false
641 }
642
649 -// CaddyModule returns the Caddy module information.
650 -func (MatchStarlarkExpr) CaddyModule() caddy.ModuleInfo {
651 - return caddy.ModuleInfo{
652 - ID: "http.matchers.starlark",
653 - New: func() caddy.Module { return new(MatchStarlarkExpr) },
654 - }
655 -}
656 -
657 -// Match returns true if r matches m.
658 -func (m MatchStarlarkExpr) Match(r *http.Request) bool {
659 - input := string(m)
660 - thread := new(starlark.Thread)
661 - env := caddyscript.MatcherEnv(r)
662 - val, err := starlark.Eval(thread, "", input, env)
663 - if err != nil {
664 - // TODO: Can we detect this in Provision or Validate instead?
665 - log.Printf("caddyscript for matcher is invalid: attempting to evaluate expression `%v` error `%v`", input, err)
666 - return false
667 - }
668 - return val.String() == "True"
669 -}
670 -
643 // MatchRegexp is an embeddable type for matching
644 // using regular expressions. It adds placeholders
645 // to the request's replacer.
@@ -834,7 +806,6 @@ var (
806 _ caddy.Provisioner = (*MatchRemoteIP)(nil)
807 _ RequestMatcher = (*MatchNegate)(nil)
808 _ caddy.Provisioner = (*MatchNegate)(nil)
837 - _ RequestMatcher = (*MatchStarlarkExpr)(nil)
809 _ caddy.Provisioner = (*MatchRegexp)(nil)
810
811 _ caddyfile.Unmarshaler = (*MatchHost)(nil)
modules/caddyhttp/standard/imports.go
-1
@@ -15,6 +15,5 @@ import (
15 _ "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy"
16 _ "github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy/fastcgi"
17 _ "github.com/caddyserver/caddy/v2/modules/caddyhttp/rewrite"
18 - _ "github.com/caddyserver/caddy/v2/modules/caddyhttp/starlarkmw"
18 _ "github.com/caddyserver/caddy/v2/modules/caddyhttp/templates"
19 )
modules/caddyhttp/starlarkmw/example/caddy.json deleted
-19
@@ -1,19 +0,0 @@
1 -{
2 - "apps": {
3 - "http": {
4 - "servers": {
5 - "MY_SERVER": {
6 - "listen": [":3001"],
7 - "routes": [
8 - {
9 - "handle": {
10 - "handler": "starlark",
11 - "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"
12 - }
13 - }
14 - ]
15 - }
16 - }
17 - }
18 - }
19 -}
\ No newline at end of file
modules/caddyhttp/starlarkmw/internal/lib/module.go deleted
-165
@@ -1,165 +0,0 @@
1 -package lib
2 -
3 -import (
4 - "encoding/json"
5 - "fmt"
6 - "strings"
7 -
8 - "github.com/caddyserver/caddy/v2/modules/caddyhttp"
9 -
10 - "github.com/caddyserver/caddy/v2"
11 - "go.starlark.net/starlark"
12 -)
13 -
14 -// ResponderModule represents a module that satisfies the caddyhttp handler.
15 -type ResponderModule struct {
16 - Name string
17 - Cfg json.RawMessage
18 - Instance caddyhttp.Handler
19 -}
20 -
21 -func (r ResponderModule) Freeze() {}
22 -func (r ResponderModule) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: responder module") }
23 -func (r ResponderModule) String() string { return "responder module" }
24 -func (r ResponderModule) Type() string { return "responder module" }
25 -func (r ResponderModule) Truth() starlark.Bool { return true }
26 -
27 -// Middleware represents a module that satisfies the starlark Value interface.
28 -type Middleware struct {
29 - Name string
30 - Cfg json.RawMessage
31 - Instance caddyhttp.MiddlewareHandler
32 -}
33 -
34 -func (r Middleware) Freeze() {}
35 -func (r Middleware) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: middleware") }
36 -func (r Middleware) String() string { return "middleware" }
37 -func (r Middleware) Type() string { return "middleware" }
38 -func (r Middleware) Truth() starlark.Bool { return true }
39 -
40 -// LoadMiddleware represents the method exposed to starlark to load a Caddy module.
41 -type LoadMiddleware struct {
42 - Middleware Middleware
43 - Ctx caddy.Context
44 -}
45 -
46 -func (r LoadMiddleware) Freeze() {}
47 -func (r LoadMiddleware) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: loadMiddleware") }
48 -func (r LoadMiddleware) String() string { return "loadMiddleware" }
49 -func (r LoadMiddleware) Type() string { return "function: loadMiddleware" }
50 -func (r LoadMiddleware) Truth() starlark.Bool { return true }
51 -
52 -// Run is the method bound to the starlark loadMiddleware function.
53 -func (r *LoadMiddleware) Run(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
54 - var name string
55 - var cfg *starlark.Dict
56 - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 2, &name, &cfg)
57 - if err != nil {
58 - return starlark.None, fmt.Errorf("unpacking arguments: %v", err.Error())
59 - }
60 -
61 - js := json.RawMessage(cfg.String())
62 -
63 - if !strings.Contains(name, "http.handlers.") {
64 - name = fmt.Sprintf("http.handlers.%s", name)
65 - }
66 -
67 - inst, err := r.Ctx.LoadModuleByID(name, js)
68 - if err != nil {
69 - return starlark.None, err
70 - }
71 -
72 - mid, ok := inst.(caddyhttp.MiddlewareHandler)
73 - if !ok {
74 - return starlark.None, fmt.Errorf("could not assert as middleware handler")
75 - }
76 -
77 - m := Middleware{
78 - Name: name,
79 - Cfg: js,
80 - Instance: mid,
81 - }
82 -
83 - r.Middleware = m
84 -
85 - return m, nil
86 -}
87 -
88 -// LoadResponder represents the method exposed to starlark to load a Caddy middleware responder.
89 -type LoadResponder struct {
90 - Module ResponderModule
91 - Ctx caddy.Context
92 -}
93 -
94 -func (r LoadResponder) Freeze() {}
95 -func (r LoadResponder) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: loadModule") }
96 -func (r LoadResponder) String() string { return "loadModule" }
97 -func (r LoadResponder) Type() string { return "function: loadModule" }
98 -func (r LoadResponder) Truth() starlark.Bool { return true }
99 -
100 -// Run is the method bound to the starlark loadResponder function.
101 -func (r *LoadResponder) Run(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
102 - var name string
103 - var cfg *starlark.Dict
104 - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 2, &name, &cfg)
105 - if err != nil {
106 - return starlark.None, fmt.Errorf("unpacking arguments: %v", err.Error())
107 - }
108 -
109 - js := json.RawMessage(cfg.String())
110 -
111 - if !strings.Contains(name, "http.handlers.") {
112 - name = fmt.Sprintf("http.handlers.%s", name)
113 - }
114 -
115 - inst, err := r.Ctx.LoadModuleByID(name, js)
116 - if err != nil {
117 - return starlark.None, err
118 - }
119 -
120 - res, ok := inst.(caddyhttp.Handler)
121 - if !ok {
122 - return starlark.None, fmt.Errorf("could not assert as responder")
123 - }
124 -
125 - m := ResponderModule{
126 - Name: name,
127 - Cfg: js,
128 - Instance: res,
129 - }
130 -
131 - r.Module = m
132 -
133 - return m, nil
134 -}
135 -
136 -// Execute represents the method exposed to starlark to build a middleware chain.
137 -type Execute struct {
138 - Modules []Middleware
139 -}
140 -
141 -func (r Execute) Freeze() {}
142 -func (r Execute) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: execute") }
143 -func (r Execute) String() string { return "execute" }
144 -func (r Execute) Type() string { return "function: execute" }
145 -func (r Execute) Truth() starlark.Bool { return true }
146 -
147 -// Run is the method bound to the starlark execute function.
148 -func (r *Execute) Run(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
149 - var mids *starlark.List
150 - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &mids)
151 - if err != nil {
152 - return starlark.None, fmt.Errorf("unpacking arguments: %v", err.Error())
153 - }
154 -
155 - for i := 0; i < mids.Len(); i++ {
156 - val, ok := mids.Index(i).(Middleware)
157 - if !ok {
158 - return starlark.None, fmt.Errorf("cannot get module from execute")
159 - }
160 -
161 - r.Modules = append(r.Modules, val)
162 - }
163 -
164 - return starlark.None, nil
165 -}
modules/caddyhttp/starlarkmw/starlarkmw.go deleted
-172
@@ -1,172 +0,0 @@
1 -package starlarkmw
2 -
3 -import (
4 - "context"
5 - "fmt"
6 - "net/http"
7 -
8 - "github.com/caddyserver/caddy/v2"
9 - "github.com/caddyserver/caddy/v2/modules/caddyhttp"
10 - "github.com/caddyserver/caddy/v2/modules/caddyhttp/starlarkmw/internal/lib"
11 - caddyscript "github.com/caddyserver/caddy/v2/pkg/caddyscript/lib"
12 - "github.com/starlight-go/starlight/convert"
13 - "go.starlark.net/starlark"
14 -)
15 -
16 -func init() {
17 - caddy.RegisterModule(StarlarkMW{})
18 -}
19 -
20 -// StarlarkMW represents a middleware responder written in starlark
21 -type StarlarkMW struct {
22 - Script string `json:"script"`
23 - serveHTTP *starlark.Function
24 - setup *starlark.Function
25 - thread *starlark.Thread
26 - loadMiddleware *lib.LoadMiddleware
27 - execute *lib.Execute
28 - globals *starlark.StringDict
29 - gctx caddy.Context
30 - rctx caddy.Context
31 - rcancel context.CancelFunc
32 -}
33 -
34 -// CaddyModule returns the Caddy module information.
35 -func (StarlarkMW) CaddyModule() caddy.ModuleInfo {
36 - return caddy.ModuleInfo{
37 - ID: "http.handlers.starlark",
38 - New: func() caddy.Module { return new(StarlarkMW) },
39 - }
40 -}
41 -
42 -// ServeHTTP responds to an http request with starlark.
43 -func (s *StarlarkMW) ServeHTTP(w http.ResponseWriter, r *http.Request) error {
44 - var mwcancel context.CancelFunc
45 - var mwctx caddy.Context
46 -
47 - // call setup() to prepare the middleware chain if it is defined
48 - if s.setup != nil {
49 - mwctx, mwcancel = caddy.NewContext(s.gctx)
50 - defer mwcancel()
51 -
52 - s.loadMiddleware.Ctx = mwctx
53 - args := starlark.Tuple{caddyscript.HTTPRequest{Req: r}}
54 -
55 - _, err := starlark.Call(new(starlark.Thread), s.setup, args, nil)
56 - if err != nil {
57 - return fmt.Errorf("starlark setup(), %v", err)
58 - }
59 - }
60 -
61 - // dynamically build middleware chain for each request
62 - var stack caddyhttp.Handler = caddyhttp.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
63 - wr, err := convert.ToValue(w)
64 - if err != nil {
65 - return fmt.Errorf("cannot convert response writer to starlark value")
66 - }
67 -
68 - args := starlark.Tuple{wr, caddyscript.HTTPRequest{Req: r}}
69 - v, err := starlark.Call(new(starlark.Thread), s.serveHTTP, args, nil)
70 - if err != nil {
71 - return fmt.Errorf("starlark serveHTTP(), %v", err)
72 - }
73 -
74 - // if a responder type was returned from starlark we should run it otherwise it
75 - // is expected to handle the request
76 - if resp, ok := v.(lib.ResponderModule); ok {
77 - return resp.Instance.ServeHTTP(w, r)
78 - }
79 -
80 - return nil
81 - })
82 -
83 - // TODO :- make middlewareResponseWriter exported and wrap w with that
84 - var mid []caddyhttp.Middleware
85 - for _, m := range s.execute.Modules {
86 - mid = append(mid, func(next caddyhttp.Handler) caddyhttp.Handler {
87 - return caddyhttp.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
88 - return m.Instance.ServeHTTP(w, r, next)
89 - })
90 - })
91 - }
92 -
93 - for i := len(mid) - 1; i >= 0; i-- {
94 - stack = mid[i](stack)
95 - }
96 -
97 - s.execute.Modules = nil
98 -
99 - return stack.ServeHTTP(w, r)
100 -}
101 -
102 -// Cleanup cleans up any modules loaded during the creation of a starlark route.
103 -func (s *StarlarkMW) Cleanup() error {
104 - s.rcancel()
105 - return nil
106 -}
107 -
108 -// Provision sets up the starlark env.
109 -func (s *StarlarkMW) Provision(ctx caddy.Context) error {
110 - // store global context
111 - s.gctx = ctx
112 -
113 - // setup context for cleaning up any modules loaded during starlark script parsing phase
114 - rctx, cancel := caddy.NewContext(ctx)
115 - s.rcancel = cancel
116 -
117 - // setup starlark global env
118 - env := make(starlark.StringDict)
119 - loadMiddleware := lib.LoadMiddleware{}
120 - loadResponder := lib.LoadResponder{
121 - Ctx: rctx,
122 - }
123 - execute := lib.Execute{}
124 -
125 - lr := starlark.NewBuiltin("loadResponder", loadResponder.Run)
126 - lr = lr.BindReceiver(&loadResponder)
127 - env["loadResponder"] = lr
128 -
129 - lm := starlark.NewBuiltin("loadMiddleware", loadMiddleware.Run)
130 - lm = lm.BindReceiver(&loadMiddleware)
131 - env["loadMiddleware"] = lm
132 -
133 - ex := starlark.NewBuiltin("execute", execute.Run)
134 - ex = ex.BindReceiver(&execute)
135 - env["execute"] = ex
136 -
137 - // import caddyscript lib
138 - env["time"] = caddyscript.Time{}
139 - env["regexp"] = caddyscript.Regexp{}
140 -
141 - // configure starlark
142 - thread := new(starlark.Thread)
143 - s.thread = thread
144 -
145 - // run starlark script
146 - globals, err := starlark.ExecFile(thread, "", s.Script, env)
147 - if err != nil {
148 - return fmt.Errorf("starlark exec file: %v", err.Error())
149 - }
150 -
151 - // extract defined methods to setup middleware chain and responder, setup is not required
152 - var setup *starlark.Function
153 - if _, ok := globals["setup"]; ok {
154 - setup, ok = globals["setup"].(*starlark.Function)
155 - if !ok {
156 - return fmt.Errorf("setup function not defined in starlark script")
157 - }
158 - }
159 -
160 - serveHTTP, ok := globals["serveHTTP"].(*starlark.Function)
161 - if !ok {
162 - return fmt.Errorf("serveHTTP function not defined in starlark script")
163 - }
164 -
165 - s.setup = setup
166 - s.serveHTTP = serveHTTP
167 - s.loadMiddleware = &loadMiddleware
168 - s.execute = &execute
169 - s.globals = &globals
170 -
171 - return nil
172 -}
modules/caddyhttp/starlarkmw/tools/gen/example.star deleted
-40
@@ -1,40 +0,0 @@
1 -# any module that provisions resources
2 -proxyConfig = {
3 - 'load_balance_type': 'round_robin',
4 - 'upstreams': [
5 - {
6 - 'host': 'http://localhost:8080',
7 - 'circuit_breaker': {
8 - 'type': 'status_ratio',
9 - 'threshold': 0.5
10 - }
11 - },
12 - {
13 - 'host': 'http://localhost:8081'
14 - }
15 - ]
16 -}
17 -
18 -sfConfig = {
19 - 'root': '/Users/dev/Desktop',
20 - 'browse': {},
21 -}
22 -
23 -proxy = loadResponder('reverse_proxy', proxyConfig)
24 -static_files = loadResponder('file_server', sfConfig)
25 -
26 -def setup(r):
27 - # create some middlewares specific to this request
28 - mid = []
29 -
30 - if r.query.get('log') == 'true':
31 - logMid = loadMiddleware('log', {'file': 'access.log'})
32 - mid.append(logMid)
33 -
34 - execute(mid)
35 -
36 -def serveHTTP(w, r):
37 - if r.url.find('static') > 0:
38 - return static_files
39 -
40 - return proxy
pkg/caddyscript/lib/http.go deleted
-111
@@ -1,111 +0,0 @@
1 -// Copyright 2015 Matthew Holt and The Caddy Authors
2 -//
3 -// Licensed under the Apache License, Version 2.0 (the "License");
4 -// you may not use this file except in compliance with the License.
5 -// You may obtain a copy of the License at
6 -//
7 -// http://www.apache.org/licenses/LICENSE-2.0
8 -//
9 -// Unless required by applicable law or agreed to in writing, software
10 -// distributed under the License is distributed on an "AS IS" BASIS,
11 -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 -// See the License for the specific language governing permissions and
13 -// limitations under the License.
14 -
15 -package caddyscript
16 -
17 -import (
18 - "fmt"
19 - "net/http"
20 -
21 - "github.com/starlight-go/starlight/convert"
22 - "go.starlark.net/starlark"
23 -)
24 -
25 -// HTTPRequest represents an http request type in caddyscript.
26 -type HTTPRequest struct{ Req *http.Request }
27 -
28 -// AttrNames defines what properties and methods are available on the HTTPRequest type.
29 -func (r HTTPRequest) AttrNames() []string {
30 - return []string{"header", "query", "url", "method", "host", "tls", "redirect"}
31 -}
32 -
33 -func (r HTTPRequest) Freeze() {}
34 -func (r HTTPRequest) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: HTTPRequest") }
35 -func (r HTTPRequest) String() string { return fmt.Sprint(r.Req) }
36 -func (r HTTPRequest) Type() string { return "HTTPRequest" }
37 -func (r HTTPRequest) Truth() starlark.Bool { return true }
38 -
39 -// Header handles returning a header key.
40 -func (r HTTPRequest) Header(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
41 - var key string
42 - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &key)
43 - if err != nil {
44 - return starlark.None, fmt.Errorf("get request header: %v", err.Error())
45 - }
46 -
47 - return starlark.String(r.Req.Header.Get(key)), nil
48 -}
49 -
50 -// Redirect handles an http redirect from starlark code.
51 -func (r HTTPRequest) Redirect(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
52 - var w starlark.Value
53 - var req HTTPRequest
54 - var newURL string
55 - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 3, &w, &req, &newURL)
56 - if err != nil {
57 - return starlark.None, fmt.Errorf("unpacking arguments: %v", err.Error())
58 - }
59 -
60 - writer := convert.FromValue(w)
61 - if w, ok := writer.(http.ResponseWriter); ok {
62 - http.Redirect(w, req.Req, newURL, http.StatusSeeOther)
63 - return starlark.None, nil
64 - }
65 -
66 - return starlark.None, fmt.Errorf("first provided argument is not http.ResponseWriter")
67 -}
68 -
69 -// Attr defines what happens when props or methods are called on the HTTPRequest type.
70 -func (r HTTPRequest) Attr(name string) (starlark.Value, error) {
71 - switch name {
72 - case "redirect":
73 - b := starlark.NewBuiltin("Redirect", r.Redirect)
74 - b = b.BindReceiver(r)
75 -
76 - return b, nil
77 - case "tls":
78 - tls := new(starlark.Dict)
79 - tls.SetKey(starlark.String("cipher_suite"), starlark.MakeUint(uint(r.Req.TLS.CipherSuite)))
80 - tls.SetKey(starlark.String("did_resume"), starlark.Bool(r.Req.TLS.DidResume))
81 - tls.SetKey(starlark.String("handshake_complete"), starlark.Bool(r.Req.TLS.HandshakeComplete))
82 - tls.SetKey(starlark.String("negotiated_protocol"), starlark.String(r.Req.TLS.NegotiatedProtocol))
83 - tls.SetKey(starlark.String("negotiated_protocol_is_mutual"), starlark.Bool(r.Req.TLS.NegotiatedProtocolIsMutual))
84 - tls.SetKey(starlark.String("server_name"), starlark.String(r.Req.TLS.ServerName))
85 - tls.SetKey(starlark.String("version"), starlark.String(r.Req.TLS.Version))
86 -
87 - return tls, nil
88 - case "header":
89 - b := starlark.NewBuiltin("Header", r.Header)
90 - b = b.BindReceiver(r)
91 -
92 - return b, nil
93 - case "query":
94 - qVals := r.Req.URL.Query()
95 - query := starlark.NewDict(len(qVals))
96 -
97 - for k, v := range qVals {
98 - query.SetKey(starlark.String(k), starlark.String(v[0]))
99 - }
100 -
101 - return query, nil
102 - case "url":
103 - return starlark.String(r.Req.URL.Path), nil
104 - case "method":
105 - return starlark.String(r.Req.Method), nil
106 - case "host":
107 - return starlark.String(r.Req.Host), nil
108 - }
109 -
110 - return nil, nil
111 -}
pkg/caddyscript/lib/regex.go deleted
-64
@@ -1,64 +0,0 @@
1 -// Copyright 2015 Matthew Holt and The Caddy Authors
2 -//
3 -// Licensed under the Apache License, Version 2.0 (the "License");
4 -// you may not use this file except in compliance with the License.
5 -// You may obtain a copy of the License at
6 -//
7 -// http://www.apache.org/licenses/LICENSE-2.0
8 -//
9 -// Unless required by applicable law or agreed to in writing, software
10 -// distributed under the License is distributed on an "AS IS" BASIS,
11 -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 -// See the License for the specific language governing permissions and
13 -// limitations under the License.
14 -
15 -package caddyscript
16 -
17 -import (
18 - "fmt"
19 - "regexp"
20 -
21 - "go.starlark.net/starlark"
22 -)
23 -
24 -// Regexp represents a regexp type for caddyscript.
25 -type Regexp struct{}
26 -
27 -// AttrNames defines what properties and methods are available on the Time type.
28 -func (r Regexp) AttrNames() []string {
29 - return []string{"match_string"}
30 -}
31 -
32 -// Attr defines what happens when props or methods are called on the Time type.
33 -func (r Regexp) Attr(name string) (starlark.Value, error) {
34 - switch name {
35 - case "match_string":
36 - b := starlark.NewBuiltin("match_string", r.MatchString)
37 - b = b.BindReceiver(r)
38 - return b, nil
39 - }
40 -
41 - return nil, nil
42 -}
43 -
44 -// 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.
45 -func (r Regexp) MatchString(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
46 - var pattern, match string
47 - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 2, &pattern, &match)
48 - if err != nil {
49 - return starlark.None, fmt.Errorf("could not unpack args: %v", err.Error())
50 - }
51 -
52 - matched, err := regexp.MatchString(pattern, match)
53 - if err != nil {
54 - return starlark.False, fmt.Errorf("matchstring: %v", err.Error())
55 - }
56 -
57 - return starlark.Bool(matched), nil
58 -}
59 -
60 -func (r Regexp) Freeze() {}
61 -func (r Regexp) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: Regexp") }
62 -func (r Regexp) String() string { return "Regexp" }
63 -func (r Regexp) Type() string { return "Regexp" }
64 -func (r Regexp) Truth() starlark.Bool { return true }
pkg/caddyscript/lib/time.go deleted
-144
@@ -1,144 +0,0 @@
1 -// Copyright 2015 Matthew Holt and The Caddy Authors
2 -//
3 -// Licensed under the Apache License, Version 2.0 (the "License");
4 -// you may not use this file except in compliance with the License.
5 -// You may obtain a copy of the License at
6 -//
7 -// http://www.apache.org/licenses/LICENSE-2.0
8 -//
9 -// Unless required by applicable law or agreed to in writing, software
10 -// distributed under the License is distributed on an "AS IS" BASIS,
11 -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 -// See the License for the specific language governing permissions and
13 -// limitations under the License.
14 -
15 -package caddyscript
16 -
17 -import (
18 - "fmt"
19 - ti "time"
20 -
21 - "go.starlark.net/starlark"
22 -)
23 -
24 -// Time represents a time type for caddyscript.
25 -type Time struct {
26 - value int64 // time since epoch in nanoseconds
27 -}
28 -
29 -// AttrNames defines what properties and methods are available on the Time type.
30 -func (r Time) AttrNames() []string {
31 - return []string{"now", "parse", "add", "subtract", "minute", "hour", "day", "value"}
32 -}
33 -
34 -// Attr defines what happens when props or methods are called on the Time type.
35 -func (r Time) Attr(name string) (starlark.Value, error) {
36 - switch name {
37 - case "now":
38 - b := starlark.NewBuiltin("now", r.Now)
39 - b = b.BindReceiver(r)
40 - return b, nil
41 - case "parse_duration":
42 - b := starlark.NewBuiltin("parse_duration", r.ParseDuration)
43 - b = b.BindReceiver(r)
44 - return b, nil
45 - case "add":
46 - b := starlark.NewBuiltin("add", r.Add)
47 - b = b.BindReceiver(r)
48 - return b, nil
49 - case "subtract":
50 - b := starlark.NewBuiltin("subtract", r.Subtract)
51 - b = b.BindReceiver(r)
52 - return b, nil
53 - case "minute":
54 - b := starlark.NewBuiltin("minute", r.Minute)
55 - b = b.BindReceiver(r)
56 - return b, nil
57 - case "hour":
58 - b := starlark.NewBuiltin("hour", r.Hour)
59 - b = b.BindReceiver(r)
60 - return b, nil
61 - case "day":
62 - b := starlark.NewBuiltin("day", r.Day)
63 - b = b.BindReceiver(r)
64 - return b, nil
65 - case "value":
66 - return starlark.MakeInt64(r.value), nil
67 - }
68 -
69 - return nil, nil
70 -}
71 -
72 -func (r Time) Freeze() {}
73 -func (r Time) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: Time") }
74 -func (r Time) String() string { return fmt.Sprint(r.value) }
75 -func (r Time) Type() string { return "Time" }
76 -func (r Time) Truth() starlark.Bool { return true }
77 -
78 -// Hour returns the current hour of a unix timestamp in range [0, 23].
79 -func (r Time) Hour(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
80 - t := ti.Unix(0, r.value)
81 - return starlark.MakeInt(t.Hour()), nil
82 -}
83 -
84 -// Minute returns the current minute of the hour for a unix timestamp in range [0, 59].
85 -func (r Time) Minute(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
86 - t := ti.Unix(0, r.value)
87 - return starlark.MakeInt(t.Minute()), nil
88 -}
89 -
90 -// Day returns the current day in a week of a unix timestamp... [Sunday = 0...]
91 -func (r Time) Day(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
92 - t := ti.Unix(0, r.value)
93 - return starlark.MakeInt(int(t.Weekday())), nil
94 -}
95 -
96 -// Now returns the current time as a unix timestamp.
97 -func (r Time) Now(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
98 - val := ti.Now().UnixNano()
99 - r.value = val
100 - return r, nil
101 -}
102 -
103 -// ParseDuration parses a go duration string to a time type.
104 -func (r Time) ParseDuration(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
105 - var dur string
106 - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &dur)
107 - if err != nil {
108 - return starlark.None, fmt.Errorf("could not unpack args: %v", err.Error())
109 - }
110 -
111 - if parsed, err := ti.ParseDuration(dur); err == nil {
112 - val := parsed.Nanoseconds()
113 - r.value = val
114 - return r, nil
115 - }
116 -
117 - return starlark.None, fmt.Errorf("time.parse_duration: argument cannot be parsed as a valid go time duration")
118 -}
119 -
120 -// Add adds time to a time type.
121 -func (r Time) Add(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
122 - var t Time
123 - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &t)
124 - if err != nil {
125 - return starlark.None, fmt.Errorf("could not unpack args: %v", err.Error())
126 - }
127 -
128 - val := r.value + t.value
129 - r.value = val
130 - return r, nil
131 -}
132 -
133 -// Subtract adds time to a time type.
134 -func (r Time) Subtract(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
135 - var t Time
136 - err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &t)
137 - if err != nil {
138 - return starlark.None, fmt.Errorf("could not unpack args: %v", err.Error())
139 - }
140 -
141 - val := r.value - t.value
142 - r.value = val
143 - return r, nil
144 -}
pkg/caddyscript/matcherenv.go deleted
-32
@@ -1,32 +0,0 @@
1 -// Copyright 2015 Matthew Holt and The Caddy Authors
2 -//
3 -// Licensed under the Apache License, Version 2.0 (the "License");
4 -// you may not use this file except in compliance with the License.
5 -// You may obtain a copy of the License at
6 -//
7 -// http://www.apache.org/licenses/LICENSE-2.0
8 -//
9 -// Unless required by applicable law or agreed to in writing, software
10 -// distributed under the License is distributed on an "AS IS" BASIS,
11 -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 -// See the License for the specific language governing permissions and
13 -// limitations under the License.
14 -
15 -package caddyscript
16 -
17 -import (
18 - "net/http"
19 -
20 - caddyscript "github.com/caddyserver/caddy/v2/pkg/caddyscript/lib"
21 - "go.starlark.net/starlark"
22 -)
23 -
24 -// MatcherEnv sets up the global context for the matcher caddyscript environment.
25 -func MatcherEnv(r *http.Request) starlark.StringDict {
26 - env := make(starlark.StringDict)
27 - env["req"] = caddyscript.HTTPRequest{Req: r}
28 - env["time"] = caddyscript.Time{}
29 - env["regexp"] = caddyscript.Regexp{}
30 -
31 - return env
32 -}