golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/websocket/hybi_test.go (about) 1 // Copyright 2011 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 "bufio" 9 "bytes" 10 "fmt" 11 "io" 12 "net/http" 13 "net/url" 14 "strings" 15 "testing" 16 ) 17 18 // Test the getNonceAccept function with values in 19 // http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17 20 func TestSecWebSocketAccept(t *testing.T) { 21 nonce := []byte("dGhlIHNhbXBsZSBub25jZQ==") 22 expected := []byte("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=") 23 accept, err := getNonceAccept(nonce) 24 if err != nil { 25 t.Errorf("getNonceAccept: returned error %v", err) 26 return 27 } 28 if !bytes.Equal(expected, accept) { 29 t.Errorf("getNonceAccept: expected %q got %q", expected, accept) 30 } 31 } 32 33 func TestHybiClientHandshake(t *testing.T) { 34 type test struct { 35 url, host string 36 } 37 tests := []test{ 38 {"ws://server.example.com/chat", "server.example.com"}, 39 {"ws://127.0.0.1/chat", "127.0.0.1"}, 40 } 41 if _, err := url.ParseRequestURI("http://[fe80::1%25lo0]"); err == nil { 42 tests = append(tests, test{"ws://[fe80::1%25lo0]/chat", "[fe80::1]"}) 43 } 44 45 for _, tt := range tests { 46 var b bytes.Buffer 47 bw := bufio.NewWriter(&b) 48 br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols 49 Upgrade: websocket 50 Connection: Upgrade 51 Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= 52 Sec-WebSocket-Protocol: chat 53 54 `)) 55 var err error 56 var config Config 57 config.Location, err = url.ParseRequestURI(tt.url) 58 if err != nil { 59 t.Fatal("location url", err) 60 } 61 config.Origin, err = url.ParseRequestURI("http://example.com") 62 if err != nil { 63 t.Fatal("origin url", err) 64 } 65 config.Protocol = append(config.Protocol, "chat") 66 config.Protocol = append(config.Protocol, "superchat") 67 config.Version = ProtocolVersionHybi13 68 config.handshakeData = map[string]string{ 69 "key": "dGhlIHNhbXBsZSBub25jZQ==", 70 } 71 if err := hybiClientHandshake(&config, br, bw); err != nil { 72 t.Fatal("handshake", err) 73 } 74 req, err := http.ReadRequest(bufio.NewReader(&b)) 75 if err != nil { 76 t.Fatal("read request", err) 77 } 78 if req.Method != "GET" { 79 t.Errorf("request method expected GET, but got %s", req.Method) 80 } 81 if req.URL.Path != "/chat" { 82 t.Errorf("request path expected /chat, but got %s", req.URL.Path) 83 } 84 if req.Proto != "HTTP/1.1" { 85 t.Errorf("request proto expected HTTP/1.1, but got %s", req.Proto) 86 } 87 if req.Host != tt.host { 88 t.Errorf("request host expected %s, but got %s", tt.host, req.Host) 89 } 90 var expectedHeader = map[string]string{ 91 "Connection": "Upgrade", 92 "Upgrade": "websocket", 93 "Sec-Websocket-Key": config.handshakeData["key"], 94 "Origin": config.Origin.String(), 95 "Sec-Websocket-Protocol": "chat, superchat", 96 "Sec-Websocket-Version": fmt.Sprintf("%d", ProtocolVersionHybi13), 97 } 98 for k, v := range expectedHeader { 99 if req.Header.Get(k) != v { 100 t.Errorf("%s expected %s, but got %v", k, v, req.Header.Get(k)) 101 } 102 } 103 } 104 } 105 106 func TestHybiClientHandshakeWithHeader(t *testing.T) { 107 b := bytes.NewBuffer([]byte{}) 108 bw := bufio.NewWriter(b) 109 br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols 110 Upgrade: websocket 111 Connection: Upgrade 112 Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= 113 Sec-WebSocket-Protocol: chat 114 115 `)) 116 var err error 117 config := new(Config) 118 config.Location, err = url.ParseRequestURI("ws://server.example.com/chat") 119 if err != nil { 120 t.Fatal("location url", err) 121 } 122 config.Origin, err = url.ParseRequestURI("http://example.com") 123 if err != nil { 124 t.Fatal("origin url", err) 125 } 126 config.Protocol = append(config.Protocol, "chat") 127 config.Protocol = append(config.Protocol, "superchat") 128 config.Version = ProtocolVersionHybi13 129 config.Header = http.Header(make(map[string][]string)) 130 config.Header.Add("User-Agent", "test") 131 132 config.handshakeData = map[string]string{ 133 "key": "dGhlIHNhbXBsZSBub25jZQ==", 134 } 135 err = hybiClientHandshake(config, br, bw) 136 if err != nil { 137 t.Errorf("handshake failed: %v", err) 138 } 139 req, err := http.ReadRequest(bufio.NewReader(b)) 140 if err != nil { 141 t.Fatalf("read request: %v", err) 142 } 143 if req.Method != "GET" { 144 t.Errorf("request method expected GET, but got %q", req.Method) 145 } 146 if req.URL.Path != "/chat" { 147 t.Errorf("request path expected /chat, but got %q", req.URL.Path) 148 } 149 if req.Proto != "HTTP/1.1" { 150 t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto) 151 } 152 if req.Host != "server.example.com" { 153 t.Errorf("request Host expected server.example.com, but got %v", req.Host) 154 } 155 var expectedHeader = map[string]string{ 156 "Connection": "Upgrade", 157 "Upgrade": "websocket", 158 "Sec-Websocket-Key": config.handshakeData["key"], 159 "Origin": config.Origin.String(), 160 "Sec-Websocket-Protocol": "chat, superchat", 161 "Sec-Websocket-Version": fmt.Sprintf("%d", ProtocolVersionHybi13), 162 "User-Agent": "test", 163 } 164 for k, v := range expectedHeader { 165 if req.Header.Get(k) != v { 166 t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k))) 167 } 168 } 169 } 170 171 func TestHybiServerHandshake(t *testing.T) { 172 config := new(Config) 173 handshaker := &hybiServerHandshaker{Config: config} 174 br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 175 Host: server.example.com 176 Upgrade: websocket 177 Connection: Upgrade 178 Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== 179 Origin: http://example.com 180 Sec-WebSocket-Protocol: chat, superchat 181 Sec-WebSocket-Version: 13 182 183 `)) 184 req, err := http.ReadRequest(br) 185 if err != nil { 186 t.Fatal("request", err) 187 } 188 code, err := handshaker.ReadHandshake(br, req) 189 if err != nil { 190 t.Errorf("handshake failed: %v", err) 191 } 192 if code != http.StatusSwitchingProtocols { 193 t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) 194 } 195 expectedProtocols := []string{"chat", "superchat"} 196 if fmt.Sprintf("%v", config.Protocol) != fmt.Sprintf("%v", expectedProtocols) { 197 t.Errorf("protocol expected %q but got %q", expectedProtocols, config.Protocol) 198 } 199 b := bytes.NewBuffer([]byte{}) 200 bw := bufio.NewWriter(b) 201 202 config.Protocol = config.Protocol[:1] 203 204 err = handshaker.AcceptHandshake(bw) 205 if err != nil { 206 t.Errorf("handshake response failed: %v", err) 207 } 208 expectedResponse := strings.Join([]string{ 209 "HTTP/1.1 101 Switching Protocols", 210 "Upgrade: websocket", 211 "Connection: Upgrade", 212 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", 213 "Sec-WebSocket-Protocol: chat", 214 "", ""}, "\r\n") 215 216 if b.String() != expectedResponse { 217 t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) 218 } 219 } 220 221 func TestHybiServerHandshakeNoSubProtocol(t *testing.T) { 222 config := new(Config) 223 handshaker := &hybiServerHandshaker{Config: config} 224 br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 225 Host: server.example.com 226 Upgrade: websocket 227 Connection: Upgrade 228 Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== 229 Origin: http://example.com 230 Sec-WebSocket-Version: 13 231 232 `)) 233 req, err := http.ReadRequest(br) 234 if err != nil { 235 t.Fatal("request", err) 236 } 237 code, err := handshaker.ReadHandshake(br, req) 238 if err != nil { 239 t.Errorf("handshake failed: %v", err) 240 } 241 if code != http.StatusSwitchingProtocols { 242 t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) 243 } 244 if len(config.Protocol) != 0 { 245 t.Errorf("len(config.Protocol) expected 0, but got %q", len(config.Protocol)) 246 } 247 b := bytes.NewBuffer([]byte{}) 248 bw := bufio.NewWriter(b) 249 250 err = handshaker.AcceptHandshake(bw) 251 if err != nil { 252 t.Errorf("handshake response failed: %v", err) 253 } 254 expectedResponse := strings.Join([]string{ 255 "HTTP/1.1 101 Switching Protocols", 256 "Upgrade: websocket", 257 "Connection: Upgrade", 258 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", 259 "", ""}, "\r\n") 260 261 if b.String() != expectedResponse { 262 t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) 263 } 264 } 265 266 func TestHybiServerHandshakeHybiBadVersion(t *testing.T) { 267 config := new(Config) 268 handshaker := &hybiServerHandshaker{Config: config} 269 br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 270 Host: server.example.com 271 Upgrade: websocket 272 Connection: Upgrade 273 Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== 274 Sec-WebSocket-Origin: http://example.com 275 Sec-WebSocket-Protocol: chat, superchat 276 Sec-WebSocket-Version: 9 277 278 `)) 279 req, err := http.ReadRequest(br) 280 if err != nil { 281 t.Fatal("request", err) 282 } 283 code, err := handshaker.ReadHandshake(br, req) 284 if err != ErrBadWebSocketVersion { 285 t.Errorf("handshake expected err %q but got %q", ErrBadWebSocketVersion, err) 286 } 287 if code != http.StatusBadRequest { 288 t.Errorf("status expected %q but got %q", http.StatusBadRequest, code) 289 } 290 } 291 292 func testHybiFrame(t *testing.T, testHeader, testPayload, testMaskedPayload []byte, frameHeader *hybiFrameHeader) { 293 b := bytes.NewBuffer([]byte{}) 294 frameWriterFactory := &hybiFrameWriterFactory{bufio.NewWriter(b), false} 295 w, _ := frameWriterFactory.NewFrameWriter(TextFrame) 296 w.(*hybiFrameWriter).header = frameHeader 297 _, err := w.Write(testPayload) 298 w.Close() 299 if err != nil { 300 t.Errorf("Write error %q", err) 301 } 302 var expectedFrame []byte 303 expectedFrame = append(expectedFrame, testHeader...) 304 expectedFrame = append(expectedFrame, testMaskedPayload...) 305 if !bytes.Equal(expectedFrame, b.Bytes()) { 306 t.Errorf("frame expected %q got %q", expectedFrame, b.Bytes()) 307 } 308 frameReaderFactory := &hybiFrameReaderFactory{bufio.NewReader(b)} 309 r, err := frameReaderFactory.NewFrameReader() 310 if err != nil { 311 t.Errorf("Read error %q", err) 312 } 313 if header := r.HeaderReader(); header == nil { 314 t.Errorf("no header") 315 } else { 316 actualHeader := make([]byte, r.Len()) 317 n, err := header.Read(actualHeader) 318 if err != nil { 319 t.Errorf("Read header error %q", err) 320 } else { 321 if n < len(testHeader) { 322 t.Errorf("header too short %q got %q", testHeader, actualHeader[:n]) 323 } 324 if !bytes.Equal(testHeader, actualHeader[:n]) { 325 t.Errorf("header expected %q got %q", testHeader, actualHeader[:n]) 326 } 327 } 328 } 329 if trailer := r.TrailerReader(); trailer != nil { 330 t.Errorf("unexpected trailer %q", trailer) 331 } 332 frame := r.(*hybiFrameReader) 333 if frameHeader.Fin != frame.header.Fin || 334 frameHeader.OpCode != frame.header.OpCode || 335 len(testPayload) != int(frame.header.Length) { 336 t.Errorf("mismatch %v (%d) vs %v", frameHeader, len(testPayload), frame) 337 } 338 payload := make([]byte, len(testPayload)) 339 _, err = r.Read(payload) 340 if err != nil && err != io.EOF { 341 t.Errorf("read %v", err) 342 } 343 if !bytes.Equal(testPayload, payload) { 344 t.Errorf("payload %q vs %q", testPayload, payload) 345 } 346 } 347 348 func TestHybiShortTextFrame(t *testing.T) { 349 frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame} 350 payload := []byte("hello") 351 testHybiFrame(t, []byte{0x81, 0x05}, payload, payload, frameHeader) 352 353 payload = make([]byte, 125) 354 testHybiFrame(t, []byte{0x81, 125}, payload, payload, frameHeader) 355 } 356 357 func TestHybiShortMaskedTextFrame(t *testing.T) { 358 frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame, 359 MaskingKey: []byte{0xcc, 0x55, 0x80, 0x20}} 360 payload := []byte("hello") 361 maskedPayload := []byte{0xa4, 0x30, 0xec, 0x4c, 0xa3} 362 header := []byte{0x81, 0x85} 363 header = append(header, frameHeader.MaskingKey...) 364 testHybiFrame(t, header, payload, maskedPayload, frameHeader) 365 } 366 367 func TestHybiShortBinaryFrame(t *testing.T) { 368 frameHeader := &hybiFrameHeader{Fin: true, OpCode: BinaryFrame} 369 payload := []byte("hello") 370 testHybiFrame(t, []byte{0x82, 0x05}, payload, payload, frameHeader) 371 372 payload = make([]byte, 125) 373 testHybiFrame(t, []byte{0x82, 125}, payload, payload, frameHeader) 374 } 375 376 func TestHybiControlFrame(t *testing.T) { 377 payload := []byte("hello") 378 379 frameHeader := &hybiFrameHeader{Fin: true, OpCode: PingFrame} 380 testHybiFrame(t, []byte{0x89, 0x05}, payload, payload, frameHeader) 381 382 frameHeader = &hybiFrameHeader{Fin: true, OpCode: PingFrame} 383 testHybiFrame(t, []byte{0x89, 0x00}, nil, nil, frameHeader) 384 385 frameHeader = &hybiFrameHeader{Fin: true, OpCode: PongFrame} 386 testHybiFrame(t, []byte{0x8A, 0x05}, payload, payload, frameHeader) 387 388 frameHeader = &hybiFrameHeader{Fin: true, OpCode: PongFrame} 389 testHybiFrame(t, []byte{0x8A, 0x00}, nil, nil, frameHeader) 390 391 frameHeader = &hybiFrameHeader{Fin: true, OpCode: CloseFrame} 392 payload = []byte{0x03, 0xe8} // 1000 393 testHybiFrame(t, []byte{0x88, 0x02}, payload, payload, frameHeader) 394 } 395 396 func TestHybiLongFrame(t *testing.T) { 397 frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame} 398 payload := make([]byte, 126) 399 testHybiFrame(t, []byte{0x81, 126, 0x00, 126}, payload, payload, frameHeader) 400 401 payload = make([]byte, 65535) 402 testHybiFrame(t, []byte{0x81, 126, 0xff, 0xff}, payload, payload, frameHeader) 403 404 payload = make([]byte, 65536) 405 testHybiFrame(t, []byte{0x81, 127, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}, payload, payload, frameHeader) 406 } 407 408 func TestHybiClientRead(t *testing.T) { 409 wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o', 410 0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping 411 0x81, 0x05, 'w', 'o', 'r', 'l', 'd'} 412 br := bufio.NewReader(bytes.NewBuffer(wireData)) 413 bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) 414 conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil) 415 416 msg := make([]byte, 512) 417 n, err := conn.Read(msg) 418 if err != nil { 419 t.Errorf("read 1st frame, error %q", err) 420 } 421 if n != 5 { 422 t.Errorf("read 1st frame, expect 5, got %d", n) 423 } 424 if !bytes.Equal(wireData[2:7], msg[:n]) { 425 t.Errorf("read 1st frame %v, got %v", wireData[2:7], msg[:n]) 426 } 427 n, err = conn.Read(msg) 428 if err != nil { 429 t.Errorf("read 2nd frame, error %q", err) 430 } 431 if n != 5 { 432 t.Errorf("read 2nd frame, expect 5, got %d", n) 433 } 434 if !bytes.Equal(wireData[16:21], msg[:n]) { 435 t.Errorf("read 2nd frame %v, got %v", wireData[16:21], msg[:n]) 436 } 437 n, err = conn.Read(msg) 438 if err == nil { 439 t.Errorf("read not EOF") 440 } 441 if n != 0 { 442 t.Errorf("expect read 0, got %d", n) 443 } 444 } 445 446 func TestHybiShortRead(t *testing.T) { 447 wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o', 448 0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping 449 0x81, 0x05, 'w', 'o', 'r', 'l', 'd'} 450 br := bufio.NewReader(bytes.NewBuffer(wireData)) 451 bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) 452 conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil) 453 454 step := 0 455 pos := 0 456 expectedPos := []int{2, 5, 16, 19} 457 expectedLen := []int{3, 2, 3, 2} 458 for { 459 msg := make([]byte, 3) 460 n, err := conn.Read(msg) 461 if step >= len(expectedPos) { 462 if err == nil { 463 t.Errorf("read not EOF") 464 } 465 if n != 0 { 466 t.Errorf("expect read 0, got %d", n) 467 } 468 return 469 } 470 pos = expectedPos[step] 471 endPos := pos + expectedLen[step] 472 if err != nil { 473 t.Errorf("read from %d, got error %q", pos, err) 474 return 475 } 476 if n != endPos-pos { 477 t.Errorf("read from %d, expect %d, got %d", pos, endPos-pos, n) 478 } 479 if !bytes.Equal(wireData[pos:endPos], msg[:n]) { 480 t.Errorf("read from %d, frame %v, got %v", pos, wireData[pos:endPos], msg[:n]) 481 } 482 step++ 483 } 484 } 485 486 func TestHybiServerRead(t *testing.T) { 487 wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20, 488 0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello 489 0x89, 0x85, 0xcc, 0x55, 0x80, 0x20, 490 0xa4, 0x30, 0xec, 0x4c, 0xa3, // ping: hello 491 0x81, 0x85, 0xed, 0x83, 0xb4, 0x24, 492 0x9a, 0xec, 0xc6, 0x48, 0x89, // world 493 } 494 br := bufio.NewReader(bytes.NewBuffer(wireData)) 495 bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) 496 conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request)) 497 498 expected := [][]byte{[]byte("hello"), []byte("world")} 499 500 msg := make([]byte, 512) 501 n, err := conn.Read(msg) 502 if err != nil { 503 t.Errorf("read 1st frame, error %q", err) 504 } 505 if n != 5 { 506 t.Errorf("read 1st frame, expect 5, got %d", n) 507 } 508 if !bytes.Equal(expected[0], msg[:n]) { 509 t.Errorf("read 1st frame %q, got %q", expected[0], msg[:n]) 510 } 511 512 n, err = conn.Read(msg) 513 if err != nil { 514 t.Errorf("read 2nd frame, error %q", err) 515 } 516 if n != 5 { 517 t.Errorf("read 2nd frame, expect 5, got %d", n) 518 } 519 if !bytes.Equal(expected[1], msg[:n]) { 520 t.Errorf("read 2nd frame %q, got %q", expected[1], msg[:n]) 521 } 522 523 n, err = conn.Read(msg) 524 if err == nil { 525 t.Errorf("read not EOF") 526 } 527 if n != 0 { 528 t.Errorf("expect read 0, got %d", n) 529 } 530 } 531 532 func TestHybiServerReadWithoutMasking(t *testing.T) { 533 wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o'} 534 br := bufio.NewReader(bytes.NewBuffer(wireData)) 535 bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) 536 conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request)) 537 // server MUST close the connection upon receiving a non-masked frame. 538 msg := make([]byte, 512) 539 _, err := conn.Read(msg) 540 if err != io.EOF { 541 t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err) 542 } 543 } 544 545 func TestHybiClientReadWithMasking(t *testing.T) { 546 wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20, 547 0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello 548 } 549 br := bufio.NewReader(bytes.NewBuffer(wireData)) 550 bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) 551 conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil) 552 553 // client MUST close the connection upon receiving a masked frame. 554 msg := make([]byte, 512) 555 _, err := conn.Read(msg) 556 if err != io.EOF { 557 t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err) 558 } 559 } 560 561 // Test the hybiServerHandshaker supports firefox implementation and 562 // checks Connection request header include (but it's not necessary 563 // equal to) "upgrade" 564 func TestHybiServerFirefoxHandshake(t *testing.T) { 565 config := new(Config) 566 handshaker := &hybiServerHandshaker{Config: config} 567 br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 568 Host: server.example.com 569 Upgrade: websocket 570 Connection: keep-alive, upgrade 571 Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== 572 Origin: http://example.com 573 Sec-WebSocket-Protocol: chat, superchat 574 Sec-WebSocket-Version: 13 575 576 `)) 577 req, err := http.ReadRequest(br) 578 if err != nil { 579 t.Fatal("request", err) 580 } 581 code, err := handshaker.ReadHandshake(br, req) 582 if err != nil { 583 t.Errorf("handshake failed: %v", err) 584 } 585 if code != http.StatusSwitchingProtocols { 586 t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) 587 } 588 b := bytes.NewBuffer([]byte{}) 589 bw := bufio.NewWriter(b) 590 591 config.Protocol = []string{"chat"} 592 593 err = handshaker.AcceptHandshake(bw) 594 if err != nil { 595 t.Errorf("handshake response failed: %v", err) 596 } 597 expectedResponse := strings.Join([]string{ 598 "HTTP/1.1 101 Switching Protocols", 599 "Upgrade: websocket", 600 "Connection: Upgrade", 601 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", 602 "Sec-WebSocket-Protocol: chat", 603 "", ""}, "\r\n") 604 605 if b.String() != expectedResponse { 606 t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) 607 } 608 }