xpra icon
Bug tracker and wiki

This bug tracker and wiki are being discontinued
please use https://github.com/Xpra-org/xpra instead.


Ticket #2121: websocket-legacy-flag.patch

File websocket-legacy-flag.patch, 5.5 KB (added by Antoine Martin, 2 years ago)

adds a flag so we can enable the new frame format without breaking older html5 clients

  • html5/js/Client.js

     
    10001000                "steal"                                         : this.steal,
    10011001                "client_type"                           : "HTML5",
    10021002                "encoding.generic"                      : true,
     1003                "websocket.multi-packet"    : true,
    10031004                "username"                                      : this.username,
    10041005                "uuid"                                          : this.uuid,
    10051006                "argv"                                          : [window.location.href],
  • xpra/client/client_base.py

     
    379379                "version"               : XPRA_VERSION,
    380380                "encoding.generic"      : True,
    381381                "namespace"             : True,
     382                "websocket.multi-packet": True,
    382383                "hostname"              : socket.gethostname(),
    383384                "uuid"                  : self.uuid,
    384385                "username"              : self.username,
  • xpra/net/protocol.py

     
    146146            self._process_packet_cb =  fj.process_packet_cb
    147147        else:
    148148            self._process_packet_cb = process_packet_cb
     149        self.make_chunk_header = self.make_xpra_header
     150        self.make_frame_header = self.noframe_header
    149151        self._write_queue = Queue(1)
    150152        self._read_queue = Queue(20)
    151153        self._process_read = self.read_queue_put
     
    191193                    "cipher_in", "cipher_in_name", "cipher_in_block_size", "cipher_in_padding",
    192194                    "cipher_out", "cipher_out_name", "cipher_out_block_size", "cipher_out_padding",
    193195                    "compression_level", "encoder", "compressor")
     196
    194197    def save_state(self):
    195198        state = {}
    196199        for x in Protocol.STATE_FIELDS:
     
    405408                log("sending %s bytes without header", payload_size)
    406409                items.append(data)
    407410            else:
    408                 header = pack_header(proto_flags, level, index, payload_size)
     411                #the xpra packet header:
     412                #(WebSocketProtocol may also add a websocket header too)
     413                header = self.make_chunk_header(packet_type, proto_flags, level, index, payload_size)
    409414                if actual_size<PACKET_JOIN_SIZE:
    410415                    if not isinstance(data, JOIN_TYPES):
    411416                        data = memoryview_to_bytes(data)
     
    413418                else:
    414419                    items.append(header)
    415420                    items.append(data)
     421        #WebSocket header may be added here:
    416422        frame_header = self.make_frame_header(packet_type, items)
    417423        if frame_header:
    418424            if len(items[0])<PACKET_JOIN_SIZE:
     
    421427                items.insert(0, frame_header)
    422428        self.raw_write(items, start_send_cb, end_send_cb, fail_cb, synchronous, more)
    423429
    424     def make_frame_header(self, _packet_type, _items):
    425         #overriden by websockets
     430    def make_xpra_header(self, _packet_type, proto_flags, level, index, payload_size):
     431        return pack_header(proto_flags, level, index, payload_size)
     432
     433    def noframe_header(self, _packet_type, _items):
    426434        return None
    427435
    428436
  • xpra/net/websocket_protocol.py

     
    3131
    3232class WebSocketProtocol(Protocol):
    3333
     34    STATE_FIELDS = tuple(list(Protocol.STATE_FIELDS)+["legacy_frame_per_chunk"])
     35
    3436    def __init__(self, *args):
    3537        Protocol.__init__(self, *args)
    3638        self.ws_data = b""
    3739        self._process_read = self.parse_ws_frame
     40        #default to legacy mode until we parse the remote caps:
     41        self.legacy_frame_per_chunk = True
     42        self.make_chunk_header = self.make_wschunk_header
    3843
    39     def make_frame_header(self, packet_type, items):
     44    def get_info(self, alias_info=True):
     45        info = Protocol.get_info(self, alias_info)
     46        info["legacy-frames"] = self.legacy_frame_per_chunk
     47        return info
     48
     49
     50    def parse_remote_caps(self, caps):
     51        Protocol.parse_remote_caps(self, caps)
     52        self.legacy_frame_per_chunk = not caps.boolget("websocket.multi-packet", True)
     53        if self.legacy_frame_per_chunk:
     54            log.warn("Warning: using slower legacy websocket frames")
     55            #websocker header for every chunk:
     56            self.make_chunk_header = self.make_wschunk_header
     57            #no frame header:
     58            self.make_frame_header = self.noframe_header
     59        else:
     60            #just the regular xpra header for each chunk:
     61            self.make_chunk_header = self.make_xpra_header
     62            #and one websocket header for all the chunks:
     63            self.make_frame_header = self.make_wsframe_header
     64
     65    def make_wschunk_header(self, packet_type, proto_flags, level, index, payload_size):
     66        header = Protocol.make_xpra_header(self, packet_type, proto_flags, level, index, payload_size)
     67        log("make_chunk_header(%s)", (packet_type, proto_flags, level, index, payload_size))
     68        return encode_hybi_header(OPCODE_BINARY, payload_size+len(header))
     69
     70    def make_wsframe_header(self, packet_type, items):
    4071        payload_len = sum(len(item) for item in items)
    4172        log("make_frame_header(%s, %i items) %i bytes", packet_type, len(items), payload_len)
    4273        return encode_hybi_header(OPCODE_BINARY, payload_len)