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