libmicrohttpd

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

commit 7eba79ea8607e1498fdc23a7045fe04f79c0daf5
parent 62f06f739ab45dc1b8d5a46c5a3060b641573e6e
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri, 26 Jun 2015 21:20:27 +0000

fix HEAD handling issue in connection with MHD_create_response_from_callback reported by Cristian Klein on the mailinglist

Diffstat:
MChangeLog | 8+++++++-
Msrc/include/microhttpd.h | 2+-
Msrc/microhttpd/connection.c | 73++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/microhttpd/internal.h | 2+-
4 files changed, 49 insertions(+), 36 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,9 @@ +Fri Jun 26 23:17:20 CEST 2015 + Fix (automatic) handling of HEAD requests with + MHD_create_response_from_callback() and HTTP/1.1 + connection keep-alives. Thanks to Cristian Klein + for reporting. -CG + Tue Jun 09 18:30:17 CEST 2015 Add new functions MHD_create_response_from_fd64() and MHD_create_response_from_fd_at_offset64(). -EG @@ -6,7 +12,7 @@ Thu Jun 4 13:37:05 CEST 2015 Fixing memory leak in digest authentication. -AW Wed Jun 03 21:23:47 CEST 2015 - Add deprecation compiler messages for deprecated functions + Add deprecation compiler messages for deprecated functions and macros. -EG Fri May 29 12:23:01 CEST 2015 diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h @@ -130,7 +130,7 @@ typedef intptr_t ssize_t; * Current version of the library. * 0x01093001 = 1.9.30-1. */ -#define MHD_VERSION 0x00094204 +#define MHD_VERSION 0x00094205 /** * MHD-internal return code for "YES". diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c @@ -337,7 +337,8 @@ try_ready_normal_body (struct MHD_Connection *connection) response = connection->response; if (NULL == response->crc) return MHD_YES; - if (0 == response->total_size) + if ( (0 == response->total_size) || + (connection->response_write_position == response->total_size) ) return MHD_YES; /* 0-byte response is always ready */ if ( (response->data_start <= connection->response_write_position) && @@ -2127,41 +2128,45 @@ MHD_connection_handle_write (struct MHD_Connection *connection) break; case MHD_CONNECTION_NORMAL_BODY_READY: response = connection->response; - if (NULL != response->crc) - (void) MHD_mutex_lock_ (&response->mutex); - if (MHD_YES != try_ready_normal_body (connection)) - break; - ret = connection->send_cls (connection, - &response->data - [connection->response_write_position - - response->data_start], - response->data_size - - (connection->response_write_position - - response->data_start)); - const int err = MHD_socket_errno_; + if (connection->response_write_position < + connection->response->total_size) + { + if (NULL != response->crc) + (void) MHD_mutex_lock_ (&response->mutex); + if (MHD_YES != try_ready_normal_body (connection)) + break; + ret = connection->send_cls (connection, + &response->data + [connection->response_write_position + - response->data_start], + response->data_size - + (connection->response_write_position + - response->data_start)); + const int err = MHD_socket_errno_; #if DEBUG_SEND_DATA - if (ret > 0) - fprintf (stderr, - "Sent DATA response: `%.*s'\n", - (int) ret, - &response->data[connection->response_write_position - - response->data_start]); + if (ret > 0) + fprintf (stderr, + "Sent DATA response: `%.*s'\n", + (int) ret, + &response->data[connection->response_write_position - + response->data_start]); #endif - if (NULL != response->crc) - (void) MHD_mutex_unlock_ (&response->mutex); - if (ret < 0) - { - if ((err == EINTR) || (err == EAGAIN) || (EWOULDBLOCK == err)) - return MHD_YES; + if (NULL != response->crc) + (void) MHD_mutex_unlock_ (&response->mutex); + if (ret < 0) + { + if ((err == EINTR) || (err == EAGAIN) || (EWOULDBLOCK == err)) + return MHD_YES; #if HAVE_MESSAGES - MHD_DLOG (connection->daemon, - "Failed to send data: %s\n", - MHD_socket_last_strerr_ ()); + MHD_DLOG (connection->daemon, + "Failed to send data: %s\n", + MHD_socket_last_strerr_ ()); #endif - CONNECTION_CLOSE_ERROR (connection, NULL); - return MHD_YES; - } - connection->response_write_position += ret; + CONNECTION_CLOSE_ERROR (connection, NULL); + return MHD_YES; + } + connection->response_write_position += ret; + } if (connection->response_write_position == connection->response->total_size) connection->state = MHD_CONNECTION_FOOTERS_SENT; /* have no footers */ @@ -2523,7 +2528,9 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) case MHD_CONNECTION_CHUNKED_BODY_UNREADY: if (NULL != connection->response->crc) (void) MHD_mutex_lock_ (&connection->response->mutex); - if (0 == connection->response->total_size) + if ( (0 == connection->response->total_size) || + (connection->response_write_position == + connection->response->total_size) ) { if (NULL != connection->response->crc) (void) MHD_mutex_unlock_ (&connection->response->mutex); diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h @@ -679,7 +679,7 @@ struct MHD_Connection size_t write_buffer_size; /** - * Offset where we are with sending from write_buffer. + * Offset where we are with sending from @e write_buffer. */ size_t write_buffer_send_offset;