Quellcode durchsuchen

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

Christian Grothoff vor 10 Jahren
Ursprung
Commit
7eba79ea86
4 geänderte Dateien mit 49 neuen und 36 gelöschten Zeilen
  1. 7 1
      ChangeLog
  2. 1 1
      src/include/microhttpd.h
  3. 40 33
      src/microhttpd/connection.c
  4. 1 1
      src/microhttpd/internal.h

+ 7 - 1
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

+ 1 - 1
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".

+ 40 - 33
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);

+ 1 - 1
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;