@@ -125,7 +125,7 @@ void Server::acceptClients()
125125 CloseSocket (AcceptSocket);
126126 continue ;
127127 }
128- connections[AcceptSocket] = Connection{ AcceptSocket, active_key} ;
128+ connections[AcceptSocket] = std::make_shared< Connection>( AcceptSocket, active_key) ;
129129 eventLoop->add (AcceptSocket);
130130 std::cout << " [SERVER] Client connected and registered!\n " ;
131131 }
@@ -182,27 +182,14 @@ void Server::runEventLoop()
182182 if (entry.event == IOEvent::Readable)
183183 {
184184 auto it = connections.find (entry.socket );
185- if (it == connections.end ())
186- continue ; // already cleaned up
187-
188- {
189- std::lock_guard<std::mutex> lock (busyMutex);
190- // A job for this socket is already queued or running -
191- // skip this notification. Level-triggered epoll will
192- // notify us again next wait() if data is still unread.
193- if (busySockets.count (entry.socket ))
194- continue ;
195- busySockets.insert (entry.socket );
196- }
197-
198- Connection conn = it->second ; // small struct, cheap to copy
199- tpool.acceptJob ([this , conn]()
200- {
201- messageHandler (conn.socket , conn.sessionKey );
202- std::lock_guard<std::mutex> lock (busyMutex);
203- busySockets.erase (conn.socket ); });
204- }
205- else // HangUp or Error
185+ if (it == connections.end ()) continue ;
186+
187+ std::shared_ptr<Connection> user_connection = it->second ; // No Copy
188+ // wont fire again until we re-arm it.
189+ tpool.acceptJob ([this , conn = std::move (user_connection)] {
190+ messageHandler (conn);
191+ });
192+ } else // HangUp or Error
206193 {
207194 closeConnection (entry.socket );
208195 }
@@ -217,21 +204,22 @@ void Server::closeConnection(SocketType sock)
217204 auto it = connections.find (sock);
218205 if (it != connections.end ())
219206 {
220- userSessionManager.remove_session (it->second . sessionKey );
207+ userSessionManager.remove_session (it->second -> sessionKey );
221208 connections.erase (it);
222209 }
223210
224211 CloseSocket (sock);
225212}
226213
227- void Server::messageHandler (SocketType clientSocket, const SessionKey &sessionKey )
214+ void Server::messageHandler (std::shared_ptr<Connection> clientConnection )
228215{
229216 std::cout << " [CLIENT] Handling client message\n " ;
230217
231- char buffer[1024 ];
218+ char tempBuffer[1024 ];
219+ SocketType clientSocket = clientConnection->socket ;
232220
233221 // On Linux, the buffer is safely passed to standard recv
234- int bytesReceived = recv (clientSocket, buffer , sizeof (buffer) - 1 , 0 );
222+ int bytesReceived = recv (clientSocket, tempBuffer , sizeof (tempBuffer) , 0 );
235223
236224 if (bytesReceived == 0 )
237225 {
@@ -247,19 +235,37 @@ void Server::messageHandler(SocketType clientSocket, const SessionKey &sessionKe
247235 // Nothing to read right now - a different job for this socket
248236 // already drained it, or epoll notified us before this job
249237 // got scheduled. Not an error, just nothing to do.
238+ this ->rearmSocket (clientSocket);
250239 return ;
251240 }
252241 std::cout << " [CLIENT] recv error, disconnecting\n " ;
253242 closeConnection (clientSocket);
254243 return ;
255244 }
256- userSessionManager.update_activity (sessionKey);
245+
246+ clientConnection->commandBuffer .append (tempBuffer, bytesReceived);
247+
248+ if (clientConnection->commandBuffer .length () > this ->MAX_COMMAND_BUFFER_LENGTH ) {
249+ std::cout << " [CLIENT] Client is abusing the command buffer disconnecting them\n " ;
250+ closeConnection (clientSocket);
251+ return ;
252+ }
253+
254+ if (clientConnection->commandBuffer .find (' \n ' ) == std::string::npos) {
255+ this ->rearmSocket (clientSocket);
256+ return ;
257+ }
258+
259+
260+
261+ userSessionManager.update_activity (clientConnection->sessionKey );
257262
258263 std::cout << " [CLIENT] Received " << bytesReceived << " bytes\n " ;
259- std::string message (buffer, bytesReceived) ;
264+ std::string message = clientConnection-> commandBuffer ;
260265 std::cout << " [CLIENT] Message: " << message << " \n " ;
261266 std::istringstream iss (message);
262267 std::string command, key, value;
268+ clientConnection->commandBuffer .clear ();
263269
264270 iss >> command;
265271 iss >> key;
@@ -277,6 +283,7 @@ void Server::messageHandler(SocketType clientSocket, const SessionKey &sessionKe
277283 {
278284 std::string response = " Empty Value Recieved, Try again\n " ;
279285 send (clientSocket, response.c_str (), response.length (), 0 );
286+ this ->rearmSocket (clientSocket);
280287 return ;
281288 }
282289
@@ -317,6 +324,18 @@ void Server::messageHandler(SocketType clientSocket, const SessionKey &sessionKe
317324 std::string response = " No command was received\n " ;
318325 send (clientSocket, response.c_str (), response.length (), 0 );
319326 }
327+
328+ // Re-enable epoll notifications for the next command from this client
329+ this ->rearmSocket (clientSocket);
330+ }
331+
332+ void Server::rearmSocket (SocketType clientSocket)
333+ {
334+ if (!eventLoop->rearm (clientSocket))
335+ {
336+ std::cout << " [SERVER] Failed to re-arm socket " << clientSocket << " , closing.\n " ;
337+ closeConnection (clientSocket);
338+ }
320339}
321340
322341void Server::onSessionExpired (SocketType sock)
0 commit comments