aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd')
-rw-r--r--src/microhttpd/connection.c32
-rw-r--r--src/microhttpd/daemon.c76
2 files changed, 72 insertions, 36 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index b3c43b63..6223b994 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -483,6 +483,19 @@ MHD_connection_close_ (struct MHD_Connection *connection,
483 &connection->client_context, 483 &connection->client_context,
484 termination_code); 484 termination_code);
485 connection->client_aware = MHD_NO; 485 connection->client_aware = MHD_NO;
486
487 /* if we were at the connection limit before and are in
488 thread-per-connection mode, signal the main thread
489 to resume accepting connections */
490 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
491 (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
492 (1 != MHD_pipe_write_ (daemon->wpipe[1], "c", 1)) )
493 {
494#ifdef HAVE_MESSAGES
495 MHD_DLOG (daemon,
496 "failed to signal end of connection via pipe");
497#endif
498 }
486} 499}
487 500
488 501
@@ -1527,6 +1540,7 @@ parse_initial_message_line (struct MHD_Connection *connection,
1527 size_t line_len) 1540 size_t line_len)
1528{ 1541{
1529 struct MHD_Daemon *daemon = connection->daemon; 1542 struct MHD_Daemon *daemon = connection->daemon;
1543 const char *curi;
1530 char *uri; 1544 char *uri;
1531 char *http_version; 1545 char *http_version;
1532 char *args; 1546 char *args;
@@ -1539,16 +1553,19 @@ parse_initial_message_line (struct MHD_Connection *connection,
1539 uri++; 1553 uri++;
1540 /* Skip any spaces. Not required by standard but allow 1554 /* Skip any spaces. Not required by standard but allow
1541 to be more tolerant. */ 1555 to be more tolerant. */
1542 while (' ' == uri[0] && (size_t)(uri - line) < line_len) 1556 while ( (' ' == uri[0]) &&
1557 ( (size_t)(uri - line) < line_len) )
1543 uri++; 1558 uri++;
1544 if (uri - line == line_len) 1559 if (uri - line == line_len)
1545 { 1560 {
1546 uri = ""; 1561 curi = "";
1562 uri = NULL;
1547 connection->version = ""; 1563 connection->version = "";
1548 args = NULL; 1564 args = NULL;
1549 } 1565 }
1550 else 1566 else
1551 { 1567 {
1568 curi = uri;
1552 /* Search from back to accept misformed URI with space */ 1569 /* Search from back to accept misformed URI with space */
1553 http_version = line + line_len - 1; 1570 http_version = line + line_len - 1;
1554 /* Skip any trailing spaces */ 1571 /* Skip any trailing spaces */
@@ -1572,7 +1589,7 @@ parse_initial_message_line (struct MHD_Connection *connection,
1572 if (NULL != daemon->uri_log_callback) 1589 if (NULL != daemon->uri_log_callback)
1573 connection->client_context 1590 connection->client_context
1574 = daemon->uri_log_callback (daemon->uri_log_callback_cls, 1591 = daemon->uri_log_callback (daemon->uri_log_callback_cls,
1575 uri, 1592 curi,
1576 connection); 1593 connection);
1577 if (NULL != args) 1594 if (NULL != args)
1578 { 1595 {
@@ -1585,10 +1602,11 @@ parse_initial_message_line (struct MHD_Connection *connection,
1585 &connection_add_header, 1602 &connection_add_header,
1586 &unused_num_headers); 1603 &unused_num_headers);
1587 } 1604 }
1588 daemon->unescape_callback (daemon->unescape_callback_cls, 1605 if (NULL != uri)
1589 connection, 1606 daemon->unescape_callback (daemon->unescape_callback_cls,
1590 uri); 1607 connection,
1591 connection->url = uri; 1608 uri);
1609 connection->url = curi;
1592 return MHD_YES; 1610 return MHD_YES;
1593} 1611}
1594 1612
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 7e13e311..77f43537 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -1281,6 +1281,17 @@ send_param_adapter (struct MHD_Connection *connection,
1281 1281
1282 1282
1283/** 1283/**
1284 * Free resources associated with all closed connections.
1285 * (destroy responses, free buffers, etc.). All closed
1286 * connections are kept in the "cleanup" doubly-linked list.
1287 *
1288 * @param daemon daemon to clean up
1289 */
1290static void
1291MHD_cleanup_connections (struct MHD_Daemon *daemon);
1292
1293
1294/**
1284 * Add another client connection to the set of connections 1295 * Add another client connection to the set of connections
1285 * managed by MHD. This API is usually not needed (since 1296 * managed by MHD. This API is usually not needed (since
1286 * MHD will accept inbound connections on the server socket). 1297 * MHD will accept inbound connections on the server socket).
@@ -1371,6 +1382,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
1371 client_socket); 1382 client_socket);
1372#endif 1383#endif
1373#endif 1384#endif
1385 //if (daemon->connections == daemon->connection_limit)
1386 // MHD_cleanup_connections (daemon); /* try to aggressively clean up to make room */
1374 if ( (daemon->connections == daemon->connection_limit) || 1387 if ( (daemon->connections == daemon->connection_limit) ||
1375 (MHD_NO == MHD_ip_limit_add (daemon, addr, addrlen)) ) 1388 (MHD_NO == MHD_ip_limit_add (daemon, addr, addrlen)) )
1376 { 1389 {
@@ -1537,7 +1550,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
1537 1550
1538 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 1551 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1539 { 1552 {
1540 if (!MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) 1553 if (! MHD_mutex_lock_ (&daemon->cleanup_connection_mutex))
1541 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 1554 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1542 } 1555 }
1543 else 1556 else
@@ -2070,7 +2083,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
2070 struct MHD_Connection *pos; 2083 struct MHD_Connection *pos;
2071 2084
2072 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 2085 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2073 (!MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) 2086 (! MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
2074 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 2087 MHD_PANIC ("Failed to acquire cleanup mutex\n");
2075 while (NULL != (pos = daemon->cleanup_head)) 2088 while (NULL != (pos = daemon->cleanup_head))
2076 { 2089 {
@@ -2080,7 +2093,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
2080 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 2093 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2081 (MHD_NO == pos->thread_joined) ) 2094 (MHD_NO == pos->thread_joined) )
2082 { 2095 {
2083 if (!MHD_join_thread_ (pos->pid)) 2096 if (! MHD_join_thread_ (pos->pid))
2084 { 2097 {
2085 MHD_PANIC ("Failed to join a thread\n"); 2098 MHD_PANIC ("Failed to join a thread\n");
2086 } 2099 }
@@ -2092,6 +2105,8 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
2092#endif 2105#endif
2093 daemon->connections--; 2106 daemon->connections--;
2094 daemon->at_limit = MHD_NO; 2107 daemon->at_limit = MHD_NO;
2108
2109 /* clean up the connection */
2095 if (NULL != daemon->notify_connection) 2110 if (NULL != daemon->notify_connection)
2096 daemon->notify_connection (daemon->notify_connection_cls, 2111 daemon->notify_connection (daemon->notify_connection_cls,
2097 pos, 2112 pos,
@@ -2141,7 +2156,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
2141 free (pos); 2156 free (pos);
2142 } 2157 }
2143 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 2158 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2144 (!MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) ) 2159 (! MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
2145 MHD_PANIC ("Failed to release cleanup mutex\n"); 2160 MHD_PANIC ("Failed to release cleanup mutex\n");
2146} 2161}
2147 2162
@@ -2364,17 +2379,6 @@ MHD_select (struct MHD_Daemon *daemon,
2364#endif 2379#endif
2365 err_state = MHD_YES; 2380 err_state = MHD_YES;
2366 } 2381 }
2367
2368 /* If we're at the connection limit, no need to
2369 accept new connections; however, make sure
2370 we do not miss the shutdown, so only do this
2371 optimization if we have a shutdown signaling
2372 pipe. */
2373 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2374 ( ( (daemon->connections == daemon->connection_limit) &&
2375 (0 != (daemon->options & MHD_USE_PIPE_FOR_SHUTDOWN)) ) ||
2376 (MHD_YES == daemon->at_limit) ) )
2377 FD_CLR (daemon->socket_fd, &rs);
2378 } 2382 }
2379 else 2383 else
2380 { 2384 {
@@ -2420,7 +2424,21 @@ MHD_select (struct MHD_Daemon *daemon,
2420 } 2424 }
2421#endif /* MHD_WINSOCK_SOCKETS */ 2425#endif /* MHD_WINSOCK_SOCKETS */
2422 } 2426 }
2423 2427 /* Stop listening if we are at the configured connection limit */
2428 /* If we're at the connection limit, no point in really
2429 accepting new connections; however, make sure we do not miss
2430 the shutdown OR the termination of an existing connection; so
2431 only do this optimization if we have a signaling pipe in
2432 place. */
2433 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2434 (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
2435 (0 != (daemon->options & MHD_USE_PIPE_FOR_SHUTDOWN)) &&
2436 ( (daemon->connections == daemon->connection_limit) ||
2437 (MHD_YES == daemon->at_limit) ) )
2438 {
2439 FD_CLR (daemon->socket_fd,
2440 &rs);
2441 }
2424 tv = NULL; 2442 tv = NULL;
2425 if (MHD_YES == err_state) 2443 if (MHD_YES == err_state)
2426 may_block = MHD_NO; 2444 may_block = MHD_NO;
@@ -4185,7 +4203,7 @@ MHD_start_daemon_va (unsigned int flags,
4185 } 4203 }
4186#endif 4204#endif
4187 4205
4188 if (!MHD_mutex_init_ (&daemon->per_ip_connection_mutex)) 4206 if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex))
4189 { 4207 {
4190#ifdef HAVE_MESSAGES 4208#ifdef HAVE_MESSAGES
4191 MHD_DLOG (daemon, 4209 MHD_DLOG (daemon,
@@ -4196,7 +4214,7 @@ MHD_start_daemon_va (unsigned int flags,
4196 MHD_PANIC ("close failed\n"); 4214 MHD_PANIC ("close failed\n");
4197 goto free_and_fail; 4215 goto free_and_fail;
4198 } 4216 }
4199 if (!MHD_mutex_init_ (&daemon->cleanup_connection_mutex)) 4217 if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
4200 { 4218 {
4201#ifdef HAVE_MESSAGES 4219#ifdef HAVE_MESSAGES
4202 MHD_DLOG (daemon, 4220 MHD_DLOG (daemon,
@@ -4229,12 +4247,12 @@ MHD_start_daemon_va (unsigned int flags,
4229 ( (0 != (flags & MHD_USE_SELECT_INTERNALLY)) && 4247 ( (0 != (flags & MHD_USE_SELECT_INTERNALLY)) &&
4230 (0 == daemon->worker_pool_size)) ) && 4248 (0 == daemon->worker_pool_size)) ) &&
4231 (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) && 4249 (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) &&
4232 (!MHD_create_named_thread_ (&daemon->pid, 4250 (! MHD_create_named_thread_ (&daemon->pid,
4233 (flags & MHD_USE_THREAD_PER_CONNECTION) ? 4251 (flags & MHD_USE_THREAD_PER_CONNECTION) ?
4234 "MHD-listen" : "MHD-single", 4252 "MHD-listen" : "MHD-single",
4235 daemon->thread_stack_size, 4253 daemon->thread_stack_size,
4236 &MHD_select_thread, 4254 &MHD_select_thread,
4237 daemon) ) ) 4255 daemon) ) )
4238 { 4256 {
4239#ifdef HAVE_MESSAGES 4257#ifdef HAVE_MESSAGES
4240 MHD_DLOG (daemon, 4258 MHD_DLOG (daemon,
@@ -4342,11 +4360,11 @@ MHD_start_daemon_va (unsigned int flags,
4342 } 4360 }
4343 4361
4344 /* Spawn the worker thread */ 4362 /* Spawn the worker thread */
4345 if (!MHD_create_named_thread_(&d->pid, 4363 if (! MHD_create_named_thread_(&d->pid,
4346 "MHD-worker", 4364 "MHD-worker",
4347 daemon->thread_stack_size, 4365 daemon->thread_stack_size,
4348 &MHD_select_thread, 4366 &MHD_select_thread,
4349 d)) 4367 d))
4350 { 4368 {
4351#ifdef HAVE_MESSAGES 4369#ifdef HAVE_MESSAGES
4352 MHD_DLOG (daemon, 4370 MHD_DLOG (daemon,