summaryrefslogtreecommitdiffstats
path: root/dom/websocket/tests/file_websocket_wsh.py
blob: 77dbc3294cd1731a5405c81b14407c2b0e588593 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import time

import six
from mod_pywebsocket import msgutil

# see the list of tests in test_websocket.html


def web_socket_do_extra_handshake(request):
    # must set request.ws_protocol to the selected version from ws_requested_protocols
    for x in request.ws_requested_protocols:
        if x != "test-does-not-exist":
            request.ws_protocol = x
            break

    if request.ws_protocol == "test-2.1":
        time.sleep(3)
    elif request.ws_protocol == "test-9":
        time.sleep(3)
    elif request.ws_protocol == "test-10":
        time.sleep(3)
    elif request.ws_protocol == "test-19":
        raise ValueError("Aborting (test-19)")
    elif request.ws_protocol == "test-20" or request.ws_protocol == "test-17":
        time.sleep(3)
    elif request.ws_protocol == "test-22":
        # The timeout is 5 seconds
        time.sleep(13)
    elif request.ws_protocol == "test-41b":
        request.sts = "max-age=100"
    elif request.ws_protocol == "test-49":
        # subprotocols are compared case-sensitively, so this should fail
        request.ws_protocol = "teST-49"
    else:
        pass


# Behave according to recommendation of RFC 6455, section # 5.5.1:
#  "When sending a Close frame in response, the endpoint typically echos the
#   status code it received."
# - Without this, pywebsocket replies with 1000 to any close code.
#
#  Note that this function is only called when the client initiates the close


def web_socket_passive_closing_handshake(request):
    if request.ws_close_code == 1005:
        return None, None
    return request.ws_close_code, request.ws_close_reason


def web_socket_transfer_data(request):
    if request.ws_protocol == "test-1" or request.ws_protocol == "test-4":
        msgutil.send_message(request, "server data")
        msgutil.close_connection(request)
    elif request.ws_protocol == "test-2.1" or request.ws_protocol == "test-2.2":
        msgutil.close_connection(request)
    elif request.ws_protocol == "test-6":
        resp = "wrong message"
        if msgutil.receive_message(request) == "1":
            resp = "2"
        msgutil.send_message(request, six.ensure_text(resp))
        resp = "wrong message"
        if msgutil.receive_message(request) == "3":
            resp = "4"
        msgutil.send_message(request, six.ensure_text(resp))
        resp = "wrong message"
        if msgutil.receive_message(request) == "5":
            resp = (
                b"\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a".decode(
                    "utf-8"
                )
            )
        msgutil.send_message(request, six.ensure_text(resp))
        msgutil.close_connection(request)
    elif request.ws_protocol == "test-7":
        msgutil.send_message(request, "test-7 data")
    elif request.ws_protocol == "test-10":
        msgutil.close_connection(request)
    elif request.ws_protocol == "test-11":
        resp = "wrong message"
        if msgutil.receive_message(request) == "client data":
            resp = "server data"
        msgutil.send_message(request, six.ensure_text(resp))
    elif request.ws_protocol == "test-12":
        msg = msgutil.receive_message(request)
        if msg == "a\ufffdb":
            # converted unpaired surrogate in UTF-16 to UTF-8 OK
            msgutil.send_message(request, "SUCCESS")
        else:
            msgutil.send_message(
                request,
                "FAIL got '" + msg + "' instead of string with replacement char'",
            )
    elif request.ws_protocol == "test-13":
        # first one binary message containing the byte 0x61 ('a')
        request.connection.write(b"\xff\x01\x61")
        # after a bad utf8 message
        request.connection.write(b"\x01\x61\xff")
        msgutil.close_connection(request)
    elif request.ws_protocol == "test-14":
        msgutil.close_connection(request)
        msgutil.send_message(request, "server data")
    elif request.ws_protocol == "test-15":
        # DISABLED: close_connection hasn't supported 2nd 'abort' argument for a
        # long time.  Passing extra arg was causing exception, which conveniently
        # caused abort :) but as of pywebsocket v606 raising an exception here no
        # longer aborts, and there's no obvious way to close TCP connection w/o
        # sending websocket CLOSE.
        raise RuntimeError("test-15 should be disabled for now")
        # msgutil.close_connection(request, True)   # OBSOLETE 2nd arg
        # return
    elif request.ws_protocol == "test-17" or request.ws_protocol == "test-21":
        time.sleep(2)
        resp = "wrong message"
        if msgutil.receive_message(request) == "client data":
            resp = "server data"
        msgutil.send_message(request, six.ensure_text(resp))
        time.sleep(2)
        msgutil.close_connection(request)
    elif request.ws_protocol == "test-20":
        msgutil.send_message(request, "server data")
        msgutil.close_connection(request)
    elif request.ws_protocol == "test-34":
        request.ws_stream.close_connection(1001, "going away now")
    elif request.ws_protocol == "test-35a":
        while not request.client_terminated:
            msgutil.receive_message(request)
        global test35code
        test35code = request.ws_close_code
        global test35reason
        test35reason = request.ws_close_reason
    elif request.ws_protocol == "test-35b":
        request.ws_stream.close_connection(test35code + 1, test35reason)
    elif request.ws_protocol == "test-37b":
        while not request.client_terminated:
            msgutil.receive_message(request)
        global test37code
        test37code = request.ws_close_code
        global test37reason
        test37reason = request.ws_close_reason
    elif request.ws_protocol == "test-37c":
        request.ws_stream.close_connection(test37code, test37reason)
    elif request.ws_protocol == "test-42":
        # Echo back 3 messages
        msgutil.send_message(request, msgutil.receive_message(request))
        msgutil.send_message(request, msgutil.receive_message(request))
        msgutil.send_message(request, msgutil.receive_message(request))
    elif request.ws_protocol == "test-44":
        rcv = six.ensure_text(msgutil.receive_message(request))
        # check we received correct binary msg
        if len(rcv) == 3 and ord(rcv[0]) == 5 and ord(rcv[1]) == 0 and ord(rcv[2]) == 7:
            # reply with binary msg 0x04
            msgutil.send_message(request, b"\x00\x04", True, True)
        else:
            msgutil.send_message(request, "incorrect binary msg received!")
    elif request.ws_protocol == "test-45":
        rcv = msgutil.receive_message(request)
        # check we received correct binary msg
        if six.ensure_text(rcv) == "flob":
            # send back same blob as binary msg
            msgutil.send_message(request, rcv, True, True)
        else:
            msgutil.send_message(
                request, "incorrect binary msg received: '" + rcv + "'"
            )
    elif request.ws_protocol == "test-46":
        msgutil.send_message(request, "client must drop this if close was called")

    while not request.client_terminated:
        msgutil.receive_message(request)