MCPcopy
hub / github.com/caddyserver/caddy / CELMatcherDecorator

Function CELMatcherDecorator

modules/caddyhttp/celmatcher.go:469–550  ·  view source on GitHub ↗

CELMatcherDecorator matches a call overload generated by a CEL macro that takes a single argument, and optimizes the implementation to precompile the matcher and return a function that references the precompiled and provisioned matcher.

(funcName string, fac any)

Source from the content-addressed store, hash-verified

467// the matcher and return a function that references the precompiled and
468// provisioned matcher.
469func CELMatcherDecorator(funcName string, fac any) interpreter.InterpretableDecorator {
470 return func(i interpreter.Interpretable) (interpreter.Interpretable, error) {
471 call, ok := i.(interpreter.InterpretableCall)
472 if !ok {
473 return i, nil
474 }
475 if call.OverloadID() != funcName {
476 return i, nil
477 }
478 callArgs := call.Args()
479 reqAttr, ok := callArgs[0].(interpreter.InterpretableAttribute)
480 if !ok {
481 return nil, errors.New("missing 'req' argument")
482 }
483 nsAttr, ok := reqAttr.Attr().(interpreter.NamespacedAttribute)
484 if !ok {
485 return nil, errors.New("missing 'req' argument")
486 }
487 varNames := nsAttr.CandidateVariableNames()
488 if len(varNames) != 1 || len(varNames) == 1 && varNames[0] != CELRequestVarName {
489 return nil, errors.New("missing 'req' argument")
490 }
491 matcherData, ok := callArgs[1].(interpreter.InterpretableConst)
492 if !ok {
493 // If the matcher arguments are not constant, then this means
494 // they contain a Caddy placeholder reference and the evaluation
495 // and matcher provisioning should be handled at dynamically.
496 return i, nil
497 }
498
499 if factory, ok := fac.(CELMatcherWithErrorFactory); ok {
500 matcher, err := factory(matcherData.Value())
501 if err != nil {
502 return nil, err
503 }
504 return interpreter.NewCall(
505 i.ID(), funcName, funcName+"_opt",
506 []interpreter.Interpretable{reqAttr},
507 func(args ...ref.Val) ref.Val {
508 // The request value, guaranteed to be of type celHTTPRequest
509 celReq := args[0]
510 // If needed this call could be changed to convert the value
511 // to a *http.Request using CEL's ConvertToNative method.
512 httpReq := celReq.Value().(celHTTPRequest)
513 match, err := matcher.MatchWithError(httpReq.Request)
514 if err != nil {
515 return types.WrapErr(err)
516 }
517 return types.Bool(match)
518 },
519 ), nil
520 }
521
522 if factory, ok := fac.(CELMatcherFactory); ok {
523 matcher, err := factory(matcherData.Value())
524 if err != nil {
525 return nil, err
526 }

Callers 2

CELLibraryMethod · 0.92
CELMatcherImplFunction · 0.85

Calls 7

ArgsMethod · 0.80
IDMethod · 0.80
WrapErrMethod · 0.80
MatchWithErrorMethod · 0.65
MatchMethod · 0.65
ValueMethod · 0.45
BoolMethod · 0.45

Tested by

no test coverage detected