websocket_test.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. // Copyright 2009 The Go 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. "log"
  10. "net"
  11. "net/http"
  12. "net/http/httptest"
  13. "net/url"
  14. "strings"
  15. "sync"
  16. "testing"
  17. )
  18. var serverAddr string
  19. var once sync.Once
  20. func echoServer(ws *Conn) { io.Copy(ws, ws) }
  21. type Count struct {
  22. S string
  23. N int
  24. }
  25. func countServer(ws *Conn) {
  26. for {
  27. var count Count
  28. err := JSON.Receive(ws, &count)
  29. if err != nil {
  30. return
  31. }
  32. count.N++
  33. count.S = strings.Repeat(count.S, count.N)
  34. err = JSON.Send(ws, count)
  35. if err != nil {
  36. return
  37. }
  38. }
  39. }
  40. func startServer() {
  41. http.Handle("/echo", Handler(echoServer))
  42. http.Handle("/count", Handler(countServer))
  43. server := httptest.NewServer(nil)
  44. serverAddr = server.Listener.Addr().String()
  45. log.Print("Test WebSocket server listening on ", serverAddr)
  46. }
  47. func newConfig(t *testing.T, path string) *Config {
  48. config, _ := NewConfig(fmt.Sprintf("ws://%s%s", serverAddr, path), "http://localhost")
  49. return config
  50. }
  51. func TestEcho(t *testing.T) {
  52. once.Do(startServer)
  53. // websocket.Dial()
  54. client, err := net.Dial("tcp", serverAddr)
  55. if err != nil {
  56. t.Fatal("dialing", err)
  57. }
  58. conn, err := NewClient(newConfig(t, "/echo"), client)
  59. if err != nil {
  60. t.Errorf("WebSocket handshake error: %v", err)
  61. return
  62. }
  63. msg := []byte("hello, world\n")
  64. if _, err := conn.Write(msg); err != nil {
  65. t.Errorf("Write: %v", err)
  66. }
  67. var actual_msg = make([]byte, 512)
  68. n, err := conn.Read(actual_msg)
  69. if err != nil {
  70. t.Errorf("Read: %v", err)
  71. }
  72. actual_msg = actual_msg[0:n]
  73. if !bytes.Equal(msg, actual_msg) {
  74. t.Errorf("Echo: expected %q got %q", msg, actual_msg)
  75. }
  76. conn.Close()
  77. }
  78. func TestAddr(t *testing.T) {
  79. once.Do(startServer)
  80. // websocket.Dial()
  81. client, err := net.Dial("tcp", serverAddr)
  82. if err != nil {
  83. t.Fatal("dialing", err)
  84. }
  85. conn, err := NewClient(newConfig(t, "/echo"), client)
  86. if err != nil {
  87. t.Errorf("WebSocket handshake error: %v", err)
  88. return
  89. }
  90. ra := conn.RemoteAddr().String()
  91. if !strings.HasPrefix(ra, "ws://") || !strings.HasSuffix(ra, "/echo") {
  92. t.Errorf("Bad remote addr: %v", ra)
  93. }
  94. la := conn.LocalAddr().String()
  95. if !strings.HasPrefix(la, "http://") {
  96. t.Errorf("Bad local addr: %v", la)
  97. }
  98. conn.Close()
  99. }
  100. func TestCount(t *testing.T) {
  101. once.Do(startServer)
  102. // websocket.Dial()
  103. client, err := net.Dial("tcp", serverAddr)
  104. if err != nil {
  105. t.Fatal("dialing", err)
  106. }
  107. conn, err := NewClient(newConfig(t, "/count"), client)
  108. if err != nil {
  109. t.Errorf("WebSocket handshake error: %v", err)
  110. return
  111. }
  112. var count Count
  113. count.S = "hello"
  114. if err := JSON.Send(conn, count); err != nil {
  115. t.Errorf("Write: %v", err)
  116. }
  117. if err := JSON.Receive(conn, &count); err != nil {
  118. t.Errorf("Read: %v", err)
  119. }
  120. if count.N != 1 {
  121. t.Errorf("count: expected %d got %d", 1, count.N)
  122. }
  123. if count.S != "hello" {
  124. t.Errorf("count: expected %q got %q", "hello", count.S)
  125. }
  126. if err := JSON.Send(conn, count); err != nil {
  127. t.Errorf("Write: %v", err)
  128. }
  129. if err := JSON.Receive(conn, &count); err != nil {
  130. t.Errorf("Read: %v", err)
  131. }
  132. if count.N != 2 {
  133. t.Errorf("count: expected %d got %d", 2, count.N)
  134. }
  135. if count.S != "hellohello" {
  136. t.Errorf("count: expected %q got %q", "hellohello", count.S)
  137. }
  138. conn.Close()
  139. }
  140. func TestWithQuery(t *testing.T) {
  141. once.Do(startServer)
  142. client, err := net.Dial("tcp", serverAddr)
  143. if err != nil {
  144. t.Fatal("dialing", err)
  145. }
  146. config := newConfig(t, "/echo")
  147. config.Location, err = url.ParseRequestURI(fmt.Sprintf("ws://%s/echo?q=v", serverAddr))
  148. if err != nil {
  149. t.Fatal("location url", err)
  150. }
  151. ws, err := NewClient(config, client)
  152. if err != nil {
  153. t.Errorf("WebSocket handshake: %v", err)
  154. return
  155. }
  156. ws.Close()
  157. }
  158. func TestWithProtocol(t *testing.T) {
  159. once.Do(startServer)
  160. client, err := net.Dial("tcp", serverAddr)
  161. if err != nil {
  162. t.Fatal("dialing", err)
  163. }
  164. config := newConfig(t, "/echo")
  165. config.Protocol = append(config.Protocol, "test")
  166. ws, err := NewClient(config, client)
  167. if err != nil {
  168. t.Errorf("WebSocket handshake: %v", err)
  169. return
  170. }
  171. ws.Close()
  172. }
  173. func TestHTTP(t *testing.T) {
  174. once.Do(startServer)
  175. // If the client did not send a handshake that matches the protocol
  176. // specification, the server MUST return an HTTP response with an
  177. // appropriate error code (such as 400 Bad Request)
  178. resp, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr))
  179. if err != nil {
  180. t.Errorf("Get: error %#v", err)
  181. return
  182. }
  183. if resp == nil {
  184. t.Error("Get: resp is null")
  185. return
  186. }
  187. if resp.StatusCode != http.StatusBadRequest {
  188. t.Errorf("Get: expected %q got %q", http.StatusBadRequest, resp.StatusCode)
  189. }
  190. }
  191. func TestTrailingSpaces(t *testing.T) {
  192. // http://code.google.com/p/go/issues/detail?id=955
  193. // The last runs of this create keys with trailing spaces that should not be
  194. // generated by the client.
  195. once.Do(startServer)
  196. config := newConfig(t, "/echo")
  197. for i := 0; i < 30; i++ {
  198. // body
  199. ws, err := DialConfig(config)
  200. if err != nil {
  201. t.Errorf("Dial #%d failed: %v", i, err)
  202. break
  203. }
  204. ws.Close()
  205. }
  206. }
  207. func TestSmallBuffer(t *testing.T) {
  208. // http://code.google.com/p/go/issues/detail?id=1145
  209. // Read should be able to handle reading a fragment of a frame.
  210. once.Do(startServer)
  211. // websocket.Dial()
  212. client, err := net.Dial("tcp", serverAddr)
  213. if err != nil {
  214. t.Fatal("dialing", err)
  215. }
  216. conn, err := NewClient(newConfig(t, "/echo"), client)
  217. if err != nil {
  218. t.Errorf("WebSocket handshake error: %v", err)
  219. return
  220. }
  221. msg := []byte("hello, world\n")
  222. if _, err := conn.Write(msg); err != nil {
  223. t.Errorf("Write: %v", err)
  224. }
  225. var small_msg = make([]byte, 8)
  226. n, err := conn.Read(small_msg)
  227. if err != nil {
  228. t.Errorf("Read: %v", err)
  229. }
  230. if !bytes.Equal(msg[:len(small_msg)], small_msg) {
  231. t.Errorf("Echo: expected %q got %q", msg[:len(small_msg)], small_msg)
  232. }
  233. var second_msg = make([]byte, len(msg))
  234. n, err = conn.Read(second_msg)
  235. if err != nil {
  236. t.Errorf("Read: %v", err)
  237. }
  238. second_msg = second_msg[0:n]
  239. if !bytes.Equal(msg[len(small_msg):], second_msg) {
  240. t.Errorf("Echo: expected %q got %q", msg[len(small_msg):], second_msg)
  241. }
  242. conn.Close()
  243. }