void HTTPSocket<isServer>::onEnd(uS::Socket s) { s.cancelTimeout(); Data *httpSocketData = (Data *) s.getSocketData(); s.close(); if (!isServer) { ((Group<CLIENT> *) httpSocketData->nodeData)->errorHandler(httpSocketData->httpUser); } delete httpSocketData; }
void HttpSocket<isServer>::onEnd(uS::Socket s) { if (!s.isShuttingDown()) { if (isServer) { getGroup<isServer>(s)->removeHttpSocket(HttpSocket<isServer>(s)); getGroup<isServer>(s)->httpDisconnectionHandler(HttpSocket<isServer>(s)); } } else { s.cancelTimeout(); } Data *httpSocketData = (Data *) s.getSocketData(); s.close(); while (!httpSocketData->messageQueue.empty()) { uS::SocketData::Queue::Message *message = httpSocketData->messageQueue.front(); if (message->callback) { message->callback(nullptr, message->callbackData, true, nullptr); } httpSocketData->messageQueue.pop(); } while (httpSocketData->outstandingResponsesHead) { getGroup<isServer>(s)->httpCancelledRequestHandler(httpSocketData->outstandingResponsesHead); HttpResponse *next = httpSocketData->outstandingResponsesHead->next; delete httpSocketData->outstandingResponsesHead; httpSocketData->outstandingResponsesHead = next; } if (httpSocketData->preAllocatedResponse) { delete httpSocketData->preAllocatedResponse; } if (!isServer) { s.cancelTimeout(); getGroup<CLIENT>(s)->errorHandler(httpSocketData->httpUser); } delete httpSocketData; }
void HTTPSocket<isServer>::onData(uS::Socket s, char *data, int length) { HTTPSocket httpSocket(s); HTTPSocket::Data *httpData = httpSocket.getData(); // 5k = force close! if (httpData->httpBuffer.length() + length > 1024 * 5) { httpSocket.onEnd(s); return; } httpData->httpBuffer.append(data, length); size_t endOfHTTPBuffer = httpData->httpBuffer.find("\r\n\r\n"); if (endOfHTTPBuffer != std::string::npos) { if (isServer) { HTTPParser httpParser = (char *) httpData->httpBuffer.data(); std::pair<char *, size_t> secKey = {}, extensions = {}, subprotocol = {}, path = httpParser.value; for (httpParser++; httpParser.key.second; httpParser++) { if (httpParser.key.second == 17 || httpParser.key.second == 24 || httpParser.key.second == 22) { // lowercase the key for (size_t i = 0; i < httpParser.key.second; i++) { httpParser.key.first[i] = tolower(httpParser.key.first[i]); } if (!strncmp(httpParser.key.first, "sec-websocket-key", httpParser.key.second)) { secKey = httpParser.value; } else if (!strncmp(httpParser.key.first, "sec-websocket-extensions", httpParser.key.second)) { extensions = httpParser.value; } else if (!strncmp(httpParser.key.first, "sec-websocket-protocol", httpParser.key.second)) { subprotocol = httpParser.value; } } } if (secKey.first && secKey.second == 24) { // this needs to be part of upgrade itself, and shared with Hub::upgrade! bool perMessageDeflate = false; std::string extensionsResponse; if (extensions.first) { Group<isServer> *group = (Group<isServer> *) s.getNodeData(s.getSocketData()); ExtensionsNegotiator<uWS::SERVER> extensionsNegotiator(group->extensionOptions); extensionsNegotiator.readOffer(std::string(extensions.first, extensions.second)); extensionsResponse = extensionsNegotiator.generateOffer(); if (extensionsNegotiator.getNegotiatedOptions() & PERMESSAGE_DEFLATE) { perMessageDeflate = true; } } if (httpSocket.upgrade(secKey.first, extensionsResponse.data(), extensionsResponse.length(), subprotocol.first, subprotocol.second)) { s.cancelTimeout(); s.enterState<WebSocket<SERVER>>(new WebSocket<SERVER>::Data(perMessageDeflate, httpData)); ((Group<SERVER> *) s.getSocketData()->nodeData)->addWebSocket(s); //s.cork(true); ((Group<SERVER> *) s.getSocketData()->nodeData)->connectionHandler(WebSocket<SERVER>(s), {path.first, subprotocol.first, path.second, subprotocol.second}); //s.cork(false); delete httpData; } } else { httpSocket.onEnd(s); } } else { httpData->httpBuffer.resize(httpData->httpBuffer.length() + WebSocketProtocol<uWS::CLIENT>::CONSUME_POST_PADDING); bool isUpgrade = false; HTTPParser httpParser = (char *) httpData->httpBuffer.data(); //std::pair<char *, size_t> secKey = {}, extensions = {}; for (httpParser++; httpParser.key.second; httpParser++) { if (httpParser.key.second == 7) { // lowercase the key for (size_t i = 0; i < httpParser.key.second; i++) { httpParser.key.first[i] = tolower(httpParser.key.first[i]); } // lowercase the value for (size_t i = 0; i < httpParser.value.second; i++) { httpParser.value.first[i] = tolower(httpParser.value.first[i]); } if (!strncmp(httpParser.key.first, "upgrade", httpParser.key.second)) { if (!strncmp(httpParser.value.first, "websocket", 9)) { isUpgrade = true; } break; } } } if (isUpgrade) { s.enterState<WebSocket<CLIENT>>(new WebSocket<CLIENT>::Data(false, httpData)); //s.cork(true); httpSocket.cancelTimeout(); httpSocket.setUserData(httpData->httpUser); ((Group<CLIENT> *) s.getSocketData()->nodeData)->addWebSocket(s); ((Group<CLIENT> *) s.getSocketData()->nodeData)->connectionHandler(WebSocket<CLIENT>(s), {nullptr, nullptr, 0, 0}); //s.cork(false); if (!(s.isClosed() || s.isShuttingDown())) { WebSocketProtocol<CLIENT> *kws = (WebSocketProtocol<CLIENT> *) ((WebSocket<CLIENT>::Data *) s.getSocketData()); kws->consume((char *) httpData->httpBuffer.data() + endOfHTTPBuffer + 4, httpData->httpBuffer.length() - endOfHTTPBuffer - 4 - WebSocketProtocol<uWS::CLIENT>::CONSUME_POST_PADDING, s); } delete httpData; } else { httpSocket.onEnd(s); } } } }