[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r12339 - in libmicrohttpd: . doc src/daemon src/include,
gnunet <=