summaryrefslogtreecommitdiff
path: root/pkg/server/hook/hook.go
diff options
context:
space:
mode:
authorMikhail Osipov <mike.osipov@gmail.com>2020-02-29 00:58:01 +0300
committerMikhail Osipov <mike.osipov@gmail.com>2020-02-29 00:58:01 +0300
commitc55afd2de177f128fae6e1c52d0c56af17096258 (patch)
tree2b06eeabf4db3a6c7ef357fb1569c4e8f72aab68 /pkg/server/hook/hook.go
parent11501b56a751d2959480aaeaf2036eff586e5629 (diff)
rename module to hook
Diffstat (limited to 'pkg/server/hook/hook.go')
-rw-r--r--pkg/server/hook/hook.go126
1 files changed, 126 insertions, 0 deletions
diff --git a/pkg/server/hook/hook.go b/pkg/server/hook/hook.go
new file mode 100644
index 0000000..b2970ac
--- /dev/null
+++ b/pkg/server/hook/hook.go
@@ -0,0 +1,126 @@
+package hook
+
+import (
+ "fmt"
+ "log"
+ "sort"
+ "strings"
+ "tunnel/pkg/server/env"
+ "tunnel/pkg/server/opts"
+ "tunnel/pkg/server/queue"
+)
+
+type hookInitFunc func(opts.Opts, env.Env) (hook, error)
+
+var hooks = map[string]hookInitFunc{}
+
+type hook interface {
+ Open(env env.Env) (interface{}, error)
+}
+
+type H interface {
+ hook
+ String() string
+}
+
+type Sender interface {
+ Send(rq, wq queue.Q) error
+}
+
+type Recver interface {
+ Recv(rq, wq queue.Q) error
+}
+
+type Func func(rq, wq queue.Q) error
+
+func (f Func) Send(rq, wq queue.Q) error {
+ return f(rq, wq)
+}
+
+func (f Func) Open(env env.Env) (interface{}, error) {
+ return f, nil
+}
+
+type wrapper struct {
+ hook
+ name string
+ reverse bool
+}
+
+func (w *wrapper) String() string {
+ return fmt.Sprintf("hook:%s", w.name)
+}
+
+func Open(h H, env env.Env) (Func, Func, error) {
+ var send, recv Func
+
+ w := h.(*wrapper)
+
+ it, err := h.Open(env)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if sender, ok := it.(Sender); ok {
+ send = sender.Send
+ }
+
+ if recver, ok := it.(Recver); ok {
+ recv = recver.Recv
+ }
+
+ if w.reverse {
+ send, recv = recv, send
+ }
+
+ return send, recv, nil
+}
+
+func New(desc string, env env.Env) (H, error) {
+ name, opts := opts.Parse(desc)
+ reverse := false
+
+ if strings.HasPrefix(name, "-") {
+ name = name[1:]
+ reverse = true
+ }
+
+ if f, ok := hooks[name]; !ok {
+ return nil, fmt.Errorf("unknown hook '%s'", name)
+ } else if h, err := f(opts, env); err != nil {
+ return nil, err
+ } else {
+ w := &wrapper{
+ hook: h,
+ name: name,
+ reverse: reverse,
+ }
+ return w, nil
+ }
+}
+
+func register(name string, f hookInitFunc) {
+ if _, ok := hooks[name]; ok {
+ log.Panicf("duplicate hook name '%s'", name)
+ }
+
+ hooks[name] = f
+}
+
+func registerFunc(name string, p Func) {
+ register(name, func(opts.Opts, env.Env) (hook, error) {
+ return p, nil
+ })
+}
+
+func GetList() []string {
+ var list []string
+
+ for k := range hooks {
+ list = append(list, k)
+ }
+
+ sort.Strings(list)
+
+ return list
+}