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.
22 func echoServer(ws *Conn) { io.Copy(ws, ws) }
25 l, e := net.Listen("tcp", "127.0.0.1:0") // any available address
27 log.Exitf("net.Listen tcp :0 %v", e)
29 serverAddr = l.Addr().String()
30 log.Print("Test WebSocket server listening on ", serverAddr)
31 http.Handle("/echo", Handler(echoServer))
32 http.Handle("/echoDraft75", Draft75Handler(echoServer))
36 // Test the getChallengeResponse function with values from section
37 // 5.1 of the specification steps 18, 26, and 43 from
38 // http://www.whatwg.org/specs/web-socket-protocol/
39 func TestChallenge(t *testing.T) {
40 var part1 uint32 = 777007543
41 var part2 uint32 = 114997259
42 key3 := []byte{0x47, 0x30, 0x22, 0x2D, 0x5A, 0x3F, 0x47, 0x58}
43 expected := []byte("0st3Rl&q-2ZU^weu")
45 response, err := getChallengeResponse(part1, part2, key3)
47 t.Errorf("getChallengeResponse: returned error %v", err)
50 if !bytes.Equal(expected, response) {
51 t.Errorf("getChallengeResponse: expected %q got %q", expected, response)
55 func TestEcho(t *testing.T) {
59 client, err := net.Dial("tcp", "", serverAddr)
61 t.Fatal("dialing", err)
63 ws, err := newClient("/echo", "localhost", "http://localhost",
64 "ws://localhost/echo", "", client, handshake)
66 t.Errorf("WebSocket handshake error: %v", err)
70 msg := []byte("hello, world\n")
71 if _, err := ws.Write(msg); err != nil {
72 t.Errorf("Write: %v", err)
74 var actual_msg = make([]byte, 512)
75 n, err := ws.Read(actual_msg)
77 t.Errorf("Read: %v", err)
79 actual_msg = actual_msg[0:n]
80 if !bytes.Equal(msg, actual_msg) {
81 t.Errorf("Echo: expected %q got %q", msg, actual_msg)
86 func TestEchoDraft75(t *testing.T) {
90 client, err := net.Dial("tcp", "", serverAddr)
92 t.Fatal("dialing", err)
94 ws, err := newClient("/echoDraft75", "localhost", "http://localhost",
95 "ws://localhost/echoDraft75", "", client, draft75handshake)
97 t.Errorf("WebSocket handshake: %v", err)
101 msg := []byte("hello, world\n")
102 if _, err := ws.Write(msg); err != nil {
103 t.Errorf("Write: error %v", err)
105 var actual_msg = make([]byte, 512)
106 n, err := ws.Read(actual_msg)
108 t.Errorf("Read: error %v", err)
110 actual_msg = actual_msg[0:n]
111 if !bytes.Equal(msg, actual_msg) {
112 t.Errorf("Echo: expected %q got %q", msg, actual_msg)
117 func TestWithQuery(t *testing.T) {
120 client, err := net.Dial("tcp", "", serverAddr)
122 t.Fatal("dialing", err)
125 ws, err := newClient("/echo?q=v", "localhost", "http://localhost",
126 "ws://localhost/echo?q=v", "", client, handshake)
128 t.Errorf("WebSocket handshake: %v", err)
134 func TestWithProtocol(t *testing.T) {
137 client, err := net.Dial("tcp", "", serverAddr)
139 t.Fatal("dialing", err)
142 ws, err := newClient("/echo", "localhost", "http://localhost",
143 "ws://localhost/echo", "test", client, handshake)
145 t.Errorf("WebSocket handshake: %v", err)
151 func TestHTTP(t *testing.T) {
154 // If the client did not send a handshake that matches the protocol
155 // specification, the server should abort the WebSocket connection.
156 _, _, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr))
158 t.Error("Get: unexpected success")
161 urlerr, ok := err.(*http.URLError)
163 t.Errorf("Get: not URLError %#v", err)
166 if urlerr.Error != io.ErrUnexpectedEOF {
167 t.Errorf("Get: error %#v", err)
172 func TestHTTPDraft75(t *testing.T) {
175 r, _, err := http.Get(fmt.Sprintf("http://%s/echoDraft75", serverAddr))
177 t.Errorf("Get: error %#v", err)
180 if r.StatusCode != http.StatusBadRequest {
181 t.Errorf("Get: got status %d", r.StatusCode)
185 func TestTrailingSpaces(t *testing.T) {
186 // http://code.google.com/p/go/issues/detail?id=955
187 // The last runs of this create keys with trailing spaces that should not be
188 // generated by the client.
190 for i := 0; i < 30; i++ {
192 _, err := Dial(fmt.Sprintf("ws://%s/echo", serverAddr), "",
195 panic("Dial failed: " + err.String())
200 func TestSmallBuffer(t *testing.T) {
201 // http://code.google.com/p/go/issues/detail?id=1145
202 // Read should be able to handle reading a fragment of a frame.
206 client, err := net.Dial("tcp", "", serverAddr)
208 t.Fatal("dialing", err)
210 ws, err := newClient("/echo", "localhost", "http://localhost",
211 "ws://localhost/echo", "", client, handshake)
213 t.Errorf("WebSocket handshake error: %v", err)
217 msg := []byte("hello, world\n")
218 if _, err := ws.Write(msg); err != nil {
219 t.Errorf("Write: %v", err)
221 var small_msg = make([]byte, 8)
222 n, err := ws.Read(small_msg)
224 t.Errorf("Read: %v", err)
226 if !bytes.Equal(msg[:len(small_msg)], small_msg) {
227 t.Errorf("Echo: expected %q got %q", msg[:len(small_msg)], small_msg)
229 var second_msg = make([]byte, len(msg))
230 n, err = ws.Read(second_msg)
232 t.Errorf("Read: %v", err)
234 second_msg = second_msg[0:n]
235 if !bytes.Equal(msg[len(small_msg):], second_msg) {
236 t.Errorf("Echo: expected %q got %q", msg[len(small_msg):], second_msg)
242 func testSkipLengthFrame(t *testing.T) {
243 b := []byte{'\x80', '\x01', 'x', 0, 'h', 'e', 'l', 'l', 'o', '\xff'}
244 buf := bytes.NewBuffer(b)
245 br := bufio.NewReader(buf)
246 bw := bufio.NewWriter(buf)
247 ws := newConn("http://127.0.0.1/", "ws://127.0.0.1/", "", bufio.NewReadWriter(br, bw), nil)
248 msg := make([]byte, 5)
249 n, err := ws.Read(msg)
251 t.Errorf("Read: %v", err)
253 if !bytes.Equal(b[4:8], msg[0:n]) {
254 t.Errorf("Read: expected %q got %q", msg[4:8], msg[0:n])
258 func testSkipNoUTF8Frame(t *testing.T) {
259 b := []byte{'\x01', 'n', '\xff', 0, 'h', 'e', 'l', 'l', 'o', '\xff'}
260 buf := bytes.NewBuffer(b)
261 br := bufio.NewReader(buf)
262 bw := bufio.NewWriter(buf)
263 ws := newConn("http://127.0.0.1/", "ws://127.0.0.1/", "", bufio.NewReadWriter(br, bw), nil)
264 msg := make([]byte, 5)
265 n, err := ws.Read(msg)
267 t.Errorf("Read: %v", err)
269 if !bytes.Equal(b[4:8], msg[0:n]) {
270 t.Errorf("Read: expected %q got %q", msg[4:8], msg[0:n])