Bump reva deps (#8412)
* bump dependencies Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * bump reva and add config options Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> --------- Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
This commit is contained in:
+61
-88
@@ -1,55 +1,30 @@
|
||||
// addr provides functions to retrieve local IP addresses from device interfaces.
|
||||
package addr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
privateBlocks []*net.IPNet
|
||||
// ErrIPNotFound no IP address found, and explicit IP not provided.
|
||||
ErrIPNotFound = errors.New("no IP address found, and explicit IP not provided")
|
||||
)
|
||||
|
||||
func init() {
|
||||
for _, b := range []string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "100.64.0.0/10", "fd00::/8"} {
|
||||
if _, block, err := net.ParseCIDR(b); err == nil {
|
||||
privateBlocks = append(privateBlocks, block)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AppendPrivateBlocks append private network blocks
|
||||
func AppendPrivateBlocks(bs ...string) {
|
||||
for _, b := range bs {
|
||||
if _, block, err := net.ParseCIDR(b); err == nil {
|
||||
privateBlocks = append(privateBlocks, block)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func isPrivateIP(ipAddr string) bool {
|
||||
ip := net.ParseIP(ipAddr)
|
||||
for _, priv := range privateBlocks {
|
||||
if priv.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsLocal tells us whether an ip is local
|
||||
// IsLocal checks whether an IP belongs to one of the device's interfaces.
|
||||
func IsLocal(addr string) bool {
|
||||
// extract the host
|
||||
// Extract the host
|
||||
host, _, err := net.SplitHostPort(addr)
|
||||
if err == nil {
|
||||
addr = host
|
||||
}
|
||||
|
||||
// check if its localhost
|
||||
if addr == "localhost" {
|
||||
return true
|
||||
}
|
||||
|
||||
// check against all local ips
|
||||
// Check against all local ips
|
||||
for _, ip := range IPs() {
|
||||
if addr == ip {
|
||||
return true
|
||||
@@ -59,80 +34,53 @@ func IsLocal(addr string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Extract returns a real ip
|
||||
// Extract returns a valid IP address. If the address provided is a valid
|
||||
// address, it will be returned directly. Otherwise the available interfaces
|
||||
// be itterated over to find an IP address, prefferably private.
|
||||
func Extract(addr string) (string, error) {
|
||||
// if addr specified then its returned
|
||||
// if addr is already specified then it's directly returned
|
||||
if len(addr) > 0 && (addr != "0.0.0.0" && addr != "[::]" && addr != "::") {
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
var (
|
||||
addrs []net.Addr
|
||||
loAddrs []net.Addr
|
||||
)
|
||||
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to get interfaces! Err: %v", err)
|
||||
return "", errors.Wrap(err, "failed to get interfaces")
|
||||
}
|
||||
|
||||
//nolint:prealloc
|
||||
var addrs []net.Addr
|
||||
var loAddrs []net.Addr
|
||||
for _, iface := range ifaces {
|
||||
ifaceAddrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
// ignore error, interface can disappear from system
|
||||
continue
|
||||
}
|
||||
|
||||
if iface.Flags&net.FlagLoopback != 0 {
|
||||
loAddrs = append(loAddrs, ifaceAddrs...)
|
||||
continue
|
||||
}
|
||||
|
||||
addrs = append(addrs, ifaceAddrs...)
|
||||
}
|
||||
|
||||
// Add loopback addresses to the end of the list
|
||||
addrs = append(addrs, loAddrs...)
|
||||
|
||||
var ipAddr string
|
||||
var publicIP string
|
||||
|
||||
for _, rawAddr := range addrs {
|
||||
var ip net.IP
|
||||
switch addr := rawAddr.(type) {
|
||||
case *net.IPAddr:
|
||||
ip = addr.IP
|
||||
case *net.IPNet:
|
||||
ip = addr.IP
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
if !isPrivateIP(ip.String()) {
|
||||
publicIP = ip.String()
|
||||
continue
|
||||
}
|
||||
|
||||
ipAddr = ip.String()
|
||||
break
|
||||
// Try to find private IP in list, public IP otherwise
|
||||
ip, err := findIP(addrs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// return private ip
|
||||
if len(ipAddr) > 0 {
|
||||
a := net.ParseIP(ipAddr)
|
||||
if a == nil {
|
||||
return "", fmt.Errorf("ip addr %s is invalid", ipAddr)
|
||||
}
|
||||
return a.String(), nil
|
||||
}
|
||||
|
||||
// return public or virtual ip
|
||||
if len(publicIP) > 0 {
|
||||
a := net.ParseIP(publicIP)
|
||||
if a == nil {
|
||||
return "", fmt.Errorf("ip addr %s is invalid", publicIP)
|
||||
}
|
||||
return a.String(), nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("No IP address found, and explicit IP not provided")
|
||||
return ip.String(), nil
|
||||
}
|
||||
|
||||
// IPs returns all known ips
|
||||
// IPs returns all available interface IP addresses.
|
||||
func IPs() []string {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
@@ -160,17 +108,42 @@ func IPs() []string {
|
||||
continue
|
||||
}
|
||||
|
||||
// dont skip ipv6 addrs
|
||||
/*
|
||||
ip = ip.To4()
|
||||
if ip == nil {
|
||||
continue
|
||||
}
|
||||
*/
|
||||
|
||||
ipAddrs = append(ipAddrs, ip.String())
|
||||
}
|
||||
}
|
||||
|
||||
return ipAddrs
|
||||
}
|
||||
|
||||
// findIP will return the first private IP available in the list,
|
||||
// if no private IP is available it will return a public IP if present.
|
||||
func findIP(addresses []net.Addr) (net.IP, error) {
|
||||
var publicIP net.IP
|
||||
|
||||
for _, rawAddr := range addresses {
|
||||
var ip net.IP
|
||||
switch addr := rawAddr.(type) {
|
||||
case *net.IPAddr:
|
||||
ip = addr.IP
|
||||
case *net.IPNet:
|
||||
ip = addr.IP
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
if !ip.IsPrivate() {
|
||||
publicIP = ip
|
||||
continue
|
||||
}
|
||||
|
||||
// Return private IP if available
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
// Return public or virtual IP
|
||||
if len(publicIP) > 0 {
|
||||
return publicIP, nil
|
||||
}
|
||||
|
||||
return nil, ErrIPNotFound
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import (
|
||||
type Cmd interface {
|
||||
// The cli app within this cmd
|
||||
App() *cli.App
|
||||
// Adds options, parses flags and initialise
|
||||
// Adds options, parses flags and initialize
|
||||
// exits on error
|
||||
Init(opts ...Option) error
|
||||
// Options set within this command
|
||||
|
||||
+35
-33
@@ -19,28 +19,31 @@ import (
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
// For the Command Line itself
|
||||
Name string
|
||||
Description string
|
||||
Version string
|
||||
|
||||
// We need pointers to things so we can swap them out if needed.
|
||||
Broker *broker.Broker
|
||||
Registry *registry.Registry
|
||||
Selector *selector.Selector
|
||||
// Other options for implementations of the interface
|
||||
// can be stored in a context
|
||||
Context context.Context
|
||||
Auth *auth.Auth
|
||||
Selector *selector.Selector
|
||||
Profile *profile.Profile
|
||||
|
||||
Registry *registry.Registry
|
||||
|
||||
Brokers map[string]func(...broker.Option) broker.Broker
|
||||
Transport *transport.Transport
|
||||
Cache *cache.Cache
|
||||
Config *config.Config
|
||||
Client *client.Client
|
||||
Server *server.Server
|
||||
Runtime *runtime.Runtime
|
||||
Store *store.Store
|
||||
Caches map[string]func(...cache.Option) cache.Cache
|
||||
Tracer *trace.Tracer
|
||||
Auth *auth.Auth
|
||||
Profile *profile.Profile
|
||||
Profiles map[string]func(...profile.Option) profile.Profile
|
||||
|
||||
Brokers map[string]func(...broker.Option) broker.Broker
|
||||
Caches map[string]func(...cache.Option) cache.Cache
|
||||
// We need pointers to things so we can swap them out if needed.
|
||||
Broker *broker.Broker
|
||||
Auths map[string]func(...auth.Option) auth.Auth
|
||||
Store *store.Store
|
||||
Configs map[string]func(...config.Option) (config.Config, error)
|
||||
Clients map[string]func(...client.Option) client.Client
|
||||
Registries map[string]func(...registry.Option) registry.Registry
|
||||
@@ -50,29 +53,28 @@ type Options struct {
|
||||
Runtimes map[string]func(...runtime.Option) runtime.Runtime
|
||||
Stores map[string]func(...store.Option) store.Store
|
||||
Tracers map[string]func(...trace.Option) trace.Tracer
|
||||
Auths map[string]func(...auth.Option) auth.Auth
|
||||
Profiles map[string]func(...profile.Option) profile.Profile
|
||||
Version string
|
||||
|
||||
// Other options for implementations of the interface
|
||||
// can be stored in a context
|
||||
Context context.Context
|
||||
// For the Command Line itself
|
||||
Name string
|
||||
Description string
|
||||
}
|
||||
|
||||
// Command line Name
|
||||
// Command line Name.
|
||||
func Name(n string) Option {
|
||||
return func(o *Options) {
|
||||
o.Name = n
|
||||
}
|
||||
}
|
||||
|
||||
// Command line Description
|
||||
// Command line Description.
|
||||
func Description(d string) Option {
|
||||
return func(o *Options) {
|
||||
o.Description = d
|
||||
}
|
||||
}
|
||||
|
||||
// Command line Version
|
||||
// Command line Version.
|
||||
func Version(v string) Option {
|
||||
return func(o *Options) {
|
||||
o.Version = v
|
||||
@@ -157,84 +159,84 @@ func Profile(p *profile.Profile) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// New broker func
|
||||
// New broker func.
|
||||
func NewBroker(name string, b func(...broker.Option) broker.Broker) Option {
|
||||
return func(o *Options) {
|
||||
o.Brokers[name] = b
|
||||
}
|
||||
}
|
||||
|
||||
// New cache func
|
||||
// New cache func.
|
||||
func NewCache(name string, c func(...cache.Option) cache.Cache) Option {
|
||||
return func(o *Options) {
|
||||
o.Caches[name] = c
|
||||
}
|
||||
}
|
||||
|
||||
// New client func
|
||||
// New client func.
|
||||
func NewClient(name string, b func(...client.Option) client.Client) Option {
|
||||
return func(o *Options) {
|
||||
o.Clients[name] = b
|
||||
}
|
||||
}
|
||||
|
||||
// New registry func
|
||||
// New registry func.
|
||||
func NewRegistry(name string, r func(...registry.Option) registry.Registry) Option {
|
||||
return func(o *Options) {
|
||||
o.Registries[name] = r
|
||||
}
|
||||
}
|
||||
|
||||
// New selector func
|
||||
// New selector func.
|
||||
func NewSelector(name string, s func(...selector.Option) selector.Selector) Option {
|
||||
return func(o *Options) {
|
||||
o.Selectors[name] = s
|
||||
}
|
||||
}
|
||||
|
||||
// New server func
|
||||
// New server func.
|
||||
func NewServer(name string, s func(...server.Option) server.Server) Option {
|
||||
return func(o *Options) {
|
||||
o.Servers[name] = s
|
||||
}
|
||||
}
|
||||
|
||||
// New transport func
|
||||
// New transport func.
|
||||
func NewTransport(name string, t func(...transport.Option) transport.Transport) Option {
|
||||
return func(o *Options) {
|
||||
o.Transports[name] = t
|
||||
}
|
||||
}
|
||||
|
||||
// New runtime func
|
||||
// New runtime func.
|
||||
func NewRuntime(name string, r func(...runtime.Option) runtime.Runtime) Option {
|
||||
return func(o *Options) {
|
||||
o.Runtimes[name] = r
|
||||
}
|
||||
}
|
||||
|
||||
// New tracer func
|
||||
// New tracer func.
|
||||
func NewTracer(name string, t func(...trace.Option) trace.Tracer) Option {
|
||||
return func(o *Options) {
|
||||
o.Tracers[name] = t
|
||||
}
|
||||
}
|
||||
|
||||
// New auth func
|
||||
// New auth func.
|
||||
func NewAuth(name string, t func(...auth.Option) auth.Auth) Option {
|
||||
return func(o *Options) {
|
||||
o.Auths[name] = t
|
||||
}
|
||||
}
|
||||
|
||||
// New config func
|
||||
// New config func.
|
||||
func NewConfig(name string, t func(...config.Option) (config.Config, error)) Option {
|
||||
return func(o *Options) {
|
||||
o.Configs[name] = t
|
||||
}
|
||||
}
|
||||
|
||||
// New profile func
|
||||
// New profile func.
|
||||
func NewProfile(name string, t func(...profile.Option) profile.Profile) Option {
|
||||
return func(o *Options) {
|
||||
o.Profiles[name] = t
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ import (
|
||||
// Input:
|
||||
// Foo.Bar, /Foo/Bar, /package.Foo/Bar, /a.package.Foo/Bar
|
||||
// Output:
|
||||
// [Foo, Bar]
|
||||
// [Foo, Bar].
|
||||
func ServiceMethod(m string) (string, string, error) {
|
||||
if len(m) == 0 {
|
||||
return "", "", fmt.Errorf("malformed method name: %q", m)
|
||||
@@ -40,7 +40,7 @@ func ServiceMethod(m string) (string, string, error) {
|
||||
}
|
||||
|
||||
// ServiceFromMethod returns the service
|
||||
// /service.Foo/Bar => service
|
||||
// /service.Foo/Bar => service.
|
||||
func ServiceFromMethod(m string) string {
|
||||
if len(m) == 0 {
|
||||
return m
|
||||
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
# Log
|
||||
|
||||
DEPRECATED: use go-micro.dev/v4/logger interface
|
||||
|
||||
This is the global logger for all micro based libraries.
|
||||
|
||||
## Set Logger
|
||||
|
||||
Set the logger for micro libraries
|
||||
|
||||
```go
|
||||
// import go-micro/util/log
|
||||
import "github.com/micro/go-micro/util/log"
|
||||
|
||||
// SetLogger expects github.com/micro/go-micro/debug/log.Log interface
|
||||
log.SetLogger(mylogger)
|
||||
```
|
||||
-227
@@ -1,227 +0,0 @@
|
||||
// Package log is a global internal logger
|
||||
// DEPRECATED: this is frozen package, use go-micro.dev/v4/logger
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
|
||||
dlog "go-micro.dev/v4/debug/log"
|
||||
nlog "go-micro.dev/v4/logger"
|
||||
)
|
||||
|
||||
// level is a log level
|
||||
type Level int32
|
||||
|
||||
const (
|
||||
LevelFatal Level = iota
|
||||
LevelError
|
||||
LevelWarn
|
||||
LevelInfo
|
||||
LevelDebug
|
||||
LevelTrace
|
||||
)
|
||||
|
||||
type elog struct {
|
||||
dlog dlog.Log
|
||||
}
|
||||
|
||||
var (
|
||||
// the local logger
|
||||
logger dlog.Log = &elog{}
|
||||
|
||||
// default log level is info
|
||||
level = LevelInfo
|
||||
|
||||
// prefix for all messages
|
||||
prefix string
|
||||
)
|
||||
|
||||
func levelToLevel(l Level) nlog.Level {
|
||||
switch l {
|
||||
case LevelTrace:
|
||||
return nlog.TraceLevel
|
||||
case LevelDebug:
|
||||
return nlog.DebugLevel
|
||||
case LevelWarn:
|
||||
return nlog.WarnLevel
|
||||
case LevelInfo:
|
||||
return nlog.InfoLevel
|
||||
case LevelError:
|
||||
return nlog.ErrorLevel
|
||||
case LevelFatal:
|
||||
return nlog.FatalLevel
|
||||
}
|
||||
return nlog.InfoLevel
|
||||
}
|
||||
|
||||
func init() {
|
||||
switch os.Getenv("MICRO_LOG_LEVEL") {
|
||||
case "trace":
|
||||
level = LevelTrace
|
||||
case "debug":
|
||||
level = LevelDebug
|
||||
case "warn":
|
||||
level = LevelWarn
|
||||
case "info":
|
||||
level = LevelInfo
|
||||
case "error":
|
||||
level = LevelError
|
||||
case "fatal":
|
||||
level = LevelFatal
|
||||
}
|
||||
}
|
||||
|
||||
func (l Level) String() string {
|
||||
switch l {
|
||||
case LevelTrace:
|
||||
return "trace"
|
||||
case LevelDebug:
|
||||
return "debug"
|
||||
case LevelWarn:
|
||||
return "warn"
|
||||
case LevelInfo:
|
||||
return "info"
|
||||
case LevelError:
|
||||
return "error"
|
||||
case LevelFatal:
|
||||
return "fatal"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
func (el *elog) Read(opt ...dlog.ReadOption) ([]dlog.Record, error) {
|
||||
return el.dlog.Read(opt...)
|
||||
}
|
||||
|
||||
func (el *elog) Write(r dlog.Record) error {
|
||||
return el.dlog.Write(r)
|
||||
}
|
||||
|
||||
func (el *elog) Stream() (dlog.Stream, error) {
|
||||
return el.dlog.Stream()
|
||||
}
|
||||
|
||||
// Log makes use of github.com/micro/debug/log
|
||||
func Log(v ...interface{}) {
|
||||
if len(prefix) > 0 {
|
||||
v = append([]interface{}{prefix, " "}, v...)
|
||||
}
|
||||
nlog.DefaultLogger.Log(levelToLevel(level), v)
|
||||
}
|
||||
|
||||
// Logf makes use of github.com/micro/debug/log
|
||||
func Logf(format string, v ...interface{}) {
|
||||
if len(prefix) > 0 {
|
||||
format = prefix + " " + format
|
||||
}
|
||||
nlog.DefaultLogger.Logf(levelToLevel(level), format, v)
|
||||
}
|
||||
|
||||
// WithLevel logs with the level specified
|
||||
func WithLevel(l Level, v ...interface{}) {
|
||||
if l > level {
|
||||
return
|
||||
}
|
||||
Log(v...)
|
||||
}
|
||||
|
||||
// WithLevel logs with the level specified
|
||||
func WithLevelf(l Level, format string, v ...interface{}) {
|
||||
if l > level {
|
||||
return
|
||||
}
|
||||
Logf(format, v...)
|
||||
}
|
||||
|
||||
// Trace provides trace level logging
|
||||
func Trace(v ...interface{}) {
|
||||
WithLevel(LevelTrace, v...)
|
||||
}
|
||||
|
||||
// Tracef provides trace level logging
|
||||
func Tracef(format string, v ...interface{}) {
|
||||
WithLevelf(LevelTrace, format, v...)
|
||||
}
|
||||
|
||||
// Debug provides debug level logging
|
||||
func Debug(v ...interface{}) {
|
||||
WithLevel(LevelDebug, v...)
|
||||
}
|
||||
|
||||
// Debugf provides debug level logging
|
||||
func Debugf(format string, v ...interface{}) {
|
||||
WithLevelf(LevelDebug, format, v...)
|
||||
}
|
||||
|
||||
// Warn provides warn level logging
|
||||
func Warn(v ...interface{}) {
|
||||
WithLevel(LevelWarn, v...)
|
||||
}
|
||||
|
||||
// Warnf provides warn level logging
|
||||
func Warnf(format string, v ...interface{}) {
|
||||
WithLevelf(LevelWarn, format, v...)
|
||||
}
|
||||
|
||||
// Info provides info level logging
|
||||
func Info(v ...interface{}) {
|
||||
WithLevel(LevelInfo, v...)
|
||||
}
|
||||
|
||||
// Infof provides info level logging
|
||||
func Infof(format string, v ...interface{}) {
|
||||
WithLevelf(LevelInfo, format, v...)
|
||||
}
|
||||
|
||||
// Error provides warn level logging
|
||||
func Error(v ...interface{}) {
|
||||
WithLevel(LevelError, v...)
|
||||
}
|
||||
|
||||
// Errorf provides warn level logging
|
||||
func Errorf(format string, v ...interface{}) {
|
||||
WithLevelf(LevelError, format, v...)
|
||||
}
|
||||
|
||||
// Fatal logs with Log and then exits with os.Exit(1)
|
||||
func Fatal(v ...interface{}) {
|
||||
WithLevel(LevelFatal, v...)
|
||||
}
|
||||
|
||||
// Fatalf logs with Logf and then exits with os.Exit(1)
|
||||
func Fatalf(format string, v ...interface{}) {
|
||||
WithLevelf(LevelFatal, format, v...)
|
||||
}
|
||||
|
||||
// SetLogger sets the local logger
|
||||
func SetLogger(l dlog.Log) {
|
||||
logger = l
|
||||
}
|
||||
|
||||
// GetLogger returns the local logger
|
||||
func GetLogger() dlog.Log {
|
||||
return logger
|
||||
}
|
||||
|
||||
// SetLevel sets the log level
|
||||
func SetLevel(l Level) {
|
||||
atomic.StoreInt32((*int32)(&level), int32(l))
|
||||
}
|
||||
|
||||
// GetLevel returns the current level
|
||||
func GetLevel() Level {
|
||||
return level
|
||||
}
|
||||
|
||||
// Set a prefix for the logger
|
||||
func SetPrefix(p string) {
|
||||
prefix = p
|
||||
}
|
||||
|
||||
// Set service name
|
||||
func Name(name string) {
|
||||
prefix = fmt.Sprintf("[%s]", name)
|
||||
}
|
||||
+28
-28
@@ -9,49 +9,48 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"go-micro.dev/v4/logger"
|
||||
"golang.org/x/net/ipv4"
|
||||
"golang.org/x/net/ipv6"
|
||||
|
||||
"go-micro.dev/v4/logger"
|
||||
)
|
||||
|
||||
// ServiceEntry is returned after we query for a service
|
||||
// ServiceEntry is returned after we query for a service.
|
||||
type ServiceEntry struct {
|
||||
Name string
|
||||
Host string
|
||||
Info string
|
||||
AddrV4 net.IP
|
||||
AddrV6 net.IP
|
||||
Port int
|
||||
Info string
|
||||
InfoFields []string
|
||||
TTL int
|
||||
Type uint16
|
||||
|
||||
Addr net.IP // @Deprecated
|
||||
|
||||
Port int
|
||||
TTL int
|
||||
Type uint16
|
||||
|
||||
hasTXT bool
|
||||
sent bool
|
||||
}
|
||||
|
||||
// complete is used to check if we have all the info we need
|
||||
// complete is used to check if we have all the info we need.
|
||||
func (s *ServiceEntry) complete() bool {
|
||||
|
||||
return (len(s.AddrV4) > 0 || len(s.AddrV6) > 0 || len(s.Addr) > 0) && s.Port != 0 && s.hasTXT
|
||||
}
|
||||
|
||||
// QueryParam is used to customize how a Lookup is performed
|
||||
// QueryParam is used to customize how a Lookup is performed.
|
||||
type QueryParam struct {
|
||||
Service string // Service to lookup
|
||||
Domain string // Lookup domain, default "local"
|
||||
Type uint16 // Lookup type, defaults to dns.TypePTR
|
||||
Context context.Context // Context
|
||||
Timeout time.Duration // Lookup timeout, default 1 second. Ignored if Context is provided
|
||||
Interface *net.Interface // Multicast interface to use
|
||||
Entries chan<- *ServiceEntry // Entries Channel
|
||||
Service string // Service to lookup
|
||||
Domain string // Lookup domain, default "local"
|
||||
Timeout time.Duration // Lookup timeout, default 1 second. Ignored if Context is provided
|
||||
Type uint16 // Lookup type, defaults to dns.TypePTR
|
||||
WantUnicastResponse bool // Unicast response desired, as per 5.4 in RFC
|
||||
}
|
||||
|
||||
// DefaultParams is used to return a default set of QueryParam's
|
||||
// DefaultParams is used to return a default set of QueryParam's.
|
||||
func DefaultParams(service string) *QueryParam {
|
||||
return &QueryParam{
|
||||
Service: service,
|
||||
@@ -100,7 +99,7 @@ func Query(params *QueryParam) error {
|
||||
return client.query(params)
|
||||
}
|
||||
|
||||
// Listen listens indefinitely for multicast updates
|
||||
// Listen listens indefinitely for multicast updates.
|
||||
func Listen(entries chan<- *ServiceEntry, exit chan struct{}) error {
|
||||
// Create a new client
|
||||
client, err := newClient()
|
||||
@@ -156,7 +155,7 @@ func Listen(entries chan<- *ServiceEntry, exit chan struct{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Lookup is the same as Query, however it uses all the default parameters
|
||||
// Lookup is the same as Query, however it uses all the default parameters.
|
||||
func Lookup(service string, entries chan<- *ServiceEntry) error {
|
||||
params := DefaultParams(service)
|
||||
params.Entries = entries
|
||||
@@ -164,7 +163,7 @@ func Lookup(service string, entries chan<- *ServiceEntry) error {
|
||||
}
|
||||
|
||||
// Client provides a query interface that can be used to
|
||||
// search for service providers using mDNS
|
||||
// search for service providers using mDNS.
|
||||
type client struct {
|
||||
ipv4UnicastConn *net.UDPConn
|
||||
ipv6UnicastConn *net.UDPConn
|
||||
@@ -172,13 +171,14 @@ type client struct {
|
||||
ipv4MulticastConn *net.UDPConn
|
||||
ipv6MulticastConn *net.UDPConn
|
||||
|
||||
closed bool
|
||||
closedCh chan struct{} // TODO(reddaly): This doesn't appear to be used.
|
||||
closeLock sync.Mutex
|
||||
|
||||
closed bool
|
||||
}
|
||||
|
||||
// NewClient creates a new mdns Client that can be used to query
|
||||
// for records
|
||||
// for records.
|
||||
func newClient() (*client, error) {
|
||||
// TODO(reddaly): At least attempt to bind to the port required in the spec.
|
||||
// Create a IPv4 listener
|
||||
@@ -253,7 +253,7 @@ func newClient() (*client, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Close is used to cleanup the client
|
||||
// Close is used to cleanup the client.
|
||||
func (c *client) Close() error {
|
||||
c.closeLock.Lock()
|
||||
defer c.closeLock.Unlock()
|
||||
@@ -281,8 +281,8 @@ func (c *client) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// setInterface is used to set the query interface, uses sytem
|
||||
// default if not provided
|
||||
// setInterface is used to set the query interface, uses system
|
||||
// default if not provided.
|
||||
func (c *client) setInterface(iface *net.Interface, loopback bool) error {
|
||||
p := ipv4.NewPacketConn(c.ipv4UnicastConn)
|
||||
if err := p.JoinGroup(iface, &net.UDPAddr{IP: mdnsGroupIPv4}); err != nil {
|
||||
@@ -309,7 +309,7 @@ func (c *client) setInterface(iface *net.Interface, loopback bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// query is used to perform a lookup and stream results
|
||||
// query is used to perform a lookup and stream results.
|
||||
func (c *client) query(params *QueryParam) error {
|
||||
// Create the service name
|
||||
serviceAddr := fmt.Sprintf("%s.%s.", trimDot(params.Service), trimDot(params.Domain))
|
||||
@@ -385,7 +385,7 @@ func (c *client) query(params *QueryParam) error {
|
||||
}
|
||||
}
|
||||
|
||||
// sendQuery is used to multicast a query out
|
||||
// sendQuery is used to multicast a query out.
|
||||
func (c *client) sendQuery(q *dns.Msg) error {
|
||||
buf, err := q.Pack()
|
||||
if err != nil {
|
||||
@@ -400,7 +400,7 @@ func (c *client) sendQuery(q *dns.Msg) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// recv is used to receive until we get a shutdown
|
||||
// recv is used to receive until we get a shutdown.
|
||||
func (c *client) recv(l *net.UDPConn, msgCh chan *dns.Msg) {
|
||||
if l == nil {
|
||||
return
|
||||
@@ -429,7 +429,7 @@ func (c *client) recv(l *net.UDPConn, msgCh chan *dns.Msg) {
|
||||
}
|
||||
}
|
||||
|
||||
// ensureName is used to ensure the named node is in progress
|
||||
// ensureName is used to ensure the named node is in progress.
|
||||
func ensureName(inprogress map[string]*ServiceEntry, name string, typ uint16) *ServiceEntry {
|
||||
if inp, ok := inprogress[name]; ok {
|
||||
return inp
|
||||
@@ -442,7 +442,7 @@ func ensureName(inprogress map[string]*ServiceEntry, name string, typ uint16) *S
|
||||
return inp
|
||||
}
|
||||
|
||||
// alias is used to setup an alias between two entries
|
||||
// alias is used to setup an alias between two entries.
|
||||
func alias(inprogress map[string]*ServiceEntry, src, dst string, typ uint16) {
|
||||
srcEntry := ensureName(inprogress, src, typ)
|
||||
inprogress[dst] = srcEntry
|
||||
|
||||
+2
-2
@@ -46,7 +46,7 @@ func (s *DNSSDService) Records(q dns.Question) []dns.RR {
|
||||
// issued to browse for DNS-SD services, as per section 9. of RFC6763.
|
||||
//
|
||||
// A meta-query has a name of the form "_services._dns-sd._udp.<Domain>" where
|
||||
// Domain is a fully-qualified domain, such as "local."
|
||||
// Domain is a fully-qualified domain, such as "local.".
|
||||
func (s *DNSSDService) dnssdMetaQueryRecords(q dns.Question) []dns.RR {
|
||||
// Intended behavior, as described in the RFC:
|
||||
// ...it may be useful for network administrators to find the list of
|
||||
@@ -80,6 +80,6 @@ func (s *DNSSDService) dnssdMetaQueryRecords(q dns.Question) []dns.RR {
|
||||
// Announcement returns DNS records that should be broadcast during the initial
|
||||
// availability of the service, as described in section 8.3 of RFC 6762.
|
||||
// TODO(reddaly): Add this when Announcement is added to the mdns.Zone interface.
|
||||
//func (s *DNSSDService) Announcement() []dns.RR {
|
||||
// func (s *DNSSDService) Announcement() []dns.RR {
|
||||
// return s.MDNSService.Announcement()
|
||||
//}
|
||||
|
||||
+21
-20
@@ -18,7 +18,7 @@ var (
|
||||
mdnsGroupIPv4 = net.ParseIP("224.0.0.251")
|
||||
mdnsGroupIPv6 = net.ParseIP("ff02::fb")
|
||||
|
||||
// mDNS wildcard addresses
|
||||
// mDNS wildcard addresses.
|
||||
mdnsWildcardAddrIPv4 = &net.UDPAddr{
|
||||
IP: net.ParseIP("224.0.0.0"),
|
||||
Port: 5353,
|
||||
@@ -28,7 +28,7 @@ var (
|
||||
Port: 5353,
|
||||
}
|
||||
|
||||
// mDNS endpoint addresses
|
||||
// mDNS endpoint addresses.
|
||||
ipv4Addr = &net.UDPAddr{
|
||||
IP: mdnsGroupIPv4,
|
||||
Port: 5353,
|
||||
@@ -40,10 +40,10 @@ var (
|
||||
)
|
||||
|
||||
// GetMachineIP is a func which returns the outbound IP of this machine.
|
||||
// Used by the server to determine whether to attempt send the response on a local address
|
||||
// Used by the server to determine whether to attempt send the response on a local address.
|
||||
type GetMachineIP func() net.IP
|
||||
|
||||
// Config is used to configure the mDNS server
|
||||
// Config is used to configure the mDNS server.
|
||||
type Config struct {
|
||||
// Zone must be provided to support responding to queries
|
||||
Zone Zone
|
||||
@@ -53,33 +53,36 @@ type Config struct {
|
||||
// is used.
|
||||
Iface *net.Interface
|
||||
|
||||
// GetMachineIP is a function to return the IP of the local machine
|
||||
GetMachineIP GetMachineIP
|
||||
|
||||
// Port If it is not 0, replace the port 5353 with this port number.
|
||||
Port int
|
||||
|
||||
// GetMachineIP is a function to return the IP of the local machine
|
||||
GetMachineIP GetMachineIP
|
||||
// LocalhostChecking if enabled asks the server to also send responses to 0.0.0.0 if the target IP
|
||||
// is this host (as defined by GetMachineIP). Useful in case machine is on a VPN which blocks comms on non standard ports
|
||||
LocalhostChecking bool
|
||||
}
|
||||
|
||||
// Server is an mDNS server used to listen for mDNS queries and respond if we
|
||||
// have a matching local record
|
||||
// have a matching local record.
|
||||
type Server struct {
|
||||
config *Config
|
||||
|
||||
ipv4List *net.UDPConn
|
||||
ipv6List *net.UDPConn
|
||||
|
||||
shutdown bool
|
||||
shutdownCh chan struct{}
|
||||
shutdownLock sync.Mutex
|
||||
wg sync.WaitGroup
|
||||
shutdownCh chan struct{}
|
||||
|
||||
outboundIP net.IP
|
||||
wg sync.WaitGroup
|
||||
|
||||
shutdownLock sync.Mutex
|
||||
|
||||
shutdown bool
|
||||
}
|
||||
|
||||
// NewServer is used to create a new mDNS server from a config
|
||||
// NewServer is used to create a new mDNS server from a config.
|
||||
func NewServer(config *Config) (*Server, error) {
|
||||
setCustomPort(config.Port)
|
||||
|
||||
@@ -152,7 +155,7 @@ func NewServer(config *Config) (*Server, error) {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// Shutdown is used to shutdown the listener
|
||||
// Shutdown is used to shutdown the listener.
|
||||
func (s *Server) Shutdown() error {
|
||||
s.shutdownLock.Lock()
|
||||
defer s.shutdownLock.Unlock()
|
||||
@@ -176,7 +179,7 @@ func (s *Server) Shutdown() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// recv is a long running routine to receive packets from an interface
|
||||
// recv is a long running routine to receive packets from an interface.
|
||||
func (s *Server) recv(c *net.UDPConn) {
|
||||
if c == nil {
|
||||
return
|
||||
@@ -199,7 +202,7 @@ func (s *Server) recv(c *net.UDPConn) {
|
||||
}
|
||||
}
|
||||
|
||||
// parsePacket is used to parse an incoming packet
|
||||
// parsePacket is used to parse an incoming packet.
|
||||
func (s *Server) parsePacket(packet []byte, from net.Addr) error {
|
||||
var msg dns.Msg
|
||||
if err := msg.Unpack(packet); err != nil {
|
||||
@@ -213,7 +216,7 @@ func (s *Server) parsePacket(packet []byte, from net.Addr) error {
|
||||
return s.handleQuery(&msg, from)
|
||||
}
|
||||
|
||||
// handleQuery is used to handle an incoming query
|
||||
// handleQuery is used to handle an incoming query.
|
||||
func (s *Server) handleQuery(query *dns.Msg, from net.Addr) error {
|
||||
if query.Opcode != dns.OpcodeQuery {
|
||||
// "In both multicast query and multicast response messages, the OPCODE MUST
|
||||
@@ -421,7 +424,7 @@ func (s *Server) probe() {
|
||||
}
|
||||
}
|
||||
|
||||
// SendMulticast us used to send a multicast response packet
|
||||
// SendMulticast us used to send a multicast response packet.
|
||||
func (s *Server) SendMulticast(msg *dns.Msg) error {
|
||||
buf, err := msg.Pack()
|
||||
if err != nil {
|
||||
@@ -436,7 +439,7 @@ func (s *Server) SendMulticast(msg *dns.Msg) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// sendResponse is used to send a response packet
|
||||
// sendResponse is used to send a response packet.
|
||||
func (s *Server) sendResponse(resp *dns.Msg, from net.Addr) error {
|
||||
// TODO(reddaly): Respect the unicast argument, and allow sending responses
|
||||
// over multicast.
|
||||
@@ -463,7 +466,6 @@ func (s *Server) sendResponse(resp *dns.Msg, from net.Addr) error {
|
||||
conn.WriteToUDP(buf, &net.UDPAddr{IP: backupTarget, Port: addr.Port})
|
||||
}
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
func (s *Server) unregister() error {
|
||||
@@ -502,7 +504,6 @@ func setCustomPort(port int) {
|
||||
}
|
||||
}
|
||||
|
||||
// getOutboundIP returns the IP address of this machine as seen when dialling out
|
||||
func getOutboundIP() net.IP {
|
||||
conn, err := net.Dial("udp", "8.8.8.8:80")
|
||||
if err != nil {
|
||||
|
||||
+9
-9
@@ -16,25 +16,25 @@ const (
|
||||
)
|
||||
|
||||
// Zone is the interface used to integrate with the server and
|
||||
// to serve records dynamically
|
||||
// to serve records dynamically.
|
||||
type Zone interface {
|
||||
// Records returns DNS records in response to a DNS question.
|
||||
Records(q dns.Question) []dns.RR
|
||||
}
|
||||
|
||||
// MDNSService is used to export a named service by implementing a Zone
|
||||
// MDNSService is used to export a named service by implementing a Zone.
|
||||
type MDNSService struct {
|
||||
Instance string // Instance name (e.g. "hostService name")
|
||||
Service string // Service name (e.g. "_http._tcp.")
|
||||
Domain string // If blank, assumes "local"
|
||||
HostName string // Host machine DNS name (e.g. "mymachine.net.")
|
||||
Port int // Service Port
|
||||
serviceAddr string // Fully qualified service address
|
||||
instanceAddr string // Fully qualified instance address
|
||||
enumAddr string // _services._dns-sd._udp.<domain>
|
||||
IPs []net.IP // IP addresses for the service's host
|
||||
TXT []string // Service TXT records
|
||||
Port int // Service Port
|
||||
TTL uint32
|
||||
serviceAddr string // Fully qualified service address
|
||||
instanceAddr string // Fully qualified instance address
|
||||
enumAddr string // _services._dns-sd._udp.<domain>
|
||||
}
|
||||
|
||||
// validateFQDN returns an error if the passed string is not a fully qualified
|
||||
@@ -130,7 +130,7 @@ func NewMDNSService(instance, service, domain, hostName string, port int, ips []
|
||||
}, nil
|
||||
}
|
||||
|
||||
// trimDot is used to trim the dots from the start or end of a string
|
||||
// trimDot is used to trim the dots from the start or end of a string.
|
||||
func trimDot(s string) string {
|
||||
return strings.Trim(s, ".")
|
||||
}
|
||||
@@ -174,7 +174,7 @@ func (m *MDNSService) serviceEnum(q dns.Question) []dns.RR {
|
||||
}
|
||||
}
|
||||
|
||||
// serviceRecords is called when the query matches the service name
|
||||
// serviceRecords is called when the query matches the service name.
|
||||
func (m *MDNSService) serviceRecords(q dns.Question) []dns.RR {
|
||||
switch q.Qtype {
|
||||
case dns.TypeANY:
|
||||
@@ -205,7 +205,7 @@ func (m *MDNSService) serviceRecords(q dns.Question) []dns.RR {
|
||||
}
|
||||
}
|
||||
|
||||
// serviceRecords is called when the query matches the instance name
|
||||
// serviceRecords is called when the query matches the instance name.
|
||||
func (m *MDNSService) instanceRecords(q dns.Question) []dns.RR {
|
||||
switch q.Qtype {
|
||||
case dns.TypeANY:
|
||||
|
||||
+3
-4
@@ -9,7 +9,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// HostPort format addr and port suitable for dial
|
||||
// HostPort format addr and port suitable for dial.
|
||||
func HostPort(addr string, port interface{}) string {
|
||||
host := addr
|
||||
if strings.Count(addr, ":") > 0 {
|
||||
@@ -26,9 +26,8 @@ func HostPort(addr string, port interface{}) string {
|
||||
}
|
||||
|
||||
// Listen takes addr:portmin-portmax and binds to the first available port
|
||||
// Example: Listen("localhost:5000-6000", fn)
|
||||
// Example: Listen("localhost:5000-6000", fn).
|
||||
func Listen(addr string, fn func(string) (net.Listener, error)) (net.Listener, error) {
|
||||
|
||||
if strings.Count(addr, ":") == 1 && strings.Count(addr, "-") == 0 {
|
||||
return fn(addr)
|
||||
}
|
||||
@@ -79,7 +78,7 @@ func Listen(addr string, fn func(string) (net.Listener, error)) (net.Listener, e
|
||||
return nil, fmt.Errorf("unable to bind to %s", addr)
|
||||
}
|
||||
|
||||
// Proxy returns the proxy and the address if it exits
|
||||
// Proxy returns the proxy and the address if it exits.
|
||||
func Proxy(service string, address []string) (string, []string, bool) {
|
||||
var hasProxy bool
|
||||
|
||||
|
||||
+31
-16
@@ -5,22 +5,24 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"go-micro.dev/v4/transport"
|
||||
)
|
||||
|
||||
type pool struct {
|
||||
size int
|
||||
ttl time.Duration
|
||||
tr transport.Transport
|
||||
tr transport.Transport
|
||||
|
||||
conns map[string][]*poolConn
|
||||
size int
|
||||
ttl time.Duration
|
||||
|
||||
sync.Mutex
|
||||
conns map[string][]*poolConn
|
||||
}
|
||||
|
||||
type poolConn struct {
|
||||
transport.Client
|
||||
id string
|
||||
created time.Time
|
||||
transport.Client
|
||||
id string
|
||||
}
|
||||
|
||||
func newPool(options Options) *pool {
|
||||
@@ -34,17 +36,24 @@ func newPool(options Options) *pool {
|
||||
|
||||
func (p *pool) Close() error {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
|
||||
var err error
|
||||
|
||||
for k, c := range p.conns {
|
||||
for _, conn := range c {
|
||||
conn.Client.Close()
|
||||
if nerr := conn.Client.Close(); nerr != nil {
|
||||
err = nerr
|
||||
}
|
||||
}
|
||||
|
||||
delete(p.conns, k)
|
||||
}
|
||||
p.Unlock()
|
||||
return nil
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// NoOp the Close since we manage it
|
||||
// NoOp the Close since we manage it.
|
||||
func (p *poolConn) Close() error {
|
||||
return nil
|
||||
}
|
||||
@@ -61,20 +70,24 @@ func (p *pool) Get(addr string, opts ...transport.DialOption) (Conn, error) {
|
||||
p.Lock()
|
||||
conns := p.conns[addr]
|
||||
|
||||
// while we have conns check age and then return one
|
||||
// While we have conns check age and then return one
|
||||
// otherwise we'll create a new conn
|
||||
for len(conns) > 0 {
|
||||
conn := conns[len(conns)-1]
|
||||
conns = conns[:len(conns)-1]
|
||||
p.conns[addr] = conns
|
||||
|
||||
// if conn is old kill it and move on
|
||||
// If conn is old kill it and move on
|
||||
if d := time.Since(conn.Created()); d > p.ttl {
|
||||
conn.Client.Close()
|
||||
if err := conn.Client.Close(); err != nil {
|
||||
p.Unlock()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// we got a good conn, lets unlock and return it
|
||||
// We got a good conn, lets unlock and return it
|
||||
p.Unlock()
|
||||
|
||||
return conn, nil
|
||||
@@ -87,6 +100,7 @@ func (p *pool) Get(addr string, opts ...transport.DialOption) (Conn, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &poolConn{
|
||||
Client: c,
|
||||
id: uuid.New().String(),
|
||||
@@ -102,13 +116,14 @@ func (p *pool) Release(conn Conn, err error) error {
|
||||
|
||||
// otherwise put it back for reuse
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
|
||||
conns := p.conns[conn.Remote()]
|
||||
if len(conns) >= p.size {
|
||||
p.Unlock()
|
||||
return conn.(*poolConn).Client.Close()
|
||||
}
|
||||
|
||||
p.conns[conn.Remote()] = append(conns, conn.(*poolConn))
|
||||
p.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+5
-2
@@ -7,16 +7,17 @@ import (
|
||||
"go-micro.dev/v4/transport"
|
||||
)
|
||||
|
||||
// Pool is an interface for connection pooling
|
||||
// Pool is an interface for connection pooling.
|
||||
type Pool interface {
|
||||
// Close the pool
|
||||
Close() error
|
||||
// Get a connection
|
||||
Get(addr string, opts ...transport.DialOption) (Conn, error)
|
||||
// Releaes the connection
|
||||
// Release the connection
|
||||
Release(c Conn, status error) error
|
||||
}
|
||||
|
||||
// Conn interface represents a pool connection.
|
||||
type Conn interface {
|
||||
// unique id of connection
|
||||
Id() string
|
||||
@@ -26,10 +27,12 @@ type Conn interface {
|
||||
transport.Client
|
||||
}
|
||||
|
||||
// NewPool will return a new pool object.
|
||||
func NewPool(opts ...Option) Pool {
|
||||
var options Options
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
return newPool(options)
|
||||
}
|
||||
|
||||
+1
@@ -24,6 +24,7 @@ func mergeMap(a map[string]interface{}, b map[string]interface{}) map[string]int
|
||||
a[bK] = bV
|
||||
}
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
|
||||
+15
-3
@@ -16,13 +16,13 @@ import (
|
||||
var (
|
||||
// ErrInvalidParam is returned when invalid data is provided to the ToJSON or Unmarshal function.
|
||||
// Specifically, this will be returned when there is no equals sign present in the URL query parameter.
|
||||
ErrInvalidParam error = errors.New("qson: invalid url query param provided")
|
||||
ErrInvalidParam = errors.New("qson: invalid url query param provided")
|
||||
|
||||
bracketSplitter *regexp.Regexp
|
||||
)
|
||||
|
||||
func init() {
|
||||
bracketSplitter = regexp.MustCompile("\\[|\\]")
|
||||
bracketSplitter = regexp.MustCompile(`\[|\]`)
|
||||
}
|
||||
|
||||
// Unmarshal will take a dest along with URL
|
||||
@@ -41,6 +41,7 @@ func Unmarshal(dst interface{}, query string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return json.Unmarshal(b, dst)
|
||||
}
|
||||
|
||||
@@ -56,14 +57,18 @@ func ToJSON(query string) ([]byte, error) {
|
||||
var (
|
||||
builder interface{} = make(map[string]interface{})
|
||||
)
|
||||
|
||||
params := strings.Split(query, "&")
|
||||
|
||||
for _, part := range params {
|
||||
tempMap, err := queryToMap(part)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
builder = merge(builder, tempMap)
|
||||
}
|
||||
|
||||
return json.Marshal(builder)
|
||||
}
|
||||
|
||||
@@ -81,10 +86,12 @@ func queryToMap(param string) (map[string]interface{}, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawValue, err = url.QueryUnescape(rawValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawKey, err = url.QueryUnescape(rawKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -108,6 +115,7 @@ func queryToMap(param string) (map[string]interface{}, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
key: value,
|
||||
}, nil
|
||||
@@ -120,6 +128,7 @@ func queryToMap(param string) (map[string]interface{}, error) {
|
||||
// and then we set {"a": queryToMap("b[c]", value)}
|
||||
ret := make(map[string]interface{}, 0)
|
||||
ret[key], err = queryToMap(buildNewKey(rawKey) + "=" + rawValue)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -132,17 +141,19 @@ func queryToMap(param string) (map[string]interface{}, error) {
|
||||
temp := ret[key].(map[string]interface{})
|
||||
ret[key] = []interface{}{temp[""]}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// buildNewKey will take something like:
|
||||
// origKey = "bar[one][two]"
|
||||
// pieces = [bar one two ]
|
||||
// and return "one[two]"
|
||||
// and return "one[two]".
|
||||
func buildNewKey(origKey string) string {
|
||||
pieces := bracketSplitter.Split(origKey, -1)
|
||||
ret := origKey[len(pieces[0])+1:]
|
||||
ret = ret[:len(pieces[1])] + ret[len(pieces[1])+1:]
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -154,5 +165,6 @@ func splitKeyAndValue(param string) (string, string, error) {
|
||||
if li == -1 {
|
||||
return "", "", ErrInvalidParam
|
||||
}
|
||||
|
||||
return param[:li], param[li+1:], nil
|
||||
}
|
||||
|
||||
+4
-4
@@ -52,7 +52,7 @@ func delNodes(old, del []*registry.Node) []*registry.Node {
|
||||
return nodes
|
||||
}
|
||||
|
||||
// CopyService make a copy of service
|
||||
// CopyService make a copy of service.
|
||||
func CopyService(service *registry.Service) *registry.Service {
|
||||
// copy service
|
||||
s := new(registry.Service)
|
||||
@@ -78,7 +78,7 @@ func CopyService(service *registry.Service) *registry.Service {
|
||||
return s
|
||||
}
|
||||
|
||||
// Copy makes a copy of services
|
||||
// Copy makes a copy of services.
|
||||
func Copy(current []*registry.Service) []*registry.Service {
|
||||
services := make([]*registry.Service, len(current))
|
||||
for i, service := range current {
|
||||
@@ -87,7 +87,7 @@ func Copy(current []*registry.Service) []*registry.Service {
|
||||
return services
|
||||
}
|
||||
|
||||
// Merge merges two lists of services and returns a new copy
|
||||
// Merge merges two lists of services and returns a new copy.
|
||||
func Merge(olist []*registry.Service, nlist []*registry.Service) []*registry.Service {
|
||||
var srv []*registry.Service
|
||||
|
||||
@@ -119,7 +119,7 @@ func Merge(olist []*registry.Service, nlist []*registry.Service) []*registry.Ser
|
||||
return srv
|
||||
}
|
||||
|
||||
// Remove removes services and returns a new copy
|
||||
// Remove removes services and returns a new copy.
|
||||
func Remove(old, del []*registry.Service) []*registry.Service {
|
||||
var services []*registry.Service
|
||||
|
||||
|
||||
+14
-14
@@ -8,32 +8,32 @@ import (
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// Buffer is ring buffer
|
||||
// Buffer is ring buffer.
|
||||
type Buffer struct {
|
||||
size int
|
||||
streams map[string]*Stream
|
||||
vals []*Entry
|
||||
size int
|
||||
|
||||
sync.RWMutex
|
||||
vals []*Entry
|
||||
streams map[string]*Stream
|
||||
}
|
||||
|
||||
// Entry is ring buffer data entry
|
||||
// Entry is ring buffer data entry.
|
||||
type Entry struct {
|
||||
Value interface{}
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
// Stream is used to stream the buffer
|
||||
// Stream is used to stream the buffer.
|
||||
type Stream struct {
|
||||
// Id of the stream
|
||||
Id string
|
||||
// Buffered entries
|
||||
Entries chan *Entry
|
||||
// Stop channel
|
||||
Stop chan bool
|
||||
// Id of the stream
|
||||
Id string
|
||||
}
|
||||
|
||||
// Put adds a new value to ring buffer
|
||||
// Put adds a new value to ring buffer.
|
||||
func (b *Buffer) Put(v interface{}) {
|
||||
b.Lock()
|
||||
defer b.Unlock()
|
||||
@@ -61,7 +61,7 @@ func (b *Buffer) Put(v interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns the last n entries
|
||||
// Get returns the last n entries.
|
||||
func (b *Buffer) Get(n int) []*Entry {
|
||||
b.RLock()
|
||||
defer b.RUnlock()
|
||||
@@ -78,7 +78,7 @@ func (b *Buffer) Get(n int) []*Entry {
|
||||
return b.vals[delta:]
|
||||
}
|
||||
|
||||
// Return the entries since a specific time
|
||||
// Return the entries since a specific time.
|
||||
func (b *Buffer) Since(t time.Time) []*Entry {
|
||||
b.RLock()
|
||||
defer b.RUnlock()
|
||||
@@ -107,7 +107,7 @@ func (b *Buffer) Since(t time.Time) []*Entry {
|
||||
}
|
||||
|
||||
// Stream logs from the buffer
|
||||
// Close the channel when you want to stop
|
||||
// Close the channel when you want to stop.
|
||||
func (b *Buffer) Stream() (<-chan *Entry, chan bool) {
|
||||
b.Lock()
|
||||
defer b.Unlock()
|
||||
@@ -125,12 +125,12 @@ func (b *Buffer) Stream() (<-chan *Entry, chan bool) {
|
||||
return entries, stop
|
||||
}
|
||||
|
||||
// Size returns the size of the ring buffer
|
||||
// Size returns the size of the ring buffer.
|
||||
func (b *Buffer) Size() int {
|
||||
return b.size
|
||||
}
|
||||
|
||||
// New returns a new buffer of the given size
|
||||
// New returns a new buffer of the given size.
|
||||
func New(i int) *Buffer {
|
||||
return &Buffer{
|
||||
size: i,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// ShutDownSingals returns all the singals that are being watched for to shut down services.
|
||||
// ShutDownSingals returns all the signals that are being watched for to shut down services.
|
||||
func Shutdown() []os.Signal {
|
||||
return []os.Signal{
|
||||
syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL,
|
||||
|
||||
+3
-3
@@ -5,8 +5,8 @@ import (
|
||||
)
|
||||
|
||||
type Pool struct {
|
||||
sync.RWMutex
|
||||
pool map[string]*Socket
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func (p *Pool) Get(id string) (*Socket, bool) {
|
||||
@@ -44,7 +44,7 @@ func (p *Pool) Release(s *Socket) {
|
||||
delete(p.pool, s.id)
|
||||
}
|
||||
|
||||
// Close the pool and delete all the sockets
|
||||
// Close the pool and delete all the sockets.
|
||||
func (p *Pool) Close() {
|
||||
p.Lock()
|
||||
defer p.Unlock()
|
||||
@@ -54,7 +54,7 @@ func (p *Pool) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
// NewPool returns a new socket pool
|
||||
// NewPool returns a new socket pool.
|
||||
func NewPool() *Pool {
|
||||
return &Pool{
|
||||
pool: make(map[string]*Socket),
|
||||
|
||||
+9
-9
@@ -7,19 +7,19 @@ import (
|
||||
"go-micro.dev/v4/transport"
|
||||
)
|
||||
|
||||
// Socket is our pseudo socket for transport.Socket
|
||||
// Socket is our pseudo socket for transport.Socket.
|
||||
type Socket struct {
|
||||
id string
|
||||
// closed
|
||||
closed chan bool
|
||||
// remote addr
|
||||
remote string
|
||||
// local addr
|
||||
local string
|
||||
// send chan
|
||||
send chan *transport.Message
|
||||
// recv chan
|
||||
recv chan *transport.Message
|
||||
id string
|
||||
// remote addr
|
||||
remote string
|
||||
// local addr
|
||||
local string
|
||||
}
|
||||
|
||||
func (s *Socket) SetLocal(l string) {
|
||||
@@ -30,7 +30,7 @@ func (s *Socket) SetRemote(r string) {
|
||||
s.remote = r
|
||||
}
|
||||
|
||||
// Accept passes a message to the socket which will be processed by the call to Recv
|
||||
// Accept passes a message to the socket which will be processed by the call to Recv.
|
||||
func (s *Socket) Accept(m *transport.Message) error {
|
||||
select {
|
||||
case s.recv <- m:
|
||||
@@ -40,7 +40,7 @@ func (s *Socket) Accept(m *transport.Message) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Process takes the next message off the send queue created by a call to Send
|
||||
// Process takes the next message off the send queue created by a call to Send.
|
||||
func (s *Socket) Process(m *transport.Message) error {
|
||||
select {
|
||||
case msg := <-s.send:
|
||||
@@ -91,7 +91,7 @@ func (s *Socket) Recv(m *transport.Message) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close closes the socket
|
||||
// Close closes the socket.
|
||||
func (s *Socket) Close() error {
|
||||
select {
|
||||
case <-s.closed:
|
||||
|
||||
Reference in New Issue
Block a user