Add timeouts, make SSL paths identical to non-SSL
This commit is contained in:
@@ -10,7 +10,7 @@ void respond(T *s) {
|
|||||||
}, SIZE);
|
}, SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define USE_SSL
|
#define USE_SSL
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ int main(int argc, char **argv) {
|
|||||||
std::cout << "Connections: " << ++connections << std::endl;
|
std::cout << "Connections: " << ++connections << std::endl;
|
||||||
}).onHttpDisconnection([](auto *s) {
|
}).onHttpDisconnection([](auto *s) {
|
||||||
std::cout << "Connections: " << --connections << std::endl;
|
std::cout << "Connections: " << --connections << std::endl;
|
||||||
}).listen("localhost", 3000, 0);
|
}).listen(nullptr, 3000, 0);
|
||||||
|
|
||||||
uWS::run();
|
uWS::run();
|
||||||
// loop.run();
|
// loop.run();
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ class AppBase {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
static const unsigned int HTTP_IDLE_TIMEOUT_S = 10;
|
||||||
|
|
||||||
template <class A, class B>
|
template <class A, class B>
|
||||||
static constexpr typename std::conditional<SSL, A, B>::type *static_dispatch(A *a, B *b) {
|
static constexpr typename std::conditional<SSL, A, B>::type *static_dispatch(A *a, B *b) {
|
||||||
if constexpr(SSL) {
|
if constexpr(SSL) {
|
||||||
@@ -66,25 +68,13 @@ protected:
|
|||||||
static_dispatch(us_ssl_socket_context_on_open, us_socket_context_on_open)(httpServerContext, [](auto *s) {
|
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));
|
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;
|
new (static_dispatch(us_ssl_socket_ext, us_socket_ext)(s)) HTTP_SOCKET_DATA_TYPE;
|
||||||
|
|
||||||
if (appData->onHttpConnection) {
|
if (appData->onHttpConnection) {
|
||||||
appData->onHttpConnection((HttpSocket<SSL> *) s);
|
appData->onHttpConnection((HttpSocket<SSL> *) 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) {
|
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) {
|
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));
|
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
|
// onHttpRequest should probably be hard-coded to HttpRouter
|
||||||
((HttpSocket<SSL> *) s)->onData(data, length, appData->onHttpRequest);
|
((HttpSocket<SSL> *) 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_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<SSL> *) s)->onWritable();
|
((HttpSocket<SSL> *) s)->onWritable();
|
||||||
});
|
});
|
||||||
|
|
||||||
static_dispatch(us_ssl_socket_context_on_timeout, us_socket_context_on_timeout)(httpServerContext, [](auto *s) {
|
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;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-22
@@ -12,7 +12,7 @@
|
|||||||
template <bool SSL>
|
template <bool SSL>
|
||||||
struct HttpSocket {
|
struct HttpSocket {
|
||||||
|
|
||||||
const size_t MAX_FALLBACK_SIZE = 1024 * 4;
|
const size_t MAX_FALLBACK_SIZE = 4096;
|
||||||
|
|
||||||
template <class A, class B>
|
template <class A, class B>
|
||||||
static constexpr typename std::conditional<SSL, A, B>::type *static_dispatch(A *a, B *b) {
|
static constexpr typename std::conditional<SSL, A, B>::type *static_dispatch(A *a, B *b) {
|
||||||
@@ -66,7 +66,7 @@ struct HttpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// never rely on this one!
|
// 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)));
|
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);
|
memcpy(loopData->corkBuffer + loopData->corkOffset, "Content-Length: ", 16);
|
||||||
@@ -81,13 +81,7 @@ struct HttpSocket {
|
|||||||
memcpy(loopData->corkBuffer + loopData->corkOffset, src, length);
|
memcpy(loopData->corkBuffer + loopData->corkOffset, src, length);
|
||||||
loopData->corkOffset += length;
|
loopData->corkOffset += length;
|
||||||
|
|
||||||
int written;
|
int written = static_dispatch(us_ssl_socket_write, us_socket_write)((SOCKET_TYPE *) this, loopData->corkBuffer, loopData->corkOffset, expectMore);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
loopData->corkOffset = 0;
|
loopData->corkOffset = 0;
|
||||||
return written;
|
return written;
|
||||||
@@ -111,7 +105,7 @@ struct HttpSocket {
|
|||||||
// this should not be anything other than a simple convenience wrapper of streams!
|
// this should not be anything other than a simple convenience wrapper of streams!
|
||||||
void end(std::string_view data) {
|
void end(std::string_view data) {
|
||||||
// end should not explicitly flush the cork buffer! delay to when done with all http 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)
|
// 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?
|
// what if the streamer cannot return any data?
|
||||||
// then it should return something to pause write, and then start it again
|
// then it should return something to pause write, and then start it again
|
||||||
// basically we need throttling
|
// basically we need throttling
|
||||||
writeToCorkBufferAndReset(chunk.data(), chunk.length(), length);
|
writeToCorkBufferAndReset(chunk.data(), chunk.length(), length, false);
|
||||||
} else {
|
} else {
|
||||||
// basically finish off the header section and send it as separate syscall (we do not copy anthing in this strategy)
|
// 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
|
// just assume this went fine
|
||||||
Data *httpData = (Data *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this);
|
Data *httpData = (Data *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this);
|
||||||
|
|
||||||
// write that off!
|
// write that off!
|
||||||
if constexpr (SSL) {
|
static_dispatch(us_ssl_socket_write, us_socket_write)((SOCKET_TYPE *) this, chunk.data(), chunk.length(), 0);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if offset is at the end, we are done
|
// if offset is at the end, we are done
|
||||||
if (httpData->offset < length) {
|
if (httpData->offset < length) {
|
||||||
@@ -154,11 +144,7 @@ struct HttpSocket {
|
|||||||
std::string_view chunk = httpData->outStream(httpData->offset);
|
std::string_view chunk = httpData->outStream(httpData->offset);
|
||||||
|
|
||||||
// write that off!
|
// write that off!
|
||||||
if constexpr (SSL) {
|
static_dispatch(us_ssl_socket_write, us_socket_write)((SOCKET_TYPE *) this, chunk.data(), chunk.length(), 0);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onData(char *data, int length, std::function<void(HttpSocket<SSL> *, HttpRequest *)> &onHttpRequest) {
|
void onData(char *data, int length, std::function<void(HttpSocket<SSL> *, HttpRequest *)> &onHttpRequest) {
|
||||||
|
|||||||
+1
-1
Submodule uSockets updated: ad9a5fb11d...2760d77be3
Reference in New Issue
Block a user