From 4721b477431586afc0184ea5b75ed77f13573a03 Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Mon, 18 Jun 2018 22:11:59 +0200 Subject: [PATCH] Make it barely benchmarkable again --- 15.pro | 4 ++-- main.cpp | 25 ++++++++++++++++++++++ src/Http.h | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/Hub.h | 11 +++++++--- 4 files changed, 96 insertions(+), 5 deletions(-) diff --git a/15.pro b/15.pro index b4f6562..93b5526 100644 --- a/15.pro +++ b/15.pro @@ -13,7 +13,7 @@ SOURCES += \ uSockets/src/loop.c \ src/Hub.cpp \ src/Http.cpp \ - src/Context.cpp + src/Context.cpp HEADERS += \ src/Hub.h \ @@ -34,4 +34,4 @@ HEADERS += \ INCLUDEPATH += uSockets/src src #QMAKE_CXXFLAGS += -fsanitize=address -LIBS += -lasan -lssl -lcrypto +LIBS += -lssl -lcrypto diff --git a/main.cpp b/main.cpp index 14e3261..309a363 100644 --- a/main.cpp +++ b/main.cpp @@ -1,12 +1,37 @@ // uWS.h #include "Hub.h" +char largeBuf[] = "HTTP/1.1 200 OK\r\nContent-Length: 512\r\n\r\n"; +int largeHttpBufSize = sizeof(largeBuf) + 512 - 1; +char *largeHttpBuf; + int main() { + largeHttpBuf = (char *) malloc(largeHttpBufSize); + memcpy(largeHttpBuf, largeBuf, sizeof(largeBuf) - 1); + std::cout << "HttpSocket size: " << sizeof(HttpSocket) << std::endl; // either use this, or use onHttpRoute but not both uWS::defaultHub.onHttpRequest([](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); + + } 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) diff --git a/src/Http.h b/src/Http.h index 1f9a530..4f5d2bd 100644 --- a/src/Http.h +++ b/src/Http.h @@ -3,9 +3,70 @@ #include "libusockets.h" #include +#include +// holds the header pointers and wrappers struct HttpRequest { + struct Header { + char *key, *value; + unsigned int keyLength, valueLength; + }; + + #define MAX_HEADERS 100 + Header headers[MAX_HEADERS]; + + // UNSAFETY NOTE: assumes *end == '\r' (might unref end pointer) + char *getHeaders(char *buffer, char *end, struct Header *headers, size_t maxHeaders) { + for (unsigned int i = 0; i < maxHeaders; i++) { + for (headers->key = buffer; (*buffer != ':') & (*buffer > 32); *(buffer++) |= 32); + if (*buffer == '\r') { + if ((buffer != end) & (buffer[1] == '\n') & (i > 0)) { + headers->key = 0; + return buffer + 2; + } else { + return 0; + } + } else { + headers->keyLength = (unsigned int) (buffer - headers->key); + for (buffer++; (*buffer == ':' || *buffer < 33) && *buffer != '\r'; buffer++); + headers->value = buffer; + buffer = (char *) memchr(buffer, '\r', end - buffer); //for (; *buffer != '\r'; buffer++); + if (buffer /*!= end*/ && buffer[1] == '\n') { + headers->valueLength = (unsigned int) (buffer - headers->value); + buffer += 2; + headers++; + } else { + return 0; + } + } + } + return 0; + } + + std::string_view url; + + HttpRequest(char *data, int length) { + // parse the shit + data[length] = '\r'; + + if (getHeaders(data, data + length, headers, MAX_HEADERS)) { + + headers->valueLength = std::max(0, headers->valueLength - 9); + + // headers should really just be string_view from the start! + url = std::string_view(headers[0].value, headers[0].valueLength); + } + } + + std::string_view getUrl() { + return url; + } + + bool isComplete() { + return url.length(); + } + }; diff --git a/src/Hub.h b/src/Hub.h index e536a94..4663b60 100644 --- a/src/Hub.h +++ b/src/Hub.h @@ -78,7 +78,7 @@ struct Context { }); us_socket_context_on_data(httpContext, [](us_socket *s, char *data, int length) { - //Data *data = (Data *) us_socket_context_ext(us_socket_get_context(s)); + Data *contextData = (Data *) us_socket_context_ext(us_socket_get_context(s)); @@ -87,11 +87,16 @@ struct Context { // - + HttpRequest req(data, length); + if (req.isComplete()) { + contextData->onHttpRequest((HttpSocket *) s, &req); + } else { + std::cout << "Got chunked HTTP headers!" << std::endl; + } // here we run the HTTP parser on this data - std::cout << std::string_view(data, length) << std::endl; + // we always give pointers to us_socket? // same mistake as before?