-
Notifications
You must be signed in to change notification settings - Fork 944
/
server.go
142 lines (115 loc) · 3.29 KB
/
server.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright (c) 2019 The BFE Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package bfe_stream
import (
"net"
)
import (
"github.com/baidu/go-lib/gotrack"
)
import (
http "github.com/bfenetworks/bfe/bfe_http"
tls "github.com/bfenetworks/bfe/bfe_tls"
)
const (
defaultConnectTimeout = 1000 // ms
defaultConnectRetryMax = 3
)
type Server struct {
// ConnectTimeout optionally specifies the timeout value (ms) to
// connect backend. If zero, a default value is used.
ConnectTimeout int
// ConnectRetryMax optionally specifies the upper limit of connect
// retris. If zero, a default value is used
ConnectRetryMax int
// BalanceHandler optionally specifies the handler for backends balance
// BalanceHandler should not be nil.
BalanceHandler BalanceHandler
// FindProductHandler finds product name for stream proxy
FindProductHandler FindProductHandler
// ProxyHandler optionally specifies the handler for process client conn
// and backend conn. If nil, a default value is used.
ProxyHandler ProxyHandler
// ProxyConfig optionally specifies the config for ProxyHandler
ProxyConfig interface{}
}
func (s *Server) connectTimeout() int {
if v := s.ConnectTimeout; v > 0 {
return v
}
return defaultConnectTimeout
}
func (s *Server) connectRetryMax() int {
if v := s.ConnectRetryMax; v > 0 {
return v
}
return defaultConnectRetryMax
}
func (s *Server) balanceHandler() BalanceHandler {
return s.BalanceHandler
}
func (s *Server) proxyHandler() ProxyHandler {
if v := s.ProxyHandler; v != nil {
return v
}
return TLSProxyHandler
}
func (s *Server) handleConn(hs *http.Server, c net.Conn, h http.Handler) *serverConn {
sc := new(serverConn)
sc.srv = s
sc.hs = hs
sc.conn = c
if tc, ok := c.(*tls.Conn); ok {
sc.tlsState = new(tls.ConnectionState)
*sc.tlsState = tc.ConnectionState()
if serverRule != nil {
sc.rule = serverRule.GetStreamRule(tc)
}
}
sc.closeNotifyCh = hs.CloseNotifyCh
sc.copyErrCh = make(chan error, 2)
sc.serveG = gotrack.NewGoroutineLock()
return sc
}
// FindProduct finds product by conn vip.
func (s *Server) FindProduct(c net.Conn) string {
productHandler := s.FindProductHandler
if productHandler == nil {
return ""
}
return productHandler(c)
}
// NewProtoHandler creates a protocol handler for stream.
func NewProtoHandler(conf *Server) func(*http.Server, *tls.Conn, http.Handler) {
if conf == nil {
conf = new(Server)
}
protoHandler := func(hs *http.Server, c *tls.Conn, h http.Handler) {
if sc := conf.handleConn(hs, c, h); sc != nil {
sc.serve()
}
}
return protoHandler
}
// Rule is the customized config for specific conn in server side.
type Rule struct {
ProxyProtocol int
}
type ServerRule interface {
GetStreamRule(conn *tls.Conn) *Rule
}
var serverRule ServerRule
func SetServerRule(r ServerRule) {
serverRule = r
}