From 67fdec20726e48ba3a934cb25bb30d47ec4a4f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yaroslav=20De=20La=20Pe=C3=B1a=20Smirnov?= Date: Wed, 29 Nov 2017 11:44:34 +0300 Subject: Initial commit, version 0.5.3 --- node_modules/uws/src/Extensions.cpp | 131 ++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 node_modules/uws/src/Extensions.cpp (limited to 'node_modules/uws/src/Extensions.cpp') diff --git a/node_modules/uws/src/Extensions.cpp b/node_modules/uws/src/Extensions.cpp new file mode 100644 index 0000000..ef8f9da --- /dev/null +++ b/node_modules/uws/src/Extensions.cpp @@ -0,0 +1,131 @@ +#include "Extensions.h" + +namespace uWS { + +enum ExtensionTokens { + TOK_PERMESSAGE_DEFLATE = 1838, + TOK_SERVER_NO_CONTEXT_TAKEOVER = 2807, + TOK_CLIENT_NO_CONTEXT_TAKEOVER = 2783, + TOK_SERVER_MAX_WINDOW_BITS = 2372, + TOK_CLIENT_MAX_WINDOW_BITS = 2348 +}; + +class ExtensionsParser { +private: + int *lastInteger = nullptr; + +public: + bool perMessageDeflate = false; + bool serverNoContextTakeover = false; + bool clientNoContextTakeover = false; + int serverMaxWindowBits = 0; + int clientMaxWindowBits = 0; + + int getToken(const char *&in, const char *stop); + ExtensionsParser(const char *data, size_t length); +}; + +int ExtensionsParser::getToken(const char *&in, const char *stop) { + while (!isalnum(*in) && in != stop) { + in++; + } + + int hashedToken = 0; + while (isalnum(*in) || *in == '-' || *in == '_') { + if (isdigit(*in)) { + hashedToken = hashedToken * 10 - (*in - '0'); + } else { + hashedToken += *in; + } + in++; + } + return hashedToken; +} + +ExtensionsParser::ExtensionsParser(const char *data, size_t length) { + const char *stop = data + length; + int token = 1; + for (; token && token != TOK_PERMESSAGE_DEFLATE; token = getToken(data, stop)); + + perMessageDeflate = (token == TOK_PERMESSAGE_DEFLATE); + while ((token = getToken(data, stop))) { + switch (token) { + case TOK_PERMESSAGE_DEFLATE: + return; + case TOK_SERVER_NO_CONTEXT_TAKEOVER: + serverNoContextTakeover = true; + break; + case TOK_CLIENT_NO_CONTEXT_TAKEOVER: + clientNoContextTakeover = true; + break; + case TOK_SERVER_MAX_WINDOW_BITS: + serverMaxWindowBits = 1; + lastInteger = &serverMaxWindowBits; + break; + case TOK_CLIENT_MAX_WINDOW_BITS: + clientMaxWindowBits = 1; + lastInteger = &clientMaxWindowBits; + break; + default: + if (token < 0 && lastInteger) { + *lastInteger = -token; + } + break; + } + } +} + +template +ExtensionsNegotiator::ExtensionsNegotiator(int wantedOptions) { + options = wantedOptions; +} + +template +std::string ExtensionsNegotiator::generateOffer() { + std::string extensionsOffer; + if (options & Options::PERMESSAGE_DEFLATE) { + extensionsOffer += "permessage-deflate"; + + if (options & Options::CLIENT_NO_CONTEXT_TAKEOVER) { + extensionsOffer += "; client_no_context_takeover"; + } + + if (options & Options::SERVER_NO_CONTEXT_TAKEOVER) { + extensionsOffer += "; server_no_context_takeover"; + } + } + + return extensionsOffer; +} + +template +void ExtensionsNegotiator::readOffer(std::string offer) { + if (isServer) { + ExtensionsParser extensionsParser(offer.data(), offer.length()); + if ((options & PERMESSAGE_DEFLATE) && extensionsParser.perMessageDeflate) { + if (extensionsParser.clientNoContextTakeover || (options & CLIENT_NO_CONTEXT_TAKEOVER)) { + options |= CLIENT_NO_CONTEXT_TAKEOVER; + } + + if (extensionsParser.serverNoContextTakeover) { + options |= SERVER_NO_CONTEXT_TAKEOVER; + } else { + options &= ~SERVER_NO_CONTEXT_TAKEOVER; + } + } else { + options &= ~PERMESSAGE_DEFLATE; + } + } else { + // todo! + } +} + +template +int ExtensionsNegotiator::getNegotiatedOptions() { + return options; +} + +template class ExtensionsNegotiator; +template class ExtensionsNegotiator; + +} -- cgit v1.2.3