First pass of overall cleanups

This commit is contained in:
Alex Hultman
2019-02-10 00:17:13 +01:00
parent cfac783cd9
commit f1bdbc968b
11 changed files with 39 additions and 54 deletions
+6 -16
View File
@@ -20,7 +20,6 @@
/* This class implements async socket memory management strategies */ /* This class implements async socket memory management strategies */
#include "LoopData.h" #include "LoopData.h"
#include "AsyncSocketData.h" #include "AsyncSocketData.h"
@@ -35,15 +34,12 @@ protected:
/* Get loop data for socket */ /* Get loop data for socket */
LoopData *getLoopData() { LoopData *getLoopData() {
return (LoopData *) us_loop_ext( return (LoopData *) us_loop_ext(us_new_socket_context_loop(SSL, us_new_socket_context(SSL, (us_new_socket_t *) this)));
us_new_socket_context_loop(SSL,
us_new_socket_context(SSL, (us_new_socket_t *) this))
);
} }
/* Get socket extension */ /* Get socket extension */
void *getExt() { AsyncSocketData<SSL> *getAsyncSocketData() {
return us_new_socket_ext(SSL, (us_new_socket_t *) this); return (AsyncSocketData<SSL> *) us_new_socket_ext(SSL, (us_new_socket_t *) this);
} }
/* Socket timeout */ /* Socket timeout */
@@ -81,20 +77,14 @@ protected:
loopData->corkOffset += size; loopData->corkOffset += size;
return {sendBuffer, false}; return {sendBuffer, false};
} else { } else {
// slow path for now /* Slow path for now, we want to always be corked if possible */
return {(char *) malloc(size), true}; return {(char *) malloc(size), true};
// if we are out of buffer, fail this completely?
} }
} }
/* Returns the user space backpressure. */ /* Returns the user space backpressure. */
int getBufferedAmount() { int getBufferedAmount() {
AsyncSocketData<SSL> *asyncSocketData = (AsyncSocketData<SSL> *) getExt(); return getAsyncSocketData()->buffer.size();
return asyncSocketData->buffer.size();
} }
/* Write in three levels of prioritization: cork-buffer, syscall, socket-buffer. Always drain if possible. /* Write in three levels of prioritization: cork-buffer, syscall, socket-buffer. Always drain if possible.
@@ -107,7 +97,7 @@ protected:
} }
LoopData *loopData = getLoopData(); LoopData *loopData = getLoopData();
AsyncSocketData<SSL> *asyncSocketData = (AsyncSocketData<SSL> *) getExt(); AsyncSocketData<SSL> *asyncSocketData = getAsyncSocketData();
/* We are limited if we have a per-socket buffer */ /* We are limited if we have a per-socket buffer */
if (asyncSocketData->buffer.length()) { if (asyncSocketData->buffer.length()) {
+9 -11
View File
@@ -22,13 +22,10 @@
#include "Loop.h" #include "Loop.h"
#include "HttpContextData.h" #include "HttpContextData.h"
#include "HttpResponseData.h" #include "HttpResponseData.h"
#include "AsyncSocket.h" #include "AsyncSocket.h"
#include <string_view> #include <string_view>
#include <functional>
#include "f2/function2.hpp" #include "f2/function2.hpp"
namespace uWS { namespace uWS {
@@ -36,6 +33,7 @@ template<bool> struct HttpResponse;
template <bool SSL> template <bool SSL>
struct HttpContext { struct HttpContext {
template<bool> friend struct TemplatedApp;
private: private:
HttpContext() = delete; HttpContext() = delete;
@@ -220,7 +218,7 @@ private:
us_new_socket_context_on_writable(SSL, getSocketContext(), [](auto *s) { us_new_socket_context_on_writable(SSL, getSocketContext(), [](auto *s) {
AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s; AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s;
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) asyncSocket->getExt(); HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) asyncSocket->getAsyncSocketData();
/* Ask the developer to write data and return success (true) or failure (false), OR skip sending anything and return success (true). */ /* Ask the developer to write data and return success (true) or failure (false), OR skip sending anything and return success (true). */
if (httpResponseData->onWritable) { if (httpResponseData->onWritable) {
@@ -272,6 +270,13 @@ private:
return this; return this;
} }
/* Used by App in its WebSocket handler */
void upgradeToWebSocket(void *newSocket) {
HttpContextData<SSL> *httpContextData = getSocketContextData();
httpContextData->upgradedWebSocket = newSocket;
}
public: public:
/* Construct a new HttpContext using specified loop */ /* 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_new_socket_context_options_t options = {}) {
@@ -319,13 +324,6 @@ public:
}); });
} }
// this should not be public
void upgradeToWebSocket(void *newSocket) {
HttpContextData<SSL> *httpContextData = getSocketContextData();
httpContextData->upgradedWebSocket = newSocket;
}
/* Listen to port using this HttpContext */ /* Listen to port using this HttpContext */
us_listen_socket *listen(const char *host, int port, int options) { 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>)); return us_new_socket_context_listen(SSL, getSocketContext(), host, port, options, sizeof(HttpResponseData<SSL>));
-2
View File
@@ -20,9 +20,7 @@
#include "HttpRouter.h" #include "HttpRouter.h"
#include <functional>
#include <vector> #include <vector>
#include "f2/function2.hpp" #include "f2/function2.hpp"
namespace uWS { namespace uWS {
+11 -18
View File
@@ -18,13 +18,13 @@
#ifndef HTTPPARSER_H #ifndef HTTPPARSER_H
#define HTTPPARSER_H #define HTTPPARSER_H
// todo: HttpParser is in need of a few clean-ups and refactorings
/* The HTTP parser is an independent module subject to unit testing / fuzz testing */ /* The HTTP parser is an independent module subject to unit testing / fuzz testing */
#include <string> #include <string>
#include <functional>
#include <cstring> #include <cstring>
#include <algorithm> #include <algorithm>
#include "f2/function2.hpp" #include "f2/function2.hpp"
namespace uWS { namespace uWS {
@@ -62,11 +62,6 @@ public:
return std::string_view(nullptr, 0); return std::string_view(nullptr, 0);
} }
// todo: implement this
/*int getHeader(std::string_view header) {
return 0;
}*/
std::string_view getUrl() { std::string_view getUrl() {
return std::string_view(headers->value.data(), querySeparator); return std::string_view(headers->value.data(), querySeparator);
} }
@@ -151,22 +146,20 @@ private:
req->headers->value = std::string_view(req->headers->value.data(), std::max<int>(0, req->headers->value.length() - 9)); req->headers->value = std::string_view(req->headers->value.data(), std::max<int>(0, req->headers->value.length() - 9));
// querySeparator is untested, todo: go through this /* Parse query */
const char *querySeparatorPtr = (const char *) memchr(req->headers->value.data(), '?', req->headers->value.length()); const char *querySeparatorPtr = (const char *) memchr(req->headers->value.data(), '?', req->headers->value.length());
req->querySeparator = (querySeparatorPtr ? querySeparatorPtr : req->headers->value.data() + req->headers->value.length()) - req->headers->value.data(); req->querySeparator = (querySeparatorPtr ? querySeparatorPtr : req->headers->value.data() + req->headers->value.length()) - req->headers->value.data();
// this one should return socket and exit on closed /* If returned socket is not what we put in we need
// what happens with data left for websockets? * to break here as we either have upgraded to
* WebSockets or otherwise closed the socket. */
void *returnedUser = requestHandler(user, req); void *returnedUser = requestHandler(user, req);
if (returnedUser != user) { if (returnedUser != user) {
// upgraded socket, or otherwise broken /* We are upgraded to WebSocket or otherwise broken */
// return pair of consumed and user
return {consumedTotal, returnedUser}; return {consumedTotal, returnedUser};
} }
// do not check this for GET! // todo: do not check this for GET (get should not have a body)
// todo: also support reading chunked streams // todo: also support reading chunked streams
std::string_view contentLengthString = req->getHeader("content-length"); std::string_view contentLengthString = req->getHeader("content-length");
if (contentLengthString.length()) { if (contentLengthString.length()) {
@@ -192,7 +185,6 @@ private:
public: public:
// todo: what can we do with the socket inside the handlers? we need to check on return from any handler if we closed or terminated or upgraded the socket
void *consumePostPadded(char *data, int length, void *user, fu2::unique_function<void *(void *, HttpRequest *)> &&requestHandler, fu2::unique_function<void *(void *, std::string_view, bool)> &&dataHandler, fu2::unique_function<void *(void *)> &&errorHandler) { void *consumePostPadded(char *data, int length, void *user, fu2::unique_function<void *(void *, HttpRequest *)> &&requestHandler, fu2::unique_function<void *(void *, std::string_view, bool)> &&dataHandler, fu2::unique_function<void *(void *)> &&errorHandler) {
HttpRequest req; HttpRequest req;
@@ -200,6 +192,7 @@ public:
if (remainingStreamingBytes) { if (remainingStreamingBytes) {
// this is exactly the same as below! // this is exactly the same as below!
// todo: refactor this
if (remainingStreamingBytes >= length) { if (remainingStreamingBytes >= length) {
void *returnedUser = dataHandler(user, std::string_view(data, length), remainingStreamingBytes == length); void *returnedUser = dataHandler(user, std::string_view(data, length), remainingStreamingBytes == length);
remainingStreamingBytes -= length; remainingStreamingBytes -= length;
@@ -222,7 +215,7 @@ public:
int maxCopyDistance = std::min(MAX_FALLBACK_SIZE - fallback.length(), (size_t) length); int maxCopyDistance = std::min(MAX_FALLBACK_SIZE - fallback.length(), (size_t) length);
fallback.reserve(maxCopyDistance + 32); // padding should be same as libus fallback.reserve(maxCopyDistance + 32); // todo: padding should be same as libus
fallback.append(data, maxCopyDistance); fallback.append(data, maxCopyDistance);
// break here on break // break here on break
@@ -260,7 +253,7 @@ public:
} else { } else {
if (fallback.length() == MAX_FALLBACK_SIZE) { if (fallback.length() == MAX_FALLBACK_SIZE) {
// you don't really need error handler, just return something strange! // note: you don't really need error handler, just return something strange!
// we could have it return a constant pointer to denote error! // we could have it return a constant pointer to denote error!
return errorHandler(user); return errorHandler(user);
} }
+1 -1
View File
@@ -44,7 +44,7 @@ struct HttpResponse : public AsyncSocket<SSL> {
typedef AsyncSocket<SSL> Super; typedef AsyncSocket<SSL> Super;
private: private:
HttpResponseData<SSL> *getHttpResponseData() { HttpResponseData<SSL> *getHttpResponseData() {
return (HttpResponseData<SSL> *) Super::getExt(); return (HttpResponseData<SSL> *) Super::getAsyncSocketData();
} }
/* Write an unsigned 32-bit integer in hex */ /* Write an unsigned 32-bit integer in hex */
-1
View File
@@ -22,7 +22,6 @@
#include "HttpParser.h" #include "HttpParser.h"
#include "AsyncSocketData.h" #include "AsyncSocketData.h"
#include <functional>
#include "f2/function2.hpp" #include "f2/function2.hpp"
+2 -1
View File
@@ -18,11 +18,12 @@
#ifndef HTTPROUTER_HPP #ifndef HTTPROUTER_HPP
#define HTTPROUTER_HPP #define HTTPROUTER_HPP
// todo: this module also needs a few clean-ups and simplifications
/* HTTP router is an independent module subject to unit testing and fuzz testing */ /* HTTP router is an independent module subject to unit testing and fuzz testing */
/* This module is not fully optimized yet, waiting for more features before doing so */ /* This module is not fully optimized yet, waiting for more features before doing so */
#include <map> #include <map>
#include <functional>
#include <vector> #include <vector>
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
+1 -3
View File
@@ -35,11 +35,9 @@ struct DeflationStream {
#else #else
#include <zlib.h> #include <zlib.h>
#include <string> #include <string>
#include <iostream>
#define LARGE_BUFFER_SIZE 1024 * 16 // fix this #define LARGE_BUFFER_SIZE 1024 * 16 // todo: fix this
struct ZlibContext { struct ZlibContext {
/* Any returned data is valid until next same-class call. /* Any returned data is valid until next same-class call.
+6
View File
@@ -27,6 +27,8 @@
#include <vector> #include <vector>
#include <set> #include <set>
// todo: obviously this module is WIP
namespace uWS { namespace uWS {
// publishing to a node, then another node, then another node should prioritize draining that way // publishing to a node, then another node, then another node should prioritize draining that way
@@ -71,6 +73,10 @@ private:
public: public:
~TopicTree() {
/* We have a few leaks here, I think */
}
TopicTree() { TopicTree() {
/* Dynamically hook us up with the Loop post handler */ /* Dynamically hook us up with the Loop post handler */
Loop::defaultLoop()->addPostHandler([this](Loop *loop) { Loop::defaultLoop()->addPostHandler([this](Loop *loop) {
+1 -1
View File
@@ -56,7 +56,7 @@ public:
bool send(std::string_view message, uWS::OpCode opCode = uWS::OpCode::BINARY, bool compress = false) { bool send(std::string_view message, uWS::OpCode opCode = uWS::OpCode::BINARY, bool compress = false) {
/* Transform the message to compressed domain if requested */ /* Transform the message to compressed domain if requested */
if (compress) { if (compress) {
WebSocketData *webSocketData = (WebSocketData *) Super::getExt(); WebSocketData *webSocketData = (WebSocketData *) Super::getAsyncSocketData();
/* Check and correct the compress hint */ /* Check and correct the compress hint */
if (opCode < 3 && webSocketData->compressionStatus == WebSocketData::ENABLED) { if (opCode < 3 && webSocketData->compressionStatus == WebSocketData::ENABLED) {
+2
View File
@@ -23,6 +23,8 @@
#include "WebSocketData.h" #include "WebSocketData.h"
#include "WebSocket.h" #include "WebSocket.h"
// todo: this module needs fixing! see below!
namespace uWS { namespace uWS {
template <bool SSL, bool isServer> template <bool SSL, bool isServer>