mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2026-02-26 16:57:08 +00:00
100 lines
2.3 KiB
Go
100 lines
2.3 KiB
Go
package route
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/metacubex/mihomo/constant"
|
|
"github.com/metacubex/mihomo/tunnel"
|
|
|
|
"github.com/metacubex/chi"
|
|
"github.com/metacubex/chi/render"
|
|
"github.com/metacubex/http"
|
|
)
|
|
|
|
func ruleRouter() http.Handler {
|
|
r := chi.NewRouter()
|
|
r.Get("/", getRules)
|
|
if !embedMode { // disallow update/patch rules in embed mode
|
|
r.Patch("/disable", disableRules)
|
|
}
|
|
return r
|
|
}
|
|
|
|
type Rule struct {
|
|
Index int `json:"index"`
|
|
Type string `json:"type"`
|
|
Payload string `json:"payload"`
|
|
Proxy string `json:"proxy"`
|
|
Size int `json:"size"`
|
|
|
|
// Extra contains information from RuleWrapper
|
|
Extra *RuleExtra `json:"extra,omitempty"`
|
|
}
|
|
|
|
type RuleExtra struct {
|
|
Disabled bool `json:"disabled"`
|
|
HitCount uint64 `json:"hitCount"`
|
|
HitAt time.Time `json:"hitAt"`
|
|
MissCount uint64 `json:"missCount"`
|
|
MissAt time.Time `json:"missAt"`
|
|
}
|
|
|
|
func getRules(w http.ResponseWriter, r *http.Request) {
|
|
rawRules := tunnel.Rules()
|
|
rules := make([]Rule, 0, len(rawRules))
|
|
for index, rule := range rawRules {
|
|
r := Rule{
|
|
Index: index,
|
|
Type: rule.RuleType().String(),
|
|
Payload: rule.Payload(),
|
|
Proxy: rule.Adapter(),
|
|
Size: -1,
|
|
}
|
|
if ruleWrapper, ok := rule.(constant.RuleWrapper); ok {
|
|
r.Extra = &RuleExtra{
|
|
Disabled: ruleWrapper.IsDisabled(),
|
|
HitCount: ruleWrapper.HitCount(),
|
|
HitAt: ruleWrapper.HitAt(),
|
|
MissCount: ruleWrapper.MissCount(),
|
|
MissAt: ruleWrapper.MissAt(),
|
|
}
|
|
rule = ruleWrapper.Unwrap() // unwrap RuleWrapper
|
|
}
|
|
if rule.RuleType() == constant.GEOIP || rule.RuleType() == constant.GEOSITE {
|
|
r.Size = rule.(constant.RuleGroup).GetRecodeSize()
|
|
}
|
|
rules = append(rules, r)
|
|
|
|
}
|
|
|
|
render.JSON(w, r, render.M{
|
|
"rules": rules,
|
|
})
|
|
}
|
|
|
|
// disableRules disable or enable rules by their indexes.
|
|
func disableRules(w http.ResponseWriter, r *http.Request) {
|
|
// key: rule index, value: disabled
|
|
var payload map[int]bool
|
|
if err := render.DecodeJSON(r.Body, &payload); err != nil {
|
|
render.Status(r, http.StatusBadRequest)
|
|
render.JSON(w, r, ErrBadRequest)
|
|
return
|
|
}
|
|
|
|
if len(payload) != 0 {
|
|
rules := tunnel.Rules()
|
|
for index, disabled := range payload {
|
|
if index < 0 || index >= len(rules) {
|
|
continue
|
|
}
|
|
rule := rules[index]
|
|
if ruleWrapper, ok := rule.(constant.RuleWrapper); ok {
|
|
ruleWrapper.SetDisabled(disabled)
|
|
}
|
|
}
|
|
}
|
|
|
|
render.NoContent(w, r)
|
|
}
|