LibRequests+RequestServer: Send oversized ws frames via shared memory
This commit is contained in:
parent
842e8a6796
commit
7c4ecaf509
4 changed files with 28 additions and 0 deletions
|
|
@ -4,11 +4,14 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <LibCore/AnonymousBuffer.h>
|
||||||
#include <LibRequests/RequestClient.h>
|
#include <LibRequests/RequestClient.h>
|
||||||
#include <LibRequests/WebSocket.h>
|
#include <LibRequests/WebSocket.h>
|
||||||
|
|
||||||
namespace Requests {
|
namespace Requests {
|
||||||
|
|
||||||
|
static constexpr size_t WEBSOCKET_SHARED_MEMORY_THRESHOLD = 16 * MiB;
|
||||||
|
|
||||||
WebSocket::WebSocket(RequestClient& client, u64 websocket_id)
|
WebSocket::WebSocket(RequestClient& client, u64 websocket_id)
|
||||||
: m_client(client)
|
: m_client(client)
|
||||||
, m_websocket_id(websocket_id)
|
, m_websocket_id(websocket_id)
|
||||||
|
|
@ -39,6 +42,16 @@ void WebSocket::send(ReadonlyBytes binary_or_text_message, bool is_text)
|
||||||
{
|
{
|
||||||
if (!m_client)
|
if (!m_client)
|
||||||
return;
|
return;
|
||||||
|
if (binary_or_text_message.size() >= WEBSOCKET_SHARED_MEMORY_THRESHOLD) {
|
||||||
|
auto buffer_or_error = Core::AnonymousBuffer::create_with_size(binary_or_text_message.size());
|
||||||
|
if (!buffer_or_error.is_error()) {
|
||||||
|
auto buffer = buffer_or_error.release_value();
|
||||||
|
__builtin_memcpy(buffer.data<void>(), binary_or_text_message.data(), binary_or_text_message.size());
|
||||||
|
m_client->async_websocket_send_shared(m_websocket_id, is_text, move(buffer));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dbgln("WebSocket::send: failed to allocate shared buffer for {} bytes: {}", binary_or_text_message.size(), buffer_or_error.error());
|
||||||
|
}
|
||||||
m_client->async_websocket_send(m_websocket_id, is_text, binary_or_text_message);
|
m_client->async_websocket_send(m_websocket_id, is_text, binary_or_text_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -586,6 +586,19 @@ void ConnectionFromClient::websocket_send(u64 websocket_id, bool is_text, ByteBu
|
||||||
connection->send(WebSocket::Message { move(data), is_text });
|
connection->send(WebSocket::Message { move(data), is_text });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConnectionFromClient::websocket_send_shared(u64 websocket_id, bool is_text, Core::AnonymousBuffer data)
|
||||||
|
{
|
||||||
|
auto* connection = m_websockets.get(websocket_id).value_or({});
|
||||||
|
if (!connection || connection->ready_state() != WebSocket::ReadyState::Open)
|
||||||
|
return;
|
||||||
|
auto byte_buffer_or_error = ByteBuffer::copy(data.bytes());
|
||||||
|
if (byte_buffer_or_error.is_error()) {
|
||||||
|
dbgln("websocket_send_shared: failed to copy {} bytes from shared buffer: {}", data.size(), byte_buffer_or_error.error());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
connection->send(WebSocket::Message { byte_buffer_or_error.release_value(), is_text });
|
||||||
|
}
|
||||||
|
|
||||||
void ConnectionFromClient::websocket_close(u64 websocket_id, u16 code, ByteString reason)
|
void ConnectionFromClient::websocket_close(u64 websocket_id, u16 code, ByteString reason)
|
||||||
{
|
{
|
||||||
if (m_pending_websockets.remove(websocket_id)) {
|
if (m_pending_websockets.remove(websocket_id)) {
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ private:
|
||||||
|
|
||||||
virtual void websocket_connect(u64 websocket_id, URL::URL, ByteString, Vector<ByteString>, Vector<ByteString>, Vector<HTTP::Header>) override;
|
virtual void websocket_connect(u64 websocket_id, URL::URL, ByteString, Vector<ByteString>, Vector<ByteString>, Vector<HTTP::Header>) override;
|
||||||
virtual void websocket_send(u64 websocket_id, bool, ByteBuffer) override;
|
virtual void websocket_send(u64 websocket_id, bool, ByteBuffer) override;
|
||||||
|
virtual void websocket_send_shared(u64 websocket_id, bool, Core::AnonymousBuffer) override;
|
||||||
virtual void websocket_close(u64 websocket_id, u16, ByteString) override;
|
virtual void websocket_close(u64 websocket_id, u16, ByteString) override;
|
||||||
virtual Messages::RequestServer::WebsocketSetCertificateResponse websocket_set_certificate(u64, ByteString, ByteString) override;
|
virtual Messages::RequestServer::WebsocketSetCertificateResponse websocket_set_certificate(u64, ByteString, ByteString) override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ endpoint RequestServer
|
||||||
// Websocket Connection API
|
// Websocket Connection API
|
||||||
websocket_connect(u64 websocket_id, URL::URL url, ByteString origin, Vector<ByteString> protocols, Vector<ByteString> extensions, Vector<HTTP::Header> additional_request_headers) =|
|
websocket_connect(u64 websocket_id, URL::URL url, ByteString origin, Vector<ByteString> protocols, Vector<ByteString> extensions, Vector<HTTP::Header> additional_request_headers) =|
|
||||||
websocket_send(u64 websocket_id, bool is_text, ByteBuffer data) =|
|
websocket_send(u64 websocket_id, bool is_text, ByteBuffer data) =|
|
||||||
|
websocket_send_shared(u64 websocket_id, bool is_text, Core::AnonymousBuffer data) =|
|
||||||
websocket_close(u64 websocket_id, u16 code, ByteString reason) =|
|
websocket_close(u64 websocket_id, u16 code, ByteString reason) =|
|
||||||
websocket_set_certificate(u64 request_id, ByteString certificate, ByteString key) => (bool success)
|
websocket_set_certificate(u64 request_id, ByteString certificate, ByteString key) => (bool success)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue