master
yumoqing 2023-09-22 13:53:32 +08:00
parent 03c90f6bbb
commit 7ec7e69f4e
4 changed files with 124 additions and 15 deletions

View File

@ -46,18 +46,20 @@ class ConfiguredServer(AppLogger):
await auth.setupAuth(self.app)
return self.app
def run(self):
def run(self, port=None):
config = getConfig()
self.configPath(config)
a = TmpFileRecord()
ssl_context = None
if port is None:
port = config.website.port or 8080
if config.website.ssl:
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.load_cert_chain(config.website.ssl.crtfile,
config.website.ssl.keyfile)
web.run_app(self.init_auth(),host=config.website.host or '0.0.0.0',
port=config.website.port or 8080,
port=port,
ssl_context=ssl_context)
def configPath(self,config):

View File

@ -40,7 +40,7 @@ from appPublic.app_logger import AppLogger
from .baseProcessor import getProcessor
from .xlsxdsProcessor import XLSXDataSourceProcessor
from .websocketProcessor import WebsocketProcessor
from .websocketProcessor import WebsocketProcessor, XtermProcessor
from .sqldsProcessor import SQLDataSourceProcessor
from .functionProcessor import FunctionProcessor
from .proxyProcessor import ProxyProcessor
@ -253,6 +253,7 @@ class ProcessorResource(AppLogger, StaticResource,Url2File):
self.y_env.i18nDict = i18nDICT
self.y_env.terminalType = getClientType(request)
self.y_env.entire_url = partial(self.entireUrl,request)
self.y_env.websocket_url = partial(self.websocketUrl,request)
self.y_env.abspath = self.abspath
self.y_env.request2ns = getArgs
self.y_env.aiohttp_client = client
@ -367,12 +368,25 @@ class ProcessorResource(AppLogger, StaticResource,Url2File):
for word, handlername in self.y_processors:
if fpath.endswith(word):
Klass = getProcessor(handlername)
processor = Klass(path,self)
return processor
try:
processor = Klass(path,self)
return processor
except Exception as e:
print('Exception:',e, 'handlername=', handlername)
return None
return None
def websocketUrl(self, request, url):
url = entireUrl(request, url)
if url.startswith('https'):
return 'wss' + url[5:]
return 'ws' + url[4:]
def entireUrl(self, request, url):
if url.startswith('http://') or url.startswith('https://'):
if url.startswith('http://') or \
url.startswith('https://') or \
url.startswith('ws://') or \
url.startswith('wss://'):
return url
scheme = request.headers.get('X-Forwarded-Scheme') or request.scheme
port = request.headers.get('X-Forwarded-Port') or str(request['port'])

View File

@ -26,7 +26,10 @@ class Url2File:
if len(url) > 0 and url[-1] == '/':
url = url[:-1]
paths = url.split('/')
if url.startswith('http://') or url.startswith('https://'):
if url.startswith('http://') or \
url.startswith('https://') or \
url.startswith('ws://') or \
url.startswith('wss://'):
paths = paths[3:]
f = os.path.join(self.path,*paths)
real_path = os.path.abspath(f)

View File

@ -1,31 +1,121 @@
import asyncio
import aiohttp
import json
import codecs
from aiohttp import web
from .baseProcessor import PythonScriptProcessor
import aiohttp_cors
from appPublic.sshx import SSHNode
from .baseProcessor import BaseProcessor, PythonScriptProcessor
class XtermProcessor(BaseProcessor):
@classmethod
def isMe(self,name):
return name=='xterm'
async def ws_2_process(self, ws):
async for msg in ws:
if msg.type == aiohttp.WSMsgType.TEXT:
self.p_obj.stdin.write(msg.data)
elif msg.type == aiohttp.WSMsgType.ERROR:
print('ws connection closed with exception %s' % ws.exception())
return
async def process_2_ws(self, ws):
while self.running:
x = await self.p_obj.stdout.read(1024)
await self.ws_sendstr(ws, x)
async def datahandle(self,request):
await self.path_call(request)
async def path_call(self, request, params={}):
await self.set_run_env(request)
lenv = self.run_ns.copy()
lenv.update(params)
del lenv['request']
ws = web.WebSocketResponse()
await ws.prepare(request)
await self.create_process()
self.ws_sendstr(ws, 'Welcom to sshclient')
r1 = self.ws_2_process(ws)
r2 = self.process_2_ws(ws)
await asyncio.gather(r1,r2)
self.retResponse = ws
return ws
def get_login_info(self):
with codecs.open(self.real_path, 'r', 'utf-8') as f:
self.login_info = json.load(f)
print(f'{self.login_info=}')
async def create_process(self):
# id = lenv['params_kw'].get('termid')
self.get_login_info()
host = self.login_info['host']
port = self.login_info.get('port', 22)
username = self.login_info.get('username', 'root')
password = self.login_info.get('password',None)
self.sshnode = SSHNode(host, username=username,
password=password,
port=port)
await self.sshnode.connect()
self.p_obj = await self.sshnode._process('bash',
term_type='vt100',
term_size=(80, 24),
encoding='utf-8')
self.running = True
async def ws_sendstr(self, ws:web.WebSocketResponse, s:str):
data = {
"type":1,
"data":s
}
await ws.send_str(json.dumps(data))
def close_process(self):
self.sshnode.close()
self.p_obj.close()
class WebsocketProcessor(PythonScriptProcessor):
@classmethod
def isMe(self,name):
return name=='ws'
async def ws_sendstr(self, ws:web.WebSocketResponse, s:str):
data = {
"type":1,
"data":s
}
await ws.send_str(json.dumps(data))
async def path_call(self, request,params={}):
print('1----------------------------------')
await self.set_run_env(request)
lenv = self.run_ns.copy()
lenv.update(params)
del lenv['request']
print('2----------------------------------')
txt = self.loadScript(self.real_path)
exec(txt,lenv,lenv)
func = lenv['myfunc']
print('3----------------------------------')
ws = web.WebSocketResponse()
await ws.prepare(request)
print('4----------------------------------', aiohttp.WSMsgType.TEXT)
await self.ws_sendstr(ws, 'Welcome to websock')
async for msg in ws:
if msg.type == aiohttp/WSMsgType.TEXT:
if msg.data == 'close':
await ws.close()
else:
lenv['ws_data'] = msg.data
resp = await func(request,**lenv)
await ws.send_str(resp)
if msg.type == aiohttp.WSMsgType.TEXT:
print('msg=:', msg)
lenv['ws_data'] = msg.data
# resp = await func(request,**lenv)
await self.ws_sendstr(ws, msg.data)
print('msg.data=', msg.data)
elif msg.type == aiohttp.WSMsgType.ERROR:
print('ws connection closed with exception %s' % ws.exception())
else:
print('datatype error', msg.type)
print('5----------------------------------')
self.retResponse = ws
await ws.close()
return ws