diff --git a/15.pro b/15.pro index 93b5526..3200899 100644 --- a/15.pro +++ b/15.pro @@ -18,7 +18,8 @@ SOURCES += \ HEADERS += \ src/Hub.h \ src/Http.h \ - src/Context.h + src/Context.h \ + src/uWS.h #uSockets/libusockets.h \ #uSockets/internal/eventing/epoll.h \ #uSockets/internal/networking/bsd.h \ diff --git a/main.cpp b/main.cpp index 309a363..b3a3356 100644 --- a/main.cpp +++ b/main.cpp @@ -1,59 +1,22 @@ -// uWS.h -#include "Hub.h" +// this is roughly the interfaces I plan for (with changes and additional helpers added with time) +// much speaks for a header-only or header-mostly implementation now that uSockets is properly isolating its internal headers -char largeBuf[] = "HTTP/1.1 200 OK\r\nContent-Length: 512\r\n\r\n"; -int largeHttpBufSize = sizeof(largeBuf) + 512 - 1; -char *largeHttpBuf; +#include "uWS.h" int main() { - largeHttpBuf = (char *) malloc(largeHttpBufSize); - memcpy(largeHttpBuf, largeBuf, sizeof(largeBuf) - 1); - std::cout << "HttpSocket size: " << sizeof(HttpSocket) << std::endl; + std::cout << "HttpSocket size: " << sizeof(HttpSocket::Data) << std::endl; + char *buffer = new char[512]; // either use this, or use onHttpRoute but not both - uWS::defaultHub.onHttpRequest([](HttpSocket *s, HttpRequest *req) { + uWS::defaultHub.onHttpRequest([buffer](HttpSocket *s, HttpRequest *req) { - // we do not care for routers just yet! if (req->getUrl() == "/") { - // just write back for now! - - us_socket *us = (us_socket *) s; - us_socket_write(us, largeHttpBuf, largeHttpBufSize, 0); - + s->writeStatus(200)->writeHeader("Server", "µWebSockets v0.15")->end(buffer, 512); } else { - - std::cout << "Got HTTP request at URL: " << req->getUrl() << std::endl; } - - // get the URL here! - - - - // an http socket can BOTH send buffered data AND have one stream in and one stream out! - - // writeStatus(234314234) - // writeHeader(key, value) - // streamOut(asdasdasdsad) - - // if some asshole posted data, stream it in - /*s->streamIn([]() { - - });*/ - - //std::cout << "Got data: " << std::string(data, length) << std::endl; - - // s->writeStatus(); - // s->writeHeader(); - - // if url == / then stream index.htm - - // stream out the response - /*s->stream(largeHttpBufSize, [](int offset) { - return std::make_pair(largeHttpBuf + offset, largeHttpBufSize - offset); - });*/ }).listen("localhost", 3000, 0).run(); // todo: important swapping to SSL should be .secureListen(same interfaces) and work out of the box! diff --git a/src/Http.h b/src/Http.h index 4f5d2bd..8fc48e1 100644 --- a/src/Http.h +++ b/src/Http.h @@ -70,18 +70,65 @@ struct HttpRequest { }; -// HttpSocket is the ext of us_socket +// HttpSocket is an alias for us_socket struct HttpSocket { - // incomplete headers buffer - std::string headerBuffer; + // chunked response will be tricky with this buffering scheme + // if we do not fit, we can always use the header buffer for this (both in and out!) + // put first 8kb chunk in the http buffer, then from there it's the stream's job! + // httpheaders should only have 1 stream in and 1 stream out, but we can have helper wrappers - // + // data is stored in ext + struct Data { + // incomplete headers buffer + std::string headerBuffer; + int offset = 0; - HttpSocket() { + std::function(int)> outStream; + }; + // cork is stored in hub + char *getCorkBuffer() { + // context -> hub -> cork buffer + + us_socket *s = (us_socket *) this; + + // get the loop from the context! + //return us_socket_context_loop(us_socket_get_context(s)); + + + return corkBuffer; } + HttpSocket *writeStatus(int status) { + char *corkBuffer = getCorkBuffer(); + + char largeBuf[] = "HTTP/1.1 200 OK\r\nContent-Length: 512\r\n\r\n"; + + memcpy(corkBuffer + corkOffset, largeBuf, sizeof(largeBuf) - 1); + corkOffset += sizeof(largeBuf) - 1; + + return this; + } + + HttpSocket *writeHeader(char *key, char *value) { + return this; + } + + void end(char *data, int length) { + us_socket *s = (us_socket *) this; + + char *corkBuffer = getCorkBuffer(); + memcpy(corkBuffer + corkOffset, data, length); + corkOffset += length; + + us_socket_write(s, corkBuffer, corkOffset, 0); + corkOffset = 0; + } + + // can't create this! + HttpSocket() = delete; + // the HttpParser should maybe be moved out of this into its own HttpProtocol.h like with websocket? void parse(char *data, int length) { @@ -89,10 +136,7 @@ struct HttpSocket { } - int offset = 0; - - std::function(int)> outStream; - void stream(int length, decltype(outStream) stream); + void stream(int length, decltype(Data::outStream) stream); }; #endif // HTTP_H diff --git a/src/Hub.h b/src/Hub.h index 4663b60..754da67 100644 --- a/src/Hub.h +++ b/src/Hub.h @@ -1,3 +1,7 @@ +// should lie in hub and be connected with pre/post callbacks +char *corkBuffer = new char[1024]; +int corkOffset = 0; + #ifndef HUB_H #define HUB_H diff --git a/src/uWS.h b/src/uWS.h new file mode 100644 index 0000000..279c597 --- /dev/null +++ b/src/uWS.h @@ -0,0 +1,6 @@ +#ifndef UWS_H +#define UWS_H + +#include "Hub.h" + +#endif // UWS_H