Hook things up more
This commit is contained in:
@@ -27,7 +27,8 @@ HEADERS += \
|
|||||||
src/new_design/HttpContext.h \
|
src/new_design/HttpContext.h \
|
||||||
src/new_design/HttpContextData.h \
|
src/new_design/HttpContextData.h \
|
||||||
src/new_design/HttpResponseData.h \
|
src/new_design/HttpResponseData.h \
|
||||||
src/new_design/HttpResponse.h
|
src/new_design/HttpResponse.h \
|
||||||
|
src/new_design/StaticDispatch.h
|
||||||
|
|
||||||
INCLUDEPATH += uSockets/src src
|
INCLUDEPATH += uSockets/src src
|
||||||
#QMAKE_CXXFLAGS += -fsanitize=address
|
#QMAKE_CXXFLAGS += -fsanitize=address
|
||||||
|
|||||||
@@ -72,7 +72,9 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
httpContext->listen();
|
httpContext->listen(nullptr, 3000, 0);
|
||||||
|
|
||||||
|
loop.run();
|
||||||
|
|
||||||
httpContext->free();
|
httpContext->free();
|
||||||
|
|
||||||
|
|||||||
+115
-22
@@ -23,38 +23,140 @@ namespace uWS {
|
|||||||
|
|
||||||
// would it be okay to depend on the context?
|
// would it be okay to depend on the context?
|
||||||
|
|
||||||
// we depend on libusockets
|
// this basically should mean: libusockets wrapper
|
||||||
#include <libusockets.h>
|
#include "StaticDispatch.h"
|
||||||
|
|
||||||
template <bool SSL>
|
template <bool SSL>
|
||||||
struct HttpContext {
|
struct HttpContext : StaticDispatch<SSL> {
|
||||||
|
|
||||||
|
using SOCKET_CONTEXT_TYPE = typename StaticDispatch<SSL>::SOCKET_CONTEXT_TYPE;
|
||||||
|
using SOCKET_TYPE = typename StaticDispatch<SSL>::SOCKET_TYPE;
|
||||||
|
using StaticDispatch<SSL>::static_dispatch;
|
||||||
|
|
||||||
|
static const int HTTP_IDLE_TIMEOUT_S = 10;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HttpContext() = delete;
|
HttpContext() = delete;
|
||||||
|
|
||||||
// helper to get the socket context
|
// helper to get the socket context
|
||||||
us_socket_context *getSocketContext() {
|
SOCKET_CONTEXT_TYPE *getSocketContext() {
|
||||||
return (us_socket_context *) this;
|
return (SOCKET_CONTEXT_TYPE *) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SOCKET_CONTEXT_TYPE *getSocketContext(SOCKET_TYPE *s) {
|
||||||
|
return (SOCKET_CONTEXT_TYPE *) us_socket_get_context(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpContextData<SSL> *getSocketContextData() {
|
HttpContextData<SSL> *getSocketContextData() {
|
||||||
return (HttpContextData<SSL> *) us_socket_context_ext(getSocketContext());
|
return (HttpContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(getSocketContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
static HttpContextData<SSL> *getSocketContextData(SOCKET_TYPE *s) {
|
||||||
|
return (HttpContextData<SSL> *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(getSocketContext(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
HttpContext<SSL> *init() {
|
||||||
|
//new (data = (Data *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(httpServerContext)) Data();
|
||||||
|
|
||||||
|
static_dispatch(us_ssl_socket_context_on_open, us_socket_context_on_open)(getSocketContext(), [](auto *s, int is_client) {
|
||||||
|
HttpContextData<SSL> *httpContextData = getSocketContextData(s);
|
||||||
|
|
||||||
|
std::cout << "Opened http connection" << std::endl;
|
||||||
|
|
||||||
|
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;
|
||||||
|
*/
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
|
||||||
|
static_dispatch(us_ssl_socket_context_on_close, us_socket_context_on_close)(getSocketContext(), [](auto *s) {
|
||||||
|
HttpContextData<SSL> *httpContextData = getSocketContextData(s);
|
||||||
|
|
||||||
|
//((HTTP_SOCKET_DATA_TYPE *) static_dispatch(us_ssl_socket_ext, us_socket_ext)(s))->~HTTP_SOCKET_DATA_TYPE();
|
||||||
|
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
|
||||||
|
static_dispatch(us_ssl_socket_context_on_data, us_socket_context_on_data)(getSocketContext(), [](auto *s, char *data, int length) {
|
||||||
|
HttpContextData<SSL> *httpContextData = getSocketContextData(s);
|
||||||
|
|
||||||
|
// warning: should NOT reset timer on any data, ONLY reset data on full HTTP requests!
|
||||||
|
// warning: if we are in shutdown state, resetting the timer is a security issue!
|
||||||
|
static_dispatch(us_ssl_socket_timeout, us_socket_timeout)(s, HTTP_IDLE_TIMEOUT_S);
|
||||||
|
|
||||||
|
|
||||||
|
// here we should totally parse and route this all on our own, no involving the HttpResponse at all!
|
||||||
|
|
||||||
|
std::cout << "Got data!" << std::endl;
|
||||||
|
|
||||||
|
//Data *httpData = (Data *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this);
|
||||||
|
|
||||||
|
// we can reach the HttpResponseData which holds the parser, so let's just run the data through it from here (no onData) bullshit in the httpsocket!
|
||||||
|
|
||||||
|
// todo: this is where the HttpSocket binds together HttpParser and HttpRouter into one
|
||||||
|
/*httpData->httpParser.consumePostPadded(data, length, this, [&onHttpRequest](void *user, HttpRequest *httpRequest) {
|
||||||
|
onHttpRequest((HttpSocket<SSL> *) user, httpRequest);
|
||||||
|
}, [httpData](void *user, std::string_view data) {
|
||||||
|
if (httpData->inStream) {
|
||||||
|
httpData->inStream(data);
|
||||||
|
}
|
||||||
|
}, [](void *user) {
|
||||||
|
std::cout << "INVALID HTTP!" << std::endl;
|
||||||
|
});*/
|
||||||
|
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
|
||||||
|
static_dispatch(us_ssl_socket_context_on_writable, us_socket_context_on_writable)(getSocketContext(), [](auto *s) {
|
||||||
|
|
||||||
|
// what if the client
|
||||||
|
|
||||||
|
// I think it's fair to never mind this one -> if we keep writing data after shutting down then that's an issue for us
|
||||||
|
static_dispatch(us_ssl_socket_timeout, us_socket_timeout)(s, HTTP_IDLE_TIMEOUT_S);
|
||||||
|
|
||||||
|
|
||||||
|
// why? WE should emit this event via the socket data that we access!
|
||||||
|
((HttpSocket<SSL> *) s)->onWritable();
|
||||||
|
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
|
||||||
|
static_dispatch(us_ssl_socket_context_on_end, us_socket_context_on_end)(getSocketContext(), [](auto *s) {
|
||||||
|
std::cout << "Socket was half-closed!" << std::endl;
|
||||||
|
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
|
||||||
|
static_dispatch(us_ssl_socket_context_on_timeout, us_socket_context_on_timeout)(getSocketContext(), [](auto *s) {
|
||||||
|
|
||||||
|
if (static_dispatch(us_ssl_socket_is_shut_down, us_socket_is_shut_down)(s)) {
|
||||||
|
std::cout << "Forcefully closing socket since shutdown was not answered in time" << std::endl;
|
||||||
|
static_dispatch(us_ssl_socket_close, us_socket_close)(s);
|
||||||
|
} else {
|
||||||
|
std::cout << "Shutting down socket now" << std::endl;
|
||||||
|
static_dispatch(us_ssl_socket_timeout, us_socket_timeout)(s, HTTP_IDLE_TIMEOUT_S);
|
||||||
|
static_dispatch(us_ssl_socket_shutdown, us_socket_shutdown)(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
static HttpContext *create(us_loop *loop) {
|
static HttpContext *create(us_loop *loop) {
|
||||||
|
|
||||||
// todo: inplace initialize the data struct!
|
HttpContext *httpContext = (HttpContext *) us_create_socket_context(loop, sizeof(HttpContextData<SSL>));
|
||||||
|
|
||||||
// todo: actually register handlers on the socket context with the behavior of HTTP! (take from HttpApp.h)
|
return httpContext->init();
|
||||||
|
|
||||||
return (HttpContext *) us_create_socket_context(loop, sizeof(HttpContextData<SSL>));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void free() {
|
void free() {
|
||||||
us_socket_context_free((us_socket_context *) this);
|
static_dispatch(us_ssl_socket_context_free, us_socket_context_free)(getSocketContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
void onGet(std::string_view pattern, std::function<void(uWS::HttpResponse<SSL> *)> handler) {
|
void onGet(std::string_view pattern, std::function<void(uWS::HttpResponse<SSL> *)> handler) {
|
||||||
@@ -65,17 +167,8 @@ public:
|
|||||||
data->handler = handler;
|
data->handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void listen() {
|
void listen(const char *host, int port, int options) {
|
||||||
// simulate routing and parsing a request
|
static_dispatch(us_ssl_socket_context_listen, us_socket_context_listen)(getSocketContext(), host, port, options, sizeof(HttpContextData<SSL>));
|
||||||
|
|
||||||
HttpContextData<SSL> *data = getSocketContextData();
|
|
||||||
|
|
||||||
// we need to pass an actual socket! not nullptr!
|
|
||||||
|
|
||||||
// simulare
|
|
||||||
data->handler(nullptr);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef STATICDISPATCH_H
|
||||||
|
#define STATICDISPATCH_H
|
||||||
|
|
||||||
|
// this headers is basically a statically dispatched libusockets wrapper base
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
#include <libusockets.h>
|
||||||
|
|
||||||
|
template <bool SSL>
|
||||||
|
struct StaticDispatch {
|
||||||
|
template <class A, class B>
|
||||||
|
static constexpr typename std::conditional<SSL, A, B>::type *static_dispatch(A *a, B *b) {
|
||||||
|
if constexpr(SSL) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef typename std::conditional<SSL, us_ssl_socket, us_socket>::type SOCKET_TYPE;
|
||||||
|
typedef typename std::conditional<SSL, us_ssl_socket_context, us_socket_context>::type SOCKET_CONTEXT_TYPE;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STATICDISPATCH_H
|
||||||
Reference in New Issue
Block a user