async def _login(self, iteration=0): """Reads challenge from line, generate response and check if everything is okay""" challenge = await self._getblock() response = self._challenge_response(challenge) await self._putblock(response) prompt = await self._getblock() prompt = prompt.strip() if len(prompt) == 0: # Empty response, server is happy pass elif prompt == MSG_OK: pass elif prompt.startswith(MSG_INFO): logger.info("%s" % prompt[1:]) elif prompt.startswith(MSG_ERROR): logger.error(prompt[1:]) raise DatabaseError(prompt[1:]) elif prompt.startswith(MSG_REDIRECT): # a redirect can contain multiple redirects, for now we only use # the first redirect = prompt.split()[0][1:].split(":") if redirect[1] == "merovingian": logger.debug("restarting authentication") if iteration <= 10: await self._login(iteration=iteration + 1) else: raise OperationalError("maximal number of redirects " "reached (10)") elif redirect[1] == "monetdb": self.hostname = redirect[2][2:] self.port, self.database = redirect[3].split("/") self.port = int(self.port) logger.info("redirect to monetdb://%s:%s/%s" % (self.hostname, self.port, self.database)) self.writer.close() await self.writer.wait_closed() self.connect( hostname=self.hostname, port=self.port, username=self.username, password=self.password, database=self.database, language=self.language, ) else: raise ProgrammingError("unknown redirect: %s" % prompt) else: raise ProgrammingError("unknown state: %s" % prompt)
def _response(self): r = self._mapi._getblock() if not r or len(r) == 0: pass # nothing to do elif r.startswith("{") and len(self._buffer) == 0: self._buffer = r else: raise OperationalError( "bad response when connecting to the profiler: %s" % r)
def _getbytes(self, bytes_): """Read an amount of bytes from the socket""" result = BytesIO() count = bytes_ while count > 0: recv = self.socket.recv(count) if len(recv) == 0: raise OperationalError("Server closed connection") count -= len(recv) result.write(recv) return result.getvalue()
async def _getbytes(self, bytes_): """Read an amount of bytes from the socket""" result = BytesIO() count = bytes_ while count > 0: # lock = asyncio.Lock() # async with lock: recv = await self.reader.read(count) if len(recv) == 0: raise OperationalError("Server closed connection") count -= len(recv) result.write(recv) return result.getvalue()
def parse_statusline(line): """ parses a sabdb format status line. Support v1 and v2. """ if line.startswith("="): line = line[1:] if not line.startswith('sabdb:'): raise OperationalError('wrong result received') code, prot_version, rest = line.split(":", 2) if prot_version not in ["1", "2"]: raise InterfaceError("unsupported sabdb protocol") else: prot_version = int(prot_version) subparts = rest.split(',') sub_iter = iter(subparts) info = {} info['name'] = next(sub_iter) info['path'] = next(sub_iter) info['locked'] = next(sub_iter) == "1" info['state'] = int(next(sub_iter)) info['scenarios'] = next(sub_iter).split("'") if prot_version == 1: next(sub_iter) info['start_counter'] = int(next(sub_iter)) info['stop_counter'] = int(next(sub_iter)) info['crash_counter'] = int(next(sub_iter)) info['avg_uptime'] = int(next(sub_iter)) info['max_uptime'] = int(next(sub_iter)) info['min_uptime'] = int(next(sub_iter)) info['last_crash'] = int(next(sub_iter)) info['last_start'] = int(next(sub_iter)) if prot_version > 1: info['last_stop'] = int(next(sub_iter)) info['crash_avg1'] = next(sub_iter) == "1" info['crash_avg10'] = float(next(sub_iter)) info['crash_avg30'] = float(next(sub_iter)) return info
def isempty(result): """ raises an exception if the result is not empty""" if result != "": raise OperationalError(result) else: return True