77 "fmt"
88 "io"
99 "net"
10+ "regexp"
1011 "slices"
1112 "strings"
1213 "time"
@@ -17,8 +18,10 @@ import (
1718 "github.com/sirupsen/logrus"
1819)
1920
20- var version = "0.4 .0"
21+ var version = "0.5 .0"
2122var payloadByte []byte
23+ var uaPattern string
24+ var uaRegexp * regexp.Regexp
2225var cache * expirable.LRU [string , string ]
2326var HTTP_METHOD = []string {"GET" , "POST" , "HEAD" , "PUT" , "DELETE" , "OPTIONS" , "TRACE" , "CONNECT" }
2427var whitelist = []string {
@@ -47,6 +50,7 @@ func main() {
4750 flag .StringVar (& addr , "b" , "127.0.0.1" , "bind address (default: 127.0.0.1)" )
4851 flag .IntVar (& port , "p" , 1080 , "port" )
4952 flag .StringVar (& payload , "f" , "FFF" , "User-Agent" )
53+ flag .StringVar (& uaPattern , "r" , "(iPhone|iPad|Android|Macintosh|Windows|Linux)" , "UA-Pattern" )
5054 flag .StringVar (& loglevel , "l" , "info" , "Log level (default: info)" )
5155 flag .Parse ()
5256
@@ -55,6 +59,7 @@ func main() {
5559 logrus .Info ("UA3F v" + version )
5660 logrus .Info (fmt .Sprintf ("Port: %d" , port ))
5761 logrus .Info (fmt .Sprintf ("User-Agent: %s" , payload ))
62+ logrus .Info (fmt .Sprintf ("User-Agent Regex Pattern: %s" , uaPattern ))
5863 logrus .Info (fmt .Sprintf ("Log level: %s" , loglevel ))
5964
6065 cache = expirable .NewLRU [string , string ](300 , nil , time .Second * 600 )
@@ -72,6 +77,11 @@ func main() {
7277 return
7378 }
7479 logrus .Info (fmt .Sprintf ("Listen on %s:%d" , addr , port ))
80+ uaRegexp , err = regexp .Compile (uaPattern )
81+ if err != nil {
82+ logrus .Fatal ("Invalid User-Agent Regex Pattern: " , err )
83+ return
84+ }
7585 for {
7686 client , err := server .Accept ()
7787 if err != nil {
@@ -425,15 +435,29 @@ func CopyPileline(dst io.Writer, src io.Reader, destAddrPort string) {
425435 httpBodyOffset , err = parser .Parse (buf [:nr ])
426436 }
427437 value , start , end := parser .FindHeader ([]byte ("User-Agent" ))
438+ uaStr := string (value )
428439 if value != nil && end > start {
429- if slices .Contains (whitelist , string (value )) {
430- logrus .Debug (fmt .Sprintf ("[%s][%s] Hit User-Agent Whitelist: %s, Add LRU Relay Cache, Cache Len: %d" , destAddrPort , src .(* net.TCPConn ).RemoteAddr ().String (), string (value ), cache .Len ()))
440+ isInWhiteList := false
441+ isMatchUaPattern := true
442+ if uaPattern != "" {
443+ isMatchUaPattern = uaRegexp .MatchString (uaStr )
444+ }
445+ if slices .Contains (whitelist , uaStr ) {
446+ isInWhiteList = true
447+ }
448+ if isInWhiteList || ! isMatchUaPattern {
449+ if ! isMatchUaPattern {
450+ logrus .Debug (fmt .Sprintf ("[%s][%s] Not Hit User-Agent Pattern: %s" , destAddrPort , src .(* net.TCPConn ).RemoteAddr ().String (), uaStr ))
451+ }
452+ if isInWhiteList {
453+ logrus .Debug (fmt .Sprintf ("[%s][%s] Hit User-Agent Whitelist: %s, Add LRU Relay Cache, Cache Len: %d" , destAddrPort , src .(* net.TCPConn ).RemoteAddr ().String (), uaStr , cache .Len ()))
454+ cache .Add (destAddrPort , destAddrPort )
455+ }
431456 dst .Write (buf [0 :nr ])
432457 io .Copy (dst , src )
433- cache .Add (destAddrPort , destAddrPort )
434458 return
435459 }
436- logrus .Debug (fmt .Sprintf ("[%s][%s] Hit User-Agent: %s" , destAddrPort , src .(* net.TCPConn ).RemoteAddr ().String (), string ( value ) ))
460+ logrus .Debug (fmt .Sprintf ("[%s][%s] Hit User-Agent: %s" , destAddrPort , src .(* net.TCPConn ).RemoteAddr ().String (), uaStr ))
437461 for i := start ; i < end ; i ++ {
438462 buf [i ] = 32
439463 }
0 commit comments