diff --git a/include/protocols/http/httprequest.h b/include/protocols/http/httprequest.h index a28350e..94bd83e 100644 --- a/include/protocols/http/httprequest.h +++ b/include/protocols/http/httprequest.h @@ -45,6 +45,8 @@ class HTTPTextParser static HTTPHeaderMap ParseRequest(std::string& request) noexcept; + static size_t GetBodySize(std::string& headers) noexcept; + private: HTTPTextParser(); ~HTTPTextParser(); diff --git a/src/net/serversock.cpp b/src/net/serversock.cpp index d2fecbc..00a9c1f 100644 --- a/src/net/serversock.cpp +++ b/src/net/serversock.cpp @@ -1,4 +1,6 @@ #include "net/serversock.h" +#include +#include "protocols/http/httprequest.h" Celeris::ServerSocket::ServerSocket() { @@ -79,30 +81,55 @@ SOCKET Celeris::ServerSocket::acceptConnection(CleanSocket* tcpSocketIPV4) { } std::string Celeris::ServerSocket::receiveData(SOCKET clientSocket) { //we do not use a clean socket here? + + std::string message; char buf[4096]; + size_t bytesReceived; + size_t header_end_pos; + while ((header_end_pos = message.find("\r\n\r\n")) == std::string::npos ){ + bytesReceived = recv(clientSocket, buf, 4096, 0); #if PLATFORM_WINDOWS - ZeroMemory(buf, (sizeof(char) * 4096)); + if (bytesReceived == SOCKET_ERROR) { + throw std::system_error(WSAGetLastError(), std::system_category()); + } #else - //bzero(buf, 4096); - memset(buf, 0, (sizeof(char) * 4096)); -#endif + //posix systems + if (bytesReceived < 0) { + //determine error type + perror("Failed to receive"); + throw std::system_error(errno, std::system_category()); + } +#endif // 0 - int bytesReceived = recv(clientSocket, buf, 4096, 0); -#if PLATFORM_WINDOWS - if (bytesReceived == SOCKET_ERROR) { - throw std::system_error(WSAGetLastError(), std::system_category()); + if (bytesReceived == 0) + break; + message.append(buf, bytesReceived); } + + size_t total_header_length = header_end_pos + 4; // Includes \r\n\r\n + size_t bytes_already_read = message.length() - total_header_length; + size_t bufferSize = HTTPTextParser::GetBodySize(message) - (bytes_already_read); + + if (bytes_already_read < bufferSize) { + std::unique_ptr bodyBuffer = std::make_unique(bufferSize); + bytesReceived = recv(clientSocket, bodyBuffer.get(), bufferSize, 0); +#if PLATFORM_WINDOWS + if (bytesReceived == SOCKET_ERROR) { + throw std::system_error(WSAGetLastError(), std::system_category()); + } #else - //posix systems - if (bytesReceived < 0) { - //determine error type - perror("Failed to send"); - throw std::system_error(errno, std::system_category()); - } + //posix systems + if (bytesReceived < 0) { + //determine error type + perror("Failed to receive"); + throw std::system_error(errno, std::system_category()); + } #endif // 0 + message.append(bodyBuffer.get(), bytesReceived); + } - return std::string(buf, 0, bytesReceived); + return message; } void Celeris::ServerSocket::sendData(SOCKET& clientSocket, const char data[]) { diff --git a/src/protocols/http/httprequest.cpp b/src/protocols/http/httprequest.cpp index 25add68..f02b79e 100644 --- a/src/protocols/http/httprequest.cpp +++ b/src/protocols/http/httprequest.cpp @@ -95,6 +95,24 @@ HTTPHeaderMap HTTPTextParser::ParseRequest(std::string& request) noexcept { return header_map; } +size_t HTTPTextParser::GetBodySize(std::string &headers) noexcept { + HTTPHeaderMap header_map = ParseRequest(headers); + + auto it = header_map.find("Content-Length"); + if (it != header_map.end()) { + try { + + return std::stoull(it->second); + } catch (...) { + + return 0; + } + } + + return 0; +} + + HTTPTextParser::HTTPTextParser() { }