@@ -183,89 +183,142 @@ static void print_raw_data(const char* s, size_t n)
183183 std::cout.flush ();
184184}
185185
186- void Server::handle_events (Client& conn, uint32_t events)
186+ static void log_request_info (uint64_t client_id, const HttpRequest& request)
187+ {
188+ LOG (INFO) << " Client #" << client_id << " : " << request.method << " " << request.path << " "
189+ << request.http_version ;
190+ }
191+
192+ void Server::read_from_socket (Client& conn)
187193{
194+ if (conn.state () != Client::kReceivingHeaders && conn.state () != Client::kReceivingBody )
195+ return ;
196+
188197 char tmp[4096 ];
189- uint64_t client_id = conn.id ();
198+ ssize_t bytes_received = recv (conn.fd (), tmp, sizeof (tmp), 0 );
199+
200+ if (bytes_received == 0 ) {
201+ LOG (INFO) << " Client #" << conn.id () << " : connection closed by remote client" ;
202+ conn.set_state (Client::kClosingConnection );
203+ return ;
204+ }
205+
190206 HttpParser& parser = conn.parser ();
191- uint32_t next_events = 0 ;
207+ parser.append_data (tmp, bytes_received);
208+ print_raw_data (tmp, bytes_received);
192209
193- // Can read from socket
194- if (events & EPOLLIN) {
210+ if (conn.state () == Client::kReceivingHeaders ) {
195211
196- size_t bytes_received = recv (conn.fd (), tmp, sizeof (tmp), 0 );
212+ if (parser.state () == HttpParser::kParsingError ) {
213+ LOG (ERROR) << " Client #" << conn.id () << " : invalid HTTP request" ;
214+ conn.set_state (Client::kClosingConnection );
215+ return ;
216+ }
197217
198- if (bytes_received == 0 ) {
199- LOG (INFO) << " Client #" << client_id << " : connection closed by remote client" ;
200- close_connection (conn);
218+ if (parser.state () < HttpParser::kParsingBody ) {
201219 return ;
202220 }
203221
204- LOG (DEBUG) << " Client #" << client_id << " : " << bytes_received << " bytes received" ;
205- print_raw_data (tmp, bytes_received);
222+ LOG (DEBUG) << " WE PARSED ALL HEADERS" ;
206223
207- // Feed data to the parser
208- parser.feed_data (tmp, bytes_received);
224+ // We parsed headers and might have some or all body bytes?
225+ log_request_info (conn.id (), parser.request ());
226+ conn.set_handler (router_.handle_request (parser.request ()));
209227
210- if (parser.status () == HttpParser::kError ) {
211- LOG (ERROR) << " Client #" << client_id << " : invalid HTTP request" ;
212- close_connection (conn);
213- return ;
228+ if (conn.handler ()->needs_input ()) {
229+ conn.set_state (Client::kReceivingBody );
214230 }
231+ else {
232+ conn.set_state (Client::kSendingResponse );
233+ }
234+ }
215235
216- if (!conn.handler () && parser.status () >= HttpParser::kHeadersDone ) {
217- HttpRequest req = parser.request ();
218- LOG (INFO) << " Client #" << client_id << " : " << req.method << " " << req.path << " "
219- << req.http_version ;
220-
221- Handler* h = router_.handle_request (req);
222- conn.set_handler (h);
236+ if (conn.state () == Client::kReceivingBody ) {
237+ size_t n = 0 ;
238+ while ((n = parser.read_body_chunk (tmp, sizeof (tmp))) > 0 ) {
239+ conn.handler ()->write_data (tmp, n);
223240 }
224- if (conn.handler ()) {
225- if (conn.handler ()->needs_input ()) {
226- size_t n = parser.slurp_data (tmp, sizeof (tmp));
227- (void ) conn.handler ()->write_data (tmp, n);
228- }
241+ if (conn.handler ()->has_output ()) {
242+ conn.set_state (Client::kSendingResponse );
229243 }
230244 }
245+ }
231246
232- // Can write to socket
233- if (events & EPOLLOUT) {
234- if (conn.handler ()) {
247+ void Server::write_to_socket (Client& conn)
248+ {
249+ assert (conn.handler () && " Handler must exist when writing to socket " );
235250
236- Handler& handler = * conn.handler ();
237- std::string& send_buffer = conn. send_buffer () ;
251+ if ( conn.state () != Client:: kSendingResponse )
252+ return ;
238253
239- if (handler.has_output ()) {
240- size_t n = handler.read_data (tmp, sizeof (tmp));
241- send_buffer.append (tmp, n);
242- }
243- if (!send_buffer.empty ()) {
244- size_t bytes_sent = send (conn.fd (), send_buffer.data (), send_buffer.size (), 0 );
245- if (bytes_sent == 0 ) {
246- LOG (WARN) << " Client #" << client_id << " : failed to send any bytes!" ;
247- }
248- else {
249- send_buffer.erase (0 , bytes_sent);
250- }
251- }
252- // Treat all connections as HTTP/1.0 for now (do not keep-alive)
253- if (send_buffer.empty () && handler.is_done ()) {
254- LOG (DEBUG) << " Client #" << client_id << " : response sent" ;
255- close_connection (conn);
256- return ;
257- }
254+ char tmp[4096 ];
255+ Handler& handler = *conn.handler ();
256+ std::string& send_buffer = conn.send_buffer ();
257+
258+ if (handler.has_output ()) {
259+ size_t n = handler.read_data (tmp, sizeof (tmp));
260+ send_buffer.append (tmp, n);
261+ }
262+ if (!send_buffer.empty ()) {
263+ size_t bytes_sent = send (conn.fd (), send_buffer.data (), send_buffer.size (), 0 );
264+ if (bytes_sent == 0 ) {
265+ LOG (WARN) << " Client #" << conn.id () << " : failed to send any bytes!" ;
266+ }
267+ else {
268+ send_buffer.erase (0 , bytes_sent);
258269 }
259270 }
260271
261- // Update next event subscription
262- if (!conn.handler () || conn.handler ()->needs_input ())
263- next_events |= EPOLLIN;
264- if (conn.handler () && (conn.handler ()->has_output () || !conn.send_buffer ().empty ()))
265- next_events |= EPOLLOUT;
272+ // All data has been written to socket -> either close or keep going
273+ if (handler.is_done () && send_buffer.empty ()) {
274+ LOG (DEBUG) << " Client #" << conn.id () << " : response sent" ;
275+
276+ if (conn.keep_alive ()) {
277+ conn.parser ().reset_for_next_request ();
278+ delete conn.handler ();
279+ conn.set_handler (NULL );
280+ conn.set_state (Client::kReceivingHeaders );
281+ LOG (DEBUG) << " WE DELETED THE HANDLER" ;
282+ }
283+ else {
284+ conn.set_state (Client::kClosingConnection );
285+ }
286+ }
287+ }
288+
289+ void Server::handle_events (Client& conn, uint32_t events)
290+ {
291+ if (events & EPOLLIN) {
292+ read_from_socket (conn);
293+ LOG (DEBUG) << " WE READ FROM SOCKET" ;
294+ }
295+ if (events & EPOLLOUT) {
296+ write_to_socket (conn);
297+ LOG (DEBUG) << " WE WROTE TO SOCKET" ;
298+ }
299+
300+ if (conn.state () == Client::kClosingConnection ) {
301+ close_connection (conn);
302+ return ;
303+ }
266304
267305 epoll_event ev;
268- ev.data .u64 = client_id;
269- ev.events = next_events;
306+ ev.data .u64 = conn.id ();
307+
308+ if (conn.state () == Client::kReceivingHeaders ) {
309+ ev.events = EPOLLIN;
310+ epoll_ctl (epoll_fd_, EPOLL_CTL_MOD, conn.fd (), &ev);
311+ LOG (DEBUG) << " WE REGISTERED EPOLLIN" ;
312+ return ;
313+ }
314+
315+ uint32_t event_mask = 0 ;
316+
317+ if (conn.handler ()->needs_input ())
318+ event_mask |= EPOLLIN;
319+ if (conn.handler ()->has_output () || !conn.send_buffer ().empty ())
320+ event_mask |= EPOLLOUT;
321+
322+ ev.events = event_mask;
270323 epoll_ctl (epoll_fd_, EPOLL_CTL_MOD, conn.fd (), &ev);
271324}
0 commit comments