Skip to content

Commit 815c942

Browse files
committed
Merge matcher and route into an interface that yields a Target.
This allows routes to compute a target at match time, instead of being statically mapped to a Target at register time.
1 parent 2065af4 commit 815c942

File tree

4 files changed

+39
-25
lines changed

4 files changed

+39
-25
lines changed

http.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,19 @@ import (
2727
//
2828
// The ipPort is any valid net.Listen TCP address.
2929
func (p *Proxy) AddHTTPHostRoute(ipPort, httpHost string, dest Target) {
30-
p.addRoute(ipPort, httpHostMatch(httpHost), dest)
30+
p.addRoute(ipPort, httpHostMatch{httpHost, dest})
3131
}
3232

33-
type httpHostMatch string
33+
type httpHostMatch struct {
34+
host string
35+
target Target
36+
}
3437

35-
func (host httpHostMatch) match(br *bufio.Reader) bool {
36-
return httpHostHeader(br) == string(host)
38+
func (m httpHostMatch) match(br *bufio.Reader) Target {
39+
if httpHostHeader(br) == m.host {
40+
return m.target
41+
}
42+
return nil
3743
}
3844

3945
// httpHostHeader returns the HTTP Host header from br without

sni.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,19 @@ import (
2929
//
3030
// The ipPort is any valid net.Listen TCP address.
3131
func (p *Proxy) AddSNIRoute(ipPort, sni string, dest Target) {
32-
p.addRoute(ipPort, sniMatch(sni), dest)
32+
p.addRoute(ipPort, sniMatch{sni, dest})
3333
}
3434

35-
type sniMatch string
35+
type sniMatch struct {
36+
sni string
37+
target Target
38+
}
3639

37-
func (sni sniMatch) match(br *bufio.Reader) bool {
38-
return clientHelloServerName(br) == string(sni)
40+
func (m sniMatch) match(br *bufio.Reader) Target {
41+
if clientHelloServerName(br) == string(m.sni) {
42+
return m.target
43+
}
44+
return nil
3945
}
4046

4147
// clientHelloServerName returns the SNI server name inside the TLS ClientHello,

tcpproxy.go

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ import (
6969
// The order that routes are added in matters; each is matched in the order
7070
// registered.
7171
type Proxy struct {
72-
routes map[string][]route // ip:port => route
72+
routes map[string][]route // ip:port => routes
7373

7474
lns []net.Listener
7575
donec chan struct{} // closed before err
@@ -81,13 +81,8 @@ type Proxy struct {
8181
ListenFunc func(net, laddr string) (net.Listener, error)
8282
}
8383

84-
type route struct {
85-
matcher matcher
86-
target Target
87-
}
88-
89-
type matcher interface {
90-
match(*bufio.Reader) bool
84+
type route interface {
85+
match(*bufio.Reader) Target
9186
}
9287

9388
func (p *Proxy) netListen() func(net, laddr string) (net.Listener, error) {
@@ -97,11 +92,11 @@ func (p *Proxy) netListen() func(net, laddr string) (net.Listener, error) {
9792
return net.Listen
9893
}
9994

100-
func (p *Proxy) addRoute(ipPort string, matcher matcher, dest Target) {
95+
func (p *Proxy) addRoute(ipPort string, r route) {
10196
if p.routes == nil {
10297
p.routes = make(map[string][]route)
10398
}
104-
p.routes[ipPort] = append(p.routes[ipPort], route{matcher, dest})
99+
p.routes[ipPort] = append(p.routes[ipPort], r)
105100
}
106101

107102
// AddRoute appends an always-matching route to the ipPort listener,
@@ -112,12 +107,14 @@ func (p *Proxy) addRoute(ipPort string, matcher matcher, dest Target) {
112107
//
113108
// The ipPort is any valid net.Listen TCP address.
114109
func (p *Proxy) AddRoute(ipPort string, dest Target) {
115-
p.addRoute(ipPort, alwaysMatch{}, dest)
110+
p.addRoute(ipPort, alwaysMatch{dest})
116111
}
117112

118-
type alwaysMatch struct{}
113+
type alwaysMatch struct {
114+
t Target
115+
}
119116

120-
func (alwaysMatch) match(*bufio.Reader) bool { return true }
117+
func (m alwaysMatch) match(*bufio.Reader) Target { return m.t }
121118

122119
// Run is calls Start, and then Wait.
123120
//
@@ -194,15 +191,15 @@ func (p *Proxy) serveListener(ret chan<- error, ln net.Listener, routes []route)
194191
func (p *Proxy) serveConn(c net.Conn, routes []route) bool {
195192
br := bufio.NewReader(c)
196193
for _, route := range routes {
197-
if route.matcher.match(br) {
194+
if target := route.match(br); target != nil {
198195
if n := br.Buffered(); n > 0 {
199196
peeked, _ := br.Peek(br.Buffered())
200197
c = &Conn{
201198
Peeked: peeked,
202199
Conn: c,
203200
}
204201
}
205-
route.target.HandleConn(c)
202+
target.HandleConn(c)
206203
return true
207204
}
208205
}

tcpproxy_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ import (
2727
"testing"
2828
)
2929

30+
type noopTarget struct{}
31+
32+
func (t *noopTarget) HandleConn(net.Conn) {}
33+
3034
func TestMatchHTTPHost(t *testing.T) {
3135
tests := []struct {
3236
name string
@@ -53,15 +57,16 @@ func TestMatchHTTPHost(t *testing.T) {
5357
want: true,
5458
},
5559
}
60+
target := &noopTarget{}
5661
for i, tt := range tests {
5762
name := tt.name
5863
if name == "" {
5964
name = fmt.Sprintf("test_index_%d", i)
6065
}
6166
t.Run(name, func(t *testing.T) {
6267
br := bufio.NewReader(tt.r)
63-
var matcher matcher = httpHostMatch(tt.host)
64-
got := matcher.match(br)
68+
r := httpHostMatch{tt.host, target}
69+
got := r.match(br) != nil
6570
if got != tt.want {
6671
t.Fatalf("match = %v; want %v", got, tt.want)
6772
}

0 commit comments

Comments
 (0)