xref: /unit/test/test_java_websockets.py (revision 1819:9344a39fb02e)
1import struct
2import time
3
4import pytest
5from unit.applications.lang.java import TestApplicationJava
6from unit.applications.websockets import TestApplicationWebsocket
7from unit.option import option
8
9
10class TestJavaWebsockets(TestApplicationJava):
11    prerequisites = {'modules': {'java': 'any'}}
12
13    ws = TestApplicationWebsocket()
14
15    @pytest.fixture(autouse=True)
16    def setup_method_fixture(self, request, skip_alert):
17        assert 'success' in self.conf(
18            {'http': {'websocket': {'keepalive_interval': 0}}}, 'settings'
19        ), 'clear keepalive_interval'
20
21        skip_alert(r'socket close\(\d+\) failed')
22
23    def close_connection(self, sock):
24        assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc'
25
26        self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close())
27
28        self.check_close(sock)
29
30    def check_close(self, sock, code=1000, no_close=False, frame=None):
31        if frame == None:
32            frame = self.ws.frame_read(sock)
33
34        assert frame['fin'] == True, 'close fin'
35        assert frame['opcode'] == self.ws.OP_CLOSE, 'close opcode'
36        assert frame['code'] == code, 'close code'
37
38        if not no_close:
39            sock.close()
40
41    def check_frame(self, frame, fin, opcode, payload, decode=True):
42        if opcode == self.ws.OP_BINARY or not decode:
43            data = frame['data']
44        else:
45            data = frame['data'].decode('utf-8')
46
47        assert frame['fin'] == fin, 'fin'
48        assert frame['opcode'] == opcode, 'opcode'
49        assert data == payload, 'payload'
50
51    def test_java_websockets_handshake(self):
52        self.load('websockets_mirror')
53
54        resp, sock, key = self.ws.upgrade()
55        sock.close()
56
57        assert resp['status'] == 101, 'status'
58        assert resp['headers']['Upgrade'] == 'websocket', 'upgrade'
59        assert resp['headers']['Connection'] == 'Upgrade', 'connection'
60        assert resp['headers']['Sec-WebSocket-Accept'] == self.ws.accept(
61            key
62        ), 'key'
63
64    def test_java_websockets_mirror(self):
65        self.load('websockets_mirror')
66
67        message = 'blah'
68
69        _, sock, _ = self.ws.upgrade()
70
71        self.ws.frame_write(sock, self.ws.OP_TEXT, message)
72        frame = self.ws.frame_read(sock)
73
74        assert message == frame['data'].decode('utf-8'), 'mirror'
75
76        self.ws.frame_write(sock, self.ws.OP_TEXT, message)
77        frame = self.ws.frame_read(sock)
78
79        assert message == frame['data'].decode('utf-8'), 'mirror 2'
80
81        sock.close()
82
83    def test_java_websockets_no_mask(self):
84        self.load('websockets_mirror')
85
86        message = 'blah'
87
88        _, sock, _ = self.ws.upgrade()
89
90        self.ws.frame_write(sock, self.ws.OP_TEXT, message, mask=False)
91
92        frame = self.ws.frame_read(sock)
93
94        assert frame['opcode'] == self.ws.OP_CLOSE, 'no mask opcode'
95        assert frame['code'] == 1002, 'no mask close code'
96
97        sock.close()
98
99    def test_java_websockets_fragmentation(self):
100        self.load('websockets_mirror')
101
102        message = 'blah'
103
104        _, sock, _ = self.ws.upgrade()
105
106        self.ws.frame_write(sock, self.ws.OP_TEXT, message, fin=False)
107        self.ws.frame_write(sock, self.ws.OP_CONT, ' ', fin=False)
108        self.ws.frame_write(sock, self.ws.OP_CONT, message)
109
110        frame = self.ws.frame_read(sock)
111
112        assert message + ' ' + message == frame['data'].decode(
113            'utf-8'
114        ), 'mirror framing'
115
116        sock.close()
117
118    def test_java_websockets_frame_fragmentation_invalid(self):
119        self.load('websockets_mirror')
120
121        message = 'blah'
122
123        _, sock, _ = self.ws.upgrade()
124
125        self.ws.frame_write(sock, self.ws.OP_PING, message, fin=False)
126
127        frame = self.ws.frame_read(sock)
128
129        frame.pop('data')
130        assert frame == {
131            'fin': True,
132            'rsv1': False,
133            'rsv2': False,
134            'rsv3': False,
135            'opcode': self.ws.OP_CLOSE,
136            'mask': 0,
137            'code': 1002,
138            'reason': 'Fragmented control frame',
139        }, 'close frame'
140
141        sock.close()
142
143    def test_java_websockets_two_clients(self):
144        self.load('websockets_mirror')
145
146        message1 = 'blah1'
147        message2 = 'blah2'
148
149        _, sock1, _ = self.ws.upgrade()
150        _, sock2, _ = self.ws.upgrade()
151
152        self.ws.frame_write(sock1, self.ws.OP_TEXT, message1)
153        self.ws.frame_write(sock2, self.ws.OP_TEXT, message2)
154
155        frame1 = self.ws.frame_read(sock1)
156        frame2 = self.ws.frame_read(sock2)
157
158        assert message1 == frame1['data'].decode('utf-8'), 'client 1'
159        assert message2 == frame2['data'].decode('utf-8'), 'client 2'
160
161        sock1.close()
162        sock2.close()
163
164    @pytest.mark.skip('not yet')
165    def test_java_websockets_handshake_upgrade_absent(
166        self
167    ):  # FAIL https://tools.ietf.org/html/rfc6455#section-4.2.1
168        self.load('websockets_mirror')
169
170        resp = self.get(
171            headers={
172                'Host': 'localhost',
173                'Connection': 'Upgrade',
174                'Sec-WebSocket-Key': self.ws.key(),
175                'Sec-WebSocket-Protocol': 'chat',
176                'Sec-WebSocket-Version': 13,
177            },
178        )
179
180        assert resp['status'] == 400, 'upgrade absent'
181
182    def test_java_websockets_handshake_case_insensitive(self):
183        self.load('websockets_mirror')
184
185        resp, sock, _ = self.ws.upgrade(
186            headers={
187                'Host': 'localhost',
188                'Upgrade': 'WEBSOCKET',
189                'Connection': 'UPGRADE',
190                'Sec-WebSocket-Key': self.ws.key(),
191                'Sec-WebSocket-Protocol': 'chat',
192                'Sec-WebSocket-Version': 13,
193            }
194        )
195        sock.close()
196
197        assert resp['status'] == 101, 'status'
198
199    @pytest.mark.skip('not yet')
200    def test_java_websockets_handshake_connection_absent(self):  # FAIL
201        self.load('websockets_mirror')
202
203        resp = self.get(
204            headers={
205                'Host': 'localhost',
206                'Upgrade': 'websocket',
207                'Sec-WebSocket-Key': self.ws.key(),
208                'Sec-WebSocket-Protocol': 'chat',
209                'Sec-WebSocket-Version': 13,
210            },
211        )
212
213        assert resp['status'] == 400, 'status'
214
215    def test_java_websockets_handshake_version_absent(self):
216        self.load('websockets_mirror')
217
218        resp = self.get(
219            headers={
220                'Host': 'localhost',
221                'Upgrade': 'websocket',
222                'Connection': 'Upgrade',
223                'Sec-WebSocket-Key': self.ws.key(),
224                'Sec-WebSocket-Protocol': 'chat',
225            },
226        )
227
228        assert resp['status'] == 426, 'status'
229
230    @pytest.mark.skip('not yet')
231    def test_java_websockets_handshake_key_invalid(self):
232        self.load('websockets_mirror')
233
234        resp = self.get(
235            headers={
236                'Host': 'localhost',
237                'Upgrade': 'websocket',
238                'Connection': 'Upgrade',
239                'Sec-WebSocket-Key': '!',
240                'Sec-WebSocket-Protocol': 'chat',
241                'Sec-WebSocket-Version': 13,
242            },
243        )
244
245        assert resp['status'] == 400, 'key length'
246
247        key = self.ws.key()
248        resp = self.get(
249            headers={
250                'Host': 'localhost',
251                'Upgrade': 'websocket',
252                'Connection': 'Upgrade',
253                'Sec-WebSocket-Key': [key, key],
254                'Sec-WebSocket-Protocol': 'chat',
255                'Sec-WebSocket-Version': 13,
256            },
257        )
258
259        assert resp['status'] == 400, 'key double'  # FAIL https://tools.ietf.org/html/rfc6455#section-11.3.1
260
261    def test_java_websockets_handshake_method_invalid(self):
262        self.load('websockets_mirror')
263
264        resp = self.post(
265            headers={
266                'Host': 'localhost',
267                'Upgrade': 'websocket',
268                'Connection': 'Upgrade',
269                'Sec-WebSocket-Key': self.ws.key(),
270                'Sec-WebSocket-Protocol': 'chat',
271                'Sec-WebSocket-Version': 13,
272            },
273        )
274
275        assert resp['status'] == 400, 'status'
276
277    def test_java_websockets_handshake_http_10(self):
278        self.load('websockets_mirror')
279
280        resp = self.get(
281            headers={
282                'Host': 'localhost',
283                'Upgrade': 'websocket',
284                'Connection': 'Upgrade',
285                'Sec-WebSocket-Key': self.ws.key(),
286                'Sec-WebSocket-Protocol': 'chat',
287                'Sec-WebSocket-Version': 13,
288            },
289            http_10=True,
290        )
291
292        assert resp['status'] == 400, 'status'
293
294    def test_java_websockets_handshake_uri_invalid(self):
295        self.load('websockets_mirror')
296
297        resp = self.get(
298            headers={
299                'Host': 'localhost',
300                'Upgrade': 'websocket',
301                'Connection': 'Upgrade',
302                'Sec-WebSocket-Key': self.ws.key(),
303                'Sec-WebSocket-Protocol': 'chat',
304                'Sec-WebSocket-Version': 13,
305            },
306            url='!',
307        )
308
309        assert resp['status'] == 400, 'status'
310
311    def test_java_websockets_protocol_absent(self):
312        self.load('websockets_mirror')
313
314        key = self.ws.key()
315        resp, sock, _ = self.ws.upgrade(
316            headers={
317                'Host': 'localhost',
318                'Upgrade': 'websocket',
319                'Connection': 'Upgrade',
320                'Sec-WebSocket-Key': key,
321                'Sec-WebSocket-Version': 13,
322            }
323        )
324        sock.close()
325
326        assert resp['status'] == 101, 'status'
327        assert resp['headers']['Upgrade'] == 'websocket', 'upgrade'
328        assert resp['headers']['Connection'] == 'Upgrade', 'connection'
329        assert resp['headers']['Sec-WebSocket-Accept'] == self.ws.accept(
330            key
331        ), 'key'
332
333    # autobahn-testsuite
334    #
335    # Some following tests fail because of Unit does not support UTF-8
336    # validation for websocket frames.  It should be implemented
337    # by application, if necessary.
338
339    def test_java_websockets_1_1_1__1_1_8(self):
340        self.load('websockets_mirror')
341
342        opcode = self.ws.OP_TEXT
343
344        _, sock, _ = self.ws.upgrade()
345
346        def check_length(length, chopsize=None):
347            payload = '*' * length
348
349            self.ws.frame_write(sock, opcode, payload, chopsize=chopsize)
350
351            frame = self.ws.message_read(sock)
352            self.check_frame(frame, True, opcode, payload)
353
354        check_length(0)                      # 1_1_1
355        check_length(125)                    # 1_1_2
356        check_length(126)                    # 1_1_3
357        check_length(127)                    # 1_1_4
358        check_length(128)                    # 1_1_5
359        check_length(65535)                  # 1_1_6
360        check_length(65536)                  # 1_1_7
361        check_length(65536, chopsize = 997)  # 1_1_8
362
363        self.close_connection(sock)
364
365    def test_java_websockets_1_2_1__1_2_8(self):
366        self.load('websockets_mirror')
367
368        opcode = self.ws.OP_BINARY
369
370        _, sock, _ = self.ws.upgrade()
371
372        def check_length(length, chopsize=None):
373            payload = b'\xfe' * length
374
375            self.ws.frame_write(sock, opcode, payload, chopsize=chopsize)
376
377            frame = self.ws.message_read(sock)
378            self.check_frame(frame, True, opcode, payload)
379
380        check_length(0)                      # 1_2_1
381        check_length(125)                    # 1_2_2
382        check_length(126)                    # 1_2_3
383        check_length(127)                    # 1_2_4
384        check_length(128)                    # 1_2_5
385        check_length(65535)                  # 1_2_6
386        check_length(65536)                  # 1_2_7
387        check_length(65536, chopsize = 997)  # 1_2_8
388
389        self.close_connection(sock)
390
391    def test_java_websockets_2_1__2_6(self):
392        self.load('websockets_mirror')
393
394        op_ping = self.ws.OP_PING
395        op_pong = self.ws.OP_PONG
396
397        _, sock, _ = self.ws.upgrade()
398
399        def check_ping(payload, chopsize=None, decode=True):
400            self.ws.frame_write(sock, op_ping, payload, chopsize=chopsize)
401            frame = self.ws.frame_read(sock)
402
403            self.check_frame(frame, True, op_pong, payload, decode=decode)
404
405        check_ping('')                                                 # 2_1
406        check_ping('Hello, world!')                                    # 2_2
407        check_ping(b'\x00\xff\xfe\xfd\xfc\xfb\x00\xff', decode=False)  # 2_3
408        check_ping(b'\xfe' * 125, decode=False)                        # 2_4
409        check_ping(b'\xfe' * 125, chopsize=1, decode=False)            # 2_6
410
411        self.close_connection(sock)
412
413        # 2_5
414
415        _, sock, _ = self.ws.upgrade()
416
417        self.ws.frame_write(sock, self.ws.OP_PING, b'\xfe' * 126)
418        self.check_close(sock, 1002)
419
420    def test_java_websockets_2_7__2_9(self):
421        self.load('websockets_mirror')
422
423        # 2_7
424
425        _, sock, _ = self.ws.upgrade()
426
427        self.ws.frame_write(sock, self.ws.OP_PONG, '')
428        assert self.recvall(sock, read_timeout=0.1) == b'', '2_7'
429
430        # 2_8
431
432        self.ws.frame_write(sock, self.ws.OP_PONG, 'unsolicited pong payload')
433        assert self.recvall(sock, read_timeout=0.1) == b'', '2_8'
434
435        # 2_9
436
437        payload = 'ping payload'
438
439        self.ws.frame_write(sock, self.ws.OP_PONG, 'unsolicited pong payload')
440        self.ws.frame_write(sock, self.ws.OP_PING, payload)
441
442        frame = self.ws.frame_read(sock)
443        self.check_frame(frame, True, self.ws.OP_PONG, payload)
444
445        self.close_connection(sock)
446
447    def test_java_websockets_2_10__2_11(self):
448        self.load('websockets_mirror')
449
450        # 2_10
451
452        _, sock, _ = self.ws.upgrade()
453
454        for i in range(0, 10):
455            self.ws.frame_write(sock, self.ws.OP_PING, 'payload-%d' % i)
456
457        for i in range(0, 10):
458            frame = self.ws.frame_read(sock)
459            self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i)
460
461        # 2_11
462
463        for i in range(0, 10):
464            opcode = self.ws.OP_PING
465            self.ws.frame_write(sock, opcode, 'payload-%d' % i, chopsize=1)
466
467        for i in range(0, 10):
468            frame = self.ws.frame_read(sock)
469            self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i)
470
471        self.close_connection(sock)
472
473    @pytest.mark.skip('not yet')
474    def test_java_websockets_3_1__3_7(self):
475        self.load('websockets_mirror')
476
477        payload = 'Hello, world!'
478
479        # 3_1
480
481        _, sock, _ = self.ws.upgrade()
482
483        self.ws.frame_write(sock, self.ws.OP_TEXT, payload, rsv1=True)
484        self.check_close(sock, 1002)
485
486        # 3_2
487
488        _, sock, _ = self.ws.upgrade()
489
490        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
491        self.ws.frame_write(sock, self.ws.OP_TEXT, payload, rsv2=True)
492        self.ws.frame_write(sock, self.ws.OP_PING, '')
493
494        frame = self.ws.frame_read(sock)
495        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
496
497        self.check_close(sock, 1002, no_close=True)
498
499        assert self.recvall(sock, read_timeout=0.1) == b'', 'empty 3_2'
500        sock.close()
501
502        # 3_3
503
504        _, sock, _ = self.ws.upgrade()
505
506        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
507
508        frame = self.ws.frame_read(sock)
509        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
510
511        self.ws.frame_write(
512            sock, self.ws.OP_TEXT, payload, rsv1=True, rsv2=True
513        )
514
515        self.check_close(sock, 1002, no_close=True)
516
517        assert self.recvall(sock, read_timeout=0.1) == b'', 'empty 3_3'
518        sock.close()
519
520        # 3_4
521
522        _, sock, _ = self.ws.upgrade()
523
524        self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1)
525        self.ws.frame_write(
526            sock, self.ws.OP_TEXT, payload, rsv3=True, chopsize=1
527        )
528        self.ws.frame_write(sock, self.ws.OP_PING, '')
529
530        frame = self.ws.frame_read(sock)
531        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
532
533        self.check_close(sock, 1002, no_close=True)
534
535        assert self.recvall(sock, read_timeout=0.1) == b'', 'empty 3_4'
536        sock.close()
537
538        # 3_5
539
540        _, sock, _ = self.ws.upgrade()
541
542        self.ws.frame_write(
543            sock,
544            self.ws.OP_BINARY,
545            b'\x00\xff\xfe\xfd\xfc\xfb\x00\xff',
546            rsv1=True,
547            rsv3=True,
548        )
549
550        self.check_close(sock, 1002)
551
552        # 3_6
553
554        _, sock, _ = self.ws.upgrade()
555
556        self.ws.frame_write(
557            sock, self.ws.OP_PING, payload, rsv2=True, rsv3=True
558        )
559
560        self.check_close(sock, 1002)
561
562        # 3_7
563
564        _, sock, _ = self.ws.upgrade()
565
566        self.ws.frame_write(
567            sock, self.ws.OP_CLOSE, payload, rsv1=True, rsv2=True, rsv3=True
568        )
569
570        self.check_close(sock, 1002)
571
572    def test_java_websockets_4_1_1__4_2_5(self):
573        self.load('websockets_mirror')
574
575        payload = 'Hello, world!'
576
577        # 4_1_1
578
579        _, sock, _ = self.ws.upgrade()
580
581        self.ws.frame_write(sock, 0x03, '')
582        self.check_close(sock, 1002)
583
584        # 4_1_2
585
586        _, sock, _ = self.ws.upgrade()
587
588        self.ws.frame_write(sock, 0x04, 'reserved opcode payload')
589        self.check_close(sock, 1002)
590
591        # 4_1_3
592
593        _, sock, _ = self.ws.upgrade()
594
595        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
596
597        frame = self.ws.frame_read(sock)
598        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
599
600        self.ws.frame_write(sock, 0x05, '')
601        self.ws.frame_write(sock, self.ws.OP_PING, '')
602
603        self.check_close(sock, 1002)
604
605        # 4_1_4
606
607        _, sock, _ = self.ws.upgrade()
608
609        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
610
611        frame = self.ws.frame_read(sock)
612        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
613
614        self.ws.frame_write(sock, 0x06, payload)
615        self.ws.frame_write(sock, self.ws.OP_PING, '')
616
617        self.check_close(sock, 1002)
618
619        # 4_1_5
620
621        _, sock, _ = self.ws.upgrade()
622
623        self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1)
624
625        frame = self.ws.frame_read(sock)
626        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
627
628        self.ws.frame_write(sock, 0x07, payload, chopsize=1)
629        self.ws.frame_write(sock, self.ws.OP_PING, '')
630
631        self.check_close(sock, 1002)
632
633        # 4_2_1
634
635        _, sock, _ = self.ws.upgrade()
636
637        self.ws.frame_write(sock, 0x0B, '')
638        self.check_close(sock, 1002)
639
640        # 4_2_2
641
642        _, sock, _ = self.ws.upgrade()
643
644        self.ws.frame_write(sock, 0x0C, 'reserved opcode payload')
645        self.check_close(sock, 1002)
646
647        # 4_2_3
648
649        _, sock, _ = self.ws.upgrade()
650
651        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
652
653        frame = self.ws.frame_read(sock)
654        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
655
656        self.ws.frame_write(sock, 0x0D, '')
657        self.ws.frame_write(sock, self.ws.OP_PING, '')
658
659        self.check_close(sock, 1002)
660
661        # 4_2_4
662
663        _, sock, _ = self.ws.upgrade()
664
665        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
666
667        frame = self.ws.frame_read(sock)
668        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
669
670        self.ws.frame_write(sock, 0x0E, payload)
671        self.ws.frame_write(sock, self.ws.OP_PING, '')
672
673        self.check_close(sock, 1002)
674
675        # 4_2_5
676
677        _, sock, _ = self.ws.upgrade()
678
679        self.ws.frame_write(sock, self.ws.OP_TEXT, payload, chopsize=1)
680
681        frame = self.ws.frame_read(sock)
682        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
683
684        self.ws.frame_write(sock, 0x0F, payload, chopsize=1)
685        self.ws.frame_write(sock, self.ws.OP_PING, '')
686
687        self.check_close(sock, 1002)
688
689    def test_java_websockets_5_1__5_20(self):
690        self.load('websockets_mirror')
691
692        # 5_1
693
694        _, sock, _ = self.ws.upgrade()
695
696        self.ws.frame_write(sock, self.ws.OP_PING, 'fragment1', fin=False)
697        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
698        self.check_close(sock, 1002)
699
700        # 5_2
701
702        _, sock, _ = self.ws.upgrade()
703
704        self.ws.frame_write(sock, self.ws.OP_PONG, 'fragment1', fin=False)
705        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
706        self.check_close(sock, 1002)
707
708        # 5_3
709
710        _, sock, _ = self.ws.upgrade()
711
712        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
713        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
714
715        frame = self.ws.frame_read(sock)
716        self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
717
718        # 5_4
719
720        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
721        assert self.recvall(sock, read_timeout=0.1) == b'', '5_4'
722        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
723
724        frame = self.ws.frame_read(sock)
725        self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
726
727        # 5_5
728
729        self.ws.frame_write(
730            sock, self.ws.OP_TEXT, 'fragment1', fin=False, chopsize=1
731        )
732        self.ws.frame_write(
733            sock, self.ws.OP_CONT, 'fragment2', fin=True, chopsize=1
734        )
735
736        frame = self.ws.frame_read(sock)
737        self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
738
739        # 5_6
740
741        ping_payload = 'ping payload'
742
743        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
744        self.ws.frame_write(sock, self.ws.OP_PING, ping_payload)
745        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
746
747        frame = self.ws.frame_read(sock)
748        self.check_frame(frame, True, self.ws.OP_PONG, ping_payload)
749
750        frame = self.ws.frame_read(sock)
751        self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
752
753        # 5_7
754
755        ping_payload = 'ping payload'
756
757        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
758        assert self.recvall(sock, read_timeout=0.1) == b'', '5_7'
759
760        self.ws.frame_write(sock, self.ws.OP_PING, ping_payload)
761
762        frame = self.ws.frame_read(sock)
763        self.check_frame(frame, True, self.ws.OP_PONG, ping_payload)
764
765        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
766
767        frame = self.ws.frame_read(sock)
768        self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
769
770        # 5_8
771
772        ping_payload = 'ping payload'
773
774        self.ws.frame_write(
775            sock, self.ws.OP_TEXT, 'fragment1', fin=False, chopsize=1
776        )
777        self.ws.frame_write(sock, self.ws.OP_PING, ping_payload, chopsize=1)
778        self.ws.frame_write(
779            sock, self.ws.OP_CONT, 'fragment2', fin=True, chopsize=1
780        )
781
782        frame = self.ws.frame_read(sock)
783        self.check_frame(frame, True, self.ws.OP_PONG, ping_payload)
784
785        frame = self.ws.frame_read(sock)
786        self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
787
788        # 5_9
789
790        self.ws.frame_write(
791            sock, self.ws.OP_CONT, 'non-continuation payload', fin=True
792        )
793        self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True)
794        self.check_close(sock, 1002)
795
796        # 5_10
797
798        _, sock, _ = self.ws.upgrade()
799
800        self.ws.frame_write(
801            sock, self.ws.OP_CONT, 'non-continuation payload', fin=True
802        )
803        self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True)
804        self.check_close(sock, 1002)
805
806        # 5_11
807
808        _, sock, _ = self.ws.upgrade()
809
810        self.ws.frame_write(
811            sock,
812            self.ws.OP_CONT,
813            'non-continuation payload',
814            fin=True,
815            chopsize=1,
816        )
817        self.ws.frame_write(
818            sock, self.ws.OP_TEXT, 'Hello, world!', fin=True, chopsize=1
819        )
820        self.check_close(sock, 1002)
821
822        # 5_12
823
824        _, sock, _ = self.ws.upgrade()
825
826        self.ws.frame_write(
827            sock, self.ws.OP_CONT, 'non-continuation payload', fin=False
828        )
829        self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True)
830        self.check_close(sock, 1002)
831
832        # 5_13
833
834        _, sock, _ = self.ws.upgrade()
835
836        self.ws.frame_write(
837            sock, self.ws.OP_CONT, 'non-continuation payload', fin=False
838        )
839        self.ws.frame_write(sock, self.ws.OP_TEXT, 'Hello, world!', fin=True)
840        self.check_close(sock, 1002)
841
842        # 5_14
843
844        _, sock, _ = self.ws.upgrade()
845
846        self.ws.frame_write(
847            sock,
848            self.ws.OP_CONT,
849            'non-continuation payload',
850            fin=False,
851            chopsize=1,
852        )
853        self.ws.frame_write(
854            sock, self.ws.OP_TEXT, 'Hello, world!', fin=True, chopsize=1
855        )
856        self.check_close(sock, 1002)
857
858        # 5_15
859
860        _, sock, _ = self.ws.upgrade()
861
862        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
863        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=True)
864        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False)
865        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment4', fin=True)
866
867        frame = self.ws.frame_read(sock)
868
869        if frame['opcode'] == self.ws.OP_TEXT:
870            self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
871            frame = None
872
873        self.check_close(sock, 1002, frame=frame)
874
875        # 5_16
876
877        _, sock, _ = self.ws.upgrade()
878
879        for i in range(0, 2):
880            self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment1', fin=False)
881            self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2', fin=False)
882            self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=True)
883        self.check_close(sock, 1002)
884
885        # 5_17
886
887        _, sock, _ = self.ws.upgrade()
888
889        for i in range(0, 2):
890            self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment1', fin=True)
891            self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2', fin=False)
892            self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=True)
893        self.check_close(sock, 1002)
894
895        # 5_18
896
897        _, sock, _ = self.ws.upgrade()
898
899        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
900        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment2')
901        self.check_close(sock, 1002)
902
903        # 5_19
904
905        _, sock, _ = self.ws.upgrade()
906
907        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
908        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=False)
909        self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 1!')
910
911        time.sleep(1)
912
913        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False)
914        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment4', fin=False)
915        self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 2!')
916        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment5')
917
918        frame = self.ws.frame_read(sock)
919        self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 1!')
920
921        frame = self.ws.frame_read(sock)
922        self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 2!')
923
924        self.check_frame(
925            self.ws.frame_read(sock),
926            True,
927            self.ws.OP_TEXT,
928            'fragment1fragment2fragment3fragment4fragment5',
929        )
930
931        # 5_20
932
933        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
934        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2', fin=False)
935        self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 1!')
936
937        frame = self.ws.frame_read(sock)
938        self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 1!')
939
940        time.sleep(1)
941
942        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment3', fin=False)
943        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment4', fin=False)
944        self.ws.frame_write(sock, self.ws.OP_PING, 'pongme 2!')
945
946        frame = self.ws.frame_read(sock)
947        self.check_frame(frame, True, self.ws.OP_PONG, 'pongme 2!')
948
949        assert self.recvall(sock, read_timeout=0.1) == b'', '5_20'
950        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment5')
951
952        self.check_frame(
953            self.ws.frame_read(sock),
954            True,
955            self.ws.OP_TEXT,
956            'fragment1fragment2fragment3fragment4fragment5',
957        )
958
959        self.close_connection(sock)
960
961    def test_java_websockets_6_1_1__6_4_4(self):
962        self.load('websockets_mirror')
963
964        # 6_1_1
965
966        _, sock, _ = self.ws.upgrade()
967
968        self.ws.frame_write(sock, self.ws.OP_TEXT, '')
969        frame = self.ws.frame_read(sock, read_timeout=3)
970        self.check_frame(frame, True, self.ws.OP_TEXT, '')
971
972        # 6_1_2
973
974        self.ws.frame_write(sock, self.ws.OP_TEXT, '', fin=False)
975        self.ws.frame_write(sock, self.ws.OP_CONT, '', fin=False)
976        self.ws.frame_write(sock, self.ws.OP_CONT, '')
977
978        frame = self.ws.frame_read(sock, read_timeout=3)
979        self.check_frame(frame, True, self.ws.OP_TEXT, '')
980
981        # 6_1_3
982
983        payload = 'middle frame payload'
984
985        self.ws.frame_write(sock, self.ws.OP_TEXT, '', fin=False)
986        self.ws.frame_write(sock, self.ws.OP_CONT, payload, fin=False)
987        self.ws.frame_write(sock, self.ws.OP_CONT, '')
988
989        frame = self.ws.frame_read(sock)
990        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
991
992        # 6_2_1
993
994        payload = 'Hello-µ@ßöäüàá-UTF-8!!'
995
996        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
997
998        frame = self.ws.frame_read(sock)
999        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
1000
1001        # 6_2_2
1002
1003        self.ws.frame_write(sock, self.ws.OP_TEXT, payload[:12], fin=False)
1004        self.ws.frame_write(sock, self.ws.OP_CONT, payload[12:])
1005
1006        frame = self.ws.frame_read(sock)
1007        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
1008
1009        # 6_2_3
1010
1011        self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1)
1012
1013        frame = self.ws.frame_read(sock)
1014        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
1015
1016        # 6_2_4
1017
1018        payload = '\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5'
1019
1020        self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1)
1021
1022        frame = self.ws.frame_read(sock)
1023        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
1024
1025        self.close_connection(sock)
1026
1027#        Unit does not support UTF-8 validation
1028#
1029#        # 6_3_1 FAIL
1030#
1031#        payload_1 = '\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5'
1032#        payload_2 = '\xed\xa0\x80'
1033#        payload_3 = '\x65\x64\x69\x74\x65\x64'
1034#
1035#        payload = payload_1 + payload_2 + payload_3
1036#
1037#        self.ws.message(sock, self.ws.OP_TEXT, payload)
1038#        self.check_close(sock, 1007)
1039#
1040#        # 6_3_2 FAIL
1041#
1042#        _, sock, _ = self.ws.upgrade()
1043#
1044#        self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1)
1045#        self.check_close(sock, 1007)
1046#
1047#        # 6_4_1 ... 6_4_4 FAIL
1048
1049    def test_java_websockets_7_1_1__7_5_1(self):
1050        self.load('websockets_mirror')
1051
1052        # 7_1_1
1053
1054        _, sock, _ = self.ws.upgrade()
1055
1056        payload = "Hello World!"
1057
1058        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
1059
1060        frame = self.ws.frame_read(sock)
1061        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
1062
1063        self.close_connection(sock)
1064
1065        # 7_1_2
1066
1067        _, sock, _ = self.ws.upgrade()
1068
1069        self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close())
1070        self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close())
1071
1072        self.check_close(sock)
1073
1074        # 7_1_3
1075
1076        _, sock, _ = self.ws.upgrade()
1077
1078        self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close())
1079        self.check_close(sock, no_close=True)
1080
1081        self.ws.frame_write(sock, self.ws.OP_PING, '')
1082        assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc'
1083
1084        sock.close()
1085
1086        # 7_1_4
1087
1088        _, sock, _ = self.ws.upgrade()
1089
1090        self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close())
1091        self.check_close(sock, no_close=True)
1092
1093        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
1094        assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc'
1095
1096        sock.close()
1097
1098        # 7_1_5
1099
1100        _, sock, _ = self.ws.upgrade()
1101
1102        self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
1103        self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close())
1104        self.check_close(sock, no_close=True)
1105
1106        self.ws.frame_write(sock, self.ws.OP_CONT, 'fragment2')
1107        assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc'
1108
1109        sock.close()
1110
1111        # 7_1_6
1112
1113        _, sock, _ = self.ws.upgrade()
1114
1115        self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2 ** 10)
1116        self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
1117        self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close())
1118
1119        self.recvall(sock, read_timeout=1)
1120
1121        self.ws.frame_write(sock, self.ws.OP_PING, '')
1122        assert self.recvall(sock, read_timeout=0.1) == b'', 'empty soc'
1123
1124        sock.close()
1125
1126        # 7_3_1
1127
1128        _, sock, _ = self.ws.upgrade()
1129
1130        self.ws.frame_write(sock, self.ws.OP_CLOSE, '')
1131        self.check_close(sock)
1132
1133        # 7_3_2
1134
1135        _, sock, _ = self.ws.upgrade()
1136
1137        self.ws.frame_write(sock, self.ws.OP_CLOSE, 'a')
1138        self.check_close(sock, 1002)
1139
1140        # 7_3_3
1141
1142        _, sock, _ = self.ws.upgrade()
1143
1144        self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close())
1145        self.check_close(sock)
1146
1147        # 7_3_4
1148
1149        _, sock, _ = self.ws.upgrade()
1150
1151        payload = self.ws.serialize_close(reason='Hello World!')
1152
1153        self.ws.frame_write(sock, self.ws.OP_CLOSE, payload)
1154        self.check_close(sock)
1155
1156        # 7_3_5
1157
1158        _, sock, _ = self.ws.upgrade()
1159
1160        payload = self.ws.serialize_close(reason='*' * 123)
1161
1162        self.ws.frame_write(sock, self.ws.OP_CLOSE, payload)
1163        self.check_close(sock)
1164
1165        # 7_3_6
1166
1167        _, sock, _ = self.ws.upgrade()
1168
1169        payload = self.ws.serialize_close(reason='*' * 124)
1170
1171        self.ws.frame_write(sock, self.ws.OP_CLOSE, payload)
1172        self.check_close(sock, 1002)
1173
1174#        # 7_5_1 FAIL Unit does not support UTF-8 validation
1175#
1176#        _, sock, _ = self.ws.upgrade()
1177#
1178#        payload = self.ws.serialize_close(reason = '\xce\xba\xe1\xbd\xb9\xcf' \
1179#            '\x83\xce\xbc\xce\xb5\xed\xa0\x80\x65\x64\x69\x74\x65\x64')
1180#
1181#        self.ws.frame_write(sock, self.ws.OP_CLOSE, payload)
1182#        self.check_close(sock, 1007)
1183
1184    def test_java_websockets_7_7_X__7_9_X(self):
1185        self.load('websockets_mirror')
1186
1187        valid_codes = [
1188            1000,
1189            1001,
1190            1002,
1191            1003,
1192            1007,
1193            1008,
1194            1009,
1195            1010,
1196            1011,
1197            3000,
1198            3999,
1199            4000,
1200            4999,
1201        ]
1202
1203        invalid_codes = [0, 999, 1004, 1005, 1006, 1016, 1100, 2000, 2999]
1204
1205        for code in valid_codes:
1206            _, sock, _ = self.ws.upgrade()
1207
1208            payload = self.ws.serialize_close(code=code)
1209
1210            self.ws.frame_write(sock, self.ws.OP_CLOSE, payload)
1211            self.check_close(sock, code=code)
1212
1213        for code in invalid_codes:
1214            _, sock, _ = self.ws.upgrade()
1215
1216            payload = self.ws.serialize_close(code=code)
1217
1218            self.ws.frame_write(sock, self.ws.OP_CLOSE, payload)
1219            self.check_close(sock, 1002)
1220
1221    def test_java_websockets_7_13_1__7_13_2(self):
1222        self.load('websockets_mirror')
1223
1224        # 7_13_1
1225
1226        _, sock, _ = self.ws.upgrade()
1227
1228        payload = self.ws.serialize_close(code=5000)
1229
1230        self.ws.frame_write(sock, self.ws.OP_CLOSE, payload)
1231        self.check_close(sock, 1002)
1232
1233        # 7_13_2
1234
1235        _, sock, _ = self.ws.upgrade()
1236
1237        payload = struct.pack('!I', 65536) + ''.encode('utf-8')
1238
1239        self.ws.frame_write(sock, self.ws.OP_CLOSE, payload)
1240        self.check_close(sock, 1002)
1241
1242    def test_java_websockets_9_1_1__9_6_6(self, is_unsafe):
1243        if not is_unsafe:
1244            pytest.skip('unsafe, long run')
1245
1246        self.load('websockets_mirror')
1247
1248        assert 'success' in self.conf(
1249            {
1250                'http': {
1251                    'websocket': {
1252                        'max_frame_size': 33554432,
1253                        'keepalive_interval': 0,
1254                    }
1255                }
1256            },
1257            'settings',
1258        ), 'increase max_frame_size and keepalive_interval'
1259
1260        _, sock, _ = self.ws.upgrade()
1261
1262        op_text = self.ws.OP_TEXT
1263        op_binary = self.ws.OP_BINARY
1264
1265        def check_payload(opcode, length, chopsize=None):
1266            if opcode == self.ws.OP_TEXT:
1267                payload = '*' * length
1268            else:
1269                payload = b'*' * length
1270
1271            self.ws.frame_write(sock, opcode, payload, chopsize=chopsize)
1272            frame = self.ws.frame_read(sock)
1273            self.check_frame(frame, True, opcode, payload)
1274
1275        def check_message(opcode, f_size):
1276            if opcode == self.ws.OP_TEXT:
1277                payload = '*' * 4 * 2 ** 20
1278            else:
1279                payload = b'*' * 4 * 2 ** 20
1280
1281            self.ws.message(sock, opcode, payload, fragmention_size=f_size)
1282            frame = self.ws.frame_read(sock, read_timeout=5)
1283            self.check_frame(frame, True, opcode, payload)
1284
1285        check_payload(op_text, 64 * 2 ** 10)              # 9_1_1
1286        check_payload(op_text, 256 * 2 ** 10)             # 9_1_2
1287        check_payload(op_text, 2 ** 20)                   # 9_1_3
1288        check_payload(op_text, 4 * 2 ** 20)               # 9_1_4
1289        check_payload(op_text, 8 * 2 ** 20)               # 9_1_5
1290        check_payload(op_text, 16 * 2 ** 20)              # 9_1_6
1291
1292        check_payload(op_binary, 64 * 2 ** 10)            # 9_2_1
1293        check_payload(op_binary, 256 * 2 ** 10)           # 9_2_2
1294        check_payload(op_binary, 2 ** 20)                 # 9_2_3
1295        check_payload(op_binary, 4 * 2 ** 20)             # 9_2_4
1296        check_payload(op_binary, 8 * 2 ** 20)             # 9_2_5
1297        check_payload(op_binary, 16 * 2 ** 20)            # 9_2_6
1298
1299        if option.system != 'Darwin' and option.system != 'FreeBSD':
1300            check_message(op_text, 64)                    # 9_3_1
1301            check_message(op_text, 256)                   # 9_3_2
1302            check_message(op_text, 2 ** 10)               # 9_3_3
1303            check_message(op_text, 4 * 2 ** 10)           # 9_3_4
1304            check_message(op_text, 16 * 2 ** 10)          # 9_3_5
1305            check_message(op_text, 64 * 2 ** 10)          # 9_3_6
1306            check_message(op_text, 256 * 2 ** 10)         # 9_3_7
1307            check_message(op_text, 2 ** 20)               # 9_3_8
1308            check_message(op_text, 4 * 2 ** 20)           # 9_3_9
1309
1310            check_message(op_binary, 64)                  # 9_4_1
1311            check_message(op_binary, 256)                 # 9_4_2
1312            check_message(op_binary, 2 ** 10)             # 9_4_3
1313            check_message(op_binary, 4 * 2 ** 10)         # 9_4_4
1314            check_message(op_binary, 16 * 2 ** 10)        # 9_4_5
1315            check_message(op_binary, 64 * 2 ** 10)        # 9_4_6
1316            check_message(op_binary, 256 * 2 ** 10)       # 9_4_7
1317            check_message(op_binary, 2 ** 20)             # 9_4_8
1318            check_message(op_binary, 4 * 2 ** 20)         # 9_4_9
1319
1320        check_payload(op_text, 2 ** 20, chopsize=64)      # 9_5_1
1321        check_payload(op_text, 2 ** 20, chopsize=128)     # 9_5_2
1322        check_payload(op_text, 2 ** 20, chopsize=256)     # 9_5_3
1323        check_payload(op_text, 2 ** 20, chopsize=512)     # 9_5_4
1324        check_payload(op_text, 2 ** 20, chopsize=1024)    # 9_5_5
1325        check_payload(op_text, 2 ** 20, chopsize=2048)    # 9_5_6
1326
1327        check_payload(op_binary, 2 ** 20, chopsize=64)    # 9_6_1
1328        check_payload(op_binary, 2 ** 20, chopsize=128)   # 9_6_2
1329        check_payload(op_binary, 2 ** 20, chopsize=256)   # 9_6_3
1330        check_payload(op_binary, 2 ** 20, chopsize=512)   # 9_6_4
1331        check_payload(op_binary, 2 ** 20, chopsize=1024)  # 9_6_5
1332        check_payload(op_binary, 2 ** 20, chopsize=2048)  # 9_6_6
1333
1334        self.close_connection(sock)
1335
1336    def test_java_websockets_10_1_1(self):
1337        self.load('websockets_mirror')
1338
1339        _, sock, _ = self.ws.upgrade()
1340
1341        payload = '*' * 65536
1342
1343        self.ws.message(sock, self.ws.OP_TEXT, payload, fragmention_size=1300)
1344
1345        frame = self.ws.message_read(sock)
1346        self.check_frame(frame, True, self.ws.OP_TEXT, payload)
1347
1348        self.close_connection(sock)
1349
1350    # settings
1351
1352    def test_java_websockets_max_frame_size(self):
1353        self.load('websockets_mirror')
1354
1355        assert 'success' in self.conf(
1356            {'http': {'websocket': {'max_frame_size': 100}}}, 'settings'
1357        ), 'configure max_frame_size'
1358
1359        _, sock, _ = self.ws.upgrade()
1360
1361        payload = '*' * 94
1362        opcode = self.ws.OP_TEXT
1363
1364        self.ws.frame_write(sock, opcode, payload)  # frame length is 100
1365
1366        frame = self.ws.frame_read(sock)
1367        self.check_frame(frame, True, opcode, payload)
1368
1369        payload = '*' * 95
1370
1371        self.ws.frame_write(sock, opcode, payload)  # frame length is 101
1372        self.check_close(sock, 1009)  # 1009 - CLOSE_TOO_LARGE
1373
1374    def test_java_websockets_read_timeout(self):
1375        self.load('websockets_mirror')
1376
1377        assert 'success' in self.conf(
1378            {'http': {'websocket': {'read_timeout': 5}}}, 'settings'
1379        ), 'configure read_timeout'
1380
1381        _, sock, _ = self.ws.upgrade()
1382
1383        frame = self.ws.frame_to_send(self.ws.OP_TEXT, 'blah')
1384        sock.sendall(frame[:2])
1385
1386        time.sleep(2)
1387
1388        self.check_close(sock, 1001)  # 1001 - CLOSE_GOING_AWAY
1389
1390    def test_java_websockets_keepalive_interval(self):
1391        self.load('websockets_mirror')
1392
1393        assert 'success' in self.conf(
1394            {'http': {'websocket': {'keepalive_interval': 5}}}, 'settings'
1395        ), 'configure keepalive_interval'
1396
1397        _, sock, _ = self.ws.upgrade()
1398
1399        frame = self.ws.frame_to_send(self.ws.OP_TEXT, 'blah')
1400        sock.sendall(frame[:2])
1401
1402        time.sleep(2)
1403
1404        frame = self.ws.frame_read(sock)
1405        self.check_frame(frame, True, self.ws.OP_PING, '')  # PING frame
1406
1407        sock.close()
1408