diff --git a/ahserver/filestorage.py b/ahserver/filestorage.py index 966859a..cc20731 100644 --- a/ahserver/filestorage.py +++ b/ahserver/filestorage.py @@ -101,12 +101,13 @@ class FileStorage: root = self.root if userid: root += f'/{userid}' - path = os.path.abspath(os.path.join(root, + path = os.path.join(root, str(v % paths[0]), str(v % paths[1]), str(v % paths[2]), - str(v % paths[3]), - name)) + str(v % paths[3])) + _mkdir(path) + path = os.path.join(path, name) return path def remove(self, path): @@ -118,6 +119,29 @@ class FileStorage: except Exception as e: exception(f'{path=}, {p=} remove error') + async def streaming_read(self, request, webpath, buf_size=8096): + fp = self.realPath(webpath) + stats = os.stat(fp) + startpos = 0 + endpos = stats.st_size + range = request.headers.get('Range') + if range: + range = range.split('=')[-1] + s,e = range.split('-') + if s: + startpos = int(s) + if e: + endpos = int(e) + debug(f'filesize={stats.st_size}, {startpos=}, {endpos=}') + async with aiofiles.open(fp, 'rb') as f: + if startpos > 0: + await f.seek(startpos) + pos = startpos + while pos < endpos: + b = await f.read(buf_size) + yield b + pos += len(b) + async def save(self,name,read_data, userid=None): p = self._name2path(name, userid=userid) fpath = p[len(self.root):] diff --git a/ahserver/globalEnv.py b/ahserver/globalEnv.py index 7143fca..81774d2 100644 --- a/ahserver/globalEnv.py +++ b/ahserver/globalEnv.py @@ -314,6 +314,7 @@ def initEnv(): g.partial = partial g.StreamHttpClient = StreamHttpClient g.server_error = server_error + g.FileStorage = FileStorage def set_builtins(): all_builtins = [ i for i in dir(builtins) if not i.startswith('_')] diff --git a/ahserver/xtermProcessor.py b/ahserver/xtermProcessor.py index 5a17546..7861aa1 100644 --- a/ahserver/xtermProcessor.py +++ b/ahserver/xtermProcessor.py @@ -25,6 +25,10 @@ class XtermProcessor(PythonScriptProcessor): async for msg in ws: if msg.type == aiohttp.WSMsgType.TEXT: data = DictObject(**json.loads(msg.data)) + if data.type == 'close': + debug(f'accept client close request, close the ws') + self.running = False + return if data.type == 'input': self.p_obj.stdin.write(data.data) elif data.type == 'heartbeat':