|
|
@ -13,6 +13,7 @@ usage example
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
import (
|
|
|
|
|
|
|
|
"context"
|
|
|
|
"crypto/tls"
|
|
|
|
"crypto/tls"
|
|
|
|
"flag"
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"fmt"
|
|
|
@ -157,13 +158,34 @@ func (h *handler) handleHTTP(w http.ResponseWriter, r *http.Request) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func newClientConn(host string, port string, hostname string, t *http2.Transport) *clientConn {
|
|
|
|
func newClientConn(host string, port string, hostname string, t *http2.Transport) *clientConn {
|
|
|
|
return &clientConn{
|
|
|
|
cc := &clientConn{
|
|
|
|
host: host,
|
|
|
|
host: host,
|
|
|
|
port: port,
|
|
|
|
port: port,
|
|
|
|
hostname: hostname,
|
|
|
|
hostname: hostname,
|
|
|
|
transport: t,
|
|
|
|
transport: t,
|
|
|
|
lock: new(sync.Mutex),
|
|
|
|
lock: new(sync.Mutex),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
go cc.ping()
|
|
|
|
|
|
|
|
return cc
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (p *clientConn) ping() {
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
|
|
|
select {
|
|
|
|
|
|
|
|
case <-time.After(time.Duration(idleTimeout-5) * time.Second):
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p.lock.Lock()
|
|
|
|
|
|
|
|
conn := p.conn
|
|
|
|
|
|
|
|
p.lock.Unlock()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if conn == nil {
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := conn.Ping(context.Background()); err != nil {
|
|
|
|
|
|
|
|
p.MarkDead(conn)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (p *clientConn) GetClientConn(req *http.Request, addr string) (*http2.ClientConn, error) {
|
|
|
|
func (p *clientConn) GetClientConn(req *http.Request, addr string) (*http2.ClientConn, error) {
|
|
|
@ -187,8 +209,8 @@ func (p *clientConn) GetClientConn(req *http.Request, addr string) (*http2.Clien
|
|
|
|
return nil, err
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// cc := &timeoutConn{c, time.Duration(idleTimeout) * time.Second}
|
|
|
|
cc := &timeoutConn{c, time.Duration(idleTimeout) * time.Second}
|
|
|
|
cc := c
|
|
|
|
// cc := c
|
|
|
|
config := &tls.Config{
|
|
|
|
config := &tls.Config{
|
|
|
|
ServerName: p.hostname,
|
|
|
|
ServerName: p.hostname,
|
|
|
|
NextProtos: []string{"h2"},
|
|
|
|
NextProtos: []string{"h2"},
|
|
|
@ -235,7 +257,7 @@ func main() {
|
|
|
|
flag.StringVar(&listen, "listen", ":8080", "listen address")
|
|
|
|
flag.StringVar(&listen, "listen", ":8080", "listen address")
|
|
|
|
flag.BoolVar(&debug, "debug", false, "verbose mode")
|
|
|
|
flag.BoolVar(&debug, "debug", false, "verbose mode")
|
|
|
|
flag.BoolVar(&insecure, "insecure", false, "insecure mode, not verify the server's certificate")
|
|
|
|
flag.BoolVar(&insecure, "insecure", false, "insecure mode, not verify the server's certificate")
|
|
|
|
flag.IntVar(&idleTimeout, "idletime", 600, "idle timeout, close connection when no data transfer")
|
|
|
|
flag.IntVar(&idleTimeout, "idletime", 20, "idle timeout, close connection when no data transfer")
|
|
|
|
flag.Parse()
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
|
|
|
|
if addr == "" {
|
|
|
|
if addr == "" {
|
|
|
@ -243,6 +265,10 @@ func main() {
|
|
|
|
os.Exit(-1)
|
|
|
|
os.Exit(-1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if idleTimeout < 10 {
|
|
|
|
|
|
|
|
idleTimeout = 10
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if debug {
|
|
|
|
if debug {
|
|
|
|
log.Default.Level = log.DEBUG
|
|
|
|
log.Default.Level = log.DEBUG
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|