mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-03 19:17:29 -05:00 
			
		
		
		
	* v2: housekeeping: update tools * v2: housekeeping: adhere to US locale in spelling * v2: housekeeping: simplify code
		
			
				
	
	
		
			166 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			166 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
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
 | 
						|
}
 |