func (m *MatchExpression) Provision(ctx caddy.Context) error {
	m.log = ctx.Logger(m)

	// replace placeholders with a function call - this is just some
	// light (and possibly naïve) syntactic sugar
	m.expandedExpr = placeholderRegexp.ReplaceAllString(m.Expr, placeholderExpansion)

	// our type adapter expands CEL's standard type support
	m.ta = celTypeAdapter{}

	// initialize the CEL libraries from the Matcher implementations which
	// have been configured to support CEL.
	matcherLibProducers := []CELLibraryProducer{}
	for _, info := range caddy.GetModules("http.matchers") {
		p, ok := info.New().(CELLibraryProducer)
		if ok {
			matcherLibProducers = append(matcherLibProducers, p)
		}
	}
	// Assemble the compilation and program options from the different library
	// producers into a single cel.Library implementation.
	matcherEnvOpts := []cel.EnvOption{}
	matcherProgramOpts := []cel.ProgramOption{}
	for _, producer := range matcherLibProducers {
		l, err := producer.CELLibrary(ctx)
		if err != nil {
			return fmt.Errorf("error initializing CEL library for %T: %v", producer, err)
		}
		matcherEnvOpts = append(matcherEnvOpts, l.CompileOptions()...)
		matcherProgramOpts = append(matcherProgramOpts, l.ProgramOptions()...)
	}
	matcherLib := cel.Lib(NewMatcherCELLibrary(matcherEnvOpts, matcherProgramOpts))

	// 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.CustomTypeAdapter(m.ta),
		ext.Strings(),
		matcherLib,
	)
	if err != nil {
		return fmt.Errorf("setting up CEL environment: %v", err)
	}

	// parse and type-check the expression
	checked, issues := env.Compile(m.expandedExpr)
	if issues.Err() != nil {
		return fmt.Errorf("compiling CEL program: %s", issues.Err())
	}

	// 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())
	}

	// compile the "program"
	m.prg, err = env.Program(checked,
		cel.EvalOptions(cel.OptOptimize),
		cel.Functions(
			&functions.Overload{
				Operator: placeholderFuncName,
				Binary:   m.caddyPlaceholderFunc,
			},
		),
	)
	if err != nil {
		return fmt.Errorf("compiling CEL program: %s", err)
	}
	return nil
}
// Provision sets ups m.
Provision sets ups m.
// Provision sets ups m .
func (m *MatchExpression) Provision(ctx caddy.Context) error {
	m.log = ctx.Logger(m)
	m.expandedExpr = placeholderRegexp.ReplaceAllString(m.Expr, placeholderExpansion)
	m.ta = celTypeAdapter{}
	matcherLibProducers := []CELLibraryProducer{}
	for _, info := range caddy.GetModules("http.matchers") {
		p, ok := info.New().(CELLibraryProducer)
		if ok {
			matcherLibProducers = append(matcherLibProducers, p)
		}
	}
	matcherEnvOpts := []cel.EnvOption{}
	matcherProgramOpts := []cel.ProgramOption{}
	for _, producer := range matcherLibProducers {
		l, err := producer.CELLibrary(ctx)
		if err != nil {
			return fmt.Errorf("error initializing CEL library for %T: %v", producer, err)
		}
		matcherEnvOpts = append(matcherEnvOpts, l.CompileOptions()...)
		matcherProgramOpts = append(matcherProgramOpts, l.ProgramOptions()...)
	}
	matcherLib := cel.Lib(NewMatcherCELLibrary(matcherEnvOpts, matcherProgramOpts))
	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.CustomTypeAdapter(m.ta),
		ext.Strings(),
		matcherLib,
	)
	if err != nil {
		return fmt.Errorf("setting up CEL environment: %v", err)
	}
	checked, issues := env.Compile(m.expandedExpr)
	if issues.Err() != nil {
		return fmt.Errorf("compiling CEL program: %s", issues.Err())
	}
	if !proto.Equal(checked.ResultType(), decls.Bool) {
		return fmt.Errorf("CEL request matcher expects return type of bool, not %s", checked.ResultType())
	}
	m.prg, err = env.Program(checked,
		cel.EvalOptions(cel.OptOptimize),
		cel.Functions(
			&functions.Overload{
				Operator: placeholderFuncName,
				Binary:   m.caddyPlaceholderFunc,
			},
		),
	)
	if err != nil {
		return fmt.Errorf("compiling CEL program: %s", err)
	}
	return nil
}
func ( m * MatchExpression ) Provision ( ctx caddy . Context ) error { m . log = ctx . Logger ( m ) m . expandedExpr = placeholderRegexp . ReplaceAllString ( m . Expr , placeholderExpansion ) m . ta = celTypeAdapter { } matcherLibProducers := [ ] CELLibraryProducer { } for _ , info := range caddy . GetModules ( " " ) { p , ok := info . New ( ) . ( CELLibraryProducer ) if ok { matcherLibProducers = append ( matcherLibProducers , p ) } } matcherEnvOpts := [ ] cel . EnvOption { } matcherProgramOpts := [ ] cel . ProgramOption { } for _ , producer := range matcherLibProducers { l , err := producer . CELLibrary ( ctx ) if err != nil { return fmt . Errorf ( " " , producer , err ) } matcherEnvOpts = append ( matcherEnvOpts , l . CompileOptions ( ) ... ) matcherProgramOpts = append ( matcherProgramOpts , l . ProgramOptions ( ) ... ) } matcherLib := cel . Lib ( NewMatcherCELLibrary ( matcherEnvOpts , matcherProgramOpts ) ) env , err := cel . NewEnv ( cel . Declarations ( decls . NewVar ( " " , httpRequestObjectType ) , decls . NewFunction ( placeholderFuncName , decls . NewOverload ( placeholderFuncName + " " , [ ] * exprpb . Type { httpRequestObjectType , decls . String } , decls . Any ) ) , ) , cel . CustomTypeAdapter ( m . ta ) , ext . Strings ( ) , matcherLib , ) if err != nil { return fmt . Errorf ( " " , err ) } checked , issues := env . Compile ( m . expandedExpr ) if issues . Err ( ) != nil { return fmt . Errorf ( " " , issues . Err ( ) ) } if ! proto . Equal ( checked . ResultType ( ) , decls . Bool ) { return fmt . Errorf ( " " , checked . ResultType ( ) ) } m . prg , err = env . Program ( checked , cel . EvalOptions ( cel . OptOptimize ) , cel . Functions ( & functions . Overload { Operator : placeholderFuncName , Binary : m . caddyPlaceholderFunc , } , ) , ) if err != nil { return fmt . Errorf ( " " , err ) } return nil }
Provision sets ups m.
Provision sets ups m .
// replace placeholders with a function call - this is just some // light (and possibly naïve) syntactic sugar // our type adapter expands CEL's standard type support // initialize the CEL libraries from the Matcher implementations which // have been configured to support CEL. // Assemble the compilation and program options from the different library // producers into a single cel.Library implementation. // create the CEL environment // parse and type-check the expression // request matching is a boolean operation, so we don't really know // what to do if the expression returns a non-boolean type // compile the "program"