diff options
| author | Mikhail Osipov <mike.osipov@gmail.com> | 2020-12-16 15:27:48 +0300 |
|---|---|---|
| committer | Mikhail Osipov <mike.osipov@gmail.com> | 2020-12-16 15:27:48 +0300 |
| commit | 6fed9dd0dd62718f78eca11e30a71c2712636fbd (patch) | |
| tree | 8d1f90b96efbe8ea8aea350c283325adc216ef9d /pkg/server/hook/hook.go | |
| parent | 050ea053dd549f0dd01beddfcd74989858391fd7 (diff) | |
hook and socket args check fix, tests
Diffstat (limited to 'pkg/server/hook/hook.go')
| -rw-r--r-- | pkg/server/hook/hook.go | 77 |
1 files changed, 58 insertions, 19 deletions
diff --git a/pkg/server/hook/hook.go b/pkg/server/hook/hook.go index 69aa237..36b01d4 100644 --- a/pkg/server/hook/hook.go +++ b/pkg/server/hook/hook.go @@ -3,16 +3,16 @@ package hook import ( "fmt" "log" + "reflect" "sort" "strings" + "tunnel/pkg/server/env" "tunnel/pkg/server/opts" "tunnel/pkg/server/queue" ) -type hookInitFunc func(opts.Opts) (hook, error) - -var hooks = map[string]hookInitFunc{} +var hooks = map[string]interface{}{} type Pipe struct { priv interface{} @@ -21,13 +21,12 @@ type Pipe struct { Recv Func } -type hook interface { - Open(env env.Env) (interface{}, error) +type Hooker interface { + New(env env.Env) (interface{}, error) } type H interface { - Open(env env.Env) (*Pipe, error) - String() string + New(env env.Env) (*Pipe, error) } type Sender interface { @@ -44,12 +43,12 @@ func (f Func) Send(rq, wq queue.Q) error { return f(rq, wq) } -func (f Func) Open(env env.Env) (interface{}, error) { +func (f Func) New(env env.Env) (interface{}, error) { return f, nil } type wrapper struct { - hook + hook Hooker name string reverse bool } @@ -58,8 +57,8 @@ func (w *wrapper) String() string { return fmt.Sprintf("hook:%s", w.name) } -func (w *wrapper) Open(env env.Env) (*Pipe, error) { - it, err := w.hook.Open(env) +func (w *wrapper) New(env env.Env) (*Pipe, error) { + it, err := w.hook.New(env) if err != nil { return nil, err } @@ -87,6 +86,23 @@ func (p *Pipe) Close() { } } +func initHook(i interface{}, opts opts.Opts) (Hooker, error) { + if f, ok := i.(Func); ok { + return f, nil + } + + if p, ok := i.(pipeHolder); ok { + return p, nil + } + + h := reflect.New(reflect.TypeOf(i)).Interface() + if err := opts.Configure(h); err != nil { + return nil, err + } + + return h.(Hooker), nil +} + func New(desc string) (H, error) { name, opts := opts.Parse(desc) reverse := false @@ -96,9 +112,9 @@ func New(desc string) (H, error) { reverse = true } - if f, ok := hooks[name]; !ok { + if i, ok := hooks[name]; !ok { return nil, fmt.Errorf("unknown hook '%s'", name) - } else if h, err := f(opts); err != nil { + } else if h, err := initHook(i, opts); err != nil { return nil, fmt.Errorf("%s: %w", name, err) } else { w := &wrapper{ @@ -110,18 +126,41 @@ func New(desc string) (H, error) { } } -func register(name string, f hookInitFunc) { +func register(name string, i interface{}) { + switch t := reflect.TypeOf(i); t.Kind() { + case reflect.Struct: + if _, ok := reflect.New(t).Interface().(Hooker); !ok { + log.Panicf("uncompatible hook type '%s'", t.String()) + } + case reflect.Func: + if _, ok := i.(Func); !ok { + log.Panicf("uncompatible func type '%s'", t.String()) + } + default: + log.Panicf("non-struct and non-func type '%s'", t.String()) + } + if _, ok := hooks[name]; ok { log.Panicf("duplicate hook name '%s'", name) } - hooks[name] = f + hooks[name] = i } -func registerFunc(name string, p Func) { - register(name, func(opts.Opts) (hook, error) { - return p, nil - }) +func registerFunc(name string, f Func) { + register(name, f) +} + +type pipeHolder struct { + i interface{} +} + +func (p pipeHolder) New(env.Env) (interface{}, error) { + return p.i, nil +} + +func registerPipe(name string, i interface{}) { + register(name, pipeHolder{i}) } func GetList() []string { |
