sing-box/transport/v2rayhttp/force_close.go
2024-07-13 17:46:22 +08:00

48 lines
1.0 KiB
Go

package v2rayhttp
import (
"net/http"
"reflect"
"sync"
"unsafe"
E "github.com/sagernet/sing/common/exceptions"
"golang.org/x/net/http2"
)
type clientConnPool struct {
t *http2.Transport
mu sync.Mutex
conns map[string][]*http2.ClientConn // key is host:port
}
type efaceWords struct {
typ unsafe.Pointer
data unsafe.Pointer
}
func ResetTransport(rawTransport http.RoundTripper) http.RoundTripper {
switch transport := rawTransport.(type) {
case *http.Transport:
transport.CloseIdleConnections()
return transport.Clone()
case *http2.Transport:
connPool := transportConnPool(transport)
p := (*clientConnPool)((*efaceWords)(unsafe.Pointer(&connPool)).data)
p.mu.Lock()
defer p.mu.Unlock()
for _, vv := range p.conns {
for _, cc := range vv {
cc.Close()
}
}
return transport
default:
panic(E.New("unknown transport type: ", reflect.TypeOf(transport)))
}
}
//go:linkname transportConnPool golang.org/x/net/http2.(*Transport).connPool
func transportConnPool(t *http2.Transport) http2.ClientConnPool