diff --git a/Jupiter/HTTP_Server.cpp b/Jupiter/HTTP_Server.cpp index ffe8f70..c829319 100644 --- a/Jupiter/HTTP_Server.cpp +++ b/Jupiter/HTTP_Server.cpp @@ -256,7 +256,7 @@ HTTPSession::HTTPSession(Jupiter::Socket &&in_sock) : sock(std::move(in_sock)) HTTPSession::~HTTPSession() { - HTTPSession::sock.closeSocket(); + HTTPSession::sock.setBlocking(true); } // Server::Data struct @@ -267,10 +267,10 @@ struct Jupiter::HTTP::Server::Data Jupiter::ArrayList hosts; Jupiter::ArrayList ports; Jupiter::ArrayList sessions; - std::chrono::milliseconds session_timeout = std::chrono::milliseconds(30000); // TODO: Config variable - std::chrono::milliseconds keep_alive_session_timeout = std::chrono::milliseconds(30000); // TODO: Config variable + std::chrono::milliseconds session_timeout = std::chrono::milliseconds(2000); // TODO: Config variable + std::chrono::milliseconds keep_alive_session_timeout = std::chrono::milliseconds(5000); // TODO: Config variable size_t max_request_size = 1024; // TODO: Config variable - bool permit_keept_alive = true; // TODO: Config variable + bool permit_keept_alive = false; // TODO: Config variable /** Foward functions */ void hook(const Jupiter::ReadableString &host, const Jupiter::ReadableString &path, Content *in_content); @@ -511,16 +511,10 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session) result += Jupiter::StringS::Format("Content-Length: %u" ENDL, content_result->size()); - switch (session.version) - { - default: - case HTTPVersion::HTTP_1_0: - result += "Connection: close"_jrs ENDL; - break; - case HTTPVersion::HTTP_1_1: + if (session.keep_alive) result += "Connection: keep-alive"_jrs ENDL; - break; - } + else + result += "Connection: close"_jrs ENDL; result += "Content-Type: "_jrs; if (content->type == nullptr) @@ -572,16 +566,10 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session) result += "Content-Length: 0"_jrs ENDL; - switch (session.version) - { - default: - case HTTPVersion::HTTP_1_0: - result += "Connection: close"_jrs ENDL; - break; - case HTTPVersion::HTTP_1_1: + if (session.keep_alive) result += "Connection: keep-alive"_jrs ENDL; - break; - } + else + result += "Connection: close"_jrs ENDL; result += ENDL ENDL; session.sock.send(result); @@ -615,7 +603,7 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session) { Jupiter::ReferenceString connection_type = line.getWord(1, " "); if (connection_type.equalsi("keep-alive"_jrs)) - session.keep_alive = true; + session.keep_alive = Jupiter::HTTP::Server::Data::permit_keept_alive; } } else // command @@ -650,7 +638,7 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session) else if (protocol_str.equalsi("http/1.1"_jrs)) { session.version = HTTPVersion::HTTP_1_1; - session.keep_alive = true; + session.keep_alive = Jupiter::HTTP::Server::Data::permit_keept_alive; } } else if (first_token.equals("HEAD"_jrs)) @@ -683,7 +671,7 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session) else if (protocol_str.equalsi("http/1.1"_jrs)) { session.version = HTTPVersion::HTTP_1_1; - session.keep_alive = true; + session.keep_alive = Jupiter::HTTP::Server::Data::permit_keept_alive; } } else @@ -801,9 +789,14 @@ int Jupiter::HTTP::Server::think() { session = Jupiter::HTTP::Server::data_->sessions.get(--index); std::chrono::steady_clock::now(); - if ((std::chrono::steady_clock::now() > session->last_active + Jupiter::HTTP::Server::data_->keep_alive_session_timeout) + if (session->sock.isShutdown()) + { + if (session->sock.recv() == 0) + delete Jupiter::HTTP::Server::data_->sessions.remove(index); + } + else if ((std::chrono::steady_clock::now() > session->last_active + Jupiter::HTTP::Server::data_->keep_alive_session_timeout) || (session->keep_alive == false && std::chrono::steady_clock::now() > session->last_active + Jupiter::HTTP::Server::data_->session_timeout)) - delete Jupiter::HTTP::Server::data_->sessions.remove(index); + session->sock.shutdown(); else if (session->sock.recv() > 0) { const Jupiter::ReadableString &sock_buffer = session->sock.getBuffer(); @@ -815,7 +808,7 @@ int Jupiter::HTTP::Server::think() session->last_active = std::chrono::steady_clock::now(); Jupiter::HTTP::Server::data_->process_request(*session); if (session->keep_alive == false) // remove completed session - delete Jupiter::HTTP::Server::data_->sessions.remove(index); + session->sock.shutdown(); } else if (session->request.size() == Jupiter::HTTP::Server::data_->max_request_size) // reject (full buffer) delete Jupiter::HTTP::Server::data_->sessions.remove(index); diff --git a/Jupiter/IRC_Client.cpp b/Jupiter/IRC_Client.cpp index dc4e6d4..14bdf1d 100644 --- a/Jupiter/IRC_Client.cpp +++ b/Jupiter/IRC_Client.cpp @@ -199,7 +199,7 @@ Jupiter::IRC::Client::Client(const Jupiter::ReadableString &configSection) Jupiter::IRC::Client::~Client() { - Jupiter::IRC::Client::data_->sock->closeSocket(); + Jupiter::IRC::Client::data_->sock->close(); Jupiter::IRC::Client::data_->channels.emptyAndDelete(); Jupiter::IRC::Client::data_->users.emptyAndDelete(); @@ -687,7 +687,7 @@ int Jupiter::IRC::Client::primaryHandler() else { // Something went wrong. Kill the socket. - t->closeSocket(); + t->close(); } } break; @@ -1302,7 +1302,7 @@ void Jupiter::IRC::Client::disconnect(bool stayDead) { Jupiter::IRC::Client::data_->channels.emptyAndDelete(); Jupiter::IRC::Client::data_->connectionStatus = 0; - Jupiter::IRC::Client::data_->sock->closeSocket(); + Jupiter::IRC::Client::data_->sock->close(); Jupiter::IRC::Client::data_->reconnectTime = time(0) + Jupiter::IRC::Client::data_->reconnectDelay; Jupiter::IRC::Client::data_->dead = stayDead; this->OnDisconnect(); diff --git a/Jupiter/SecureSocket.cpp b/Jupiter/SecureSocket.cpp index 31212d9..fff5872 100644 --- a/Jupiter/SecureSocket.cpp +++ b/Jupiter/SecureSocket.cpp @@ -96,18 +96,25 @@ bool Jupiter::SecureSocket::bind(const char *hostname, unsigned short iPort, boo return Jupiter::Socket::bind(hostname, iPort, andListen); } -void Jupiter::SecureSocket::closeSocket() +void Jupiter::SecureSocket::shutdown() { - if (Jupiter::SecureSocket::SSLdata_ != nullptr) + Jupiter::Socket::shutdown(); + if (Jupiter::SecureSocket::SSLdata_ != nullptr && Jupiter::SecureSocket::SSLdata_->handle != nullptr) { - Jupiter::Socket::closeSocket(); - if (Jupiter::SecureSocket::SSLdata_->handle != nullptr) - { - if (SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle) == 0) - SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle); - SSL_free(Jupiter::SecureSocket::SSLdata_->handle); - Jupiter::SecureSocket::SSLdata_->handle = nullptr; - } + if (SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle) == 0) + SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle); + } +} + +void Jupiter::SecureSocket::close() +{ + Jupiter::Socket::close(); + if (Jupiter::SecureSocket::SSLdata_ != nullptr && Jupiter::SecureSocket::SSLdata_->handle != nullptr) + { + if (SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle) == 0) + SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle); + SSL_free(Jupiter::SecureSocket::SSLdata_->handle); + Jupiter::SecureSocket::SSLdata_->handle = nullptr; } } diff --git a/Jupiter/SecureSocket.h b/Jupiter/SecureSocket.h index 52f9c32..1d63491 100644 --- a/Jupiter/SecureSocket.h +++ b/Jupiter/SecureSocket.h @@ -119,7 +119,8 @@ namespace Jupiter /** * @brief Closes the socket. */ - virtual void closeSocket() override; + virtual void shutdown() override; + virtual void close() override; /** * @brief Writes new data from the socket to the buffer, without removing it from the socket queue. diff --git a/Jupiter/Socket.cpp b/Jupiter/Socket.cpp index 9532b7a..395a085 100644 --- a/Jupiter/Socket.cpp +++ b/Jupiter/Socket.cpp @@ -61,6 +61,7 @@ struct Jupiter::Socket::Data Jupiter::CStringS bound_host; int sockType = SOCK_RAW; int sockProto = IPPROTO_RAW; + bool is_shutdown = false; #if defined _WIN32 unsigned long blockMode = 0; #endif @@ -116,7 +117,7 @@ Jupiter::Socket::~Socket() { if (Jupiter::Socket::data_->rawSock > 0) { - Jupiter::Socket::closeSocket(); + Jupiter::Socket::close(); } delete Jupiter::Socket::data_; } @@ -185,9 +186,9 @@ bool Jupiter::Socket::connect(const char *hostname, unsigned short iPort, const if (::connect(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR) { #if defined _WIN32 - closesocket(Jupiter::Socket::data_->rawSock); + ::closesocket(Jupiter::Socket::data_->rawSock); #else // _WIN32 - close(Jupiter::Socket::data_->rawSock); + ::close(Jupiter::Socket::data_->rawSock); #endif // WIN32 Jupiter::Socket::data_->rawSock = INVALID_SOCKET; info = info->ai_next; @@ -226,9 +227,9 @@ bool Jupiter::Socket::bind(const char *hostname, unsigned short iPort, bool andL if (::bind(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR) { #if defined _WIN32 - closesocket(Jupiter::Socket::data_->rawSock); + ::closesocket(Jupiter::Socket::data_->rawSock); #else // _WIN32 - close(Jupiter::Socket::data_->rawSock); + ::close(Jupiter::Socket::data_->rawSock); #endif // WIN32 Jupiter::Socket::data_->rawSock = INVALID_SOCKET; info = info->ai_next; @@ -245,20 +246,35 @@ bool Jupiter::Socket::bind(const char *hostname, unsigned short iPort, bool andL return false; } -void Jupiter::Socket::closeSocket() +void Jupiter::Socket::shutdown() { if (Jupiter::Socket::data_ != nullptr) { - shutdown(Jupiter::Socket::data_->rawSock, 2); + ::shutdown(Jupiter::Socket::data_->rawSock, 2); + Jupiter::Socket::data_->is_shutdown = true; + } +} + +void Jupiter::Socket::close() +{ + if (Jupiter::Socket::data_ != nullptr) + { + if (Jupiter::Socket::data_->is_shutdown == false) + this->shutdown(); #if defined _WIN32 - closesocket(Jupiter::Socket::data_->rawSock); + ::closesocket(Jupiter::Socket::data_->rawSock); #else // _WIN32 - close(Jupiter::Socket::data_->rawSock); + ::close(Jupiter::Socket::data_->rawSock); #endif // _WIN32 Jupiter::Socket::data_->rawSock = 0; } } +bool Jupiter::Socket::isShutdown() const +{ + return Jupiter::Socket::data_->is_shutdown; +} + addrinfo *Jupiter::Socket::getAddrInfo(const char *hostname, const char *port) // static { addrinfo *ptr; diff --git a/Jupiter/Socket.h b/Jupiter/Socket.h index 377f9d6..29fda66 100644 --- a/Jupiter/Socket.h +++ b/Jupiter/Socket.h @@ -275,7 +275,9 @@ namespace Jupiter /** * @brief Closes the socket. */ - virtual void closeSocket(); + virtual void shutdown(); + virtual void close(); + bool isShutdown() const; /** * @brief Returns the hostname that the socket is connected to. diff --git a/Release/Jupiter.lib b/Release/Jupiter.lib index 418c7b7..7753ab0 100644 Binary files a/Release/Jupiter.lib and b/Release/Jupiter.lib differ