diff --git a/main.cpp b/main.cpp index 6ca7ee0..0b8fb8e 100644 --- a/main.cpp +++ b/main.cpp @@ -10,7 +10,7 @@ void respond(T *s) { }, SIZE); } -//#define USE_SSL +#define USE_SSL int main(int argc, char **argv) { @@ -57,7 +57,7 @@ int main(int argc, char **argv) { std::cout << "Connections: " << ++connections << std::endl; }).onHttpDisconnection([](auto *s) { std::cout << "Connections: " << --connections << std::endl; - }).listen("localhost", 3000, 0); + }).listen(nullptr, 3000, 0); uWS::run(); // loop.run(); diff --git a/src/App.h b/src/App.h index 622cad5..5bd9087 100644 --- a/src/App.h +++ b/src/App.h @@ -14,6 +14,8 @@ class AppBase { protected: + static const unsigned int HTTP_IDLE_TIMEOUT_S = 10; + template static constexpr typename std::conditional::type *static_dispatch(A *a, B *b) { if constexpr(SSL) { @@ -66,25 +68,13 @@ protected: static_dispatch(us_ssl_socket_context_on_open, us_socket_context_on_open)(httpServerContext, [](auto *s) { Data *appData = (Data *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(static_dispatch(us_ssl_socket_get_context, us_socket_get_context)(s)); + static_dispatch(us_ssl_socket_timeout, us_socket_timeout)(s, HTTP_IDLE_TIMEOUT_S); + new (static_dispatch(us_ssl_socket_ext, us_socket_ext)(s)) HTTP_SOCKET_DATA_TYPE; 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) { @@ -100,6 +90,8 @@ protected: static_dispatch(us_ssl_socket_context_on_data, us_socket_context_on_data)(httpServerContext, [](auto *s, char *data, int length) { Data *appData = (Data *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(static_dispatch(us_ssl_socket_get_context, us_socket_get_context)(s)); + static_dispatch(us_ssl_socket_timeout, us_socket_timeout)(s, HTTP_IDLE_TIMEOUT_S); + // onHttpRequest should probably be hard-coded to HttpRouter ((HttpSocket *) s)->onData(data, length, appData->onHttpRequest); @@ -109,11 +101,16 @@ protected: }); static_dispatch(us_ssl_socket_context_on_writable, us_socket_context_on_writable)(httpServerContext, [](auto *s) { + static_dispatch(us_ssl_socket_timeout, us_socket_timeout)(s, HTTP_IDLE_TIMEOUT_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; + + // basically, when any socket times out we want to close it + + std::cout << "The server would now like to close a socket!" << std::endl; }); } diff --git a/src/HttpSocket.h b/src/HttpSocket.h index 465e183..9ded908 100644 --- a/src/HttpSocket.h +++ b/src/HttpSocket.h @@ -12,7 +12,7 @@ template struct HttpSocket { - const size_t MAX_FALLBACK_SIZE = 1024 * 4; + const size_t MAX_FALLBACK_SIZE = 4096; template static constexpr typename std::conditional::type *static_dispatch(A *a, B *b) { @@ -66,7 +66,7 @@ struct HttpSocket { } // never rely on this one! - int writeToCorkBufferAndReset(const char *src, int length, int contentLength) { + int writeToCorkBufferAndReset(const char *src, int length, int contentLength, bool expectMore) { uWS::Loop::Data *loopData = (uWS::Loop::Data *) us_loop_ext(us_socket_context_loop(us_socket_get_context((us_socket *) this))); memcpy(loopData->corkBuffer + loopData->corkOffset, "Content-Length: ", 16); @@ -81,13 +81,7 @@ struct HttpSocket { memcpy(loopData->corkBuffer + loopData->corkOffset, src, length); loopData->corkOffset += length; - int written; - - if constexpr(SSL) { - written = us_ssl_socket_write((us_ssl_socket *) this, loopData->corkBuffer, loopData->corkOffset); - } else { - written = us_socket_write((us_socket *) this, loopData->corkBuffer, loopData->corkOffset, 0); - } + int written = static_dispatch(us_ssl_socket_write, us_socket_write)((SOCKET_TYPE *) this, loopData->corkBuffer, loopData->corkOffset, expectMore); loopData->corkOffset = 0; return written; @@ -111,7 +105,7 @@ struct HttpSocket { // this should not be anything other than a simple convenience wrapper of streams! void end(std::string_view data) { // end should not explicitly flush the cork buffer! delay to when done with all http data! - writeToCorkBufferAndReset(data.data(), data.length(), data.length()); + writeToCorkBufferAndReset(data.data(), data.length(), data.length(), false); } // stream out (todo: fix up large sends and benchmark it again) @@ -123,20 +117,16 @@ struct HttpSocket { // what if the streamer cannot return any data? // then it should return something to pause write, and then start it again // basically we need throttling - writeToCorkBufferAndReset(chunk.data(), chunk.length(), length); + writeToCorkBufferAndReset(chunk.data(), chunk.length(), length, false); } else { // basically finish off the header section and send it as separate syscall (we do not copy anthing in this strategy) - writeToCorkBufferAndReset(nullptr, 0, length); + writeToCorkBufferAndReset(nullptr, 0, length, true); // just assume this went fine Data *httpData = (Data *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this); // 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); - } + static_dispatch(us_ssl_socket_write, us_socket_write)((SOCKET_TYPE *) this, chunk.data(), chunk.length(), 0); // if offset is at the end, we are done if (httpData->offset < length) { @@ -154,11 +144,7 @@ struct HttpSocket { std::string_view chunk = httpData->outStream(httpData->offset); // 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); - } + static_dispatch(us_ssl_socket_write, us_socket_write)((SOCKET_TYPE *) this, chunk.data(), chunk.length(), 0); } void onData(char *data, int length, std::function *, HttpRequest *)> &onHttpRequest) { diff --git a/uSockets b/uSockets index ad9a5fb..2760d77 160000 --- a/uSockets +++ b/uSockets @@ -1 +1 @@ -Subproject commit ad9a5fb11d417b49403bf9bf2d2d6f190c2b6e7a +Subproject commit 2760d77be39efbb79ba92e34ed6989921e523fec