The reconcile package is used for DOM reconcilation in Isomorphic Go web applications.

hybi_test.go 18KB

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