-
Notifications
You must be signed in to change notification settings - Fork 0
/
proxy.go
69 lines (57 loc) · 1.65 KB
/
proxy.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
package nprxy
import (
"context"
"fmt"
"net"
"net/url"
)
// DialUpstream func to create conn to upstream service
type DialUpstream func(network, addr string) (net.Conn, error)
// Proxy forwards data from listener to upstream connection
type Proxy interface {
Serve(ctx context.Context, Listener net.Listener, DialUpstream DialUpstream) error
}
// Proxy, Listener and Upstream factory
var (
ProxyFactory = map[string]func(ServiceConfig) (Proxy, error){}
ListenerFactory = map[string]func(ServiceConfig) (net.Listener, error){}
UpstreamDialFactory = map[string]func(ServiceConfig) (DialUpstream, error){}
)
// ProxyService create proxy and forward traffic
func ProxyService(ctx context.Context, c ServiceConfig) error {
u, err := url.Parse(c.Upstream)
if err != nil {
return fmt.Errorf("failed to parse Upstream: %v", err)
}
// Create proxy with factory
pf, ok := ProxyFactory[u.Scheme]
if !ok {
return fmt.Errorf("unsupported upstream scheme %s", u.Scheme)
}
p, err := pf(c)
if err != nil {
return fmt.Errorf("failed to create proxy: %v", err)
}
// Create listener with factory
if c.Listen.Kind == "" {
c.Listen.Kind = "plain"
}
lf, ok := ListenerFactory[c.Listen.Kind]
if !ok {
return fmt.Errorf("unsupported listener type %s", c.Listen.Kind)
}
l, err := lf(c)
if err != nil {
return fmt.Errorf("failed to create listener: %v", err)
}
// Create upstream with factory
udf, ok := UpstreamDialFactory["plain"]
if !ok {
return fmt.Errorf("unsupported Upstream dialer type %s", "TODO")
}
ud, err := udf(c)
if err != nil {
return fmt.Errorf("failed to create upstream dialer: %v", err)
}
return p.Serve(ctx, l, ud)
}