From 45a29a276b9a3474c73f8e7ade8f772effeec572 Mon Sep 17 00:00:00 2001 From: Ciro Date: Mon, 31 Oct 2022 20:51:16 -0300 Subject: [PATCH] fixed try_end, removed use of uWebSockets/capi/Makefile --- examples/file_stream.py | 4 ++-- examples/helpers/static.py | 7 +++---- examples/helpers/static_aiofile.py | 4 ++-- examples/helpers/static_aiofiles.py | 4 ++-- examples/static_files.py | 4 ++-- setup.py | 19 ++++++++----------- src/socketify/native/Makefile | 22 ++++++++++++++++++++-- src/socketify/socketify.py | 12 +++++++----- src/socketify/uWebSockets | 2 +- 9 files changed, 47 insertions(+), 31 deletions(-) diff --git a/examples/file_stream.py b/examples/file_stream.py index 1904842..2644671 100644 --- a/examples/file_stream.py +++ b/examples/file_stream.py @@ -8,8 +8,8 @@ from os import path mimetypes.init() async def home(res, req): - #there is also a helper called static with an send_file method see static_files.py for examples of usage - #here is an sample implementation, a more complete one is in static.send_file + #there is also a helper called static with an sendfile method see static_files.py for examples of usage + #here is an sample implementation, a more complete one is in static.sendfile filename = "./public/media/flower.webm" #read headers before the first await diff --git a/examples/helpers/static.py b/examples/helpers/static.py index ba33843..5ccc09b 100644 --- a/examples/helpers/static.py +++ b/examples/helpers/static.py @@ -7,7 +7,7 @@ mimetypes.init() # We have an version of this using aiofile and aiofiles # This is an sync version without any dependencies is normally much faster in CPython and PyPy3 # In production we highly recomend to use CDN like CloudFlare or/and NGINX or similar for static files -async def send_file(res, req, filename): +async def sendfile(res, req, filename): #read headers before the first await if_modified_since = req.get_header('if-modified-since') range_header = req.get_header('range') @@ -62,7 +62,6 @@ async def send_file(res, req, filename): #tells the browser that we support range res.write_header(b'Accept-Ranges', b'bytes') res.write_header(b'Content-Range', 'bytes %d-%d/%d' % (start, end, total_size)) - pending_size = size #keep sending until abort or done while not res.aborted: @@ -95,11 +94,11 @@ def static_route(app, route, directory): if url.startswith("/"): url = url[1::] filename = path.join(path.realpath(directory), url) - + if not in_directory(filename, directory): res.write_status(404).end_without_body() return - res.run_async(send_file(res, req, filename)) + res.run_async(sendfile(res, req, filename)) if route.startswith("/"): route = route[1::] app.get("%s/*" % route, route_handler) \ No newline at end of file diff --git a/examples/helpers/static_aiofile.py b/examples/helpers/static_aiofile.py index 13a17e4..9d4195d 100644 --- a/examples/helpers/static_aiofile.py +++ b/examples/helpers/static_aiofile.py @@ -6,7 +6,7 @@ from os import path mimetypes.init() # In production we highly recomend to use CDN like CloudFlare or/and NGINX or similar for static files -async def send_file(res, req, filename): +async def sendfile(res, req, filename): #read headers before the first await if_modified_since = req.get_header('if-modified-since') range_header = req.get_header('range') @@ -99,7 +99,7 @@ def static_route(app, route, directory): if not in_directory(filename, directory): res.write_status(404).end_without_body() return - res.run_async(send_file(res, req, filename)) + res.run_async(sendfile(res, req, filename)) if route.startswith("/"): route = route[1::] app.get("%s/*" % route, route_handler) \ No newline at end of file diff --git a/examples/helpers/static_aiofiles.py b/examples/helpers/static_aiofiles.py index eeb77f3..884f8f6 100644 --- a/examples/helpers/static_aiofiles.py +++ b/examples/helpers/static_aiofiles.py @@ -6,7 +6,7 @@ from os import path mimetypes.init() # In production we highly recomend to use CDN like CloudFlare or/and NGINX or similar for static files -async def send_file(res, req, filename): +async def sendfile(res, req, filename): #read headers before the first await if_modified_since = req.get_header('if-modified-since') range_header = req.get_header('range') @@ -99,7 +99,7 @@ def static_route(app, route, directory): if not in_directory(filename, directory): res.write_status(404).end_without_body() return - res.run_async(send_file(res, req, filename)) + res.run_async(sendfile(res, req, filename)) if route.startswith("/"): route = route[1::] app.get("%s/*" % route, route_handler) \ No newline at end of file diff --git a/examples/static_files.py b/examples/static_files.py index 29d166f..0510ad9 100644 --- a/examples/static_files.py +++ b/examples/static_files.py @@ -31,7 +31,7 @@ from socketify import App from helpers.static import static_route -from helpers.static import send_file +from helpers.static import sendfile app = App() @@ -40,7 +40,7 @@ app = App() #send home page index.html async def home(res, req): #sends the whole file with 304 and bytes range support - await send_file(res, req, "./public/index.html") + await sendfile(res, req, "./public/index.html") app.get("/", home) diff --git a/setup.py b/setup.py index 5c9ee4a..5700a88 100644 --- a/setup.py +++ b/setup.py @@ -18,11 +18,10 @@ import subprocess _ROOT = pathlib.Path(__file__).parent -UWS_CAPI_DIR = str(_ROOT / "build" / "uWebSockets" / "capi") -UWS_LIB_PATH = str(_ROOT / "build" / "uWebSockets" / "capi" / "libuwebsockets.so") +UWS_LIB_PATH = str(_ROOT / "build" / "native" / "libuwebsockets.so") UWS_DIR = str(_ROOT / "src" / "socketify" /"uWebSockets") UWS_BUILD_DIR = str(_ROOT / "build" /"uWebSockets") -UWS_LIB_OUTPUT = str(_ROOT / "src" / "socketify" / "libuwebsockets.so") +UWS_LIB_OUTPUT = str(_ROOT / "src" / "socketify" / "native" / "libuwebsockets.so") NATIVE_CAPI_DIR = str(_ROOT / "build" / "native") @@ -37,7 +36,8 @@ NATIVE_LIB_OUTPUT = str(_ROOT / "src" / "socketify" / "native"/ "libsocketify.so class Prepare(sdist): def run(self): super().run() - + + class Makefile(build_ext): def run(self): env = os.environ.copy() @@ -46,16 +46,13 @@ class Makefile(build_ext): shutil.rmtree(UWS_BUILD_DIR) shutil.copytree(UWS_DIR, UWS_BUILD_DIR) - subprocess.run(["make", "shared"], cwd=UWS_CAPI_DIR, env=env, check=True) - shutil.move(UWS_LIB_PATH, UWS_LIB_OUTPUT) - - if os.path.exists(NATIVE_CAPI_DIR): shutil.rmtree(NATIVE_CAPI_DIR) shutil.copytree(NATIVE_DIR, NATIVE_CAPI_DIR) - subprocess.run(["make"], cwd=NATIVE_CAPI_DIR, env=env, check=True) + subprocess.run(["make", "shared"], cwd=NATIVE_CAPI_DIR, env=env, check=True) shutil.move(NATIVE_LIB_PATH, NATIVE_LIB_OUTPUT) + shutil.move(UWS_LIB_PATH, UWS_LIB_OUTPUT) super().run() @@ -86,8 +83,8 @@ setuptools.setup( package_dir={"": "src"}, package_data={"": ['./*.so', './uWebSockets/*','./uWebSockets/*/*','./uWebSockets/*/*/*', './native/*','./native/*/*','./native/*/*/*']}, python_requires=">=3.7", - install_requires=["cffi>=1.0.0"], + install_requires=["cffi>=1.0.0", "setuptools>=60.0.0"], has_ext_modules=lambda: True, - cmdclass={'sdist': Prepare,'build_ext': Makefile}, + cmdclass={'sdist': Prepare, 'build_ext': Makefile}, include_package_data=True ) \ No newline at end of file diff --git a/src/socketify/native/Makefile b/src/socketify/native/Makefile index 0fdd6b1..8db0dff 100644 --- a/src/socketify/native/Makefile +++ b/src/socketify/native/Makefile @@ -1,5 +1,23 @@ LIBRARY_NAME := libsocketify +UWS_LIBRARY_NAME := libuwebsockets + +clean: + cd ../uWebSockets/uSockets && rm -f *.o $(LIBRARY_NAME).a $(LIBRARY_NAME).so $(UWS_LIBRARY_NAME).a $(UWS_LIBRARY_NAME).so + cd ../uWebSockets/ && rm -f *.o $(LIBRARY_NAME).a $(LIBRARY_NAME).so $(UWS_LIBRARY_NAME).a $(UWS_LIBRARY_NAME).so + rm -f *.o $(LIBRARY_NAME).a $(LIBRARY_NAME).so $(UWS_LIBRARY_NAME).a $(UWS_LIBRARY_NAME).so + +shared: + + $(MAKE) clean + + cd ../uWebSockets/uSockets && $(CC) -pthread -DLIBUS_USE_OPENSSL -DLIBUS_USE_LIBUV -std=c11 -Isrc -flto -fPIC -O3 -c src/*.c src/eventing/*.c src/crypto/*.c + cd ../uWebSockets/uSockets && $(CXX) -std=c++17 -flto -fPIC -O3 -c src/crypto/*.cpp + cd ../uWebSockets/uSockets && $(AR) rvs uSockets.a *.o + + $(CXX) -c -O3 -std=c++17 -lz -luv -flto -fPIC -I ../uWebSockets/src -I ../uWebSockets/uSockets/src ../uWebSockets/capi/$(UWS_LIBRARY_NAME).cpp + $(CXX) -shared -o $(UWS_LIBRARY_NAME).so $(UWS_LIBRARY_NAME).o ../uWebSockets/uSockets/uSockets.a -fPIC -lz -luv -lssl -lcrypto -default: $(CC) -c -O3 -luv -flto -fPIC -I ./src ./src/$(LIBRARY_NAME).c - $(CC) -shared -o $(LIBRARY_NAME).so $(LIBRARY_NAME).o -luv \ No newline at end of file + $(CC) -shared -o $(LIBRARY_NAME).so $(LIBRARY_NAME).o -luv + + rm -f *.o \ No newline at end of file diff --git a/src/socketify/socketify.py b/src/socketify/socketify.py index 25d5b40..6a783d5 100644 --- a/src/socketify/socketify.py +++ b/src/socketify/socketify.py @@ -225,7 +225,7 @@ void uws_req_for_each_header(uws_req_t *res, uws_get_headers_server_handler hand """) -library_path = os.path.join(os.path.dirname(__file__), "libuwebsockets.so") +library_path = os.path.join(os.path.dirname(__file__), "native", "libuwebsockets.so") lib = ffi.dlopen(library_path) @ffi.callback("void(const char *, size_t, const char *, size_t, void *)") @@ -583,9 +583,11 @@ class AppResponse: def send_chunk(self, buffer, total_size): self._chunkFuture = self.loop.create_future() self._lastChunkOffset = 0 + def is_aborted(self): self.aborted = True try: + print("aborted!", self._chunkFuture.done()) if not self._chunkFuture.done(): self._chunkFuture.set_result((False, True)) #if aborted set to done True and ok False except: @@ -650,10 +652,10 @@ class AppResponse: lib.uws_res_override_write_offset(self.SSL, self.res, ffi.cast("uintmax_t", offset)) return self - def try_end(self, message, total_size, close_connection=False): + def try_end(self, message, total_size, end_connection=False): try: if self.aborted: - return (False, False) + return (False, True) if self._write_jar != None: self.write_header("Set-Cookie", self._write_jar.output(header="")) self._write_jar = None @@ -662,11 +664,11 @@ class AppResponse: elif isinstance(message, bytes): data = message else: - return (False, False) + return (False, True) result = lib.uws_res_try_end(self.SSL, self.res, data, len(data),ffi.cast("uintmax_t", total_size), 1 if end_connection else 0) return (bool(result.ok), bool(result.has_responded)) except: - return (False, False) + return (False, True) def cork_end(self, message, end_connection=False): self.cork(lambda res: res.end(message, end_connection)) diff --git a/src/socketify/uWebSockets b/src/socketify/uWebSockets index a9a2484..d38dbd8 160000 --- a/src/socketify/uWebSockets +++ b/src/socketify/uWebSockets @@ -1 +1 @@ -Subproject commit a9a248486dcd4883dfac4456658080ca33059cb2 +Subproject commit d38dbd88348d42292f5c2c4ab7daf9b5aa1bb657