2022-03-31 15:12:54 +02:00
|
|
|
package filter
|
2022-03-31 14:53:40 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2025-02-05 21:54:59 +01:00
|
|
|
|
|
|
|
"github.com/dstotijn/hetty/pkg/http"
|
2022-03-31 14:53:40 +02:00
|
|
|
)
|
|
|
|
|
2025-02-05 21:54:59 +01:00
|
|
|
func MatchHTTPHeaders(op TokenType, expr Expression, headers []*http.Header) (bool, error) {
|
2022-03-31 14:53:40 +02:00
|
|
|
if headers == nil {
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
switch op {
|
|
|
|
case TokOpEq:
|
|
|
|
strLiteral, ok := expr.(StringLiteral)
|
|
|
|
if !ok {
|
2022-03-31 15:12:54 +02:00
|
|
|
return false, errors.New("filter: expression must be a string literal")
|
2022-03-31 14:53:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return `true` if at least one header (<key>: <value>) is equal to the string literal.
|
2025-02-05 21:54:59 +01:00
|
|
|
for _, header := range headers {
|
|
|
|
if strLiteral.Value == fmt.Sprintf("%v: %v", header.Key, header.Value) {
|
|
|
|
return true, nil
|
2022-03-31 14:53:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false, nil
|
|
|
|
case TokOpNotEq:
|
|
|
|
strLiteral, ok := expr.(StringLiteral)
|
|
|
|
if !ok {
|
2022-03-31 15:12:54 +02:00
|
|
|
return false, errors.New("filter: expression must be a string literal")
|
2022-03-31 14:53:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return `true` if none of the headers (<key>: <value>) are equal to the string literal.
|
2025-02-05 21:54:59 +01:00
|
|
|
for _, header := range headers {
|
|
|
|
if strLiteral.Value == fmt.Sprintf("%v: %v", header.Key, header.Value) {
|
|
|
|
return false, nil
|
2022-03-31 14:53:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true, nil
|
|
|
|
case TokOpRe:
|
|
|
|
re, ok := expr.(RegexpLiteral)
|
|
|
|
if !ok {
|
2022-03-31 15:12:54 +02:00
|
|
|
return false, errors.New("filter: expression must be a regular expression")
|
2022-03-31 14:53:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return `true` if at least one header (<key>: <value>) matches the regular expression.
|
2025-02-05 21:54:59 +01:00
|
|
|
for _, header := range headers {
|
|
|
|
if re.Regexp.MatchString(fmt.Sprintf("%v: %v", header.Key, header.Value)) {
|
|
|
|
return true, nil
|
2022-03-31 14:53:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false, nil
|
|
|
|
case TokOpNotRe:
|
|
|
|
re, ok := expr.(RegexpLiteral)
|
|
|
|
if !ok {
|
2022-03-31 15:12:54 +02:00
|
|
|
return false, errors.New("filter: expression must be a regular expression")
|
2022-03-31 14:53:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return `true` if none of the headers (<key>: <value>) match the regular expression.
|
2025-02-05 21:54:59 +01:00
|
|
|
for _, header := range headers {
|
|
|
|
if re.Regexp.MatchString(fmt.Sprintf("%v: %v", header.Key, header.Value)) {
|
|
|
|
return false, nil
|
2022-03-31 14:53:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true, nil
|
|
|
|
default:
|
2022-03-31 15:12:54 +02:00
|
|
|
return false, fmt.Errorf("filter: unsupported operator %q", op.String())
|
2022-03-31 14:53:40 +02:00
|
|
|
}
|
|
|
|
}
|