ソースを参照

more lib/ work

Christian Grothoff 8 年 前
コミット
b7dd331e44

+ 27 - 19
src/include/microhttpd2.h

@@ -2608,7 +2608,14 @@ enum MHD_ConnectionInformationType
    * Get connection timeout
    * @ingroup request
    */
-  MHD_CONNECTION_INFORMATION_CONNECTION_TIMEOUT
+  MHD_CONNECTION_INFORMATION_CONNECTION_TIMEOUT,
+  
+  /**
+   * Check whether the connection is suspended.
+   * @ingroup request
+   */
+  MHD_CONNECTION_INFORMATION_CONNECTION_SUSPENDED
+
 
 };
 
@@ -2654,7 +2661,7 @@ union MHD_ConnectionInformation
   /**
    * Address information for the client.
    */
-  struct sockaddr *client_addr;
+  const struct sockaddr *client_addr;
 
   /**
    * Which daemon manages this connection (useful in case there are many
@@ -2663,10 +2670,16 @@ union MHD_ConnectionInformation
   struct MHD_Daemon *daemon;
 
   /**
-   * Socket-specific client context.  Points to the same address as
-   * the "socket_context" of the #MHD_NotifyConnectionCallback.
+   * Pointer to connection-specific client context.  Points to the
+   * same address as the "socket_context" of the
+   * #MHD_NotifyConnectionCallback.
+   */
+  void **socket_context;
+  
+  /**
+   * Is this connection right now suspended?
    */
-  void *socket_context;
+  enum MHD_Bool suspended;
 };
 
 
@@ -2721,15 +2734,10 @@ union MHD_RequestInformation
   struct MHD_Connection *connection;
 
   /**
-   * Socket-specific client context.  Will also be given to
+   * Pointer to client context.  Will also be given to
    * the application in a #MHD_RequestTerminationCallback.
    */
-  void *request_context;
-
-  /**
-   * The suspended status of a request.
-   */
-  enum MHD_Bool suspended;
+  void **request_context;
 
   /**
    * HTTP version requested by the client.
@@ -2762,11 +2770,11 @@ enum MHD_RequestInformationType
   MHD_REQUEST_INFORMATION_CONNECTION,
 
   /**
-   * Check whether the connection is suspended.
-   * @ingroup request
+   * Returns the client-specific pointer to a `void *` that
+   * is specific to this request.
    */
-  MHD_REQUEST_INFORMATION_SUSPENDED,
-
+  MHD_REQUEST_INFORMATION_CLIENT_CONTEXT,
+  
   /**
    * Return the HTTP version string given by the client.
    * @ingroup request
@@ -2837,7 +2845,7 @@ enum MHD_DaemonInformationType
    * Request the file descriptor for the listening socket.
    * No extra arguments should be passed.
    */
-  MHD_DAEMON_INFORMATION_LISTEN_FD,
+  MHD_DAEMON_INFORMATION_LISTEN_SOCKET,
 
   /**
    * Request the file descriptor for the external epoll.
@@ -2871,9 +2879,9 @@ union MHD_DaemonInformation
 {
 
   /**
-   * Socket, returned for #MHD_DAEMON_INFORMATION_LISTEN_FD.
+   * Socket, returned for #MHD_DAEMON_INFORMATION_LISTEN_SOCKET.
    */
-  MHD_socket listen_fd;
+  MHD_socket listen_socket;
 
   /**
    * Bind port number, returned for #MHD_DAEMON_INFORMATION_BIND_PORT.

+ 19 - 1
src/include/microhttpd_tls.h

@@ -13,6 +13,12 @@
 #define MHD_TLS_ABI_VERSION_STR "0"
 
 
+/**
+ * Data structure kept per TLS client by the plugin.
+ */
+struct MHD_TLS_ConnectionState;
+
+
 /**
  * Callback functions to use for TLS operations.
  */
@@ -70,7 +76,19 @@ struct MHD_TLS_Plugin
   enum MHD_StatusCode
   (*init_mem_trust)(void *cls,
 		    const char *mem_trust);
-  
+
+
+  /**
+   * Function called when we receive a connection and need
+   * to initialize our TLS state for it.
+   *
+   * @param cls the @e cls of this struct
+   * @param ... TBD
+   * @return NULL on error
+   */
+  struct MHD_TLS_ConnectionState *
+  (*setup_connection)(void *cls,
+		      ...);
   
   /**
    * TODO: More functions here....

+ 59 - 1
src/lib/connection_info.c

@@ -46,7 +46,65 @@ MHD_connection_get_information_sz (struct MHD_Connection *connection,
 				   union MHD_ConnectionInformation *return_value,
 				   size_t return_value_size)
 {
-  return MHD_NO; /* FIXME: not yet implemented */
+#define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \
+    return MHD_NO
+  
+  switch (info_type)
+  {
+#ifdef HTTPS_SUPPORT
+  case MHD_CONNECTION_INFORMATION_CIPHER_ALGO:
+    CHECK_SIZE (int);
+    if (NULL == connection->tls_cs)
+      return MHD_NO;
+    // return_value->cipher_algorithm
+    //  = gnutls_cipher_get (connection->tls_session);
+    return MHD_NO; // FIXME: to be implemented
+  case MHD_CONNECTION_INFORMATION_PROTOCOL:
+    CHECK_SIZE (int);
+    if (NULL == connection->tls_cs)
+      return MHD_NO;
+    //return_value->protocol
+    //  = gnutls_protocol_get_version (connection->tls_session);
+    return MHD_NO; // FIXME: to be implemented
+  case MHD_CONNECTION_INFORMATION_GNUTLS_SESSION:
+    CHECK_SIZE (void *);
+    if (NULL == connection->tls_cs)
+      return MHD_NO;
+    // return_value->tls_session = connection->tls_session;
+    return MHD_NO; // FIXME: to be implemented
+#endif /* HTTPS_SUPPORT */
+  case MHD_CONNECTION_INFORMATION_CLIENT_ADDRESS:
+    CHECK_SIZE (struct sockaddr *);
+    return_value->client_addr
+      = (const struct sockaddr *) &connection->addr;
+    return MHD_YES;
+  case MHD_CONNECTION_INFORMATION_DAEMON:
+    CHECK_SIZE (struct MHD_Daemon *);
+    return_value->daemon = connection->daemon;
+    return MHD_YES;
+  case MHD_CONNECTION_INFORMATION_CONNECTION_FD:
+    CHECK_SIZE (MHD_socket);
+    return_value->connect_fd = connection->socket_fd;
+    return MHD_YES;
+  case MHD_CONNECTION_INFORMATION_SOCKET_CONTEXT:
+    CHECK_SIZE (void **);
+    return_value->socket_context = &connection->socket_context;
+    return MHD_YES;
+  case MHD_CONNECTION_INFORMATION_CONNECTION_SUSPENDED:
+    CHECK_SIZE (enum MHD_Bool);
+    return_value->suspended
+      = connection->suspended ? MHD_YES : MHD_NO;
+    return MHD_YES;
+  case MHD_CONNECTION_INFORMATION_CONNECTION_TIMEOUT:
+    CHECK_SIZE (unsigned int);
+    return_value->connection_timeout
+      = (unsigned int) connection->connection_timeout;
+    return MHD_YES;
+  default:
+    return MHD_NO;
+  }
+  
+#undef CHECK_SIZE
 }
 
 /* end of connection_info.c */

+ 36 - 27
src/lib/daemon_info.c

@@ -46,50 +46,59 @@ MHD_daemon_get_information_sz (struct MHD_Daemon *daemon,
 			       union MHD_DaemonInformation *return_value,
 			       size_t return_value_size)
 {
-#if OLD
-  if (NULL == daemon)
-    return NULL;
+#define CHECK_SIZE(type) if (sizeof(type) < return_value_size)	\
+    return MHD_NO
+
   switch (info_type)
     {
-    case MHD_DAEMON_INFO_KEY_SIZE:
-      return NULL; /* no longer supported */
-    case MHD_DAEMON_INFO_MAC_KEY_SIZE:
-      return NULL; /* no longer supported */
-    case MHD_DAEMON_INFO_LISTEN_FD:
-      return (const union MHD_DaemonInfo *) &daemon->listen_fd;
+    case MHD_DAEMON_INFORMATION_LISTEN_SOCKET:
+      CHECK_SIZE (MHD_socket);
+      return_value->listen_socket
+	= daemon->listen_socket;
+      return MHD_YES;
 #ifdef EPOLL_SUPPORT
-    case MHD_DAEMON_INFO_EPOLL_FD:
-      return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
+    case MHD_DAEMON_INFORMATION_EPOLL_FD:
+      CHECK_SIZE (int);
+      // FIXME: maybe return MHD_NO if we are not using EPOLL?
+      return_value->epoll_fd = daemon->epoll_fd;
+      return MHD_YES;
 #endif
-    case MHD_DAEMON_INFO_CURRENT_CONNECTIONS:
-      if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
+    case MHD_DAEMON_INFORMATION_CURRENT_CONNECTIONS:
+      CHECK_SIZE (unsigned int);
+      if (MHD_TM_EXTERNAL_EVENT_LOOP == daemon->threading_model)
         {
-          /* Assume that MHD_run() in not called in other thread
-           * at the same time. */
+          /* Assumes that MHD_run() in not called in other thread
+	     (of the application) at the same time. */
           MHD_cleanup_connections (daemon);
+	  return_value->num_connections
+	    = daemon->connections;
         }
       else if (daemon->worker_pool)
         {
           unsigned int i;
           /* Collect the connection information stored in the workers. */
-          daemon->connections = 0;
-          for (i = 0; i < daemon->worker_pool_size; i++)
+	  return_value->num_connections = 0;
+	  for (i = 0; i < daemon->worker_pool_size; i++)
             {
               /* FIXME: next line is thread-safe only if read is atomic. */
-              daemon->connections += daemon->worker_pool[i].connections;
+              return_value->num_connections
+		+= daemon->worker_pool[i].connections;
             }
         }
-      return (const union MHD_DaemonInfo *) &daemon->connections;
-    case MHD_DAEMON_INFO_FLAGS:
-      return (const union MHD_DaemonInfo *) &daemon->options;
-    case MHD_DAEMON_INFO_BIND_PORT:
-      return (const union MHD_DaemonInfo *) &daemon->port;
+      else
+	return_value->num_connections
+	  = daemon->connections;
+      return MHD_YES;
+    case MHD_DAEMON_INFORMATION_BIND_PORT:
+      CHECK_SIZE (uint16_t);
+      // FIXME: return MHD_NO if port is not known/UNIX?
+      return_value->port = daemon->listen_port;
+      return MHD_YES;
     default:
-      return NULL;
+      return MHD_NO;
     }
-#else
-  return MHD_NO;
-#endif
+  
+#undef CHECK_SIZE
 }
 
 /* end of daemon_info.c */

+ 12 - 6
src/lib/daemon_options.c

@@ -126,7 +126,7 @@ MHD_daemon_disallow_suspend_resume (struct MHD_Daemon *daemon)
 void
 MHD_daemon_disallow_upgrade (struct MHD_Daemon *daemon)
 {
-  daemon->disallow_upgrade;
+  daemon->disallow_upgrade = true;
 }
 
 
@@ -165,6 +165,7 @@ MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon,
     return MHD_NO;
 #endif
   }
+  return MHD_NO;
 }
 
 
@@ -355,20 +356,20 @@ MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon,
   if (NULL ==
       (daemon->tls_backend_lib = dlopen (filename,
 					 RTLD_NOW | RTLD_LOCAL)))
-    return MHD_SC_BACKEND_UNSUPPORTED; /* plugin not found */
+    return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* plugin not found */
   if (NULL == (init = dlsym (daemon->tls_backend_lib,
 			     "MHD_TLS_init_" MHD_TLS_ABI_VERSION_STR)))
 
   {
     dlclose (daemon->tls_backend_lib);
     daemon->tls_backend_lib = NULL;
-    return MHD_SC_BACKEND_UNSUPPORTED; /* possibly wrong version installed */
+    return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* possibly wrong version installed */
   }
   if (NULL == (daemon->tls_api = init (ciphers)))
   {
     dlclose (daemon->tls_backend_lib);
     daemon->tls_backend_lib = NULL;
-    return MHD_SC_CIPHERS_INVALID; /* possibly wrong version installed */
+    return MHD_SC_TLS_CIPHERS_INVALID; /* possibly wrong version installed */
   }
   return MHD_SC_OK;
 #endif
@@ -545,8 +546,8 @@ MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon,
 				 MHD_EarlyUriLogCallback cb,
 				 void *cb_cls)
 {
-  daemon->early_uri_logger = cb;
-  daemon->early_uri_logger_cls = cb_cls;
+  daemon->early_uri_logger_cb = cb;
+  daemon->early_uri_logger_cb_cls = cb_cls;
 }
 
 
@@ -687,6 +688,9 @@ MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon,
   daemon->digest_auth_random_buf = buf;
   daemon->digest_auth_random_buf_size = buf_size;
 #else
+  (void) daemon;
+  (void) buf_size;
+  (void) buf;
   MHD_PANIC ("digest authentication not supported by this build");
 #endif
 }
@@ -732,6 +736,8 @@ MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon,
   daemon->digest_nc_length = nc_length;
   return MHD_SC_OK;
 #else
+  (void) daemon;
+  (void) nc_length;
   return MHD_SC_DIGEST_AUTH_NOT_SUPPORTED_BY_BUILD;
 #endif
 }

+ 1 - 1
src/lib/internal.c

@@ -238,7 +238,7 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
 	  break;
 	}
       /* amper is non-NULL here */
-      amper[0] = '\0';d
+      amper[0] = '\0';
       amper++;
       if ( (NULL == equals) ||
 	   (equals >= amper) )

+ 44 - 8
src/lib/internal.h

@@ -454,7 +454,7 @@ struct MHD_Request
    * HTTP version string (i.e. http/1.1).  Allocated
    * in pool.
    */
-  char *version;
+  char *version_s;
 
   /**
    * Close connection after sending response?
@@ -493,7 +493,6 @@ struct MHD_Request
    */
   char *colon;
 
-
   /**
    * Function used for reading HTTP request stream.
    */
@@ -514,11 +513,6 @@ struct MHD_Request
   struct MHD_UpgradeResponseHandle *urh;
 #endif /* UPGRADE_SUPPORT */
 
-  /**
-   * Foreign address (of length @e addr_len).
-   */
-  struct sockaddr_storage addr;
-
   /**
    * Thread handle for this connection (if we are using
    * one thread per connection).
@@ -741,13 +735,34 @@ struct MHD_Connection
    * Reference to the MHD_Daemon struct.
    */
   struct MHD_Daemon *daemon;
+  
+  /**
+   * We allow the main application to associate some pointer with the
+   * TCP connection (which may span multiple HTTP requests).  Here is
+   * where we store it.  (MHD does not know or care what it is).
+   * The location is given to the #MHD_NotifyConnectionCallback and
+   * also accessible via #MHD_CONNECTION_INFO_SOCKET_CONTEXT.
+   */
+  void *socket_context;
 
+#ifdef HTTPS_SUPPORT
+  /**
+   * State kept per TLS connection. Plugin-specific.
+   */
+  struct MHD_TLS_ConnectionState *tls_cs;
+#endif
+  
   /**
    * Information about the current request we are processing
    * on this connection.
    */
   struct MHD_Request request;
 
+  /**
+   * Foreign address (of length @e addr_len). 
+   */
+  struct sockaddr_storage addr;
+
   /**
    * Length of the foreign address.
    */
@@ -858,7 +873,7 @@ struct MHD_Daemon
   /**
    * Closure for @e early_uri_logger_cb.
    */
-  void *early_uri_logger_cls;
+  void *early_uri_logger_cb_cls;
 
   /**
    * Function to call whenever a connection is started or
@@ -881,6 +896,17 @@ struct MHD_Daemon
    * Closure for @e unescape_cb.
    */
   void *unescape_cb_cls;
+
+  /**
+   * Pointer to master daemon (NULL if this is the master)
+   */
+  struct MHD_Daemon *master;
+
+  /**
+   * Worker daemons (one per thread)
+   */
+  struct MHD_Daemon *worker_pool;
+
   
 #if HTTPS_SUPPORT
   /**
@@ -1134,6 +1160,16 @@ struct MHD_Daemon
    */
   unsigned int ip_connection_limit;
 
+  /**
+   * Number of active parallel connections.
+   */
+  unsigned int connections;
+
+  /**
+   * Number of worker daemons
+   */
+  unsigned int worker_pool_size;
+
   /**
    * Default timeout in seconds for idle connections.
    */

+ 35 - 1
src/lib/request_info.c

@@ -46,7 +46,41 @@ MHD_request_get_information_sz (struct MHD_Request *request,
 			        union MHD_RequestInformation *return_value,
 			        size_t return_value_size)
 {
-  return MHD_NO; /* not implemented */
+#define CHECK_SIZE(type) if (sizeof(type) < return_value_size)	\
+    return MHD_NO
+  
+  switch (info_type)
+  {
+  case MHD_REQUEST_INFORMATION_CONNECTION:
+    CHECK_SIZE (struct MHD_Connection *);
+    return_value->connection = request->connection;
+    return MHD_YES;
+  case MHD_REQUEST_INFORMATION_CLIENT_CONTEXT:
+    CHECK_SIZE (void **);
+    return_value->request_context = &request->client_context;
+    return MHD_YES;
+  case MHD_REQUEST_INFORMATION_HTTP_VERSION:
+    CHECK_SIZE (const char *);
+    return_value->http_version = request->version_s;
+    return MHD_YES;
+  case MHD_REQUEST_INFORMATION_HTTP_METHOD:
+    CHECK_SIZE (const char *);
+    return_value->http_method = request->method_s;
+    return MHD_YES;
+  case MHD_REQUEST_INFORMATION_HEADER_SIZE:
+    CHECK_SIZE (size_t);
+    if ( (MHD_REQUEST_HEADERS_RECEIVED > request->state) ||
+	 (MHD_REQUEST_CLOSED == request->state) ||
+           (MHD_REQUEST_IN_CLEANUP == request->state) )
+        return MHD_NO; /* invalid, too early! */
+    return_value->header_size = request->header_size;
+    return MHD_YES;
+
+  default:
+    return MHD_NO;
+  }
+  
+#undef CHECK_SIZE
 }