mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2025-02-23 02:33:14 +08:00
fix: add backgroundRead for plain http inbound (#952)
https://github.com/golang/go/blob/go1.21.5/src/net/http/server.go#L682
This commit is contained in:
parent
1d3e9f4889
commit
4ee267ca7e
@ -1,10 +1,14 @@
|
|||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
"github.com/metacubex/mihomo/adapter/inbound"
|
"github.com/metacubex/mihomo/adapter/inbound"
|
||||||
"github.com/metacubex/mihomo/common/lru"
|
"github.com/metacubex/mihomo/common/lru"
|
||||||
@ -14,9 +18,18 @@ import (
|
|||||||
"github.com/metacubex/mihomo/log"
|
"github.com/metacubex/mihomo/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:linkname registerOnHitEOF net/http.registerOnHitEOF
|
||||||
|
func registerOnHitEOF(rc io.ReadCloser, fn func())
|
||||||
|
|
||||||
|
//go:linkname requestBodyRemains net/http.requestBodyRemains
|
||||||
|
func requestBodyRemains(rc io.ReadCloser) bool
|
||||||
|
|
||||||
func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool], additions ...inbound.Addition) {
|
func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool], additions ...inbound.Addition) {
|
||||||
client := newClient(c, tunnel, additions...)
|
client := newClient(c, tunnel, additions...)
|
||||||
defer client.CloseIdleConnections()
|
defer client.CloseIdleConnections()
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
peekMutex := sync.Mutex{}
|
||||||
|
|
||||||
conn := N.NewBufferedConn(c)
|
conn := N.NewBufferedConn(c)
|
||||||
|
|
||||||
@ -24,7 +37,9 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool],
|
|||||||
trusted := cache == nil // disable authenticate if lru is nil
|
trusted := cache == nil // disable authenticate if lru is nil
|
||||||
|
|
||||||
for keepAlive {
|
for keepAlive {
|
||||||
|
peekMutex.Lock()
|
||||||
request, err := ReadRequest(conn.Reader())
|
request, err := ReadRequest(conn.Reader())
|
||||||
|
peekMutex.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -72,6 +87,23 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, cache *lru.LruCache[string, bool],
|
|||||||
if request.URL.Scheme == "" || request.URL.Host == "" {
|
if request.URL.Scheme == "" || request.URL.Host == "" {
|
||||||
resp = responseWith(request, http.StatusBadRequest)
|
resp = responseWith(request, http.StatusBadRequest)
|
||||||
} else {
|
} else {
|
||||||
|
request = request.WithContext(ctx)
|
||||||
|
|
||||||
|
startBackgroundRead := func() {
|
||||||
|
go func() {
|
||||||
|
peekMutex.Lock()
|
||||||
|
defer peekMutex.Unlock()
|
||||||
|
_, err := conn.Peek(1)
|
||||||
|
if err != nil {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
if requestBodyRemains(request.Body) {
|
||||||
|
registerOnHitEOF(request.Body, startBackgroundRead)
|
||||||
|
} else {
|
||||||
|
startBackgroundRead()
|
||||||
|
}
|
||||||
resp, err = client.Do(request)
|
resp, err = client.Do(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp = responseWith(request, http.StatusBadGateway)
|
resp = responseWith(request, http.StatusBadGateway)
|
||||||
|
Loading…
Reference in New Issue
Block a user