Răsfoiți Sursa

get src/lib/ to build -- with plenty of warnings

Christian Grothoff 8 ani în urmă
părinte
comite
b926a975e6

+ 398 - 0
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
@@ -1186,6 +1552,16 @@ MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon,
 				  enum MHD_ProtocolStrictLevel sl);
 
 
+/**
+ * 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.
  *
@@ -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

+ 8 - 8
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
 
 

+ 4 - 0
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;

+ 102 - 77
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 */
   

+ 13 - 0
src/lib/daemon_options.c

@@ -245,6 +245,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.

+ 1 - 1
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];
 	  

+ 131 - 106
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;
 }
 

+ 31 - 0
src/lib/init.c

@@ -118,6 +118,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.
  */

+ 13 - 13
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))

+ 27 - 4
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.
@@ -1285,12 +1298,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?
    */
@@ -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,

+ 182 - 0
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";
+}

+ 2 - 2
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;