Add concept of route yielding

This commit is contained in:
Alex Hultman
2019-01-22 18:30:25 +01:00
parent ed4e9f5c45
commit 9829f7fb37
4 changed files with 19 additions and 6 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ int main(int argc, char **argv) {
/* Use this route to signal stop listening */ /* Use this route to signal stop listening */
us_listen_socket_close(token); us_listen_socket_close(token);
token = nullptr; token = nullptr;
}).ws<PerSocketData>("/ws", { }).ws<PerSocketData>("/*", {
/* Settings */ /* Settings */
.compression = uWS::DEDICATED_COMPRESSOR, .compression = uWS::DEDICATED_COMPRESSOR,
.maxPayloadLength = 16 * 1024 * 1024, .maxPayloadLength = 16 * 1024 * 1024,
+2 -2
View File
@@ -217,8 +217,8 @@ public:
/* We do not need to check for any close or shutdown here as we immediately return from get handler */ /* We do not need to check for any close or shutdown here as we immediately return from get handler */
} else { } else {
/* For now we do not support having HTTP and websocket routes on the same URL */ /* Tell the router that we did not handle this request */
res->close(); req->setYield(true);
} }
})); }));
} }
+6 -3
View File
@@ -145,8 +145,7 @@ private:
/* Route the method and URL in two passes */ /* Route the method and URL in two passes */
typename HttpContextData<SSL>::RouterData routerData = {(HttpResponse<SSL> *) s, httpRequest}; typename HttpContextData<SSL>::RouterData routerData = {(HttpResponse<SSL> *) s, httpRequest};
bool firstPass = httpContextData->router.route(httpRequest->getMethod(), httpRequest->getUrl(), routerData); if (!httpContextData->router.route(httpRequest->getMethod(), httpRequest->getUrl(), routerData)) {
if (!firstPass) {
/* If first pass failed, we try and match by "any" method */ /* If first pass failed, we try and match by "any" method */
if (!httpContextData->router.route("*", httpRequest->getUrl(), routerData)) { 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 */ /* If second pass fail, we have to force close this socket as we have no handler for it */
@@ -311,10 +310,14 @@ public:
HttpContextData<SSL> *httpContextData = getSocketContextData(); HttpContextData<SSL> *httpContextData = getSocketContextData();
httpContextData->router.add(method, pattern, [handler](typename HttpContextData<SSL>::RouterData &user, std::pair<int, std::string_view *> params) { httpContextData->router.add(method, pattern, [handler](typename HttpContextData<SSL>::RouterData &user, std::pair<int, std::string_view *> params) {
user.httpRequest->setYield(false);
user.httpRequest->setParameters(params); user.httpRequest->setParameters(params);
handler(user.httpResponse, user.httpRequest); handler(user.httpResponse, user.httpRequest);
// for now all routes handle it /* If any handler yielded, the router will keep looking for a suitable handler. */
if (user.httpRequest->getYield()) {
return false;
}
return true; return true;
}); });
} }
+10
View File
@@ -37,10 +37,20 @@ private:
std::string_view key, value; std::string_view key, value;
} headers[MAX_HEADERS]; } headers[MAX_HEADERS];
int querySeparator; int querySeparator;
bool didYield;
std::pair<int, std::string_view *> currentParameters; std::pair<int, std::string_view *> currentParameters;
public: public:
bool getYield() {
return didYield;
}
/* If you do not want to handle this route */
void setYield(bool yield) {
didYield = yield;
}
std::string_view getHeader(std::string_view header) { std::string_view getHeader(std::string_view header) {
for (Header *h = headers; (++h)->key.length(); ) { for (Header *h = headers; (++h)->key.length(); ) {
if (h->key.length() == header.length() && !strncmp(h->key.data(), header.data(), header.length())) { if (h->key.length() == header.length() && !strncmp(h->key.data(), header.data(), header.length())) {