~ubuntu-branches/ubuntu/trusty/juju-core/trusty-proposed

« back to all changes in this revision

Viewing changes to src/golang.org/x/net/websocket/websocket_test.go

  • Committer: Package Import Robot
  • Author(s): Robie Basak
  • Date: 2015-07-15 13:09:07 UTC
  • mfrom: (35.1.15 wily-proposed)
  • Revision ID: package-import@ubuntu.com-20150715130907-wqak1zpebzzdvy3q
Tags: 1.22.6-0ubuntu1~14.04.1
* No change backport to 14.04 (LP: #1469744). This results in the
  following packaging delta from the previous 1.20.11-0ubuntu0.14.04.1
  in trusty-updates:
  - distro-info added and libgo5 removed from Build-Depends.
  - Standards-Version bumped.
  - cloud-image-utils | cloud-utils added to juju-local Depends.
  - d/copyright updated.
  - dep8 tests updated.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
5
package websocket
 
6
 
 
7
import (
 
8
        "bytes"
 
9
        "fmt"
 
10
        "io"
 
11
        "log"
 
12
        "net"
 
13
        "net/http"
 
14
        "net/http/httptest"
 
15
        "net/url"
 
16
        "strings"
 
17
        "sync"
 
18
        "testing"
 
19
        "time"
 
20
)
 
21
 
 
22
var serverAddr string
 
23
var once sync.Once
 
24
 
 
25
func echoServer(ws *Conn) { io.Copy(ws, ws) }
 
26
 
 
27
type Count struct {
 
28
        S string
 
29
        N int
 
30
}
 
31
 
 
32
func countServer(ws *Conn) {
 
33
        for {
 
34
                var count Count
 
35
                err := JSON.Receive(ws, &count)
 
36
                if err != nil {
 
37
                        return
 
38
                }
 
39
                count.N++
 
40
                count.S = strings.Repeat(count.S, count.N)
 
41
                err = JSON.Send(ws, count)
 
42
                if err != nil {
 
43
                        return
 
44
                }
 
45
        }
 
46
}
 
47
 
 
48
func subProtocolHandshake(config *Config, req *http.Request) error {
 
49
        for _, proto := range config.Protocol {
 
50
                if proto == "chat" {
 
51
                        config.Protocol = []string{proto}
 
52
                        return nil
 
53
                }
 
54
        }
 
55
        return ErrBadWebSocketProtocol
 
56
}
 
57
 
 
58
func subProtoServer(ws *Conn) {
 
59
        for _, proto := range ws.Config().Protocol {
 
60
                io.WriteString(ws, proto)
 
61
        }
 
62
}
 
63
 
 
64
func startServer() {
 
65
        http.Handle("/echo", Handler(echoServer))
 
66
        http.Handle("/count", Handler(countServer))
 
67
        subproto := Server{
 
68
                Handshake: subProtocolHandshake,
 
69
                Handler:   Handler(subProtoServer),
 
70
        }
 
71
        http.Handle("/subproto", subproto)
 
72
        server := httptest.NewServer(nil)
 
73
        serverAddr = server.Listener.Addr().String()
 
74
        log.Print("Test WebSocket server listening on ", serverAddr)
 
75
}
 
76
 
 
77
func newConfig(t *testing.T, path string) *Config {
 
78
        config, _ := NewConfig(fmt.Sprintf("ws://%s%s", serverAddr, path), "http://localhost")
 
79
        return config
 
80
}
 
81
 
 
82
func TestEcho(t *testing.T) {
 
83
        once.Do(startServer)
 
84
 
 
85
        // websocket.Dial()
 
86
        client, err := net.Dial("tcp", serverAddr)
 
87
        if err != nil {
 
88
                t.Fatal("dialing", err)
 
89
        }
 
90
        conn, err := NewClient(newConfig(t, "/echo"), client)
 
91
        if err != nil {
 
92
                t.Errorf("WebSocket handshake error: %v", err)
 
93
                return
 
94
        }
 
95
 
 
96
        msg := []byte("hello, world\n")
 
97
        if _, err := conn.Write(msg); err != nil {
 
98
                t.Errorf("Write: %v", err)
 
99
        }
 
100
        var actual_msg = make([]byte, 512)
 
101
        n, err := conn.Read(actual_msg)
 
102
        if err != nil {
 
103
                t.Errorf("Read: %v", err)
 
104
        }
 
105
        actual_msg = actual_msg[0:n]
 
106
        if !bytes.Equal(msg, actual_msg) {
 
107
                t.Errorf("Echo: expected %q got %q", msg, actual_msg)
 
108
        }
 
109
        conn.Close()
 
110
}
 
111
 
 
112
func TestAddr(t *testing.T) {
 
113
        once.Do(startServer)
 
114
 
 
115
        // websocket.Dial()
 
116
        client, err := net.Dial("tcp", serverAddr)
 
117
        if err != nil {
 
118
                t.Fatal("dialing", err)
 
119
        }
 
120
        conn, err := NewClient(newConfig(t, "/echo"), client)
 
121
        if err != nil {
 
122
                t.Errorf("WebSocket handshake error: %v", err)
 
123
                return
 
124
        }
 
125
 
 
126
        ra := conn.RemoteAddr().String()
 
127
        if !strings.HasPrefix(ra, "ws://") || !strings.HasSuffix(ra, "/echo") {
 
128
                t.Errorf("Bad remote addr: %v", ra)
 
129
        }
 
130
        la := conn.LocalAddr().String()
 
131
        if !strings.HasPrefix(la, "http://") {
 
132
                t.Errorf("Bad local addr: %v", la)
 
133
        }
 
134
        conn.Close()
 
135
}
 
136
 
 
137
func TestCount(t *testing.T) {
 
138
        once.Do(startServer)
 
139
 
 
140
        // websocket.Dial()
 
141
        client, err := net.Dial("tcp", serverAddr)
 
142
        if err != nil {
 
143
                t.Fatal("dialing", err)
 
144
        }
 
145
        conn, err := NewClient(newConfig(t, "/count"), client)
 
146
        if err != nil {
 
147
                t.Errorf("WebSocket handshake error: %v", err)
 
148
                return
 
149
        }
 
150
 
 
151
        var count Count
 
152
        count.S = "hello"
 
153
        if err := JSON.Send(conn, count); err != nil {
 
154
                t.Errorf("Write: %v", err)
 
155
        }
 
156
        if err := JSON.Receive(conn, &count); err != nil {
 
157
                t.Errorf("Read: %v", err)
 
158
        }
 
159
        if count.N != 1 {
 
160
                t.Errorf("count: expected %d got %d", 1, count.N)
 
161
        }
 
162
        if count.S != "hello" {
 
163
                t.Errorf("count: expected %q got %q", "hello", count.S)
 
164
        }
 
165
        if err := JSON.Send(conn, count); err != nil {
 
166
                t.Errorf("Write: %v", err)
 
167
        }
 
168
        if err := JSON.Receive(conn, &count); err != nil {
 
169
                t.Errorf("Read: %v", err)
 
170
        }
 
171
        if count.N != 2 {
 
172
                t.Errorf("count: expected %d got %d", 2, count.N)
 
173
        }
 
174
        if count.S != "hellohello" {
 
175
                t.Errorf("count: expected %q got %q", "hellohello", count.S)
 
176
        }
 
177
        conn.Close()
 
178
}
 
179
 
 
180
func TestWithQuery(t *testing.T) {
 
181
        once.Do(startServer)
 
182
 
 
183
        client, err := net.Dial("tcp", serverAddr)
 
184
        if err != nil {
 
185
                t.Fatal("dialing", err)
 
186
        }
 
187
 
 
188
        config := newConfig(t, "/echo")
 
189
        config.Location, err = url.ParseRequestURI(fmt.Sprintf("ws://%s/echo?q=v", serverAddr))
 
190
        if err != nil {
 
191
                t.Fatal("location url", err)
 
192
        }
 
193
 
 
194
        ws, err := NewClient(config, client)
 
195
        if err != nil {
 
196
                t.Errorf("WebSocket handshake: %v", err)
 
197
                return
 
198
        }
 
199
        ws.Close()
 
200
}
 
201
 
 
202
func testWithProtocol(t *testing.T, subproto []string) (string, error) {
 
203
        once.Do(startServer)
 
204
 
 
205
        client, err := net.Dial("tcp", serverAddr)
 
206
        if err != nil {
 
207
                t.Fatal("dialing", err)
 
208
        }
 
209
 
 
210
        config := newConfig(t, "/subproto")
 
211
        config.Protocol = subproto
 
212
 
 
213
        ws, err := NewClient(config, client)
 
214
        if err != nil {
 
215
                return "", err
 
216
        }
 
217
        msg := make([]byte, 16)
 
218
        n, err := ws.Read(msg)
 
219
        if err != nil {
 
220
                return "", err
 
221
        }
 
222
        ws.Close()
 
223
        return string(msg[:n]), nil
 
224
}
 
225
 
 
226
func TestWithProtocol(t *testing.T) {
 
227
        proto, err := testWithProtocol(t, []string{"chat"})
 
228
        if err != nil {
 
229
                t.Errorf("SubProto: unexpected error: %v", err)
 
230
        }
 
231
        if proto != "chat" {
 
232
                t.Errorf("SubProto: expected %q, got %q", "chat", proto)
 
233
        }
 
234
}
 
235
 
 
236
func TestWithTwoProtocol(t *testing.T) {
 
237
        proto, err := testWithProtocol(t, []string{"test", "chat"})
 
238
        if err != nil {
 
239
                t.Errorf("SubProto: unexpected error: %v", err)
 
240
        }
 
241
        if proto != "chat" {
 
242
                t.Errorf("SubProto: expected %q, got %q", "chat", proto)
 
243
        }
 
244
}
 
245
 
 
246
func TestWithBadProtocol(t *testing.T) {
 
247
        _, err := testWithProtocol(t, []string{"test"})
 
248
        if err != ErrBadStatus {
 
249
                t.Errorf("SubProto: expected %v, got %v", ErrBadStatus, err)
 
250
        }
 
251
}
 
252
 
 
253
func TestHTTP(t *testing.T) {
 
254
        once.Do(startServer)
 
255
 
 
256
        // If the client did not send a handshake that matches the protocol
 
257
        // specification, the server MUST return an HTTP response with an
 
258
        // appropriate error code (such as 400 Bad Request)
 
259
        resp, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr))
 
260
        if err != nil {
 
261
                t.Errorf("Get: error %#v", err)
 
262
                return
 
263
        }
 
264
        if resp == nil {
 
265
                t.Error("Get: resp is null")
 
266
                return
 
267
        }
 
268
        if resp.StatusCode != http.StatusBadRequest {
 
269
                t.Errorf("Get: expected %q got %q", http.StatusBadRequest, resp.StatusCode)
 
270
        }
 
271
}
 
272
 
 
273
func TestTrailingSpaces(t *testing.T) {
 
274
        // http://code.google.com/p/go/issues/detail?id=955
 
275
        // The last runs of this create keys with trailing spaces that should not be
 
276
        // generated by the client.
 
277
        once.Do(startServer)
 
278
        config := newConfig(t, "/echo")
 
279
        for i := 0; i < 30; i++ {
 
280
                // body
 
281
                ws, err := DialConfig(config)
 
282
                if err != nil {
 
283
                        t.Errorf("Dial #%d failed: %v", i, err)
 
284
                        break
 
285
                }
 
286
                ws.Close()
 
287
        }
 
288
}
 
289
 
 
290
func TestDialConfigBadVersion(t *testing.T) {
 
291
        once.Do(startServer)
 
292
        config := newConfig(t, "/echo")
 
293
        config.Version = 1234
 
294
 
 
295
        _, err := DialConfig(config)
 
296
 
 
297
        if dialerr, ok := err.(*DialError); ok {
 
298
                if dialerr.Err != ErrBadProtocolVersion {
 
299
                        t.Errorf("dial expected err %q but got %q", ErrBadProtocolVersion, dialerr.Err)
 
300
                }
 
301
        }
 
302
}
 
303
 
 
304
func TestSmallBuffer(t *testing.T) {
 
305
        // http://code.google.com/p/go/issues/detail?id=1145
 
306
        // Read should be able to handle reading a fragment of a frame.
 
307
        once.Do(startServer)
 
308
 
 
309
        // websocket.Dial()
 
310
        client, err := net.Dial("tcp", serverAddr)
 
311
        if err != nil {
 
312
                t.Fatal("dialing", err)
 
313
        }
 
314
        conn, err := NewClient(newConfig(t, "/echo"), client)
 
315
        if err != nil {
 
316
                t.Errorf("WebSocket handshake error: %v", err)
 
317
                return
 
318
        }
 
319
 
 
320
        msg := []byte("hello, world\n")
 
321
        if _, err := conn.Write(msg); err != nil {
 
322
                t.Errorf("Write: %v", err)
 
323
        }
 
324
        var small_msg = make([]byte, 8)
 
325
        n, err := conn.Read(small_msg)
 
326
        if err != nil {
 
327
                t.Errorf("Read: %v", err)
 
328
        }
 
329
        if !bytes.Equal(msg[:len(small_msg)], small_msg) {
 
330
                t.Errorf("Echo: expected %q got %q", msg[:len(small_msg)], small_msg)
 
331
        }
 
332
        var second_msg = make([]byte, len(msg))
 
333
        n, err = conn.Read(second_msg)
 
334
        if err != nil {
 
335
                t.Errorf("Read: %v", err)
 
336
        }
 
337
        second_msg = second_msg[0:n]
 
338
        if !bytes.Equal(msg[len(small_msg):], second_msg) {
 
339
                t.Errorf("Echo: expected %q got %q", msg[len(small_msg):], second_msg)
 
340
        }
 
341
        conn.Close()
 
342
}
 
343
 
 
344
var parseAuthorityTests = []struct {
 
345
        in  *url.URL
 
346
        out string
 
347
}{
 
348
        {
 
349
                &url.URL{
 
350
                        Scheme: "ws",
 
351
                        Host:   "www.google.com",
 
352
                },
 
353
                "www.google.com:80",
 
354
        },
 
355
        {
 
356
                &url.URL{
 
357
                        Scheme: "wss",
 
358
                        Host:   "www.google.com",
 
359
                },
 
360
                "www.google.com:443",
 
361
        },
 
362
        {
 
363
                &url.URL{
 
364
                        Scheme: "ws",
 
365
                        Host:   "www.google.com:80",
 
366
                },
 
367
                "www.google.com:80",
 
368
        },
 
369
        {
 
370
                &url.URL{
 
371
                        Scheme: "wss",
 
372
                        Host:   "www.google.com:443",
 
373
                },
 
374
                "www.google.com:443",
 
375
        },
 
376
        // some invalid ones for parseAuthority. parseAuthority doesn't
 
377
        // concern itself with the scheme unless it actually knows about it
 
378
        {
 
379
                &url.URL{
 
380
                        Scheme: "http",
 
381
                        Host:   "www.google.com",
 
382
                },
 
383
                "www.google.com",
 
384
        },
 
385
        {
 
386
                &url.URL{
 
387
                        Scheme: "http",
 
388
                        Host:   "www.google.com:80",
 
389
                },
 
390
                "www.google.com:80",
 
391
        },
 
392
        {
 
393
                &url.URL{
 
394
                        Scheme: "asdf",
 
395
                        Host:   "127.0.0.1",
 
396
                },
 
397
                "127.0.0.1",
 
398
        },
 
399
        {
 
400
                &url.URL{
 
401
                        Scheme: "asdf",
 
402
                        Host:   "www.google.com",
 
403
                },
 
404
                "www.google.com",
 
405
        },
 
406
}
 
407
 
 
408
func TestParseAuthority(t *testing.T) {
 
409
        for _, tt := range parseAuthorityTests {
 
410
                out := parseAuthority(tt.in)
 
411
                if out != tt.out {
 
412
                        t.Errorf("got %v; want %v", out, tt.out)
 
413
                }
 
414
        }
 
415
}
 
416
 
 
417
type closerConn struct {
 
418
        net.Conn
 
419
        closed int // count of the number of times Close was called
 
420
}
 
421
 
 
422
func (c *closerConn) Close() error {
 
423
        c.closed++
 
424
        return c.Conn.Close()
 
425
}
 
426
 
 
427
func TestClose(t *testing.T) {
 
428
        once.Do(startServer)
 
429
 
 
430
        conn, err := net.Dial("tcp", serverAddr)
 
431
        if err != nil {
 
432
                t.Fatal("dialing", err)
 
433
        }
 
434
 
 
435
        cc := closerConn{Conn: conn}
 
436
 
 
437
        client, err := NewClient(newConfig(t, "/echo"), &cc)
 
438
        if err != nil {
 
439
                t.Fatalf("WebSocket handshake: %v", err)
 
440
        }
 
441
 
 
442
        // set the deadline to ten minutes ago, which will have expired by the time
 
443
        // client.Close sends the close status frame.
 
444
        conn.SetDeadline(time.Now().Add(-10 * time.Minute))
 
445
 
 
446
        if err := client.Close(); err == nil {
 
447
                t.Errorf("ws.Close(): expected error, got %v", err)
 
448
        }
 
449
        if cc.closed < 1 {
 
450
                t.Fatalf("ws.Close(): expected underlying ws.rwc.Close to be called > 0 times, got: %v", cc.closed)
 
451
        }
 
452
}