libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 6d8b462082b0e8c69021bac140cd7d06686de6af
parent 1fb2f7354f420e5ae1748ec9a17cde8c4c3e05c4
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri, 15 May 2009 03:22:33 +0000

fixing issue with completed notification being called multiple times

Diffstat:
MChangeLog | 8++++++++
Msrc/daemon/connection.c | 25+++++++++++++++----------
Msrc/daemon/internal.h | 7+++++++
3 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,11 @@ +Thu May 14 21:20:30 MDT 2009 + Fixed issue where the "NOTIFY_COMPLETED" handler could be called + twice (if a socket error or timeout occured for a pipelined + connection after successfully completing a request and before + the next request was successfully transmitted). This could + confuse applications not expecting to see a connection "complete" + that they were never aware of in the first place. -CG + Mon May 11 13:01:16 MDT 2009 Fixed issue where error code on timeout was "TERMINATED_WITH_ERROR" instead of "TERMINATED_TIMEOUT_REACHED". -CG diff --git a/src/daemon/connection.c b/src/daemon/connection.c @@ -287,16 +287,17 @@ void MHD_connection_close (struct MHD_Connection *connection, enum MHD_RequestTerminationCode termination_code) { - SHUTDOWN (connection->socket_fd, SHUT_RDWR); CLOSE (connection->socket_fd); connection->socket_fd = -1; connection->state = MHD_CONNECTION_CLOSED; - if (connection->daemon->notify_completed != NULL) + if ( (NULL != connection->daemon->notify_completed) && + (MHD_YES == connection->client_aware) ) connection->daemon->notify_completed (connection->daemon-> - notify_completed_cls, connection, - &connection->client_context, - termination_code); + notify_completed_cls, connection, + &connection->client_context, + termination_code); + connection->client_aware = MHD_NO; } /** @@ -1215,6 +1216,7 @@ call_connection_handler (struct MHD_Connection *connection) processed = available; } used = processed; + connection->client_aware = MHD_YES; if (MHD_NO == connection->daemon->default_handler (connection->daemon-> default_handler_cls, @@ -2039,11 +2041,14 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) #endif MHD_destroy_response (connection->response); if (connection->daemon->notify_completed != NULL) - connection->daemon->notify_completed (connection->daemon-> - notify_completed_cls, - connection, - &connection->client_context, - MHD_REQUEST_TERMINATED_COMPLETED_OK); + { + connection->daemon->notify_completed (connection->daemon-> + notify_completed_cls, + connection, + &connection->client_context, + MHD_REQUEST_TERMINATED_COMPLETED_OK); + } + connection->client_aware = MHD_NO; end = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_CONNECTION); diff --git a/src/daemon/internal.h b/src/daemon/internal.h @@ -512,6 +512,13 @@ struct MHD_Connection time_t last_activity; /** + * Did we ever call the "default_handler" on this connection? + * (this flag will determine if we call the 'notify_completed' + * handler when the connection closes down). + */ + int client_aware; + + /** * Socket for this connection. Set to -1 if * this connection has died (daemon should clean * up in that case).