Serenity Operating System
at master 99 lines 3.1 kB view raw
1/* 2 * Copyright (c) 2021, Dex♪ <dexes.ttp@gmail.com> 3 * Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org> 4 * Copyright (c) 2022, the SerenityOS developers. 5 * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> 6 * 7 * SPDX-License-Identifier: BSD-2-Clause 8 */ 9 10#define AK_DONT_REPLACE_STD 11 12#include "WebSocketImplQt.h" 13#include "Utilities.h" 14#include <LibCore/EventLoop.h> 15#include <QSslSocket> 16#include <QTcpSocket> 17 18namespace Ladybird { 19 20WebSocketImplQt::~WebSocketImplQt() = default; 21WebSocketImplQt::WebSocketImplQt() = default; 22 23bool WebSocketImplQt::can_read_line() 24{ 25 return m_socket->canReadLine(); 26} 27 28bool WebSocketImplQt::send(ReadonlyBytes bytes) 29{ 30 auto bytes_written = m_socket->write(reinterpret_cast<char const*>(bytes.data()), bytes.size()); 31 if (bytes_written == -1) 32 return false; 33 VERIFY(static_cast<size_t>(bytes_written) == bytes.size()); 34 return true; 35} 36 37bool WebSocketImplQt::eof() 38{ 39 return m_socket->state() == QTcpSocket::SocketState::UnconnectedState 40 && !m_socket->bytesAvailable(); 41} 42 43void WebSocketImplQt::discard_connection() 44{ 45 m_socket = nullptr; 46} 47 48void WebSocketImplQt::connect(WebSocket::ConnectionInfo const& connection_info) 49{ 50 VERIFY(!m_socket); 51 VERIFY(on_connected); 52 VERIFY(on_connection_error); 53 VERIFY(on_ready_to_read); 54 55 if (connection_info.is_secure()) { 56 auto ssl_socket = make<QSslSocket>(); 57 ssl_socket->connectToHostEncrypted( 58 qstring_from_ak_deprecated_string(connection_info.url().host()), 59 connection_info.url().port_or_default()); 60 QObject::connect(ssl_socket.ptr(), &QSslSocket::alertReceived, [this](QSsl::AlertLevel level, QSsl::AlertType, QString const&) { 61 if (level == QSsl::AlertLevel::Fatal) 62 on_connection_error(); 63 }); 64 m_socket = move(ssl_socket); 65 } else { 66 m_socket = make<QTcpSocket>(); 67 m_socket->connectToHost( 68 qstring_from_ak_deprecated_string(connection_info.url().host()), 69 connection_info.url().port_or_default()); 70 } 71 72 QObject::connect(m_socket.ptr(), &QTcpSocket::readyRead, [this] { 73 on_ready_to_read(); 74 }); 75 76 QObject::connect(m_socket.ptr(), &QTcpSocket::connected, [this] { 77 on_connected(); 78 }); 79} 80 81ErrorOr<ByteBuffer> WebSocketImplQt::read(int max_size) 82{ 83 auto buffer = TRY(ByteBuffer::create_uninitialized(max_size)); 84 auto bytes_read = m_socket->read(reinterpret_cast<char*>(buffer.data()), buffer.size()); 85 if (bytes_read == -1) 86 return Error::from_string_literal("WebSocketImplQt::read(): Error reading from socket"); 87 return buffer.slice(0, bytes_read); 88} 89 90ErrorOr<DeprecatedString> WebSocketImplQt::read_line(size_t size) 91{ 92 auto buffer = TRY(ByteBuffer::create_uninitialized(size)); 93 auto bytes_read = m_socket->readLine(reinterpret_cast<char*>(buffer.data()), buffer.size()); 94 if (bytes_read == -1) 95 return Error::from_string_literal("WebSocketImplQt::read_line(): Error reading from socket"); 96 return DeprecatedString::copy(buffer.span().slice(0, bytes_read)); 97} 98 99}