chore: direct append data to bufio.Reader's internal buffer as much as possible

This commit is contained in:
wwqgtxx 2023-11-09 22:19:29 +08:00
parent fe7c1a2cdb
commit 832dae3421
3 changed files with 43 additions and 2 deletions

View file

@ -84,9 +84,9 @@ func (c *BufferedConn) ReadCached() *buf.Buffer { // call in sing/common/bufio.C
length := c.r.Buffered()
b, _ := c.r.Peek(length)
_, _ = c.r.Discard(length)
c.r = nil // drop bufio.Reader to let gc can clean up its internal buf
return buf.As(b)
}
c.r = nil // drop bufio.Reader to let gc can clean up its internal buf
return nil
}

View file

@ -0,0 +1,34 @@
package net
import (
"io"
"unsafe"
)
// bufioReader copy from stdlib bufio/bufio.go
// This structure has remained unchanged from go1.5 to go1.21.
type bufioReader struct {
buf []byte
rd io.Reader // reader provided by the client
r, w int // buf read and write positions
err error
lastByte int // last byte read for UnreadByte; -1 means invalid
lastRuneSize int // size of last rune read for UnreadRune; -1 means invalid
}
func (c *BufferedConn) AppendData(buf []byte) (ok bool) {
b := (*bufioReader)(unsafe.Pointer(c.r))
pos := len(b.buf) - b.w - len(buf)
if pos >= -b.r { // len(b.buf)-(b.w - b.r) >= len(buf)
if pos < 0 { // len(b.buf)-b.w < len(buf)
// Slide existing data to beginning.
copy(b.buf, b.buf[b.r:b.w])
b.w -= b.r
b.r = 0
}
b.w += copy(b.buf[b.w:], buf)
return true
}
return false
}

View file

@ -554,8 +554,15 @@ func StreamUpgradedWebsocketConn(w http.ResponseWriter, r *http.Request) (net.Co
}
if edBuf := decodeXray0rtt(r.Header); len(edBuf) > 0 {
appendOk := false
if bufConn, ok := conn.(*N.BufferedConn); ok {
appendOk = bufConn.AppendData(edBuf)
}
if !appendOk {
conn = N.NewCachedConn(conn, edBuf)
}
}
return conn, nil
}