115 lines
2.2 KiB
Go
115 lines
2.2 KiB
Go
// Package transport provides a tunnel transport
|
|
package transport
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/unistack-org/micro/v3/transport"
|
|
"github.com/unistack-org/micro/v3/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()
|
|
}
|
|
|
|
// 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(addr string, opts ...transport.DialOption) (transport.Client, error) {
|
|
if err := t.tunnel.Connect(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
c, err := t.tunnel.Dial(addr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return c, nil
|
|
}
|
|
|
|
func (t *tunTransport) Listen(addr string, opts ...transport.ListenOption) (transport.Listener, error) {
|
|
if err := t.tunnel.Connect(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
l, err := t.tunnel.Listen(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
|
|
}
|
|
|
|
// WithTransport 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)
|
|
}
|
|
}
|