]> Cypherpunks.ru repositories - goircd.git/commitdiff
Refactored and corrected client's network data reading
authorSergey Matveev <stargrave@stargrave.org>
Tue, 6 Oct 2015 08:27:11 +0000 (11:27 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Tue, 6 Oct 2015 09:48:04 +0000 (12:48 +0300)
client.go
client_test.go
daemon_test.go
room_test.go

index 95dd93f60d9e7958d5eeec9229284cb96ab403cb..9bcaf30575d6829b00d96cedd04b7166330fb986 100644 (file)
--- a/client.go
+++ b/client.go
@@ -27,8 +27,11 @@ import (
 )
 
 const (
 )
 
 const (
-       CRLF    = "\x0d\x0a"
-       BufSize = 1380
+       BufSize = 1500
+)
+
+var (
+       CRLF []byte = []byte{'\x0d', '\x0a'}
 )
 
 type Client struct {
 )
 
 type Client struct {
@@ -59,34 +62,41 @@ func NewClient(hostname *string, conn net.Conn) *Client {
 // splits messages by CRLF and send them to Daemon gorouting for processing
 // it futher. Also it can signalize that client is unavailable (disconnected).
 func (client *Client) Processor(sink chan<- ClientEvent) {
 // splits messages by CRLF and send them to Daemon gorouting for processing
 // it futher. Also it can signalize that client is unavailable (disconnected).
 func (client *Client) Processor(sink chan<- ClientEvent) {
-       var bufNet []byte
-       buf := make([]byte, 0)
-       log.Println(client, "New client")
        sink <- ClientEvent{client, EventNew, ""}
        sink <- ClientEvent{client, EventNew, ""}
+       log.Println(client, "New client")
+       buf := make([]byte, BufSize*2)
+       var n int
+       var prev int
+       var i int
+       var err error
        for {
        for {
-               bufNet = make([]byte, BufSize)
-               _, err := client.conn.Read(bufNet)
+               if prev == BufSize {
+                       log.Println(client, "buffer size exceeded, kicking him")
+                       sink <- ClientEvent{client, EventDel, ""}
+                       client.conn.Close()
+                       break
+               }
+               n, err = client.conn.Read(buf[prev:])
                if err != nil {
                        sink <- ClientEvent{client, EventDel, ""}
                        break
                }
                if err != nil {
                        sink <- ClientEvent{client, EventDel, ""}
                        break
                }
-               bufNet = bytes.TrimRight(bufNet, "\x00")
-               buf = append(buf, bufNet...)
-               if !bytes.HasSuffix(buf, []byte(CRLF)) {
+               prev += n
+       CheckMore:
+               i = bytes.Index(buf[:prev], CRLF)
+               if i == -1 {
                        continue
                }
                        continue
                }
-               for _, msg := range bytes.Split(buf[:len(buf)-2], []byte(CRLF)) {
-                       if len(msg) > 0 {
-                               sink <- ClientEvent{client, EventMsg, string(msg)}
-                       }
-               }
-               buf = []byte{}
+               sink <- ClientEvent{client, EventMsg, string(buf[:i])}
+               copy(buf, buf[i+2:prev])
+               prev -= (i + 2)
+               goto CheckMore
        }
 }
 
 // Send message as is with CRLF appended.
 func (client *Client) Msg(text string) {
        }
 }
 
 // Send message as is with CRLF appended.
 func (client *Client) Msg(text string) {
-       client.conn.Write([]byte(text + CRLF))
+       client.conn.Write(append([]byte(text), CRLF...))
 }
 
 // Send message from server. It has ": servername" prefix.
 }
 
 // Send message from server. It has ": servername" prefix.
index 38f88081dc8f4f73d0b352e77705a983c3fb3e5c..3735e1f71034f8c3ebcd03f7efb63c522eff4c1a 100644 (file)
@@ -47,10 +47,10 @@ func (conn *TestingConn) Read(b []byte) (n int, err error) {
        if msg == "" {
                return 0, conn
        }
        if msg == "" {
                return 0, conn
        }
-       for n, bt := range []byte(msg + CRLF) {
+       for n, bt := range append([]byte(msg), CRLF...) {
                b[n] = bt
        }
                b[n] = bt
        }
-       return len(msg), nil
+       return len(msg)+2, nil
 }
 
 type MyAddr struct{}
 }
 
 type MyAddr struct{}
index 3db72cb6b73fee9d3636d6a9a30133ee8e8d5ac9..efdb39fd3e3598dea52a2cd2431bcdadb7a5d8f0 100644 (file)
@@ -91,6 +91,7 @@ func TestRegistrationWorkflow(t *testing.T) {
 
        conn.inbound <- "AWAY"
        conn.inbound <- "UNEXISTENT CMD"
 
        conn.inbound <- "AWAY"
        conn.inbound <- "UNEXISTENT CMD"
+       <-conn.outbound
        if r := <-conn.outbound; r != ":foohost 421 meinick UNEXISTENT :Unknown command\r\n" {
                t.Fatal("reply for unexistent command", r)
        }
        if r := <-conn.outbound; r != ":foohost 421 meinick UNEXISTENT :Unknown command\r\n" {
                t.Fatal("reply for unexistent command", r)
        }
index d5bf41180549eb7485087faf19b12f6dd94f902e..d94e8d49634d24ef836cbb899d31bff9752b4a23 100644 (file)
@@ -56,8 +56,8 @@ func TestTwoUsers(t *testing.T) {
        go client1.Processor(events)
        go client2.Processor(events)
 
        go client1.Processor(events)
        go client2.Processor(events)
 
-       conn1.inbound <- "NICK nick1\r\nUSER foo1 bar1 baz1 :Long name1\r\n"
-       conn2.inbound <- "NICK nick2\r\nUSER foo2 bar2 baz2 :Long name2\r\n"
+       conn1.inbound <- "NICK nick1\r\nUSER foo1 bar1 baz1 :Long name1"
+       conn2.inbound <- "NICK nick2\r\nUSER foo2 bar2 baz2 :Long name2"
        for i := 0; i < 6; i++ {
                <-conn1.outbound
                <-conn2.outbound
        for i := 0; i < 6; i++ {
                <-conn1.outbound
                <-conn2.outbound
@@ -105,6 +105,7 @@ func TestTwoUsers(t *testing.T) {
        conn1.inbound <- "PRIVMSG nick2 :Hello"
        conn1.inbound <- "PRIVMSG #foo :world"
        conn1.inbound <- "NOTICE #foo :world"
        conn1.inbound <- "PRIVMSG nick2 :Hello"
        conn1.inbound <- "PRIVMSG #foo :world"
        conn1.inbound <- "NOTICE #foo :world"
+       <-conn2.outbound
        if r := <-conn2.outbound; r != ":nick1!foo1@someclient PRIVMSG nick2 :Hello\r\n" {
                t.Fatal("first message", r)
        }
        if r := <-conn2.outbound; r != ":nick1!foo1@someclient PRIVMSG nick2 :Hello\r\n" {
                t.Fatal("first message", r)
        }
@@ -127,7 +128,7 @@ func TestJoin(t *testing.T) {
        client := NewClient(&host, conn)
        go client.Processor(events)
 
        client := NewClient(&host, conn)
        go client.Processor(events)
 
-       conn.inbound <- "NICK nick2\r\nUSER foo2 bar2 baz2 :Long name2\r\n"
+       conn.inbound <- "NICK nick2\r\nUSER foo2 bar2 baz2 :Long name2"
        for i := 0; i < 6; i++ {
                <-conn.outbound
        }
        for i := 0; i < 6; i++ {
                <-conn.outbound
        }