From a3dd3ef9582af03a1e919ddef4395793681118d5 Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Mon, 2 Jul 2018 23:13:55 +0200 Subject: [PATCH] Lots of fixes, begin to think about timeouts --- main.cpp | 42 +++++++++++++++++++++++++++--------------- src/App.h | 31 +++++++++++++++++++++++++++++++ src/HttpRouter.h | 7 ++++++- src/HttpSocket.h | 4 ++-- src/Loop.h | 2 +- 5 files changed, 67 insertions(+), 19 deletions(-) diff --git a/main.cpp b/main.cpp index 33fe71c..6ca7ee0 100644 --- a/main.cpp +++ b/main.cpp @@ -1,20 +1,21 @@ #include "uWS.h" std::string buffer; +int connections = 0; + +template +void respond(T *s) { + s->writeStatus("200 OK")->write([](int offset) { + return std::string_view(buffer.data() + offset, SIZE - offset); + }, SIZE); +} //#define USE_SSL int main(int argc, char **argv) { - // dynamically set respinse size from arguments - if (argc == 2) { - int bytes = atoi(argv[1]); - std::cout << "Server going to respond with " << bytes << " bytes of data" << std::endl; - buffer.resize(bytes); - } else { - std::cout << "Usage: uWS_test bytesInResponse" << std::endl; - return -1; - } + // 50 mb for huge + buffer.resize(52428800); //uWS::init(); //uWS::Loop loop(); @@ -28,13 +29,20 @@ int main(int argc, char **argv) { uWS::App app; #endif + // todo: add timeouts and socket shutdown! + app.onGet("/", [](auto *s, auto *req, auto *args) { - - // streams need to expose more information about lifetime! - s->writeStatus("200 OK")->write([](int offset) { - return std::string_view(buffer.data() + offset, buffer.length() - offset); - }, buffer.length()); - + s->writeStatus("200 OK")->writeHeader("Content-type", "text/html; charset=utf-8")->end("

Welcome to µWebSockets v0.15!

"); + }).onGet("/tiny", [](auto *s, auto *req, auto *args) { + respond<512>(s); + }).onGet("/small", [](auto *s, auto *req, auto *args) { + respond<4096>(s); + }).onGet("/medium", [](auto *s, auto *req, auto *args) { + respond<16384>(s); + }).onGet("/large", [](auto *s, auto *req, auto *args) { + respond<51200>(s); + }).onGet("/huge", [](auto *s, auto *req, auto *args) { + respond<52428800>(s); }).onPost("/upload", [](auto *s, auto *req, auto *args) { s->read([s](std::string_view chunk) { @@ -45,6 +53,10 @@ int main(int argc, char **argv) { }).onWebSocket("/wsApi", []() { + }).onHttpConnection([](auto *s) { + std::cout << "Connections: " << ++connections << std::endl; + }).onHttpDisconnection([](auto *s) { + std::cout << "Connections: " << --connections << std::endl; }).listen("localhost", 3000, 0); uWS::run(); diff --git a/src/App.h b/src/App.h index b9cf0c6..622cad5 100644 --- a/src/App.h +++ b/src/App.h @@ -71,6 +71,20 @@ protected: if (appData->onHttpConnection) { appData->onHttpConnection((HttpSocket *) s); } + + // we should already be linked! + //static_dispatch(us_ssl_socket_context_link, us_socket_context_link)(httpServerContext, s); + + // this should absolutely not be exposed like this! + // fix up timers! + // this goes hand in hand with fixing up shutdown also! + if constexpr (!SSL) { + us_socket_context_link(us_socket_get_context(s), s); + } + + // start a timeout on this socket of 10 seconds + std::cout << "Arming socket timeout" << std::endl; + static_dispatch(us_ssl_socket_timeout, us_socket_timeout)(s, 10); }); static_dispatch(us_ssl_socket_context_on_close, us_socket_context_on_close)(httpServerContext, [](auto *s) { @@ -97,6 +111,10 @@ protected: static_dispatch(us_ssl_socket_context_on_writable, us_socket_context_on_writable)(httpServerContext, [](auto *s) { ((HttpSocket *) s)->onWritable(); }); + + static_dispatch(us_ssl_socket_context_on_timeout, us_socket_context_on_timeout)(httpServerContext, [](auto *s) { + std::cout << "Some socket timed out!" << std::endl; + }); } public: @@ -122,6 +140,19 @@ public: return *this; } + // why even bother with these? + AppBase &onHttpConnection(std::function *)> handler) { + data->onHttpConnection = handler; + + return *this; + } + + AppBase &onHttpDisconnection(std::function *)> handler) { + data->onHttpDisconnection = handler; + + return *this; + } + // for client and server AppBase &onWebSocket(std::string pattern, std::function handler) { return *this; diff --git a/src/HttpRouter.h b/src/HttpRouter.h index b233fe6..0eaa764 100644 --- a/src/HttpRouter.h +++ b/src/HttpRouter.h @@ -158,7 +158,12 @@ public: } void route(const char *method, unsigned int method_length, const char *url, unsigned int url_length, USERDATA userData) { - handlers[lookup(url, url_length)](userData, ¶ms); + + int index = lookup(url, url_length); + if (index != -1) { + handlers[index](userData, ¶ms); + } + params.clear(); } }; diff --git a/src/HttpSocket.h b/src/HttpSocket.h index 06e6b2b..465e183 100644 --- a/src/HttpSocket.h +++ b/src/HttpSocket.h @@ -133,7 +133,7 @@ struct HttpSocket { // write that off! if constexpr (SSL) { - + httpData->offset = us_ssl_socket_write((SOCKET_TYPE *) this, chunk.data(), chunk.length()); } else { httpData->offset = us_socket_write((SOCKET_TYPE *) this, chunk.data(), chunk.length(), 0); } @@ -155,7 +155,7 @@ struct HttpSocket { // write that off! if constexpr (SSL) { - + httpData->offset += us_ssl_socket_write((SOCKET_TYPE *) this, chunk.data(), chunk.length()); } else { httpData->offset += us_socket_write((SOCKET_TYPE *) this, chunk.data(), chunk.length(), 0); } diff --git a/src/Loop.h b/src/Loop.h index 50aa7d5..a5da773 100644 --- a/src/Loop.h +++ b/src/Loop.h @@ -13,7 +13,7 @@ struct Loop { us_loop *loop; static const int CORK_BUFFER_SIZE = 16 * 1024; - static const int MAX_COPY_DISTANCE = 4 * 1024; + static const int MAX_COPY_DISTANCE = 4096; struct Data {