mirror of
https://github.com/chaitin/MonkeyCode.git
synced 2026-02-02 14:53:55 +08:00
82 lines
1.6 KiB
Go
82 lines
1.6 KiB
Go
|
|
package tee
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"bytes"
|
|||
|
|
"fmt"
|
|||
|
|
"io"
|
|||
|
|
"sync"
|
|||
|
|
"time"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
type ReqTee struct {
|
|||
|
|
src io.ReadCloser
|
|||
|
|
buf bytes.Buffer
|
|||
|
|
done chan struct{}
|
|||
|
|
mu sync.RWMutex
|
|||
|
|
closed bool
|
|||
|
|
maxSize int64 // 最大缓冲区大小,0表示无限制
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var _ io.ReadCloser = &ReqTee{}
|
|||
|
|
|
|||
|
|
func NewReqTee(src io.ReadCloser) *ReqTee {
|
|||
|
|
return NewReqTeeWithMaxSize(src, 0)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// NewReqTeeWithMaxSize 创建带最大缓冲区大小限制的ReqTee
|
|||
|
|
func NewReqTeeWithMaxSize(src io.ReadCloser, maxSize int64) *ReqTee {
|
|||
|
|
return &ReqTee{
|
|||
|
|
src: src,
|
|||
|
|
buf: bytes.Buffer{},
|
|||
|
|
done: make(chan struct{}),
|
|||
|
|
maxSize: maxSize,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (r *ReqTee) GetBody() ([]byte, error) {
|
|||
|
|
return r.GetBodyWithTimeout(30 * time.Second)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetBodyWithTimeout 获取缓冲的数据,支持自定义超时时间
|
|||
|
|
func (r *ReqTee) GetBodyWithTimeout(timeout time.Duration) ([]byte, error) {
|
|||
|
|
select {
|
|||
|
|
case <-r.done:
|
|||
|
|
r.mu.RLock()
|
|||
|
|
defer r.mu.RUnlock()
|
|||
|
|
return r.buf.Bytes(), nil
|
|||
|
|
case <-time.After(timeout):
|
|||
|
|
return nil, fmt.Errorf("timeout waiting for data")
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Close implements io.ReadCloser.
|
|||
|
|
func (r *ReqTee) Close() error {
|
|||
|
|
r.mu.Lock()
|
|||
|
|
defer r.mu.Unlock()
|
|||
|
|
|
|||
|
|
if r.closed {
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
r.closed = true
|
|||
|
|
|
|||
|
|
close(r.done)
|
|||
|
|
return r.src.Close()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Read implements io.ReadCloser.
|
|||
|
|
func (r *ReqTee) Read(p []byte) (n int, err error) {
|
|||
|
|
n, err = r.src.Read(p)
|
|||
|
|
if n > 0 {
|
|||
|
|
r.mu.Lock()
|
|||
|
|
// 检查缓冲区大小限制
|
|||
|
|
if r.maxSize > 0 && int64(r.buf.Len()+n) > r.maxSize {
|
|||
|
|
r.mu.Unlock()
|
|||
|
|
return n, fmt.Errorf("buffer size limit exceeded: %d bytes", r.maxSize)
|
|||
|
|
}
|
|||
|
|
// 直接写入缓冲区,避免额外的内存分配和复制
|
|||
|
|
r.buf.Write(p[:n])
|
|||
|
|
r.mu.Unlock()
|
|||
|
|
}
|
|||
|
|
return n, err
|
|||
|
|
}
|