checker.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // Package checker defines the Checker interface and a helper utility to avoid import cycles.
  2. package checker
  3. import (
  4. "fmt"
  5. "net/http"
  6. "strings"
  7. "github.com/TecharoHQ/anubis/internal"
  8. )
  9. type Impl interface {
  10. Check(*http.Request) (bool, error)
  11. Hash() string
  12. }
  13. type Func func(*http.Request) (bool, error)
  14. func (f Func) Check(r *http.Request) (bool, error) {
  15. return f(r)
  16. }
  17. func (f Func) Hash() string { return internal.FastHash(fmt.Sprintf("%#v", f)) }
  18. type List []Impl
  19. // Check runs each checker in the list against the request.
  20. // It returns true only if *all* checkers return true (AND semantics).
  21. // If any checker returns an error, the function returns false and the error.
  22. func (l List) Check(r *http.Request) (bool, error) {
  23. for _, c := range l {
  24. ok, err := c.Check(r)
  25. if err != nil {
  26. // Propagate the error; overall result is false.
  27. return false, err
  28. }
  29. if !ok {
  30. // One false means the combined result is false. Short-circuit
  31. // so we don't waste time.
  32. return false, err
  33. }
  34. }
  35. // Assume success until a checker says otherwise.
  36. return true, nil
  37. }
  38. func (l List) Hash() string {
  39. var sb strings.Builder
  40. for _, c := range l {
  41. fmt.Fprintln(&sb, c.Hash())
  42. }
  43. return internal.FastHash(sb.String())
  44. }