github.com/igoogolx/clash@v1.19.8/adapter/provider/parser.go (about)

     1  package provider
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/igoogolx/clash/common/structure"
     9  	C "github.com/igoogolx/clash/constant"
    10  	types "github.com/igoogolx/clash/constant/provider"
    11  )
    12  
    13  var (
    14  	errVehicleType = errors.New("unsupport vehicle type")
    15  	errSubPath     = errors.New("path is not subpath of home directory")
    16  )
    17  
    18  type healthCheckSchema struct {
    19  	Enable   bool   `provider:"enable"`
    20  	URL      string `provider:"url"`
    21  	Interval int    `provider:"interval"`
    22  	Lazy     bool   `provider:"lazy,omitempty"`
    23  }
    24  
    25  type proxyProviderSchema struct {
    26  	Type        string            `provider:"type"`
    27  	Path        string            `provider:"path"`
    28  	URL         string            `provider:"url,omitempty"`
    29  	Interval    int               `provider:"interval,omitempty"`
    30  	Filter      string            `provider:"filter,omitempty"`
    31  	HealthCheck healthCheckSchema `provider:"health-check,omitempty"`
    32  }
    33  
    34  func ParseProxyProvider(name string, mapping map[string]any) (types.ProxyProvider, error) {
    35  	decoder := structure.NewDecoder(structure.Option{TagName: "provider", WeaklyTypedInput: true})
    36  
    37  	schema := &proxyProviderSchema{
    38  		HealthCheck: healthCheckSchema{
    39  			Lazy: true,
    40  		},
    41  	}
    42  	if err := decoder.Decode(mapping, schema); err != nil {
    43  		return nil, err
    44  	}
    45  
    46  	var hcInterval uint
    47  	if schema.HealthCheck.Enable {
    48  		hcInterval = uint(schema.HealthCheck.Interval)
    49  	}
    50  	hc := NewHealthCheck([]C.Proxy{}, schema.HealthCheck.URL, hcInterval, schema.HealthCheck.Lazy)
    51  
    52  	path := C.Path.Resolve(schema.Path)
    53  
    54  	var vehicle types.Vehicle
    55  	switch schema.Type {
    56  	case "file":
    57  		vehicle = NewFileVehicle(path)
    58  	case "http":
    59  		if !C.Path.IsSubPath(path) {
    60  			return nil, fmt.Errorf("%w: %s", errSubPath, path)
    61  		}
    62  		vehicle = NewHTTPVehicle(schema.URL, path)
    63  	default:
    64  		return nil, fmt.Errorf("%w: %s", errVehicleType, schema.Type)
    65  	}
    66  
    67  	interval := time.Duration(uint(schema.Interval)) * time.Second
    68  	filter := schema.Filter
    69  	return NewProxySetProvider(name, interval, filter, vehicle, hc)
    70  }