Merge branch 'dev' of https://github.com/Dreamacro/clash into Alpha
This commit is contained in:
@ -5,7 +5,6 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Dreamacro/clash/adapter/inbound"
|
||||
"github.com/Dreamacro/clash/common/cache"
|
||||
@ -15,7 +14,7 @@ import (
|
||||
"github.com/Dreamacro/clash/log"
|
||||
)
|
||||
|
||||
func HandleConn(c net.Conn, in chan<- C.ConnContext, cache *cache.Cache[string, bool]) {
|
||||
func HandleConn(c net.Conn, in chan<- C.ConnContext, cache *cache.LruCache[string, bool]) {
|
||||
client := newClient(c.RemoteAddr(), in)
|
||||
defer client.CloseIdleConnections()
|
||||
|
||||
@ -62,9 +61,9 @@ func HandleConn(c net.Conn, in chan<- C.ConnContext, cache *cache.Cache[string,
|
||||
request.RequestURI = ""
|
||||
|
||||
if isUpgradeRequest(request) {
|
||||
if resp = handleUpgrade(conn, conn.RemoteAddr(), request, in); resp == nil {
|
||||
return // hijack connection
|
||||
}
|
||||
handleUpgrade(conn, request, in)
|
||||
|
||||
return // hijack connection
|
||||
}
|
||||
|
||||
removeHopByHopHeaders(request.Header)
|
||||
@ -99,7 +98,7 @@ func HandleConn(c net.Conn, in chan<- C.ConnContext, cache *cache.Cache[string,
|
||||
_ = conn.Close()
|
||||
}
|
||||
|
||||
func authenticate(request *http.Request, cache *cache.Cache[string, bool]) *http.Response {
|
||||
func authenticate(request *http.Request, cache *cache.LruCache[string, bool]) *http.Response {
|
||||
authenticator := authStore.Authenticator()
|
||||
if authenticator != nil {
|
||||
credential := parseBasicProxyAuthorization(request)
|
||||
@ -109,11 +108,11 @@ func authenticate(request *http.Request, cache *cache.Cache[string, bool]) *http
|
||||
return resp
|
||||
}
|
||||
|
||||
var authed bool
|
||||
if authed = cache.Get(credential); !authed {
|
||||
authed, exist := cache.Get(credential)
|
||||
if !exist {
|
||||
user, pass, err := decodeBasicProxyAuthorization(credential)
|
||||
authed = err == nil && authenticator.Verify(user, pass)
|
||||
cache.Put(credential, authed, time.Minute)
|
||||
cache.Set(credential, authed)
|
||||
}
|
||||
if !authed {
|
||||
log.Infoln("Auth failed from %s", request.RemoteAddr)
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"github.com/database64128/tfo-go"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/Dreamacro/clash/common/cache"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
@ -46,9 +45,9 @@ func NewWithAuthenticate(addr string, in chan<- C.ConnContext, authenticate bool
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var c *cache.Cache[string, bool]
|
||||
var c *cache.LruCache[string, bool]
|
||||
if authenticate {
|
||||
c = cache.New[string, bool](time.Second * 30)
|
||||
c = cache.New[string, bool](cache.WithAge[string, bool](30))
|
||||
}
|
||||
|
||||
hl := &Listener{
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Dreamacro/clash/adapter/inbound"
|
||||
N "github.com/Dreamacro/clash/common/net"
|
||||
@ -26,17 +25,15 @@ func isUpgradeRequest(req *http.Request) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func handleUpgrade(localConn net.Conn, source net.Addr, request *http.Request, in chan<- C.ConnContext) (resp *http.Response) {
|
||||
func handleUpgrade(conn net.Conn, request *http.Request, in chan<- C.ConnContext) {
|
||||
defer conn.Close()
|
||||
|
||||
removeProxyHeaders(request.Header)
|
||||
removeExtraHTTPHostPort(request)
|
||||
|
||||
address := request.Host
|
||||
if _, _, err := net.SplitHostPort(address); err != nil {
|
||||
port := "80"
|
||||
if request.TLS != nil {
|
||||
port = "443"
|
||||
}
|
||||
address = net.JoinHostPort(address, port)
|
||||
address = net.JoinHostPort(address, "80")
|
||||
}
|
||||
|
||||
dstAddr := socks5.ParseAddr(address)
|
||||
@ -46,9 +43,9 @@ func handleUpgrade(localConn net.Conn, source net.Addr, request *http.Request, i
|
||||
|
||||
left, right := net.Pipe()
|
||||
|
||||
in <- inbound.NewHTTP(dstAddr, source, right)
|
||||
in <- inbound.NewHTTP(dstAddr, conn.RemoteAddr(), right)
|
||||
|
||||
var remoteServer *N.BufferedConn
|
||||
var bufferedLeft *N.BufferedConn
|
||||
if request.TLS != nil {
|
||||
tlsConn := tls.Client(left, &tls.Config{
|
||||
ServerName: request.URL.Hostname(),
|
||||
@ -57,47 +54,36 @@ func handleUpgrade(localConn net.Conn, source net.Addr, request *http.Request, i
|
||||
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout)
|
||||
defer cancel()
|
||||
if tlsConn.HandshakeContext(ctx) != nil {
|
||||
_ = localConn.Close()
|
||||
_ = left.Close()
|
||||
return
|
||||
}
|
||||
|
||||
remoteServer = N.NewBufferedConn(tlsConn)
|
||||
bufferedLeft = N.NewBufferedConn(tlsConn)
|
||||
} else {
|
||||
remoteServer = N.NewBufferedConn(left)
|
||||
bufferedLeft = N.NewBufferedConn(left)
|
||||
}
|
||||
defer func() {
|
||||
_ = remoteServer.Close()
|
||||
_ = bufferedLeft.Close()
|
||||
}()
|
||||
|
||||
err := request.Write(remoteServer)
|
||||
err := request.Write(bufferedLeft)
|
||||
if err != nil {
|
||||
_ = localConn.Close()
|
||||
return
|
||||
}
|
||||
|
||||
resp, err = http.ReadResponse(remoteServer.Reader(), request)
|
||||
resp, err := http.ReadResponse(bufferedLeft.Reader(), request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
removeProxyHeaders(resp.Header)
|
||||
|
||||
err = resp.Write(conn)
|
||||
if err != nil {
|
||||
_ = localConn.Close()
|
||||
return
|
||||
}
|
||||
|
||||
if resp.StatusCode == http.StatusSwitchingProtocols {
|
||||
removeProxyHeaders(resp.Header)
|
||||
|
||||
err = localConn.SetReadDeadline(time.Time{}) // set to not time out
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = resp.Write(localConn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
N.Relay(remoteServer, localConn) // blocking here
|
||||
_ = localConn.Close()
|
||||
resp = nil
|
||||
N.Relay(bufferedLeft, conn)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
Reference in New Issue
Block a user