tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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)