mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2025-02-23 20:52:15 +08:00
feat: gRPC gun implement extended writer
This commit is contained in:
parent
ead21f37d7
commit
926ef9e33d
@ -17,6 +17,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Dreamacro/clash/common/buf"
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
|
|
||||||
"go.uber.org/atomic"
|
"go.uber.org/atomic"
|
||||||
@ -121,13 +122,13 @@ func (g *Conn) Read(b []byte) (n int, err error) {
|
|||||||
func (g *Conn) Write(b []byte) (n int, err error) {
|
func (g *Conn) Write(b []byte) (n int, err error) {
|
||||||
protobufHeader := [binary.MaxVarintLen64 + 1]byte{0x0A}
|
protobufHeader := [binary.MaxVarintLen64 + 1]byte{0x0A}
|
||||||
varuintSize := binary.PutUvarint(protobufHeader[1:], uint64(len(b)))
|
varuintSize := binary.PutUvarint(protobufHeader[1:], uint64(len(b)))
|
||||||
grpcHeader := make([]byte, 5)
|
var grpcHeader [5]byte
|
||||||
grpcPayloadLen := uint32(varuintSize + 1 + len(b))
|
grpcPayloadLen := uint32(varuintSize + 1 + len(b))
|
||||||
binary.BigEndian.PutUint32(grpcHeader[1:5], grpcPayloadLen)
|
binary.BigEndian.PutUint32(grpcHeader[1:5], grpcPayloadLen)
|
||||||
|
|
||||||
buf := pool.GetBuffer()
|
buf := pool.GetBuffer()
|
||||||
defer pool.PutBuffer(buf)
|
defer pool.PutBuffer(buf)
|
||||||
buf.Write(grpcHeader)
|
buf.Write(grpcHeader[:])
|
||||||
buf.Write(protobufHeader[:varuintSize+1])
|
buf.Write(protobufHeader[:varuintSize+1])
|
||||||
buf.Write(b)
|
buf.Write(b)
|
||||||
|
|
||||||
@ -139,6 +140,28 @@ func (g *Conn) Write(b []byte) (n int, err error) {
|
|||||||
return len(b), err
|
return len(b), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *Conn) WriteBuffer(buffer *buf.Buffer) error {
|
||||||
|
defer buffer.Release()
|
||||||
|
dataLen := buffer.Len()
|
||||||
|
varLen := UVarintLen(uint64(dataLen))
|
||||||
|
header := buffer.ExtendHeader(6 + varLen)
|
||||||
|
header[0] = 0x00
|
||||||
|
binary.BigEndian.PutUint32(header[1:5], uint32(1+varLen+dataLen))
|
||||||
|
header[5] = 0x0A
|
||||||
|
binary.PutUvarint(header[6:], uint64(dataLen))
|
||||||
|
_, err := g.writer.Write(buffer.Bytes())
|
||||||
|
|
||||||
|
if err == io.ErrClosedPipe && g.err != nil {
|
||||||
|
err = g.err
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Conn) FrontHeadroom() int {
|
||||||
|
return 6 + binary.MaxVarintLen64
|
||||||
|
}
|
||||||
|
|
||||||
func (g *Conn) Close() error {
|
func (g *Conn) Close() error {
|
||||||
g.close.Store(true)
|
g.close.Store(true)
|
||||||
if r := g.response; r != nil {
|
if r := g.response; r != nil {
|
||||||
|
10
transport/gun/utils.go
Normal file
10
transport/gun/utils.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package gun
|
||||||
|
|
||||||
|
func UVarintLen(x uint64) int {
|
||||||
|
i := 0
|
||||||
|
for x >= 0x80 {
|
||||||
|
x >>= 7
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return i + 1
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user