client server: config objects

This commit is contained in:
mmatczuk 2016-09-26 10:05:21 +02:00
parent f8a8ff0163
commit 8c03ca0427
4 changed files with 141 additions and 81 deletions

View file

@ -3,7 +3,6 @@ package h2tun
import (
"crypto/tls"
"fmt"
"io"
"net"
"net/http"
@ -12,27 +11,52 @@ import (
"golang.org/x/net/http2"
)
// ClientConfig is Client configuration object.
type ClientConfig struct {
// ServerAddr specifies TCP address of the tunnel server.
ServerAddr string
// TLSClientConfig specifies the TLS configuration to use with tls.Client.
TLSClientConfig *tls.Config
// DialTLS specifies an optional dial function for creating
// TLS connections for requests.
//
// If DialTLS is nil, tls.Dial is used.
DialTLS func(network, addr string, config *tls.Config) (net.Conn, error)
// Proxy specifies proxying rules.
Proxy ProxyFunc
// Log specifies the logger. If nil a default logging.Logger is used.
Log logging.Logger
}
// Client is client to tunnel server.
type Client struct {
proxy ProxyFunc
serverAddr string
tlsConfig *tls.Config
config *ClientConfig
conn net.Conn
httpServer *http2.Server
log logging.Logger
}
func NewClient(proxy ProxyFunc, serverAddr string, tlsConfig *tls.Config) *Client {
return &Client{
proxy: proxy,
serverAddr: serverAddr,
tlsConfig: tlsConfig,
httpServer: &http2.Server{},
log: logging.NewLogger("client"),
func NewClient(config *ClientConfig) *Client {
// TODO (phase2) add validation
log := logging.NewLogger("client")
if config.Log != nil {
log = config.Log
}
c := &Client{
config: config,
httpServer: &http2.Server{},
log: log,
}
return c
}
func (c *Client) Connect() error {
conn, err := tls.Dial("tcp", c.serverAddr, c.tlsConfig)
c.log.Info("Connecting to %q", c.config.ServerAddr)
conn, err := c.dial("tcp", c.config.ServerAddr, c.config.TLSClientConfig)
if err != nil {
return fmt.Errorf("failed to connect to server: %s", err)
}
@ -45,6 +69,13 @@ func (c *Client) Connect() error {
return nil
}
func (c *Client) dial(network, addr string, config *tls.Config) (net.Conn, error) {
if c.config.DialTLS != nil {
return c.config.DialTLS(network, addr, config)
}
return tls.Dial(network, addr, config)
}
func (c *Client) serveHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodConnect {
c.log.Info("Handshake: hello from server")
@ -57,21 +88,9 @@ func (c *Client) serveHTTP(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
c.log.Debug("Proxy init %s %v", r.RemoteAddr, msg)
c.proxy(flushWriter{w}, r.Body, msg)
c.log.Debug("Proxy over %s %v", r.RemoteAddr, msg)
}
type flushWriter struct {
w io.Writer
}
func (fw flushWriter) Write(p []byte) (n int, err error) {
n, err = fw.w.Write(p)
if f, ok := fw.w.(http.Flusher); ok {
f.Flush()
}
return
c.log.Debug("Start proxying %v", msg)
c.config.Proxy(flushWriter{w}, r.Body, msg)
c.log.Debug("Done proxying %v", msg)
}
func (c *Client) Close() error {