micro/network/tunnel/transport/transport.go
Vasiliy Tolstov 8a2b122015
many fixes for lint and context.Context usage (#5)
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-11-03 02:02:32 +03:00

115 lines
2.3 KiB
Go

// Package transport provides a tunnel transport
package transport
import (
"context"
"fmt"
"github.com/unistack-org/micro/v3/network/transport"
"github.com/unistack-org/micro/v3/network/tunnel"
)
type tunTransport struct {
options transport.Options
tunnel tunnel.Tunnel
}
type tunnelKey struct{}
type transportKey struct{}
func (t *tunTransport) Init(opts ...transport.Option) error {
for _, o := range opts {
o(&t.options)
}
// close the existing tunnel
if t.tunnel != nil {
t.tunnel.Close(context.TODO())
}
// get the tunnel
tun, ok := t.options.Context.Value(tunnelKey{}).(tunnel.Tunnel)
if !ok {
return fmt.Errorf("tunnel not set")
}
// get the transport
tr, ok := t.options.Context.Value(transportKey{}).(transport.Transport)
if ok {
tun.Init(tunnel.Transport(tr))
}
// set the tunnel
t.tunnel = tun
return nil
}
func (t *tunTransport) Dial(ctx context.Context, addr string, opts ...transport.DialOption) (transport.Client, error) {
if err := t.tunnel.Connect(ctx); err != nil {
return nil, err
}
c, err := t.tunnel.Dial(ctx, addr)
if err != nil {
return nil, err
}
return c, nil
}
func (t *tunTransport) Listen(ctx context.Context, addr string, opts ...transport.ListenOption) (transport.Listener, error) {
if err := t.tunnel.Connect(ctx); err != nil {
return nil, err
}
l, err := t.tunnel.Listen(ctx, addr)
if err != nil {
return nil, err
}
return &tunListener{l}, nil
}
func (t *tunTransport) Options() transport.Options {
return t.options
}
func (t *tunTransport) String() string {
return "tunnel"
}
// NewTransport honours the initialiser used in
func NewTransport(opts ...transport.Option) transport.Transport {
t := &tunTransport{
options: transport.Options{},
}
// initialise
t.Init(opts...)
return t
}
// WithTunnel sets the internal tunnel
func WithTunnel(t tunnel.Tunnel) transport.Option {
return func(o *transport.Options) {
if o.Context == nil {
o.Context = context.Background()
}
o.Context = context.WithValue(o.Context, tunnelKey{}, t)
}
}
// WithTransport sets the internal transport
func WithTransport(t transport.Transport) transport.Option {
return func(o *transport.Options) {
if o.Context == nil {
o.Context = context.Background()
}
o.Context = context.WithValue(o.Context, transportKey{}, t)
}
}