summaryrefslogtreecommitdiff
path: root/pkg/server/hook/hook.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/server/hook/hook.go')
-rw-r--r--pkg/server/hook/hook.go77
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 {