fix tcp redirect

This commit is contained in:
ginuerzh 2022-12-17 22:42:05 +08:00
parent 3b21b41ab3
commit 1cb719f694

View File

@ -11,6 +11,7 @@ import (
"net" "net"
"net/http" "net/http"
"net/http/httputil" "net/http/httputil"
"strings"
"time" "time"
"github.com/go-gost/core/chain" "github.com/go-gost/core/chain"
@ -108,10 +109,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
} }
// try to sniff HTTP traffic // try to sniff HTTP traffic
buf := new(bytes.Buffer) if isHTTP(string(hdr[:])) {
_, err = http.ReadRequest(bufio.NewReader(io.TeeReader(rw, buf)))
rw = xio.NewReadWriter(io.MultiReader(buf, rw), rw)
if err == nil {
return h.handleHTTP(ctx, rw, conn.RemoteAddr(), log) return h.handleHTTP(ctx, rw, conn.RemoteAddr(), log)
} }
} }
@ -184,19 +182,25 @@ func (h *redirectHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, radd
return err return err
} }
resp, err := http.ReadResponse(bufio.NewReader(cc), req) var rw2 io.ReadWriter = cc
if log.IsLevelEnabled(logger.TraceLevel) {
var buf bytes.Buffer
resp, err := http.ReadResponse(bufio.NewReader(io.TeeReader(cc, &buf)), req)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
return err return err
} }
defer resp.Body.Close() defer resp.Body.Close()
if log.IsLevelEnabled(logger.TraceLevel) {
dump, _ := httputil.DumpResponse(resp, false) dump, _ := httputil.DumpResponse(resp, false)
log.Trace(string(dump)) log.Trace(string(dump))
rw2 = xio.NewReadWriter(io.MultiReader(&buf, cc), cc)
} }
return resp.Write(rw) netpkg.Transport(rw, rw2)
return nil
} }
func (h *redirectHandler) handleHTTPS(ctx context.Context, rw io.ReadWriter, raddr, dstAddr net.Addr, log logger.Logger) error { func (h *redirectHandler) handleHTTPS(ctx context.Context, rw io.ReadWriter, raddr, dstAddr net.Addr, log logger.Logger) error {
@ -277,3 +281,15 @@ func (h *redirectHandler) checkRateLimit(addr net.Addr) bool {
return true return true
} }
func isHTTP(s string) bool {
return strings.HasPrefix(http.MethodGet, s[:3]) ||
strings.HasPrefix(http.MethodPost, s[:4]) ||
strings.HasPrefix(http.MethodPut, s[:3]) ||
strings.HasPrefix(http.MethodDelete, s) ||
strings.HasPrefix(http.MethodOptions, s) ||
strings.HasPrefix(http.MethodPatch, s) ||
strings.HasPrefix(http.MethodHead, s[:4]) ||
strings.HasPrefix(http.MethodConnect, s) ||
strings.HasPrefix(http.MethodTrace, s)
}