optimize send a little bit

pull/106/head
Ciro 2023-02-06 12:11:05 -03:00
rodzic f04a5fd642
commit a84dba6eab
8 zmienionych plików z 803 dodań i 552 usunięć

Wyświetl plik

@ -4,10 +4,12 @@ import multiprocessing
import asyncio import asyncio
def run_app(): def run_app():
app = App(request_response_factory_max_items=200_000) app = App(request_response_factory_max_items=200_000)
async def home(res, req): router = app.router()
res.end("Hello, World!")
@router.get("/")
def home(res, req):
res.send(b"Hello, World!")
app.get("/", home)
app.listen( app.listen(
8000, 8000,
lambda config: print( lambda config: print(

Wyświetl plik

@ -61,7 +61,7 @@ class AppResponse:
def get_proxied_remote_address_bytes(self): def get_proxied_remote_address_bytes(self):
def get_proxied_remote_address(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 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 send(self, message: any = b"", 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 end(self, message, end_connection=False):
def pause(self): def pause(self):
def resume(self): def resume(self):

Wyświetl plik

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "socketify" name = "socketify"
version = "0.0.12" version = "0.0.13"
authors = [ authors = [
{ name="Ciro Spaciari", email="ciro.spaciari@gmail.com" }, { name="Ciro Spaciari", email="ciro.spaciari@gmail.com" },
] ]

Wyświetl plik

@ -58,7 +58,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
setuptools.setup( setuptools.setup(
name="socketify", name="socketify",
version="0.0.12", version="0.0.13",
platforms=["any"], platforms=["any"],
author="Ciro Spaciari", author="Ciro Spaciari",
author_email="ciro.spaciari@gmail.com", author_email="ciro.spaciari@gmail.com",

Wyświetl plik

@ -385,6 +385,12 @@ void socketify_ws_cork_send(int ssl, uws_websocket_t *ws, const char* data, size
void socketify_ws_cork_send_with_options(int ssl, uws_websocket_t *ws, const char* data, size_t length, uws_opcode_t opcode, bool compress, bool close_connection); void socketify_ws_cork_send_with_options(int ssl, uws_websocket_t *ws, const char* data, size_t length, uws_opcode_t opcode, bool compress, bool close_connection);
void socketify_res_send_int_code(int ssl, uws_res_t *res, const char* content_data, size_t content_data_size, int code, const char *content_type, size_t content_type_size, bool close_connection);
void socketify_res_send(int ssl, uws_res_t *res, const char *content_data, size_t content_data_size, const char *status_code, size_t status_code_size, const char *content_type, size_t content_type_size, bool close_connection);
void socketify_res_cork_send_int_code(int ssl, uws_res_t *res, const char* content_data, size_t content_data_size, int code, const char *content_type, size_t content_type_size, bool close_connection);
void socketify_res_cork_send(int ssl, uws_res_t *res, const char *content_data, size_t content_data_size, const char *status_code, size_t status_code_size, const char *content_type, size_t content_type_size, bool close_connection);
""" """
) )

Wyświetl plik

@ -7,116 +7,254 @@
extern "C" extern "C"
{ {
static std::map<int, const char *> status_codes{
{100, "100 Continue"},
{101, "101 Switching Protocols"},
{102, "102 Processing"},
{103, "103 Early Hints"},
{200, "200 OK"},
{201, "201 Created"},
{202, "202 Accepted"},
{203, "203 Non-Authoritative Information"},
{204, "204 No Content"},
{205, "205 Reset Content"},
{206, "206 Partial Content"},
{207, "207 Multi-Status"},
{208, "208 Already Reported"},
{226, "226 IM Used (HTTP Delta encoding)"},
{300, "300 Multiple Choices"},
{301, "301 Moved Permanently"},
{302, "302 Found"},
{303, "303 See Other"},
{304, "304 Not Modified"},
{305, "305 Use Proxy Deprecated"},
{306, "306 unused"},
{307, "307 Temporary Redirect"},
{308, "308 Permanent Redirect"},
{400, "400 Bad Request"},
{401, "401 Unauthorized"},
{402, "402 Payment Required Experimental"},
{403, "403 Forbidden"},
{404, "404 Not Found"},
{405, "405 Method Not Allowed"},
{406, "406 Not Acceptable"},
{407, "407 Proxy Authentication Required"},
{408, "408 Request Timeout"},
{409, "409 Conflict"},
{410, "410 Gone"},
{411, "411 Length Required"},
{412, "412 Precondition Failed"},
{413, "413 Payload Too Large"},
{414, "414 URI Too Long"},
{415, "415 Unsupported Media Type"},
{416, "416 Range Not Satisfiable"},
{417, "417 Expectation Failed"},
{418, "418 I'm a teapot"},
{421, "421 Misdirected Request"},
{422, "422 Unprocessable Entity"},
{423, "423 Locked"},
{424, "424 Failed Dependency"},
{425, "425 Too Early Experimental"},
{426, "426 Upgrade Required"},
{428, "428 Precondition Required"},
{429, "429 Too Many Requests"},
{431, "431 Request Header Fields Too Large"},
{451, "451 Unavailable For Legal Reasons"},
{500, "500 Internal Server Error"},
{501, "501 Not Implemented"},
{502, "502 Bad Gateway"},
{503, "503 Service Unavailable"},
{504, "504 Gateway Timeout"},
{505, "505 HTTP Version Not Supported"},
{506, "506 Variant Also Negotiates"},
{507, "507 Insufficient Storage"},
{508, "508 Loop Detected"},
{510, "510 Not Extended"},
{511, "511 Network Authentication Required"}};
static std::map<int, const char*> status_codes{ bool socketify_res_write_int_status(int ssl, uws_res_t *res, int code)
{ 100, "100 Continue" },
{ 101, "101 Switching Protocols"},
{ 102, "102 Processing" },
{ 103, "103 Early Hints"},
{ 200, "200 OK" },
{ 201, "201 Created"},
{ 202, "202 Accepted"},
{ 203, "203 Non-Authoritative Information"},
{ 204, "204 No Content"},
{ 205, "205 Reset Content"},
{ 206, "206 Partial Content"},
{ 207, "207 Multi-Status"},
{ 208, "208 Already Reported"},
{ 226, "226 IM Used (HTTP Delta encoding)"},
{ 300, "300 Multiple Choices"},
{ 301, "301 Moved Permanently"},
{ 302, "302 Found" },
{ 303, "303 See Other"},
{ 304, "304 Not Modified"},
{ 305, "305 Use Proxy Deprecated"},
{ 306, "306 unused" },
{ 307, "307 Temporary Redirect"},
{ 308, "308 Permanent Redirect"},
{ 400, "400 Bad Request"},
{ 401, "401 Unauthorized" },
{ 402, "402 Payment Required Experimental"},
{ 403, "403 Forbidden" },
{ 404, "404 Not Found"},
{ 405, "405 Method Not Allowed"},
{ 406, "406 Not Acceptable"},
{ 407, "407 Proxy Authentication Required"},
{ 408, "408 Request Timeout"},
{ 409, "409 Conflict" },
{ 410, "410 Gone"},
{ 411, "411 Length Required"},
{ 412, "412 Precondition Failed"},
{ 413, "413 Payload Too Large"},
{ 414, "414 URI Too Long"},
{ 415, "415 Unsupported Media Type"},
{ 416, "416 Range Not Satisfiable"},
{ 417, "417 Expectation Failed"},
{ 418, "418 I'm a teapot"},
{ 421, "421 Misdirected Request"},
{ 422, "422 Unprocessable Entity"},
{ 423, "423 Locked" },
{ 424, "424 Failed Dependency"},
{ 425, "425 Too Early Experimental"},
{ 426, "426 Upgrade Required"},
{ 428, "428 Precondition Required"},
{ 429, "429 Too Many Requests"},
{ 431, "431 Request Header Fields Too Large"},
{ 451, "451 Unavailable For Legal Reasons"},
{ 500, "500 Internal Server Error"},
{ 501, "501 Not Implemented"},
{ 502, "502 Bad Gateway"},
{ 503, "503 Service Unavailable"},
{ 504, "504 Gateway Timeout"},
{ 505, "505 HTTP Version Not Supported"},
{ 506, "506 Variant Also Negotiates"},
{ 507, "507 Insufficient Storage"},
{ 508, "508 Loop Detected"},
{ 510, "510 Not Extended"},
{ 511, "511 Network Authentication Required"}
};
bool socketify_res_write_int_status(int ssl, uws_res_t* res, int code) {
if (code == 200) {
uws_res_write_status(ssl, res, "200 OK", 6);
return true; //default
}
std::map<int,const char*>::iterator it = status_codes.find(code);
if(it != status_codes.end())
{ {
//element found; if (code == 200)
const char* status = it->second; {
uws_res_write_status(ssl, res, "200 OK", 6);
return true; // default
}
std::map<int, const char *>::iterator it = status_codes.find(code);
if (it != status_codes.end())
{
// element found;
const char *status = it->second;
uws_res_write_status(ssl, res, status, strlen(status)); uws_res_write_status(ssl, res, status, strlen(status));
return true; return true;
} }
return false; return false;
} }
void socketify_res_send_int_code(int ssl, uws_res_t *res, const char *content_data, size_t content_data_size, int code, const char *content_type, size_t content_type_size, bool close_connection)
{
socketify_res_write_int_status(ssl, res, code);
if (content_type && content_type_size)
{
uws_res_write_header(ssl, res, "Content-Type", 12, content_type, content_type_size);
}
void socketify_res_write_headers(int ssl, uws_res_t* res, socketify_header* headers) { if (content_data != NULL)
{
uws_res_end(ssl, res, content_data, content_data_size, close_connection);
}
else
{
uws_res_end_without_body(ssl, res, close_connection);
}
}
void socketify_res_cork_send_int_code(int ssl, uws_res_t *res, const char *content_data, size_t content_data_size, int code, const char *content_type, size_t content_type_size, bool close_connection)
{
if (ssl)
{
uWS::HttpResponse<true> *uwsRes = (uWS::HttpResponse<true> *)res;
uwsRes->cork([=](){
socketify_res_write_int_status(ssl, res, code);
if (content_type && content_type_size)
{
uws_res_write_header(ssl, res, "Content-Type", 12, content_type, content_type_size);
}
if (content_data != NULL)
{
uws_res_end(ssl, res, content_data, content_data_size, close_connection);
}
else
{
uws_res_end_without_body(ssl, res, close_connection);
}
});
}
else
{
uWS::HttpResponse<false> *uwsRes = (uWS::HttpResponse<false> *)res;
uwsRes->cork([=](){
socketify_res_write_int_status(ssl, res, code);
if (content_type && content_type_size)
{
uws_res_write_header(ssl, res, "Content-Type", 12, content_type, content_type_size);
}
if (content_data != NULL)
{
uws_res_end(ssl, res, content_data, content_data_size, close_connection);
}
else
{
uws_res_end_without_body(ssl, res, close_connection);
}
});
}
}
void socketify_res_cork_send(int ssl, uws_res_t *res, const char *content_data, size_t content_data_size, const char *status_code, size_t status_code_size, const char *content_type, size_t content_type_size, bool close_connection)
{
if (ssl)
{
uWS::HttpResponse<true> *uwsRes = (uWS::HttpResponse<true> *)res;
uwsRes->cork([=](){
uws_res_write_status(ssl, res, status_code, status_code_size);
if (content_type && content_type_size)
{
uws_res_write_header(ssl, res, "Content-Type", 12, content_type, content_type_size);
}
if (content_data != NULL)
{
uws_res_end(ssl, res, content_data, content_data_size, close_connection);
}
else
{
uws_res_end_without_body(ssl, res, close_connection);
}
});
}
else
{
uWS::HttpResponse<false> *uwsRes = (uWS::HttpResponse<false> *)res;
uwsRes->cork([=](){
uws_res_write_status(ssl, res, status_code, status_code_size);
if (content_type && content_type_size)
{
uws_res_write_header(ssl, res, "Content-Type", 12, content_type, content_type_size);
}
if (content_data != NULL)
{
uws_res_end(ssl, res, content_data, content_data_size, close_connection);
}
else
{
uws_res_end_without_body(ssl, res, close_connection);
}
});
}
}
void socketify_res_send(int ssl, uws_res_t *res, const char *content_data, size_t content_data_size, const char *status_code, size_t status_code_size, const char *content_type, size_t content_type_size, bool close_connection)
{
uws_res_write_status(ssl, res, status_code, status_code_size);
if (content_type && content_type_size)
{
uws_res_write_header(ssl, res, "Content-Type", 12, content_type, content_type_size);
}
if (content_data && content_data_size)
{
uws_res_end(ssl, res, content_data, content_data_size, close_connection);
}
else
{
uws_res_end_without_body(ssl, res, close_connection);
}
}
void socketify_res_write_headers(int ssl, uws_res_t *res, socketify_header *headers)
{
while (headers != NULL) while (headers != NULL)
{ {
uws_res_write_header(ssl, res, headers->name, headers->name_size, headers->value, headers->value_size); uws_res_write_header(ssl, res, headers->name, headers->name_size, headers->value, headers->value_size);
headers = (socketify_header *)headers->next;
}
} }
}
bool socketify_res_write_int_status_with_headers(int ssl, uws_res_t* res, int code, socketify_header* headers) { bool socketify_res_write_int_status_with_headers(int ssl, uws_res_t *res, int code, socketify_header *headers)
if(socketify_res_write_int_status(ssl, res, code)){ {
if (socketify_res_write_int_status(ssl, res, code))
{
socketify_res_write_headers(ssl, res, headers); socketify_res_write_headers(ssl, res, headers);
return true; return true;
} }
return false; return false;
} }
void socketify_destroy_headers(socketify_header* headers){ void socketify_destroy_headers(socketify_header *headers)
{
socketify_header* current = headers; socketify_header *current = headers;
while(current != NULL){ while (current != NULL)
socketify_header* next = (socketify_header*)current->next; {
socketify_header *next = (socketify_header *)current->next;
free(current); free(current);
current = next; current = next;
} }
} }
socketify_asgi_data socketify_asgi_request(int ssl, uws_req_t *req, uws_res_t *res){ socketify_asgi_data socketify_asgi_request(int ssl, uws_req_t *req, uws_res_t *res)
{
socketify_asgi_data result; socketify_asgi_data result;
@ -148,36 +286,40 @@ socketify_asgi_data socketify_asgi_request(int ssl, uws_req_t *req, uws_res_t *r
result.has_content = false; result.has_content = false;
uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)req; uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)req;
result.header_list = NULL; result.header_list = NULL;
socketify_header* last = NULL; socketify_header *last = NULL;
for (auto header : *uwsReq) for (auto header : *uwsReq)
{ {
socketify_header* current = (socketify_header*)malloc(sizeof(socketify_header)); socketify_header *current = (socketify_header *)malloc(sizeof(socketify_header));
auto name = header.first; auto name = header.first;
auto value = header.second; auto value = header.second;
current->name = name.data(); current->name = name.data();
current->name_size = name.length(); current->name_size = name.length();
if(name.compare("content-length") == 0 || name.compare("transfer-encoding") == 0){ if (name.compare("content-length") == 0 || name.compare("transfer-encoding") == 0)
{
result.has_content = true; result.has_content = true;
} }
current->value = header.second.data(); current->value = header.second.data();
current->value_size = header.second.length(); current->value_size = header.second.length();
current->next = NULL; current->next = NULL;
if(last == NULL){ if (last == NULL)
{
result.header_list = current; result.header_list = current;
last = current; last = current;
}else{ }
else
{
last->next = current; last->next = current;
last = current; last = current;
} }
} }
return result; return result;
}
} socketify_asgi_ws_data socketify_asgi_ws_request(int ssl, uws_req_t *req, uws_res_t *res)
{
socketify_asgi_ws_data socketify_asgi_ws_request(int ssl, uws_req_t *req, uws_res_t *res){
socketify_asgi_ws_data result; socketify_asgi_ws_data result;
@ -209,7 +351,7 @@ socketify_asgi_ws_data socketify_asgi_ws_request(int ssl, uws_req_t *req, uws_re
uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)req; uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)req;
result.header_list = NULL; result.header_list = NULL;
socketify_header* last = NULL; socketify_header *last = NULL;
const char *protocol = NULL; const char *protocol = NULL;
const char *extensions = NULL; const char *extensions = NULL;
@ -222,33 +364,40 @@ socketify_asgi_ws_data socketify_asgi_ws_request(int ssl, uws_req_t *req, uws_re
{ {
auto name = header.first; auto name = header.first;
auto value = header.second; auto value = header.second;
const char* value_data = value.data(); const char *value_data = value.data();
size_t value_size = value.length(); size_t value_size = value.length();
if (name.compare("sec-websocket-key") == 0){ if (name.compare("sec-websocket-key") == 0)
{
key = value_data; key = value_data;
key_size = value_size; key_size = value_size;
}else if (name.compare("sec-websocket-protocol") == 0){ }
else if (name.compare("sec-websocket-protocol") == 0)
{
protocol = value_data; protocol = value_data;
protocol_size = value_size; protocol_size = value_size;
continue;//exclude protocol continue; // exclude protocol
}else if (name.compare("sec-websocket-extensions") == 0){ }
else if (name.compare("sec-websocket-extensions") == 0)
{
extensions = value_data; extensions = value_data;
extensions_size = value_size; extensions_size = value_size;
} }
socketify_header* current = (socketify_header*)malloc(sizeof(socketify_header)); socketify_header *current = (socketify_header *)malloc(sizeof(socketify_header));
current->name = name.data(); current->name = name.data();
current->name_size = name.length(); current->name_size = name.length();
current->value = value_data; current->value = value_data;
current->value_size = value_size; current->value_size = value_size;
current->next = NULL; current->next = NULL;
if(last == NULL){ if (last == NULL)
{
result.header_list = current; result.header_list = current;
last = current; last = current;
}else{ }
else
{
last->next = current; last->next = current;
last = current; last = current;
} }
@ -260,201 +409,215 @@ socketify_asgi_ws_data socketify_asgi_ws_request(int ssl, uws_req_t *req, uws_re
result.key_size = key_size; result.key_size = key_size;
result.extensions_size = extensions_size; result.extensions_size = extensions_size;
return result; return result;
}
} void socketify_asgi_http_handler(uws_res_t *response, uws_req_t *request, void *user_data)
{
void socketify_asgi_http_handler(uws_res_t *response, uws_req_t *request, void *user_data){ socksocketify_asgi_app_info *info = ((socksocketify_asgi_app_info *)user_data);
socksocketify_asgi_app_info* info = ((socksocketify_asgi_app_info*)user_data);
socketify_asgi_data data = socketify_asgi_request(info->ssl, request, response); socketify_asgi_data data = socketify_asgi_request(info->ssl, request, response);
bool* aborted = (bool*)malloc(sizeof(aborted)); bool *aborted = (bool *)malloc(sizeof(aborted));
*aborted = false; *aborted = false;
uws_res_on_aborted(info->ssl, response, [](uws_res_t *res, void *opcional_data){ uws_res_on_aborted(
info->ssl, response, [](uws_res_t *res, void *opcional_data)
{
bool* aborted = (bool*)opcional_data; bool* aborted = (bool*)opcional_data;
*aborted = true; *aborted = true; },
}, aborted); aborted);
info->handler(info->ssl, response, data, info->user_data, aborted); info->handler(info->ssl, response, data, info->user_data, aborted);
socketify_destroy_headers(data.header_list); socketify_destroy_headers(data.header_list);
} }
void socketify_res_cork_write(int ssl, uws_res_t *res, const char *data, size_t length)
{
void socketify_res_cork_write(int ssl, uws_res_t *res, const char* data, size_t length){
if (ssl) if (ssl)
{ {
uWS::HttpResponse<true> *uwsRes = (uWS::HttpResponse<true> *)res; uWS::HttpResponse<true> *uwsRes = (uWS::HttpResponse<true> *)res;
uwsRes->cork([=](){ uwsRes->cork([=]()
uwsRes->write(std::string_view(data, length)); { uwsRes->write(std::string_view(data, length)); });
});
} }
else else
{ {
uWS::HttpResponse<false> *uwsRes = (uWS::HttpResponse<false> *)res; uWS::HttpResponse<false> *uwsRes = (uWS::HttpResponse<false> *)res;
uwsRes->cork([=](){ uwsRes->cork([=]()
uwsRes->write(std::string_view(data, length)); { uwsRes->write(std::string_view(data, length)); });
}); }
} }
}
void socketify_res_cork_end(int ssl, uws_res_t *res, const char* data, size_t length, bool close_connection){ void socketify_res_cork_end(int ssl, uws_res_t *res, const char *data, size_t length, bool close_connection)
{
if (ssl) if (ssl)
{ {
uWS::HttpResponse<true> *uwsRes = (uWS::HttpResponse<true> *)res; uWS::HttpResponse<true> *uwsRes = (uWS::HttpResponse<true> *)res;
uwsRes->cork([=](){ uwsRes->cork([=]()
uwsRes->end(std::string_view(data, length), close_connection); { uwsRes->end(std::string_view(data, length), close_connection); });
});
} }
else else
{ {
uWS::HttpResponse<false> *uwsRes = (uWS::HttpResponse<false> *)res; uWS::HttpResponse<false> *uwsRes = (uWS::HttpResponse<false> *)res;
uwsRes->cork([=](){ uwsRes->cork([=]()
uwsRes->end(std::string_view(data, length), close_connection); { uwsRes->end(std::string_view(data, length), close_connection); });
});
} }
} }
void socketify_ws_cork_send(int ssl, uws_websocket_t *ws, const char* data, size_t length, uws_opcode_t opcode){ void socketify_ws_cork_send(int ssl, uws_websocket_t *ws, const char *data, size_t length, uws_opcode_t opcode)
{
if (ssl) if (ssl)
{ {
uWS::WebSocket<true, true, void *> *uws = (uWS::WebSocket<true, true, void *> *)ws; uWS::WebSocket<true, true, void *> *uws = (uWS::WebSocket<true, true, void *> *)ws;
uws->cork([&](){ uws->cork([&]()
uws->send(std::string_view(data, length), (uWS::OpCode)(unsigned char) opcode); { uws->send(std::string_view(data, length), (uWS::OpCode)(unsigned char)opcode); });
});
} }
else else
{ {
uWS::WebSocket<false, true, void *> *uws = (uWS::WebSocket<false, true, void *> *)ws; uWS::WebSocket<false, true, void *> *uws = (uWS::WebSocket<false, true, void *> *)ws;
uws->cork([&](){ uws->cork([&]()
uws->send(std::string_view(data, length), (uWS::OpCode)(unsigned char) opcode); { uws->send(std::string_view(data, length), (uWS::OpCode)(unsigned char)opcode); });
}); }
} }
} void socketify_ws_cork_send_with_options(int ssl, uws_websocket_t *ws, const char *data, size_t length, uws_opcode_t opcode, bool compress, bool fin)
{
void socketify_ws_cork_send_with_options(int ssl, uws_websocket_t *ws, const char* data, size_t length, uws_opcode_t opcode, bool compress, bool fin){
if (ssl) if (ssl)
{ {
uWS::WebSocket<true, true, void *> *uws = (uWS::WebSocket<true, true, void *> *)ws; uWS::WebSocket<true, true, void *> *uws = (uWS::WebSocket<true, true, void *> *)ws;
uws->cork([&](){ uws->cork([&]()
uws->send(std::string_view(data, length), (uWS::OpCode)(unsigned char) opcode, compress, fin); { uws->send(std::string_view(data, length), (uWS::OpCode)(unsigned char)opcode, compress, fin); });
});
} }
else else
{ {
uWS::WebSocket<false, true, void *> *uws = (uWS::WebSocket<false, true, void *> *)ws; uWS::WebSocket<false, true, void *> *uws = (uWS::WebSocket<false, true, void *> *)ws;
uws->cork([&](){ uws->cork([&]()
uws->send(std::string_view(data, length), (uWS::OpCode)(unsigned char) opcode, compress, fin); { uws->send(std::string_view(data, length), (uWS::OpCode)(unsigned char)opcode, compress, fin); });
}); }
} }
}
socksocketify_asgi_ws_app_info *socketify_add_asgi_ws_handler(int ssl, uws_app_t *app, uws_socket_behavior_t behavior, socketify_asgi_ws_method_handler handler, void *user_data)
socksocketify_asgi_ws_app_info* socketify_add_asgi_ws_handler(int ssl, uws_app_t* app, uws_socket_behavior_t behavior, socketify_asgi_ws_method_handler handler, void* user_data){ {
socksocketify_asgi_ws_app_info* info = (socksocketify_asgi_ws_app_info*)malloc(sizeof(socksocketify_asgi_ws_app_info)); socksocketify_asgi_ws_app_info *info = (socksocketify_asgi_ws_app_info *)malloc(sizeof(socksocketify_asgi_ws_app_info));
info->ssl = ssl; info->ssl = ssl;
info->app = app; info->app = app;
info->handler = handler; info->handler = handler;
info->user_data = user_data; info->user_data = user_data;
info->behavior = behavior; info->behavior = behavior;
const char* pattern = "/*"; const char *pattern = "/*";
uws_socket_behavior_t ws_behavior; uws_socket_behavior_t ws_behavior;
memcpy(&ws_behavior, &behavior, sizeof(behavior)); memcpy(&ws_behavior, &behavior, sizeof(behavior));
ws_behavior.upgrade = [](uws_res_t *response, uws_req_t *request, uws_socket_context_t *context, void* user_data){ ws_behavior.upgrade = [](uws_res_t *response, uws_req_t *request, uws_socket_context_t *context, void *user_data)
socksocketify_asgi_ws_app_info* info = ((socksocketify_asgi_ws_app_info*)user_data); {
socksocketify_asgi_ws_app_info *info = ((socksocketify_asgi_ws_app_info *)user_data);
socketify_asgi_ws_data data = socketify_asgi_ws_request(info->ssl, request, response); socketify_asgi_ws_data data = socketify_asgi_ws_request(info->ssl, request, response);
bool* aborted = (bool*)malloc(sizeof(aborted)); bool *aborted = (bool *)malloc(sizeof(aborted));
*aborted = false; *aborted = false;
uws_res_on_aborted(info->ssl, response, [](uws_res_t *res, void *opcional_data){ uws_res_on_aborted(
info->ssl, response, [](uws_res_t *res, void *opcional_data)
{
bool* aborted = (bool*)opcional_data; bool* aborted = (bool*)opcional_data;
*aborted = true; *aborted = true; },
}, aborted); aborted);
info->handler(info->ssl, response, data, context, info->user_data, aborted); info->handler(info->ssl, response, data, context, info->user_data, aborted);
socketify_destroy_headers(data.header_list); socketify_destroy_headers(data.header_list);
}; };
ws_behavior.open = [](uws_websocket_t *ws, void* user_data){ ws_behavior.open = [](uws_websocket_t *ws, void *user_data)
socksocketify_asgi_ws_app_info* info = ((socksocketify_asgi_ws_app_info*)user_data); {
socksocketify_asgi_ws_app_info *info = ((socksocketify_asgi_ws_app_info *)user_data);
auto socket_data = uws_ws_get_user_data(info->ssl, ws); auto socket_data = uws_ws_get_user_data(info->ssl, ws);
info->behavior.open(ws, socket_data); info->behavior.open(ws, socket_data);
}; };
ws_behavior.message = [](uws_websocket_t* ws, const char* message, size_t length, uws_opcode_t opcode, void* user_data){ ws_behavior.message = [](uws_websocket_t *ws, const char *message, size_t length, uws_opcode_t opcode, void *user_data)
socksocketify_asgi_ws_app_info* info = ((socksocketify_asgi_ws_app_info*)user_data); {
socksocketify_asgi_ws_app_info *info = ((socksocketify_asgi_ws_app_info *)user_data);
auto socket_data = uws_ws_get_user_data(info->ssl, ws); auto socket_data = uws_ws_get_user_data(info->ssl, ws);
info->behavior.message(ws, message, length, opcode, socket_data); info->behavior.message(ws, message, length, opcode, socket_data);
}; };
ws_behavior.close = [](uws_websocket_t* ws, int code, const char* message, size_t length, void* user_data){ ws_behavior.close = [](uws_websocket_t *ws, int code, const char *message, size_t length, void *user_data)
socksocketify_asgi_ws_app_info* info = ((socksocketify_asgi_ws_app_info*)user_data); {
socksocketify_asgi_ws_app_info *info = ((socksocketify_asgi_ws_app_info *)user_data);
auto socket_data = uws_ws_get_user_data(info->ssl, ws); auto socket_data = uws_ws_get_user_data(info->ssl, ws);
info->behavior.close(ws,code, message, length, socket_data); info->behavior.close(ws, code, message, length, socket_data);
}; };
uws_ws(ssl, app, pattern, ws_behavior, info); uws_ws(ssl, app, pattern, ws_behavior, info);
return info; return info;
} }
socksocketify_asgi_app_info* socketify_add_asgi_http_handler(int ssl, uws_app_t* app, socketify_asgi_method_handler handler, void* user_data){ socksocketify_asgi_app_info *socketify_add_asgi_http_handler(int ssl, uws_app_t *app, socketify_asgi_method_handler handler, void *user_data)
socksocketify_asgi_app_info* info = (socksocketify_asgi_app_info*)malloc(sizeof(socksocketify_asgi_app_info)); {
socksocketify_asgi_app_info *info = (socksocketify_asgi_app_info *)malloc(sizeof(socksocketify_asgi_app_info));
info->ssl = ssl; info->ssl = ssl;
info->app = app; info->app = app;
info->handler = handler; info->handler = handler;
info->user_data = user_data; info->user_data = user_data;
const char* pattern = "/*"; const char *pattern = "/*";
uws_app_any(ssl, app, pattern, socketify_asgi_http_handler, info); uws_app_any(ssl, app, pattern, socketify_asgi_http_handler, info);
return info; return info;
} }
void socketify_destroy_asgi_app_info(socksocketify_asgi_app_info* app){ void socketify_destroy_asgi_app_info(socksocketify_asgi_app_info *app)
{
free(app); free(app);
} }
void socketify_destroy_asgi_ws_app_info(socksocketify_asgi_ws_app_info* app){ void socketify_destroy_asgi_ws_app_info(socksocketify_asgi_ws_app_info *app)
{
free(app); free(app);
} }
void socketify_generic_prepare_callback(uv_prepare_t *prepare){ void socketify_generic_prepare_callback(uv_prepare_t *prepare)
socketify_loop* loop = (socketify_loop*)uv_handle_get_data((uv_handle_t*)prepare); {
socketify_loop *loop = (socketify_loop *)uv_handle_get_data((uv_handle_t *)prepare);
loop->on_prepare_handler(loop->on_prepare_data); loop->on_prepare_handler(loop->on_prepare_data);
} }
void socketify_generic_timer_callback(uv_timer_t *timer){ void socketify_generic_timer_callback(uv_timer_t *timer)
socketify_timer* loop_data = (socketify_timer*)uv_handle_get_data((uv_handle_t*)timer); {
socketify_timer *loop_data = (socketify_timer *)uv_handle_get_data((uv_handle_t *)timer);
loop_data->handler(loop_data->user_data); loop_data->handler(loop_data->user_data);
} }
void socketify_generic_check_callback(uv_check_t *timer){ void socketify_generic_check_callback(uv_check_t *timer)
socketify_timer* loop_data = (socketify_timer*)uv_handle_get_data((uv_handle_t*)timer); {
socketify_timer *loop_data = (socketify_timer *)uv_handle_get_data((uv_handle_t *)timer);
loop_data->handler(loop_data->user_data); loop_data->handler(loop_data->user_data);
} }
void *socketify_get_native_loop(socketify_loop *loop)
void* socketify_get_native_loop(socketify_loop* loop){ {
return loop->uv_loop; return loop->uv_loop;
} }
socketify_loop * socketify_create_loop(){ socketify_loop *socketify_create_loop()
socketify_loop* loop = (socketify_loop*)malloc(sizeof(uv_prepare_t)); {
socketify_loop *loop = (socketify_loop *)malloc(sizeof(uv_prepare_t));
loop->uv_loop = NULL; loop->uv_loop = NULL;
loop->on_prepare_handler = NULL; loop->on_prepare_handler = NULL;
loop->uv_prepare_ptr = NULL; loop->uv_prepare_ptr = NULL;
uv_loop_t* uv_loop = (uv_loop_t*)malloc(sizeof(uv_loop_t)); uv_loop_t *uv_loop = (uv_loop_t *)malloc(sizeof(uv_loop_t));
if(uv_loop_init(uv_loop)){ if (uv_loop_init(uv_loop))
{
free(uv_loop); free(uv_loop);
return loop; return loop;
} }
loop->uv_loop = uv_loop; loop->uv_loop = uv_loop;
return loop; return loop;
} }
bool socketify_constructor_failed(socketify_loop* loop){ bool socketify_constructor_failed(socketify_loop *loop)
{
return loop->uv_loop == NULL; return loop->uv_loop == NULL;
} }
bool socketify_on_prepare(socketify_loop* loop, socketify_prepare_handler handler, void* user_data){ bool socketify_on_prepare(socketify_loop *loop, socketify_prepare_handler handler, void *user_data)
if (loop->uv_prepare_ptr != NULL) return false; {
if(handler == NULL) return false; if (loop->uv_prepare_ptr != NULL)
uv_prepare_t* prepare = (uv_prepare_t*)malloc(sizeof(uv_prepare_t)); return false;
if(uv_prepare_init((uv_loop_t*)loop->uv_loop, prepare)){ if (handler == NULL)
return false;
uv_prepare_t *prepare = (uv_prepare_t *)malloc(sizeof(uv_prepare_t));
if (uv_prepare_init((uv_loop_t *)loop->uv_loop, prepare))
{
free(prepare); free(prepare);
return false; return false;
} }
@ -462,99 +625,110 @@ bool socketify_on_prepare(socketify_loop* loop, socketify_prepare_handler handle
loop->on_prepare_handler = handler; loop->on_prepare_handler = handler;
loop->on_prepare_data = user_data; loop->on_prepare_data = user_data;
loop->uv_prepare_ptr = prepare; loop->uv_prepare_ptr = prepare;
uv_handle_set_data((uv_handle_t*)prepare, loop); uv_handle_set_data((uv_handle_t *)prepare, loop);
uv_prepare_start(prepare, socketify_generic_prepare_callback); uv_prepare_start(prepare, socketify_generic_prepare_callback);
return true; return true;
} }
bool socketify_prepare_unbind(socketify_loop* loop){ bool socketify_prepare_unbind(socketify_loop *loop)
if(loop->uv_prepare_ptr == NULL) return false; {
if (loop->uv_prepare_ptr == NULL)
return false;
uv_prepare_stop((uv_prepare_t *)loop->uv_prepare_ptr); uv_prepare_stop((uv_prepare_t *)loop->uv_prepare_ptr);
free(loop->uv_prepare_ptr); free(loop->uv_prepare_ptr);
loop->uv_prepare_ptr = NULL; loop->uv_prepare_ptr = NULL;
return true; return true;
}
int socketify_loop_run(socketify_loop* loop, socketify_run_mode mode){
return uv_run((uv_loop_t*)loop->uv_loop, (uv_run_mode)mode);
}
void socketify_loop_stop(socketify_loop* loop){
if(uv_loop_alive((uv_loop_t*)loop->uv_loop)){
uv_stop((uv_loop_t*)loop->uv_loop);
} }
}
void socketify_destroy_loop(socketify_loop* loop){ int socketify_loop_run(socketify_loop *loop, socketify_run_mode mode)
{
return uv_run((uv_loop_t *)loop->uv_loop, (uv_run_mode)mode);
}
void socketify_loop_stop(socketify_loop *loop)
{
if (uv_loop_alive((uv_loop_t *)loop->uv_loop))
{
uv_stop((uv_loop_t *)loop->uv_loop);
}
}
void socketify_destroy_loop(socketify_loop *loop)
{
socketify_loop_stop(loop); socketify_loop_stop(loop);
uv_loop_close((uv_loop_t*)loop->uv_loop); uv_loop_close((uv_loop_t *)loop->uv_loop);
free(loop->uv_loop); free(loop->uv_loop);
if(loop->uv_prepare_ptr){ if (loop->uv_prepare_ptr)
{
free(loop->uv_prepare_ptr); free(loop->uv_prepare_ptr);
} }
free(loop); free(loop);
} }
socketify_timer* socketify_create_timer(socketify_loop* loop, uint64_t timeout, uint64_t repeat, socketify_timer_handler handler, void* user_data){ socketify_timer *socketify_create_timer(socketify_loop *loop, uint64_t timeout, uint64_t repeat, socketify_timer_handler handler, void *user_data)
{
uv_timer_t* uv_timer = (uv_timer_t* ) malloc(sizeof(uv_timer_t)); uv_timer_t *uv_timer = (uv_timer_t *)malloc(sizeof(uv_timer_t));
if(uv_timer_init((uv_loop_t*)loop->uv_loop, uv_timer)){ if (uv_timer_init((uv_loop_t *)loop->uv_loop, uv_timer))
{
free(uv_timer); free(uv_timer);
return NULL; return NULL;
} }
socketify_timer* timer = (socketify_timer*)malloc(sizeof(socketify_timer)); socketify_timer *timer = (socketify_timer *)malloc(sizeof(socketify_timer));
timer->uv_timer_ptr = uv_timer; timer->uv_timer_ptr = uv_timer;
timer->user_data = user_data; timer->user_data = user_data;
timer->handler = handler; timer->handler = handler;
uv_handle_set_data((uv_handle_t*)uv_timer, timer); uv_handle_set_data((uv_handle_t *)uv_timer, timer);
uv_timer_start(uv_timer, socketify_generic_timer_callback, timeout, repeat); uv_timer_start(uv_timer, socketify_generic_timer_callback, timeout, repeat);
return timer; return timer;
} }
void socketify_timer_set_repeat(socketify_timer* timer, uint64_t repeat){ void socketify_timer_set_repeat(socketify_timer *timer, uint64_t repeat)
uv_timer_set_repeat((uv_timer_t *) timer->uv_timer_ptr, repeat); {
} uv_timer_set_repeat((uv_timer_t *)timer->uv_timer_ptr, repeat);
}
// stops and destroy timer info
//stops and destroy timer info void socketify_timer_destroy(socketify_timer *timer)
void socketify_timer_destroy(socketify_timer* timer){ {
uv_timer_stop((uv_timer_t *)timer->uv_timer_ptr); uv_timer_stop((uv_timer_t *)timer->uv_timer_ptr);
free(timer->uv_timer_ptr); free(timer->uv_timer_ptr);
free(timer); free(timer);
} }
socketify_timer *socketify_create_check(socketify_loop *loop, socketify_timer_handler handler, void *user_data)
{
uv_check_t *uv_timer = (uv_check_t *)malloc(sizeof(uv_check_t));
socketify_timer* socketify_create_check(socketify_loop* loop, socketify_timer_handler handler, void* user_data){ if (uv_check_init((uv_loop_t *)loop->uv_loop, uv_timer))
{
uv_check_t* uv_timer = (uv_check_t*)malloc(sizeof(uv_check_t));
if(uv_check_init((uv_loop_t*)loop->uv_loop, uv_timer)){
free(uv_timer); free(uv_timer);
return NULL; return NULL;
} }
socketify_timer* timer = (socketify_timer*)malloc(sizeof(socketify_timer)); socketify_timer *timer = (socketify_timer *)malloc(sizeof(socketify_timer));
timer->uv_timer_ptr = uv_timer; timer->uv_timer_ptr = uv_timer;
timer->user_data = user_data; timer->user_data = user_data;
timer->handler = handler; timer->handler = handler;
uv_handle_set_data((uv_handle_t*)uv_timer, timer); uv_handle_set_data((uv_handle_t *)uv_timer, timer);
uv_check_start(uv_timer, socketify_generic_check_callback); uv_check_start(uv_timer, socketify_generic_check_callback);
return timer; return timer;
} }
//stops and destroy timer info // stops and destroy timer info
void socketify_check_destroy(socketify_timer* timer){ void socketify_check_destroy(socketify_timer *timer)
{
uv_check_stop((uv_check_t *)timer->uv_timer_ptr); uv_check_stop((uv_check_t *)timer->uv_timer_ptr);
free(timer->uv_timer_ptr); free(timer->uv_timer_ptr);
free(timer); free(timer);
} }
} }

Wyświetl plik

@ -138,6 +138,10 @@ DLL_EXPORT socksocketify_asgi_ws_app_info* socketify_add_asgi_ws_handler(int ssl
DLL_EXPORT void socketify_destroy_asgi_ws_app_info(socksocketify_asgi_ws_app_info* app); DLL_EXPORT void socketify_destroy_asgi_ws_app_info(socksocketify_asgi_ws_app_info* app);
DLL_EXPORT void socketify_ws_cork_send(int ssl, uws_websocket_t *ws, const char* data, size_t length, uws_opcode_t opcode); DLL_EXPORT void socketify_ws_cork_send(int ssl, uws_websocket_t *ws, const char* data, size_t length, uws_opcode_t opcode);
DLL_EXPORT void socketify_ws_cork_send_with_options(int ssl, uws_websocket_t *ws, const char* data, size_t length, uws_opcode_t opcode, bool compress, bool fin); DLL_EXPORT void socketify_ws_cork_send_with_options(int ssl, uws_websocket_t *ws, const char* data, size_t length, uws_opcode_t opcode, bool compress, bool fin);
DLL_EXPORT void socketify_res_send_int_code(int ssl, uws_res_t *res, const char* content_data, size_t content_data_size, int code, const char *content_type, size_t content_type_size, bool close_connection);
DLL_EXPORT void socketify_res_send(int ssl, uws_res_t *res, const char *content_data, size_t content_data_size, const char *status_code, size_t status_code_size, const char *content_type, size_t content_type_size, bool close_connection);
DLL_EXPORT void socketify_res_cork_send_int_code(int ssl, uws_res_t *res, const char* content_data, size_t content_data_size, int code, const char *content_type, size_t content_type_size, bool close_connection);
DLL_EXPORT void socketify_res_cork_send(int ssl, uws_res_t *res, const char *content_data, size_t content_data_size, const char *status_code, size_t status_code_size, const char *content_type, size_t content_type_size, bool close_connection);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
} }

Wyświetl plik

@ -1733,6 +1733,7 @@ class AppResponse:
headers=None, headers=None,
end_connection: bool = False, end_connection: bool = False,
): ):
# TODO: use socketify_res_cork_send_int_code and socketify_res_cork_send after optimize headers
self.cork( self.cork(
lambda res: res.send(message, content_type, status, headers, end_connection) lambda res: res.send(message, content_type, status, headers, end_connection)
) )
@ -1740,42 +1741,107 @@ class AppResponse:
def send( def send(
self, self,
message: any, message: any = b"",
content_type: Union[str, bytes] = b"text/plain", content_type: Union[str, bytes] = b"text/plain",
status: Union[str, bytes, int] = b"200 OK", status: Union[str, bytes, int] = b"200 OK",
headers=None, headers = None,
end_connection: bool = False, end_connection: bool = False,
): ):
if self.aborted:
return self
self.write_status(status)
# TODO: optimize headers
if headers is not None: if headers is not None:
for name, value in headers: for name, value in headers:
self.write_header(name, value) self.write_header(name, value)
try: try:
# TODO: optimize Set-Cookie
if self._write_jar is not None: if self._write_jar is not None:
self.write_header("Set-Cookie", self._write_jar.output(header="")) self.write_header("Set-Cookie", self._write_jar.output(header=""))
self._write_jar = None self._write_jar = None
if isinstance(message, str): if isinstance(message, str):
data = message.encode("utf-8") data = message.encode("utf-8")
self.write_header(b"Content-Type", content_type)
elif isinstance(message, bytes): elif isinstance(message, bytes):
self.write_header(b"Content-Type", content_type)
data = message data = message
elif message is None: elif message is None:
self.write_header(b"Content-Type", content_type) if isinstance(status, int):
self.end_without_body(end_connection) lib.socketify_res_send_int_code(
self.app.SSL,
self.res,
ffi.NULL,
0,
status,
content_type,
len(content_type),
1 if end_connection else 0,
)
elif isinstance(status, str):
status = status.encode("utf-8")
lib.socketify_res_send(
self.app.SSL,
self.res,
ffi.NULL,
0,
status,
len(status),
content_type,
len(content_type),
1 if end_connection else 0,
)
else:
lib.socketify_res_send(
self.app.SSL,
self.res,
ffi.NULL,
0,
status,
len(status),
content_type,
len(content_type),
1 if end_connection else 0,
)
return self return self
else: else:
data = self.app._json_serializer.dumps(message).encode("utf-8") data = self.app._json_serializer.dumps(message).encode("utf-8")
# ignores content_type should always be json here content_type = b"application/json"
self.write_header(b"Content-Type", b"application/json")
lib.uws_res_end( if isinstance(status, int):
self.app.SSL, self.res, data, len(data), 1 if end_connection else 0 lib.socketify_res_send_int_code(
self.app.SSL,
self.res,
data,
len(data),
status,
content_type,
len(content_type),
1 if end_connection else 0,
) )
elif isinstance(status, str):
status = status.encode("utf-8")
lib.socketify_res_send(
self.app.SSL,
self.res,
ffi.NULL,
0,
status,
len(status),
content_type,
len(content_type),
1 if end_connection else 0,
)
else:
lib.socketify_res_send(
self.app.SSL,
self.res,
data,
len(data),
status,
len(status),
content_type,
len(content_type),
1 if end_connection else 0,
)
finally: finally:
return self return self
@ -2506,7 +2572,6 @@ class App:
self._native_options.append(cert_file_name) self._native_options.append(cert_file_name)
socket_options.cert_file_name = cert_file_name socket_options.cert_file_name = cert_file_name
passphrase = ( passphrase = (
ffi.NULL ffi.NULL
if options.passphrase is None if options.passphrase is None