mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2024-11-16 03:32:33 +08:00
chore: new rule
This commit is contained in:
parent
3fd954d185
commit
1f7a883bfc
|
@ -263,8 +263,8 @@ type RawTuicServer struct {
|
|||
}
|
||||
|
||||
type RawMitm struct {
|
||||
Port int `yaml:"port" json:"port"`
|
||||
Rules []string `yaml:"rules" json:"rules"`
|
||||
Port int `yaml:"port" json:"port"`
|
||||
Rules []rewrites.RawMitmRule `yaml:"rules" json:"rules"`
|
||||
}
|
||||
|
||||
type RawConfig struct {
|
||||
|
@ -456,7 +456,7 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
|
|||
},
|
||||
MITM: RawMitm{
|
||||
Port: 0,
|
||||
Rules: []string{},
|
||||
Rules: []rewrites.RawMitmRule{},
|
||||
},
|
||||
Profile: Profile{
|
||||
StoreSelected: true,
|
||||
|
|
|
@ -162,6 +162,8 @@ func (m *Metadata) SourceAddress() string {
|
|||
func (m *Metadata) SourceDetail() string {
|
||||
if m.Type == INNER {
|
||||
return fmt.Sprintf("%s", ClashName)
|
||||
} else if m.Type == MITM {
|
||||
return fmt.Sprintf("%s-MITM", ClashName)
|
||||
}
|
||||
|
||||
switch {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package constant
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
regexp "github.com/dlclark/regexp2"
|
||||
)
|
||||
|
||||
|
@ -37,6 +39,42 @@ const (
|
|||
|
||||
type RewriteType int
|
||||
|
||||
// UnmarshalYAML unserialize RewriteType with yaml
|
||||
func (e *RewriteType) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
var tp string
|
||||
if err := unmarshal(&tp); err != nil {
|
||||
return err
|
||||
}
|
||||
mode, exist := RewriteTypeMapping[tp]
|
||||
if !exist {
|
||||
return errors.New("invalid MITM Action")
|
||||
}
|
||||
*e = mode
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalYAML serialize RewriteType with yaml
|
||||
func (e RewriteType) MarshalYAML() (any, error) {
|
||||
return e.String(), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON unserialize RewriteType with json
|
||||
func (e *RewriteType) UnmarshalJSON(data []byte) error {
|
||||
var tp string
|
||||
json.Unmarshal(data, &tp)
|
||||
mode, exist := RewriteTypeMapping[tp]
|
||||
if !exist {
|
||||
return errors.New("invalid MITM Action")
|
||||
}
|
||||
*e = mode
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON serialize RewriteType with json
|
||||
func (e RewriteType) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(e.String())
|
||||
}
|
||||
|
||||
func (rt RewriteType) String() string {
|
||||
switch rt {
|
||||
case MitmReject:
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
@ -31,6 +32,8 @@ func (*RewriteHandler) HandleRequest(session *mitm.Session) (*http.Request, *htt
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
log.Infof("[MITM] %s <- request %s", rule.RuleType().String(), request.URL.String())
|
||||
|
||||
switch rule.RuleType() {
|
||||
case C.MitmReject:
|
||||
response = session.NewResponse(http.StatusNotFound, nil)
|
||||
|
@ -113,6 +116,8 @@ func (*RewriteHandler) HandleResponse(session *mitm.Session) *http.Response {
|
|||
return nil
|
||||
}
|
||||
|
||||
log.Infof("[MITM] %s <- response %s", rule.RuleType().String(), request.URL.String())
|
||||
|
||||
switch rule.RuleType() {
|
||||
case C.MitmResponseHeader:
|
||||
if len(response.Header) == 0 {
|
||||
|
@ -182,7 +187,7 @@ func matchRewriteRule(url string, isRequest bool) (rr C.Rewrite, sub []string, f
|
|||
if isRequest {
|
||||
found = rewrites.SearchInRequest(func(r C.Rewrite) bool {
|
||||
sub, err := r.URLRegx().FindStringMatch(url)
|
||||
if err != nil {
|
||||
if err != nil || sub == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
@ -7,12 +7,7 @@ import (
|
|||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
func ParseRewrite(line string) (C.Rewrite, error) {
|
||||
url, others, found := strings.Cut(strings.TrimSpace(line), "url")
|
||||
if !found {
|
||||
return nil, errInvalid
|
||||
}
|
||||
|
||||
func ParseRewrite(line RawMitmRule) (C.Rewrite, error) {
|
||||
var (
|
||||
urlRegx *regexp.Regexp
|
||||
ruleType *C.RewriteType
|
||||
|
@ -22,57 +17,37 @@ func ParseRewrite(line string) (C.Rewrite, error) {
|
|||
err error
|
||||
)
|
||||
|
||||
url := line.Url
|
||||
urlRegx, err = regexp.Compile(strings.Trim(url, " "), regexp.None)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
others = strings.Trim(others, " ")
|
||||
first := strings.Split(others, " ")[0]
|
||||
for k, v := range C.RewriteTypeMapping {
|
||||
if k == others {
|
||||
ruleType = &v
|
||||
ruleType = &line.Action
|
||||
switch *ruleType {
|
||||
case C.Mitm302, C.Mitm307:
|
||||
{
|
||||
rulePayload = line.New
|
||||
break
|
||||
}
|
||||
case C.MitmRequestHeader, C.MitmRequestBody, C.MitmResponseHeader, C.MitmResponseBody:
|
||||
{
|
||||
var old string
|
||||
if line.Old == nil {
|
||||
old = ".*"
|
||||
} else {
|
||||
old = *line.Old
|
||||
}
|
||||
|
||||
if k != first {
|
||||
continue
|
||||
}
|
||||
|
||||
rs := trimArr(strings.Split(others, k))
|
||||
l := len(rs)
|
||||
if l > 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
if l == 1 {
|
||||
ruleType = &v
|
||||
rulePayload = rs[0]
|
||||
break
|
||||
} else {
|
||||
ruleRegx, err = regexp.Compile(rs[0], regexp.None)
|
||||
re, err := regexp.Compile(old, regexp.Singleline)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ruleRegx = re
|
||||
|
||||
ruleType = &v
|
||||
rulePayload = rs[1]
|
||||
break
|
||||
rulePayload = line.New
|
||||
}
|
||||
}
|
||||
|
||||
if ruleType == nil {
|
||||
return nil, errInvalid
|
||||
}
|
||||
|
||||
return NewRewriteRule(urlRegx, *ruleType, ruleRegx, rulePayload), nil
|
||||
}
|
||||
|
||||
func trimArr(arr []string) (r []string) {
|
||||
for _, e := range arr {
|
||||
if s := strings.Trim(e, " "); s != "" {
|
||||
r = append(r, s)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
package rewrites
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/draw"
|
||||
"image/png"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/Dreamacro/clash/constant"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParseRewrite(t *testing.T) {
|
||||
line0 := `^https?://example\.com/resource1/3/ url reject-dict`
|
||||
line1 := `^https?://example\.com/(resource2)/ url 307 https://example.com/new-$1`
|
||||
line2 := `^https?://example\.com/resource4/ url request-header (\r\n)User-Agent:.+(\r\n) request-header $1User-Agent: Fuck-Who$2`
|
||||
line3 := `should be error`
|
||||
|
||||
c0, err0 := ParseRewrite(line0)
|
||||
c1, err1 := ParseRewrite(line1)
|
||||
c2, err2 := ParseRewrite(line2)
|
||||
_, err3 := ParseRewrite(line3)
|
||||
|
||||
assert.NotNil(t, err3)
|
||||
|
||||
assert.Nil(t, err0)
|
||||
assert.Equal(t, c0.RuleType(), constant.MitmRejectDict)
|
||||
|
||||
assert.Nil(t, err1)
|
||||
assert.Equal(t, c1.RuleType(), constant.Mitm307)
|
||||
assert.Equal(t, c1.URLRegx(), regexp.MustCompile(`^https?://example\.com/(resource2)/`))
|
||||
assert.Equal(t, c1.RulePayload(), "https://example.com/new-$1")
|
||||
|
||||
assert.Nil(t, err2)
|
||||
assert.Equal(t, c2.RuleType(), constant.MitmRequestHeader)
|
||||
assert.Equal(t, c2.RuleRegx(), regexp.MustCompile(`(\r\n)User-Agent:.+(\r\n)`))
|
||||
assert.Equal(t, c2.RulePayload(), "$1User-Agent: Fuck-Who$2")
|
||||
}
|
||||
|
||||
func Test1PxPNG(t *testing.T) {
|
||||
m := image.NewRGBA(image.Rect(0, 0, 1, 1))
|
||||
|
||||
draw.Draw(m, m.Bounds(), &image.Uniform{C: color.Transparent}, image.Point{}, draw.Src)
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
assert.Nil(t, png.Encode(buf, m))
|
||||
|
||||
fmt.Printf("len: %d\n", buf.Len())
|
||||
fmt.Printf("% #x\n", buf.Bytes())
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package rewrites
|
||||
|
||||
import (
|
||||
"errors"
|
||||
regexp "github.com/dlclark/regexp2"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -11,7 +10,12 @@ import (
|
|||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
var errInvalid = errors.New("invalid rewrite rule")
|
||||
type RawMitmRule struct {
|
||||
Url string `yaml:"url" json:"url"`
|
||||
Action C.RewriteType `yaml:"action" json:"action"`
|
||||
Old *string `yaml:"old" json:"old"`
|
||||
New string `yaml:"new" json:"new"`
|
||||
}
|
||||
|
||||
type RewriteRule struct {
|
||||
id string
|
||||
|
|
|
@ -561,6 +561,10 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
|
|||
}
|
||||
|
||||
for _, rule := range getRules(metadata) {
|
||||
if metadata.Type == C.MITM && rule.Adapter() == "MITM" {
|
||||
continue
|
||||
}
|
||||
|
||||
if !resolved && shouldResolveIP(rule, metadata) {
|
||||
func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), resolver.DefaultDNSTimeout)
|
||||
|
|
Loading…
Reference in New Issue
Block a user