Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# This file is part of Xpra. 

2# This file is based on websockify/websocket.py from the websockify project 

3# Copyright 2019 Antoine Martin <antoine@xpra.org> 

4# Copyright 2011 Joel Martin 

5# Copyright 2016 Pierre Ossman 

6# Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3) 

7 

8import struct 

9 

10from xpra.buffers.cyxor import hybi_unmask #@UnresolvedImport 

11 

12 

13def encode_hybi_header(opcode, payload_len, has_mask=False, fin=True): 

14 """ Encode a HyBi style WebSocket frame """ 

15 assert (opcode & 0x0f)==opcode, "invalid opcode %#x" % opcode 

16 mask_bit = 0x80*has_mask 

17 b1 = opcode | (0x80 * fin) 

18 if payload_len <= 125: 

19 return struct.pack('>BB', b1, payload_len | mask_bit) 

20 if payload_len < 65536: 

21 return struct.pack('>BBH', b1, 126 | mask_bit, payload_len) 

22 return struct.pack('>BBQ', b1, 127 | mask_bit, payload_len) 

23 

24 

25def decode_hybi(buf): 

26 """ Decode HyBi style WebSocket packets """ 

27 blen = len(buf) 

28 hlen = 2 

29 if blen < hlen: 

30 #log("decode_hybi_header() buffer too small: %i", blen) 

31 return None 

32 

33 b1, b2 = struct.unpack(">BB", buf[:2]) 

34 opcode = b1 & 0x0f 

35 fin = bool(b1 & 0x80) 

36 masked = bool(b2 & 0x80) 

37 if masked: 

38 hlen += 4 

39 if blen < hlen: 

40 #log("decode_hybi_header() buffer too small for mask: %i", blen) 

41 return None 

42 

43 payload_len = b2 & 0x7f 

44 if payload_len == 126: 

45 hlen += 2 

46 if blen < hlen: 

47 #log("decode_hybi_header() buffer too small for 126 payload: %i", blen) 

48 return None 

49 payload_len = struct.unpack('>H', buf[2:4])[0] 

50 elif payload_len == 127: 

51 hlen += 8 

52 if blen < hlen: 

53 #log("decode_hybi_header() buffer too small for 127 payload: %i", blen) 

54 return None 

55 payload_len = struct.unpack('>Q', buf[2:10])[0] 

56 

57 #log("decode_hybi_header() decoded header '%s': hlen=%i, 

58 # payload_len=%i, buffer len=%i", binascii.hexlify(buf[:hlen]), hlen, payload_len, blen) 

59 length = hlen + payload_len 

60 if blen < length: 

61 #log("decode_hybi_header() buffer too small for payload: %i (needed %i)", blen, length) 

62 return None 

63 

64 if masked: 

65 payload = hybi_unmask(buf, hlen-4, payload_len) 

66 else: 

67 payload = buf[hlen:length] 

68 #log("decode_hybi_header() payload_len=%i, hlen=%i, 

69 # length=%i, fin=%s", payload_len, hlen, length, fin) 

70 return opcode, payload, length, fin