-
Notifications
You must be signed in to change notification settings - Fork 0
/
pipeconn.go
101 lines (81 loc) · 1.87 KB
/
pipeconn.go
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package csi
import (
"context"
"net"
"net/http"
"sync"
"time"
)
// PipeConn is an in-memory network connection that can be provided
// to a Serve function as a net.Listener and to gRPC/net.http clients
// as their dialer.
type PipeConn interface {
net.Listener
// DialGrpc is used by a grpc client.
DialGrpc(raddr string, timeout time.Duration) (net.Conn, error)
// DialHTTP16 is used by <=Go 1.6 net.http clients.
DialHTTP16(network, addr string) (net.Conn, error)
// DialHTTP17 is used by >=Go 1.7 net.http clients.
DialHTTP17(ctx context.Context, network, addr string) (net.Conn, error)
}
// NewPipeConn returns a new pipe connection. The provided name
// is returned by PipeConn.Addr().String().
func NewPipeConn(name string) PipeConn {
return &pipeConn{
addr: &pipeAddr{name: name},
chcn: make(chan net.Conn, 1),
}
}
type pipeConn struct {
sync.Once
addr *pipeAddr
chcn chan net.Conn
}
func (p *pipeConn) Dial(ctx context.Context) (net.Conn, error) {
r, w := net.Pipe()
go func() {
p.chcn <- r
}()
return w, nil
}
func (p *pipeConn) DialGrpc(
raddr string,
timeout time.Duration) (net.Conn, error) {
return p.Dial(context.Background())
}
func (p *pipeConn) DialHTTP16(
network, addr string) (net.Conn, error) {
return p.Dial(context.Background())
}
func (p *pipeConn) DialHTTP17(
ctx context.Context, network, addr string) (net.Conn, error) {
return p.Dial(ctx)
}
func (p *pipeConn) Accept() (net.Conn, error) {
for c := range p.chcn {
return c, nil
}
return nil, http.ErrServerClosed
}
func (p *pipeConn) Close() (err error) {
p.Once.Do(func() {
if p.chcn == nil {
return
}
close(p.chcn)
p.chcn = nil
})
return http.ErrServerClosed
}
func (p *pipeConn) Addr() net.Addr {
return p.addr
}
type pipeAddr struct {
name string
}
func (a *pipeAddr) Network() string {
return "pipe"
}
func (a *pipeAddr) String() string {
return a.name
}