1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
package httpz
import (
"context"
"net"
"sync"
"time"
)
// ContextConn is a wrapper around net.Conn that can be used to tie connection lifetime to context cancellation.
type ContextConn struct {
net.Conn
closeOnce sync.Once
cancelContextSync chan struct{}
}
func NewContextConn(conn net.Conn) *ContextConn {
return &ContextConn{
Conn: conn,
cancelContextSync: make(chan struct{}),
}
}
func (c *ContextConn) CloseOnDone(ctx context.Context) {
select {
case <-ctx.Done():
_ = c.Conn.Close()
case <-c.cancelContextSync:
}
}
func (c *ContextConn) Close() error {
c.closeOnce.Do(func() {
close(c.cancelContextSync)
})
return c.Conn.Close()
}
type WriteTimeoutConn struct {
net.Conn
Timeout time.Duration
}
func (c *WriteTimeoutConn) Write(b []byte) (int, error) {
err := c.Conn.SetWriteDeadline(time.Now().Add(c.Timeout))
if err != nil {
return 0, err
}
return c.Conn.Write(b)
}
|