Go + Vue 管理台:Agent 隧道、域名反代、IP 安全、访客验证与监控大盘。 Gitea Actions CI 多架构镜像;纯 Go SQLite、无 CGO Docker 构建。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
package bridge
|
||||
|
||||
import (
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// rateLimitedConn limits read/write throughput to bytesPerSec (simple token bucket).
|
||||
type rateLimitedConn struct {
|
||||
net.Conn
|
||||
bytesPerSec int64
|
||||
mu sync.Mutex
|
||||
allowance float64
|
||||
lastCheck time.Time
|
||||
}
|
||||
|
||||
func newRateLimitedConn(conn net.Conn, bytesPerSec int64) net.Conn {
|
||||
if bytesPerSec <= 0 {
|
||||
return conn
|
||||
}
|
||||
return &rateLimitedConn{
|
||||
Conn: conn,
|
||||
bytesPerSec: bytesPerSec,
|
||||
lastCheck: time.Now(),
|
||||
allowance: float64(bytesPerSec),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *rateLimitedConn) wait(n int) {
|
||||
if c.bytesPerSec <= 0 || n <= 0 {
|
||||
return
|
||||
}
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
now := time.Now()
|
||||
elapsed := now.Sub(c.lastCheck).Seconds()
|
||||
c.lastCheck = now
|
||||
c.allowance += elapsed * float64(c.bytesPerSec)
|
||||
if c.allowance > float64(c.bytesPerSec)*2 {
|
||||
c.allowance = float64(c.bytesPerSec) * 2
|
||||
}
|
||||
for float64(n) > c.allowance {
|
||||
deficit := float64(n) - c.allowance
|
||||
sleep := time.Duration(deficit/float64(c.bytesPerSec)*1e9) * time.Nanosecond
|
||||
if sleep < time.Millisecond {
|
||||
sleep = time.Millisecond
|
||||
}
|
||||
c.mu.Unlock()
|
||||
time.Sleep(sleep)
|
||||
c.mu.Lock()
|
||||
now = time.Now()
|
||||
elapsed = now.Sub(c.lastCheck).Seconds()
|
||||
c.lastCheck = now
|
||||
c.allowance += elapsed * float64(c.bytesPerSec)
|
||||
if c.allowance > float64(c.bytesPerSec)*2 {
|
||||
c.allowance = float64(c.bytesPerSec) * 2
|
||||
}
|
||||
}
|
||||
c.allowance -= float64(n)
|
||||
}
|
||||
|
||||
func (c *rateLimitedConn) Read(b []byte) (int, error) {
|
||||
n, err := c.Conn.Read(b)
|
||||
if n > 0 {
|
||||
c.wait(n)
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (c *rateLimitedConn) Write(b []byte) (int, error) {
|
||||
c.wait(len(b))
|
||||
return c.Conn.Write(b)
|
||||
}
|
||||
Reference in New Issue
Block a user