fix docs, add res.send and res.cork_send

pull/75/head
Ciro 2023-01-07 08:47:50 -03:00
rodzic e5bf0b201f
commit 14ab02f5f3
8 zmienionych plików z 406 dodań i 157 usunięć

Wyświetl plik

@ -34,7 +34,7 @@ With no precedents websocket performance and an really fast HTTP server that can
- [Templates](templates.md)
- [GraphiQL](graphiql.md)
- [WebSockets and Backpressure](websockets-backpressure.md)
- [SSL](ssl.md)
- [Plugins / Extensions](extensions.md)
- [SSL](ssl.md)
- [CLI, ASGI and WSGI](cli.md)
- [API Reference](api.md)

Wyświetl plik

@ -12,7 +12,7 @@
- [Templates](templates.md)
- [GraphiQL](graphiql.md)
- [WebSockets and Backpressure](websockets-backpressure.md)
- [SSL](ssl.md)
- [Plugins / Extensions](extensions.md)
- [SSL](ssl.md)
- [CLI, ASGI and WSGI](cli.md)
- [API Reference](api.md)

Wyświetl plik

@ -3,6 +3,7 @@
class App:
def __init__(self, options=None):
def router(self, prefix: str="", *middlewares):
def register(self, extension):
def template(self, template_engine):
def json_serializer(self, json_serializer):
@ -55,6 +56,8 @@ class AppResponse:
def get_remote_address(self):
def get_proxied_remote_address_bytes(self):
def get_proxied_remote_address(self):
def cork_send(self, message: any, content_type: str = b'text/plain', status : str | bytes | int = b'200 OK', headers=None, end_connection=False):
def send(self, message: any, content_type: str = b'text/plain', status : str | bytes | int = b'200 OK', headers=None, end_connection=False):
def end(self, message, end_connection=False):
def pause(self):
def resume(self):

Wyświetl plik

@ -7,8 +7,15 @@ This section is to show the basics of `AppResponse` and `AppRequest`
`res.write(message)` were message can be String, bytes or an Object that can be converted to json, send the message to the response without ending.
`res.cork_end(message, end_connection=False)` or `res.end(message, end_connection=False)` were message can be String, bytes or an Object that can be converted to json, send the message to the response and end the response.
The above `res.end()` or `res.cork_end()` call will actually call three separate send functions; res.write_status, res.write_header and whatever it does itself. By wrapping the call in `res.cork` or `res.cork_end` you make sure these three send functions are efficient and only result in one single send syscall and one single SSL block if using SSL.
`res.send(message, content_type=b'text/plain, status=b'200 OK', headers=None, end_connection=False)` and `res.cork_send(message, content_type=b'text/plain', status=b'200 OK', headers=None, end_connection=False)`
combines `res.write_status()`, `res.write_headers()`, and `res.end()` in a way that is easier to use, if you want to send all in one call just using named parameters. Headers can receive any iterator of iterators/tuple like `iter(tuple(str, str))` where the first value is the header name and the following the value, using `res.cork_send` will make sure to send all the
data in a corked state.
Using `res.write_continue()` writes HTTP/1.1 100 Continue as response
@ -51,9 +58,25 @@ def not_found(res, req):
res.write_status(404).end("Not Found")
def ok(res, req):
res.write_status("200 OK").end("Not Found")
res.write_status("200 OK").end("OK")
```
### Using send
```python
def not_found(res, req):
res.send("Not Found", status=404)
def ok(res, req):
res.send("OK", status="200 OK")
def json(res, req):
res.send({"Hello", "World!"})
def with_headers(res, req):
res.send({"Hello": "World!"}, headers=(("X-Rate-Limit-Remaining", "10"), (b'Another-Headers', b'Value')))
```
### Check the URL or Method
`req.get_full_url()` will return the path with query string
`req.get_url()` will return the path without query string

Wyświetl plik

@ -52,4 +52,4 @@ def extension(request, response, ws):
app.register(extension)
```
### Next [CLI, ASGI and WSGI](cli.md)
### Next [SSL](ssl.md)

Wyświetl plik

@ -31,4 +31,4 @@ class AppOptions:
ssl_ciphers: str = None,
ssl_prefer_low_memory_usage: int = 0
```
### Next [CLI Reference](cli.md)
### Next [CLI, ASGI and WSGI](cli.md)

Wyświetl plik

@ -54,6 +54,7 @@ def uws_websocket_factory_drain_handler(ws, user_data):
if inspect.iscoroutinefunction(handler):
if dispose:
async def wrapper(app, instances, handler, ws):
try:
await handler(ws)
@ -74,6 +75,7 @@ def uws_websocket_factory_drain_handler(ws, user_data):
"Uncaught Exception: %s" % str(err)
) # just log in console the error to call attention
@ffi.callback("void(uws_websocket_t*, void*)")
def uws_websocket_drain_handler(ws, user_data):
if user_data != ffi.NULL:
@ -90,8 +92,16 @@ def uws_websocket_drain_handler(ws, user_data):
"Uncaught Exception: %s" % str(err)
) # just log in console the error to call attention
@ffi.callback("void(uws_websocket_t*, const char *, size_t, int, int, void*)")
def uws_websocket_factory_subscription_handler(ws, topic_name, topic_name_length, new_number_of_subscriber, old_number_of_subscriber, user_data):
def uws_websocket_factory_subscription_handler(
ws,
topic_name,
topic_name_length,
new_number_of_subscriber,
old_number_of_subscriber,
user_data,
):
if user_data != ffi.NULL:
handlers, app = ffi.from_handle(user_data)
instances = app._ws_factory.get(app, ws)
@ -103,22 +113,57 @@ def uws_websocket_factory_subscription_handler(ws, topic_name, topic_name_length
else:
topic = ffi.unpack(topic_name, topic_name_length).decode("utf-8")
handler = handlers.subscription
if inspect.iscoroutinefunction(handler):
if dispose:
async def wrapper(app, instances, handler, ws, topic, new_number_of_subscriber, old_number_of_subscriber):
async def wrapper(
app,
instances,
handler,
ws,
topic,
new_number_of_subscriber,
old_number_of_subscriber,
):
try:
await handler(ws, topic, new_number_of_subscriber, old_number_of_subscriber)
await handler(
ws,
topic,
new_number_of_subscriber,
old_number_of_subscriber,
)
finally:
app._ws_factory.dispose(instances)
app.run_async(wrapper(app, instances, handler, ws, topic, int(new_number_of_subscriber), int(old_number_of_subscriber)))
app.run_async(
wrapper(
app,
instances,
handler,
ws,
topic,
int(new_number_of_subscriber),
int(old_number_of_subscriber),
)
)
else:
app.run_async(handler(ws, topic, int(new_number_of_subscriber), int(old_number_of_subscriber)))
app.run_async(
handler(
ws,
topic,
int(new_number_of_subscriber),
int(old_number_of_subscriber),
)
)
else:
handler(ws, topic, int(new_number_of_subscriber), int(old_number_of_subscriber))
handler(
ws,
topic,
int(new_number_of_subscriber),
int(old_number_of_subscriber),
)
if dispose:
app._ws_factory.dispose(instances)
except Exception as err:
@ -128,8 +173,16 @@ def uws_websocket_factory_subscription_handler(ws, topic_name, topic_name_length
"Uncaught Exception: %s" % str(err)
) # just log in console the error to call attention
@ffi.callback("void(uws_websocket_t*, const char *, size_t, int, int, void*)")
def uws_websocket_subscription_handler(ws, topic_name, topic_name_length, new_number_of_subscriber, old_number_of_subscriber, user_data):
def uws_websocket_subscription_handler(
ws,
topic_name,
topic_name_length,
new_number_of_subscriber,
old_number_of_subscriber,
user_data,
):
if user_data != ffi.NULL:
try:
handlers, app = ffi.from_handle(user_data)
@ -142,9 +195,21 @@ def uws_websocket_subscription_handler(ws, topic_name, topic_name_length, new_nu
topic = ffi.unpack(topic_name, topic_name_length).decode("utf-8")
if inspect.iscoroutinefunction(handler):
app.run_async(handler(ws, topic, int(new_number_of_subscriber), int(old_number_of_subscriber)))
app.run_async(
handler(
ws,
topic,
int(new_number_of_subscriber),
int(old_number_of_subscriber),
)
)
else:
handler(ws, topic, int(new_number_of_subscriber), int(old_number_of_subscriber))
handler(
ws,
topic,
int(new_number_of_subscriber),
int(old_number_of_subscriber),
)
except Exception as err:
logging.error(
"Uncaught Exception: %s" % str(err)
@ -161,6 +226,7 @@ def uws_websocket_factory_open_handler(ws, user_data):
handler = handlers.open
if inspect.iscoroutinefunction(handler):
if dispose:
async def wrapper(app, instances, handler, ws):
try:
await handler(ws)
@ -181,6 +247,7 @@ def uws_websocket_factory_open_handler(ws, user_data):
"Uncaught Exception: %s" % str(err)
) # just log in console the error to call attention
@ffi.callback("void(uws_websocket_t*, void*)")
def uws_websocket_open_handler(ws, user_data):
@ -217,6 +284,7 @@ def uws_websocket_factory_message_handler(ws, message, length, opcode, user_data
handler = handlers.message
if inspect.iscoroutinefunction(handler):
if dispose:
async def wrapper(app, instances, handler, ws, data):
try:
await handler(ws, data)
@ -238,6 +306,7 @@ def uws_websocket_factory_message_handler(ws, message, length, opcode, user_data
"Uncaught Exception: %s" % str(err)
) # just log in console the error to call attention
@ffi.callback("void(uws_websocket_t*, const char*, size_t, uws_opcode_t, void*)")
def uws_websocket_message_handler(ws, message, length, opcode, user_data):
if user_data != ffi.NULL:
@ -280,6 +349,7 @@ def uws_websocket_factory_pong_handler(ws, message, length, user_data):
handler = handlers.pong
if inspect.iscoroutinefunction(handler):
if dispose:
async def wrapper(app, instances, handler, ws, data):
try:
await handler(ws, data)
@ -300,6 +370,8 @@ def uws_websocket_factory_pong_handler(ws, message, length, user_data):
logging.error(
"Uncaught Exception: %s" % str(err)
) # just log in console the error to call attention
@ffi.callback("void(uws_websocket_t*, const char*, size_t, void*)")
def uws_websocket_pong_handler(ws, message, length, user_data):
if user_data != ffi.NULL:
@ -338,6 +410,7 @@ def uws_websocket_factory_ping_handler(ws, message, length, user_data):
handler = handlers.ping
if inspect.iscoroutinefunction(handler):
if dispose:
async def wrapper(app, instances, handler, ws, data):
try:
await handler(ws, data)
@ -359,6 +432,7 @@ def uws_websocket_factory_ping_handler(ws, message, length, user_data):
"Uncaught Exception: %s" % str(err)
) # just log in console the error to call attention
@ffi.callback("void(uws_websocket_t*, const char*, size_t, void*)")
def uws_websocket_ping_handler(ws, message, length, user_data):
if user_data != ffi.NULL:
@ -404,6 +478,7 @@ def uws_websocket_factory_close_handler(ws, code, message, length, user_data):
return
if inspect.iscoroutinefunction(handler):
async def wrapper(app, instances, handler, ws, data, code, dispose):
try:
return await handler(ws, code, data)
@ -414,7 +489,9 @@ def uws_websocket_factory_close_handler(ws, code, message, length, user_data):
if dispose:
app._ws_factory.dispose(instances)
app.run_async(wrapper(app, instances, handler, ws, data, int(code), dispose))
app.run_async(
wrapper(app, instances, handler, ws, data, int(code), dispose)
)
else:
handler(ws, int(code), data)
key = ws.get_user_data_uuid()
@ -428,6 +505,7 @@ def uws_websocket_factory_close_handler(ws, code, message, length, user_data):
"Uncaught Exception: %s" % str(err)
) # just log in console the error to call attention
@ffi.callback("void(uws_websocket_t*, int, const char*, size_t, void*)")
def uws_websocket_close_handler(ws, code, message, length, user_data):
if user_data != ffi.NULL:
@ -447,6 +525,7 @@ def uws_websocket_close_handler(ws, code, message, length, user_data):
return
if inspect.iscoroutinefunction(handler):
async def wrapper(app, handler, ws, data, code, dispose):
try:
return await handler(ws, code, data)
@ -478,13 +557,16 @@ def uws_generic_factory_method_handler(res, req, user_data):
if inspect.iscoroutinefunction(handler):
response.grab_aborted_handler()
if dispose:
async def wrapper(app, instances, handler, response, request):
try:
await handler(response, request)
finally:
app._factory.dispose(instances)
response.run_async(wrapper(app, instances, handler, response, request))
response.run_async(
wrapper(app, instances, handler, response, request)
)
else:
response.run_async(handler(response, request))
else:
@ -498,6 +580,7 @@ def uws_generic_factory_method_handler(res, req, user_data):
if dispose:
app._factory.dispose(instances)
@ffi.callback("void(uws_res_t*, uws_req_t*, uws_socket_context_t*, void*)")
def uws_websocket_factory_upgrade_handler(res, req, context, user_data):
if user_data != ffi.NULL:
@ -510,13 +593,18 @@ def uws_websocket_factory_upgrade_handler(res, req, context, user_data):
if inspect.iscoroutinefunction(handler):
response.grab_aborted_handler()
if dispose:
async def wrapper(app, instances, handler, response, request, context):
async def wrapper(
app, instances, handler, response, request, context
):
try:
await handler(response, request, context)
finally:
app._factadd_done_callbackory.dispose(instances)
response.run_async(wrapper(app, instances, handler, response, request, context))
response.run_async(
wrapper(app, instances, handler, response, request, context)
)
else:
response.run_async(handler(response, request, context))
else:
@ -529,6 +617,7 @@ def uws_websocket_factory_upgrade_handler(res, req, context, user_data):
if dispose:
app._factory.dispose(instances)
@ffi.callback("void(uws_res_t*, uws_req_t*, uws_socket_context_t*, void*)")
def uws_websocket_upgrade_handler_with_extension(res, req, context, user_data):
if user_data != ffi.NULL:
@ -555,6 +644,7 @@ def uws_websocket_upgrade_handler_with_extension(res, req, context, user_data):
response.grab_aborted_handler()
app.trigger_error(err, response, request)
@ffi.callback("void(uws_res_t*, uws_req_t*, uws_socket_context_t*, void*)")
def uws_websocket_upgrade_handler(res, req, context, user_data):
if user_data != ffi.NULL:
@ -610,13 +700,16 @@ def uws_generic_factory_method_handler(res, req, user_data):
response.grab_aborted_handler()
response.grab_aborted_handler()
if dispose:
async def wrapper(app, instances, handler, response, request):
try:
await handler(response, request)
finally:
app._factory.dispose(instances)
response.run_async(wrapper(app, instances, handler, response, request))
response.run_async(
wrapper(app, instances, handler, response, request)
)
else:
response.run_async(handler(response, request))
else:
@ -630,6 +723,7 @@ def uws_generic_factory_method_handler(res, req, user_data):
if dispose:
app._factory.dispose(instances)
@ffi.callback("void(uws_res_t*, uws_req_t*, void*)")
def uws_generic_method_handler_with_extension(res, req, user_data):
if user_data != ffi.NULL:
@ -655,6 +749,7 @@ def uws_generic_method_handler_with_extension(res, req, user_data):
response.grab_aborted_handler()
app.trigger_error(err, response, request)
@ffi.callback("void(uws_res_t*, uws_req_t*, void*)")
def uws_generic_method_handler(res, req, user_data):
if user_data != ffi.NULL:
@ -673,10 +768,10 @@ def uws_generic_method_handler(res, req, user_data):
app.trigger_error(err, response, request)
@ffi.callback("void(struct us_listen_socket_t*, const char*, size_t,int, void*)")
def uws_generic_listen_domain_handler(listen_socket, domain, length, _options, user_data):
def uws_generic_listen_domain_handler(
listen_socket, domain, length, _options, user_data
):
domain = ffi.unpack(domain, length).decode("utf8")
if listen_socket == ffi.NULL:
raise RuntimeError("Failed to listen on domain %s" % domain)
@ -686,12 +781,9 @@ def uws_generic_listen_domain_handler(listen_socket, domain, length, _options, u
app = ffi.from_handle(user_data)
if hasattr(app, "_listen_handler") and hasattr(app._listen_handler, "__call__"):
app.socket = listen_socket
app._listen_handler(
AppListenOptions(
domain=domain,
options=int(_options)
)
)
app._listen_handler(AppListenOptions(domain=domain, options=int(_options)))
@ffi.callback("void(struct us_listen_socket_t*, uws_app_listen_config_t, void*)")
def uws_generic_listen_handler(listen_socket, config, user_data):
if listen_socket == ffi.NULL:
@ -709,7 +801,6 @@ def uws_generic_listen_handler(listen_socket, config, user_data):
pass
app._listen_handler(
None
if config == ffi.NULL
else AppListenOptions(
port=int(config.port),
@ -917,7 +1008,9 @@ class WebSocket:
else:
return False
return bool(lib.uws_ws_is_subscribed(self.app.SSL, self.ws, data, len(data)))
return bool(
lib.uws_ws_is_subscribed(self.app.SSL, self.ws, data, len(data))
)
except:
return False
@ -1007,7 +1100,9 @@ class WebSocket:
data = self.app._json_serializer.dumps(message).encode("utf-8")
return SendStatus(
lib.uws_ws_send_fragment(self.app.SSL, self.ws, data, len(data), compress)
lib.uws_ws_send_fragment(
self.app.SSL, self.ws, data, len(data), compress
)
)
except:
return None
@ -1114,6 +1209,7 @@ class WebSocket:
self.ws = ffi.NULL
self._ptr = ffi.NULL
class AppResponse:
def __init__(self, response, app):
self.res = response
@ -1135,7 +1231,9 @@ class AppResponse:
if not self.aborted:
self.grab_aborted_handler()
self._cork_handler = callback
lib.uws_res_cork(self.app.SSL, self.res, uws_generic_cork_handler, self._ptr)
lib.uws_res_cork(
self.app.SSL, self.res, uws_generic_cork_handler, self._ptr
)
def set_cookie(self, name, value, options):
if options is None:
@ -1351,9 +1449,11 @@ class AppResponse:
def render(self, *args, **kwargs):
if self.app._template:
def render(res):
res.write_header(b'Content-Type', b'text/html')
res.write_header(b"Content-Type", b"text/html")
res.end(self.app._template.render(*args, **kwargs))
self.cork(render)
return self
raise RuntimeError("No registered templated engine")
@ -1404,6 +1504,55 @@ class AppResponse:
except Exception: # invalid utf-8
return None
def cork_send(
self,
message,
content_type: str | bytes = b"text/plain",
status: str | bytes | int = b"200 OK",
headers=None,
end_connection=False,
):
self.cork(
lambda res: res.send(message, content_type, status, headers, end_connection)
)
return self
def send(
self,
message: any,
content_type: str | bytes = b"text/plain",
status: str | bytes | int = b"200 OK",
headers=None,
end_connection=False,
):
if self.aborted:
return self
self.write_status(status)
self.write_header(b"Content-Type", content_type)
if headers is not None:
for name, value in headers:
self.write_header(name, value)
try:
if self._write_jar is not None:
self.write_header("Set-Cookie", self._write_jar.output(header=""))
self._write_jar = None
if isinstance(message, str):
data = message.encode("utf-8")
elif isinstance(message, bytes):
data = message
elif message is None:
self.end_without_body(end_connection)
return self
else:
data = self.app._json_serializer.dumps(message).encode("utf-8")
lib.uws_res_end(
self.app.SSL, self.res, data, len(data), 1 if end_connection else 0
)
finally:
return self
def end(self, message, end_connection=False):
try:
if self.aborted:
@ -1445,7 +1594,11 @@ class AppResponse:
def write_status(self, status_or_status_text):
if not self.aborted:
if isinstance(status_or_status_text, int):
if bool(lib.socketify_res_write_int_status(self.app.SSL, self.res, status_or_status_text)):
if bool(
lib.socketify_res_write_int_status(
self.app.SSL, self.res, status_or_status_text
)
):
return self
raise RuntimeError(
'"%d" Is not an valid Status Code' % status_or_status_text
@ -1456,7 +1609,9 @@ class AppResponse:
elif isinstance(status_or_status_text, bytes):
data = status_or_status_text
else:
data = self.app._json_serializer.dumps(status_or_status_text).encode("utf-8")
data = self.app._json_serializer.dumps(status_or_status_text).encode(
"utf-8"
)
lib.uws_res_write_status(self.app.SSL, self.res, data, len(data))
return self
@ -1485,7 +1640,12 @@ class AppResponse:
else:
value_data = self.app._json_serializer.dumps(value).encode("utf-8")
lib.uws_res_write_header(
self.app.SSL, self.res, key_data, len(key_data), value_data, len(value_data)
self.app.SSL,
self.res,
key_data,
len(key_data),
value_data,
len(value_data),
)
return self
@ -1493,7 +1653,9 @@ class AppResponse:
if not self.aborted:
if self._write_jar is not None:
self.write_header("Set-Cookie", self._write_jar.output(header=""))
lib.uws_res_end_without_body(self.app.SSL, self.res, 1 if end_connection else 0)
lib.uws_res_end_without_body(
self.app.SSL, self.res, 1 if end_connection else 0
)
return self
def write(self, message):
@ -1647,7 +1809,6 @@ class WebSocketFactory:
websocket = WebSocket(None, self.app)
self.factory_queue.append((websocket, True))
def _get_with_extension(self, app, ws):
if len(self.factory_queue) == 0:
websocket = WebSocket(ws, app)
@ -1662,7 +1823,6 @@ class WebSocketFactory:
websocket.ws = ws
return instances
def _get(self, app, ws):
if len(self.factory_queue) == 0:
response = WebSocket(ws, app)
@ -1697,6 +1857,7 @@ class WebSocketFactory:
websocket.got_socket_data = False
self.factory_queue.append(instances)
class RequestResponseFactory:
def __init__(self, app, max_size):
self.factory_queue = []
@ -1825,6 +1986,7 @@ class RequestResponseFactory:
req._method = None
self.factory_queue.append(instances)
class AppRequest:
def __init__(self, request, app):
self.req = request
@ -2049,6 +2211,7 @@ class AppRequest:
self.req = ffi.NULL
self._ptr = ffi.NULL
class AppExtension:
def __init__(self):
self.properties = []
@ -2069,7 +2232,6 @@ class AppExtension:
for (name, property) in self.properties:
setattr(instance, name, property)
def method(self, method: callable):
self.empty = False
self.methods.append((method.__name__, method))
@ -2081,7 +2243,13 @@ class AppExtension:
class App:
def __init__(self, options=None, request_response_factory_max_items=0, websocket_factory_max_items=0, task_factory_max_items=100_000):
def __init__(
self,
options=None,
request_response_factory_max_items=0,
websocket_factory_max_items=0,
task_factory_max_items=100_000,
):
socket_options_ptr = ffi.new("struct us_socket_context_options_t *")
socket_options = socket_options_ptr[0]
self.options = options
@ -2128,10 +2296,9 @@ class App:
self.is_ssl = False
self.SSL = ffi.cast("int", 0)
self.loop = Loop(
lambda loop, context, response: self.trigger_error(context, response, None),
task_factory_max_items
task_factory_max_items,
)
# set async loop to be the last created (is thread_local), App must be one per thread otherwise will use only the lasted loop
@ -2146,8 +2313,13 @@ class App:
self.error_handler = None
self._missing_server_handler = None
if request_response_factory_max_items and request_response_factory_max_items >= 1:
self._factory = RequestResponseFactory(self, request_response_factory_max_items)
if (
request_response_factory_max_items
and request_response_factory_max_items >= 1
):
self._factory = RequestResponseFactory(
self, request_response_factory_max_items
)
else:
self._factory = None
@ -2173,7 +2345,9 @@ class App:
extension(self._request_extension, self._response_extension, self._ws_extension)
if self._factory is not None and (not self._request_extension.empty or not self._response_extension.empty):
if self._factory is not None and (
not self._request_extension.empty or not self._response_extension.empty
):
self._factory.update_extensions()
if self._ws_factory is not None and not self._ws_extension.empty:
self._ws_factory.update_extensions()
@ -2193,7 +2367,9 @@ class App:
self.handlers.append(user_data) # Keep alive handler
if self._factory:
handler = uws_generic_factory_method_handler
elif self._response_extension and (not self._response_extension.empty or not self._request_extension.empty):
elif self._response_extension and (
not self._response_extension.empty or not self._request_extension.empty
):
handler = uws_generic_method_handler_with_extension
else:
handler = uws_generic_method_handler
@ -2212,7 +2388,9 @@ class App:
self.handlers.append(user_data) # Keep alive handler
if self._factory:
handler = uws_generic_factory_method_handler
elif self._response_extension and (not self._response_extension.empty or not self._request_extension.empty):
elif self._response_extension and (
not self._response_extension.empty or not self._request_extension.empty
):
handler = uws_generic_method_handler_with_extension
else:
handler = uws_generic_method_handler
@ -2231,7 +2409,9 @@ class App:
self.handlers.append(user_data) # Keep alive handler
if self._factory:
handler = uws_generic_factory_method_handler
elif self._response_extension and (not self._response_extension.empty or not self._request_extension.empty):
elif self._response_extension and (
not self._response_extension.empty or not self._request_extension.empty
):
handler = uws_generic_method_handler_with_extension
else:
handler = uws_generic_method_handler
@ -2250,7 +2430,9 @@ class App:
self.handlers.append(user_data) # Keep alive handler
if self._factory:
handler = uws_generic_factory_method_handler
elif self._response_extension and (not self._response_extension.empty or not self._request_extension.empty):
elif self._response_extension and (
not self._response_extension.empty or not self._request_extension.empty
):
handler = uws_generic_method_handler_with_extension
else:
handler = uws_generic_method_handler
@ -2269,7 +2451,9 @@ class App:
self.handlers.append(user_data) # Keep alive handler
if self._factory:
handler = uws_generic_factory_method_handler
elif self._response_extension and (not self._response_extension.empty or not self._request_extension.empty):
elif self._response_extension and (
not self._response_extension.empty or not self._request_extension.empty
):
handler = uws_generic_method_handler_with_extension
else:
handler = uws_generic_method_handler
@ -2288,12 +2472,13 @@ class App:
self.handlers.append(user_data) # Keep alive handler
if self._factory:
handler = uws_generic_factory_method_handler
elif self._response_extension and (not self._response_extension.empty or not self._request_extension.empty):
elif self._response_extension and (
not self._response_extension.empty or not self._request_extension.empty
):
handler = uws_generic_method_handler_with_extension
else:
handler = uws_generic_method_handler
lib.uws_app_put(
self.SSL,
self.app,
@ -2308,12 +2493,13 @@ class App:
self.handlers.append(user_data) # Keep alive handler
if self._factory:
handler = uws_generic_factory_method_handler
elif self._response_extension and (not self._response_extension.empty or not self._request_extension.empty):
elif self._response_extension and (
not self._response_extension.empty or not self._request_extension.empty
):
handler = uws_generic_method_handler_with_extension
else:
handler = uws_generic_method_handler
lib.uws_app_head(
self.SSL,
self.app,
@ -2328,12 +2514,13 @@ class App:
self.handlers.append(user_data) # Keep alive handler
if self._factory:
handler = uws_generic_factory_method_handler
elif self._response_extension and (not self._response_extension.empty or not self._request_extension.empty):
elif self._response_extension and (
not self._response_extension.empty or not self._request_extension.empty
):
handler = uws_generic_method_handler_with_extension
else:
handler = uws_generic_method_handler
lib.uws_app_connect(
self.SSL,
self.app,
@ -2348,7 +2535,9 @@ class App:
self.handlers.append(user_data) # Keep alive handler
if self._factory:
handler = uws_generic_factory_method_handler
elif self._response_extension and (not self._response_extension.empty or not self._request_extension.empty):
elif self._response_extension and (
not self._response_extension.empty or not self._request_extension.empty
):
handler = uws_generic_method_handler_with_extension
else:
handler = uws_generic_method_handler
@ -2367,12 +2556,13 @@ class App:
self.handlers.append(user_data) # Keep alive handler
if self._factory:
handler = uws_generic_factory_method_handler
elif self._response_extension and (not self._response_extension.empty or not self._request_extension.empty):
elif self._response_extension and (
not self._response_extension.empty or not self._request_extension.empty
):
handler = uws_generic_method_handler_with_extension
else:
handler = uws_generic_method_handler
lib.uws_app_any(
self.SSL,
self.app,
@ -2583,7 +2773,9 @@ class App:
if self._factory:
native_behavior.upgrade = uws_websocket_factory_upgrade_handler
elif self._response_extension and (not self._response_extension.empty or not self._request_extension.empty):
elif self._response_extension and (
not self._response_extension.empty or not self._request_extension.empty
):
native_behavior.upgrade = uws_websocket_upgrade_handler_with_extension
else:
native_behavior.upgrade = uws_websocket_upgrade_handler
@ -2592,47 +2784,74 @@ class App:
if open_handler:
handlers.open = open_handler
native_behavior.open = uws_websocket_factory_open_handler if self._ws_factory else uws_websocket_open_handler
native_behavior.open = (
uws_websocket_factory_open_handler
if self._ws_factory
else uws_websocket_open_handler
)
else:
native_behavior.open = ffi.NULL
if message_handler:
handlers.message = message_handler
native_behavior.message = uws_websocket_factory_message_handler if self._ws_factory else uws_websocket_message_handler
native_behavior.message = (
uws_websocket_factory_message_handler
if self._ws_factory
else uws_websocket_message_handler
)
else:
native_behavior.message = ffi.NULL
if drain_handler:
handlers.drain = drain_handler
native_behavior.drain = uws_websocket_factory_drain_handler if self._ws_factory else uws_websocket_drain_handler
native_behavior.drain = (
uws_websocket_factory_drain_handler
if self._ws_factory
else uws_websocket_drain_handler
)
else:
native_behavior.drain = ffi.NULL
if ping_handler:
handlers.ping = ping_handler
native_behavior.ping = uws_websocket_factory_ping_handler if self._ws_factory else uws_websocket_ping_handler
native_behavior.ping = (
uws_websocket_factory_ping_handler
if self._ws_factory
else uws_websocket_ping_handler
)
else:
native_behavior.ping = ffi.NULL
if pong_handler:
handlers.pong = pong_handler
native_behavior.pong = uws_websocket_factory_pong_handler if self._ws_factory else uws_websocket_pong_handler
native_behavior.pong = (
uws_websocket_factory_pong_handler
if self._ws_factory
else uws_websocket_pong_handler
)
else:
native_behavior.pong = ffi.NULL
if close_handler:
handlers.close = close_handler
native_behavior.close = uws_websocket_factory_close_handler if self._ws_factory else uws_websocket_close_handler
native_behavior.close = (
uws_websocket_factory_close_handler
if self._ws_factory
else uws_websocket_close_handler
)
else: # always keep an close
native_behavior.close = uws_websocket_close_handler
if subscription_handler:
handlers.subscription = subscription_handler
native_behavior.subscription = uws_websocket_factory_subscription_handler if self._ws_factory else uws_websocket_subscription_handler
native_behavior.subscription = (
uws_websocket_factory_subscription_handler
if self._ws_factory
else uws_websocket_subscription_handler
)
else: # always keep an close
native_behavior.subscription = ffi.NULL
user_data = ffi.new_handle((handlers, self))
self.handlers.append(user_data) # Keep alive handlers
lib.uws_ws(self.SSL, self.app, path.encode("utf-8"), native_behavior, user_data)
@ -2683,8 +2902,16 @@ class App:
)
else:
if port_or_options.domain:
domain = port_or_options.domain.encode('utf8')
lib.uws_app_listen_domain_with_options(self.SSL, self.app, domain, len(domain), int(port_or_options.options), uws_generic_listen_domain_handler, self._ptr)
domain = port_or_options.domain.encode("utf8")
lib.uws_app_listen_domain_with_options(
self.SSL,
self.app,
domain,
len(domain),
int(port_or_options.options),
uws_generic_listen_domain_handler,
self._ptr,
)
else:
native_options = ffi.new("uws_app_listen_config_t *")
options = native_options[0]
@ -2776,7 +3003,6 @@ class App:
self.loop = None
@dataclass
class AppListenOptions:
port: int = 0
@ -2794,16 +3020,19 @@ class AppListenOptions:
if not isinstance(self.options, int):
raise RuntimeError("options must be an int")
if self.domain and (self.host or self.port != 0):
raise RuntimeError("if domain is specified, host and port will be no effect")
raise RuntimeError(
"if domain is specified, host and port will be no effect"
)
@dataclass
class AppOptions:
key_file_name: str = None,
cert_file_name: str = None,
passphrase: str = None,
dh_params_file_name: str = None,
ca_file_name: str = None,
ssl_ciphers: str = None,
key_file_name: str = (None,)
cert_file_name: str = (None,)
passphrase: str = (None,)
dh_params_file_name: str = (None,)
ca_file_name: str = (None,)
ssl_ciphers: str = (None,)
ssl_prefer_low_memory_usage: int = 0
def __post_init__(self):

Wyświetl plik

@ -14,12 +14,6 @@ def extension(request, response, ws):
async def get_cart(self):
return [{ "quantity": 10, "name": "T-Shirt" }]
@response.method
def send(self, content: any, content_type: str = b'text/plain', status=200):
self.write_header(b'Content-Type', content_type)
self.write_status(status)
self.end(content)
request.property("token", "testing")
# extensions must be registered before routes
@ -31,18 +25,18 @@ def auth_middleware(res, req, data):
req.token = token
return { "name": "Test" } if token else { "name", "Anonymous" }
router = app.router("", auth_middleware)
router = app.router("")
@router.get("/")
async def home(res, req, data=None):
print(data)
print("token", req.token)
cart = await req.get_cart()
print("cart", cart)
user = await req.get_user()
print("user", user)
print("token", req.token)
res.send("Hello World!")
def home(res, req, data=None):
# print(data)
# print("token", req.token)
# cart = await req.get_cart()
# print("cart", cart)
# user = await req.get_user()
# print("user", user)
# print("token", req.token)
res.send({"Hello": "World!"}, headers=(("X-Rate-Limit-Remaining", "10"), (b'Another-Headers', b'Value')))
app.listen(