hybi_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  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 TestHybiClientHandshakeHybi08(t *testing.T) {
  151. b := bytes.NewBuffer([]byte{})
  152. bw := bufio.NewWriter(b)
  153. br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols
  154. Upgrade: websocket
  155. Connection: Upgrade
  156. Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
  157. Sec-WebSocket-Protocol: chat
  158. `))
  159. var err error
  160. config := new(Config)
  161. config.Location, err = url.ParseRequestURI("ws://server.example.com/chat")
  162. if err != nil {
  163. t.Fatal("location url", err)
  164. }
  165. config.Origin, err = url.ParseRequestURI("http://example.com")
  166. if err != nil {
  167. t.Fatal("origin url", err)
  168. }
  169. config.Protocol = append(config.Protocol, "chat")
  170. config.Protocol = append(config.Protocol, "superchat")
  171. config.Version = ProtocolVersionHybi08
  172. config.handshakeData = map[string]string{
  173. "key": "dGhlIHNhbXBsZSBub25jZQ==",
  174. }
  175. err = hybiClientHandshake(config, br, bw)
  176. if err != nil {
  177. t.Errorf("handshake failed: %v", err)
  178. }
  179. req, err := http.ReadRequest(bufio.NewReader(b))
  180. if err != nil {
  181. t.Fatalf("read request: %v", err)
  182. }
  183. if req.Method != "GET" {
  184. t.Errorf("request method expected GET, but got %q", req.Method)
  185. }
  186. if req.URL.Path != "/chat" {
  187. t.Errorf("request path expected /demo, but got %q", req.URL.Path)
  188. }
  189. if req.Proto != "HTTP/1.1" {
  190. t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto)
  191. }
  192. if req.Host != "server.example.com" {
  193. t.Errorf("request Host expected example.com, but got %v", req.Host)
  194. }
  195. var expectedHeader = map[string]string{
  196. "Connection": "Upgrade",
  197. "Upgrade": "websocket",
  198. "Sec-Websocket-Key": config.handshakeData["key"],
  199. "Sec-Websocket-Origin": config.Origin.String(),
  200. "Sec-Websocket-Protocol": "chat, superchat",
  201. "Sec-Websocket-Version": fmt.Sprintf("%d", ProtocolVersionHybi08),
  202. }
  203. for k, v := range expectedHeader {
  204. if req.Header.Get(k) != v {
  205. t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k)))
  206. }
  207. }
  208. }
  209. func TestHybiServerHandshake(t *testing.T) {
  210. config := new(Config)
  211. handshaker := &hybiServerHandshaker{Config: config}
  212. br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
  213. Host: server.example.com
  214. Upgrade: websocket
  215. Connection: Upgrade
  216. Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  217. Origin: http://example.com
  218. Sec-WebSocket-Protocol: chat, superchat
  219. Sec-WebSocket-Version: 13
  220. `))
  221. req, err := http.ReadRequest(br)
  222. if err != nil {
  223. t.Fatal("request", err)
  224. }
  225. code, err := handshaker.ReadHandshake(br, req)
  226. if err != nil {
  227. t.Errorf("handshake failed: %v", err)
  228. }
  229. if code != http.StatusSwitchingProtocols {
  230. t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
  231. }
  232. b := bytes.NewBuffer([]byte{})
  233. bw := bufio.NewWriter(b)
  234. config.Protocol = []string{"chat"}
  235. err = handshaker.AcceptHandshake(bw)
  236. if err != nil {
  237. t.Errorf("handshake response failed: %v", err)
  238. }
  239. expectedResponse := strings.Join([]string{
  240. "HTTP/1.1 101 Switching Protocols",
  241. "Upgrade: websocket",
  242. "Connection: Upgrade",
  243. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
  244. "Sec-WebSocket-Protocol: chat",
  245. "", ""}, "\r\n")
  246. if b.String() != expectedResponse {
  247. t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
  248. }
  249. }
  250. func TestHybiServerHandshakeHybi08(t *testing.T) {
  251. config := new(Config)
  252. handshaker := &hybiServerHandshaker{Config: config}
  253. br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
  254. Host: server.example.com
  255. Upgrade: websocket
  256. Connection: Upgrade
  257. Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  258. Sec-WebSocket-Origin: http://example.com
  259. Sec-WebSocket-Protocol: chat, superchat
  260. Sec-WebSocket-Version: 8
  261. `))
  262. req, err := http.ReadRequest(br)
  263. if err != nil {
  264. t.Fatal("request", err)
  265. }
  266. code, err := handshaker.ReadHandshake(br, req)
  267. if err != nil {
  268. t.Errorf("handshake failed: %v", err)
  269. }
  270. if code != http.StatusSwitchingProtocols {
  271. t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
  272. }
  273. b := bytes.NewBuffer([]byte{})
  274. bw := bufio.NewWriter(b)
  275. config.Protocol = []string{"chat"}
  276. err = handshaker.AcceptHandshake(bw)
  277. if err != nil {
  278. t.Errorf("handshake response failed: %v", err)
  279. }
  280. expectedResponse := strings.Join([]string{
  281. "HTTP/1.1 101 Switching Protocols",
  282. "Upgrade: websocket",
  283. "Connection: Upgrade",
  284. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
  285. "Sec-WebSocket-Protocol: chat",
  286. "", ""}, "\r\n")
  287. if b.String() != expectedResponse {
  288. t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
  289. }
  290. }
  291. func TestHybiServerHandshakeHybiBadVersion(t *testing.T) {
  292. config := new(Config)
  293. handshaker := &hybiServerHandshaker{Config: config}
  294. br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
  295. Host: server.example.com
  296. Upgrade: websocket
  297. Connection: Upgrade
  298. Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  299. Sec-WebSocket-Origin: http://example.com
  300. Sec-WebSocket-Protocol: chat, superchat
  301. Sec-WebSocket-Version: 9
  302. `))
  303. req, err := http.ReadRequest(br)
  304. if err != nil {
  305. t.Fatal("request", err)
  306. }
  307. code, err := handshaker.ReadHandshake(br, req)
  308. if err != ErrBadWebSocketVersion {
  309. t.Errorf("handshake expected err %q but got %q", ErrBadWebSocketVersion, err)
  310. }
  311. if code != http.StatusBadRequest {
  312. t.Errorf("status expected %q but got %q", http.StatusBadRequest, code)
  313. }
  314. }
  315. func testHybiFrame(t *testing.T, testHeader, testPayload, testMaskedPayload []byte, frameHeader *hybiFrameHeader) {
  316. b := bytes.NewBuffer([]byte{})
  317. frameWriterFactory := &hybiFrameWriterFactory{bufio.NewWriter(b), false}
  318. w, _ := frameWriterFactory.NewFrameWriter(TextFrame)
  319. w.(*hybiFrameWriter).header = frameHeader
  320. _, err := w.Write(testPayload)
  321. w.Close()
  322. if err != nil {
  323. t.Errorf("Write error %q", err)
  324. }
  325. var expectedFrame []byte
  326. expectedFrame = append(expectedFrame, testHeader...)
  327. expectedFrame = append(expectedFrame, testMaskedPayload...)
  328. if !bytes.Equal(expectedFrame, b.Bytes()) {
  329. t.Errorf("frame expected %q got %q", expectedFrame, b.Bytes())
  330. }
  331. frameReaderFactory := &hybiFrameReaderFactory{bufio.NewReader(b)}
  332. r, err := frameReaderFactory.NewFrameReader()
  333. if err != nil {
  334. t.Errorf("Read error %q", err)
  335. }
  336. if header := r.HeaderReader(); header == nil {
  337. t.Errorf("no header")
  338. } else {
  339. actualHeader := make([]byte, r.Len())
  340. n, err := header.Read(actualHeader)
  341. if err != nil {
  342. t.Errorf("Read header error %q", err)
  343. } else {
  344. if n < len(testHeader) {
  345. t.Errorf("header too short %q got %q", testHeader, actualHeader[:n])
  346. }
  347. if !bytes.Equal(testHeader, actualHeader[:n]) {
  348. t.Errorf("header expected %q got %q", testHeader, actualHeader[:n])
  349. }
  350. }
  351. }
  352. if trailer := r.TrailerReader(); trailer != nil {
  353. t.Errorf("unexpected trailer %q", trailer)
  354. }
  355. frame := r.(*hybiFrameReader)
  356. if frameHeader.Fin != frame.header.Fin ||
  357. frameHeader.OpCode != frame.header.OpCode ||
  358. len(testPayload) != int(frame.header.Length) {
  359. t.Errorf("mismatch %v (%d) vs %v", frameHeader, len(testPayload), frame)
  360. }
  361. payload := make([]byte, len(testPayload))
  362. _, err = r.Read(payload)
  363. if err != nil {
  364. t.Errorf("read %v", err)
  365. }
  366. if !bytes.Equal(testPayload, payload) {
  367. t.Errorf("payload %q vs %q", testPayload, payload)
  368. }
  369. }
  370. func TestHybiShortTextFrame(t *testing.T) {
  371. frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame}
  372. payload := []byte("hello")
  373. testHybiFrame(t, []byte{0x81, 0x05}, payload, payload, frameHeader)
  374. payload = make([]byte, 125)
  375. testHybiFrame(t, []byte{0x81, 125}, payload, payload, frameHeader)
  376. }
  377. func TestHybiShortMaskedTextFrame(t *testing.T) {
  378. frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame,
  379. MaskingKey: []byte{0xcc, 0x55, 0x80, 0x20}}
  380. payload := []byte("hello")
  381. maskedPayload := []byte{0xa4, 0x30, 0xec, 0x4c, 0xa3}
  382. header := []byte{0x81, 0x85}
  383. header = append(header, frameHeader.MaskingKey...)
  384. testHybiFrame(t, header, payload, maskedPayload, frameHeader)
  385. }
  386. func TestHybiShortBinaryFrame(t *testing.T) {
  387. frameHeader := &hybiFrameHeader{Fin: true, OpCode: BinaryFrame}
  388. payload := []byte("hello")
  389. testHybiFrame(t, []byte{0x82, 0x05}, payload, payload, frameHeader)
  390. payload = make([]byte, 125)
  391. testHybiFrame(t, []byte{0x82, 125}, payload, payload, frameHeader)
  392. }
  393. func TestHybiControlFrame(t *testing.T) {
  394. frameHeader := &hybiFrameHeader{Fin: true, OpCode: PingFrame}
  395. payload := []byte("hello")
  396. testHybiFrame(t, []byte{0x89, 0x05}, payload, payload, frameHeader)
  397. frameHeader = &hybiFrameHeader{Fin: true, OpCode: PongFrame}
  398. testHybiFrame(t, []byte{0x8A, 0x05}, payload, payload, frameHeader)
  399. frameHeader = &hybiFrameHeader{Fin: true, OpCode: CloseFrame}
  400. payload = []byte{0x03, 0xe8} // 1000
  401. testHybiFrame(t, []byte{0x88, 0x02}, payload, payload, frameHeader)
  402. }
  403. func TestHybiLongFrame(t *testing.T) {
  404. frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame}
  405. payload := make([]byte, 126)
  406. testHybiFrame(t, []byte{0x81, 126, 0x00, 126}, payload, payload, frameHeader)
  407. payload = make([]byte, 65535)
  408. testHybiFrame(t, []byte{0x81, 126, 0xff, 0xff}, payload, payload, frameHeader)
  409. payload = make([]byte, 65536)
  410. testHybiFrame(t, []byte{0x81, 127, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}, payload, payload, frameHeader)
  411. }
  412. func TestHybiClientRead(t *testing.T) {
  413. wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o',
  414. 0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping
  415. 0x81, 0x05, 'w', 'o', 'r', 'l', 'd'}
  416. br := bufio.NewReader(bytes.NewBuffer(wireData))
  417. bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
  418. conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil)
  419. msg := make([]byte, 512)
  420. n, err := conn.Read(msg)
  421. if err != nil {
  422. t.Errorf("read 1st frame, error %q", err)
  423. }
  424. if n != 5 {
  425. t.Errorf("read 1st frame, expect 5, got %d", n)
  426. }
  427. if !bytes.Equal(wireData[2:7], msg[:n]) {
  428. t.Errorf("read 1st frame %v, got %v", wireData[2:7], msg[:n])
  429. }
  430. n, err = conn.Read(msg)
  431. if err != nil {
  432. t.Errorf("read 2nd frame, error %q", err)
  433. }
  434. if n != 5 {
  435. t.Errorf("read 2nd frame, expect 5, got %d", n)
  436. }
  437. if !bytes.Equal(wireData[16:21], msg[:n]) {
  438. t.Errorf("read 2nd frame %v, got %v", wireData[16:21], msg[:n])
  439. }
  440. n, err = conn.Read(msg)
  441. if err == nil {
  442. t.Errorf("read not EOF")
  443. }
  444. if n != 0 {
  445. t.Errorf("expect read 0, got %d", n)
  446. }
  447. }
  448. func TestHybiShortRead(t *testing.T) {
  449. wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o',
  450. 0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping
  451. 0x81, 0x05, 'w', 'o', 'r', 'l', 'd'}
  452. br := bufio.NewReader(bytes.NewBuffer(wireData))
  453. bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
  454. conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil)
  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. 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. expected := [][]byte{[]byte("hello"), []byte("world")}
  498. msg := make([]byte, 512)
  499. n, err := conn.Read(msg)
  500. if err != nil {
  501. t.Errorf("read 1st frame, error %q", err)
  502. }
  503. if n != 5 {
  504. t.Errorf("read 1st frame, expect 5, got %d", n)
  505. }
  506. if !bytes.Equal(expected[0], msg[:n]) {
  507. t.Errorf("read 1st frame %q, got %q", expected[0], msg[:n])
  508. }
  509. n, err = conn.Read(msg)
  510. if err != nil {
  511. t.Errorf("read 2nd frame, error %q", err)
  512. }
  513. if n != 5 {
  514. t.Errorf("read 2nd frame, expect 5, got %d", n)
  515. }
  516. if !bytes.Equal(expected[1], msg[:n]) {
  517. t.Errorf("read 2nd frame %q, got %q", expected[1], msg[:n])
  518. }
  519. n, err = conn.Read(msg)
  520. if err == nil {
  521. t.Errorf("read not EOF")
  522. }
  523. if n != 0 {
  524. t.Errorf("expect read 0, got %d", n)
  525. }
  526. }
  527. func TestHybiServerReadWithoutMasking(t *testing.T) {
  528. wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o'}
  529. br := bufio.NewReader(bytes.NewBuffer(wireData))
  530. bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
  531. conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request))
  532. // server MUST close the connection upon receiving a non-masked frame.
  533. msg := make([]byte, 512)
  534. _, err := conn.Read(msg)
  535. if err != io.EOF {
  536. t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err)
  537. }
  538. }
  539. func TestHybiClientReadWithMasking(t *testing.T) {
  540. wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20,
  541. 0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello
  542. }
  543. br := bufio.NewReader(bytes.NewBuffer(wireData))
  544. bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
  545. conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil)
  546. // client MUST close the connection upon receiving a masked frame.
  547. msg := make([]byte, 512)
  548. _, err := conn.Read(msg)
  549. if err != io.EOF {
  550. t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err)
  551. }
  552. }
  553. // Test the hybiServerHandshaker supports firefox implementation and
  554. // checks Connection request header include (but it's not necessary
  555. // equal to) "upgrade"
  556. func TestHybiServerFirefoxHandshake(t *testing.T) {
  557. config := new(Config)
  558. handshaker := &hybiServerHandshaker{Config: config}
  559. br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
  560. Host: server.example.com
  561. Upgrade: websocket
  562. Connection: keep-alive, upgrade
  563. Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  564. Origin: http://example.com
  565. Sec-WebSocket-Protocol: chat, superchat
  566. Sec-WebSocket-Version: 13
  567. `))
  568. req, err := http.ReadRequest(br)
  569. if err != nil {
  570. t.Fatal("request", err)
  571. }
  572. code, err := handshaker.ReadHandshake(br, req)
  573. if err != nil {
  574. t.Errorf("handshake failed: %v", err)
  575. }
  576. if code != http.StatusSwitchingProtocols {
  577. t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
  578. }
  579. b := bytes.NewBuffer([]byte{})
  580. bw := bufio.NewWriter(b)
  581. config.Protocol = []string{"chat"}
  582. err = handshaker.AcceptHandshake(bw)
  583. if err != nil {
  584. t.Errorf("handshake response failed: %v", err)
  585. }
  586. expectedResponse := strings.Join([]string{
  587. "HTTP/1.1 101 Switching Protocols",
  588. "Upgrade: websocket",
  589. "Connection: Upgrade",
  590. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
  591. "Sec-WebSocket-Protocol: chat",
  592. "", ""}, "\r\n")
  593. if b.String() != expectedResponse {
  594. t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
  595. }
  596. }