mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2024-11-04 19:04:00 +00: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 changed files with 32 additions and 0 deletions
|
@ -1,10 +1,14 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
_ "unsafe"
|
||||
|
||||
"github.com/metacubex/mihomo/adapter/inbound"
|
||||
"github.com/metacubex/mihomo/common/lru"
|
||||
|
@ -14,9 +18,18 @@ import (
|
|||
"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) {
|
||||
client := newClient(c, tunnel, additions...)
|
||||
defer client.CloseIdleConnections()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
peekMutex := sync.Mutex{}
|
||||
|
||||
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
|
||||
|
||||
for keepAlive {
|
||||
peekMutex.Lock()
|
||||
request, err := ReadRequest(conn.Reader())
|
||||
peekMutex.Unlock()
|
||||
if err != nil {
|
||||
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 == "" {
|
||||
resp = responseWith(request, http.StatusBadRequest)
|
||||
} 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)
|
||||
if err != nil {
|
||||
resp = responseWith(request, http.StatusBadGateway)
|
||||
|
|
Loading…
Reference in a new issue