expr.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package expr
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "net/http"
  7. "regexp"
  8. "github.com/AlexxIT/go2rtc/pkg/tcp"
  9. "github.com/expr-lang/expr"
  10. )
  11. func newRequest(method, url string, headers map[string]any) (*http.Request, error) {
  12. if method == "" {
  13. method = "GET"
  14. }
  15. req, err := http.NewRequest(method, url, nil)
  16. if err != nil {
  17. return nil, err
  18. }
  19. for k, v := range headers {
  20. req.Header.Set(k, fmt.Sprintf("%v", v))
  21. }
  22. return req, nil
  23. }
  24. func regExp(params ...any) (*regexp.Regexp, error) {
  25. exp := params[0].(string)
  26. if len(params) >= 2 {
  27. // support:
  28. // i case-insensitive (default false)
  29. // m multi-line mode: ^ and $ match begin/end line (default false)
  30. // s let . match \n (default false)
  31. // https://pkg.go.dev/regexp/syntax
  32. flags := params[1].(string)
  33. exp = "(?" + flags + ")" + exp
  34. }
  35. return regexp.Compile(exp)
  36. }
  37. var Options = []expr.Option{
  38. expr.Function(
  39. "fetch",
  40. func(params ...any) (any, error) {
  41. var req *http.Request
  42. var err error
  43. url := params[0].(string)
  44. if len(params) == 2 {
  45. options := params[1].(map[string]any)
  46. method, _ := options["method"].(string)
  47. headers, _ := options["headers"].(map[string]any)
  48. req, err = newRequest(method, url, headers)
  49. } else {
  50. req, err = http.NewRequest("GET", url, nil)
  51. }
  52. if err != nil {
  53. return nil, err
  54. }
  55. res, err := tcp.Do(req)
  56. if err != nil {
  57. return nil, err
  58. }
  59. b, _ := io.ReadAll(res.Body)
  60. return map[string]any{
  61. "ok": res.StatusCode < 400,
  62. "status": res.Status,
  63. "text": string(b),
  64. "json": func() (v any) {
  65. _ = json.Unmarshal(b, &v)
  66. return
  67. },
  68. }, nil
  69. },
  70. //new(func(url string) map[string]any),
  71. //new(func(url string, options map[string]any) map[string]any),
  72. ),
  73. expr.Function(
  74. "match",
  75. func(params ...any) (any, error) {
  76. re, err := regExp(params[1:]...)
  77. if err != nil {
  78. return nil, err
  79. }
  80. str := params[0].(string)
  81. return re.FindStringSubmatch(str), nil
  82. },
  83. //new(func(str, expr string) []string),
  84. //new(func(str, expr, flags string) []string),
  85. ),
  86. expr.Function(
  87. "RegExp",
  88. func(params ...any) (any, error) {
  89. return regExp(params)
  90. },
  91. ),
  92. }
  93. func Run(input string) (any, error) {
  94. program, err := expr.Compile(input, Options...)
  95. if err != nil {
  96. return nil, err
  97. }
  98. return expr.Run(program, nil)
  99. }