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