def test_binary_to_term_small_tuple(self): self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83h') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83h\1') self.assertEqual((), erlang.binary_to_term(b'\x83h\0')) self.assertEqual(([], []), erlang.binary_to_term(b'\x83h\2jj'))
def test_binary_to_term_string_list(self): self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83k') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83k\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83k\0\1') self.assertEqual(b'', erlang.binary_to_term(b'\x83k\0\0')) self.assertEqual(b'test', erlang.binary_to_term(b'\x83k\0\4test'))
def test_binary_to_term_small_big_integer(self): self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83n') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83n\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83n\1\0') self.assertEqual(0, erlang.binary_to_term(b'\x83n\0\0')) self.assertEqual(6618611909121, erlang.binary_to_term(b'\x83n\6\0\1\2\3\4\5\6')) self.assertEqual(-6618611909121, erlang.binary_to_term(b'\x83n\6\1\1\2\3\4\5\6'))
def test_binary_to_term_list(self): self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83l') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83l\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83l\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83l\0\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83l\0\0\0\0') self.assertEqual([], erlang.binary_to_term(b'\x83l\0\0\0\0j')) self.assertEqual([[], []], erlang.binary_to_term(b'\x83l\0\0\0\2jjj'))
def test_binary_to_term_large_tuple(self): self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83i') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83i\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83i\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83i\0\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83i\0\0\0\1') self.assertEqual((), erlang.binary_to_term(b'\x83i\0\0\0\0')) self.assertEqual(([], []), erlang.binary_to_term(b'\x83i\0\0\0\2jj'))
def test_binary_to_term_atom(self): self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83d') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83d\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83d\0\1') self.assertEqual(erlang.OtpErlangAtom(b''), erlang.binary_to_term(b'\x83d\0\0')) self.assertEqual(erlang.OtpErlangAtom(b''), erlang.binary_to_term(b'\x83s\0')) self.assertEqual(erlang.OtpErlangAtom(b'test'), erlang.binary_to_term(b'\x83d\0\4test')) self.assertEqual(erlang.OtpErlangAtom(b'test'), erlang.binary_to_term(b'\x83s\4test'))
def test_binary_to_term_integer(self): self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83b') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83b\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83b\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83b\0\0\0') self.assertEqual(0, erlang.binary_to_term(b'\x83b\0\0\0\0')) self.assertEqual(2147483647, erlang.binary_to_term(b'\x83b\x7f\xff\xff\xff')) self.assertEqual(-2147483648, erlang.binary_to_term(b'\x83b\x80\0\0\0')) self.assertEqual(-1, erlang.binary_to_term(b'\x83b\xff\xff\xff\xff'))
def test_binary_to_term_binary(self): self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83m') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83m\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83m\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83m\0\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83m\0\0\0\1') self.assertEqual(erlang.OtpErlangBinary(b''), erlang.binary_to_term(b'\x83m\0\0\0\0')) self.assertEqual(erlang.OtpErlangBinary(b'data'), erlang.binary_to_term(b'\x83m\0\0\0\4data'))
def test_binary_to_term_improper_list(self): self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83l\0\0\0\0k') lst = erlang.binary_to_term(b'\x83l\0\0\0\1jd\0\4tail') self.assertEqual(erlang.OtpErlangList, type(lst)) self.assertEqual([[], erlang.OtpErlangAtom(b'tail')], lst.value) self.assertEqual(True, lst.improper)
def test_binary_to_term_port(self): port_old_binary = ( b'\x83\x66\x64\x00\x0D\x6E\x6F\x6E\x6F\x64\x65\x40\x6E\x6F\x68' b'\x6F\x73\x74\x00\x00\x00\x06\x00' ) port_old = erlang.binary_to_term(port_old_binary) self.assertTrue(isinstance(port_old, erlang.OtpErlangPort)) self.assertEqual(erlang.term_to_binary(port_old), b'\x83fs\rnonode@nohost\x00\x00\x00\x06\x00') port_new_binary = ( b'\x83\x59\x64\x00\x0D\x6E\x6F\x6E\x6F\x64\x65\x40\x6E\x6F\x68' b'\x6F\x73\x74\x00\x00\x00\x06\x00\x00\x00\x00' ) port_new = erlang.binary_to_term(port_new_binary) self.assertTrue(isinstance(port_new, erlang.OtpErlangPort)) self.assertEqual(erlang.term_to_binary(port_new), b'\x83Ys\rnonode@nohost\x00\x00\x00\x06' b'\x00\x00\x00\x00')
def test_binary_to_term_predefined_atoms(self): self.assertEqual(True, erlang.binary_to_term(b'\x83s\4true')) self.assertEqual(False, erlang.binary_to_term(b'\x83s\5false')) self.assertEqual(False, erlang.binary_to_term(b'\x83w\5false')) self.assertEqual(None, erlang.binary_to_term(b'\x83s\11undefined')) self.assertEqual(None, erlang.binary_to_term(b'\x83w\11undefined')) self.assertEqual(None, erlang.binary_to_term(b'\x83d\0\11undefined')) self.assertEqual(None, erlang.binary_to_term(b'\x83v\0\11undefined'))
def test_binary_to_term_pid(self): pid_old_binary = ( b'\x83\x67\x64\x00\x0D\x6E\x6F\x6E\x6F\x64\x65\x40\x6E\x6F' b'\x68\x6F\x73\x74\x00\x00\x00\x4E\x00\x00\x00\x00\x00' ) pid_old = erlang.binary_to_term(pid_old_binary) self.assertTrue(isinstance(pid_old, erlang.OtpErlangPid)) self.assertEqual(erlang.term_to_binary(pid_old), b'\x83gs\rnonode@nohost\x00\x00\x00N' b'\x00\x00\x00\x00\x00') pid_new_binary = ( b'\x83\x58\x64\x00\x0D\x6E\x6F\x6E\x6F\x64\x65\x40\x6E\x6F\x68' b'\x6F\x73\x74\x00\x00\x00\x4E\x00\x00\x00\x00\x00\x00\x00\x00' ) pid_new = erlang.binary_to_term(pid_new_binary) self.assertTrue(isinstance(pid_new, erlang.OtpErlangPid)) self.assertEqual(erlang.term_to_binary(pid_new), b'\x83Xs\rnonode@nohost\x00\x00\x00N' b'\x00\x00\x00\x00\x00\x00\x00\x00')
def test_binary_to_term_float(self): self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83F') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83F\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83F\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83F\0\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83F\0\0\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83F\0\0\0\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83F\0\0\0\0\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83F\0\0\0\0\0\0\0') self.assertEqual(0.0, erlang.binary_to_term(b'\x83F\0\0\0\0\0\0\0\0')) self.assertEqual(1.5, erlang.binary_to_term(b'\x83F?\xf8\0\0\0\0\0\0'))
def _extract_maybe_binary(self, value_length: int): is_binary = self._extract_bool() val = self._extract_str(value_length - 1) if is_binary: return val else: try: return erlang.binary_to_term(val) except Exception as e: raise ValueError(e)
def recv(stream): """Read an Erlang term from an input stream.""" header = stream.read(4) if len(header) != 4: return None # EOF (length, ) = struct.unpack('!I', header) payload = stream.read(length) if len(payload) != length: return None term = erlang.binary_to_term(payload) return term
def test_binary_to_term_ref(self): ref_new_binary = ( b'\x83\x72\x00\x03\x64\x00\x0D\x6E\x6F\x6E\x6F\x64\x65\x40\x6E' b'\x6F\x68\x6F\x73\x74\x00\x00\x03\xE8\x4E\xE7\x68\x00\x02\xA4' b'\xC8\x53\x40' ) ref_new = erlang.binary_to_term(ref_new_binary) self.assertTrue(isinstance(ref_new, erlang.OtpErlangReference)) self.assertEqual(erlang.term_to_binary(ref_new), b'\x83r\x00\x03s\rnonode@nohost\x00\x00\x03\xe8' b'N\xe7h\x00\x02\xa4\xc8S@') ref_newer_binary = ( b'\x83\x5A\x00\x03\x64\x00\x0D\x6E\x6F\x6E\x6F\x64\x65\x40\x6E' b'\x6F\x68\x6F\x73\x74\x00\x00\x00\x00\x00\x01\xAC\x03\xC7\x00' b'\x00\x04\xBB\xB2\xCA\xEE' ) ref_newer = erlang.binary_to_term(ref_newer_binary) self.assertTrue(isinstance(ref_newer, erlang.OtpErlangReference)) self.assertEqual(erlang.term_to_binary(ref_newer), b'\x83Z\x00\x03s\rnonode@nohost\x00\x00\x00\x00\x00' b'\x01\xac\x03\xc7\x00\x00\x04\xbb\xb2\xca\xee')
def recv(self): """Read an Erlang term from an input stream.""" stream = self.input header = stream.read(4) if len(header) != 4: return None # EOF (length,) = struct.unpack('!I', header) payload = stream.read(length) if len(payload) != length: return None term = erlang.binary_to_term(payload) return term
def __recvUntilKey(self, target_key): while True: try: result = self.__ws.recv() etf_data = erlang.binary_to_term(result) erlang.etfDictToJson(self.__session_settings, etf_data[OtpErlangAtom('d')]) if self.__session_settings.has_key( target_key ): # TODO: this only searches 1 depth of dictionary, needs to be fixed return except websocket._exceptions.WebSocketTimeoutException: return
def _get_vector_clocks(self): clock_length = self._extract_uint32() if clock_length != 0: if self._vc_format == "dict": try: erl_term = erlang.binary_to_term( self._extract_str(clock_length)) self.vector_clocks = {} for clock in erl_term: actor = "".join([str(x) for x in clock[0].binary()]) self.vector_clocks[actor] = clock[1][0] except: raise ValueError("Could not decode vector clocks") else: self.vector_clocks = base64.b64encode( self._extract_str(clock_length))
def test_binary_to_term_compressed_term(self): self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83P') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83P\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83P\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83P\0\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83P\0\0\0\0') self.assertRaises( erlang.ParseException, erlang.binary_to_term, b'\x83P\0\0\0\x16\x78\xda\xcb\x66\x10\x49\xc1\2\0\x5d\x60\x08\x50') self.assertEqual( b'd' * 20, erlang.binary_to_term(b'\x83P\0\0\0\x17\x78\xda\xcb\x66' b'\x10\x49\xc1\2\0\x5d\x60\x08\x50'))
def _lookup(self, node, key): if node == None: raise Exception("not found") offset = node[0] print "----" print "file offset ", offset print "block offset", 4096 * (offset/4096),4096 * (1+offset/4096) print "block space ", 4096 * (1+offset/4096) - offset print "++++" self.fd.seek(offset) length = struct.unpack(">I", self.fd.read(4))[0] print "reading " + `length` + " bytes" self.fd.seek(offset + 4) prefix = self.fd.read(1) if ord(prefix) == 1: print "skipping 5 bytes" print_bin(self.fd.read(4)) length -= 5 node_data = self.fd.read(length) print_bin(node_data) node_value = erlang.binary_to_term(node_data) node_left_key = node_value[1][0][0] node_left_node = node_value[1][0][1] node_right_node = node_value[1][1][1] print node_value # if node_key == key: # return node_value if key <= node_left_key: print "going left" return self._lookup(node_left_node, key) else: print "going right" return self._lookup(node_right_node, key)
def erl_dist_recv(f): hdr = f.recv(4) if len(hdr) != 4: return (length, ) = unpack('!I', hdr) data = f.recv(length) if len(data) != length: return # remove 0x70 from head of stream data = data[1:] while data: (parsed, term) = erl.binary_to_term(data) if parsed <= 0: print('failed to parse erlang term, may need to peek into it') break yield term data = data[parsed:]
def test_binary_to_term_compressed_term(self): self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83P') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83P\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83P\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83P\0\0\0') self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83P\0\0\0\0') self.assertRaises( erlang.ParseException, erlang.binary_to_term, b'\x83P\0\0\0\x16\x78\xda\xcb\x66\x10\x49\xc1\2\0\x5d\x60\x08\x50' ) self.assertEqual(b'd' * 20, erlang.binary_to_term(b'\x83P\0\0\0\x17\x78\xda\xcb\x66' b'\x10\x49\xc1\2\0\x5d\x60\x08\x50') )
def test_binary_to_term_predefined_atoms(self): self.assertEqual(True, erlang.binary_to_term(b'\x83s\4true')) self.assertEqual(False, erlang.binary_to_term(b'\x83s\5false')) self.assertEqual(erlang.OtpErlangAtom(b'undefined'), erlang.binary_to_term(b'\x83d\0\11undefined'))
def Connect(self, token): gateway_auth_data = { OtpErlangBinary('op', bits=8): 2, OtpErlangBinary('d', bits=8): { OtpErlangBinary('properties', bits=8): { OtpErlangBinary('client_version', bits=8): OtpErlangBinary('0.0.305', bits=8), OtpErlangBinary('os', bits=8): OtpErlangBinary('Windows', bits=8), OtpErlangBinary('os_version', bits=8): OtpErlangBinary('6.1.7601', bits=8), OtpErlangBinary('os_arch', bits=8): OtpErlangBinary('x64', bits=8), OtpErlangBinary('release_channel', bits=8): OtpErlangBinary('stable', bits=8), OtpErlangBinary('client_build_number', bits=8): 44004, OtpErlangBinary('browser', bits=8): OtpErlangBinary('Discord Client', bits=8), OtpErlangBinary('client_event_source', bits=8): OtpErlangAtom('nil') }, OtpErlangBinary('compress', bits=8): False, OtpErlangBinary('token', bits=8): OtpErlangBinary("{}".format(token), bits=8), OtpErlangBinary('presence', bits=8): { OtpErlangBinary('status', bits=8): OtpErlangBinary('online', bits=8), OtpErlangBinary('since', bits=8): 0, OtpErlangBinary('afk', bits=8): False, OtpErlangBinary('activities', bits=8): [] } } } # Connect to gateway gateway_auth_data = erlang.term_to_binary(gateway_auth_data) if self.__proxy_host != False and self.__proxy_port != False: self.__ws.connect( self.URL, origin="https://discordapp.com", http_proxy_host=self.__proxy_host, http_proxy_port=self.__proxy_port, header={ "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) discord/0.0.305 Chrome/69.0.3497.128 Electron/4.0.8 Safari/537.36" }) else: self.__ws.connect( self.URL, origin="https://discordapp.com", header={ "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) discord/0.0.305 Chrome/69.0.3497.128 Electron/4.0.8 Safari/537.36" }) Logger.LogMessage('Gateway_wss connecting -> {}'.format(self.URL), log_level=LogLevel.OK) # Receive response response = self.__ws.recv() Logger.LogMessage('Gateway_wss received <- {} bytes'.format( len(response))) Logger.LogMessage('Gateway_wss data received \r\n', to_file=True, to_console=False, hex_data=response) # Send auth message Logger.LogMessage('Gateway_wss sending -> {} bytes'.format( len(gateway_auth_data))) self.__ws.send_binary(gateway_auth_data) Logger.LogMessage('Gateway_wss data sent -> \r\n', to_file=True, to_console=False, hex_data=gateway_auth_data) # Receive media_token response = self.__ws.recv() etf_data = erlang.binary_to_term(response) Logger.LogMessage('Gateway_wss received <- {} bytes'.format( len(response))) Logger.LogMessage('Gateway_wss data received <- \r\n', to_file=True, to_console=False, hex_data=response) erlang.etfDictToJson(self.__session_settings, etf_data[OtpErlangAtom('d')]) Logger.LogMessage('Authenticated over gateway as {}'.format( self.__session_settings['user']['id']), log_level=LogLevel.OK) Logger.LogMessage('Session id: {}'.format( self.__session_settings['session_id']))
def test_binary_to_term_small_integer(self): self.assertRaises(erlang.ParseException, erlang.binary_to_term, b'\x83a') self.assertEqual(0, erlang.binary_to_term(b'\x83a\0')) self.assertEqual(255, erlang.binary_to_term(b'\x83a\xff'))
def poll(self): ready = False while ready == False: IN, OUT, EXCEPT = select.select([self.__s], [], [self.__s]) if len(EXCEPT) > 0: return None if len(IN) > 0: ready = True data = '' while ready == True: fragment = self.__s.recv(self.__size) data += fragment ready = (len(fragment) == self.__size) if ready: IN, OUT, EXCEPT = select.select([self.__s], [], [], 0) ready == (len(IN) > 0) if len(data) == 0: return None # socket was closed while True: i, j = 0, 4 command = struct.unpack("=I", data[i:j])[0] if command == _MESSAGE_INIT: i, j = j, j + 4 prefixSize = struct.unpack("=I", data[i:j])[0] i, j = j, j + prefixSize + 4 + 4 (prefix, null_terminator, timeoutAsync, timeoutSync) = struct.unpack("=%dscII" % (prefixSize - 1), data[i:j]) assert j == len(data) return (prefix, timeoutSync, timeoutAsync) elif (command == _MESSAGE_SEND_ASYNC or command == _MESSAGE_SEND_SYNC): i, j = j, j + 4 nameSize = struct.unpack("=I", data[i:j])[0] i, j = j, j + nameSize + 4 (name, null_terminator, requestSize) = struct.unpack("=%dscI" % (nameSize - 1), data[i:j]) i, j = j, j + requestSize + 4 + 16 + 4 (request, timeout, transId, pidSize) = struct.unpack("=%dsI16sI" % requestSize, data[i:j]) i, j = j, j + pidSize pid = struct.unpack("=%ds" % pidSize, data[i:j])[0] assert j == len(data) data = '' self.__callback(command, name, request, timeout, transId, binary_to_term(pid)) elif (command == _MESSAGE_RECV_ASYNC or command == _MESSAGE_RETURN_SYNC): i, j = j, j + 4 responseSize = struct.unpack("=I", data[i:j])[0] i, j = j, j + responseSize + 16 assert j == len(data) return struct.unpack("=%ds16s" % responseSize, data[i:j]) elif command == _MESSAGE_RETURN_ASYNC: i, j = j, j + 16 assert j == len(data) return struct.unpack("=16s", data[i:j])[0] elif command == _MESSAGE_RETURNS_ASYNC: i, j = j, j + 4 transIdCount = struct.unpack("=I", data[i:j])[0] i, j = j, j + 16 * transIdCount assert j == len(data) return struct.unpack("=" + "16s" * transIdCount, data[i:j]) elif command == _MESSAGE_KEEPALIVE: self.__s.sendall(term_to_binary(OtpErlangAtom("keepalive"))) assert j >= len(data) data = data[j:] if len(data) > 0: IN, OUT, EXCEPT = select.select([self.__s], [], [], 0) if len(IN) == 0: continue else: assert False ready = False while ready == False: IN, OUT, EXCEPT = select.select([self.__s], [], [self.__s]) if len(EXCEPT) > 0: return None if len(IN) > 0: ready = True while ready == True: fragment = self.__s.recv(self.__size) data += fragment ready = (len(fragment) == self.__size) if ready: IN, OUT, EXCEPT = select.select([self.__s], [], [], 0) ready == (len(IN) > 0) if len(data) == 0: return None # socket was closed
def __poll_request(self, timeout, external): if self.__terminate: return False elif external and not self.__initialization_complete: self.__send(term_to_binary(OtpErlangAtom(b'polling'))) self.__initialization_complete = True poll_timer = None if timeout is None or timeout < 0: timeout_value = None elif timeout == 0: timeout_value = 0 elif timeout > 0: poll_timer = default_timer() timeout_value = timeout * 0.001 IN, OUT, EXCEPT = select.select([self.__s],[],[self.__s], timeout_value) if len(EXCEPT) > 0: return False if len(IN) == 0: return True data = b'' data = self.__recv(data) data_size = len(data) if data_size == 0: return False # socket was closed i, j = 0, 4 while True: command = struct.unpack(b'=I', data[i:j])[0] if command == _MESSAGE_INIT: i, j = j, j + 4 + 4 + 4 + 4 + 4 (process_index, process_count, process_count_max, process_count_min, prefix_size) = struct.unpack(b'=IIIII', data[i:j]) i, j = j, j + prefix_size + 4 + 4 + 4 + 4 + 1 + 1 (prefix, null_terminator, timeout_initialize, timeout_async, timeout_sync, timeout_terminate, priority_default, request_timeout_adjustment) = struct.unpack( '=%dscIIIIbB' % (prefix_size - 1), data[i:j] ) if j != data_size: assert external == False self.__handle_events(external, data, data_size, j) return (process_index, process_count, process_count_max, process_count_min, prefix.decode('utf-8'), timeout_initialize, timeout_sync, timeout_async, timeout_terminate, priority_default, bool(request_timeout_adjustment)) elif (command == _MESSAGE_SEND_ASYNC or command == _MESSAGE_SEND_SYNC): i, j = j, j + 4 name_size = struct.unpack(b'=I', data[i:j])[0] i, j = j, j + name_size + 4 (name, null_terminator, pattern_size) = struct.unpack('=%dscI' % (name_size - 1), data[i:j]) i, j = j, j + pattern_size + 4 (pattern, null_terminator, request_info_size) = struct.unpack( '=%dscI' % (pattern_size - 1), data[i:j] ) i, j = j, j + request_info_size + 1 + 4 (request_info, null_terminator, request_size) = struct.unpack( '=%dscI' % request_info_size, data[i:j] ) i, j = j, j + request_size + 1 + 4 + 1 + 16 + 4 (request, null_terminator, request_timeout, priority, trans_id, pid_size) = struct.unpack( '=%dscIb16sI' % request_size, data[i:j] ) i, j = j, j + pid_size pid = data[i:j] if j != data_size: assert external == True if not self.__handle_events(external, data, data_size, j): return False data = b'' self.__callback(command, name.decode('utf-8'), pattern.decode('utf-8'), request_info, request, request_timeout, priority, trans_id, binary_to_term(pid)) elif (command == _MESSAGE_RECV_ASYNC or command == _MESSAGE_RETURN_SYNC): i, j = j, j + 4 response_info_size = struct.unpack(b'=I', data[i:j])[0] i, j = j, j + response_info_size + 1 + 4 (response_info, null_terminator, response_size) = struct.unpack( '=%dscI' % response_info_size, data[i:j] ) i, j = j, j + response_size + 1 + 16 (response, null_terminator, trans_id) = struct.unpack( '=%dsc16s' % response_size, data[i:j] ) if j != data_size: assert external == False self.__handle_events(external, data, data_size, j) return (response_info, response, trans_id) elif command == _MESSAGE_RETURN_ASYNC: i, j = j, j + 16 trans_id = data[i:j] if j != data_size: assert external == False self.__handle_events(external, data, data_size, j) return trans_id elif command == _MESSAGE_RETURNS_ASYNC: i, j = j, j + 4 trans_id_count = struct.unpack(b'=I', data[i:j])[0] i, j = j, j + 16 * trans_id_count trans_ids = struct.unpack( b'=' + b'16s' * trans_id_count, data[i:j] ) if j != data_size: assert external == False self.__handle_events(external, data, data_size, j) return trans_ids elif command == _MESSAGE_SUBSCRIBE_COUNT: i, j = j, j + 4 count = struct.unpack(b'=I', data[i:j])[0] if j != data_size: assert external == False self.__handle_events(external, data, data_size, j) return count elif command == _MESSAGE_TERM: if not self.__handle_events(external, data, data_size, j, command=command): return False assert False elif command == _MESSAGE_REINIT: i, j = j, j + 4 self.__process_count = struct.unpack(b'=I', data[i:j])[0] if j == data_size: pass elif j < data_size: i, j = j, j + 4 continue else: raise message_decoding_exception() elif command == _MESSAGE_KEEPALIVE: self.__send(term_to_binary(OtpErlangAtom(b'keepalive'))) if j == data_size: pass elif j < data_size: i, j = j, j + 4 continue else: raise message_decoding_exception() else: raise message_decoding_exception() if poll_timer is not None: poll_timer_new = default_timer() elapsed = max(0, int((poll_timer_new - poll_timer) * 1000.0)) poll_timer = poll_timer_new if elapsed >= timeout: timeout = 0 else: timeout -= elapsed if timeout_value is not None: if timeout == 0: return True elif timeout > 0: timeout_value = timeout * 0.001 IN, OUT, EXCEPT = select.select([self.__s],[],[self.__s], timeout_value) if len(EXCEPT) > 0: return False if len(IN) == 0: return True data = self.__recv(data) data_size = len(data) if data_size == 0: return False # socket was closed i, j = 0, 4
def __poll_request(self, external): if external and not self.__initializtion_complete: self.__send(term_to_binary(OtpErlangAtom('polling'))) self.__initializtion_complete = True ready = False while ready == False: IN, OUT, EXCEPT = select.select([self.__s],[],[self.__s]) if len(EXCEPT) > 0: return None if len(IN) > 0: ready = True data = '' data = self.__recv(data) if len(data) == 0: return None # socket was closed while True: i, j = 0, 4 command = struct.unpack('=I', data[i:j])[0] if command == _MESSAGE_INIT: i, j = j, j + 4 prefixSize = struct.unpack('=I', data[i:j])[0] i, j = j, j + prefixSize + 4 + 4 + 1 + 1 (prefix, nullTerminator, timeoutAsync, timeoutSync, priorityDefault, requestTimeoutAdjustment) = struct.unpack( '=%dscIIbB' % (prefixSize - 1), data[i:j] ) if j != len(data): raise message_decoding_exception() return (prefix, timeoutSync, timeoutAsync, priorityDefault, bool(requestTimeoutAdjustment)) elif (command == _MESSAGE_SEND_ASYNC or command == _MESSAGE_SEND_SYNC): i, j = j, j + 4 nameSize = struct.unpack('=I', data[i:j])[0] i, j = j, j + nameSize + 4 (name, nullTerminator, patternSize) = struct.unpack('=%dscI' % (nameSize - 1), data[i:j]) i, j = j, j + patternSize + 4 (pattern, nullTerminator, request_infoSize) = struct.unpack('=%dscI' % (patternSize - 1), data[i:j]) i, j = j, j + request_infoSize + 1 + 4 (request_info, nullTerminator, requestSize) = struct.unpack('=%dscI' % request_infoSize, data[i:j]) i, j = j, j + requestSize + 1 + 4 + 1 + 16 + 4 (request, nullTerminator, timeout, priority, trans_id, pidSize) = struct.unpack('=%dscIb16sI' % requestSize, data[i:j]) i, j = j, j + pidSize pid = struct.unpack('=%ds' % pidSize, data[i:j])[0] if j != len(data): raise message_decoding_exception() data = '' self.__callback(command, name, pattern, request_info, request, timeout, priority, trans_id, binary_to_term(pid)) elif (command == _MESSAGE_RECV_ASYNC or command == _MESSAGE_RETURN_SYNC): i, j = j, j + 4 responseInfoSize = struct.unpack('=I', data[i:j])[0] i, j = j, j + responseInfoSize + 1 + 4 (response_info, nullTerminator, responseSize) = struct.unpack('=%dscI' % responseInfoSize, data[i:j]) i, j = j, j + responseSize + 1 + 16 if j != len(data): raise message_decoding_exception() (response, nullTerminator, trans_id) = struct.unpack('=%dsc16s' % responseSize, data[i:j]) return (response_info, response, trans_id) elif command == _MESSAGE_RETURN_ASYNC: i, j = j, j + 16 if j != len(data): raise message_decoding_exception() return struct.unpack('=16s', data[i:j])[0] elif command == _MESSAGE_RETURNS_ASYNC: i, j = j, j + 4 transIdCount = struct.unpack('=I', data[i:j])[0] i, j = j, j + 16 * transIdCount if j != len(data): raise message_decoding_exception() return struct.unpack('=' + '16s' * transIdCount, data[i:j]) elif command == _MESSAGE_KEEPALIVE: self.__send(term_to_binary(OtpErlangAtom('keepalive'))) if j < len(data): raise message_decoding_exception() data = data[j:] if len(data) > 0: IN, OUT, EXCEPT = select.select([self.__s],[],[],0) if len(IN) == 0: continue else: raise message_decoding_exception() ready = False while ready == False: IN, OUT, EXCEPT = select.select([self.__s],[],[self.__s]) if len(EXCEPT) > 0: return None if len(IN) > 0: ready = True data = self.__recv(data) if len(data) == 0: return None # socket was closed
def __poll_request(self, timeout, external): # pylint: disable=too-many-locals # pylint: disable=too-many-return-statements # pylint: disable=too-many-branches # pylint: disable=too-many-statements if self.__terminate: return False elif external and not self.__initialization_complete: self.__send(term_to_binary(OtpErlangAtom(b'polling'))) self.__initialization_complete = True poll_timer = None if timeout is None or timeout < 0: timeout_value = None elif timeout == 0: timeout_value = 0.0 elif timeout > 0: poll_timer = default_timer() timeout_value = timeout * 0.001 fd_in, _, fd_except = select.select([self.__s], [], [self.__s], timeout_value) if len(fd_except) > 0: return False if len(fd_in) == 0: return True data = b'' data = self.__recv(data) data_size = len(data) if data_size == 0: return False # socket was closed i, j = 0, 4 while True: command = struct.unpack(b'=I', data[i:j])[0] if command == _MESSAGE_INIT: i, j = j, j + 4 + 4 + 4 + 4 + 4 (process_index, process_count, process_count_max, process_count_min, prefix_size) = struct.unpack(b'=IIIII', data[i:j]) i, j = j, j + prefix_size + 4 + 4 + 4 + 4 + 1 (prefix, _, timeout_initialize, timeout_async, timeout_sync, timeout_terminate, priority_default) = struct.unpack( '=%dscIIIIb' % (prefix_size - 1), data[i:j]) if j != data_size: assert external is False self.__handle_events(external, data, data_size, j) return (process_index, process_count, process_count_max, process_count_min, prefix.decode('utf-8'), timeout_initialize, timeout_sync, timeout_async, timeout_terminate, priority_default) elif (command == _MESSAGE_SEND_ASYNC or command == _MESSAGE_SEND_SYNC): i, j = j, j + 4 name_size = struct.unpack(b'=I', data[i:j])[0] i, j = j, j + name_size + 4 (name, _, pattern_size) = struct.unpack('=%dscI' % (name_size - 1), data[i:j]) i, j = j, j + pattern_size + 4 (pattern, _, request_info_size) = struct.unpack( '=%dscI' % (pattern_size - 1), data[i:j]) i, j = j, j + request_info_size + 1 + 4 (request_info, _, request_size) = struct.unpack('=%dscI' % request_info_size, data[i:j]) i, j = j, j + request_size + 1 + 4 + 1 + 16 + 4 (request, _, request_timeout, priority, trans_id, pid_size) = struct.unpack('=%dscIb16sI' % request_size, data[i:j]) i, j = j, j + pid_size pid = data[i:j] if j != data_size: assert external is True if not self.__handle_events(external, data, data_size, j): return False data = b'' self.__callback(command, name.decode('utf-8'), pattern.decode('utf-8'), request_info, request, request_timeout, priority, trans_id, binary_to_term(pid)) elif (command == _MESSAGE_RECV_ASYNC or command == _MESSAGE_RETURN_SYNC): i, j = j, j + 4 response_info_size = struct.unpack(b'=I', data[i:j])[0] i, j = j, j + response_info_size + 1 + 4 (response_info, _, response_size) = struct.unpack('=%dscI' % response_info_size, data[i:j]) i, j = j, j + response_size + 1 + 16 (response, _, trans_id) = struct.unpack('=%dsc16s' % response_size, data[i:j]) if j != data_size: assert external is False self.__handle_events(external, data, data_size, j) return (response_info, response, trans_id) elif command == _MESSAGE_RETURN_ASYNC: i, j = j, j + 16 trans_id = data[i:j] if j != data_size: assert external is False self.__handle_events(external, data, data_size, j) return trans_id elif command == _MESSAGE_RETURNS_ASYNC: i, j = j, j + 4 trans_id_count = struct.unpack(b'=I', data[i:j])[0] i, j = j, j + 16 * trans_id_count trans_ids = struct.unpack(b'=' + b'16s' * trans_id_count, data[i:j]) if j != data_size: assert external is False self.__handle_events(external, data, data_size, j) return trans_ids elif command == _MESSAGE_SUBSCRIBE_COUNT: i, j = j, j + 4 count = struct.unpack(b'=I', data[i:j])[0] if j != data_size: assert external is False self.__handle_events(external, data, data_size, j) return count elif command == _MESSAGE_TERM: if not self.__handle_events( external, data, data_size, j, command=command): return False assert False elif command == _MESSAGE_REINIT: i, j = j, j + 4 + 4 + 4 + 1 (self.__process_count, self.__timeout_async, self.__timeout_sync, self.__priority_default) = struct.unpack(b'=IIIb', data[i:j]) if j == data_size: data = b'' elif j < data_size: i, j = j, j + 4 continue else: raise MessageDecodingException() elif command == _MESSAGE_KEEPALIVE: self.__send(term_to_binary(OtpErlangAtom(b'keepalive'))) if j == data_size: data = b'' elif j < data_size: i, j = j, j + 4 continue else: raise MessageDecodingException() else: raise MessageDecodingException() if poll_timer is not None: poll_timer_new = default_timer() elapsed = max(0, int((poll_timer_new - poll_timer) * 1000.0)) poll_timer = poll_timer_new if elapsed >= timeout: timeout = 0 else: timeout -= elapsed if timeout_value is not None: if timeout == 0: return True elif timeout > 0: timeout_value = timeout * 0.001 fd_in, _, fd_except = select.select([self.__s], [], [self.__s], timeout_value) if len(fd_except) > 0: return False if len(fd_in) == 0: return True data = self.__recv(data) data_size = len(data) if data_size == 0: return False # socket was closed i, j = 0, 4
def test_binary_to_term_empty_list(self): self.assertEqual([], erlang.binary_to_term(b'\x83j'))
def poll(self): ready = False while ready == False: IN, OUT, EXCEPT = select.select([self.__s],[],[self.__s]) if len(EXCEPT) > 0: return None if len(IN) > 0: ready = True data = '' data = self.__recv(data) if len(data) == 0: return None # socket was closed while True: i, j = 0, 4 command = struct.unpack("=I", data[i:j])[0] if command == _MESSAGE_INIT: i, j = j, j + 4 prefixSize = struct.unpack("=I", data[i:j])[0] i, j = j, j + prefixSize + 4 + 4 + 1 (prefix, nullTerminator, timeoutAsync, timeoutSync, priorityDefault) = struct.unpack("=%dscIIb" % (prefixSize - 1), data[i:j]) if j != len(data): raise message_decoding_exception() return (prefix, timeoutSync, timeoutAsync, priorityDefault) elif (command == _MESSAGE_SEND_ASYNC or command == _MESSAGE_SEND_SYNC): i, j = j, j + 4 nameSize = struct.unpack("=I", data[i:j])[0] i, j = j, j + nameSize + 4 (name, nullTerminator, patternSize) = struct.unpack("=%dscI" % (nameSize - 1), data[i:j]) i, j = j, j + patternSize + 4 (pattern, nullTerminator, requestInfoSize) = struct.unpack("=%dscI" % (patternSize - 1), data[i:j]) i, j = j, j + requestInfoSize + 1 + 4 (requestInfo, nullTerminator, requestSize) = struct.unpack("=%dscI" % requestInfoSize, data[i:j]) i, j = j, j + requestSize + 1 + 4 + 1 + 16 + 4 (request, nullTerminator, timeout, priority, transId, pidSize) = struct.unpack("=%dscIb16sI" % requestSize, data[i:j]) i, j = j, j + pidSize pid = struct.unpack("=%ds" % pidSize, data[i:j])[0] if j != len(data): raise message_decoding_exception() data = '' self.__callback(command, name, pattern, requestInfo, request, timeout, priority, transId, binary_to_term(pid)) elif (command == _MESSAGE_RECV_ASYNC or command == _MESSAGE_RETURN_SYNC): i, j = j, j + 4 responseInfoSize = struct.unpack("=I", data[i:j])[0] i, j = j, j + responseInfoSize + 1 + 4 (responseInfo, nullTerminator, responseSize) = struct.unpack("=%dscI" % responseInfoSize, data[i:j]) i, j = j, j + responseSize + 1 + 16 if j != len(data): raise message_decoding_exception() (response, nullTerminator, transId) = struct.unpack("=%dsc16s" % responseSize, data[i:j]) return (responseInfo, response, transId) elif command == _MESSAGE_RETURN_ASYNC: i, j = j, j + 16 if j != len(data): raise message_decoding_exception() return struct.unpack("=16s", data[i:j])[0] elif command == _MESSAGE_RETURNS_ASYNC: i, j = j, j + 4 transIdCount = struct.unpack("=I", data[i:j])[0] i, j = j, j + 16 * transIdCount if j != len(data): raise message_decoding_exception() return struct.unpack("=" + "16s" * transIdCount, data[i:j]) elif command == _MESSAGE_KEEPALIVE: self.__send(term_to_binary(OtpErlangAtom("keepalive"))) if j < len(data): raise message_decoding_exception() data = data[j:] if len(data) > 0: IN, OUT, EXCEPT = select.select([self.__s],[],[],0) if len(IN) == 0: continue else: raise message_decoding_exception() ready = False while ready == False: IN, OUT, EXCEPT = select.select([self.__s],[],[self.__s]) if len(EXCEPT) > 0: return None if len(IN) > 0: ready = True data = self.__recv(data) if len(data) == 0: return None # socket was closed
def poll(self): ready = False while ready == False: IN, OUT, EXCEPT = select.select([self.__s],[],[self.__s]) if len(EXCEPT) > 0: return None if len(IN) > 0: ready = True data = '' while ready == True: fragment = self.__s.recv(self.__size) data += fragment ready = (len(fragment) == self.__size) if ready: IN, OUT, EXCEPT = select.select([self.__s],[],[],0) ready == (len(IN) > 0) if len(data) == 0: return None # socket was closed while True: i, j = 0, 4 command = struct.unpack("=I", data[i:j])[0] if command == _MESSAGE_INIT: i, j = j, j + 4 prefixSize = struct.unpack("=I", data[i:j])[0] i, j = j, j + prefixSize + 4 + 4 (prefix, null_terminator, timeoutAsync, timeoutSync) = struct.unpack("=%dscII" % (prefixSize - 1), data[i:j]) assert j == len(data) return (prefix, timeoutSync, timeoutAsync) elif (command == _MESSAGE_SEND_ASYNC or command == _MESSAGE_SEND_SYNC): i, j = j, j + 4 nameSize = struct.unpack("=I", data[i:j])[0] i, j = j, j + nameSize + 4 (name, null_terminator, requestSize) = struct.unpack("=%dscI" % (nameSize - 1), data[i:j]) i, j = j, j + requestSize + 4 + 16 + 4 (request, timeout, transId, pidSize) = struct.unpack("=%dsI16sI" % requestSize, data[i:j]) i, j = j, j + pidSize pid = struct.unpack("=%ds" % pidSize, data[i:j])[0] assert j == len(data) data = '' self.__callback(command, name, request, timeout, transId, binary_to_term(pid)) elif (command == _MESSAGE_RECV_ASYNC or command == _MESSAGE_RETURN_SYNC): i, j = j, j + 4 responseSize = struct.unpack("=I", data[i:j])[0] i, j = j, j + responseSize + 16 assert j == len(data) return struct.unpack("=%ds16s" % responseSize, data[i:j]) elif command == _MESSAGE_RETURN_ASYNC: i, j = j, j + 16 assert j == len(data) return struct.unpack("=16s", data[i:j])[0] elif command == _MESSAGE_RETURNS_ASYNC: i, j = j, j + 4 transIdCount = struct.unpack("=I", data[i:j])[0] i, j = j, j + 16 * transIdCount assert j == len(data) return struct.unpack("=" + "16s" * transIdCount, data[i:j]) elif command == _MESSAGE_KEEPALIVE: self.__s.sendall(term_to_binary(OtpErlangAtom("keepalive"))) assert j >= len(data) data = data[j:] if len(data) > 0: IN, OUT, EXCEPT = select.select([self.__s],[],[],0) if len(IN) == 0: continue else: assert False ready = False while ready == False: IN, OUT, EXCEPT = select.select([self.__s],[],[self.__s]) if len(EXCEPT) > 0: return None if len(IN) > 0: ready = True while ready == True: fragment = self.__s.recv(self.__size) data += fragment ready = (len(fragment) == self.__size) if ready: IN, OUT, EXCEPT = select.select([self.__s],[],[],0) ready == (len(IN) > 0) if len(data) == 0: return None # socket was closed