gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r12339 - in libmicrohttpd: . doc src/daemon src/include


From: gnunet
Subject: [GNUnet-SVN] r12339 - in libmicrohttpd: . doc src/daemon src/include
Date: Sun, 25 Jul 2010 15:17:10 +0200

Author: grothoff
Date: 2010-07-25 15:17:10 +0200 (Sun, 25 Jul 2010)
New Revision: 12339

Modified:
   libmicrohttpd/ChangeLog
   libmicrohttpd/README
   libmicrohttpd/doc/microhttpd.texi
   libmicrohttpd/src/daemon/connection.c
   libmicrohttpd/src/daemon/daemon.c
   libmicrohttpd/src/daemon/internal.h
   libmicrohttpd/src/daemon/response.c
   libmicrohttpd/src/include/microhttpd.h
Log:
systemd and sendfile support

Modified: libmicrohttpd/ChangeLog
===================================================================
--- libmicrohttpd/ChangeLog     2010-07-25 10:30:29 UTC (rev 12338)
+++ libmicrohttpd/ChangeLog     2010-07-25 13:17:10 UTC (rev 12339)
@@ -1,3 +1,8 @@
+Sun Jul 25 14:57:47 CEST 2010
+       Adding support for sendfile on Linux.  Adding support
+       for systemd-style passing of an existing listen socket
+       as an option. -CG
+
 Sun Jul 25 11:10:45 CEST 2010
        Changed code to use external libgnutls code instead of
        the "fork".  Minor API changes for setting TLS options. -CG

Modified: libmicrohttpd/README
===================================================================
--- libmicrohttpd/README        2010-07-25 10:30:29 UTC (rev 12338)
+++ libmicrohttpd/README        2010-07-25 13:17:10 UTC (rev 12339)
@@ -95,6 +95,7 @@
 - MHD_del_response_header 
 - MHD_get_response_headers
 - MHD_tls_connection_close
+- MHD_create_response_from_fd & sendfile support (!)
 
 
 Missing documentation:

Modified: libmicrohttpd/doc/microhttpd.texi
===================================================================
--- libmicrohttpd/doc/microhttpd.texi   2010-07-25 10:30:29 UTC (rev 12338)
+++ libmicrohttpd/doc/microhttpd.texi   2010-07-25 13:17:10 UTC (rev 12339)
@@ -342,23 +342,32 @@
 be the 0-terminated URI of the request.
 
 @item MHD_OPTION_HTTPS_MEM_KEY
address@hidden SSL
address@hidden TLS
 Memory pointer to the private key to be used by the
 HTTPS daemon.  This option should be followed by an
 "const char*" argument.
 This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_CERT'.
    
 @item MHD_OPTION_HTTPS_MEM_CERT
address@hidden SSL
address@hidden TLS
 Memory pointer to the certificate to be used by the
 HTTPS daemon.  This option should be followed by an
 "const char*" argument.
 This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_KEY'.
    
 @item MHD_OPTION_CRED_TYPE
address@hidden SSL
address@hidden TLS
 Daemon credentials type.  Either certificate or anonymous,
 this option should be followed by one of the values listed in
 "enum MHD_GNUTLS_CredentialsType".
    
 @item MHD_OPTION_HTTPS_PRIORITIES
address@hidden SSL
address@hidden TLS
address@hidden cipher
 SSL/TLS protocol version and ciphers.
 This option must be followwed by an "const char *" argument
 specifying the SSL/TLS protocol versions and ciphers that
@@ -366,6 +375,13 @@
 unchanged to gnutls_priority_init.  If this option is not
 specified, ``NORMAL'' is used.
   
address@hidden MHD_OPTION_LISTEN_SOCKET
address@hidden systemd
+Listen socket to use.  Pass a listen socket for MHD to use
+(systemd-style).  If this option is used, MHD will not open its own
+listen socket(s). The argument passed must be of type "int" and refer
+to an existing socket that has been bound to a port and is listening.
+  
 @item MHD_OPTION_EXTERNAL_LOGGER
 @cindex logging
 Use the given function for logging error messages.
@@ -381,6 +397,7 @@
 even if this argument is used.
 
 @item MHD_OPTION_THREAD_POOL_SIZE
address@hidden performance
 Number (unsigned int) of threads in thread pool. Enable
 thread pooling by setting this value to to something
 greater than 1. Currently, thread model must be
@@ -1134,6 +1151,24 @@
 @end deftypefun
 
 
+
address@hidden {struct MHD_Response *} MHD_create_response_from_fd (uint64_t 
size, int fd)
+Create a response object.  The response object can be extended with
+header information and then it can be used any number of times.
+
address@hidden @var
address@hidden size
+size of the data portion of the response, @code{-1} for unknown;
+
address@hidden fd
+file descriptor referring to a file on disk with the data; will be
+closed when response is destroyed
address@hidden table
+
+Return @mynull{} on error (i.e. invalid arguments, out of memory).
address@hidden deftypefun
+
+
 @deftypefun {struct MHD_Response *} MHD_create_response_from_data (size_t 
size, void *data, int must_free, int must_copy)
 Create a response object.  The response object can be extended with
 header information and then it can be used any number of times.

Modified: libmicrohttpd/src/daemon/connection.c
===================================================================
--- libmicrohttpd/src/daemon/connection.c       2010-07-25 10:30:29 UTC (rev 
12338)
+++ libmicrohttpd/src/daemon/connection.c       2010-07-25 13:17:10 UTC (rev 
12339)
@@ -333,6 +333,11 @@
        (response->data_size + response->data_start >
        connection->response_write_position) )
     return MHD_YES; /* response already ready */
+#if LINUX
+  if ( (response->fd != -1) &&
+       (0 == (connection->daemon->options & MHD_USE_SSL)) )
+    return MHD_YES; /* will use sendfile */
+#endif
   ret = response->crc (response->crc_cls,
                        connection->response_write_position,
                        response->data,
@@ -1795,29 +1800,13 @@
               connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY;
               break;
             }
-#if HTTPS_SUPPORT
-          if (connection->daemon->options & MHD_USE_SSL)
-            {
-              ret = gnutls_record_send (connection->tls_session,
-                                             &connection->response->data
-                                             [connection->
-                                              response_write_position -
-                                              response->data_start],
-                                             response->data_size -
-                                             
(connection->response_write_position
-                                              - response->data_start));
-            }
-          else
-#endif
-            {
-              ret = connection->send_cls (connection,
-                                          &response->data
-                                          [connection->response_write_position
-                                           - response->data_start],
-                                          response->data_size -
-                                          (connection->response_write_position
-                                           - response->data_start));
-            }
+         ret = connection->send_cls (connection,
+                                     &response->data
+                                     [connection->response_write_position
+                                      - response->data_start],
+                                     response->data_size -
+                                     (connection->response_write_position
+                                      - response->data_start));
 #if DEBUG_SEND_DATA
           if (ret > 0)
             FPRINTF (stderr,

Modified: libmicrohttpd/src/daemon/daemon.c
===================================================================
--- libmicrohttpd/src/daemon/daemon.c   2010-07-25 10:30:29 UTC (rev 12338)
+++ libmicrohttpd/src/daemon/daemon.c   2010-07-25 13:17:10 UTC (rev 12339)
@@ -40,6 +40,10 @@
 #include <poll.h>
 #endif
 
+#ifdef LINUX
+#include <sys/sendfile.h>
+#endif
+
 /**
  * Default connection limit.
  */
@@ -603,8 +607,7 @@
     return -1;
   if (0 != (connection->daemon->options & MHD_USE_SSL))
     return RECV (connection->socket_fd, other, i, MSG_NOSIGNAL);
-  else
-    return RECV (connection->socket_fd, other, i, MSG_NOSIGNAL | MSG_DONTWAIT);
+  return RECV (connection->socket_fd, other, i, MSG_NOSIGNAL | MSG_DONTWAIT);
 }
 
 /**
@@ -619,12 +622,27 @@
 send_param_adapter (struct MHD_Connection *connection,
                     const void *other, size_t i)
 {
+#if LINUX
+  int fd;
+  off_t offset;
+#endif
   if (connection->socket_fd == -1)
     return -1;
   if (0 != (connection->daemon->options & MHD_USE_SSL))
     return SEND (connection->socket_fd, other, i, MSG_NOSIGNAL);
-  else
-    return SEND (connection->socket_fd, other, i, MSG_NOSIGNAL | MSG_DONTWAIT);
+#if LINUX
+  if ( (NULL != connection->response) &&
+       (-1 != (fd = connection->response->fd)) )
+    {
+      /* can use sendfile */
+      offset = (off_t) connection->response_write_position;
+      return sendfile (connection->socket_fd, 
+                      fd,
+                      &offset,
+                      i);
+    }
+#endif
+  return SEND (connection->socket_fd, other, i, MSG_NOSIGNAL | MSG_DONTWAIT);
 }
 
 
@@ -1310,7 +1328,7 @@
                     opt);        
 #endif
           break;
-       case MHD_OPTION_CRED_TYPE:
+       case MHD_OPTION_HTTPS_CRED_TYPE:
          daemon->cred_type = va_arg (ap, gnutls_credentials_type_t);
          break;
         case MHD_OPTION_HTTPS_PRIORITIES:
@@ -1328,6 +1346,9 @@
            return MHD_NO;
           break;
 #endif
+       case MHD_OPTION_LISTEN_SOCKET:
+         daemon->socket_fd = va_arg (ap, int);   
+         break;
         case MHD_OPTION_EXTERNAL_LOGGER:
 #if HAVE_MESSAGES
           daemon->custom_error_log =
@@ -1367,7 +1388,8 @@
                    return MHD_NO;
                  break;
                  /* all options taking 'int' or 'enum' */
-               case MHD_OPTION_CRED_TYPE:
+               case MHD_OPTION_HTTPS_CRED_TYPE:
+               case MHD_OPTION_LISTEN_SOCKET:
                  if (MHD_YES != parse_options (daemon,
                                                servaddr,
                                                opt,
@@ -1471,6 +1493,7 @@
                        "NORMAL",
                        NULL);
 #endif
+  retVal->socket_fd = -1;
   retVal->options = (enum MHD_OPTION)options;
   retVal->port = port;
   retVal->apc = apc;
@@ -1547,105 +1570,117 @@
       return NULL;
     }
 #endif
-  if ((options & MHD_USE_IPv6) != 0)
+  if (retVal->socket_fd == -1)
+    {
+      if ((options & MHD_USE_IPv6) != 0)
 #if HAVE_INET6
-    socket_fd = SOCKET (PF_INET6, SOCK_STREAM, 0);
+       socket_fd = SOCKET (PF_INET6, SOCK_STREAM, 0);
 #else
-    {
+      {
 #if HAVE_MESSAGES
-      fprintf (stderr, "AF_INET6 not supported\n");
+       fprintf (stderr, "AF_INET6 not supported\n");
 #endif
-      free (retVal);
-      return NULL;
-    }
+       free (retVal);
+       return NULL;
+      }
 #endif
-  else
-    socket_fd = SOCKET (PF_INET, SOCK_STREAM, 0);
-  if (socket_fd == -1)
-    {
+      else
+       socket_fd = SOCKET (PF_INET, SOCK_STREAM, 0);
+      if (socket_fd == -1)
+       {
 #if HAVE_MESSAGES
-      if ((options & MHD_USE_DEBUG) != 0)
-        FPRINTF (stderr, "Call to socket failed: %s\n", STRERROR (errno));
+         if ((options & MHD_USE_DEBUG) != 0)
+           FPRINTF (stderr, "Call to socket failed: %s\n", STRERROR (errno));
 #endif
-      free (retVal);
-      return NULL;
-    }
-#ifndef WINDOWS
-  if ( (socket_fd >= FD_SETSIZE) &&
-       (0 == (options & MHD_USE_POLL)) )
-    {
+         free (retVal);
+         return NULL;
+       }
+      if ((SETSOCKOPT (socket_fd,
+                      SOL_SOCKET,
+                      SO_REUSEADDR,
+                      &on, sizeof (on)) < 0) && ((options & MHD_USE_DEBUG) != 
0))
+       {
 #if HAVE_MESSAGES
-      if ((options & MHD_USE_DEBUG) != 0)
-        FPRINTF (stderr,
-                 "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
-                 socket_fd,
-                 FD_SETSIZE);
+         FPRINTF (stderr, "setsockopt failed: %s\n", STRERROR (errno));
 #endif
-      CLOSE (socket_fd);
-      free (retVal);
-      return NULL;
-    }
+       }
+      
+      /* check for user supplied sockaddr */
+#if HAVE_INET6
+      if ((options & MHD_USE_IPv6) != 0)
+       addrlen = sizeof (struct sockaddr_in6);
+      else
 #endif
-  if ((SETSOCKOPT (socket_fd,
-                   SOL_SOCKET,
-                   SO_REUSEADDR,
-                   &on, sizeof (on)) < 0) && ((options & MHD_USE_DEBUG) != 0))
-    {
-#if HAVE_MESSAGES
-      FPRINTF (stderr, "setsockopt failed: %s\n", STRERROR (errno));
+       addrlen = sizeof (struct sockaddr_in);
+      if (NULL == servaddr)
+       {
+#if HAVE_INET6
+         if ((options & MHD_USE_IPv6) != 0)
+           {
+             memset (&servaddr6, 0, sizeof (struct sockaddr_in6));
+             servaddr6.sin6_family = AF_INET6;
+             servaddr6.sin6_port = htons (port);
+             servaddr = (struct sockaddr *) &servaddr6;
+           }
+         else
 #endif
-    }
+           {
+             memset (&servaddr4, 0, sizeof (struct sockaddr_in));
+             servaddr4.sin_family = AF_INET;
+             servaddr4.sin_port = htons (port);
+             servaddr = (struct sockaddr *) &servaddr4;
+           }
+       }
+      retVal->socket_fd = socket_fd;
 
-  /* check for user supplied sockaddr */
-#if HAVE_INET6
-  if ((options & MHD_USE_IPv6) != 0)
-    addrlen = sizeof (struct sockaddr_in6);
-  else
-#endif
-    addrlen = sizeof (struct sockaddr_in);
-  if (NULL == servaddr)
-    {
-#if HAVE_INET6
       if ((options & MHD_USE_IPv6) != 0)
-        {
-          memset (&servaddr6, 0, sizeof (struct sockaddr_in6));
-          servaddr6.sin6_family = AF_INET6;
-          servaddr6.sin6_port = htons (port);
-          servaddr = (struct sockaddr *) &servaddr6;
-        }
-      else
+       {
+         const int on = 1;
+         setsockopt (socket_fd, 
+                     IPPROTO_IPV6, IPV6_V6ONLY, 
+                     &on, sizeof (on));      
+       }
+      if (BIND (socket_fd, servaddr, addrlen) == -1)
+       {
+#if HAVE_MESSAGES
+         if ((options & MHD_USE_DEBUG) != 0)
+           FPRINTF (stderr,
+                    "Failed to bind to port %u: %s\n", port, STRERROR (errno));
 #endif
-        {
-          memset (&servaddr4, 0, sizeof (struct sockaddr_in));
-          servaddr4.sin_family = AF_INET;
-          servaddr4.sin_port = htons (port);
-          servaddr = (struct sockaddr *) &servaddr4;
-        }
-    }
-  retVal->socket_fd = socket_fd;
-  if (BIND (socket_fd, servaddr, addrlen) == -1)
-    {
+         CLOSE (socket_fd);
+         free (retVal);
+         return NULL;
+       }
+      
+      if (LISTEN (socket_fd, 20) < 0)
+       {
 #if HAVE_MESSAGES
-      if ((options & MHD_USE_DEBUG) != 0)
-        FPRINTF (stderr,
-                 "Failed to bind to port %u: %s\n", port, STRERROR (errno));
+         if ((options & MHD_USE_DEBUG) != 0)
+           FPRINTF (stderr,
+                    "Failed to listen for connections: %s\n", STRERROR 
(errno));
 #endif
-      CLOSE (socket_fd);
-      free (retVal);
-      return NULL;
+         CLOSE (socket_fd);
+         free (retVal);
+         return NULL;
+       }      
     }
 
-  if (LISTEN (socket_fd, 20) < 0)
+#ifndef WINDOWS
+  if ( (socket_fd >= FD_SETSIZE) &&
+       (0 == (options & MHD_USE_POLL)) )
     {
 #if HAVE_MESSAGES
       if ((options & MHD_USE_DEBUG) != 0)
         FPRINTF (stderr,
-                 "Failed to listen for connections: %s\n", STRERROR (errno));
+                 "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
+                 socket_fd,
+                 FD_SETSIZE);
 #endif
       CLOSE (socket_fd);
       free (retVal);
       return NULL;
     }
+#endif
 
   if (0 != pthread_mutex_init (&retVal->per_ip_connection_mutex, NULL))
     {

Modified: libmicrohttpd/src/daemon/internal.h
===================================================================
--- libmicrohttpd/src/daemon/internal.h 2010-07-25 10:30:29 UTC (rev 12338)
+++ libmicrohttpd/src/daemon/internal.h 2010-07-25 13:17:10 UTC (rev 12339)
@@ -186,15 +186,15 @@
   pthread_mutex_t mutex;
 
   /**
-   * Reference count for this response.  Free
-   * once the counter hits zero.
+   * Set to MHD_SIZE_UNKNOWN if size is not known.
    */
-  unsigned int reference_count;
+  uint64_t total_size;
 
   /**
-   * Set to MHD_SIZE_UNKNOWN if size is not known.
+   * At what offset in the stream is the
+   * beginning of data located?
    */
-  uint64_t total_size;
+  uint64_t data_start;
 
   /**
    * Size of data.
@@ -207,11 +207,16 @@
   size_t data_buffer_size;
 
   /**
-   * At what offset in the stream is the
-   * beginning of data located?
+   * Reference count for this response.  Free
+   * once the counter hits zero.
    */
-  uint64_t data_start;
+  unsigned int reference_count;
 
+  /**
+   * File-descriptor if this response is FD-backed.
+   */
+  int fd;
+
 };
 
 /**

Modified: libmicrohttpd/src/daemon/response.c
===================================================================
--- libmicrohttpd/src/daemon/response.c 2010-07-25 10:30:29 UTC (rev 12338)
+++ libmicrohttpd/src/daemon/response.c 2010-07-25 13:17:10 UTC (rev 12339)
@@ -189,6 +189,7 @@
   if (retVal == NULL)
     return NULL;
   memset (retVal, 0, sizeof (struct MHD_Response));
+  retVal->fd = -1;
   retVal->data = (void *) &retVal[1];
   retVal->data_buffer_size = block_size;
   if (pthread_mutex_init (&retVal->mutex, NULL) != 0)
@@ -204,11 +205,73 @@
   return retVal;
 }
 
+
 /**
+ * Given a file descriptor, read data from the file
+ * to generate the response.
+ * 
+ * @param cls pointer to the file descriptor
+ * @param pos offset in the file to access
+ * @param buf where to write the data
+ * @param max number of bytes to write at most
+ * @return number of bytes written
+ */
+static int
+file_reader (void *cls, uint64_t pos, char *buf, int max)
+{
+  int *fd = cls;
+
+  (void) lseek (*fd, pos, SEEK_SET);
+  return read (*fd, buf, max);
+}
+
+
+/**
+ * Destroy file reader context.  Closes the file
+ * descriptor.
+ *
+ * @param cls pointer to file descriptor
+ */
+static void
+free_callback (void *cls)
+{
+  int *fd = cls;
+  close (*fd);
+  *fd = -1;
+}
+
+
+/**
  * Create a response object.  The response object can be extended with
  * header information and then be used any number of times.
  *
  * @param size size of the data portion of the response
+ * @param fd file descriptor referring to a file on disk with the data
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ */
+struct MHD_Response *MHD_create_response_from_fd (size_t size,
+                                                 int fd)
+{
+  struct MHD_Response *ret;
+
+  ret = MHD_create_response_from_callback (size,
+                                          4 * 1024,
+                                          &file_reader,
+                                          NULL,
+                                          &free_callback);
+  if (ret == NULL)
+    return NULL;
+  ret->fd = fd;
+  ret->crc_cls = &ret->fd;
+  return ret;
+}
+
+
+/**
+ * Create a response object.  The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @param size size of the data portion of the response
  * @param data the data itself
  * @param must_free libmicrohttpd should free data when done
  * @param must_copy libmicrohttpd must make a copy of data
@@ -229,6 +292,7 @@
   if (retVal == NULL)
     return NULL;
   memset (retVal, 0, sizeof (struct MHD_Response));
+  retVal->fd = -1;
   if (pthread_mutex_init (&retVal->mutex, NULL) != 0)
     {
       free (retVal);

Modified: libmicrohttpd/src/include/microhttpd.h
===================================================================
--- libmicrohttpd/src/include/microhttpd.h      2010-07-25 10:30:29 UTC (rev 
12338)
+++ libmicrohttpd/src/include/microhttpd.h      2010-07-25 13:17:10 UTC (rev 
12339)
@@ -415,15 +415,23 @@
    * Followed by an argument of type
    * "gnutls_credentials_type_t".
    */
-  MHD_OPTION_CRED_TYPE = 10,
+  MHD_OPTION_HTTPS_CRED_TYPE = 10,
 
   /**
    * Memory pointer to a "const char*" specifying the
    * cipher algorithm (default: "NORMAL").
    */
-  MHD_OPTION_HTTPS_PRIORITIES = 12,
+  MHD_OPTION_HTTPS_PRIORITIES = 11,
 
   /**
+   * Pass a listen socket for MHD to use (systemd-style).  If this
+   * option is used, MHD will not open its own listen socket(s). The
+   * argument passed must be of type "int" and refer to an
+   * existing socket that has been bound to a port and is listening.
+   */
+  MHD_OPTION_LISTEN_SOCKET = 12,
+
+  /**
    * Use the given function for logging error messages.
    * This option must be followed by two arguments; the
    * first must be a pointer to a function
@@ -1074,7 +1082,19 @@
                                                     int must_free,
                                                     int must_copy);
 
+
 /**
+ * Create a response object.  The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @param size size of the data portion of the response
+ * @param fd file descriptor referring to a file on disk with the data; will 
be closed when response is destroyed
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ */
+struct MHD_Response *MHD_create_response_from_fd (size_t size,
+                                                 int fd);
+
+/**
  * Destroy a response object and associated resources.  Note that
  * libmicrohttpd may keep some of the resources around if the response
  * is still in the queue for some clients, so the memory may not




reply via email to

[Prev in Thread] Current Thread [Next in Thread]