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
|
||||
*/
|
||||
|
||||
#include <LibCore/AnonymousBuffer.h>
|
||||
#include <LibRequests/RequestClient.h>
|
||||
#include <LibRequests/WebSocket.h>
|
||||
|
||||
namespace Requests {
|
||||
|
||||
static constexpr size_t WEBSOCKET_SHARED_MEMORY_THRESHOLD = 16 * MiB;
|
||||
|
||||
WebSocket::WebSocket(RequestClient& client, u64 websocket_id)
|
||||
: m_client(client)
|
||||
, m_websocket_id(websocket_id)
|
||||
|
|
@ -39,6 +42,16 @@ void WebSocket::send(ReadonlyBytes binary_or_text_message, bool is_text)
|
|||
{
|
||||
if (!m_client)
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -586,6 +586,19 @@ void ConnectionFromClient::websocket_send(u64 websocket_id, bool is_text, ByteBu
|
|||
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)
|
||||
{
|
||||
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_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 Messages::RequestServer::WebsocketSetCertificateResponse websocket_set_certificate(u64, ByteString, ByteString) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ endpoint RequestServer
|
|||
// 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_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_set_certificate(u64 request_id, ByteString certificate, ByteString key) => (bool success)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue