hybi_test.go 17 KB

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