Move most upgrading into HttpResponse
This commit is contained in:
@@ -25,8 +25,6 @@
|
||||
#include "HttpResponse.h"
|
||||
#include "WebSocketContext.h"
|
||||
#include "WebSocket.h"
|
||||
#include "WebSocketExtensions.h"
|
||||
#include "WebSocketHandshake.h"
|
||||
#include "PerMessageDeflate.h"
|
||||
|
||||
namespace uWS {
|
||||
@@ -168,69 +166,18 @@ public:
|
||||
|
||||
|
||||
// handle close here
|
||||
} else {
|
||||
/* Default handler upgrades to WebSocket */
|
||||
std::string_view secWebSocketProtocol = req->getHeader("sec-websocket-protocol");
|
||||
std::string_view secWebSocketExtensions = req->getHeader("sec-websocket-extensions");
|
||||
|
||||
res->upgrade(secWebSocketKey, secWebSocketProtocol, secWebSocketExtensions, behavior.compression);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Note: OpenSSL can be used here to speed this up somewhat */
|
||||
char secWebSocketAccept[29] = {};
|
||||
WebSocketHandshake::generate(secWebSocketKey.data(), secWebSocketAccept);
|
||||
|
||||
res->writeStatus("101 Switching Protocols")
|
||||
->writeHeader("Upgrade", "websocket")
|
||||
->writeHeader("Connection", "Upgrade")
|
||||
->writeHeader("Sec-WebSocket-Accept", secWebSocketAccept);
|
||||
|
||||
/* Select first subprotocol if present */
|
||||
std::string_view secWebSocketProtocol = req->getHeader("sec-websocket-protocol");
|
||||
if (secWebSocketProtocol.length()) {
|
||||
res->writeHeader("Sec-WebSocket-Protocol", secWebSocketProtocol.substr(0, secWebSocketProtocol.find(',')));
|
||||
}
|
||||
|
||||
/* Negotiate compression, we may use a smaller compression window than we negotiate */
|
||||
bool perMessageDeflate = false;
|
||||
/* We are always allowed to share compressor, if perMessageDeflate */
|
||||
int compressOptions = behavior.compression & SHARED_COMPRESSOR;
|
||||
if (behavior.compression != DISABLED) {
|
||||
std::string_view extensions = req->getHeader("sec-websocket-extensions");
|
||||
if (extensions.length()) {
|
||||
/* We never support client context takeover (the client cannot compress with a sliding window). */
|
||||
int wantedOptions = PERMESSAGE_DEFLATE | CLIENT_NO_CONTEXT_TAKEOVER;
|
||||
|
||||
/* Shared compressor is the default */
|
||||
if (behavior.compression == SHARED_COMPRESSOR) {
|
||||
/* Disable per-socket compressor */
|
||||
wantedOptions |= SERVER_NO_CONTEXT_TAKEOVER;
|
||||
}
|
||||
|
||||
/* isServer = true */
|
||||
ExtensionsNegotiator<true> extensionsNegotiator(wantedOptions);
|
||||
extensionsNegotiator.readOffer(extensions);
|
||||
|
||||
/* Todo: remove these mid string copies */
|
||||
std::string offer = extensionsNegotiator.generateOffer();
|
||||
if (offer.length()) {
|
||||
res->writeHeader("Sec-WebSocket-Extensions", offer);
|
||||
}
|
||||
|
||||
/* Did we negotiate permessage-deflate? */
|
||||
if (extensionsNegotiator.getNegotiatedOptions() & PERMESSAGE_DEFLATE) {
|
||||
perMessageDeflate = true;
|
||||
}
|
||||
|
||||
/* Is the server allowed to compress with a sliding window? */
|
||||
if (!(extensionsNegotiator.getNegotiatedOptions() & SERVER_NO_CONTEXT_TAKEOVER)) {
|
||||
compressOptions = behavior.compression;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This will add our mark */
|
||||
res->upgrade();
|
||||
|
||||
/* Move any backpressure */
|
||||
std::string backpressure(std::move(((AsyncSocketData<SSL> *) res->getHttpResponseData())->buffer));
|
||||
|
||||
@@ -249,7 +196,7 @@ public:
|
||||
|
||||
/* Initialize websocket with any moved backpressure intact */
|
||||
httpContext->upgradeToWebSocket(
|
||||
webSocket->init(perMessageDeflate, compressOptions, std::move(backpressure))
|
||||
webSocket->init(/*perMessageDeflate*/ false, /*compressOptions*/ 0, std::move(backpressure))
|
||||
);
|
||||
|
||||
/* Arm idleTimeout */
|
||||
|
||||
+58
-1
@@ -25,6 +25,9 @@
|
||||
#include "HttpContextData.h"
|
||||
#include "Utilities.h"
|
||||
|
||||
#include "WebSocketExtensions.h"
|
||||
#include "WebSocketHandshake.h"
|
||||
|
||||
#include "f2/function2.hpp"
|
||||
|
||||
/* todo: tryWrite is missing currently, only send smaller segments with write */
|
||||
@@ -162,7 +165,61 @@ private:
|
||||
}
|
||||
|
||||
/* This call is identical to end, but will never write content-length and is thus suitable for upgrades */
|
||||
void upgrade() {
|
||||
void upgrade(std::string_view secWebSocketKey, std::string_view secWebSocketProtocol, std::string_view secWebSocketExtensions, int compression) {
|
||||
|
||||
/* Note: OpenSSL can be used here to speed this up somewhat */
|
||||
char secWebSocketAccept[29] = {};
|
||||
WebSocketHandshake::generate(secWebSocketKey.data(), secWebSocketAccept);
|
||||
|
||||
writeStatus("101 Switching Protocols")
|
||||
->writeHeader("Upgrade", "websocket")
|
||||
->writeHeader("Connection", "Upgrade")
|
||||
->writeHeader("Sec-WebSocket-Accept", secWebSocketAccept);
|
||||
|
||||
/* Select first subprotocol if present */
|
||||
//std::string_view secWebSocketProtocol = req->getHeader("sec-websocket-protocol");
|
||||
if (secWebSocketProtocol.length()) {
|
||||
writeHeader("Sec-WebSocket-Protocol", secWebSocketProtocol.substr(0, secWebSocketProtocol.find(',')));
|
||||
}
|
||||
|
||||
/* Negotiate compression, we may use a smaller compression window than we negotiate */
|
||||
bool perMessageDeflate = false;
|
||||
/* We are always allowed to share compressor, if perMessageDeflate */
|
||||
int compressOptions = /*behavior.compression*/ compression & SHARED_COMPRESSOR;
|
||||
if (/*behavior.compression*/ compression != DISABLED) {
|
||||
//std::string_view extensions = req->getHeader("sec-websocket-extensions");
|
||||
if (secWebSocketExtensions.length()) {
|
||||
/* We never support client context takeover (the client cannot compress with a sliding window). */
|
||||
int wantedOptions = PERMESSAGE_DEFLATE | CLIENT_NO_CONTEXT_TAKEOVER;
|
||||
|
||||
/* Shared compressor is the default */
|
||||
if (/*behavior.compression*/ compression == SHARED_COMPRESSOR) {
|
||||
/* Disable per-socket compressor */
|
||||
wantedOptions |= SERVER_NO_CONTEXT_TAKEOVER;
|
||||
}
|
||||
|
||||
/* isServer = true */
|
||||
ExtensionsNegotiator<true> extensionsNegotiator(wantedOptions);
|
||||
extensionsNegotiator.readOffer(secWebSocketExtensions);
|
||||
|
||||
/* Todo: remove these mid string copies */
|
||||
std::string offer = extensionsNegotiator.generateOffer();
|
||||
if (offer.length()) {
|
||||
writeHeader("Sec-WebSocket-Extensions", offer);
|
||||
}
|
||||
|
||||
/* Did we negotiate permessage-deflate? */
|
||||
if (extensionsNegotiator.getNegotiatedOptions() & PERMESSAGE_DEFLATE) {
|
||||
perMessageDeflate = true;
|
||||
}
|
||||
|
||||
/* Is the server allowed to compress with a sliding window? */
|
||||
if (!(extensionsNegotiator.getNegotiatedOptions() & SERVER_NO_CONTEXT_TAKEOVER)) {
|
||||
compressOptions = /*behavior.*/compression;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internalEnd({nullptr, 0}, 0, false, false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user