file_websocket_wsh.py (7261B)
1 import time 2 3 from mod_pywebsocket import msgutil 4 5 # see the list of tests in test_websocket.html 6 7 8 def web_socket_do_extra_handshake(request): 9 # must set request.ws_protocol to the selected version from ws_requested_protocols 10 for x in request.ws_requested_protocols: 11 if x != "test-does-not-exist": 12 request.ws_protocol = x 13 break 14 15 if request.ws_protocol == "test-2.1": 16 time.sleep(3) 17 elif request.ws_protocol == "test-9": 18 time.sleep(3) 19 elif request.ws_protocol == "test-10": 20 time.sleep(3) 21 elif request.ws_protocol == "test-19": 22 raise ValueError("Aborting (test-19)") 23 elif request.ws_protocol in {"test-20", "test-17"}: 24 time.sleep(3) 25 elif request.ws_protocol == "test-22": 26 # The timeout is 5 seconds 27 time.sleep(13) 28 elif request.ws_protocol == "test-41b": 29 request.sts = "max-age=100" 30 elif request.ws_protocol == "test-49": 31 # subprotocols are compared case-sensitively, so this should fail 32 request.ws_protocol = "teST-49" 33 else: 34 pass 35 36 37 # Behave according to recommendation of RFC 6455, section # 5.5.1: 38 # "When sending a Close frame in response, the endpoint typically echos the 39 # status code it received." 40 # - Without this, pywebsocket replies with 1000 to any close code. 41 # 42 # Note that this function is only called when the client initiates the close 43 44 45 def web_socket_passive_closing_handshake(request): 46 if request.ws_close_code == 1005: 47 return None, None 48 return request.ws_close_code, request.ws_close_reason 49 50 51 def web_socket_transfer_data(request): 52 if request.ws_protocol in {"test-1", "test-4"}: 53 msgutil.send_message(request, "server data") 54 msgutil.close_connection(request) 55 elif request.ws_protocol in {"test-2.1", "test-2.2"}: 56 msgutil.close_connection(request) 57 elif request.ws_protocol == "test-6": 58 resp = "wrong message" 59 if msgutil.receive_message(request) == "1": 60 resp = "2" 61 msgutil.send_message(request, resp) 62 resp = "wrong message" 63 if msgutil.receive_message(request) == "3": 64 resp = "4" 65 msgutil.send_message(request, resp) 66 resp = "wrong message" 67 if msgutil.receive_message(request) == "5": 68 resp = ( 69 b"\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a".decode( 70 "utf-8" 71 ) 72 ) 73 msgutil.send_message(request, resp) 74 msgutil.close_connection(request) 75 elif request.ws_protocol == "test-7": 76 msgutil.send_message(request, "test-7 data") 77 elif request.ws_protocol == "test-10": 78 msgutil.close_connection(request) 79 elif request.ws_protocol == "test-11": 80 resp = "wrong message" 81 if msgutil.receive_message(request) == "client data": 82 resp = "server data" 83 msgutil.send_message(request, resp) 84 elif request.ws_protocol == "test-12": 85 msg = msgutil.receive_message(request) 86 if msg == "a\ufffdb": 87 # converted unpaired surrogate in UTF-16 to UTF-8 OK 88 msgutil.send_message(request, "SUCCESS") 89 else: 90 msgutil.send_message( 91 request, 92 "FAIL got '" + msg + "' instead of string with replacement char'", 93 ) 94 elif request.ws_protocol == "test-13": 95 # first one binary message containing the byte 0x61 ('a') 96 request.connection.write(b"\xff\x01\x61") 97 # after a bad utf8 message 98 request.connection.write(b"\x01\x61\xff") 99 msgutil.close_connection(request) 100 elif request.ws_protocol == "test-14": 101 msgutil.close_connection(request) 102 msgutil.send_message(request, "server data") 103 elif request.ws_protocol == "test-15": 104 # DISABLED: close_connection hasn't supported 2nd 'abort' argument for a 105 # long time. Passing extra arg was causing exception, which conveniently 106 # caused abort :) but as of pywebsocket v606 raising an exception here no 107 # longer aborts, and there's no obvious way to close TCP connection w/o 108 # sending websocket CLOSE. 109 raise RuntimeError("test-15 should be disabled for now") 110 # msgutil.close_connection(request, True) # OBSOLETE 2nd arg 111 # return 112 elif request.ws_protocol in {"test-17", "test-21"}: 113 time.sleep(2) 114 resp = "wrong message" 115 if msgutil.receive_message(request) == "client data": 116 resp = "server data" 117 msgutil.send_message(request, resp) 118 time.sleep(2) 119 msgutil.close_connection(request) 120 elif request.ws_protocol == "test-20": 121 msgutil.send_message(request, "server data") 122 msgutil.close_connection(request) 123 elif request.ws_protocol == "test-34": 124 request.ws_stream.close_connection(1001, "going away now") 125 elif request.ws_protocol == "test-35a": 126 while not request.client_terminated: 127 msgutil.receive_message(request) 128 global test35code 129 test35code = request.ws_close_code 130 global test35reason 131 test35reason = request.ws_close_reason 132 elif request.ws_protocol == "test-35b": 133 request.ws_stream.close_connection(test35code + 1, test35reason) 134 elif request.ws_protocol == "test-37b": 135 while not request.client_terminated: 136 msgutil.receive_message(request) 137 global test37code 138 test37code = request.ws_close_code 139 global test37reason 140 test37reason = request.ws_close_reason 141 elif request.ws_protocol == "test-37c": 142 request.ws_stream.close_connection(test37code, test37reason) 143 elif request.ws_protocol == "test-42": 144 # Echo back 3 messages 145 msgutil.send_message(request, msgutil.receive_message(request)) 146 msgutil.send_message(request, msgutil.receive_message(request)) 147 msgutil.send_message(request, msgutil.receive_message(request)) 148 elif request.ws_protocol == "test-44": 149 rcv = msgutil.receive_message(request) 150 if isinstance(rcv, bytes): 151 rcv = rcv.decode() 152 # check we received correct binary msg 153 if ( 154 rcv 155 and len(rcv) == 3 156 and ord(rcv[0]) == 5 157 and ord(rcv[1]) == 0 158 and ord(rcv[2]) == 7 159 ): 160 # reply with binary msg 0x04 161 msgutil.send_message(request, b"\x00\x04", True, True) 162 else: 163 msgutil.send_message(request, "incorrect binary msg received!") 164 elif request.ws_protocol == "test-45": 165 rcv = msgutil.receive_message(request) 166 # check we received correct binary msg 167 rcv_str = rcv 168 if isinstance(rcv_str, bytes): 169 rcv_str = rcv_str.decode() 170 if rcv_str == "flob": 171 # send back same blob as binary msg 172 msgutil.send_message(request, rcv, True, True) 173 else: 174 msgutil.send_message( 175 request, "incorrect binary msg received: '" + rcv + "'" 176 ) 177 elif request.ws_protocol == "test-46": 178 msgutil.send_message(request, "client must drop this if close was called") 179 180 while not request.client_terminated: 181 msgutil.receive_message(request)