summaryrefslogtreecommitdiff
path: root/pkg/server/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/server/server.go')
-rw-r--r--pkg/server/server.go55
1 files changed, 42 insertions, 13 deletions
diff --git a/pkg/server/server.go b/pkg/server/server.go
index 1248b1d..e2515cb 100644
--- a/pkg/server/server.go
+++ b/pkg/server/server.go
@@ -2,6 +2,7 @@ package server
import (
"tunnel/pkg/config"
+ "tunnel/pkg/netstring"
"strings"
"bytes"
"sync"
@@ -46,6 +47,8 @@ type request struct {
argc int
args []string
+ failed bool
+
out *bytes.Buffer
}
@@ -183,7 +186,7 @@ func (c *client) newRequest() *request {
r := &request{
c: c,
id: c.nextRid,
- out: bytes.NewBuffer(nil),
+ out: new(bytes.Buffer),
}
c.nextRid++
@@ -209,9 +212,7 @@ func (c *client) handle() {
r := c.newRequest()
- if r.parse(query) {
- r.run()
- }
+ r.run(query)
if r.out.Len() == 0 {
r.out.Write([]byte("\n"))
@@ -225,30 +226,58 @@ func (c *client) handle() {
}
}
-func (r *request) parse(query string) bool {
- c, args := getCmd(strings.Split(query, " "))
+func (r *request) decode(query string) []string {
+ dec := netstring.NewDecoder(bytes.NewReader([]byte(query)))
+ var t []string
+
+ for {
+ if s, err := dec.Decode(); err == nil {
+ t = append(t, s)
+ } else {
+ if err == io.EOF {
+ break
+ }
+
+ r.Fatal("failed to parse request")
+ }
+ }
+
+ return t
+}
+func (r *request) parse(query string) {
+ c, args := getCmd(r.decode(query))
if c == nil {
- r.Print("command not found")
- return false
+ r.Fatal("command not found")
+ }
+
+ for n, s := range args {
+ if strings.HasPrefix(s, "%") {
+ if v, ok := r.c.s.env.get(s[1:]); ok {
+ args[n] = v
+ } else {
+ r.Fatal("unbound variable ", s)
+ }
+ }
}
r.args = args
r.argc = len(args)
r.cmd = c
-
- return true
}
-func (r *request) run() {
- log.Printf("%s %s run [%s] '%s'", r.c, r, r.cmd.name, strings.Join(r.args, " "))
-
+func (r *request) run(query string) {
defer func () {
if e := recover(); e != nil {
+ r.failed = true
r.Print(e)
}
}()
+ r.parse(query)
+
+ log.Printf("%s %s run [%s] '%s'", r.c, r, r.cmd.name, strings.Join(r.args, " "))
+
r.cmd.f(r)
}