def open(self): self.src_addr = self.get_client_endpoint() LOG.info('Connected from {}:{}'.format(*self.src_addr)) try: # Get id from query argument from minion_id = self.get_value('id') LOG.debug(f"############ minion id: {minion_id}") minion = MINIONS.get(minion_id) if not minion: self.close(reason='Websocket failed.') return minion_obj = minion.get('minion', None) if minion_obj: # minions[minion_id]["minion"] = None self.set_nodelay(True) minion_obj.set_handler(self) self.minion_ref = weakref.ref(minion_obj) self.loop.add_handler(minion_obj.fd, minion_obj, IOLoop.READ) else: self.close(reason='Websocket authentication failed.') except (tornado.web.MissingArgumentError, InvalidValueError) as err: self.close(reason=str(err))
def on_close(self): LOG.info('Disconnected from {}:{}'.format(*self.src_addr)) if not self.close_reason: self.close_reason = 'client disconnected' minion = self.minion_ref() if self.minion_ref else None if minion: minion.close(reason=self.close_reason)
def create_minion(self, args): ssh_endpoint = args[:2] LOG.info('Connecting to {}:{}'.format(*ssh_endpoint)) term = self.get_argument('term', '') or 'xterm' shell_channel = self.ssh_term_client.invoke_shell(term=term) shell_channel.setblocking(0) minion = Minion(self.loop, self.ssh_term_client, shell_channel, ssh_endpoint) minion.encoding = conf.encoding if conf.encoding else self.get_server_encoding( self.ssh_term_client) return minion
def close(self, reason=None): if self.closed: return self.closed = True LOG.info(f'Closing minion {self.id}: {reason}') if self.handler: self.loop.remove_handler(self.fd) self.handler.close(reason=reason) self.chan.close() self.ssh.close() LOG.info('Connection to {}:{} lost'.format(*self.dst_addr)) clear_minion(self) LOG.debug(MINIONS)
def main(): LOG.info(f'Gru mode: {conf.mode}') loop = tornado.ioloop.IOLoop.current() app = Term1nal(loop=loop) ssl_ctx = get_ssl_context(conf) server_settings = dict( xheaders=True, max_body_size=6000 * 1024 * 1024, # 6G ) app.listen(conf.port, conf.address, **server_settings) if ssl_ctx: server_settings.update(ssl_options=ssl_ctx) app.listen(conf.ssl_port, conf.host, **server_settings) loop.start()
async def get(self): chunk_size = 1024 * 1024 * 1 # 1 MiB remote_file_path = self.get_value("filepath", arg_type="query") filename = os.path.basename(remote_file_path) LOG.debug(remote_file_path) try: self.exec_remote_cmd(cmd=f'cat {remote_file_path}', probe_cmd=f'ls {remote_file_path}') except tornado.web.HTTPError: self.write(f'Not found: {remote_file_path}') await self.finish() return self.set_header("Content-Type", "application/octet-stream") self.set_header("Accept-Ranges", "bytes") self.set_header("Content-Disposition", f"attachment; filename={filename}") while True: chunk = self.channel.recv(chunk_size) if not chunk: break try: # Write the chunk to response self.write(chunk) # Send the chunk to client await self.flush() except tornado.iostream.StreamClosedError: break finally: del chunk await tornado.web.gen.sleep(0.000000001) # 1 nanosecond self.ssh_transport_client.close() try: await self.finish() except tornado.iostream.StreamClosedError as err: LOG.error(err) LOG.debug("Maybe user cancelled download") LOG.info(f"Download ended: {remote_file_path}")
def prepare(self): LOG.info("In NotFoundHandler") raise tornado.web.HTTPError(status_code=404, reason="Oops!")