hybi_test.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  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. expectedProtocols := []string{"chat", "superchat"}
  233. if fmt.Sprintf("%v", config.Protocol) != fmt.Sprintf("%v", expectedProtocols) {
  234. t.Errorf("protocol expected %q but got %q", expectedProtocols, config.Protocol)
  235. }
  236. b := bytes.NewBuffer([]byte{})
  237. bw := bufio.NewWriter(b)
  238. config.Protocol = config.Protocol[:1]
  239. err = handshaker.AcceptHandshake(bw)
  240. if err != nil {
  241. t.Errorf("handshake response failed: %v", err)
  242. }
  243. expectedResponse := strings.Join([]string{
  244. "HTTP/1.1 101 Switching Protocols",
  245. "Upgrade: websocket",
  246. "Connection: Upgrade",
  247. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
  248. "Sec-WebSocket-Protocol: chat",
  249. "", ""}, "\r\n")
  250. if b.String() != expectedResponse {
  251. t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
  252. }
  253. }
  254. func TestHybiServerHandshakeNoSubProtocol(t *testing.T) {
  255. config := new(Config)
  256. handshaker := &hybiServerHandshaker{Config: config}
  257. br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
  258. Host: server.example.com
  259. Upgrade: websocket
  260. Connection: Upgrade
  261. Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  262. Origin: http://example.com
  263. Sec-WebSocket-Version: 13
  264. `))
  265. req, err := http.ReadRequest(br)
  266. if err != nil {
  267. t.Fatal("request", err)
  268. }
  269. code, err := handshaker.ReadHandshake(br, req)
  270. if err != nil {
  271. t.Errorf("handshake failed: %v", err)
  272. }
  273. if code != http.StatusSwitchingProtocols {
  274. t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
  275. }
  276. if len(config.Protocol) != 0 {
  277. t.Errorf("len(config.Protocol) expected 0, but got %q", len(config.Protocol))
  278. }
  279. b := bytes.NewBuffer([]byte{})
  280. bw := bufio.NewWriter(b)
  281. err = handshaker.AcceptHandshake(bw)
  282. if err != nil {
  283. t.Errorf("handshake response failed: %v", err)
  284. }
  285. expectedResponse := strings.Join([]string{
  286. "HTTP/1.1 101 Switching Protocols",
  287. "Upgrade: websocket",
  288. "Connection: Upgrade",
  289. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
  290. "", ""}, "\r\n")
  291. if b.String() != expectedResponse {
  292. t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
  293. }
  294. }
  295. func TestHybiServerHandshakeHybi08(t *testing.T) {
  296. config := new(Config)
  297. handshaker := &hybiServerHandshaker{Config: config}
  298. br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
  299. Host: server.example.com
  300. Upgrade: websocket
  301. Connection: Upgrade
  302. Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  303. Sec-WebSocket-Origin: http://example.com
  304. Sec-WebSocket-Protocol: chat, superchat
  305. Sec-WebSocket-Version: 8
  306. `))
  307. req, err := http.ReadRequest(br)
  308. if err != nil {
  309. t.Fatal("request", err)
  310. }
  311. code, err := handshaker.ReadHandshake(br, req)
  312. if err != nil {
  313. t.Errorf("handshake failed: %v", err)
  314. }
  315. if code != http.StatusSwitchingProtocols {
  316. t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
  317. }
  318. b := bytes.NewBuffer([]byte{})
  319. bw := bufio.NewWriter(b)
  320. config.Protocol = []string{"chat"}
  321. err = handshaker.AcceptHandshake(bw)
  322. if err != nil {
  323. t.Errorf("handshake response failed: %v", err)
  324. }
  325. expectedResponse := strings.Join([]string{
  326. "HTTP/1.1 101 Switching Protocols",
  327. "Upgrade: websocket",
  328. "Connection: Upgrade",
  329. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
  330. "Sec-WebSocket-Protocol: chat",
  331. "", ""}, "\r\n")
  332. if b.String() != expectedResponse {
  333. t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
  334. }
  335. }
  336. func TestHybiServerHandshakeHybiBadVersion(t *testing.T) {
  337. config := new(Config)
  338. handshaker := &hybiServerHandshaker{Config: config}
  339. br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
  340. Host: server.example.com
  341. Upgrade: websocket
  342. Connection: Upgrade
  343. Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  344. Sec-WebSocket-Origin: http://example.com
  345. Sec-WebSocket-Protocol: chat, superchat
  346. Sec-WebSocket-Version: 9
  347. `))
  348. req, err := http.ReadRequest(br)
  349. if err != nil {
  350. t.Fatal("request", err)
  351. }
  352. code, err := handshaker.ReadHandshake(br, req)
  353. if err != ErrBadWebSocketVersion {
  354. t.Errorf("handshake expected err %q but got %q", ErrBadWebSocketVersion, err)
  355. }
  356. if code != http.StatusBadRequest {
  357. t.Errorf("status expected %q but got %q", http.StatusBadRequest, code)
  358. }
  359. }
  360. func testHybiFrame(t *testing.T, testHeader, testPayload, testMaskedPayload []byte, frameHeader *hybiFrameHeader) {
  361. b := bytes.NewBuffer([]byte{})
  362. frameWriterFactory := &hybiFrameWriterFactory{bufio.NewWriter(b), false}
  363. w, _ := frameWriterFactory.NewFrameWriter(TextFrame)
  364. w.(*hybiFrameWriter).header = frameHeader
  365. _, err := w.Write(testPayload)
  366. w.Close()
  367. if err != nil {
  368. t.Errorf("Write error %q", err)
  369. }
  370. var expectedFrame []byte
  371. expectedFrame = append(expectedFrame, testHeader...)
  372. expectedFrame = append(expectedFrame, testMaskedPayload...)
  373. if !bytes.Equal(expectedFrame, b.Bytes()) {
  374. t.Errorf("frame expected %q got %q", expectedFrame, b.Bytes())
  375. }
  376. frameReaderFactory := &hybiFrameReaderFactory{bufio.NewReader(b)}
  377. r, err := frameReaderFactory.NewFrameReader()
  378. if err != nil {
  379. t.Errorf("Read error %q", err)
  380. }
  381. if header := r.HeaderReader(); header == nil {
  382. t.Errorf("no header")
  383. } else {
  384. actualHeader := make([]byte, r.Len())
  385. n, err := header.Read(actualHeader)
  386. if err != nil {
  387. t.Errorf("Read header error %q", err)
  388. } else {
  389. if n < len(testHeader) {
  390. t.Errorf("header too short %q got %q", testHeader, actualHeader[:n])
  391. }
  392. if !bytes.Equal(testHeader, actualHeader[:n]) {
  393. t.Errorf("header expected %q got %q", testHeader, actualHeader[:n])
  394. }
  395. }
  396. }
  397. if trailer := r.TrailerReader(); trailer != nil {
  398. t.Errorf("unexpected trailer %q", trailer)
  399. }
  400. frame := r.(*hybiFrameReader)
  401. if frameHeader.Fin != frame.header.Fin ||
  402. frameHeader.OpCode != frame.header.OpCode ||
  403. len(testPayload) != int(frame.header.Length) {
  404. t.Errorf("mismatch %v (%d) vs %v", frameHeader, len(testPayload), frame)
  405. }
  406. payload := make([]byte, len(testPayload))
  407. _, err = r.Read(payload)
  408. if err != nil {
  409. t.Errorf("read %v", err)
  410. }
  411. if !bytes.Equal(testPayload, payload) {
  412. t.Errorf("payload %q vs %q", testPayload, payload)
  413. }
  414. }
  415. func TestHybiShortTextFrame(t *testing.T) {
  416. frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame}
  417. payload := []byte("hello")
  418. testHybiFrame(t, []byte{0x81, 0x05}, payload, payload, frameHeader)
  419. payload = make([]byte, 125)
  420. testHybiFrame(t, []byte{0x81, 125}, payload, payload, frameHeader)
  421. }
  422. func TestHybiShortMaskedTextFrame(t *testing.T) {
  423. frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame,
  424. MaskingKey: []byte{0xcc, 0x55, 0x80, 0x20}}
  425. payload := []byte("hello")
  426. maskedPayload := []byte{0xa4, 0x30, 0xec, 0x4c, 0xa3}
  427. header := []byte{0x81, 0x85}
  428. header = append(header, frameHeader.MaskingKey...)
  429. testHybiFrame(t, header, payload, maskedPayload, frameHeader)
  430. }
  431. func TestHybiShortBinaryFrame(t *testing.T) {
  432. frameHeader := &hybiFrameHeader{Fin: true, OpCode: BinaryFrame}
  433. payload := []byte("hello")
  434. testHybiFrame(t, []byte{0x82, 0x05}, payload, payload, frameHeader)
  435. payload = make([]byte, 125)
  436. testHybiFrame(t, []byte{0x82, 125}, payload, payload, frameHeader)
  437. }
  438. func TestHybiControlFrame(t *testing.T) {
  439. frameHeader := &hybiFrameHeader{Fin: true, OpCode: PingFrame}
  440. payload := []byte("hello")
  441. testHybiFrame(t, []byte{0x89, 0x05}, payload, payload, frameHeader)
  442. frameHeader = &hybiFrameHeader{Fin: true, OpCode: PongFrame}
  443. testHybiFrame(t, []byte{0x8A, 0x05}, payload, payload, frameHeader)
  444. frameHeader = &hybiFrameHeader{Fin: true, OpCode: CloseFrame}
  445. payload = []byte{0x03, 0xe8} // 1000
  446. testHybiFrame(t, []byte{0x88, 0x02}, payload, payload, frameHeader)
  447. }
  448. func TestHybiLongFrame(t *testing.T) {
  449. frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame}
  450. payload := make([]byte, 126)
  451. testHybiFrame(t, []byte{0x81, 126, 0x00, 126}, payload, payload, frameHeader)
  452. payload = make([]byte, 65535)
  453. testHybiFrame(t, []byte{0x81, 126, 0xff, 0xff}, payload, payload, frameHeader)
  454. payload = make([]byte, 65536)
  455. testHybiFrame(t, []byte{0x81, 127, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}, payload, payload, frameHeader)
  456. }
  457. func TestHybiClientRead(t *testing.T) {
  458. wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o',
  459. 0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping
  460. 0x81, 0x05, 'w', 'o', 'r', 'l', 'd'}
  461. br := bufio.NewReader(bytes.NewBuffer(wireData))
  462. bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
  463. conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil)
  464. msg := make([]byte, 512)
  465. n, err := conn.Read(msg)
  466. if err != nil {
  467. t.Errorf("read 1st frame, error %q", err)
  468. }
  469. if n != 5 {
  470. t.Errorf("read 1st frame, expect 5, got %d", n)
  471. }
  472. if !bytes.Equal(wireData[2:7], msg[:n]) {
  473. t.Errorf("read 1st frame %v, got %v", wireData[2:7], msg[:n])
  474. }
  475. n, err = conn.Read(msg)
  476. if err != nil {
  477. t.Errorf("read 2nd frame, error %q", err)
  478. }
  479. if n != 5 {
  480. t.Errorf("read 2nd frame, expect 5, got %d", n)
  481. }
  482. if !bytes.Equal(wireData[16:21], msg[:n]) {
  483. t.Errorf("read 2nd frame %v, got %v", wireData[16:21], msg[:n])
  484. }
  485. n, err = conn.Read(msg)
  486. if err == nil {
  487. t.Errorf("read not EOF")
  488. }
  489. if n != 0 {
  490. t.Errorf("expect read 0, got %d", n)
  491. }
  492. }
  493. func TestHybiShortRead(t *testing.T) {
  494. wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o',
  495. 0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping
  496. 0x81, 0x05, 'w', 'o', 'r', 'l', 'd'}
  497. br := bufio.NewReader(bytes.NewBuffer(wireData))
  498. bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
  499. conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil)
  500. step := 0
  501. pos := 0
  502. expectedPos := []int{2, 5, 16, 19}
  503. expectedLen := []int{3, 2, 3, 2}
  504. for {
  505. msg := make([]byte, 3)
  506. n, err := conn.Read(msg)
  507. if step >= len(expectedPos) {
  508. if err == nil {
  509. t.Errorf("read not EOF")
  510. }
  511. if n != 0 {
  512. t.Errorf("expect read 0, got %d", n)
  513. }
  514. return
  515. }
  516. pos = expectedPos[step]
  517. endPos := pos + expectedLen[step]
  518. if err != nil {
  519. t.Errorf("read from %d, got error %q", pos, err)
  520. return
  521. }
  522. if n != endPos-pos {
  523. t.Errorf("read from %d, expect %d, got %d", pos, endPos-pos, n)
  524. }
  525. if !bytes.Equal(wireData[pos:endPos], msg[:n]) {
  526. t.Errorf("read from %d, frame %v, got %v", pos, wireData[pos:endPos], msg[:n])
  527. }
  528. step++
  529. }
  530. }
  531. func TestHybiServerRead(t *testing.T) {
  532. wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20,
  533. 0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello
  534. 0x89, 0x85, 0xcc, 0x55, 0x80, 0x20,
  535. 0xa4, 0x30, 0xec, 0x4c, 0xa3, // ping: hello
  536. 0x81, 0x85, 0xed, 0x83, 0xb4, 0x24,
  537. 0x9a, 0xec, 0xc6, 0x48, 0x89, // world
  538. }
  539. br := bufio.NewReader(bytes.NewBuffer(wireData))
  540. bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
  541. conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request))
  542. expected := [][]byte{[]byte("hello"), []byte("world")}
  543. msg := make([]byte, 512)
  544. n, err := conn.Read(msg)
  545. if err != nil {
  546. t.Errorf("read 1st frame, error %q", err)
  547. }
  548. if n != 5 {
  549. t.Errorf("read 1st frame, expect 5, got %d", n)
  550. }
  551. if !bytes.Equal(expected[0], msg[:n]) {
  552. t.Errorf("read 1st frame %q, got %q", expected[0], msg[:n])
  553. }
  554. n, err = conn.Read(msg)
  555. if err != nil {
  556. t.Errorf("read 2nd frame, error %q", err)
  557. }
  558. if n != 5 {
  559. t.Errorf("read 2nd frame, expect 5, got %d", n)
  560. }
  561. if !bytes.Equal(expected[1], msg[:n]) {
  562. t.Errorf("read 2nd frame %q, got %q", expected[1], msg[:n])
  563. }
  564. n, err = conn.Read(msg)
  565. if err == nil {
  566. t.Errorf("read not EOF")
  567. }
  568. if n != 0 {
  569. t.Errorf("expect read 0, got %d", n)
  570. }
  571. }
  572. func TestHybiServerReadWithoutMasking(t *testing.T) {
  573. wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o'}
  574. br := bufio.NewReader(bytes.NewBuffer(wireData))
  575. bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
  576. conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request))
  577. // server MUST close the connection upon receiving a non-masked frame.
  578. msg := make([]byte, 512)
  579. _, err := conn.Read(msg)
  580. if err != io.EOF {
  581. t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err)
  582. }
  583. }
  584. func TestHybiClientReadWithMasking(t *testing.T) {
  585. wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20,
  586. 0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello
  587. }
  588. br := bufio.NewReader(bytes.NewBuffer(wireData))
  589. bw := bufio.NewWriter(bytes.NewBuffer([]byte{}))
  590. conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil)
  591. // client MUST close the connection upon receiving a masked frame.
  592. msg := make([]byte, 512)
  593. _, err := conn.Read(msg)
  594. if err != io.EOF {
  595. t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err)
  596. }
  597. }
  598. // Test the hybiServerHandshaker supports firefox implementation and
  599. // checks Connection request header include (but it's not necessary
  600. // equal to) "upgrade"
  601. func TestHybiServerFirefoxHandshake(t *testing.T) {
  602. config := new(Config)
  603. handshaker := &hybiServerHandshaker{Config: config}
  604. br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
  605. Host: server.example.com
  606. Upgrade: websocket
  607. Connection: keep-alive, upgrade
  608. Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  609. Origin: http://example.com
  610. Sec-WebSocket-Protocol: chat, superchat
  611. Sec-WebSocket-Version: 13
  612. `))
  613. req, err := http.ReadRequest(br)
  614. if err != nil {
  615. t.Fatal("request", err)
  616. }
  617. code, err := handshaker.ReadHandshake(br, req)
  618. if err != nil {
  619. t.Errorf("handshake failed: %v", err)
  620. }
  621. if code != http.StatusSwitchingProtocols {
  622. t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
  623. }
  624. b := bytes.NewBuffer([]byte{})
  625. bw := bufio.NewWriter(b)
  626. config.Protocol = []string{"chat"}
  627. err = handshaker.AcceptHandshake(bw)
  628. if err != nil {
  629. t.Errorf("handshake response failed: %v", err)
  630. }
  631. expectedResponse := strings.Join([]string{
  632. "HTTP/1.1 101 Switching Protocols",
  633. "Upgrade: websocket",
  634. "Connection: Upgrade",
  635. "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
  636. "Sec-WebSocket-Protocol: chat",
  637. "", ""}, "\r\n")
  638. if b.String() != expectedResponse {
  639. t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
  640. }
  641. }