mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-27 04:09:31 +03:00
-fix misc issues with upgrade introduction
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2015 Daniel Pittman and Christian Grothoff
|
||||
Copyright (C) 2007-2016 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
+73
-26
@@ -654,14 +654,15 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
|
||||
unsigned int fd_setsize)
|
||||
{
|
||||
struct MHD_Connection *pos;
|
||||
struct MHD_UpgradeResponseHandle *urh;
|
||||
int result = MHD_YES;
|
||||
|
||||
if ( (NULL == daemon)
|
||||
|| (NULL == read_fd_set)
|
||||
|| (NULL == write_fd_set)
|
||||
|| (MHD_YES == daemon->shutdown)
|
||||
|| (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
|
||||
|| (0 != (daemon->options & MHD_USE_POLL)))
|
||||
if ( (NULL == daemon) ||
|
||||
(NULL == read_fd_set) ||
|
||||
(NULL == write_fd_set) ||
|
||||
(MHD_YES == daemon->shutdown) ||
|
||||
(0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
|
||||
(0 != (daemon->options & MHD_USE_POLL)))
|
||||
return MHD_NO;
|
||||
#ifdef EPOLL_SUPPORT
|
||||
if (0 != (daemon->options & MHD_USE_EPOLL))
|
||||
@@ -669,11 +670,17 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
|
||||
/* we're in epoll mode, use the epoll FD as a stand-in for
|
||||
the entire event set */
|
||||
|
||||
return MHD_add_to_fd_set_ (daemon->epoll_fd, read_fd_set, max_fd, fd_setsize) ? MHD_YES : MHD_NO;
|
||||
return MHD_add_to_fd_set_ (daemon->epoll_fd,
|
||||
read_fd_set,
|
||||
max_fd,
|
||||
fd_setsize) ? MHD_YES : MHD_NO;
|
||||
}
|
||||
#endif
|
||||
if (MHD_INVALID_SOCKET != daemon->socket_fd &&
|
||||
!MHD_add_to_fd_set_ (daemon->socket_fd, read_fd_set, max_fd, fd_setsize))
|
||||
if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
|
||||
(! MHD_add_to_fd_set_ (daemon->socket_fd,
|
||||
read_fd_set,
|
||||
max_fd,
|
||||
fd_setsize)) )
|
||||
result = MHD_NO;
|
||||
|
||||
for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
|
||||
@@ -681,19 +688,31 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
|
||||
switch (pos->event_loop_info)
|
||||
{
|
||||
case MHD_EVENT_LOOP_INFO_READ:
|
||||
if (!MHD_add_to_fd_set_ (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
|
||||
if (! MHD_add_to_fd_set_ (pos->socket_fd,
|
||||
read_fd_set,
|
||||
max_fd,
|
||||
fd_setsize))
|
||||
result = MHD_NO;
|
||||
break;
|
||||
case MHD_EVENT_LOOP_INFO_WRITE:
|
||||
if (!MHD_add_to_fd_set_ (pos->socket_fd, write_fd_set, max_fd, fd_setsize))
|
||||
if (! MHD_add_to_fd_set_ (pos->socket_fd,
|
||||
write_fd_set,
|
||||
max_fd,
|
||||
fd_setsize))
|
||||
result = MHD_NO;
|
||||
if (pos->read_buffer_size > pos->read_buffer_offset &&
|
||||
!MHD_add_to_fd_set_ (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
|
||||
if ( (pos->read_buffer_size > pos->read_buffer_offset) &&
|
||||
! MHD_add_to_fd_set_ (pos->socket_fd,
|
||||
read_fd_set,
|
||||
max_fd,
|
||||
fd_setsize))
|
||||
result = MHD_NO;
|
||||
break;
|
||||
case MHD_EVENT_LOOP_INFO_BLOCK:
|
||||
if (pos->read_buffer_size > pos->read_buffer_offset &&
|
||||
!MHD_add_to_fd_set_ (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
|
||||
if ( (pos->read_buffer_size > pos->read_buffer_offset) &&
|
||||
! MHD_add_to_fd_set_ (pos->socket_fd,
|
||||
read_fd_set,
|
||||
max_fd,
|
||||
fd_setsize))
|
||||
result = MHD_NO;
|
||||
break;
|
||||
case MHD_EVENT_LOOP_INFO_CLEANUP:
|
||||
@@ -701,6 +720,33 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
|
||||
{
|
||||
if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->celi_mhd)) &&
|
||||
(! MHD_add_to_fd_set_ (urh->mhd_socket,
|
||||
read_fd_set,
|
||||
max_fd,
|
||||
fd_setsize)) )
|
||||
result = MHD_NO;
|
||||
if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_mhd)) &&
|
||||
(! MHD_add_to_fd_set_ (urh->mhd_socket,
|
||||
write_fd_set,
|
||||
max_fd,
|
||||
fd_setsize)) )
|
||||
result = MHD_NO;
|
||||
if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->celi_client)) &&
|
||||
(! MHD_add_to_fd_set_ (urh->connection->socket_fd,
|
||||
read_fd_set,
|
||||
max_fd,
|
||||
fd_setsize)) )
|
||||
result = MHD_NO;
|
||||
if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->celi_client)) &&
|
||||
(! MHD_add_to_fd_set_ (urh->connection->socket_fd,
|
||||
write_fd_set,
|
||||
max_fd,
|
||||
fd_setsize)) )
|
||||
result = MHD_NO;
|
||||
}
|
||||
#if DEBUG_CONNECT
|
||||
#ifdef HAVE_MESSAGES
|
||||
if (NULL != max_fd)
|
||||
@@ -714,9 +760,8 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
|
||||
|
||||
|
||||
/**
|
||||
* Call the handlers for a connection in the
|
||||
* appropriate order based on the readiness as
|
||||
* detected by the event loop.
|
||||
* Call the handlers for a connection in the appropriate order based
|
||||
* on the readiness as detected by the event loop.
|
||||
*
|
||||
* @param con connection to handle
|
||||
* @param read_ready set if the socket is ready for reading
|
||||
@@ -1239,7 +1284,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
if ( (!MHD_SCKT_FD_FITS_FDSET_(client_socket, NULL)) &&
|
||||
if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket, NULL)) &&
|
||||
(0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
|
||||
{
|
||||
#ifdef HAVE_MESSAGES
|
||||
@@ -1791,7 +1836,7 @@ MHD_add_connection (struct MHD_Daemon *daemon,
|
||||
already set in MHD_USE_EPOLL_TURBO mode */
|
||||
if (0 != (daemon->options & MHD_USE_EPOLL_TURBO))
|
||||
{
|
||||
if (!MHD_socket_nonblocking_ (client_socket))
|
||||
if (! MHD_socket_nonblocking_ (client_socket))
|
||||
{
|
||||
#ifdef HAVE_MESSAGES
|
||||
MHD_DLOG (daemon,
|
||||
@@ -1799,7 +1844,7 @@ MHD_add_connection (struct MHD_Daemon *daemon,
|
||||
MHD_socket_last_strerr_());
|
||||
#endif
|
||||
}
|
||||
if (!MHD_socket_noninheritable_ (client_socket))
|
||||
if (! MHD_socket_noninheritable_ (client_socket))
|
||||
{
|
||||
#ifdef HAVE_MESSAGES
|
||||
MHD_DLOG (daemon,
|
||||
@@ -1858,7 +1903,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
|
||||
if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err))
|
||||
return MHD_NO; /* do not print error if client just disconnected early */
|
||||
#ifdef HAVE_MESSAGES
|
||||
if ( !MHD_SCKT_ERR_IS_EAGAIN_ (err) )
|
||||
if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) )
|
||||
MHD_DLOG (daemon,
|
||||
"Error accepting connection: %s\n",
|
||||
MHD_socket_strerr_(err));
|
||||
@@ -1895,7 +1940,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
|
||||
return MHD_NO;
|
||||
}
|
||||
#if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK)
|
||||
if (!MHD_socket_nonblocking_ (s))
|
||||
if (! MHD_socket_nonblocking_ (s))
|
||||
{
|
||||
#ifdef HAVE_MESSAGES
|
||||
MHD_DLOG (daemon,
|
||||
@@ -1905,7 +1950,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
|
||||
}
|
||||
#endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */
|
||||
#if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC)
|
||||
if (!MHD_socket_noninheritable_ (s))
|
||||
if (! MHD_socket_noninheritable_ (s))
|
||||
{
|
||||
#ifdef HAVE_MESSAGES
|
||||
MHD_DLOG (daemon,
|
||||
@@ -1920,8 +1965,10 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
|
||||
s);
|
||||
#endif
|
||||
#endif
|
||||
(void) internal_add_connection (daemon, s,
|
||||
addr, addrlen,
|
||||
(void) internal_add_connection (daemon,
|
||||
s,
|
||||
addr,
|
||||
addrlen,
|
||||
MHD_NO);
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
+21
-10
@@ -147,22 +147,22 @@ enum MHD_ConnectionEventLoopInfo
|
||||
/**
|
||||
* We are waiting to be able to read.
|
||||
*/
|
||||
MHD_EVENT_LOOP_INFO_READ = 1,
|
||||
MHD_EVENT_LOOP_INFO_READ = 0,
|
||||
|
||||
/**
|
||||
* We are waiting to be able to write.
|
||||
*/
|
||||
MHD_EVENT_LOOP_INFO_WRITE = 2,
|
||||
MHD_EVENT_LOOP_INFO_WRITE = 1,
|
||||
|
||||
/**
|
||||
* We are waiting for the application to provide data.
|
||||
*/
|
||||
MHD_EVENT_LOOP_INFO_BLOCK = 4,
|
||||
MHD_EVENT_LOOP_INFO_BLOCK = 2,
|
||||
|
||||
/**
|
||||
* We are finished and are awaiting cleanup.
|
||||
*/
|
||||
MHD_EVENT_LOOP_INFO_CLEANUP = 8
|
||||
MHD_EVENT_LOOP_INFO_CLEANUP = 3
|
||||
};
|
||||
|
||||
|
||||
@@ -917,11 +917,6 @@ struct MHD_UpgradeResponseHandle
|
||||
*/
|
||||
MHD_socket app_socket;
|
||||
|
||||
/**
|
||||
* IO-state of the @e app_socket.
|
||||
*/
|
||||
enum MHD_ConnectionEventLoopInfo celi_app;
|
||||
|
||||
/**
|
||||
* If @a app_sock was a socketpair, our end of it, otherwise
|
||||
* #MHD_INVALID_SOCKET; (r/w).
|
||||
@@ -931,7 +926,13 @@ struct MHD_UpgradeResponseHandle
|
||||
/**
|
||||
* IO-state of the @e mhd_socket.
|
||||
*/
|
||||
enum MHD_ConnectionEventLoopInfo celi_mhd;
|
||||
enum MHD_EpollState celi_mhd;
|
||||
|
||||
/**
|
||||
* IO-state of the @e connection's socket.
|
||||
*/
|
||||
enum MHD_EpollState celi_client;
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -1026,6 +1027,16 @@ struct MHD_Daemon
|
||||
struct MHD_Connection *eready_tail;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Head of DLL of upgrade response handles we are processing.
|
||||
*/
|
||||
struct MHD_UpgradeResponseHandle *urh_head;
|
||||
|
||||
/**
|
||||
* Tail of DLL of upgrade response handles we are processing.
|
||||
*/
|
||||
struct MHD_UpgradeResponseHandle *urh_tail;
|
||||
|
||||
/**
|
||||
* Head of the XDLL of ALL connections with a default ('normal')
|
||||
* timeout, sorted by timeout (earliest at the tail, most recently
|
||||
|
||||
@@ -597,10 +597,20 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh,
|
||||
enum MHD_UpgradeAction action,
|
||||
...)
|
||||
{
|
||||
struct MHD_Daemon *daemon = urh->connection->daemon;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case MHD_UPGRADE_ACTION_CLOSE:
|
||||
/* Application is done with this connection, tear it down! */
|
||||
if (0 != (daemon->options & MHD_USE_SSL) )
|
||||
{
|
||||
DLL_remove (daemon->urh_head,
|
||||
daemon->urh_tail,
|
||||
urh);
|
||||
/* FIXME: if running in epoll()-mode, do we have
|
||||
to remove any of the FDs from any epoll-sets here? */
|
||||
}
|
||||
if ( (MHD_INVALID_SOCKET != urh->app_socket) &&
|
||||
(0 != MHD_socket_close_ (urh->app_socket)) )
|
||||
MHD_PANIC ("close failed\n");
|
||||
@@ -636,6 +646,7 @@ int
|
||||
MHD_response_execute_upgrade_ (struct MHD_Response *response,
|
||||
struct MHD_Connection *connection)
|
||||
{
|
||||
struct MHD_Daemon *daemon = connection->daemon;
|
||||
struct MHD_UpgradeResponseHandle *urh;
|
||||
int sv[2];
|
||||
size_t rbo;
|
||||
@@ -645,7 +656,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
|
||||
MHD_HTTP_HEADER_UPGRADE))
|
||||
{
|
||||
#ifdef HAVE_MESSAGES
|
||||
MHD_DLOG (connection->daemon,
|
||||
MHD_DLOG (daemon,
|
||||
"Invalid response for upgrade: application failed to set the 'Upgrade' header!\n");
|
||||
#endif
|
||||
return MHD_NO;
|
||||
@@ -655,7 +666,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
|
||||
if (NULL == urh)
|
||||
return MHD_NO;
|
||||
#if HTTPS_SUPPORT
|
||||
if (0 != (connection->daemon->options & MHD_USE_SSL) )
|
||||
if (0 != (daemon->options & MHD_USE_SSL) )
|
||||
{
|
||||
/* FIXME: this is non-portable for now; W32 port pending... */
|
||||
if (0 != socketpair (AF_UNIX,
|
||||
@@ -666,6 +677,23 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
|
||||
free (urh);
|
||||
return MHD_NO;
|
||||
}
|
||||
if ( (! MHD_SCKT_FD_FITS_FDSET_(sv[1], NULL)) &&
|
||||
(0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
|
||||
{
|
||||
#ifdef HAVE_MESSAGES
|
||||
MHD_DLOG (daemon,
|
||||
"Socketpair descriptor larger than FD_SETSIZE: %d > %d\n",
|
||||
(int) sv[1],
|
||||
(int) FD_SETSIZE);
|
||||
#endif
|
||||
if (0 != MHD_socket_close_ (sv[0]))
|
||||
MHD_PANIC ("close failed\n");
|
||||
if (0 != MHD_socket_close_ (sv[1]))
|
||||
MHD_PANIC ("close failed\n");
|
||||
free (urh);
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
urh->app_socket = sv[0];
|
||||
urh->mhd_socket = sv[1];
|
||||
urh->connection = connection;
|
||||
@@ -682,8 +710,14 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response,
|
||||
suspended; it will be resumed once we are done
|
||||
in the #MHD_upgrade_action() function */
|
||||
MHD_suspend_connection (connection);
|
||||
/* FIXME: also need to start some processing logic in _all_ MHD
|
||||
event loops for the sv traffic! (NOT IMPLEMENTED!!!) */
|
||||
urh->celi_mhd = MHD_EPOLL_STATE_UNREADY;
|
||||
urh->celi_client = MHD_EPOLL_STATE_UNREADY;
|
||||
/* FIXME: is it possible we did not fully drain the client
|
||||
socket yet and are thus read-ready already? This may
|
||||
matter if we are in epoll() edge triggered mode... */
|
||||
DLL_insert (connection->daemon->urh_head,
|
||||
connection->daemon->urh_tail,
|
||||
urh);
|
||||
return MHD_YES;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user