Forráskód Böngészése

add remaining missing symbols for library to fully link

Christian Grothoff 8 éve
szülő
commit
e5c2f9a339

+ 20 - 0
src/gnutls/update_event_loop_info.c

@@ -0,0 +1,20 @@
+  enum MHD_Bool
+  (*update_event_loop_info)(void *cls,
+			    struct MHD_TLS_ConnectionState *cs,
+			    enum MHD_RequestEventLoopInfo *eli);
+
+
+      switch (connection->tls_state)
+        {
+          case MHD_TLS_CONN_INIT:
+            *eli = MHD_EVENT_LOOP_INFO_READ;
+            return true;
+          case MHD_TLS_CONN_HANDSHAKING:
+            if (0 == gnutls_record_get_direction (connection->tls_session))
+              *eli = MHD_EVENT_LOOP_INFO_READ;
+            else
+              *eli = MHD_EVENT_LOOP_INFO_WRITE;
+            return true;
+          default:
+            return false;
+        }

+ 37 - 2
src/include/microhttpd2.h

@@ -323,12 +323,13 @@ struct MHD_Connection;
  * for logging.
  *
  * A value of 0 indicates success (as a return value).
- * Values between 1 and 10000 must not be used.
+ * Values between 0 and 10000 must be handled explicitly by the app.
  * Values from 10000-19999 are informational.
  * Values from 20000-29999 indicate successful operations.
  * Values from 30000-39999 indicate unsuccessful (normal) operations.
  * Values from 40000-49999 indicate client errors.
- * Values from 50000-59999 indicate server errors.
+ * Values from 50000-59999 indicate MHD server errors.
+ * Values from 60000-69999 indicate application errors.
  */
 enum MHD_StatusCode
 {
@@ -866,6 +867,13 @@ enum MHD_StatusCode
    */
   MHD_SC_APPLICATION_HUNG_CONNECTION = 60007,
 
+  /**
+   * Application only partially processed upload and did
+   * not suspend connection and the read buffer was maxxed
+   * out, so MHD closed the connection.
+   */
+  MHD_SC_APPLICATION_HUNG_CONNECTION_CLOSED = 60008,
+
 
 };
 
@@ -4154,4 +4162,31 @@ _MHD_EXTERN enum MHD_Bool
 MHD_is_feature_supported (enum MHD_Feature feature);
 
 
+/**
+ * What is this request waiting for?
+ */
+enum MHD_RequestEventLoopInfo
+{
+  /**
+   * We are waiting to be able to read.
+   */
+  MHD_EVENT_LOOP_INFO_READ = 0,
+
+  /**
+   * We are waiting to be able to write.
+   */
+  MHD_EVENT_LOOP_INFO_WRITE = 1,
+
+  /**
+   * We are waiting for the application to provide data.
+   */
+  MHD_EVENT_LOOP_INFO_BLOCK = 2,
+
+  /**
+   * We are finished and are awaiting cleanup.
+   */
+  MHD_EVENT_LOOP_INFO_CLEANUP = 3
+};
+
+
 #endif

+ 33 - 0
src/include/microhttpd_tls.h

@@ -1,6 +1,33 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2018 Christian Grothoff (and other contributing authors)
+
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Lesser General Public
+     License as published by the Free Software Foundation; either
+     version 2.1 of the License, or (at your option) any later version.
+
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Lesser General Public License for more details.
+
+     You should have received a copy of the GNU Lesser General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+/**
+ * @file microhttpd_tls.h
+ * @brief interface for TLS plugins of libmicrohttpd
+ * @author Christian Grothoff
+ */
+
 #ifndef MICROHTTPD_TLS_H
 #define MICROHTTPD_TLS_H
 
+#include <microhttpd2.h>
+
 /**
  * Version of the TLS ABI.
  */
@@ -100,6 +127,12 @@ struct MHD_TLS_Plugin
   enum MHD_Bool
   (*idle_ready)(void *cls,
 		struct MHD_TLS_ConnectionState *cs);
+
+
+  enum MHD_Bool
+  (*update_event_loop_info)(void *cls,
+			    struct MHD_TLS_ConnectionState *cs,
+			    enum MHD_RequestEventLoopInfo *eli);
   
   ssize_t
   (*send)(void *cls,

+ 0 - 1
src/lib/Makefile.am

@@ -65,7 +65,6 @@ libmicrohttpd_la_SOURCES = \
   connection_finish_forward.c connection_finish_forward.h \
   connection_info.c \
   connection_options.c \
-  connection_update_event_loop_info.c connection_update_event_loop_info.h \
   connection_update_last_activity.c connection_update_last_activity.h \
   daemon_close_all_connections.c daemon_close_all_connections.h \
   daemon_create.c \

+ 1 - 1
src/lib/action_from_response.c

@@ -89,7 +89,7 @@ response_action (void *cls,
       request->state = MHD_REQUEST_FOOTERS_RECEIVED;
     }
   if (! request->in_idle)
-    (void) MHD_connection_handle_idle (request->connection);
+    (void) MHD_request_handle_idle_ (request);
   return MHD_SC_OK;
 }
 

+ 165 - 2
src/lib/connection_call_handlers.c

@@ -23,7 +23,6 @@
  */
 #include "internal.h"
 #include "connection_call_handlers.h"
-#include "connection_update_event_loop_info.h"
 #include "connection_update_last_activity.h"
 #include "connection_close.h"
 
@@ -2888,6 +2887,170 @@ connection_epoll_update_ (struct MHD_Connection *connection)
 #endif
 
 
+/**
+ * Update the 'event_loop_info' field of this connection based on the
+ * state that the connection is now in.  May also close the connection
+ * or perform other updates to the connection if needed to prepare for
+ * the next round of the event loop.
+ *
+ * @param connection connection to get poll set for
+ */
+static void
+connection_update_event_loop_info (struct MHD_Connection *connection)
+{
+  struct MHD_Daemon *daemon = connection->daemon;
+  struct MHD_Request *request = &connection->request;
+  
+  /* Do not update states of suspended connection */
+  if (connection->suspended)
+    return; /* States will be updated after resume. */
+#ifdef HTTPS_SUPPORT
+  {
+    struct MHD_TLS_Plugin *tls;
+    
+    if ( (NULL != (tls = daemon->tls_api)) &&
+	 (tls->update_event_loop_info (tls->cls,
+				       connection->tls_cs,
+				       &request->event_loop_info)) )
+      return; /* TLS has decided what to do */
+  }
+#endif /* HTTPS_SUPPORT */
+  while (1)
+    {
+#if DEBUG_STATES
+      MHD_DLOG (daemon,
+		MHD_SC_STATE_MACHINE_STATUS_REPORT,
+                _("In function %s handling connection at state: %s\n"),
+                __FUNCTION__,
+                MHD_state_to_string (request->state));
+#endif
+      switch (request->state)
+        {
+        case MHD_REQUEST_INIT:
+        case MHD_REQUEST_URL_RECEIVED:
+        case MHD_REQUEST_HEADER_PART_RECEIVED:
+          /* while reading headers, we always grow the
+             read buffer if needed, no size-check required */
+          if ( (request->read_buffer_offset == request->read_buffer_size) &&
+	       (! try_grow_read_buffer (request)) )
+            {
+              transmit_error_response (request,
+				       MHD_SC_CLIENT_HEADER_TOO_BIG,
+                                       (NULL != request->url)
+                                       ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
+                                       : MHD_HTTP_URI_TOO_LONG,
+                                       REQUEST_TOO_BIG);
+              continue;
+            }
+	  if (! connection->read_closed)
+	    request->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+	  else
+	    request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+          break;
+        case MHD_REQUEST_HEADERS_RECEIVED:
+          mhd_assert (0);
+          break;
+        case MHD_REQUEST_HEADERS_PROCESSED:
+          mhd_assert (0);
+          break;
+        case MHD_REQUEST_CONTINUE_SENDING:
+          request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+          break;
+        case MHD_REQUEST_CONTINUE_SENT:
+          if (request->read_buffer_offset == request->read_buffer_size)
+            {
+              if ( (! try_grow_read_buffer (request)) &&
+		   (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_model) )
+                {
+                  /* failed to grow the read buffer, and the client
+                     which is supposed to handle the received data in
+                     a *blocking* fashion (in this mode) did not
+                     handle the data as it was supposed to!
+
+                     => we would either have to do busy-waiting
+                     (on the client, which would likely fail),
+                     or if we do nothing, we would just timeout
+                     on the connection (if a timeout is even set!).
+
+                     Solution: we kill the connection with an error */
+                  transmit_error_response (request,
+					   MHD_SC_APPLICATION_HUNG_CONNECTION_CLOSED,
+                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                           INTERNAL_ERROR);
+                  continue;
+                }
+            }
+          if ( (request->read_buffer_offset < request->read_buffer_size) &&
+	       (! connection->read_closed) )
+	    request->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+	  else
+	    request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+          break;
+        case MHD_REQUEST_BODY_RECEIVED:
+        case MHD_REQUEST_FOOTER_PART_RECEIVED:
+          /* while reading footers, we always grow the
+             read buffer if needed, no size-check required */
+          if (connection->read_closed)
+            {
+	      CONNECTION_CLOSE_ERROR (connection,
+				      MHD_SC_CONNECTION_READ_FAIL_CLOSED,
+				      NULL);
+              continue;
+            }
+	  request->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
+          /* transition to FOOTERS_RECEIVED
+             happens in read handler */
+          break;
+        case MHD_REQUEST_FOOTERS_RECEIVED:
+	  request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+          break;
+        case MHD_REQUEST_HEADERS_SENDING:
+          /* headers in buffer, keep writing */
+	  request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+          break;
+        case MHD_REQUEST_HEADERS_SENT:
+          mhd_assert (0);
+          break;
+        case MHD_REQUEST_NORMAL_BODY_READY:
+	  request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+          break;
+        case MHD_REQUEST_NORMAL_BODY_UNREADY:
+	  request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+          break;
+        case MHD_REQUEST_CHUNKED_BODY_READY:
+	  request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+          break;
+        case MHD_REQUEST_CHUNKED_BODY_UNREADY:
+	  request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
+          break;
+        case MHD_REQUEST_BODY_SENT:
+          mhd_assert (0);
+          break;
+        case MHD_REQUEST_FOOTERS_SENDING:
+	  request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
+          break;
+        case MHD_REQUEST_FOOTERS_SENT:
+          mhd_assert (0);
+          break;
+        case MHD_REQUEST_CLOSED:
+	  request->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
+          return;       /* do nothing, not even reading */
+        case MHD_REQUEST_IN_CLEANUP:
+          mhd_assert (0);
+          break;
+#ifdef UPGRADE_SUPPORT
+        case MHD_REQUEST_UPGRADE:
+          mhd_assert (0);
+          break;
+#endif /* UPGRADE_SUPPORT */
+        default:
+          mhd_assert (0);
+        }
+      break;
+    }
+}
+
+
 /**
  * This function was created to handle per-request processing that
  * has to happen even if the socket cannot be read or written to.
@@ -3386,7 +3549,7 @@ MHD_request_handle_idle_ (struct MHD_Request *request)
           return true;
         }
     }
-  MHD_connection_update_event_loop_info_ (connection);
+  connection_update_event_loop_info (connection);
   ret = true;
 #ifdef EPOLL_SUPPORT
   if ( (! connection->suspended) &&

+ 0 - 195
src/lib/connection_update_event_loop_info.c

@@ -1,195 +0,0 @@
-/*
-  This file is part of libmicrohttpd
-  Copyright (C) 2007-2018 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
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-/**
- * @file lib/connection_update_event_loop_info.c
- * @brief update the set of network events this connection is waiting for
- * @author Christian Grothoff
- */
-#include "internal.h"
-#include "connection_update_event_loop_info.h"
-
-
-/**
- * Update the 'event_loop_info' field of this connection based on the
- * state that the connection is now in.  May also close the connection
- * or perform other updates to the connection if needed to prepare for
- * the next round of the event loop.
- *
- * @param connection connection to get poll set for
- */
-void
-MHD_connection_update_event_loop_info_ (struct MHD_Connection *connection)
-{
-  /* Do not update states of suspended connection */
-  if (connection->suspended)
-    return; /* States will be updated after resume. */
-#ifdef HTTPS_SUPPORT
-  if (MHD_TLS_CONN_NO_TLS != connection->tls_state)
-    { /* HTTPS connection. */
-      switch (connection->tls_state)
-        {
-          case MHD_TLS_CONN_INIT:
-            connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
-            return;
-          case MHD_TLS_CONN_HANDSHAKING:
-            if (0 == gnutls_record_get_direction (connection->tls_session))
-              connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
-            else
-              connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
-            return;
-          default:
-            break;
-        }
-    }
-#endif /* HTTPS_SUPPORT */
-  while (1)
-    {
-#if DEBUG_STATES
-      MHD_DLOG (connection->daemon,
-                _("In function %s handling connection at state: %s\n"),
-                __FUNCTION__,
-                MHD_state_to_string (connection->state));
-#endif
-      switch (connection->state)
-        {
-        case MHD_CONNECTION_INIT:
-        case MHD_CONNECTION_URL_RECEIVED:
-        case MHD_CONNECTION_HEADER_PART_RECEIVED:
-          /* while reading headers, we always grow the
-             read buffer if needed, no size-check required */
-          if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
-	       (MHD_NO == try_grow_read_buffer (connection)) )
-            {
-              transmit_error_response (connection,
-                                       (connection->url != NULL)
-                                       ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
-                                       : MHD_HTTP_URI_TOO_LONG,
-                                       REQUEST_TOO_BIG);
-              continue;
-            }
-	  if (! connection->read_closed)
-	    connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
-	  else
-	    connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
-          break;
-        case MHD_CONNECTION_HEADERS_RECEIVED:
-          mhd_assert (0);
-          break;
-        case MHD_CONNECTION_HEADERS_PROCESSED:
-          mhd_assert (0);
-          break;
-        case MHD_CONNECTION_CONTINUE_SENDING:
-          connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
-          break;
-        case MHD_CONNECTION_CONTINUE_SENT:
-          if (connection->read_buffer_offset == connection->read_buffer_size)
-            {
-              if ((MHD_YES != try_grow_read_buffer (connection)) &&
-                  (0 != (connection->daemon->options &
-                         MHD_USE_INTERNAL_POLLING_THREAD)))
-                {
-                  /* failed to grow the read buffer, and the
-                     client which is supposed to handle the
-                     received data in a *blocking* fashion
-                     (in this mode) did not handle the data as
-                     it was supposed to!
-                     => we would either have to do busy-waiting
-                     (on the client, which would likely fail),
-                     or if we do nothing, we would just timeout
-                     on the connection (if a timeout is even
-                     set!).
-                     Solution: we kill the connection with an error */
-                  transmit_error_response (connection,
-                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                           INTERNAL_ERROR);
-                  continue;
-                }
-            }
-          if ( (connection->read_buffer_offset < connection->read_buffer_size) &&
-	       (! connection->read_closed) )
-	    connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
-	  else
-	    connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
-          break;
-        case MHD_CONNECTION_BODY_RECEIVED:
-        case MHD_CONNECTION_FOOTER_PART_RECEIVED:
-          /* while reading footers, we always grow the
-             read buffer if needed, no size-check required */
-          if (connection->read_closed)
-            {
-	      CONNECTION_CLOSE_ERROR (connection,
-				      NULL);
-              continue;
-            }
-	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
-          /* transition to FOOTERS_RECEIVED
-             happens in read handler */
-          break;
-        case MHD_CONNECTION_FOOTERS_RECEIVED:
-	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
-          break;
-        case MHD_CONNECTION_HEADERS_SENDING:
-          /* headers in buffer, keep writing */
-	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
-          break;
-        case MHD_CONNECTION_HEADERS_SENT:
-          mhd_assert (0);
-          break;
-        case MHD_CONNECTION_NORMAL_BODY_READY:
-	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
-          break;
-        case MHD_CONNECTION_NORMAL_BODY_UNREADY:
-	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
-          break;
-        case MHD_CONNECTION_CHUNKED_BODY_READY:
-	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
-          break;
-        case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
-	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
-          break;
-        case MHD_CONNECTION_BODY_SENT:
-          mhd_assert (0);
-          break;
-        case MHD_CONNECTION_FOOTERS_SENDING:
-	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
-          break;
-        case MHD_CONNECTION_FOOTERS_SENT:
-          mhd_assert (0);
-          break;
-        case MHD_CONNECTION_CLOSED:
-	  connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
-          return;       /* do nothing, not even reading */
-        case MHD_CONNECTION_IN_CLEANUP:
-          mhd_assert (0);
-          break;
-#ifdef UPGRADE_SUPPORT
-        case MHD_CONNECTION_UPGRADE:
-          mhd_assert (0);
-          break;
-#endif /* UPGRADE_SUPPORT */
-        default:
-          mhd_assert (0);
-        }
-      break;
-    }
-}
-
-
-/* end of connection_update_event_loop_info.c */
-

+ 0 - 42
src/lib/connection_update_event_loop_info.h

@@ -1,42 +0,0 @@
-/*
-  This file is part of libmicrohttpd
-  Copyright (C) 2007-2018 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
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-/**
- * @file lib/connection_update_event_loop_info.h
- * @brief function to update last activity of a connection
- * @author Christian Grothoff
- */
-
-#ifndef CONNECTION_UPDATE_EVENT_LOOP_INFO_H
-#define CONNECTION_UPDATE_EVENT_LOOP_INFO_H
-
-
-/**
- * Update the 'event_loop_info' field of this connection based on the
- * state that the connection is now in.  May also close the connection
- * or perform other updates to the connection if needed to prepare for
- * the next round of the event loop.
- *
- * @param connection connection to get poll set for
- */
-void
-MHD_connection_update_event_loop_info_ (struct MHD_Connection *connection)
-  MHD_NONNULL (1);
-
-
-#endif

+ 3 - 3
src/lib/daemon_epoll.c

@@ -477,7 +477,7 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon,
     }
 
   /* Finally, handle timed-out connections; we need to do this here
-     as the epoll mechanism won't call the 'MHD_connection_handle_idle()' on everything,
+     as the epoll mechanism won't call the 'MHD_request_handle_idle_()' on everything,
      as the other event loops do.  As timeouts do not get an explicit
      event, we need to find those connections that might have timed out
      here.
@@ -488,7 +488,7 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon,
   while (NULL != (pos = prev))
     {
       prev = pos->prevX;
-      MHD_connection_handle_idle (pos);
+      MHD_request_handle_idle_ (&pos->request);
     }
   /* Connections with the default timeout are sorted by prepending
      them to the head of the list whenever we touch the connection;
@@ -498,7 +498,7 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon,
   while (NULL != (pos = prev))
     {
       prev = pos->prevX;
-      MHD_connection_handle_idle (pos);
+      MHD_request_handle_idle_ (&pos->request);
       if (MHD_REQUEST_CLOSED != pos->request.state)
 	break; /* sorted by timeout, no need to visit the rest! */
     }

+ 0 - 27
src/lib/internal.h

@@ -362,33 +362,6 @@ struct MHD_HTTP_Header
 };
 
 
-/**
- * What is this request waiting for?
- */
-enum MHD_RequestEventLoopInfo
-{
-  /**
-   * We are waiting to be able to read.
-   */
-  MHD_EVENT_LOOP_INFO_READ = 0,
-
-  /**
-   * We are waiting to be able to write.
-   */
-  MHD_EVENT_LOOP_INFO_WRITE = 1,
-
-  /**
-   * We are waiting for the application to provide data.
-   */
-  MHD_EVENT_LOOP_INFO_BLOCK = 2,
-
-  /**
-   * We are finished and are awaiting cleanup.
-   */
-  MHD_EVENT_LOOP_INFO_CLEANUP = 3
-};
-
-
 /**
  * State kept for each HTTP request.
  */