Upgrade to uSockets 0.2.0a1 (experimental)
This commit is contained in:
+38
-38
@@ -40,31 +40,31 @@ private:
|
||||
/* Maximum delay allowed until an HTTP connection is terminated due to outstanding request or rejected data (slow loris protection) */
|
||||
static const int HTTP_IDLE_TIMEOUT_S = 10;
|
||||
|
||||
us_new_socket_context_t *getSocketContext() {
|
||||
return (us_new_socket_context_t *) this;
|
||||
us_socket_context_t *getSocketContext() {
|
||||
return (us_socket_context_t *) this;
|
||||
}
|
||||
|
||||
static us_new_socket_context_t *getSocketContext(us_new_socket_t *s) {
|
||||
return (us_new_socket_context_t *) us_new_socket_context(SSL, s);
|
||||
static us_socket_context_t *getSocketContext(us_socket_t *s) {
|
||||
return (us_socket_context_t *) us_socket_context(SSL, s);
|
||||
}
|
||||
|
||||
HttpContextData<SSL> *getSocketContextData() {
|
||||
return (HttpContextData<SSL> *) us_new_socket_context_ext(SSL, getSocketContext());
|
||||
return (HttpContextData<SSL> *) us_socket_context_ext(SSL, getSocketContext());
|
||||
}
|
||||
|
||||
static HttpContextData<SSL> *getSocketContextDataS(us_new_socket_t *s) {
|
||||
return (HttpContextData<SSL> *) us_new_socket_context_ext(SSL, getSocketContext(s));
|
||||
static HttpContextData<SSL> *getSocketContextDataS(us_socket_t *s) {
|
||||
return (HttpContextData<SSL> *) us_socket_context_ext(SSL, getSocketContext(s));
|
||||
}
|
||||
|
||||
/* Init the HttpContext by registering libusockets event handlers */
|
||||
HttpContext<SSL> *init() {
|
||||
/* Handle socket connections */
|
||||
us_new_socket_context_on_open(SSL, getSocketContext(), [](us_new_socket_t *s, int is_client, char *ip, int ip_length) {
|
||||
us_socket_context_on_open(SSL, getSocketContext(), [](us_socket_t *s, int is_client, char *ip, int ip_length) {
|
||||
/* Any connected socket should timeout until it has a request */
|
||||
us_new_socket_timeout(SSL, s, HTTP_IDLE_TIMEOUT_S);
|
||||
us_socket_timeout(SSL, s, HTTP_IDLE_TIMEOUT_S);
|
||||
|
||||
/* Init socket ext */
|
||||
new (us_new_socket_ext(SSL, s)) HttpResponseData<SSL>;
|
||||
new (us_socket_ext(SSL, s)) HttpResponseData<SSL>;
|
||||
|
||||
/* Call filter */
|
||||
HttpContextData<SSL> *httpContextData = getSocketContextDataS(s);
|
||||
@@ -76,9 +76,9 @@ private:
|
||||
});
|
||||
|
||||
/* Handle socket disconnections */
|
||||
us_new_socket_context_on_close(SSL, getSocketContext(), [](us_new_socket_t *s) {
|
||||
us_socket_context_on_close(SSL, getSocketContext(), [](us_socket_t *s) {
|
||||
/* Get socket ext */
|
||||
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) us_new_socket_ext(SSL, s);
|
||||
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) us_socket_ext(SSL, s);
|
||||
|
||||
/* Call filter */
|
||||
HttpContextData<SSL> *httpContextData = getSocketContextDataS(s);
|
||||
@@ -98,7 +98,7 @@ private:
|
||||
});
|
||||
|
||||
/* Handle HTTP data streams */
|
||||
us_new_socket_context_on_data(SSL, getSocketContext(), [](us_new_socket_t *s, char *data, int length) {
|
||||
us_socket_context_on_data(SSL, getSocketContext(), [](us_socket_t *s, char *data, int length) {
|
||||
|
||||
// total overhead is about 210k down to 180k
|
||||
// ~210k req/sec is the original perf with write in data
|
||||
@@ -109,11 +109,11 @@ private:
|
||||
HttpContextData<SSL> *httpContextData = getSocketContextDataS(s);
|
||||
|
||||
/* Do not accept any data while in shutdown state */
|
||||
if (us_new_socket_is_shut_down(SSL, (us_new_socket_t *) s)) {
|
||||
if (us_socket_is_shut_down(SSL, (us_socket_t *) s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) us_new_socket_ext(SSL, s);
|
||||
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) us_socket_ext(SSL, s);
|
||||
|
||||
/* Cork this socket */
|
||||
((AsyncSocket<SSL> *) s)->cork();
|
||||
@@ -125,15 +125,15 @@ private:
|
||||
void *returnedSocket = httpResponseData->consumePostPadded(data, length, s, [httpContextData](void *s, uWS::HttpRequest *httpRequest) -> void * {
|
||||
/* For every request we reset the timeout and hang until user makes action */
|
||||
/* Warning: if we are in shutdown state, resetting the timer is a security issue! */
|
||||
us_new_socket_timeout(SSL, (us_new_socket_t *) s, 0);
|
||||
us_socket_timeout(SSL, (us_socket_t *) s, 0);
|
||||
|
||||
/* Reset httpResponse */
|
||||
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) us_new_socket_ext(SSL, (us_new_socket_t *) s);
|
||||
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) us_socket_ext(SSL, (us_socket_t *) s);
|
||||
httpResponseData->offset = 0;
|
||||
|
||||
/* Are we not ready for another request yet? Terminate the connection. */
|
||||
if (httpResponseData->state & HttpResponseData<SSL>::HTTP_RESPONSE_PENDING) {
|
||||
us_new_socket_close(SSL, (us_new_socket_t *) s);
|
||||
us_socket_close(SSL, (us_socket_t *) s);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ private:
|
||||
/* If first pass failed, we try and match by "any" method */
|
||||
if (!httpContextData->router.route("*", httpRequest->getUrl(), routerData)) {
|
||||
/* If second pass fail, we have to force close this socket as we have no handler for it */
|
||||
us_new_socket_close(SSL, (us_new_socket_t *) s);
|
||||
us_socket_close(SSL, (us_socket_t *) s);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -158,12 +158,12 @@ private:
|
||||
}
|
||||
|
||||
/* Was the socket closed? */
|
||||
if (us_new_socket_is_closed(SSL, (struct us_new_socket_t *) s)) {
|
||||
if (us_socket_is_closed(SSL, (struct us_socket_t *) s)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* We absolutely have to terminate parsing if shutdown */
|
||||
if (us_new_socket_is_shut_down(SSL, (us_new_socket_t *) s)) {
|
||||
if (us_socket_is_shut_down(SSL, (us_socket_t *) s)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ private:
|
||||
|
||||
/* If we have not responded and we have a data handler, we need to timeout to enfore client sending the data */
|
||||
if (!((HttpResponse<SSL> *) s)->hasResponded() && httpResponseData->inStream) {
|
||||
us_new_socket_timeout(SSL, (us_new_socket_t *) s, HTTP_IDLE_TIMEOUT_S);
|
||||
us_socket_timeout(SSL, (us_socket_t *) s, HTTP_IDLE_TIMEOUT_S);
|
||||
}
|
||||
|
||||
/* Continue parsing */
|
||||
@@ -188,25 +188,25 @@ private:
|
||||
|
||||
/* Getting a chunk of data while having a data handler should reset timeout (todo: if last, short timeout, if not last, bigger timeout) */
|
||||
/* Really, we only need to reset timeout to the larger delay if we are not fin */
|
||||
us_new_socket_timeout(SSL, (struct us_new_socket_t *) user, HTTP_IDLE_TIMEOUT_S);
|
||||
us_socket_timeout(SSL, (struct us_socket_t *) user, HTTP_IDLE_TIMEOUT_S);
|
||||
|
||||
/* We might respond in the handler, so do not change timeout after this */
|
||||
httpResponseData->inStream(data, fin);
|
||||
|
||||
/* Was the socket closed? */
|
||||
if (us_new_socket_is_closed(SSL, (struct us_new_socket_t *) user)) {
|
||||
if (us_socket_is_closed(SSL, (struct us_socket_t *) user)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* We absolutely have to terminate parsing if shutdown */
|
||||
if (us_new_socket_is_shut_down(SSL, (us_new_socket_t *) user)) {
|
||||
if (us_socket_is_shut_down(SSL, (us_socket_t *) user)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return user;
|
||||
}, [](void *user) {
|
||||
/* Close any socket on HTTP errors */
|
||||
us_new_socket_close(SSL, (us_new_socket_t *) user);
|
||||
us_socket_close(SSL, (us_socket_t *) user);
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
@@ -219,7 +219,7 @@ private:
|
||||
((AsyncSocket<SSL> *) s)->timeout(HTTP_IDLE_TIMEOUT_S);
|
||||
}
|
||||
|
||||
return (us_new_socket_t *) returnedSocket;
|
||||
return (us_socket_t *) returnedSocket;
|
||||
}
|
||||
|
||||
/* If we upgraded, check here (differ between nullptr close and nullptr upgrade) */
|
||||
@@ -234,7 +234,7 @@ private:
|
||||
httpContextData->upgradedWebSocket = nullptr;
|
||||
|
||||
/* Return the new upgraded websocket */
|
||||
return (us_new_socket_t *) asyncSocket;
|
||||
return (us_socket_t *) asyncSocket;
|
||||
}
|
||||
|
||||
/* We cannot return nullptr to the underlying stack in any case */
|
||||
@@ -242,7 +242,7 @@ private:
|
||||
});
|
||||
|
||||
/* Handle HTTP write out (note: SSL_read may trigger this spuriously, the app need to handle spurious calls) */
|
||||
us_new_socket_context_on_writable(SSL, getSocketContext(), [](us_new_socket_t *s) {
|
||||
us_socket_context_on_writable(SSL, getSocketContext(), [](us_socket_t *s) {
|
||||
|
||||
AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s;
|
||||
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) asyncSocket->getAsyncSocketData();
|
||||
@@ -250,7 +250,7 @@ private:
|
||||
/* Ask the developer to write data and return success (true) or failure (false), OR skip sending anything and return success (true). */
|
||||
if (httpResponseData->onWritable) {
|
||||
/* We are now writable, so hang timeout again, the user does not have to do anything so we should hang until end or tryEnd rearms timeout */
|
||||
us_new_socket_timeout(SSL, s, 0);
|
||||
us_socket_timeout(SSL, s, 0);
|
||||
|
||||
/* We expect the developer to return whether or not write was successful (true).
|
||||
* If write was never called, the developer should still return true so that we may drain. */
|
||||
@@ -277,7 +277,7 @@ private:
|
||||
});
|
||||
|
||||
/* Handle FIN, HTTP does not support half-closed sockets, so simply close */
|
||||
us_new_socket_context_on_end(SSL, getSocketContext(), [](us_new_socket_t *s) {
|
||||
us_socket_context_on_end(SSL, getSocketContext(), [](us_socket_t *s) {
|
||||
|
||||
/* We do not care for half closed sockets */
|
||||
AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s;
|
||||
@@ -286,7 +286,7 @@ private:
|
||||
});
|
||||
|
||||
/* Handle socket timeouts, simply close them so to not confuse client with FIN */
|
||||
us_new_socket_context_on_timeout(SSL, getSocketContext(), [](us_new_socket_t *s) {
|
||||
us_socket_context_on_timeout(SSL, getSocketContext(), [](us_socket_t *s) {
|
||||
|
||||
/* Force close rather than gracefully shutdown and risk confusing the client with a complete download */
|
||||
AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s;
|
||||
@@ -306,17 +306,17 @@ private:
|
||||
|
||||
public:
|
||||
/* Construct a new HttpContext using specified loop */
|
||||
static HttpContext *create(Loop *loop, us_new_socket_context_options_t options = {}) {
|
||||
static HttpContext *create(Loop *loop, us_socket_context_options_t options = {}) {
|
||||
HttpContext *httpContext;
|
||||
|
||||
httpContext = (HttpContext *) us_new_create_socket_context(SSL, (us_loop *) loop, sizeof(HttpContextData<SSL>), options);
|
||||
httpContext = (HttpContext *) us_create_socket_context(SSL, (us_loop_t *) loop, sizeof(HttpContextData<SSL>), options);
|
||||
|
||||
if (!httpContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Init socket context data */
|
||||
new ((HttpContextData<SSL> *) us_new_socket_context_ext(SSL, (us_new_socket_context_t *) httpContext)) HttpContextData<SSL>();
|
||||
new ((HttpContextData<SSL> *) us_socket_context_ext(SSL, (us_socket_context_t *) httpContext)) HttpContextData<SSL>();
|
||||
return httpContext->init();
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ public:
|
||||
httpContextData->~HttpContextData<SSL>();
|
||||
|
||||
/* Free the socket context in whole */
|
||||
us_new_socket_context_free(SSL, getSocketContext());
|
||||
us_socket_context_free(SSL, getSocketContext());
|
||||
}
|
||||
|
||||
void filter(fu2::unique_function<void(HttpResponse<SSL> *, int)> &&filterHandler) {
|
||||
@@ -352,8 +352,8 @@ public:
|
||||
}
|
||||
|
||||
/* Listen to port using this HttpContext */
|
||||
us_listen_socket *listen(const char *host, int port, int options) {
|
||||
return us_new_socket_context_listen(SSL, getSocketContext(), host, port, options, sizeof(HttpResponseData<SSL>));
|
||||
us_listen_socket_t *listen(const char *host, int port, int options) {
|
||||
return us_socket_context_listen(SSL, getSocketContext(), host, port, options, sizeof(HttpResponseData<SSL>));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user