conn_test.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. // Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package websocket
  5. import (
  6. "bufio"
  7. "bytes"
  8. "fmt"
  9. "io"
  10. "io/ioutil"
  11. "net"
  12. "reflect"
  13. "testing"
  14. "testing/iotest"
  15. "time"
  16. )
  17. var _ net.Error = errWriteTimeout
  18. type fakeNetConn struct {
  19. io.Reader
  20. io.Writer
  21. }
  22. func (c fakeNetConn) Close() error { return nil }
  23. func (c fakeNetConn) LocalAddr() net.Addr { return nil }
  24. func (c fakeNetConn) RemoteAddr() net.Addr { return nil }
  25. func (c fakeNetConn) SetDeadline(t time.Time) error { return nil }
  26. func (c fakeNetConn) SetReadDeadline(t time.Time) error { return nil }
  27. func (c fakeNetConn) SetWriteDeadline(t time.Time) error { return nil }
  28. func TestFraming(t *testing.T) {
  29. frameSizes := []int{0, 1, 2, 124, 125, 126, 127, 128, 129, 65534, 65535, 65536, 65537}
  30. var readChunkers = []struct {
  31. name string
  32. f func(io.Reader) io.Reader
  33. }{
  34. {"half", iotest.HalfReader},
  35. {"one", iotest.OneByteReader},
  36. {"asis", func(r io.Reader) io.Reader { return r }},
  37. }
  38. writeBuf := make([]byte, 65537)
  39. for i := range writeBuf {
  40. writeBuf[i] = byte(i)
  41. }
  42. for _, isServer := range []bool{true, false} {
  43. for _, chunker := range readChunkers {
  44. var connBuf bytes.Buffer
  45. wc := newConn(fakeNetConn{Reader: nil, Writer: &connBuf}, isServer, 1024, 1024)
  46. rc := newConn(fakeNetConn{Reader: chunker.f(&connBuf), Writer: nil}, !isServer, 1024, 1024)
  47. for _, n := range frameSizes {
  48. for _, iocopy := range []bool{true, false} {
  49. name := fmt.Sprintf("s:%v, r:%s, n:%d c:%v", isServer, chunker.name, n, iocopy)
  50. w, err := wc.NextWriter(TextMessage)
  51. if err != nil {
  52. t.Errorf("%s: wc.NextWriter() returned %v", name, err)
  53. continue
  54. }
  55. var nn int
  56. if iocopy {
  57. var n64 int64
  58. n64, err = io.Copy(w, bytes.NewReader(writeBuf[:n]))
  59. nn = int(n64)
  60. } else {
  61. nn, err = w.Write(writeBuf[:n])
  62. }
  63. if err != nil || nn != n {
  64. t.Errorf("%s: w.Write(writeBuf[:n]) returned %d, %v", name, nn, err)
  65. continue
  66. }
  67. err = w.Close()
  68. if err != nil {
  69. t.Errorf("%s: w.Close() returned %v", name, err)
  70. continue
  71. }
  72. opCode, r, err := rc.NextReader()
  73. if err != nil || opCode != TextMessage {
  74. t.Errorf("%s: NextReader() returned %d, r, %v", name, opCode, err)
  75. continue
  76. }
  77. rbuf, err := ioutil.ReadAll(r)
  78. if err != nil {
  79. t.Errorf("%s: ReadFull() returned rbuf, %v", name, err)
  80. continue
  81. }
  82. if len(rbuf) != n {
  83. t.Errorf("%s: len(rbuf) is %d, want %d", name, len(rbuf), n)
  84. continue
  85. }
  86. for i, b := range rbuf {
  87. if byte(i) != b {
  88. t.Errorf("%s: bad byte at offset %d", name, i)
  89. break
  90. }
  91. }
  92. }
  93. }
  94. }
  95. }
  96. }
  97. func TestControl(t *testing.T) {
  98. const message = "this is a ping/pong messsage"
  99. for _, isServer := range []bool{true, false} {
  100. for _, isWriteControl := range []bool{true, false} {
  101. name := fmt.Sprintf("s:%v, wc:%v", isServer, isWriteControl)
  102. var connBuf bytes.Buffer
  103. wc := newConn(fakeNetConn{Reader: nil, Writer: &connBuf}, isServer, 1024, 1024)
  104. rc := newConn(fakeNetConn{Reader: &connBuf, Writer: nil}, !isServer, 1024, 1024)
  105. if isWriteControl {
  106. wc.WriteControl(PongMessage, []byte(message), time.Now().Add(time.Second))
  107. } else {
  108. w, err := wc.NextWriter(PongMessage)
  109. if err != nil {
  110. t.Errorf("%s: wc.NextWriter() returned %v", name, err)
  111. continue
  112. }
  113. if _, err := w.Write([]byte(message)); err != nil {
  114. t.Errorf("%s: w.Write() returned %v", name, err)
  115. continue
  116. }
  117. if err := w.Close(); err != nil {
  118. t.Errorf("%s: w.Close() returned %v", name, err)
  119. continue
  120. }
  121. var actualMessage string
  122. rc.SetPongHandler(func(s string) error { actualMessage = s; return nil })
  123. rc.NextReader()
  124. if actualMessage != message {
  125. t.Errorf("%s: pong=%q, want %q", name, actualMessage, message)
  126. continue
  127. }
  128. }
  129. }
  130. }
  131. }
  132. func TestCloseBeforeFinalFrame(t *testing.T) {
  133. const bufSize = 512
  134. expectedErr := &CloseError{Code: CloseNormalClosure, Text: "hello"}
  135. var b1, b2 bytes.Buffer
  136. wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, bufSize)
  137. rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
  138. w, _ := wc.NextWriter(BinaryMessage)
  139. w.Write(make([]byte, bufSize+bufSize/2))
  140. wc.WriteControl(CloseMessage, FormatCloseMessage(expectedErr.Code, expectedErr.Text), time.Now().Add(10*time.Second))
  141. w.Close()
  142. op, r, err := rc.NextReader()
  143. if op != BinaryMessage || err != nil {
  144. t.Fatalf("NextReader() returned %d, %v", op, err)
  145. }
  146. _, err = io.Copy(ioutil.Discard, r)
  147. if !reflect.DeepEqual(err, expectedErr) {
  148. t.Fatalf("io.Copy() returned %v, want %v", err, expectedErr)
  149. }
  150. _, _, err = rc.NextReader()
  151. if !reflect.DeepEqual(err, expectedErr) {
  152. t.Fatalf("NextReader() returned %v, want %v", err, expectedErr)
  153. }
  154. }
  155. func TestEOFBeforeFinalFrame(t *testing.T) {
  156. const bufSize = 512
  157. var b1, b2 bytes.Buffer
  158. wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, bufSize)
  159. rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
  160. w, _ := wc.NextWriter(BinaryMessage)
  161. w.Write(make([]byte, bufSize+bufSize/2))
  162. op, r, err := rc.NextReader()
  163. if op != BinaryMessage || err != nil {
  164. t.Fatalf("NextReader() returned %d, %v", op, err)
  165. }
  166. _, err = io.Copy(ioutil.Discard, r)
  167. if err != errUnexpectedEOF {
  168. t.Fatalf("io.Copy() returned %v, want %v", err, errUnexpectedEOF)
  169. }
  170. _, _, err = rc.NextReader()
  171. if err != errUnexpectedEOF {
  172. t.Fatalf("NextReader() returned %v, want %v", err, errUnexpectedEOF)
  173. }
  174. }
  175. func TestReadLimit(t *testing.T) {
  176. const readLimit = 512
  177. message := make([]byte, readLimit+1)
  178. var b1, b2 bytes.Buffer
  179. wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, 1024, readLimit-2)
  180. rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, 1024, 1024)
  181. rc.SetReadLimit(readLimit)
  182. // Send message at the limit with interleaved pong.
  183. w, _ := wc.NextWriter(BinaryMessage)
  184. w.Write(message[:readLimit-1])
  185. wc.WriteControl(PongMessage, []byte("this is a pong"), time.Now().Add(10*time.Second))
  186. w.Write(message[:1])
  187. w.Close()
  188. // Send message larger than the limit.
  189. wc.WriteMessage(BinaryMessage, message[:readLimit+1])
  190. op, _, err := rc.NextReader()
  191. if op != BinaryMessage || err != nil {
  192. t.Fatalf("1: NextReader() returned %d, %v", op, err)
  193. }
  194. op, r, err := rc.NextReader()
  195. if op != BinaryMessage || err != nil {
  196. t.Fatalf("2: NextReader() returned %d, %v", op, err)
  197. }
  198. _, err = io.Copy(ioutil.Discard, r)
  199. if err != ErrReadLimit {
  200. t.Fatalf("io.Copy() returned %v", err)
  201. }
  202. }
  203. func TestUnderlyingConn(t *testing.T) {
  204. var b1, b2 bytes.Buffer
  205. fc := fakeNetConn{Reader: &b1, Writer: &b2}
  206. c := newConn(fc, true, 1024, 1024)
  207. ul := c.UnderlyingConn()
  208. if ul != fc {
  209. t.Fatalf("Underlying conn is not what it should be.")
  210. }
  211. }
  212. func TestBufioReadBytes(t *testing.T) {
  213. // Test calling bufio.ReadBytes for value longer than read buffer size.
  214. m := make([]byte, 512)
  215. m[len(m)-1] = '\n'
  216. var b1, b2 bytes.Buffer
  217. wc := newConn(fakeNetConn{Reader: nil, Writer: &b1}, false, len(m)+64, len(m)+64)
  218. rc := newConn(fakeNetConn{Reader: &b1, Writer: &b2}, true, len(m)-64, len(m)-64)
  219. w, _ := wc.NextWriter(BinaryMessage)
  220. w.Write(m)
  221. w.Close()
  222. op, r, err := rc.NextReader()
  223. if op != BinaryMessage || err != nil {
  224. t.Fatalf("NextReader() returned %d, %v", op, err)
  225. }
  226. br := bufio.NewReader(r)
  227. p, err := br.ReadBytes('\n')
  228. if err != nil {
  229. t.Fatalf("ReadBytes() returned %v", err)
  230. }
  231. if len(p) != len(m) {
  232. t.Fatalf("read returnd %d bytes, want %d bytes", len(p), len(m))
  233. }
  234. }