conn_test.go 6.7 KB

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