Browse Source

Socket:

* Replaced 'closeSocket' function with 'close' and 'shutdown' functions.
* Added 'isShutdown' function
release/0.19
Jessica James 9 years ago
parent
commit
dbeac36e50
  1. 49
      Jupiter/HTTP_Server.cpp
  2. 6
      Jupiter/IRC_Client.cpp
  3. 27
      Jupiter/SecureSocket.cpp
  4. 3
      Jupiter/SecureSocket.h
  5. 34
      Jupiter/Socket.cpp
  6. 4
      Jupiter/Socket.h
  7. BIN
      Release/Jupiter.lib

49
Jupiter/HTTP_Server.cpp

@ -256,7 +256,7 @@ HTTPSession::HTTPSession(Jupiter::Socket &&in_sock) : sock(std::move(in_sock))
HTTPSession::~HTTPSession() HTTPSession::~HTTPSession()
{ {
HTTPSession::sock.closeSocket(); HTTPSession::sock.setBlocking(true);
} }
// Server::Data struct // Server::Data struct
@ -267,10 +267,10 @@ struct Jupiter::HTTP::Server::Data
Jupiter::ArrayList<Jupiter::HTTP::Server::Host> hosts; Jupiter::ArrayList<Jupiter::HTTP::Server::Host> hosts;
Jupiter::ArrayList<Socket> ports; Jupiter::ArrayList<Socket> ports;
Jupiter::ArrayList<HTTPSession> sessions; Jupiter::ArrayList<HTTPSession> sessions;
std::chrono::milliseconds 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(30000); // 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 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 */ /** Foward functions */
void hook(const Jupiter::ReadableString &host, const Jupiter::ReadableString &path, Content *in_content); 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()); result += Jupiter::StringS::Format("Content-Length: %u" ENDL, content_result->size());
switch (session.version) if (session.keep_alive)
{
default:
case HTTPVersion::HTTP_1_0:
result += "Connection: close"_jrs ENDL;
break;
case HTTPVersion::HTTP_1_1:
result += "Connection: keep-alive"_jrs ENDL; result += "Connection: keep-alive"_jrs ENDL;
break; else
} result += "Connection: close"_jrs ENDL;
result += "Content-Type: "_jrs; result += "Content-Type: "_jrs;
if (content->type == nullptr) if (content->type == nullptr)
@ -572,16 +566,10 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session)
result += "Content-Length: 0"_jrs ENDL; result += "Content-Length: 0"_jrs ENDL;
switch (session.version) if (session.keep_alive)
{
default:
case HTTPVersion::HTTP_1_0:
result += "Connection: close"_jrs ENDL;
break;
case HTTPVersion::HTTP_1_1:
result += "Connection: keep-alive"_jrs ENDL; result += "Connection: keep-alive"_jrs ENDL;
break; else
} result += "Connection: close"_jrs ENDL;
result += ENDL ENDL; result += ENDL ENDL;
session.sock.send(result); session.sock.send(result);
@ -615,7 +603,7 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session)
{ {
Jupiter::ReferenceString connection_type = line.getWord(1, " "); Jupiter::ReferenceString connection_type = line.getWord(1, " ");
if (connection_type.equalsi("keep-alive"_jrs)) if (connection_type.equalsi("keep-alive"_jrs))
session.keep_alive = true; session.keep_alive = Jupiter::HTTP::Server::Data::permit_keept_alive;
} }
} }
else // command else // command
@ -650,7 +638,7 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session)
else if (protocol_str.equalsi("http/1.1"_jrs)) else if (protocol_str.equalsi("http/1.1"_jrs))
{ {
session.version = HTTPVersion::HTTP_1_1; 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)) 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)) else if (protocol_str.equalsi("http/1.1"_jrs))
{ {
session.version = HTTPVersion::HTTP_1_1; session.version = HTTPVersion::HTTP_1_1;
session.keep_alive = true; session.keep_alive = Jupiter::HTTP::Server::Data::permit_keept_alive;
} }
} }
else else
@ -801,9 +789,14 @@ int Jupiter::HTTP::Server::think()
{ {
session = Jupiter::HTTP::Server::data_->sessions.get(--index); session = Jupiter::HTTP::Server::data_->sessions.get(--index);
std::chrono::steady_clock::now(); 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)) || (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) else if (session->sock.recv() > 0)
{ {
const Jupiter::ReadableString &sock_buffer = session->sock.getBuffer(); 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(); session->last_active = std::chrono::steady_clock::now();
Jupiter::HTTP::Server::data_->process_request(*session); Jupiter::HTTP::Server::data_->process_request(*session);
if (session->keep_alive == false) // remove completed 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) else if (session->request.size() == Jupiter::HTTP::Server::data_->max_request_size) // reject (full buffer)
delete Jupiter::HTTP::Server::data_->sessions.remove(index); delete Jupiter::HTTP::Server::data_->sessions.remove(index);

6
Jupiter/IRC_Client.cpp

@ -199,7 +199,7 @@ Jupiter::IRC::Client::Client(const Jupiter::ReadableString &configSection)
Jupiter::IRC::Client::~Client() 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_->channels.emptyAndDelete();
Jupiter::IRC::Client::data_->users.emptyAndDelete(); Jupiter::IRC::Client::data_->users.emptyAndDelete();
@ -687,7 +687,7 @@ int Jupiter::IRC::Client::primaryHandler()
else else
{ {
// Something went wrong. Kill the socket. // Something went wrong. Kill the socket.
t->closeSocket(); t->close();
} }
} }
break; break;
@ -1302,7 +1302,7 @@ void Jupiter::IRC::Client::disconnect(bool stayDead)
{ {
Jupiter::IRC::Client::data_->channels.emptyAndDelete(); Jupiter::IRC::Client::data_->channels.emptyAndDelete();
Jupiter::IRC::Client::data_->connectionStatus = 0; 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_->reconnectTime = time(0) + Jupiter::IRC::Client::data_->reconnectDelay;
Jupiter::IRC::Client::data_->dead = stayDead; Jupiter::IRC::Client::data_->dead = stayDead;
this->OnDisconnect(); this->OnDisconnect();

27
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); 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 (SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle) == 0)
if (Jupiter::SecureSocket::SSLdata_->handle != nullptr) SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle);
{ }
if (SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle) == 0) }
SSL_shutdown(Jupiter::SecureSocket::SSLdata_->handle);
SSL_free(Jupiter::SecureSocket::SSLdata_->handle); void Jupiter::SecureSocket::close()
Jupiter::SecureSocket::SSLdata_->handle = nullptr; {
} 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;
} }
} }

3
Jupiter/SecureSocket.h

@ -119,7 +119,8 @@ namespace Jupiter
/** /**
* @brief Closes the socket. * @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. * @brief Writes new data from the socket to the buffer, without removing it from the socket queue.

34
Jupiter/Socket.cpp

@ -61,6 +61,7 @@ struct Jupiter::Socket::Data
Jupiter::CStringS bound_host; Jupiter::CStringS bound_host;
int sockType = SOCK_RAW; int sockType = SOCK_RAW;
int sockProto = IPPROTO_RAW; int sockProto = IPPROTO_RAW;
bool is_shutdown = false;
#if defined _WIN32 #if defined _WIN32
unsigned long blockMode = 0; unsigned long blockMode = 0;
#endif #endif
@ -116,7 +117,7 @@ Jupiter::Socket::~Socket()
{ {
if (Jupiter::Socket::data_->rawSock > 0) if (Jupiter::Socket::data_->rawSock > 0)
{ {
Jupiter::Socket::closeSocket(); Jupiter::Socket::close();
} }
delete Jupiter::Socket::data_; 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 (::connect(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR)
{ {
#if defined _WIN32 #if defined _WIN32
closesocket(Jupiter::Socket::data_->rawSock); ::closesocket(Jupiter::Socket::data_->rawSock);
#else // _WIN32 #else // _WIN32
close(Jupiter::Socket::data_->rawSock); ::close(Jupiter::Socket::data_->rawSock);
#endif // WIN32 #endif // WIN32
Jupiter::Socket::data_->rawSock = INVALID_SOCKET; Jupiter::Socket::data_->rawSock = INVALID_SOCKET;
info = info->ai_next; 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 (::bind(Jupiter::Socket::data_->rawSock, info->ai_addr, info->ai_addrlen) == SOCKET_ERROR)
{ {
#if defined _WIN32 #if defined _WIN32
closesocket(Jupiter::Socket::data_->rawSock); ::closesocket(Jupiter::Socket::data_->rawSock);
#else // _WIN32 #else // _WIN32
close(Jupiter::Socket::data_->rawSock); ::close(Jupiter::Socket::data_->rawSock);
#endif // WIN32 #endif // WIN32
Jupiter::Socket::data_->rawSock = INVALID_SOCKET; Jupiter::Socket::data_->rawSock = INVALID_SOCKET;
info = info->ai_next; info = info->ai_next;
@ -245,20 +246,35 @@ bool Jupiter::Socket::bind(const char *hostname, unsigned short iPort, bool andL
return false; return false;
} }
void Jupiter::Socket::closeSocket() void Jupiter::Socket::shutdown()
{ {
if (Jupiter::Socket::data_ != nullptr) 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 #if defined _WIN32
closesocket(Jupiter::Socket::data_->rawSock); ::closesocket(Jupiter::Socket::data_->rawSock);
#else // _WIN32 #else // _WIN32
close(Jupiter::Socket::data_->rawSock); ::close(Jupiter::Socket::data_->rawSock);
#endif // _WIN32 #endif // _WIN32
Jupiter::Socket::data_->rawSock = 0; 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 *Jupiter::Socket::getAddrInfo(const char *hostname, const char *port) // static
{ {
addrinfo *ptr; addrinfo *ptr;

4
Jupiter/Socket.h

@ -275,7 +275,9 @@ namespace Jupiter
/** /**
* @brief Closes the socket. * @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. * @brief Returns the hostname that the socket is connected to.

BIN
Release/Jupiter.lib

Binary file not shown.
Loading…
Cancel
Save