From c15172e3fd4866f421bce3fa1b5b57dbd3ff7951 Mon Sep 17 00:00:00 2001 From: binary1248 Date: Sun, 8 May 2016 22:15:14 +0200 Subject: [PATCH] Fixed FTP directory listing blocking forever if both expected responses are read from the command socket in a single call. (#1025) --- include/SFML/Network/Ftp.hpp | 3 ++- src/SFML/Network/Ftp.cpp | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/include/SFML/Network/Ftp.hpp b/include/SFML/Network/Ftp.hpp index c62db7ba..93b6502a 100644 --- a/include/SFML/Network/Ftp.hpp +++ b/include/SFML/Network/Ftp.hpp @@ -529,7 +529,8 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - TcpSocket m_commandSocket; ///< Socket holding the control connection with the server + TcpSocket m_commandSocket; ///< Socket holding the control connection with the server + std::string m_receiveBuffer; ///< Received command data that is yet to be processed }; } // namespace sf diff --git a/src/SFML/Network/Ftp.cpp b/src/SFML/Network/Ftp.cpp index 44a03b8b..80688e56 100644 --- a/src/SFML/Network/Ftp.cpp +++ b/src/SFML/Network/Ftp.cpp @@ -395,8 +395,18 @@ Ftp::Response Ftp::getResponse() // Receive the response from the server char buffer[1024]; std::size_t length; - if (m_commandSocket.receive(buffer, sizeof(buffer), length) != Socket::Done) - return Response(Response::ConnectionClosed); + + if (m_receiveBuffer.empty()) + { + if (m_commandSocket.receive(buffer, sizeof(buffer), length) != Socket::Done) + return Response(Response::ConnectionClosed); + } + else + { + std::copy(m_receiveBuffer.begin(), m_receiveBuffer.end(), buffer); + length = m_receiveBuffer.size(); + m_receiveBuffer.clear(); + } // There can be several lines inside the received buffer, extract them all std::istringstream in(std::string(buffer, length), std::ios_base::binary); @@ -452,6 +462,9 @@ Ftp::Response Ftp::getResponse() message = separator + line; } + // Save the remaining data for the next time getResponse() is called + m_receiveBuffer.assign(buffer + in.tellg(), length - in.tellg()); + // Return the response code and message return Response(static_cast(code), message); }