commit b926a975e6633e9d4d1c2ec21f459e55a5ceb5de
parent 8c8f43fa9526f29e568305d51980466eda79c6a0
Author: Christian Grothoff <christian@grothoff.org>
Date: Thu, 15 Feb 2018 02:52:09 +0100
get src/lib/ to build -- with plenty of warnings
Diffstat:
12 files changed, 912 insertions(+), 211 deletions(-)
diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h
@@ -520,7 +520,28 @@ enum MHD_StatusCode
*/
MHD_SC_THREAD_POOL_LAUNCH_FAILURE = 50031,
+ /**
+ * We failed to add a socket to the epoll() set.
+ */
+ MHD_SC_EPOLL_CTL_ADD_FAILED = 50032,
+
+ /**
+ * We failed to start a thread.
+ */
+ MHD_SC_THREAD_LAUNCH_FAILURE = 50033,
+ /**
+ * We failed to create control socket for the epoll().
+ */
+ MHD_SC_EPOLL_CTL_CREATE_FAILED = 50034,
+
+ /**
+ * We failed to configure control socket for the epoll()
+ * to be non-inheritable.
+ */
+ MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED = 50035,
+
+
};
@@ -542,6 +563,12 @@ struct MHD_Action;
* add additional methods (as per IANA registry), thus even if the API
* returns "unknown" today, it may return a method-specific header in
* the future!
+ *
+ * @defgroup methods HTTP methods
+ * HTTP methods (as strings).
+ * See: http://www.iana.org/assignments/http-methods/http-methods.xml
+ * Registry Version 2015-05-19
+ * @{
*/
enum MHD_Method
{
@@ -553,31 +580,37 @@ enum MHD_Method
/**
* "OPTIONS" method.
+ * Safe. Idempotent. RFC7231, Section 4.3.7.
*/
MHD_METHOD_OPTIONS = 1,
/**
* "GET" method.
+ * Safe. Idempotent. RFC7231, Section 4.3.1.
*/
MHD_METHOD_GET = 2,
/**
* "HEAD" method.
+ * Safe. Idempotent. RFC7231, Section 4.3.2.
*/
MHD_METHOD_HEAD = 3,
/**
* "POST" method.
+ * Not safe. Not idempotent. RFC7231, Section 4.3.3.
*/
MHD_METHOD_POST = 4,
/**
* "PUT" method.
+ * Not safe. Idempotent. RFC7231, Section 4.3.4.
*/
MHD_METHOD_PUT = 5,
/**
* "DELETE" method.
+ * Not safe. Idempotent. RFC7231, Section 4.3.5.
*/
MHD_METHOD_DELETE = 6,
@@ -746,6 +779,339 @@ enum MHD_Method
};
+/** @} */ /* end of group methods */
+
+
+/**
+ * @defgroup postenc HTTP POST encodings
+ * See also: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4
+ * @{
+ */
+#define MHD_HTTP_POST_ENCODING_FORM_URLENCODED "application/x-www-form-urlencoded"
+#define MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA "multipart/form-data"
+
+/** @} */ /* end of group postenc */
+
+
+
+/**
+ * @defgroup headers HTTP headers
+ * These are the standard headers found in HTTP requests and responses.
+ * See: http://www.iana.org/assignments/message-headers/message-headers.xml
+ * Registry Version 2017-01-27
+ * @{
+ */
+
+/* Main HTTP headers. */
+/* Standard. RFC7231, Section 5.3.2 */
+#define MHD_HTTP_HEADER_ACCEPT "Accept"
+/* Standard. RFC7231, Section 5.3.3 */
+#define MHD_HTTP_HEADER_ACCEPT_CHARSET "Accept-Charset"
+/* Standard. RFC7231, Section 5.3.4; RFC7694, Section 3 */
+#define MHD_HTTP_HEADER_ACCEPT_ENCODING "Accept-Encoding"
+/* Standard. RFC7231, Section 5.3.5 */
+#define MHD_HTTP_HEADER_ACCEPT_LANGUAGE "Accept-Language"
+/* Standard. RFC7233, Section 2.3 */
+#define MHD_HTTP_HEADER_ACCEPT_RANGES "Accept-Ranges"
+/* Standard. RFC7234, Section 5.1 */
+#define MHD_HTTP_HEADER_AGE "Age"
+/* Standard. RFC7231, Section 7.4.1 */
+#define MHD_HTTP_HEADER_ALLOW "Allow"
+/* Standard. RFC7235, Section 4.2 */
+#define MHD_HTTP_HEADER_AUTHORIZATION "Authorization"
+/* Standard. RFC7234, Section 5.2 */
+#define MHD_HTTP_HEADER_CACHE_CONTROL "Cache-Control"
+/* Reserved. RFC7230, Section 8.1 */
+#define MHD_HTTP_HEADER_CLOSE "Close"
+/* Standard. RFC7230, Section 6.1 */
+#define MHD_HTTP_HEADER_CONNECTION "Connection"
+/* Standard. RFC7231, Section 3.1.2.2 */
+#define MHD_HTTP_HEADER_CONTENT_ENCODING "Content-Encoding"
+/* Standard. RFC7231, Section 3.1.3.2 */
+#define MHD_HTTP_HEADER_CONTENT_LANGUAGE "Content-Language"
+/* Standard. RFC7230, Section 3.3.2 */
+#define MHD_HTTP_HEADER_CONTENT_LENGTH "Content-Length"
+/* Standard. RFC7231, Section 3.1.4.2 */
+#define MHD_HTTP_HEADER_CONTENT_LOCATION "Content-Location"
+/* Standard. RFC7233, Section 4.2 */
+#define MHD_HTTP_HEADER_CONTENT_RANGE "Content-Range"
+/* Standard. RFC7231, Section 3.1.1.5 */
+#define MHD_HTTP_HEADER_CONTENT_TYPE "Content-Type"
+/* Standard. RFC7231, Section 7.1.1.2 */
+#define MHD_HTTP_HEADER_DATE "Date"
+/* Standard. RFC7232, Section 2.3 */
+#define MHD_HTTP_HEADER_ETAG "ETag"
+/* Standard. RFC7231, Section 5.1.1 */
+#define MHD_HTTP_HEADER_EXPECT "Expect"
+/* Standard. RFC7234, Section 5.3 */
+#define MHD_HTTP_HEADER_EXPIRES "Expires"
+/* Standard. RFC7231, Section 5.5.1 */
+#define MHD_HTTP_HEADER_FROM "From"
+/* Standard. RFC7230, Section 5.4 */
+#define MHD_HTTP_HEADER_HOST "Host"
+/* Standard. RFC7232, Section 3.1 */
+#define MHD_HTTP_HEADER_IF_MATCH "If-Match"
+/* Standard. RFC7232, Section 3.3 */
+#define MHD_HTTP_HEADER_IF_MODIFIED_SINCE "If-Modified-Since"
+/* Standard. RFC7232, Section 3.2 */
+#define MHD_HTTP_HEADER_IF_NONE_MATCH "If-None-Match"
+/* Standard. RFC7233, Section 3.2 */
+#define MHD_HTTP_HEADER_IF_RANGE "If-Range"
+/* Standard. RFC7232, Section 3.4 */
+#define MHD_HTTP_HEADER_IF_UNMODIFIED_SINCE "If-Unmodified-Since"
+/* Standard. RFC7232, Section 2.2 */
+#define MHD_HTTP_HEADER_LAST_MODIFIED "Last-Modified"
+/* Standard. RFC7231, Section 7.1.2 */
+#define MHD_HTTP_HEADER_LOCATION "Location"
+/* Standard. RFC7231, Section 5.1.2 */
+#define MHD_HTTP_HEADER_MAX_FORWARDS "Max-Forwards"
+/* Standard. RFC7231, Appendix A.1 */
+#define MHD_HTTP_HEADER_MIME_VERSION "MIME-Version"
+/* Standard. RFC7234, Section 5.4 */
+#define MHD_HTTP_HEADER_PRAGMA "Pragma"
+/* Standard. RFC7235, Section 4.3 */
+#define MHD_HTTP_HEADER_PROXY_AUTHENTICATE "Proxy-Authenticate"
+/* Standard. RFC7235, Section 4.4 */
+#define MHD_HTTP_HEADER_PROXY_AUTHORIZATION "Proxy-Authorization"
+/* Standard. RFC7233, Section 3.1 */
+#define MHD_HTTP_HEADER_RANGE "Range"
+/* Standard. RFC7231, Section 5.5.2 */
+#define MHD_HTTP_HEADER_REFERER "Referer"
+/* Standard. RFC7231, Section 7.1.3 */
+#define MHD_HTTP_HEADER_RETRY_AFTER "Retry-After"
+/* Standard. RFC7231, Section 7.4.2 */
+#define MHD_HTTP_HEADER_SERVER "Server"
+/* Standard. RFC7230, Section 4.3 */
+#define MHD_HTTP_HEADER_TE "TE"
+/* Standard. RFC7230, Section 4.4 */
+#define MHD_HTTP_HEADER_TRAILER "Trailer"
+/* Standard. RFC7230, Section 3.3.1 */
+#define MHD_HTTP_HEADER_TRANSFER_ENCODING "Transfer-Encoding"
+/* Standard. RFC7230, Section 6.7 */
+#define MHD_HTTP_HEADER_UPGRADE "Upgrade"
+/* Standard. RFC7231, Section 5.5.3 */
+#define MHD_HTTP_HEADER_USER_AGENT "User-Agent"
+/* Standard. RFC7231, Section 7.1.4 */
+#define MHD_HTTP_HEADER_VARY "Vary"
+/* Standard. RFC7230, Section 5.7.1 */
+#define MHD_HTTP_HEADER_VIA "Via"
+/* Standard. RFC7235, Section 4.1 */
+#define MHD_HTTP_HEADER_WWW_AUTHENTICATE "WWW-Authenticate"
+/* Standard. RFC7234, Section 5.5 */
+#define MHD_HTTP_HEADER_WARNING "Warning"
+
+/* Additional HTTP headers. */
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_A_IM "A-IM"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_ACCEPT_ADDITIONS "Accept-Additions"
+/* Informational. RFC7089 */
+#define MHD_HTTP_HEADER_ACCEPT_DATETIME "Accept-Datetime"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_ACCEPT_FEATURES "Accept-Features"
+/* No category. RFC5789 */
+#define MHD_HTTP_HEADER_ACCEPT_PATCH "Accept-Patch"
+/* Standard. RFC7639, Section 2 */
+#define MHD_HTTP_HEADER_ALPN "ALPN"
+/* Standard. RFC7838 */
+#define MHD_HTTP_HEADER_ALT_SVC "Alt-Svc"
+/* Standard. RFC7838 */
+#define MHD_HTTP_HEADER_ALT_USED "Alt-Used"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_ALTERNATES "Alternates"
+/* No category. RFC4437 */
+#define MHD_HTTP_HEADER_APPLY_TO_REDIRECT_REF "Apply-To-Redirect-Ref"
+/* Experimental. RFC8053, Section 4 */
+#define MHD_HTTP_HEADER_AUTHENTICATION_CONTROL "Authentication-Control"
+/* Standard. RFC7615, Section 3 */
+#define MHD_HTTP_HEADER_AUTHENTICATION_INFO "Authentication-Info"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_C_EXT "C-Ext"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_C_MAN "C-Man"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_C_OPT "C-Opt"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_C_PEP "C-PEP"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_C_PEP_INFO "C-PEP-Info"
+/* Standard. RFC7809, Section 7.1 */
+#define MHD_HTTP_HEADER_CALDAV_TIMEZONES "CalDAV-Timezones"
+/* Obsoleted. RFC2068; RFC2616 */
+#define MHD_HTTP_HEADER_CONTENT_BASE "Content-Base"
+/* Standard. RFC6266 */
+#define MHD_HTTP_HEADER_CONTENT_DISPOSITION "Content-Disposition"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_CONTENT_ID "Content-ID"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_CONTENT_MD5 "Content-MD5"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_CONTENT_SCRIPT_TYPE "Content-Script-Type"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_CONTENT_STYLE_TYPE "Content-Style-Type"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_CONTENT_VERSION "Content-Version"
+/* Standard. RFC6265 */
+#define MHD_HTTP_HEADER_COOKIE "Cookie"
+/* Obsoleted. RFC2965; RFC6265 */
+#define MHD_HTTP_HEADER_COOKIE2 "Cookie2"
+/* Standard. RFC5323 */
+#define MHD_HTTP_HEADER_DASL "DASL"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_DAV "DAV"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_DEFAULT_STYLE "Default-Style"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_DELTA_BASE "Delta-Base"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_DEPTH "Depth"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_DERIVED_FROM "Derived-From"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_DESTINATION "Destination"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_DIFFERENTIAL_ID "Differential-ID"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_DIGEST "Digest"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_EXT "Ext"
+/* Standard. RFC7239 */
+#define MHD_HTTP_HEADER_FORWARDED "Forwarded"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_GETPROFILE "GetProfile"
+/* Experimental. RFC7486, Section 6.1.1 */
+#define MHD_HTTP_HEADER_HOBAREG "Hobareg"
+/* Standard. RFC7540, Section 3.2.1 */
+#define MHD_HTTP_HEADER_HTTP2_SETTINGS "HTTP2-Settings"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_IM "IM"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_IF "If"
+/* Standard. RFC6638 */
+#define MHD_HTTP_HEADER_IF_SCHEDULE_TAG_MATCH "If-Schedule-Tag-Match"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_KEEP_ALIVE "Keep-Alive"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_LABEL "Label"
+/* No category. RFC5988 */
+#define MHD_HTTP_HEADER_LINK "Link"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_LOCK_TOKEN "Lock-Token"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_MAN "Man"
+/* Informational. RFC7089 */
+#define MHD_HTTP_HEADER_MEMENTO_DATETIME "Memento-Datetime"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_METER "Meter"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_NEGOTIATE "Negotiate"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_OPT "Opt"
+/* Experimental. RFC8053, Section 3 */
+#define MHD_HTTP_HEADER_OPTIONAL_WWW_AUTHENTICATE "Optional-WWW-Authenticate"
+/* Standard. RFC4229 */
+#define MHD_HTTP_HEADER_ORDERING_TYPE "Ordering-Type"
+/* Standard. RFC6454 */
+#define MHD_HTTP_HEADER_ORIGIN "Origin"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_OVERWRITE "Overwrite"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_P3P "P3P"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PEP "PEP"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PICS_LABEL "PICS-Label"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PEP_INFO "Pep-Info"
+/* Standard. RFC4229 */
+#define MHD_HTTP_HEADER_POSITION "Position"
+/* Standard. RFC7240 */
+#define MHD_HTTP_HEADER_PREFER "Prefer"
+/* Standard. RFC7240 */
+#define MHD_HTTP_HEADER_PREFERENCE_APPLIED "Preference-Applied"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROFILEOBJECT "ProfileObject"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROTOCOL "Protocol"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROTOCOL_INFO "Protocol-Info"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROTOCOL_QUERY "Protocol-Query"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROTOCOL_REQUEST "Protocol-Request"
+/* Standard. RFC7615, Section 4 */
+#define MHD_HTTP_HEADER_PROXY_AUTHENTICATION_INFO "Proxy-Authentication-Info"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROXY_FEATURES "Proxy-Features"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PROXY_INSTRUCTION "Proxy-Instruction"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_PUBLIC "Public"
+/* Standard. RFC7469 */
+#define MHD_HTTP_HEADER_PUBLIC_KEY_PINS "Public-Key-Pins"
+/* Standard. RFC7469 */
+#define MHD_HTTP_HEADER_PUBLIC_KEY_PINS_REPORT_ONLY "Public-Key-Pins-Report-Only"
+/* No category. RFC4437 */
+#define MHD_HTTP_HEADER_REDIRECT_REF "Redirect-Ref"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_SAFE "Safe"
+/* Standard. RFC6638 */
+#define MHD_HTTP_HEADER_SCHEDULE_REPLY "Schedule-Reply"
+/* Standard. RFC6638 */
+#define MHD_HTTP_HEADER_SCHEDULE_TAG "Schedule-Tag"
+/* Standard. RFC6455 */
+#define MHD_HTTP_HEADER_SEC_WEBSOCKET_ACCEPT "Sec-WebSocket-Accept"
+/* Standard. RFC6455 */
+#define MHD_HTTP_HEADER_SEC_WEBSOCKET_EXTENSIONS "Sec-WebSocket-Extensions"
+/* Standard. RFC6455 */
+#define MHD_HTTP_HEADER_SEC_WEBSOCKET_KEY "Sec-WebSocket-Key"
+/* Standard. RFC6455 */
+#define MHD_HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL "Sec-WebSocket-Protocol"
+/* Standard. RFC6455 */
+#define MHD_HTTP_HEADER_SEC_WEBSOCKET_VERSION "Sec-WebSocket-Version"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_SECURITY_SCHEME "Security-Scheme"
+/* Standard. RFC6265 */
+#define MHD_HTTP_HEADER_SET_COOKIE "Set-Cookie"
+/* Obsoleted. RFC2965; RFC6265 */
+#define MHD_HTTP_HEADER_SET_COOKIE2 "Set-Cookie2"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_SETPROFILE "SetProfile"
+/* Standard. RFC5023 */
+#define MHD_HTTP_HEADER_SLUG "SLUG"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_SOAPACTION "SoapAction"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_STATUS_URI "Status-URI"
+/* Standard. RFC6797 */
+#define MHD_HTTP_HEADER_STRICT_TRANSPORT_SECURITY "Strict-Transport-Security"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_SURROGATE_CAPABILITY "Surrogate-Capability"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_SURROGATE_CONTROL "Surrogate-Control"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_TCN "TCN"
+/* Standard. RFC4918 */
+#define MHD_HTTP_HEADER_TIMEOUT "Timeout"
+/* Standard. RFC8030, Section 5.4 */
+#define MHD_HTTP_HEADER_TOPIC "Topic"
+/* Standard. RFC8030, Section 5.2 */
+#define MHD_HTTP_HEADER_TTL "TTL"
+/* Standard. RFC8030, Section 5.3 */
+#define MHD_HTTP_HEADER_URGENCY "Urgency"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_URI "URI"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_VARIANT_VARY "Variant-Vary"
+/* No category. RFC4229 */
+#define MHD_HTTP_HEADER_WANT_DIGEST "Want-Digest"
+/* Informational. RFC7034 */
+#define MHD_HTTP_HEADER_X_FRAME_OPTIONS "X-Frame-Options"
+
+/* Some provisional headers. */
+#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN "Access-Control-Allow-Origin"
+/** @} */ /* end of group headers */
+
/**
* A client has requested the given url using the given method
@@ -1187,6 +1553,16 @@ MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon,
/**
+ * Use SHOUTcast. This will cause the response to begin
+ * with the SHOUTcast "ICY" line instad of "HTTP".
+ *
+ * @param daemon daemon to set SHOUTcast option for
+ */
+_MHD_EXTERN void
+MHD_daemon_enable_shoutcast (struct MHD_Daemon *daemon);
+
+
+/**
* Enable and configure TLS.
*
* @param daemon which instance should be configured
@@ -1836,9 +2212,31 @@ enum MHD_HTTP_StatusCode {
MHD_HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511
};
+
+
+/**
+ * Returns the string reason phrase for a response code.
+ *
+ * If we don't have a string for a status code, we give the first
+ * message in that status code class.
+ */
+_MHD_EXTERN const char *
+MHD_get_reason_phrase_for (enum MHD_HTTP_StatusCode code);
+
/** @} */ /* end of group httpcode */
+/**
+ * @defgroup versions HTTP versions
+ * These strings should be used to match against the first line of the
+ * HTTP header.
+ * @{
+ */
+#define MHD_HTTP_VERSION_1_0 "HTTP/1.0"
+#define MHD_HTTP_VERSION_1_1 "HTTP/1.1"
+
+/** @} */ /* end of group versions */
+
/**
* Suspend handling of network data for a given request. This can
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
@@ -143,22 +143,22 @@ endif
# TBD!
if HAVE_POSTPROCESSOR
-libmicrohttpd_la_SOURCES += \
- postprocessor.c
+#libmicrohttpd_la_SOURCES += \
+# postprocessor.c
endif
# TBD!
if ENABLE_DAUTH
-libmicrohttpd_la_SOURCES += \
- digestauth.c \
- md5.c md5.h
+#libmicrohttpd_la_SOURCES += \
+# digestauth.c \
+# md5.c md5.h
endif
# TBD!
if ENABLE_BAUTH
-libmicrohttpd_la_SOURCES += \
- basicauth.c \
- base64.c base64.h
+#libmicrohttpd_la_SOURCES += \
+# basicauth.c \
+# base64.c base64.h
endif
diff --git a/src/lib/daemon_create.c b/src/lib/daemon_create.c
@@ -23,6 +23,7 @@
* @author Christian Grothoff
*/
#include "internal.h"
+#include "init.h"
/**
@@ -95,6 +96,9 @@ MHD_daemon_create (MHD_RequestCallback cb,
memset (daemon,
0,
sizeof (struct MHD_Daemon));
+#ifdef EPOLL_SUPPORT
+ daemon->epoll_itc_marker = "itc_marker";
+#endif
daemon->rc = cb;
daemon->rc_cls = cb_cls;
daemon->logger = &file_logger;
diff --git a/src/lib/daemon_destroy.c b/src/lib/daemon_destroy.c
@@ -24,7 +24,63 @@
*/
#include "internal.h"
-/* TODO: migrate logic below! */
+
+/**
+ * Stop all worker threads from the worker pool.
+ *
+ * @param daemon master daemon controling the workers
+ */
+static void
+stop_workers (struct MHD_Daemon *daemon)
+{
+ MHD_socket fd;
+ unsigned int i;
+
+ mhd_assert (1 < daemon->worker_pool_size);
+ mhd_assert (1 < daemon->threading_model);
+ if (daemon->was_quiesced)
+ fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
+ else
+ fd = daemon->listen_socket;
+ /* Let workers shutdown in parallel. */
+ for (i = 0; i < daemon->worker_pool_size; i++)
+ {
+ daemon->worker_pool[i].shutdown = true;
+ if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
+ {
+ if (! MHD_itc_activate_ (daemon->worker_pool[i].itc,
+ "e"))
+ MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel."));
+ }
+ else
+ {
+ /* Better hope shutdown() works... */
+ mhd_assert (MHD_INVALID_SOCKET != fd);
+ }
+ }
+#ifdef HAVE_LISTEN_SHUTDOWN
+ if (MHD_INVALID_SOCKET != fd)
+ {
+ (void) shutdown (fd,
+ SHUT_RDWR);
+ }
+#endif /* HAVE_LISTEN_SHUTDOWN */
+ for (i = 0; i < daemon->worker_pool_size; ++i)
+ {
+ MHD_daemon_destroy (&daemon->worker_pool[i]);
+ }
+ free (daemon->worker_pool);
+ daemon->worker_pool = NULL;
+ /* FIXME: does this still hold? */
+ mhd_assert (MHD_ITC_IS_INVALID_(daemon->itc));
+#ifdef EPOLL_SUPPORT
+ mhd_assert (-1 == daemon->epoll_fd);
+#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
+ mhd_assert (-1 == daemon->epoll_upgrade_fd);
+#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
+#endif /* EPOLL_SUPPORT */
+}
+
/**
* Shutdown and destroy an HTTP daemon.
@@ -36,7 +92,6 @@ void
MHD_daemon_destroy (struct MHD_Daemon *daemon)
{
MHD_socket fd;
- unsigned int i;
if (NULL == daemon)
return;
@@ -50,92 +105,60 @@ MHD_daemon_destroy (struct MHD_Daemon *daemon)
if (NULL != daemon->worker_pool)
{ /* Master daemon with worker pool. */
- mhd_assert (1 < daemon->worker_pool_size);
- mhd_assert (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD));
-
- /* Let workers shutdown in parallel. */
- for (i = 0; i < daemon->worker_pool_size; ++i)
- {
- daemon->worker_pool[i].shutdown = true;
- if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
- {
- if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "e"))
- MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel."));
- }
- else
- mhd_assert (MHD_INVALID_SOCKET != fd);
- }
-#ifdef HAVE_LISTEN_SHUTDOWN
- if (MHD_INVALID_SOCKET != fd)
- {
- (void) shutdown (fd,
- SHUT_RDWR);
- }
-#endif /* HAVE_LISTEN_SHUTDOWN */
- for (i = 0; i < daemon->worker_pool_size; ++i)
- {
- MHD_stop_daemon (&daemon->worker_pool[i]);
- }
- free (daemon->worker_pool);
- mhd_assert (MHD_ITC_IS_INVALID_(daemon->itc));
-#ifdef EPOLL_SUPPORT
- mhd_assert (-1 == daemon->epoll_fd);
-#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
- mhd_assert (-1 == daemon->epoll_upgrade_fd);
-#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
-#endif /* EPOLL_SUPPORT */
+ stop_workers (daemon);
}
else
- { /* Worker daemon or single daemon. */
- if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
- { /* Worker daemon or single daemon with internal thread(s). */
- mhd_assert (0 == daemon->worker_pool_size);
- if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
+ {
+ mhd_assert (0 == daemon->worker_pool_size);
+ /* Worker daemon or single-thread daemon. */
+ if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_model)
+ {
+ /* Worker daemon or single daemon with internal thread(s). */
+ if (! daemon->disallow_suspend_resume)
resume_suspended_connections (daemon);
- if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
- {
- /* Separate thread(s) is used for polling sockets. */
- if (MHD_ITC_IS_VALID_(daemon->itc))
- {
- if (! MHD_itc_activate_ (daemon->itc, "e"))
- MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
- }
- else
- {
+ /* Separate thread(s) is used for polling sockets. */
+ if (MHD_ITC_IS_VALID_(daemon->itc))
+ {
+ if (! MHD_itc_activate_ (daemon->itc,
+ "e"))
+ MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
+ }
+ else
+ {
#ifdef HAVE_LISTEN_SHUTDOWN
- if (MHD_INVALID_SOCKET != fd)
- {
- if (NULL == daemon->master)
- (void) shutdown (fd,
- SHUT_RDWR);
- }
- else
+ if (MHD_INVALID_SOCKET != fd)
+ {
+ if (NULL == daemon->master)
+ (void) shutdown (fd,
+ SHUT_RDWR);
+ }
+ else
#endif /* HAVE_LISTEN_SHUTDOWN */
- mhd_assert (false); /* Should never happen */
- }
-
- if (! MHD_join_thread_ (daemon->pid.handle))
- {
- MHD_PANIC (_("Failed to join a thread\n"));
- }
- /* close_all_connections() was called in daemon thread. */
- }
- }
+ mhd_assert (false); /* Should never happen */
+ }
+
+ if (! MHD_join_thread_ (daemon->pid.handle))
+ {
+ MHD_PANIC (_("Failed to join a thread\n"));
+ }
+ /* close_all_connections() was called in daemon thread. */
+ }
else
{
- /* No internal threads are used for polling sockets. */
+ /* No internal threads are used for polling sockets
+ (external event loop) */
close_all_connections (daemon);
}
if (MHD_ITC_IS_VALID_ (daemon->itc))
MHD_itc_destroy_chk_ (daemon->itc);
#ifdef EPOLL_SUPPORT
- if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
(-1 != daemon->epoll_fd) )
MHD_socket_close_chk_ (daemon->epoll_fd);
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
- if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
+ if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
(-1 != daemon->epoll_upgrade_fd) )
MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
@@ -154,16 +177,18 @@ MHD_daemon_destroy (struct MHD_Daemon *daemon)
/* TLS clean up */
#ifdef HTTPS_SUPPORT
- if (daemon->have_dhparams)
- {
- gnutls_dh_params_deinit (daemon->https_mem_dhparams);
- daemon->have_dhparams = false;
- }
- if (0 != (daemon->options & MHD_USE_TLS))
+ if (NULL != daemon->tls_api)
{
+#if FIXME_TLS_API
+ if (daemon->have_dhparams)
+ {
+ gnutls_dh_params_deinit (daemon->https_mem_dhparams);
+ daemon->have_dhparams = false;
+ }
gnutls_priority_deinit (daemon->priority_cache);
if (daemon->x509_cred)
gnutls_certificate_free_credentials (daemon->x509_cred);
+#endif
}
#endif /* HTTPS_SUPPORT */
diff --git a/src/lib/daemon_options.c b/src/lib/daemon_options.c
@@ -246,6 +246,19 @@ MHD_daemon_listen_allow_address_reuse (struct MHD_Daemon *daemon)
/**
+ * Use SHOUTcast. This will cause the response to begin
+ * with the SHOUTcast "ICY" line instad of "HTTP".
+ *
+ * @param daemon daemon to set SHOUTcast option for
+ */
+_MHD_EXTERN void
+MHD_daemon_enable_shoutcast (struct MHD_Daemon *daemon)
+{
+ daemon->enable_shoutcast = true;
+}
+
+
+/**
* Accept connections from the given socket. Socket
* must be a TCP or UNIX domain (stream) socket.
*
diff --git a/src/lib/daemon_quiesce.c b/src/lib/daemon_quiesce.c
@@ -67,7 +67,7 @@ MHD_daemon_quiesce (struct MHD_Daemon *daemon)
{
unsigned int i;
- for (i = 0; i < daemon->threading_model; i++)
+ for (i = 0; i < daemon->worker_pool_size; i++)
{
struct MHD_Daemon *worker = &daemon->worker_pool[i];
diff --git a/src/lib/daemon_start.c b/src/lib/daemon_start.c
@@ -48,40 +48,17 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
/* Apply the socket options according to
listening_address_reuse. */
- /* FIXME: used to be -1/0/1, now defined as a bool!
- MISMATCH! */
- if (0 == daemon->listening_address_reuse)
- {
-#ifndef MHD_WINSOCK_SOCKETS
- /* No user requirement, use "traditional" default SO_REUSEADDR
- * on non-W32 platforms, and do not fail if it doesn't work.
- * Don't use it on W32, because on W32 it will allow multiple
- * bind to the same address:port, like SO_REUSEPORT on others. */
- if (0 > setsockopt (listen_fd,
- SOL_SOCKET,
- SO_REUSEADDR,
- (void*) &on, sizeof (on)))
- {
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED,
- _("setsockopt failed: %s\n"),
- MHD_socket_last_strerr_ ());
-#endif
- }
-#endif /* ! MHD_WINSOCK_SOCKETS */
- return MHD_SC_OK;
- }
- if (daemon->listening_address_reuse > 0)
+ if (daemon->allow_address_reuse)
{
/* User requested to allow reusing listening address:port. */
#ifndef MHD_WINSOCK_SOCKETS
/* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
* it doesn't work. */
- if (0 > setsockopt (listen_fd,
+ if (0 > setsockopt (daemon->listen_socket,
SOL_SOCKET,
SO_REUSEADDR,
- (void*)&on, sizeof (on)))
+ (void *) &on,
+ sizeof (on)))
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
@@ -91,6 +68,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
#endif
return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED;
}
+ return MHD_SC_OK;
#endif /* ! MHD_WINSOCK_SOCKETS */
/* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
* Fail if SO_REUSEPORT is not defined or setsockopt fails.
@@ -98,7 +76,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
/* SO_REUSEADDR on W32 has the same semantics
as SO_REUSEPORT on BSD/Linux */
#if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
- if (0 > setsockopt (listen_fd,
+ if (0 > setsockopt (daemon->listen_socket,
SOL_SOCKET,
#ifndef MHD_WINSOCK_SOCKETS
SO_REUSEPORT,
@@ -116,6 +94,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
#endif
return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED;
}
+ return MHD_SC_OK;
#else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
/* we're supposed to allow address:port re-use, but
on this platform we cannot; fail hard */
@@ -128,7 +107,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
#endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
}
- /* if (daemon->listening_address_reuse < 0) */
+ /* if (! daemon->allow_address_reuse) */
/* User requested to disallow reusing listening address:port.
* Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
* is used and Solaris with SO_EXCLBIND.
@@ -155,6 +134,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
#endif
return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED;
}
+ return MHD_SC_OK;
#elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
@@ -163,6 +143,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
#endif
return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED;
#endif /* MHD_WINSOCK_SOCKETS */
+ /* Not on WINSOCK, simply doing nothing will do */
return MHD_SC_OK;
}
@@ -183,81 +164,75 @@ open_listen_socket (struct MHD_Daemon *daemon)
int pf;
bool use_v6;
- if (MHD_INVALID_SOCKET != daemon->listen_fd)
+ if (MHD_INVALID_SOCKET != daemon->listen_socket)
return MHD_SC_OK; /* application opened it for us! */
/* Determine address family */
- if (MHD_AF_NONE != daemon->address_family)
+ switch (daemon->listen_af)
{
- switch (daemon->address_family)
+ case MHD_AF_NONE:
+ if (0 == daemon->listen_sa_len)
{
- case MHD_AF_NONE:
- abort ();
- case MHD_AF_AUTO:
-#if HAVE_INET6
- pf = PF_INET6;
- use_v6 = true;
-#else
+ /* no listening desired, that's OK */
+ return MHD_SC_OK;
+ }
+ /* we have a listen address, get AF from there! */
+ switch (daemon->listen_sa.ss_family)
+ {
+ case AF_INET:
pf = PF_INET;
use_v6 = false;
-#endif
- break;
- case MHD_AF_INET:
- use_v6 = false;
- pf = PF_INET;
break;
- case MHD_AF_INET6:
- case MHD_AF_DUAL:
-#if HAVE_INET6
+#ifdef AF_INET6
+ case AF_INET6:
pf = PF_INET6;
use_v6 = true;
break;
-#else
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD,
- _("IPv6 not supported by this build\n"));
#endif
- return MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD;
+#ifdef AF_UNIX
+ case AF_UNIX:
+ pf = PF_UNIX;
+ use_v6 = false;
+ break;
#endif
- }
- }
- else if (0 != daemon->listen_sa_len)
- {
-
- /* we have a listen address, get AF from there! */
- switch (daemon->listen_sa.ss_family)
- {
- case AF_INET:
- pf = PF_INET;
- use_v6 = false;
- break;
-#ifdef AF_INET6
- case AF_INET6:
- pf = PF_INET6;
- use_v6 = true;
- break;
+ default:
+ return MHD_SC_AF_NOT_SUPPORTED_BY_BUILD;
+ } /* switch on ss_family */
+ break; /* MHD_AF_NONE */
+ case MHD_AF_AUTO:
+#if HAVE_INET6
+ pf = PF_INET6;
+ use_v6 = true;
+#else
+ pf = PF_INET;
+ use_v6 = false;
#endif
-#ifdef AF_UNIX
- case AF_UNIX:
- pf = PF_UNIX;
- use_v6 = false;
+ break;
+ case MHD_AF_INET4:
+ use_v6 = false;
+ pf = PF_INET;
+ break;
+ case MHD_AF_INET6:
+ case MHD_AF_DUAL:
+#if HAVE_INET6
+ pf = PF_INET6;
+ use_v6 = true;
+ break;
+#else
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD,
+ _("IPv6 not supported by this build\n"));
+#endif
+ return MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD;
#endif
- default:
- return MHD_SC_AF_NOT_SUPPORTED_BY_BUILD;
- }
- }
- else
- {
- /* no listening desired, that's OK */
- return MHD_SC_OK;
}
/* try to open listen socket */
try_open_listen_socket:
daemon->listen_socket = MHD_socket_create_listen_(pf);
if ( (MHD_INVALID_SOCKET == daemon->listen_socket) &&
- (MHD_AF_AUTO == daemon->address_family) &&
+ (MHD_AF_AUTO == daemon->listen_af) &&
(use_v6) )
{
use_v6 = false;
@@ -288,8 +263,8 @@ open_listen_socket (struct MHD_Daemon *daemon)
and may also be missing on older POSIX systems; good luck if you have any of those,
your IPv6 socket may then also bind against IPv4 anyway... */
const MHD_SCKT_OPT_BOOL_ v6_only =
- (MHD_AF_INET6 == daemon->address_family);
- if (0 > setsockopt (listen_fd,
+ (MHD_AF_INET6 == daemon->listen_af);
+ if (0 > setsockopt (daemon->listen_socket,
IPPROTO_IPV6,
IPV6_V6ONLY,
(const void *) &v6_only,
@@ -315,7 +290,7 @@ open_listen_socket (struct MHD_Daemon *daemon)
if (0 != daemon->listen_sa_len)
{
/* Bind address explicitly given */
- sa = daemon->listen_sa;
+ sa = (const struct sockaddr *) &daemon->listen_sa;
addrlen = daemon->listen_sa_len;
}
else
@@ -359,7 +334,7 @@ open_listen_socket (struct MHD_Daemon *daemon)
sin4->sin_len = sizeof (struct sockaddr_in);
#endif
}
- sa = (const struct sockaddr *) ss;
+ sa = (const struct sockaddr *) &ss;
}
/* actually do the bind() */
@@ -374,13 +349,13 @@ open_listen_socket (struct MHD_Daemon *daemon)
{
case AF_INET:
if (addrlen == sizeof (struct sockaddr_in))
- port = ntohs (((const struct sockaddr_in*)sa)->sin_port);
+ port = ntohs (((const struct sockaddr_in *) sa)->sin_port);
else
port = UINT16_MAX + 1; /* indicate size error */
break;
case AF_INET6:
if (addrlen == sizeof (struct sockaddr_in6))
- port = ntohs (((const struct sockaddr_in6*)sa)->sin_port);
+ port = ntohs (((const struct sockaddr_in6 *) sa)->sin6_port);
else
port = UINT16_MAX + 1; /* indicate size error */
break;
@@ -404,8 +379,8 @@ open_listen_socket (struct MHD_Daemon *daemon)
if (0 != setsockopt (daemon->listen_socket,
IPPROTO_TCP,
TCP_FASTOPEN,
- &daemon->fastopen_queue_size,
- sizeof (daemon->fastopen_queue_size)))
+ &daemon->fo_queue_length,
+ sizeof (daemon->fo_queue_length)))
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
@@ -421,7 +396,7 @@ open_listen_socket (struct MHD_Daemon *daemon)
/* setup listening */
if (0 > listen (daemon->listen_socket,
- daemon->listen_backlog_size))
+ daemon->listen_backlog))
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
@@ -449,7 +424,7 @@ get_listen_port_number (struct MHD_Daemon *daemon)
struct sockaddr_storage servaddr;
socklen_t addrlen;
- if ( (0 != daemon->port) ||
+ if ( (0 != daemon->listen_port) ||
(MHD_INVALID_SOCKET == daemon->listen_socket) )
return; /* nothing to be done */
@@ -487,7 +462,7 @@ get_listen_port_number (struct MHD_Daemon *daemon)
{
struct sockaddr_in *s4 = (struct sockaddr_in *) &servaddr;
- daemon->port = ntohs (s4->sin_port);
+ daemon->listen_port = ntohs (s4->sin_port);
break;
}
#ifdef HAVE_INET6
@@ -495,13 +470,13 @@ get_listen_port_number (struct MHD_Daemon *daemon)
{
struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &servaddr;
- daemon->port = ntohs(s6->sin6_port);
+ daemon->listen_port = ntohs(s6->sin6_port);
break;
}
#endif /* HAVE_INET6 */
#ifdef AF_UNIX
case AF_UNIX:
- daemon->port = 0; /* special value for UNIX domain sockets */
+ daemon->listen_port = 0; /* special value for UNIX domain sockets */
break;
#endif
default:
@@ -510,12 +485,57 @@ get_listen_port_number (struct MHD_Daemon *daemon)
MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF,
_("Unknown address family!\n"));
#endif
- daemon->port = 0; /* ugh */
+ daemon->listen_port = 0; /* ugh */
break;
}
}
+#ifdef EPOLL_SUPPORT
+/**
+ * Setup file descriptor to be used for epoll() control.
+ *
+ * @param daemon the daemon to setup epoll FD for
+ * @return the epoll() fd to use
+ */
+static int
+setup_epoll_fd (struct MHD_Daemon *daemon)
+{
+ int fd;
+
+#ifndef HAVE_MESSAGES
+ (void)daemon; /* Mute compiler warning. */
+#endif /* ! HAVE_MESSAGES */
+
+#ifdef USE_EPOLL_CREATE1
+ fd = epoll_create1 (EPOLL_CLOEXEC);
+#else /* ! USE_EPOLL_CREATE1 */
+ fd = epoll_create (MAX_EVENTS);
+#endif /* ! USE_EPOLL_CREATE1 */
+ if (MHD_INVALID_SOCKET == fd)
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_EPOLL_CTL_CREATE_FAILED,
+ _("Call to epoll_create1 failed: %s\n"),
+ MHD_socket_last_strerr_ ());
+#endif
+ return MHD_INVALID_SOCKET;
+ }
+#if !defined(USE_EPOLL_CREATE1)
+ if (! MHD_socket_noninheritable_ (fd))
+ {
+#ifdef HAVE_MESSAGES
+ MHD_DLOG (daemon,
+ MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED,
+ _("Failed to set noninheritable mode on epoll FD.\n"));
+#endif
+ }
+#endif /* ! USE_EPOLL_CREATE1 */
+ return fd;
+}
+
+
/**
* Setup epoll() FD for the daemon and initialize it to listen
* on the listen FD.
@@ -536,14 +556,14 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
if (-1 == daemon->epoll_fd)
return MHD_NO;
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
- if (0 != (MHD_ALLOW_UPGRADE & daemon->options))
+ if (! daemon->disallow_upgrade)
{
daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
return MHD_NO;
}
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
- if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_fd)) ||
+ if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_socket)) ||
(daemon->was_quiesced) )
return MHD_YES; /* non-listening daemon */
event.events = EPOLLIN;
@@ -555,6 +575,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
+ MHD_SC_EPOLL_CTL_ADD_FAILED,
_("Call to epoll_ctl failed: %s\n"),
MHD_socket_last_strerr_ ());
#endif
@@ -564,7 +585,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
if (MHD_ITC_IS_VALID_(daemon->itc))
{
event.events = EPOLLIN;
- event.data.ptr = (void *) epoll_itc_marker;
+ event.data.ptr = (void *) daemon->epoll_itc_marker;
if (0 != epoll_ctl (daemon->epoll_fd,
EPOLL_CTL_ADD,
MHD_itc_r_fd_ (daemon->itc),
@@ -572,6 +593,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
+ MHD_SC_EPOLL_CTL_ADD_FAILED,
_("Call to epoll_ctl failed: %s\n"),
MHD_socket_last_strerr_ ());
#endif
@@ -647,7 +669,7 @@ setup_thread_pool (struct MHD_Daemon *daemon)
/ daemon->threading_model;
unsigned int leftover_conns = daemon->global_connection_limit
% daemon->threading_model;
- unsigned int i;
+ int i;
enum MHD_StatusCode sc;
/* Allocate memory for pooled objects */
@@ -675,7 +697,7 @@ setup_thread_pool (struct MHD_Daemon *daemon)
* Thread indexes in [0, leftover_conns) each get one of the
* leftover connections. */
d->global_connection_limit = conns_per_thread;
- if (i < leftover_conns)
+ if (((unsigned int) i) < leftover_conns)
++d->global_connection_limit;
if (! daemon->disable_itc)
@@ -733,7 +755,7 @@ setup_thread_pool (struct MHD_Daemon *daemon)
/* Spawn the worker thread */
if (! MHD_create_named_thread_ (&d->pid,
"MHD-worker",
- daemon->thread_stack_size,
+ daemon->thread_stack_limit_b,
&MHD_polling_thread,
d))
{
@@ -909,9 +931,9 @@ MHD_daemon_start (struct MHD_Daemon *daemon)
(MHD_TM_THREAD_PER_CONNECTION == daemon->threading_model)
? "MHD-listen"
: "MHD-single",
- daemon->thread_stack_size,
+ daemon->thread_stack_limit_b,
&MHD_polling_thread,
- daemon) )
+ daemon) ) )
{
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
@@ -928,7 +950,10 @@ MHD_daemon_start (struct MHD_Daemon *daemon)
(MHD_INVALID_SOCKET != daemon->listen_socket) &&
(MHD_SC_OK != (sc = setup_thread_pool (daemon))) )
return sc;
-
+
+ /* make sure we know our listen port (if any) */
+ get_listen_port_number (daemon);
+
return MHD_SC_OK;
}
diff --git a/src/lib/init.c b/src/lib/init.c
@@ -119,6 +119,37 @@ MHD_check_global_init_ (void)
/**
+ * Default implementation of the panic function,
+ * prints an error message and aborts.
+ *
+ * @param cls unused
+ * @param file name of the file with the problem
+ * @param line line number with the problem
+ * @param reason error message with details
+ */
+static void
+mhd_panic_std (void *cls,
+ const char *file,
+ unsigned int line,
+ const char *reason)
+{
+ (void)cls; /* Mute compiler warning. */
+#ifdef HAVE_MESSAGES
+ fprintf (stderr,
+ _("Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
+ file,
+ line,
+ reason);
+#else /* ! HAVE_MESSAGES */
+ (void)file; /* Mute compiler warning. */
+ (void)line; /* Mute compiler warning. */
+ (void)reason; /* Mute compiler warning. */
+#endif
+ abort ();
+}
+
+
+/**
* Initialize do setup work.
*/
void
diff --git a/src/lib/internal.c b/src/lib/internal.c
@@ -173,8 +173,8 @@ MHD_http_unescape (char *val)
* Parse and unescape the arguments given by the client
* as part of the HTTP request URI.
*
+ * @param request request to add headers to
* @param kind header kind to pass to @a cb
- * @param connection connection to add headers to
* @param[in,out] args argument URI string (after "?" in URI),
* clobbered in the process!
* @param cb function to call on each key-value pair found
@@ -184,13 +184,13 @@ MHD_http_unescape (char *val)
* returned #MHD_YES)
*/
int
-MHD_parse_arguments_ (struct MHD_Connection *connection,
+MHD_parse_arguments_ (struct MHD_Request *request,
enum MHD_ValueKind kind,
char *args,
MHD_ArgumentIterator_ cb,
unsigned int *num_headers)
{
- struct MHD_Daemon *daemon = connection->daemon;
+ struct MHD_Daemon *daemon = request->daemon;
char *equals;
char *amper;
@@ -208,9 +208,9 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
/* last argument, without '=' */
MHD_unescape_plus (args);
daemon->unescape_cb (daemon->unescape_cb_cls,
- connection,
+ request,
args);
- if (MHD_YES != cb (connection,
+ if (MHD_YES != cb (request,
args,
NULL,
kind))
@@ -223,13 +223,13 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
equals++;
MHD_unescape_plus (args);
daemon->unescape_cb (daemon->unescape_cb_cls,
- connection,
+ request,
args);
MHD_unescape_plus (equals);
daemon->unescape_cb (daemon->unescape_cb_cls,
- connection,
+ request,
equals);
- if (MHD_YES != cb (connection,
+ if (MHD_YES != cb (request,
args,
equals,
kind))
@@ -246,9 +246,9 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
/* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
MHD_unescape_plus (args);
daemon->unescape_cb (daemon->unescape_cb_cls,
- connection,
+ request,
args);
- if (MHD_YES != cb (connection,
+ if (MHD_YES != cb (request,
args,
NULL,
kind))
@@ -264,13 +264,13 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
equals++;
MHD_unescape_plus (args);
daemon->unescape_cb (daemon->unescape_cb_cls,
- connection,
+ request,
args);
MHD_unescape_plus (equals);
daemon->unescape_cb (daemon->unescape_cb_cls,
- connection,
+ request,
equals);
- if (MHD_YES != cb (connection,
+ if (MHD_YES != cb (request,
args,
equals,
kind))
diff --git a/src/lib/internal.h b/src/lib/internal.h
@@ -33,6 +33,7 @@
#include "microhttpd_tls.h"
#include "mhd_assert.h"
#include "mhd_compat.h"
+#include "mhd_itc.h"
#include "mhd_mono_clock.h"
#include "memorypool.h"
@@ -1011,6 +1012,13 @@ struct MHD_Daemon
*/
struct MHD_Connection *eready_tail;
+#ifdef EPOLL_SUPPORT
+ /**
+ * Pointer to marker used to indicate ITC slot in epoll sets.
+ */
+ const char *epoll_itc_marker;
+#endif
+
#ifdef UPGRADE_SUPPORT
/**
* Head of EDLL of upgraded connections ready for processing (in epoll mode).
@@ -1052,6 +1060,11 @@ struct MHD_Daemon
unsigned int nonce_nc_size;
#endif
+
+ /**
+ * The select thread handle (if we have internal select)
+ */
+ MHD_thread_handle_ID_ pid;
/**
* Socket address to bind to for the listen socket.
@@ -1286,12 +1299,22 @@ struct MHD_Daemon
bool enable_turbo;
/**
+ * MHD_daemon_quiesce() was run against this daemon.
+ */
+ bool was_quiesced;
+
+ /**
* Allow reusing the address:port combination when binding.
* See #MHD_daemon_listen_allow_address_reuse().
*/
bool allow_address_reuse;
/**
+ * MHD should speak SHOUTcast instead of HTTP.
+ */
+ bool enable_shoutcast;
+
+ /**
* Are we shutting down?
*/
volatile bool shutdown;
@@ -1463,7 +1486,7 @@ struct MHD_Response
* Callback invoked when iterating over @a key / @a value
* argument pairs during parsing.
*
- * @param connection context of the iteration
+ * @param request context of the iteration
* @param key 0-terminated key string, never NULL
* @param value 0-terminated value string, may be NULL
* @param kind origin of the key-value pair
@@ -1471,7 +1494,7 @@ struct MHD_Response
* #MHD_NO to signal failure (and abort iteration)
*/
typedef int
-(*MHD_ArgumentIterator_)(struct MHD_Connection *connection,
+(*MHD_ArgumentIterator_)(struct MHD_Request *request,
const char *key,
const char *value,
enum MHD_ValueKind kind);
@@ -1481,8 +1504,8 @@ typedef int
* Parse and unescape the arguments given by the client
* as part of the HTTP request URI.
*
+ * @param request request to add headers to
* @param kind header kind to pass to @a cb
- * @param connection connection to add headers to
* @param[in,out] args argument URI string (after "?" in URI),
* clobbered in the process!
* @param cb function to call on each key-value pair found
@@ -1492,7 +1515,7 @@ typedef int
* returned #MHD_YES)
*/
int
-MHD_parse_arguments_ (struct MHD_Connection *connection,
+MHD_parse_arguments_ (struct MHD_Request *request,
enum MHD_ValueKind kind,
char *args,
MHD_ArgumentIterator_ cb,
diff --git a/src/lib/reason_phrase.c b/src/lib/reason_phrase.c
@@ -0,0 +1,182 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007, 2011, 2017 Christian Grothoff, Karlson2k (Evgeny Grin)
+
+ 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 reason_phrase.c
+ * @brief Tables of the string response phrases
+ * @author Elliot Glaysher
+ * @author Christian Grothoff (minor code clean up)
+ * @author Karlson2k (Evgeny Grin)
+ */
+#include "internal.h"
+
+#ifndef NULL
+#define NULL ((void*)0)
+#endif
+
+static const char *const invalid_hundred[] = {
+ NULL
+};
+
+static const char *const one_hundred[] = {
+ "Continue",
+ "Switching Protocols",
+ "Processing"
+};
+
+static const char *const two_hundred[] = {
+ "OK",
+ "Created",
+ "Accepted",
+ "Non-Authoritative Information",
+ "No Content",
+ "Reset Content",
+ "Partial Content",
+ "Multi-Status",
+ "Already Reported",
+ "Unknown",
+ "Unknown", /* 210 */
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown", /* 215 */
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown", /* 220 */
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown", /* 225 */
+ "IM Used"
+};
+
+static const char *const three_hundred[] = {
+ "Multiple Choices",
+ "Moved Permanently",
+ "Found",
+ "See Other",
+ "Not Modified",
+ "Use Proxy",
+ "Switch Proxy",
+ "Temporary Redirect",
+ "Permanent Redirect"
+};
+
+static const char *const four_hundred[] = {
+ "Bad Request",
+ "Unauthorized",
+ "Payment Required",
+ "Forbidden",
+ "Not Found",
+ "Method Not Allowed",
+ "Not Acceptable",
+ "Proxy Authentication Required",
+ "Request Timeout",
+ "Conflict",
+ "Gone",
+ "Length Required",
+ "Precondition Failed",
+ "Payload Too Large",
+ "URI Too Long",
+ "Unsupported Media Type",
+ "Range Not Satisfiable",
+ "Expectation Failed",
+ "Unknown",
+ "Unknown",
+ "Unknown", /* 420 */
+ "Misdirected Request",
+ "Unprocessable Entity",
+ "Locked",
+ "Failed Dependency",
+ "Unordered Collection",
+ "Upgrade Required",
+ "Unknown",
+ "Precondition Required",
+ "Too Many Requests",
+ "Unknown", /* 430 */
+ "Request Header Fields Too Large",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown", /* 435 */
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Unknown", /* 440 */
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "No Response",
+ "Unknown", /* 445 */
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "Retry With",
+ "Blocked by Windows Parental Controls", /* 450 */
+ "Unavailable For Legal Reasons"
+};
+
+static const char *const five_hundred[] = {
+ "Internal Server Error",
+ "Not Implemented",
+ "Bad Gateway",
+ "Service Unavailable",
+ "Gateway Timeout",
+ "HTTP Version Not Supported",
+ "Variant Also Negotiates",
+ "Insufficient Storage",
+ "Loop Detected",
+ "Bandwidth Limit Exceeded",
+ "Not Extended",
+ "Network Authentication Required"
+};
+
+
+struct MHD_Reason_Block
+{
+ size_t max;
+ const char *const*data;
+};
+
+#define BLOCK(m) { (sizeof(m) / sizeof(char*)), m }
+
+static const struct MHD_Reason_Block reasons[] = {
+ BLOCK (invalid_hundred),
+ BLOCK (one_hundred),
+ BLOCK (two_hundred),
+ BLOCK (three_hundred),
+ BLOCK (four_hundred),
+ BLOCK (five_hundred),
+};
+
+
+const char *
+MHD_get_reason_phrase_for (enum MHD_HTTP_StatusCode code)
+{
+ if ( (code >= 100) &&
+ (code < 600) &&
+ (reasons[code / 100].max > (code % 100)) )
+ return reasons[code / 100].data[code % 100];
+ return "Unknown";
+}
diff --git a/src/lib/response_for_upgrade.c b/src/lib/response_for_upgrade.c
@@ -77,11 +77,11 @@ MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
response->total_size = MHD_SIZE_UNKNOWN;
response->reference_count = 1;
if (MHD_NO ==
- MHD_add_response_header (response,
+ MHD_response_add_header (response,
MHD_HTTP_HEADER_CONNECTION,
"Upgrade"))
{
- MHD_destroy_response (response);
+ MHD_response_queue_for_destroy (response);
return NULL;
}
return response;