Fix most of the errors

This commit is contained in:
Jarred Sumner
2022-06-17 20:29:56 -07:00
committed by Jarred Sumner
parent 89f08aae27
commit 71025c8bcc
6 changed files with 117 additions and 119 deletions

View File

@@ -1,23 +1,24 @@
#include "ScriptExecutionContext.h"
#include <uws/uSockets/src/libusockets.h>
#include <uws/src/Loop.h>
#include <uws/src/App.h>
#include "WebSocketStream.h"
extern "C" void Bun__startLoop(us_loop_t* loop);
namespace WebCore {
template<bool isSSL>
us_socket_context_t* webSocketContext()
us_socket_context_t* ScriptExecutionContext::webSocketContext()
{
if constexpr (isSSL) {
if (!m_ssl_client_websockets_ctx) {
us_loop_t* loop = (us_loop_t*)uWS::Loop::get();
us_socket_context_options_t opts;
memset(&opts, 0, sizeof(us_socket_context_t));
this->m_ssl_client_websockets_ctx = us_create_socket_context(1, loop, sizeof(*ScriptExecutionContext), opts);
*us_socket_context_ext(m_ssl_client_websockets_ctx) = this;
WebSocketStream::registerHTTPContext(this, m_ssl_client_websockets_ctx, loop);
memset(&opts, 0, sizeof(us_socket_context_options_t));
this->m_ssl_client_websockets_ctx = us_create_socket_context(1, loop, sizeof(size_t), opts);
void** ptr = reinterpret_cast<void**>(us_socket_context_ext(1, m_ssl_client_websockets_ctx));
*ptr = this;
registerHTTPContextForWebSocket<isSSL, false>(this, m_ssl_client_websockets_ctx);
}
return m_ssl_client_websockets_ctx;
@@ -25,10 +26,11 @@ us_socket_context_t* webSocketContext()
if (!m_client_websockets_ctx) {
us_loop_t* loop = (us_loop_t*)uWS::Loop::get();
us_socket_context_options_t opts;
memset(&opts, 0, sizeof(us_socket_context_t));
this->m_client_websockets_ctx = us_create_socket_context(0, loop, sizeof(*ScriptExecutionContext), opts);
*us_socket_context_ext(m_client_websockets_ctx) = this;
SecureWebSocketStream::registerHTTPContext(this, m_client_websockets_ctx, loop);
memset(&opts, 0, sizeof(us_socket_context_options_t));
this->m_client_websockets_ctx = us_create_socket_context(0, loop, sizeof(size_t), opts);
void** ptr = reinterpret_cast<void**>(us_socket_context_ext(0, m_client_websockets_ctx));
*ptr = this;
registerHTTPContextForWebSocket<isSSL, false>(this, m_client_websockets_ctx);
}
return m_client_websockets_ctx;
@@ -36,13 +38,13 @@ us_socket_context_t* webSocketContext()
}
template<bool isSSL, bool isServer>
uWS::WebSocketContext<isSSL, isServer, ScriptExecutionContext*>*
uWS::WebSocketContext<isSSL, isServer, ScriptExecutionContext*>* ScriptExecutionContext::connnectedWebSocketContext()
{
if constexpr (isSSL) {
if (!m_connected_ssl_client_websockets_ctx) {
// should be the parent
RELEASE_ASSERT(m_ssl_client_websockets_ctx);
m_connected_client_websockets_ctx = SecureWebSocketStream::registerClientContext(this, webSocketContext<isSSL>(), loop);
m_connected_client_websockets_ctx = registerWebSocketClientContext(this, webSocketContext<isSSL>());
}
return m_connected_ssl_client_websockets_ctx;
@@ -50,7 +52,7 @@ uWS::WebSocketContext<isSSL, isServer, ScriptExecutionContext*>*
if (!m_connected_client_websockets_ctx) {
// should be the parent
RELEASE_ASSERT(m_client_websockets_ctx);
m_connected_client_websockets_ctx = WebSocketStream::registerClientContext(this, webSocketContext<isSSL>(), loop);
m_connected_client_websockets_ctx = registerWebSocketClientContext(this, webSocketContext<isSSL>());
}
return m_connected_client_websockets_ctx;

View File

@@ -10,7 +10,11 @@
#include <wtf/text/WTFString.h>
#include "CachedScript.h"
#include "wtf/URL.h"
#include <uws/src/WebSocketContext.h>
namespace uWS {
template<bool isServer, bool isClient, typename UserData>
struct WebSocketContext;
}
struct us_socket_t;
struct us_socket_context_t;
@@ -106,7 +110,7 @@ private:
us_socket_context_t* m_ssl_client_websockets_ctx = nullptr;
us_socket_context_t* m_client_websockets_ctx = nullptr;
uWS::WebSocketContext<true, false, ScriptExecutionContext*>* m_ssl_client_websockets_ctx = nullptr;
uWS::WebSocketContext<true, true, ScriptExecutionContext*>* m_client_websockets_ctx = nullptr;
uWS::WebSocketContext<true, false, ScriptExecutionContext*>* m_connected_ssl_client_websockets_ctx = nullptr;
uWS::WebSocketContext<true, true, ScriptExecutionContext*>* m_connected_client_websockets_ctx = nullptr;
};
}

View File

@@ -69,6 +69,8 @@
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#include <uws/src/App.h>
// #if USE(WEB_THREAD)
// #include "WebCoreThreadRun.h"
// #endif
@@ -78,6 +80,20 @@ using ThreadableWebSocketChannel = WebSocketStream;
using WebSocketChannelClient = WebSocketStream;
WTF_MAKE_ISO_ALLOCATED_IMPL(WebSocket);
static size_t getFramingOverhead(size_t payloadSize)
{
static const size_t hybiBaseFramingOverhead = 2; // Every frame has at least two-byte header.
static const size_t hybiMaskingKeyLength = 4; // Every frame from client must have masking key.
static const size_t minimumPayloadSizeWithTwoByteExtendedPayloadLength = 126;
static const size_t minimumPayloadSizeWithEightByteExtendedPayloadLength = 0x10000;
size_t overhead = hybiBaseFramingOverhead + hybiMaskingKeyLength;
if (payloadSize >= minimumPayloadSizeWithEightByteExtendedPayloadLength)
overhead += 8;
else if (payloadSize >= minimumPayloadSizeWithTwoByteExtendedPayloadLength)
overhead += 2;
return overhead;
}
const size_t maxReasonSizeInBytes = 123;
static inline bool isValidProtocolCharacter(UChar character)
@@ -145,8 +161,6 @@ WebSocket::WebSocket(ScriptExecutionContext& context)
: ContextDestructionObserver(&context)
, m_subprotocol(emptyString())
, m_extensions(emptyString())
, m_handshake(url, )
{
}
@@ -164,19 +178,19 @@ WebSocket::~WebSocket()
switch (m_connectedWebSocketKind) {
case ConnectedWebSocketKind::Client: {
this->m_connectedWebSocket.client->end(code);
this->m_connectedWebSocket.client->end(None);
break;
}
case ConnectedWebSocketKind::ClientSSL: {
this->m_connectedWebSocket.clientSSL->end(code);
this->m_connectedWebSocket.clientSSL->end(None);
break;
}
case ConnectedWebSocketKind::Server: {
this->m_connectedWebSocket.server->end(code);
this->m_connectedWebSocket.server->end(None);
break;
}
case ConnectedWebSocketKind::ServerSSL: {
this->m_connectedWebSocket.serverSSL->end(code);
this->m_connectedWebSocket.serverSSL->end(None);
break;
}
default: {
@@ -195,10 +209,10 @@ ExceptionOr<Ref<WebSocket>> WebSocket::create(ScriptExecutionContext& context, c
if (url.isNull())
return Exception { SyntaxError };
auto socket = adoptRef(*new WebSocket(context, url));
auto socket = adoptRef(*new WebSocket(context));
// socket->suspendIfNeeded();
auto result = socket->connect(url.string(), protocols);
auto result = socket->connect(url, protocols);
// auto result = socket->connect(url, protocols);
if (result.hasException())
@@ -351,16 +365,20 @@ ExceptionOr<void> WebSocket::connect(const String& url, const Vector<String>& pr
auto resource = resourceName(m_url);
ZigString path = Zig::toZigString(resource);
ZigString clientProtocolString = Zig::toZigString(protocolString);
uint16_t port = m_url.port();
uint16_t port = is_secure ? 443 : 80;
if (auto userPort = m_url.port()) {
port = userPort.value();
}
m_isSecure = is_secure;
if (is_secure) {
us_socket_context_t* ctx = scriptExecutionContext->webSocketContext<true>();
us_socket_context_t* ctx = scriptExecutionContext()->webSocketContext<true>();
RELEASE_ASSERT(ctx);
this->m_upgradeClient = Bun_SecureWebSocketUpgradeClient__connect(scriptExecutionContext->jsGlobalObject(), ctx, this, &host, port, &path, &clientProtocolString);
this->m_upgradeClient = Bun_SecureWebSocketUpgradeClient__connect(scriptExecutionContext()->jsGlobalObject(), ctx, this, &host, port, &path, &clientProtocolString);
} else {
us_socket_context_t* ctx = scriptExecutionContext->webSocketContext<false>();
us_socket_context_t* ctx = scriptExecutionContext()->webSocketContext<false>();
RELEASE_ASSERT(ctx);
this->m_upgradeClient = Bun_WebSocketUpgradeClient__connect(scriptExecutionContext->jsGlobalObject(), ctx, this, &host, port, &path, &clientProtocolString);
this->m_upgradeClient = Bun_WebSocketUpgradeClient__connect(scriptExecutionContext()->jsGlobalObject(), ctx, this, &host, port, &path, &clientProtocolString);
}
if (this->m_upgradeClient == nullptr) {
@@ -439,8 +457,8 @@ ExceptionOr<void> WebSocket::send(ArrayBufferView& arrayBufferView)
}
ASSERT(m_channel);
auto buffer = arrayBufferView.unsharedBuffer();
char* baseAddress = reinterpret_cast<char*>(buffer.baseAddress()) + arrayBufferView.byteOffset();
auto buffer = arrayBufferView.unsharedBuffer().get();
char* baseAddress = reinterpret_cast<char*>(buffer->data()) + arrayBufferView.byteOffset();
size_t length = arrayBufferView.byteLength();
if (length > 0)
this->sendWebSocketData<true>(baseAddress, length);
@@ -468,10 +486,10 @@ ExceptionOr<void> WebSocket::send(ArrayBufferView& arrayBufferView)
template<bool isBinary>
void WebSocket::sendWebSocketData(const char* baseAddress, size_t length)
{
uWS::OpCode opCode = uWS::OpCode::Text;
uWS::OpCode opCode = uWS::OpCode::TEXT;
if constexpr (isBinary)
opCode = uWS::OpCode::Binary;
opCode = uWS::OpCode::BINARY;
switch (m_connectedWebSocketKind) {
case ConnectedWebSocketKind::Client: {
@@ -732,7 +750,7 @@ void WebSocket::didReceiveBinaryData(Vector<uint8_t>&& binaryData)
// });
}
void WebSocket::didReceiveMessageError(String&& reason)
void WebSocket::didReceiveMessageError(WTF::StringImpl::StaticStringImpl* reason)
{
LOG(Network, "WebSocket %p didReceiveErrorMessage()", this);
// queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this, reason = WTFMove(reason)] {
@@ -747,26 +765,7 @@ void WebSocket::didReceiveMessageError(String&& reason)
// }
// FIXME: As per https://html.spec.whatwg.org/multipage/web-sockets.html#feedback-from-the-protocol:concept-websocket-closed, we should synchronously fire a close event.
dispatchErrorEventIfNeeded();
// });
}
void WebSocket::didReceiveMessageError(String& reason)
{
LOG(Network, "WebSocket %p didReceiveErrorMessage()", this);
// queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this, reason = WTFMove(reason)] {
if (m_state == CLOSED)
return;
m_state = CLOSED;
ASSERT(scriptExecutionContext());
// if (UNLIKELY(InspectorInstrumentation::hasFrontends())) {
// if (auto* inspector = m_channel->channelInspector())
// inspector->didReceiveWebSocketFrameError(reason);
// }
// FIXME: As per https://html.spec.whatwg.org/multipage/web-sockets.html#feedback-from-the-protocol:concept-websocket-closed, we should synchronously fire a close event.
dispatchEvent(CloseEvent::create(false, 0, reason));
dispatchEvent(CloseEvent::create(false, 0, WTF::String(reason)));
// });
}
@@ -819,25 +818,11 @@ void WebSocket::didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompl
// });
}
void WebSocket::didUpgradeURL()
{
ASSERT(m_url.protocolIs("ws"));
m_url.setProtocol("wss");
}
size_t WebSocket::getFramingOverhead(size_t payloadSize)
{
static const size_t hybiBaseFramingOverhead = 2; // Every frame has at least two-byte header.
static const size_t hybiMaskingKeyLength = 4; // Every frame from client must have masking key.
static const size_t minimumPayloadSizeWithTwoByteExtendedPayloadLength = 126;
static const size_t minimumPayloadSizeWithEightByteExtendedPayloadLength = 0x10000;
size_t overhead = hybiBaseFramingOverhead + hybiMaskingKeyLength;
if (payloadSize >= minimumPayloadSizeWithEightByteExtendedPayloadLength)
overhead += 8;
else if (payloadSize >= minimumPayloadSizeWithTwoByteExtendedPayloadLength)
overhead += 2;
return overhead;
}
// void WebSocket::didUpgradeURL()
// {
// ASSERT(m_url.protocolIs("ws"));
// m_url.setProtocol("wss");
// }
void WebSocket::dispatchErrorEventIfNeeded()
{
@@ -850,24 +835,24 @@ void WebSocket::dispatchErrorEventIfNeeded()
void WebSocket::didConnect(us_socket_t* socket, char* bufferedData, size_t bufferedDataSize)
{
m_state = CONNECTED;
m_state = OPEN;
this->m_upgradeClient = nullptr;
if (m_isSecure) {
/* Adopting a socket invalidates it, do not rely on it directly to carry any data */
uWS::WebSocket<true, false, WebSocket*>* webSocket = (uWS::WebSocket<true, false, WebSocket*>*)us_socket_context_adopt_socket(1,
(us_socket_context_t*)this->scriptExecutionContext()->connnectedWebSocketContext<true>(), socket, sizeof(uWS::WebSocketData) + sizeof(WebSocket*));
(us_socket_context_t*)this->scriptExecutionContext()->connnectedWebSocketContext<true, false>(), socket, sizeof(uWS::WebSocketData) + sizeof(WebSocket*));
webSocket->init(0, uWS::CompressOptions::disabled, uWS::Backpressure());
*webSocket->getExt() = this;
webSocket->init(0, uWS::CompressOptions::DISABLED, uWS::BackPressure());
*webSocket->getUserData() = this;
this->m_connectedWebSocket.clientSSL = webSocket;
this->m_connectedWebSocketKind = ConnectedWebSocketKind::ClientSSL;
} else {
/* Adopting a socket invalidates it, do not rely on it directly to carry any data */
uWS::WebSocket<false, false, WebSocket*>* webSocket = (uWS::WebSocket<false, false, WebSocket*>*)us_socket_context_adopt_socket(1,
(us_socket_context_t*)this->scriptExecutionContext()->connnectedWebSocketContext<false>(), socket, sizeof(uWS::WebSocketData) + sizeof(WebSocket*));
(us_socket_context_t*)this->scriptExecutionContext()->connnectedWebSocketContext<false, false>(), socket, sizeof(uWS::WebSocketData) + sizeof(WebSocket*));
webSocket->init(0, uWS::CompressOptions::disabled, uWS::Backpressure());
*webSocket->getExt() = this;
webSocket->init(0, uWS::CompressOptions::DISABLED, uWS::BackPressure());
*webSocket->getUserData() = this;
this->m_connectedWebSocket.client = webSocket;
this->m_connectedWebSocketKind = ConnectedWebSocketKind::Client;
}
@@ -996,11 +981,11 @@ void WebSocket::didFailToConnect(int32_t code)
}
} // namespace WebCore
extern "C" WebSocket__didConnect(WebCore::WebSocket* webSocket, us_socket_t* socket, char* bufferedData, size_t len)
extern "C" void WebSocket__didConnect(WebCore::WebSocket* webSocket, us_socket_t* socket, char* bufferedData, size_t len)
{
webSocket->didConnect(socket, bufferedData, len);
}
extern "C" WebSocket__didFailToConnect(WebCore::WebSocket* webSocket, int32_t errorCode)
extern "C" void WebSocket__didFailToConnect(WebCore::WebSocket* webSocket, int32_t errorCode)
{
webSocket->didFailToConnect(socket, errorCode);
webSocket->didFailToConnect(errorCode);
}

View File

@@ -70,7 +70,8 @@ public:
CONNECTING = 0,
OPEN = 1,
CLOSING = 2,
CLOSED = 3
CLOSED = 3,
};
ExceptionOr<void> connect(const String& url);
@@ -100,12 +101,16 @@ public:
using RefCounted::deref;
using RefCounted::ref;
void didConnect();
void didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompletionStatus, unsigned short code, const String& reason);
void didConnect(us_socket_t* socket, char* bufferedData, size_t bufferedDataSize);
void didFailToConnect(int32_t code);
private:
typedef union AnyWebSocket {
uWS::WebSocket<false, false, WebSocket*>* client;
uWS::WebSocket<false, true, WebSocket*>* clientSSL;
uWS::WebSocket<true, false, WebSocket*>* server;
uWS::WebSocket<true, false, WebSocket*>* clientSSL;
uWS::WebSocket<false, true, WebSocket*>* server;
uWS::WebSocket<true, true, WebSocket*>* serverSSL;
} AnyWebSocket;
enum ConnectedWebSocketKind {
@@ -117,6 +122,7 @@ private:
};
explicit WebSocket(ScriptExecutionContext&);
explicit WebSocket(ScriptExecutionContext&, const String& url);
void dispatchErrorEventIfNeeded();
@@ -131,16 +137,14 @@ private:
void refEventTarget() final { ref(); }
void derefEventTarget() final { deref(); }
void didConnect();
void didReceiveMessage(String&& message);
void didReceiveData(const char* data, size_t length);
void didReceiveBinaryData(Vector<uint8_t>&&);
void didReceiveMessageError(String&& reason);
void didReceiveMessageError(WTF::StringImpl::StaticStringImpl* reason);
void didUpdateBufferedAmount(unsigned bufferedAmount);
void didStartClosingHandshake();
void didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompletionStatus, unsigned short code, const String& reason);
void didConnect(us_socket_t* socket, char* bufferedData, size_t bufferedDataSize);
void didFailToConnect(int32_t code);
template<bool isBinary>
void sendWebSocketData(const char* data, size_t length);
void failAsynchronously();

View File

@@ -1,27 +1,14 @@
#include "root.h"
#include "WebSocketStream.h"
#include "ScriptExecutionContext.h"
#include <uws/src/App.h>
#include <uws/uSockets/src/libusockets.h>
namespace WebCore {
template<bool SSL, bool isServer>
WebSocketStreamBase<SSL, isServer>* WebSocketStreamBase<SSL, isServer>::adoptSocket(us_socket_t* socket, ScriptExecutionContext* scriptCtx)
{
using UserData = WebCore::WebSocket;
/* Adopting a socket invalidates it, do not rely on it directly to carry any data */
uWS::WebSocket<SSL, isServer, UserData>* webSocket = (uWS::WebSocket<SSL, isServer, UserData>*)us_socket_context_adopt_socket(SSL,
(us_socket_context_t*)webSocketContext, (us_socket_t*)this, sizeof(WebSocketData) + sizeof(UserData));
/* For whatever reason we were corked, update cork to the new socket */
if (wasCorked) {
webSocket->AsyncSocket<SSL>::corkUnchecked();
}
/* Initialize websocket with any moved backpressure intact */
webSocket->init(perMessageDeflate, compressOptions, std::move(backpressure));
}
void WebSocketStreamBase::registerHTTPContext(ScriptExecutionContext* script, us_socket_context_t* ctx, us_loop_t* loop)
void registerHTTPContextForWebSocket(ScriptExecutionContext* script, us_socket_context_t* ctx, us_loop_t* loop)
{
if constexpr (!isServer) {
if constexpr (SSL) {
@@ -35,11 +22,13 @@ void WebSocketStreamBase::registerHTTPContext(ScriptExecutionContext* script, us
}
template<bool SSL, bool isServer>
uWS::WebSocketContext* WebSocketStreamBase<SSL, isServer>::registerClientContext(ScriptExecutionContext*, us_socket_context_t* parent)
uWS::WebSocketContext<SSL, isServer, ScriptExecutionContext*>* registerWebSocketClientContext(ScriptExecutionContext* script, us_socket_context_t* parent)
{
uWS::Loop* loop = uWS::Loop::get();
uWS::WebSocketContext<SSL, isServer>* ctx = uWS::WebSocketContext<SSL, isServer>::create(loop, parent, nullptr);
uWS::WebSocketContext<SSL, isServer, ScriptExecutionContext*>* ctx = uWS::WebSocketContext<SSL, isServer>::create(loop, parent, nullptr);
auto* opts = ctx->getExt();
ScriptExecutionContext** scriptCtx = ctx->getUserData();
*scriptCtx = script;
/* Maximum message size we can receive */
static unsigned int maxPayloadLength = 128 * 1024 * 1024;

View File

@@ -36,7 +36,14 @@
#include "wtf/URL.h"
#include "wtf/Vector.h"
#include "wtf/Function.h"
#include <uws/src/WebSocketContext.h>
namespace uWS {
template<bool, bool, typename>
class WebSocket;
template<bool, bool, typename>
class WebSocketContext;
}
struct us_socket_context_t;
struct us_socket_t;
@@ -44,18 +51,23 @@ struct us_loop_t;
namespace WebCore {
class ScriptExecutionContext;
enum ClosingHandshakeCompletionStatus {
ClosingHandshakeIncomplete,
ClosingHandshakeComplete
};
class WebSocket;
// This class expects the stream to already be connected & ready to go
template<bool isSSL, bool isServer>
class WebSocketStreamBase final {
public:
using WebSocketImpl = uWS::WebSocket<isSSL, isServer>;
using WebSocketStreamPtr = WebCore::WebSocket*;
using WebSocketImpl = uWS::WebSocket<isSSL, isServer, WebSocketStreamPtr>;
using WebSocketStreamImpl = WebSocketStreamBase<isSSL, isServer>;
using WebSocketContext = uWS::WebSocketContext<isSSL, isServer>;
using WebSocketContext = uWS::WebSocketContext<isSSL, isServer, WebSocketStreamPtr>;
~WebSocketStreamBase();
void didConnect();
@@ -65,10 +77,6 @@ public:
void didUpdateBufferedAmount(unsigned bufferedAmount);
void didStartClosingHandshake();
static WebSocketStreamImpl* adoptSocket(us_socket_t* socket, ScriptExecutionContext* scriptCtx);
static void registerHTTPContext(ScriptExecutionContext*, us_socket_context_t*);
static WebSocketContext* registerClientContext(ScriptExecutionContext*, us_socket_context_t* parent);
void sendData(const uint8_t* data, size_t length, Function<void(bool)>);
void close(); // Disconnect after all data in buffer are sent.
void disconnect();
@@ -103,6 +111,12 @@ public:
}
};
template<bool isSSL, bool isServer>
void registerHTTPContextForWebSocket(ScriptExecutionContext*, us_socket_context_t*);
template<bool SSL, bool isServer>
uWS::WebSocketContext<SSL, isServer, ScriptExecutionContext*>* registerWebSocketClientContext(ScriptExecutionContext*, us_socket_context_t* parent);
using WebSocketStream = WebSocketStreamBase<false, false>;
using SecureWebSocketStream = WebSocketStreamBase<true, false>;
using ServerWebSocketStream = WebSocketStreamBase<false, true>;