hybi_test.go 18 KB

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