summaryrefslogtreecommitdiff
path: root/modules/caddyhttp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/caddyhttp')
-rw-r--r--modules/caddyhttp/celmatcher.go114
-rw-r--r--modules/caddyhttp/fileserver/matcher.go12
-rw-r--r--modules/caddyhttp/matchers.go24
3 files changed, 42 insertions, 108 deletions
diff --git a/modules/caddyhttp/celmatcher.go b/modules/caddyhttp/celmatcher.go
index 4938cd5..7b1e89d 100644
--- a/modules/caddyhttp/celmatcher.go
+++ b/modules/caddyhttp/celmatcher.go
@@ -28,7 +28,6 @@ import (
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
"github.com/google/cel-go/cel"
- "github.com/google/cel-go/checker/decls"
"github.com/google/cel-go/common"
"github.com/google/cel-go/common/operators"
"github.com/google/cel-go/common/types"
@@ -40,7 +39,6 @@ import (
"github.com/google/cel-go/parser"
"go.uber.org/zap"
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
- "google.golang.org/protobuf/proto"
)
func init() {
@@ -126,13 +124,12 @@ func (m *MatchExpression) Provision(ctx caddy.Context) error {
// create the CEL environment
env, err := cel.NewEnv(
- cel.Declarations(
- decls.NewVar("request", httpRequestObjectType),
- decls.NewFunction(placeholderFuncName,
- decls.NewOverload(placeholderFuncName+"_httpRequest_string",
- []*exprpb.Type{httpRequestObjectType, decls.String},
- decls.Any)),
- ),
+ cel.Function(placeholderFuncName, cel.SingletonBinaryImpl(m.caddyPlaceholderFunc), cel.Overload(
+ placeholderFuncName+"_httpRequest_string",
+ []*cel.Type{httpRequestObjectType, cel.StringType},
+ cel.AnyType,
+ )),
+ cel.Variable("request", httpRequestObjectType),
cel.CustomTypeAdapter(m.ta),
ext.Strings(),
matcherLib,
@@ -149,20 +146,12 @@ func (m *MatchExpression) Provision(ctx caddy.Context) error {
// request matching is a boolean operation, so we don't really know
// what to do if the expression returns a non-boolean type
- if !proto.Equal(checked.ResultType(), decls.Bool) {
- return fmt.Errorf("CEL request matcher expects return type of bool, not %s", checked.ResultType())
+ if checked.OutputType() != cel.BoolType {
+ return fmt.Errorf("CEL request matcher expects return type of bool, not %s", checked.OutputType())
}
// compile the "program"
- m.prg, err = env.Program(checked,
- cel.EvalOptions(cel.OptOptimize),
- cel.Functions(
- &functions.Overload{
- Operator: placeholderFuncName,
- Binary: m.caddyPlaceholderFunc,
- },
- ),
- )
+ m.prg, err = env.Program(checked, cel.EvalOptions(cel.OptOptimize))
if err != nil {
return fmt.Errorf("compiling CEL program: %s", err)
}
@@ -321,62 +310,46 @@ type CELLibraryProducer interface {
// limited set of function signatures. For strong type validation you may need
// to provide a custom macro which does a more detailed analysis of the CEL
// literal provided to the macro as an argument.
-func CELMatcherImpl(macroName, funcName string, matcherDataTypes []*exprpb.Type, fac CELMatcherFactory) (cel.Library, error) {
- requestType := decls.NewObjectType("http.Request")
+func CELMatcherImpl(macroName, funcName string, matcherDataTypes []*cel.Type, fac CELMatcherFactory) (cel.Library, error) {
+ requestType := cel.ObjectType("http.Request")
var macro parser.Macro
switch len(matcherDataTypes) {
case 1:
matcherDataType := matcherDataTypes[0]
- if isCELStringListType(matcherDataType) {
+ switch matcherDataType.String() {
+ case "list(string)":
macro = parser.NewGlobalVarArgMacro(macroName, celMatcherStringListMacroExpander(funcName))
- } else if isCELStringType(matcherDataType) {
+ case cel.StringType.String():
macro = parser.NewGlobalMacro(macroName, 1, celMatcherStringMacroExpander(funcName))
- } else if isCELJSONType(matcherDataType) {
+ case CELTypeJSON.String():
macro = parser.NewGlobalMacro(macroName, 1, celMatcherJSONMacroExpander(funcName))
- } else {
- return nil, fmt.Errorf("unsupported matcher data type: %s", cel.FormatType(matcherDataType))
+ default:
+ return nil, fmt.Errorf("unsupported matcher data type: %s", matcherDataType)
}
case 2:
- if isCELStringType(matcherDataTypes[0]) && isCELStringType(matcherDataTypes[1]) {
+ if matcherDataTypes[0] == cel.StringType && matcherDataTypes[1] == cel.StringType {
macro = parser.NewGlobalMacro(macroName, 2, celMatcherStringListMacroExpander(funcName))
- matcherDataTypes = []*exprpb.Type{CelTypeListString}
+ matcherDataTypes = []*cel.Type{cel.ListType(cel.StringType)}
} else {
- return nil, fmt.Errorf(
- "unsupported matcher data type: %s, %s",
- cel.FormatType(matcherDataTypes[0]), cel.FormatType(matcherDataTypes[1]),
- )
+ return nil, fmt.Errorf("unsupported matcher data type: %s, %s", matcherDataTypes[0], matcherDataTypes[1])
}
case 3:
- if isCELStringType(matcherDataTypes[0]) && isCELStringType(matcherDataTypes[1]) && isCELStringType(matcherDataTypes[2]) {
+ if matcherDataTypes[0] == cel.StringType && matcherDataTypes[1] == cel.StringType && matcherDataTypes[2] == cel.StringType {
macro = parser.NewGlobalMacro(macroName, 3, celMatcherStringListMacroExpander(funcName))
- matcherDataTypes = []*exprpb.Type{CelTypeListString}
+ matcherDataTypes = []*cel.Type{cel.ListType(cel.StringType)}
} else {
- return nil, fmt.Errorf(
- "unsupported matcher data type: %s, %s, %s",
- cel.FormatType(matcherDataTypes[0]), cel.FormatType(matcherDataTypes[1]), cel.FormatType(matcherDataTypes[2]),
- )
+ return nil, fmt.Errorf("unsupported matcher data type: %s, %s, %s", matcherDataTypes[0], matcherDataTypes[1], matcherDataTypes[2])
}
}
envOptions := []cel.EnvOption{
cel.Macros(macro),
- cel.Declarations(
- decls.NewFunction(funcName,
- decls.NewOverload(
- funcName,
- append([]*exprpb.Type{requestType}, matcherDataTypes...),
- decls.Bool,
- ),
- ),
- ),
+ cel.Function(funcName,
+ cel.Overload(funcName, append([]*cel.Type{requestType}, matcherDataTypes...), cel.BoolType),
+
+ cel.SingletonBinaryImpl(CELMatcherRuntimeFunction(funcName, fac))),
}
programOptions := []cel.ProgramOption{
cel.CustomDecorator(CELMatcherDecorator(funcName, fac)),
- cel.Functions(
- &functions.Overload{
- Operator: funcName,
- Binary: CELMatcherRuntimeFunction(funcName, fac),
- },
- ),
}
return NewMatcherCELLibrary(envOptions, programOptions), nil
}
@@ -610,25 +583,6 @@ func CELValueToMapStrList(data ref.Val) (map[string][]string, error) {
return mapStrListStr, nil
}
-// isCELJSONType returns whether the type corresponds to JSON input.
-func isCELJSONType(t *exprpb.Type) bool {
- switch t.GetTypeKind().(type) {
- case *exprpb.Type_MapType_:
- mapType := t.GetMapType()
- return isCELStringType(mapType.GetKeyType()) && mapType.GetValueType().GetDyn() != nil
- }
- return false
-}
-
-// isCELStringType returns whether the type corresponds to a string.
-func isCELStringType(t *exprpb.Type) bool {
- switch t.GetTypeKind().(type) {
- case *exprpb.Type_Primitive:
- return t.GetPrimitive() == exprpb.Type_STRING
- }
- return false
-}
-
// isCELStringExpr indicates whether the expression is a supported string expression
func isCELStringExpr(e *exprpb.Expr) bool {
return isCELStringLiteral(e) || isCELCaddyPlaceholderCall(e) || isCELConcatCall(e)
@@ -681,15 +635,6 @@ func isCELConcatCall(e *exprpb.Expr) bool {
return false
}
-// isCELStringListType returns whether the type corresponds to a list of strings.
-func isCELStringListType(t *exprpb.Type) bool {
- switch t.GetTypeKind().(type) {
- case *exprpb.Type_ListType_:
- return isCELStringType(t.GetListType().GetElemType())
- }
- return false
-}
-
// isCELStringListLiteral returns whether the expression resolves to a list literal
// containing only string constants or a placeholder call.
func isCELStringListLiteral(e *exprpb.Expr) bool {
@@ -713,11 +658,10 @@ var (
placeholderRegexp = regexp.MustCompile(`{([a-zA-Z][\w.-]+)}`)
placeholderExpansion = `caddyPlaceholder(request, "${1}")`
- CelTypeListString = decls.NewListType(decls.String)
- CelTypeJson = decls.NewMapType(decls.String, decls.Dyn)
+ CELTypeJSON = cel.MapType(cel.StringType, cel.DynType)
)
-var httpRequestObjectType = decls.NewObjectType("http.Request")
+var httpRequestObjectType = cel.ObjectType("http.Request")
// The name of the CEL function which accesses Replacer values.
const placeholderFuncName = "caddyPlaceholder"
diff --git a/modules/caddyhttp/fileserver/matcher.go b/modules/caddyhttp/fileserver/matcher.go
index 4f3ffef..7ed9343 100644
--- a/modules/caddyhttp/fileserver/matcher.go
+++ b/modules/caddyhttp/fileserver/matcher.go
@@ -27,7 +27,6 @@ import (
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
"github.com/google/cel-go/cel"
- "github.com/google/cel-go/checker/decls"
"github.com/google/cel-go/common"
"github.com/google/cel-go/common/operators"
"github.com/google/cel-go/common/types/ref"
@@ -153,17 +152,10 @@ func (m *MatchFile) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
// Example:
// expression file({'root': '/srv', 'try_files': [{http.request.uri.path}, '/index.php'], 'try_policy': 'first_exist', 'split_path': ['.php']})
func (MatchFile) CELLibrary(ctx caddy.Context) (cel.Library, error) {
- requestType := decls.NewObjectType("http.Request")
+ requestType := cel.ObjectType("http.Request")
envOptions := []cel.EnvOption{
cel.Macros(parser.NewGlobalVarArgMacro("file", celFileMatcherMacroExpander())),
- cel.Declarations(
- decls.NewFunction("file",
- decls.NewOverload("file_request_map",
- []*exprpb.Type{requestType, caddyhttp.CelTypeJson},
- decls.Bool,
- ),
- ),
- ),
+ cel.Function("file", cel.Overload("file_request_map", []*cel.Type{requestType, caddyhttp.CELTypeJSON}, cel.BoolType)),
}
matcherFactory := func(data ref.Val) (caddyhttp.RequestMatcher, error) {
diff --git a/modules/caddyhttp/matchers.go b/modules/caddyhttp/matchers.go
index c8db22f..82972e5 100644
--- a/modules/caddyhttp/matchers.go
+++ b/modules/caddyhttp/matchers.go
@@ -33,11 +33,9 @@ import (
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
"github.com/google/cel-go/cel"
- "github.com/google/cel-go/checker/decls"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"go.uber.org/zap"
- exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
)
type (
@@ -310,7 +308,7 @@ func (MatchHost) CELLibrary(ctx caddy.Context) (cel.Library, error) {
return CELMatcherImpl(
"host",
"host_match_request_list",
- []*exprpb.Type{CelTypeListString},
+ []*cel.Type{cel.ListType(cel.StringType)},
func(data ref.Val) (RequestMatcher, error) {
refStringList := reflect.TypeOf([]string{})
strList, err := data.ConvertToNative(refStringList)
@@ -441,7 +439,7 @@ func (MatchPath) CELLibrary(ctx caddy.Context) (cel.Library, error) {
// name of the function that the macro will be rewritten to call.
"path_match_request_list",
// internal data type of the MatchPath value.
- []*exprpb.Type{CelTypeListString},
+ []*cel.Type{cel.ListType(cel.StringType)},
// function to convert a constant list of strings to a MatchPath instance.
func(data ref.Val) (RequestMatcher, error) {
refStringList := reflect.TypeOf([]string{})
@@ -509,7 +507,7 @@ func (MatchPathRE) CELLibrary(ctx caddy.Context) (cel.Library, error) {
unnamedPattern, err := CELMatcherImpl(
"path_regexp",
"path_regexp_request_string",
- []*exprpb.Type{decls.String},
+ []*cel.Type{cel.StringType},
func(data ref.Val) (RequestMatcher, error) {
pattern := data.(types.String)
matcher := MatchPathRE{MatchRegexp{Pattern: string(pattern)}}
@@ -523,7 +521,7 @@ func (MatchPathRE) CELLibrary(ctx caddy.Context) (cel.Library, error) {
namedPattern, err := CELMatcherImpl(
"path_regexp",
"path_regexp_request_string_string",
- []*exprpb.Type{decls.String, decls.String},
+ []*cel.Type{cel.StringType, cel.StringType},
func(data ref.Val) (RequestMatcher, error) {
refStringList := reflect.TypeOf([]string{})
params, err := data.ConvertToNative(refStringList)
@@ -582,7 +580,7 @@ func (MatchMethod) CELLibrary(_ caddy.Context) (cel.Library, error) {
return CELMatcherImpl(
"method",
"method_request_list",
- []*exprpb.Type{CelTypeListString},
+ []*cel.Type{cel.ListType(cel.StringType)},
func(data ref.Val) (RequestMatcher, error) {
refStringList := reflect.TypeOf([]string{})
strList, err := data.ConvertToNative(refStringList)
@@ -668,7 +666,7 @@ func (MatchQuery) CELLibrary(_ caddy.Context) (cel.Library, error) {
return CELMatcherImpl(
"query",
"query_matcher_request_map",
- []*exprpb.Type{CelTypeJson},
+ []*cel.Type{CELTypeJSON},
func(data ref.Val) (RequestMatcher, error) {
mapStrListStr, err := CELValueToMapStrList(data)
if err != nil {
@@ -744,7 +742,7 @@ func (MatchHeader) CELLibrary(_ caddy.Context) (cel.Library, error) {
return CELMatcherImpl(
"header",
"header_matcher_request_map",
- []*exprpb.Type{CelTypeJson},
+ []*cel.Type{CELTypeJSON},
func(data ref.Val) (RequestMatcher, error) {
mapStrListStr, err := CELValueToMapStrList(data)
if err != nil {
@@ -901,7 +899,7 @@ func (MatchHeaderRE) CELLibrary(ctx caddy.Context) (cel.Library, error) {
unnamedPattern, err := CELMatcherImpl(
"header_regexp",
"header_regexp_request_string_string",
- []*exprpb.Type{decls.String, decls.String},
+ []*cel.Type{cel.StringType, cel.StringType},
func(data ref.Val) (RequestMatcher, error) {
refStringList := reflect.TypeOf([]string{})
params, err := data.ConvertToNative(refStringList)
@@ -921,7 +919,7 @@ func (MatchHeaderRE) CELLibrary(ctx caddy.Context) (cel.Library, error) {
namedPattern, err := CELMatcherImpl(
"header_regexp",
"header_regexp_request_string_string_string",
- []*exprpb.Type{decls.String, decls.String, decls.String},
+ []*cel.Type{cel.StringType, cel.StringType, cel.StringType},
func(data ref.Val) (RequestMatcher, error) {
refStringList := reflect.TypeOf([]string{})
params, err := data.ConvertToNative(refStringList)
@@ -985,7 +983,7 @@ func (MatchProtocol) CELLibrary(_ caddy.Context) (cel.Library, error) {
return CELMatcherImpl(
"protocol",
"protocol_request_string",
- []*exprpb.Type{decls.String},
+ []*cel.Type{cel.StringType},
func(data ref.Val) (RequestMatcher, error) {
protocolStr, ok := data.(types.String)
if !ok {
@@ -1107,7 +1105,7 @@ func (MatchRemoteIP) CELLibrary(ctx caddy.Context) (cel.Library, error) {
// name of the function that the macro will be rewritten to call.
"remote_ip_match_request_list",
// internal data type of the MatchPath value.
- []*exprpb.Type{CelTypeListString},
+ []*cel.Type{cel.ListType(cel.StringType)},
// function to convert a constant list of strings to a MatchPath instance.
func(data ref.Val) (RequestMatcher, error) {
refStringList := reflect.TypeOf([]string{})