Add transport tls
This commit is contained in:
		| @@ -3,6 +3,7 @@ package transport | |||||||
| import ( | import ( | ||||||
| 	"bufio" | 	"bufio" | ||||||
| 	"bytes" | 	"bytes" | ||||||
|  | 	"crypto/tls" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"io" | 	"io" | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| @@ -10,13 +11,17 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"sync" | 	"sync" | ||||||
|  |  | ||||||
|  | 	mls "github.com/micro/misc/lib/tls" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type buffer struct { | type buffer struct { | ||||||
| 	io.ReadWriter | 	io.ReadWriter | ||||||
| } | } | ||||||
|  |  | ||||||
| type httpTransport struct{} | type httpTransport struct { | ||||||
|  | 	opts Options | ||||||
|  | } | ||||||
|  |  | ||||||
| type httpTransportClient struct { | type httpTransportClient struct { | ||||||
| 	ht       *httpTransport | 	ht       *httpTransport | ||||||
| @@ -284,7 +289,22 @@ func (h *httpTransport) Dial(addr string, opts ...DialOption) (Client, error) { | |||||||
| 		opt(&dopts) | 		opt(&dopts) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	conn, err := net.DialTimeout("tcp", addr, dopts.Timeout) | 	var conn net.Conn | ||||||
|  | 	var err error | ||||||
|  |  | ||||||
|  | 	// TODO: support dial option here rather than using internal config | ||||||
|  | 	if h.opts.Secure || h.opts.TLSConfig != nil { | ||||||
|  | 		config := h.opts.TLSConfig | ||||||
|  | 		if config == nil { | ||||||
|  | 			config = &tls.Config{ | ||||||
|  | 				InsecureSkipVerify: true, | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		conn, err = tls.DialWithDialer(&net.Dialer{Timeout: dopts.Timeout}, "tcp", addr, config) | ||||||
|  | 	} else { | ||||||
|  | 		conn, err = net.DialTimeout("tcp", addr, dopts.Timeout) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -299,8 +319,30 @@ func (h *httpTransport) Dial(addr string, opts ...DialOption) (Client, error) { | |||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (h *httpTransport) Listen(addr string) (Listener, error) { | func (h *httpTransport) Listen(addr string, opts ...ListenOption) (Listener, error) { | ||||||
| 	l, err := net.Listen("tcp", addr) | 	var options ListenOptions | ||||||
|  | 	for _, o := range opts { | ||||||
|  | 		o(&options) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var l net.Listener | ||||||
|  | 	var err error | ||||||
|  |  | ||||||
|  | 	// TODO: support use of listen options | ||||||
|  | 	if h.opts.Secure || h.opts.TLSConfig != nil { | ||||||
|  | 		config := h.opts.TLSConfig | ||||||
|  | 		if config == nil { | ||||||
|  | 			cert, err := mls.Certificate(addr) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return nil, err | ||||||
|  | 			} | ||||||
|  | 			config = &tls.Config{Certificates: []tls.Certificate{cert}} | ||||||
|  | 		} | ||||||
|  | 		l, err = tls.Listen("tcp", addr, config) | ||||||
|  | 	} else { | ||||||
|  | 		l, err = net.Listen("tcp", addr) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -314,6 +356,10 @@ func (h *httpTransport) String() string { | |||||||
| 	return "http" | 	return "http" | ||||||
| } | } | ||||||
|  |  | ||||||
| func newHttpTransport(addrs []string, opt ...Option) *httpTransport { | func newHttpTransport(addrs []string, opts ...Option) *httpTransport { | ||||||
| 	return &httpTransport{} | 	var options Options | ||||||
|  | 	for _, o := range opts { | ||||||
|  | 		o(&options) | ||||||
|  | 	} | ||||||
|  | 	return &httpTransport{opts: options} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,12 +1,16 @@ | |||||||
| package transport | package transport | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"crypto/tls" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"golang.org/x/net/context" | 	"golang.org/x/net/context" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type Options struct { | type Options struct { | ||||||
|  | 	Secure    bool | ||||||
|  | 	TLSConfig *tls.Config | ||||||
|  |  | ||||||
| 	// Other options for implementations of the interface | 	// Other options for implementations of the interface | ||||||
| 	// can be stored in a context | 	// can be stored in a context | ||||||
| 	Context context.Context | 	Context context.Context | ||||||
| @@ -16,17 +20,46 @@ type DialOptions struct { | |||||||
| 	Stream  bool | 	Stream  bool | ||||||
| 	Timeout time.Duration | 	Timeout time.Duration | ||||||
|  |  | ||||||
|  | 	// TODO: add tls options when dialling | ||||||
|  | 	// Currently set in global options | ||||||
|  |  | ||||||
| 	// Other options for implementations of the interface | 	// Other options for implementations of the interface | ||||||
| 	// can be stored in a context | 	// can be stored in a context | ||||||
| 	Context context.Context | 	Context context.Context | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type ListenOptions struct { | ||||||
|  | 	// TODO: add tls options when listening | ||||||
|  | 	// Currently set in global options | ||||||
|  |  | ||||||
|  | 	// Other options for implementations of the interface | ||||||
|  | 	// can be stored in a context | ||||||
|  | 	Context context.Context | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Use secure communication. If TLSConfig is not specified we | ||||||
|  | // use InsecureSkipVerify and generate a self signed cert | ||||||
|  | func Secure(b bool) Option { | ||||||
|  | 	return func(o *Options) { | ||||||
|  | 		o.Secure = b | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TLSConfig to be used for the transport. | ||||||
|  | func TLSConfig(t *tls.Config) Option { | ||||||
|  | 	return func(o *Options) { | ||||||
|  | 		o.TLSConfig = t | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Indicates whether this is a streaming connection | ||||||
| func WithStream() DialOption { | func WithStream() DialOption { | ||||||
| 	return func(o *DialOptions) { | 	return func(o *DialOptions) { | ||||||
| 		o.Stream = true | 		o.Stream = true | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Timeout used when dialling the remote side | ||||||
| func WithTimeout(d time.Duration) DialOption { | func WithTimeout(d time.Duration) DialOption { | ||||||
| 	return func(o *DialOptions) { | 	return func(o *DialOptions) { | ||||||
| 		o.Timeout = d | 		o.Timeout = d | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ type Listener interface { | |||||||
|  |  | ||||||
| type Transport interface { | type Transport interface { | ||||||
| 	Dial(addr string, opts ...DialOption) (Client, error) | 	Dial(addr string, opts ...DialOption) (Client, error) | ||||||
| 	Listen(addr string) (Listener, error) | 	Listen(addr string, opts ...ListenOption) (Listener, error) | ||||||
| 	String() string | 	String() string | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -37,6 +37,8 @@ type Option func(*Options) | |||||||
|  |  | ||||||
| type DialOption func(*DialOptions) | type DialOption func(*DialOptions) | ||||||
|  |  | ||||||
|  | type ListenOption func(*ListenOptions) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| 	DefaultTransport Transport = newHttpTransport([]string{}) | 	DefaultTransport Transport = newHttpTransport([]string{}) | ||||||
|  |  | ||||||
| @@ -51,8 +53,8 @@ func Dial(addr string, opts ...DialOption) (Client, error) { | |||||||
| 	return DefaultTransport.Dial(addr, opts...) | 	return DefaultTransport.Dial(addr, opts...) | ||||||
| } | } | ||||||
|  |  | ||||||
| func Listen(addr string) (Listener, error) { | func Listen(addr string, opts ...ListenOption) (Listener, error) { | ||||||
| 	return DefaultTransport.Listen(addr) | 	return DefaultTransport.Listen(addr, opts...) | ||||||
| } | } | ||||||
|  |  | ||||||
| func String() string { | func String() string { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user