diff --git a/client.go b/client.go index eee3710..fad4f93 100644 --- a/client.go +++ b/client.go @@ -98,6 +98,7 @@ func (c *Client) err(template string, args ...interface{}) { func (c *Client) run() { go c.term() + if err := c.dial(); err != nil { exit(1, "%v", err) } diff --git a/server.go b/server.go index 2779cec..0941ede 100644 --- a/server.go +++ b/server.go @@ -3,37 +3,67 @@ package main import ( "encoding/json" "fmt" + "io" "net" ) -func authConnection(conn net.Conn) error { - var raw json.RawMessage - d := json.NewDecoder(conn) - if err := d.Decode(&raw); err != nil { - return fmt.Errorf("unable to decode client request: %v", err) - } +func stream(r io.Reader, c chan Envelope, e chan error, done chan interface{}) { + defer close(done) + decoder := json.NewDecoder(r) var env Envelope - if err := json.Unmarshal(raw, &env); err != nil { - return fmt.Errorf("man, fuck all this. %v", err) - } - switch env.Kind { - case "auth": - var auth Auth - if err := json.Unmarshal(env.Body, &auth); err != nil { - return fmt.Errorf("unable to decode auth body: %v", err) + for { + err := decoder.Decode(&env) + switch err { + case io.EOF: + return + case nil: + c <- env + default: + e <- err } - info_log.Printf("authenticated user %s", auth.Nick) } +} + +func handleAuthRequest(conn net.Conn, body json.RawMessage) error { + var auth Auth + if err := json.Unmarshal(body, &auth); err != nil { + return fmt.Errorf("bad auth request: %v", err) + } + info_log.Printf("authenticated user %s", auth.Nick) return nil } +func handleRequest(conn net.Conn, request Envelope) error { + switch request.Kind { + case "auth": + return handleAuthRequest(conn, request.Body) + default: + return fmt.Errorf("no such request type: %v", request.Kind) + } +} + func handleConnection(conn net.Conn) { defer func() { conn.Close() info_log.Printf("connection ended: %v", conn.RemoteAddr()) }() info_log.Printf("connection start: %v", conn.RemoteAddr()) - authConnection(conn) + requests := make(chan Envelope) + errors := make(chan error) + done := make(chan interface{}) + go stream(conn, requests, errors, done) + for { + select { + case request := <-requests: + if err := handleRequest(conn, request); err != nil { + error_log.Printf("client error: %v", err) + } + case err := <-errors: + error_log.Printf("connection error: %v", err) + case <-done: + return + } + } } func serve() {