aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/daemon.c')
-rw-r--r--src/daemon/daemon.c53
1 files changed, 47 insertions, 6 deletions
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index 3caade12..0c198454 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -163,20 +163,35 @@ MHD_handle_connection (void *data)
163 fd_set ws; 163 fd_set ws;
164 fd_set es; 164 fd_set es;
165 int max; 165 int max;
166 struct timeval tv;
167 unsigned int timeout;
168 time_t now;
166 169
167 if (con == NULL) 170 if (con == NULL)
168 abort (); 171 abort ();
169 while ((!con->daemon->shutdown) && (con->socket_fd != -1)) 172 timeout = con->daemon->connection_timeout;
173 now = time(NULL);
174 while ( (!con->daemon->shutdown) &&
175 (con->socket_fd != -1) &&
176 ( (timeout == 0) ||
177 (now - timeout > con->last_activity) ) )
170 { 178 {
171 FD_ZERO (&rs); 179 FD_ZERO (&rs);
172 FD_ZERO (&ws); 180 FD_ZERO (&ws);
173 FD_ZERO (&es); 181 FD_ZERO (&es);
174 max = 0; 182 max = 0;
175 MHD_connection_get_fdset (con, &rs, &ws, &es, &max); 183 MHD_connection_get_fdset (con, &rs, &ws, &es, &max);
176 num_ready = SELECT (max + 1, &rs, &ws, &es, NULL); 184 tv.tv_usec = 0;
177 if (num_ready <= 0) 185 tv.tv_sec = timeout - (now - con->last_activity);
186 num_ready = SELECT (max + 1,
187 &rs,
188 &ws,
189 &es,
190 (tv.tv_sec != 0) ? &tv : NULL);
191 now = time(NULL);
192 if (num_ready < 0)
178 { 193 {
179 if (errno == EINTR) 194 if (errno == EINTR)
180 continue; 195 continue;
181 break; 196 break;
182 } 197 }
@@ -188,6 +203,10 @@ MHD_handle_connection (void *data)
188 break; 203 break;
189 if ((con->headersReceived == 1) && (con->response == NULL)) 204 if ((con->headersReceived == 1) && (con->response == NULL))
190 MHD_call_connection_handler (con); 205 MHD_call_connection_handler (con);
206 if ( (con->socket_fd != -1) &&
207 ( (FD_ISSET (con->socket_fd, &rs)) ||
208 (FD_ISSET (con->socket_fd, &ws)) ) )
209 con->last_activity = now;
191 } 210 }
192 if (con->socket_fd != -1) 211 if (con->socket_fd != -1)
193 { 212 {
@@ -261,6 +280,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
261 free (connection); 280 free (connection);
262 return MHD_NO; 281 return MHD_NO;
263 } 282 }
283 connection->last_activity = time(NULL);
264 connection->next = daemon->connections; 284 connection->next = daemon->connections;
265 daemon->connections = connection; 285 daemon->connections = connection;
266 daemon->max_connections--; 286 daemon->max_connections--;
@@ -284,11 +304,22 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
284 struct MHD_Connection *pos; 304 struct MHD_Connection *pos;
285 struct MHD_Connection *prev; 305 struct MHD_Connection *prev;
286 void *unused; 306 void *unused;
307 time_t timeout;
287 308
309 timeout = time(NULL);
310 if (daemon->connection_timeout != 0)
311 timeout -= daemon->connection_timeout;
312 else
313 timeout = 0;
288 pos = daemon->connections; 314 pos = daemon->connections;
289 prev = NULL; 315 prev = NULL;
290 while (pos != NULL) 316 while (pos != NULL)
291 { 317 {
318 if ( (pos->last_activity < timeout) &&
319 (pos->socket_fd != -1) ) {
320 CLOSE(pos->socket_fd);
321 pos->socket_fd = -1;
322 }
292 if (pos->socket_fd == -1) 323 if (pos->socket_fd == -1)
293 { 324 {
294 if (prev == NULL) 325 if (prev == NULL)
@@ -339,6 +370,7 @@ MHD_select (struct MHD_Daemon *daemon, int may_block)
339 int max; 370 int max;
340 struct timeval timeout; 371 struct timeval timeout;
341 int ds; 372 int ds;
373 time_t now;
342 374
343 timeout.tv_sec = 0; 375 timeout.tv_sec = 0;
344 timeout.tv_usec = 0; 376 timeout.tv_usec = 0;
@@ -378,6 +410,7 @@ MHD_select (struct MHD_Daemon *daemon, int may_block)
378 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 410 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
379 { 411 {
380 /* do not have a thread per connection, process all connections now */ 412 /* do not have a thread per connection, process all connections now */
413 now = time(NULL);
381 pos = daemon->connections; 414 pos = daemon->connections;
382 while (pos != NULL) 415 while (pos != NULL)
383 { 416 {
@@ -387,10 +420,14 @@ MHD_select (struct MHD_Daemon *daemon, int may_block)
387 pos = pos->next; 420 pos = pos->next;
388 continue; 421 continue;
389 } 422 }
390 if (FD_ISSET (ds, &rs)) 423 if (FD_ISSET (ds, &rs)) {
424 pos->last_activity = now;
391 MHD_connection_handle_read (pos); 425 MHD_connection_handle_read (pos);
392 if (FD_ISSET (ds, &ws)) 426 }
427 if (FD_ISSET (ds, &ws)) {
428 pos->last_activity = now;
393 MHD_connection_handle_write (pos); 429 MHD_connection_handle_write (pos);
430 }
394 pos = pos->next; 431 pos = pos->next;
395 } 432 }
396 } 433 }
@@ -530,6 +567,7 @@ MHD_start_daemon (unsigned int options,
530 retVal->default_handler.next = NULL; 567 retVal->default_handler.next = NULL;
531 retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT; 568 retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT;
532 retVal->pool_size = MHD_POOL_SIZE_DEFAULT; 569 retVal->pool_size = MHD_POOL_SIZE_DEFAULT;
570 retVal->connection_timeout = 0; /* no timeout */
533 va_start (ap, dh_cls); 571 va_start (ap, dh_cls);
534 while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION))) 572 while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION)))
535 { 573 {
@@ -541,6 +579,9 @@ MHD_start_daemon (unsigned int options,
541 case MHD_OPTION_CONNECTION_LIMIT: 579 case MHD_OPTION_CONNECTION_LIMIT:
542 retVal->max_connections = va_arg (ap, unsigned int); 580 retVal->max_connections = va_arg (ap, unsigned int);
543 break; 581 break;
582 case MHD_OPTION_CONNECTION_TIMEOUT:
583 retVal->connection_timeout = va_arg (ap, unsigned int);
584 break;
544 default: 585 default:
545 fprintf (stderr, 586 fprintf (stderr,
546 "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); 587 "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n");