github.com/yaling888/clash@v1.53.0/listener/http/server.go (about) 1 package http 2 3 import ( 4 "net" 5 6 "github.com/yaling888/clash/common/cache" 7 "github.com/yaling888/clash/component/auth" 8 C "github.com/yaling888/clash/constant" 9 ) 10 11 type Listener struct { 12 listener net.Listener 13 addr string 14 auth auth.Authenticator 15 closed bool 16 } 17 18 // RawAddress implements C.Listener 19 func (l *Listener) RawAddress() string { 20 return l.addr 21 } 22 23 // Address implements C.Listener 24 func (l *Listener) Address() string { 25 return l.listener.Addr().String() 26 } 27 28 // Close implements C.Listener 29 func (l *Listener) Close() error { 30 l.closed = true 31 return l.listener.Close() 32 } 33 34 // SetAuthenticator implements C.AuthenticatorListener 35 func (l *Listener) SetAuthenticator(users []auth.AuthUser) { 36 l.auth = auth.NewAuthenticator(users) 37 } 38 39 func New(addr string, in chan<- C.ConnContext) (C.Listener, error) { 40 return NewWithAuthenticate(addr, in, true) 41 } 42 43 func NewWithAuthenticate(addr string, in chan<- C.ConnContext, authenticate bool) (C.Listener, error) { 44 l, err := net.Listen("tcp", addr) 45 if err != nil { 46 return nil, err 47 } 48 49 var c *cache.LruCache[string, bool] 50 if authenticate { 51 c = cache.New[string, bool](cache.WithAge[string, bool](30)) 52 } 53 54 hl := &Listener{ 55 listener: l, 56 addr: addr, 57 } 58 go func() { 59 for { 60 conn, err := hl.listener.Accept() 61 if err != nil { 62 if hl.closed { 63 break 64 } 65 continue 66 } 67 go HandleConn(conn, in, c, hl.auth) 68 } 69 }() 70 71 return hl, nil 72 }