github.com/yaling888/clash@v1.53.0/component/script/expr_builtin.go (about)

     1  package script
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/expr-lang/expr/ast"
     7  
     8  	C "github.com/yaling888/clash/constant"
     9  )
    10  
    11  type (
    12  	scStringFunc          = func(string) string
    13  	scStringBoolFunc      = func(string) (bool, error)
    14  	scEmptyFunc           = func() string
    15  	scStringStringFunc    = func(string, string) bool
    16  	scStringStringErrFunc = func(string, string) (bool, error)
    17  )
    18  
    19  type shortcutEnvironment struct {
    20  	Network      string  `expr:"network"`
    21  	Type         string  `expr:"type"`
    22  	SrcIP        string  `expr:"src_ip"`
    23  	DstIP        string  `expr:"dst_ip"`
    24  	SrcPort      uint16  `expr:"src_port"`
    25  	DstPort      uint16  `expr:"dst_port"`
    26  	InboundPort  uint16  `expr:"inbound_port"`
    27  	Host         string  `expr:"host"`
    28  	ProcessName  string  `expr:"process_name"`
    29  	ProcessPath  string  `expr:"process_path"`
    30  	UserAgent    string  `expr:"user_agent"`
    31  	SpecialProxy string  `expr:"special_proxy"`
    32  	Now          nowExpr `expr:"now"`
    33  
    34  	ResolveIP          scStringFunc          `expr:"resolve_ip"`
    35  	InCidr             scStringStringErrFunc `expr:"in_cidr"`
    36  	InIPSet            scStringStringFunc    `expr:"in_ipset"`
    37  	GeoIP              scStringFunc          `expr:"geoip"`
    38  	MatchProvider      scStringBoolFunc      `expr:"match_provider"`
    39  	ResolveProcessName scEmptyFunc           `expr:"resolve_process_name"`
    40  	ResolveProcessPath scEmptyFunc           `expr:"resolve_process_path"`
    41  }
    42  
    43  type nowExpr struct {
    44  	Year       int   `expr:"year"`
    45  	Month      int   `expr:"month"`
    46  	Day        int   `expr:"day"`
    47  	Hour       int   `expr:"hour"`
    48  	Minute     int   `expr:"minute"`
    49  	Second     int   `expr:"second"`
    50  	Nanosecond int   `expr:"nanosecond"`
    51  	Unix       int64 `expr:"unix"`
    52  	UnixNano   int64 `expr:"unix_nano"`
    53  	Weekday    int   `expr:"weekday"`
    54  }
    55  
    56  type stringInString struct{}
    57  
    58  func (*stringInString) Visit(node *ast.Node) {
    59  	switch n := (*node).(type) {
    60  	case *ast.BinaryNode:
    61  		if n.Operator == "in" {
    62  			switch n.Right.(type) {
    63  			case *ast.StringNode, *ast.IdentifierNode, *ast.CallNode:
    64  				if _, ok := n.Left.(*ast.StringNode); ok {
    65  					ast.Patch(node, &ast.BinaryNode{
    66  						Operator: "contains",
    67  						Left:     n.Right,
    68  						Right:    n.Left,
    69  					})
    70  				}
    71  			}
    72  		}
    73  	}
    74  }
    75  
    76  func parseEnv(mtd *C.Metadata, hasNow bool) shortcutEnvironment {
    77  	env := shortcutEnvironment{
    78  		Network:      mtd.NetWork.String(),
    79  		Type:         mtd.Type.String(),
    80  		SrcPort:      uint16(mtd.SrcPort),
    81  		DstPort:      uint16(mtd.DstPort),
    82  		InboundPort:  mtd.OriginDst.Port(),
    83  		Host:         mtd.Host,
    84  		ProcessName:  mtd.Process,
    85  		ProcessPath:  mtd.ProcessPath,
    86  		UserAgent:    mtd.UserAgent,
    87  		SpecialProxy: mtd.SpecialProxy,
    88  
    89  		InCidr:  uInCidr,
    90  		InIPSet: uInIPSet,
    91  		GeoIP:   uGeoIP,
    92  	}
    93  
    94  	if mtd.SrcIP.IsValid() {
    95  		env.SrcIP = mtd.SrcIP.String()
    96  	}
    97  
    98  	if mtd.DstIP.IsValid() {
    99  		env.DstIP = mtd.DstIP.String()
   100  	}
   101  
   102  	if hasNow {
   103  		env.Now = makeNowField()
   104  	}
   105  
   106  	env.ResolveIP = func(host string) string {
   107  		return uResolveIP(mtd, host)
   108  	}
   109  
   110  	env.MatchProvider = func(name string) (bool, error) {
   111  		return uMatchProvider(mtd, name)
   112  	}
   113  
   114  	env.ResolveProcessName = func() string {
   115  		uResolveProcess(mtd)
   116  		return mtd.Process
   117  	}
   118  
   119  	env.ResolveProcessPath = func() string {
   120  		uResolveProcess(mtd)
   121  		return mtd.ProcessPath
   122  	}
   123  
   124  	return env
   125  }
   126  
   127  func makeNowField() nowExpr {
   128  	t := time.Now()
   129  	return nowExpr{
   130  		Year:       t.Year(),
   131  		Month:      int(t.Month()),
   132  		Day:        t.Day(),
   133  		Hour:       t.Hour(),
   134  		Minute:     t.Minute(),
   135  		Second:     t.Second(),
   136  		Nanosecond: t.Nanosecond(),
   137  		Unix:       t.Unix(),
   138  		UnixNano:   t.UnixNano(),
   139  		Weekday:    int(t.Weekday()),
   140  	}
   141  }