michael@0: from mod_pywebsocket import msgutil michael@0: michael@0: import time michael@0: import sys michael@0: import struct michael@0: michael@0: # see the list of tests in test_websocket.html michael@0: michael@0: def web_socket_do_extra_handshake(request): michael@0: # must set request.ws_protocol to the selected version from ws_requested_protocols michael@0: for x in request.ws_requested_protocols: michael@0: if x != "test-does-not-exist": michael@0: request.ws_protocol = x michael@0: break michael@0: michael@0: if request.ws_protocol == "test-2.1": michael@0: time.sleep(3) michael@0: elif request.ws_protocol == "test-9": michael@0: time.sleep(3) michael@0: elif request.ws_protocol == "test-10": michael@0: time.sleep(3) michael@0: elif request.ws_protocol == "test-19": michael@0: raise ValueError('Aborting (test-19)') michael@0: elif request.ws_protocol == "test-20" or request.ws_protocol == "test-17": michael@0: time.sleep(3) michael@0: elif request.ws_protocol == "test-22": michael@0: # The timeout is 5 seconds michael@0: time.sleep(13) michael@0: elif request.ws_protocol == "test-41b": michael@0: request.sts = "max-age=100" michael@0: else: michael@0: pass michael@0: michael@0: # Behave according to recommendation of RFC 6455, section # 5.5.1: michael@0: # "When sending a Close frame in response, the endpoint typically echos the michael@0: # status code it received." michael@0: # - Without this, pywebsocket replies with 1000 to any close code. michael@0: # michael@0: # Note that this function is only called when the client initiates the close michael@0: def web_socket_passive_closing_handshake(request): michael@0: if request.ws_close_code == 1005: michael@0: return None, None michael@0: else: michael@0: return request.ws_close_code, request.ws_close_reason michael@0: michael@0: michael@0: def web_socket_transfer_data(request): michael@0: if request.ws_protocol == "test-2.1" or request.ws_protocol == "test-2.2": michael@0: msgutil.close_connection(request) michael@0: elif request.ws_protocol == "test-6": michael@0: resp = "wrong message" michael@0: if msgutil.receive_message(request) == "1": michael@0: resp = "2" michael@0: msgutil.send_message(request, resp.decode('utf-8')) michael@0: resp = "wrong message" michael@0: if msgutil.receive_message(request) == "3": michael@0: resp = "4" michael@0: msgutil.send_message(request, resp.decode('utf-8')) michael@0: resp = "wrong message" michael@0: if msgutil.receive_message(request) == "5": michael@0: resp = "あいうえお" michael@0: msgutil.send_message(request, resp.decode('utf-8')) michael@0: msgutil.close_connection(request) michael@0: elif request.ws_protocol == "test-7": michael@0: msgutil.send_message(request, "test-7 data") michael@0: elif request.ws_protocol == "test-10": michael@0: msgutil.close_connection(request) michael@0: elif request.ws_protocol == "test-11": michael@0: resp = "wrong message" michael@0: if msgutil.receive_message(request) == "client data": michael@0: resp = "server data" michael@0: msgutil.send_message(request, resp.decode('utf-8')) michael@0: elif request.ws_protocol == "test-12": michael@0: msg = msgutil.receive_message(request) michael@0: if msg == u'a\ufffdb': michael@0: # converted unpaired surrogate in UTF-16 to UTF-8 OK michael@0: msgutil.send_message(request, "SUCCESS") michael@0: else: michael@0: msgutil.send_message(request, "FAIL got '" + msg michael@0: + "' instead of string with replacement char'") michael@0: elif request.ws_protocol == "test-13": michael@0: # first one binary message containing the byte 0x61 ('a') michael@0: request.connection.write('\xff\x01\x61') michael@0: # after a bad utf8 message michael@0: request.connection.write('\x01\x61\xff') michael@0: msgutil.close_connection(request) michael@0: elif request.ws_protocol == "test-14": michael@0: msgutil.close_connection(request) michael@0: msgutil.send_message(request, "server data") michael@0: elif request.ws_protocol == "test-15": michael@0: # DISABLED: close_connection hasn't supported 2nd 'abort' argument for a michael@0: # long time. Passing extra arg was causing exception, which conveniently michael@0: # caused abort :) but as of pywebsocket v606 raising an exception here no michael@0: # longer aborts, and there's no obvious way to close TCP connection w/o michael@0: # sending websocket CLOSE. michael@0: raise RuntimeError("test-15 should be disabled for now") michael@0: #msgutil.close_connection(request, True) # OBSOLETE 2nd arg michael@0: return michael@0: elif request.ws_protocol == "test-17" or request.ws_protocol == "test-21": michael@0: time.sleep(2) michael@0: resp = "wrong message" michael@0: if msgutil.receive_message(request) == "client data": michael@0: resp = "server data" michael@0: msgutil.send_message(request, resp.decode('utf-8')) michael@0: time.sleep(2) michael@0: msgutil.close_connection(request) michael@0: elif request.ws_protocol == "test-20": michael@0: msgutil.send_message(request, "server data") michael@0: msgutil.close_connection(request) michael@0: elif request.ws_protocol == "test-34": michael@0: request.ws_stream.close_connection(1001, "going away now") michael@0: elif request.ws_protocol == "test-35a": michael@0: while not request.client_terminated: michael@0: msgutil.receive_message(request) michael@0: global test35code michael@0: test35code = request.ws_close_code michael@0: global test35reason michael@0: test35reason = request.ws_close_reason michael@0: elif request.ws_protocol == "test-35b": michael@0: request.ws_stream.close_connection(test35code + 1, test35reason) michael@0: elif request.ws_protocol == "test-37b": michael@0: while not request.client_terminated: michael@0: msgutil.receive_message(request) michael@0: global test37code michael@0: test37code = request.ws_close_code michael@0: global test37reason michael@0: test37reason = request.ws_close_reason michael@0: elif request.ws_protocol == "test-37c": michael@0: request.ws_stream.close_connection(test37code, test37reason) michael@0: elif request.ws_protocol == "test-42": michael@0: # Echo back 3 messages michael@0: msgutil.send_message(request, michael@0: msgutil.receive_message(request)) michael@0: msgutil.send_message(request, michael@0: msgutil.receive_message(request)) michael@0: msgutil.send_message(request, michael@0: msgutil.receive_message(request)) michael@0: elif request.ws_protocol == "test-44": michael@0: rcv = msgutil.receive_message(request) michael@0: # check we received correct binary msg michael@0: if len(rcv) == 3 \ michael@0: and ord(rcv[0]) == 5 and ord(rcv[1]) == 0 and ord(rcv[2]) == 7: michael@0: # reply with binary msg 0x04 michael@0: msgutil.send_message(request, struct.pack("cc", chr(0), chr(4)), True, True) michael@0: else: michael@0: msgutil.send_message(request, "incorrect binary msg received!") michael@0: elif request.ws_protocol == "test-45": michael@0: rcv = msgutil.receive_message(request) michael@0: # check we received correct binary msg michael@0: if rcv == "flob": michael@0: # send back same blob as binary msg michael@0: msgutil.send_message(request, rcv, True, True) michael@0: else: michael@0: msgutil.send_message(request, "incorrect binary msg received: '" + rcv + "'") michael@0: elif request.ws_protocol == "test-46": michael@0: msgutil.send_message(request, "client must drop this if close was called") michael@0: michael@0: while not request.client_terminated: michael@0: msgutil.receive_message(request)