#include "session.h" #include "server.h" #include namespace scar { Session::Session(boost::asio::ssl::stream socket, std::shared_ptr auth, Server* server) : socket_(std::move(socket)), auth_(auth), server_(server), authenticated_(false) {} void Session::start() { doHandshake(); } void Session::doHandshake() { auto self(shared_from_this()); socket_.async_handshake(boost::asio::ssl::stream_base::server, [this, self](const boost::system::error_code& error) { if (!error) { std::cout << "SSL handshake completed" << std::endl; doReadHeader(); } else { std::cerr << "SSL handshake error: " << error.message() << std::endl; } }); } void Session::doReadHeader() { read_buffer_.resize(sizeof(MessageHeader)); auto self(shared_from_this()); boost::asio::async_read(socket_, boost::asio::buffer(read_buffer_), [this, self](const boost::system::error_code& error, std::size_t /*length*/) { if (!error) { MessageHeader header; std::memcpy(&header, read_buffer_.data(), sizeof(MessageHeader)); if (header.length > sizeof(MessageHeader)) { doReadBody(header.length - sizeof(MessageHeader)); } else { doReadHeader(); } } else { std::cerr << "Read error: " << error.message() << std::endl; if (authenticated_) { server_->removeSession(shared_from_this()); } } }); } void Session::doReadBody(uint32_t length) { auto body_buffer = std::make_shared>(length); auto self(shared_from_this()); boost::asio::async_read(socket_, boost::asio::buffer(*body_buffer), [this, self, body_buffer](const boost::system::error_code& error, std::size_t /*bytes*/) { if (!error) { // Combine header and body std::vector full_message; full_message.insert(full_message.end(), read_buffer_.begin(), read_buffer_.end()); full_message.insert(full_message.end(), body_buffer->begin(), body_buffer->end()); try { auto message = Message::deserialize(full_message); handleMessage(std::move(message)); } catch (const std::exception& e) { std::cerr << "Message deserialization error: " << e.what() << std::endl; } doReadHeader(); } else { std::cerr << "Read error: " << error.message() << std::endl; if (authenticated_) { server_->removeSession(shared_from_this()); } } }); } void Session::handleMessage(std::unique_ptr message) { std::cout << "Received message type: " << static_cast(message->type()) << std::endl; switch (message->type()) { case MessageType::LOGIN_REQUEST: handleLoginRequest(*dynamic_cast(message.get())); break; case MessageType::TEXT_MESSAGE: if (authenticated_) { server_->broadcastMessage(*dynamic_cast(message.get())); } break; case MessageType::SCREEN_SHARE_START: case MessageType::SCREEN_SHARE_DATA: case MessageType::SCREEN_SHARE_STOP: if (authenticated_) { // Broadcast screen share messages to all other clients server_->broadcastToOthers(*message, shared_from_this()); } break; default: std::cerr << "Unhandled message type" << std::endl; break; } } void Session::handleLoginRequest(const LoginRequest& request) { std::cout << "LoginRequest received - Username: '" << request.username() << "', Password length: " << request.password().length() << std::endl; std::string token = auth_->authenticate(request.username(), request.password()); if (!token.empty()) { authenticated_ = true; username_ = request.username(); LoginResponse response(true, token); std::cout << "Sending successful LoginResponse with token" << std::endl; send(response); server_->addSession(shared_from_this()); } else { LoginResponse response(false, "", ErrorCode::AUTH_FAILED); std::cout << "Sending failed LoginResponse" << std::endl; send(response); } } void Session::send(const Message& message) { auto self(shared_from_this()); write_buffer_ = message.serialize(); std::cout << "Sending message type " << static_cast(message.type()) << ", size: " << write_buffer_.size() << " bytes" << std::endl; boost::asio::async_write(socket_, boost::asio::buffer(write_buffer_), [this, self](const boost::system::error_code& error, std::size_t bytes) { if (error) { std::cerr << "Write error: " << error.message() << std::endl; if (authenticated_) { server_->removeSession(shared_from_this()); } } else { std::cout << "Successfully sent " << bytes << " bytes" << std::endl; } }); } } // namespace scar