parse.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package provider
  2. import (
  3. "errors"
  4. "fmt"
  5. "time"
  6. "github.com/metacubex/mihomo/common/structure"
  7. "github.com/metacubex/mihomo/component/resource"
  8. C "github.com/metacubex/mihomo/constant"
  9. P "github.com/metacubex/mihomo/constant/provider"
  10. )
  11. var (
  12. errSubPath = errors.New("path is not subpath of home directory")
  13. )
  14. type ruleProviderSchema struct {
  15. Type string `provider:"type"`
  16. Behavior string `provider:"behavior"`
  17. Path string `provider:"path,omitempty"`
  18. URL string `provider:"url,omitempty"`
  19. Proxy string `provider:"proxy,omitempty"`
  20. Format string `provider:"format,omitempty"`
  21. Interval int `provider:"interval,omitempty"`
  22. }
  23. func ParseRuleProvider(name string, mapping map[string]interface{}, parse func(tp, payload, target string, params []string, subRules map[string][]C.Rule) (parsed C.Rule, parseErr error)) (P.RuleProvider, error) {
  24. schema := &ruleProviderSchema{}
  25. decoder := structure.NewDecoder(structure.Option{TagName: "provider", WeaklyTypedInput: true})
  26. if err := decoder.Decode(mapping, schema); err != nil {
  27. return nil, err
  28. }
  29. behavior, err := P.ParseBehavior(schema.Behavior)
  30. if err != nil {
  31. return nil, err
  32. }
  33. format, err := P.ParseRuleFormat(schema.Format)
  34. if err != nil {
  35. return nil, err
  36. }
  37. var vehicle P.Vehicle
  38. switch schema.Type {
  39. case "file":
  40. path := C.Path.Resolve(schema.Path)
  41. vehicle = resource.NewFileVehicle(path)
  42. case "http":
  43. path := C.Path.GetPathByHash("rules", schema.URL)
  44. if schema.Path != "" {
  45. path = C.Path.Resolve(schema.Path)
  46. if !C.Path.IsSafePath(path) {
  47. return nil, fmt.Errorf("%w: %s", errSubPath, path)
  48. }
  49. }
  50. vehicle = resource.NewHTTPVehicle(schema.URL, path, schema.Proxy, nil)
  51. default:
  52. return nil, fmt.Errorf("unsupported vehicle type: %s", schema.Type)
  53. }
  54. return NewRuleSetProvider(name, behavior, format, time.Duration(uint(schema.Interval))*time.Second, vehicle, parse), nil
  55. }