aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-02-15 02:52:09 +0100
committerChristian Grothoff <christian@grothoff.org>2018-02-15 03:08:53 +0100
commitb926a975e6633e9d4d1c2ec21f459e55a5ceb5de (patch)
tree75bb814a38e1120a33231921aed4382ee1e61347
parent8c8f43fa9526f29e568305d51980466eda79c6a0 (diff)
downloadlibmicrohttpd-b926a975e6633e9d4d1c2ec21f459e55a5ceb5de.tar.gz
libmicrohttpd-b926a975e6633e9d4d1c2ec21f459e55a5ceb5de.zip
get src/lib/ to build -- with plenty of warnings
-rw-r--r--src/include/microhttpd2.h398
-rw-r--r--src/lib/Makefile.am16
-rw-r--r--src/lib/daemon_create.c4
-rw-r--r--src/lib/daemon_destroy.c179
-rw-r--r--src/lib/daemon_options.c13
-rw-r--r--src/lib/daemon_quiesce.c2
-rw-r--r--src/lib/daemon_start.c237
-rw-r--r--src/lib/init.c31
-rw-r--r--src/lib/internal.c26
-rw-r--r--src/lib/internal.h31
-rw-r--r--src/lib/reason_phrase.c182
-rw-r--r--src/lib/response_for_upgrade.c4
12 files changed, 912 insertions, 211 deletions
diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h
index f4b39fbe..bb65f534 100644
--- a/src/include/microhttpd2.h
+++ b/src/include/microhttpd2.h
@@ -520,7 +520,28 @@ enum MHD_StatusCode
520 */ 520 */
521 MHD_SC_THREAD_POOL_LAUNCH_FAILURE = 50031, 521 MHD_SC_THREAD_POOL_LAUNCH_FAILURE = 50031,
522 522
523 /**
524 * We failed to add a socket to the epoll() set.
525 */
526 MHD_SC_EPOLL_CTL_ADD_FAILED = 50032,
527
528 /**
529 * We failed to start a thread.
530 */
531 MHD_SC_THREAD_LAUNCH_FAILURE = 50033,
523 532
533 /**
534 * We failed to create control socket for the epoll().
535 */
536 MHD_SC_EPOLL_CTL_CREATE_FAILED = 50034,
537
538 /**
539 * We failed to configure control socket for the epoll()
540 * to be non-inheritable.
541 */
542 MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED = 50035,
543
544
524}; 545};
525 546
526 547
@@ -542,6 +563,12 @@ struct MHD_Action;
542 * add additional methods (as per IANA registry), thus even if the API 563 * add additional methods (as per IANA registry), thus even if the API
543 * returns "unknown" today, it may return a method-specific header in 564 * returns "unknown" today, it may return a method-specific header in
544 * the future! 565 * the future!
566 *
567 * @defgroup methods HTTP methods
568 * HTTP methods (as strings).
569 * See: http://www.iana.org/assignments/http-methods/http-methods.xml
570 * Registry Version 2015-05-19
571 * @{
545 */ 572 */
546enum MHD_Method 573enum MHD_Method
547{ 574{
@@ -553,31 +580,37 @@ enum MHD_Method
553 580
554 /** 581 /**
555 * "OPTIONS" method. 582 * "OPTIONS" method.
583 * Safe. Idempotent. RFC7231, Section 4.3.7.
556 */ 584 */
557 MHD_METHOD_OPTIONS = 1, 585 MHD_METHOD_OPTIONS = 1,
558 586
559 /** 587 /**
560 * "GET" method. 588 * "GET" method.
589 * Safe. Idempotent. RFC7231, Section 4.3.1.
561 */ 590 */
562 MHD_METHOD_GET = 2, 591 MHD_METHOD_GET = 2,
563 592
564 /** 593 /**
565 * "HEAD" method. 594 * "HEAD" method.
595 * Safe. Idempotent. RFC7231, Section 4.3.2.
566 */ 596 */
567 MHD_METHOD_HEAD = 3, 597 MHD_METHOD_HEAD = 3,
568 598
569 /** 599 /**
570 * "POST" method. 600 * "POST" method.
601 * Not safe. Not idempotent. RFC7231, Section 4.3.3.
571 */ 602 */
572 MHD_METHOD_POST = 4, 603 MHD_METHOD_POST = 4,
573 604
574 /** 605 /**
575 * "PUT" method. 606 * "PUT" method.
607 * Not safe. Idempotent. RFC7231, Section 4.3.4.
576 */ 608 */
577 MHD_METHOD_PUT = 5, 609 MHD_METHOD_PUT = 5,
578 610
579 /** 611 /**
580 * "DELETE" method. 612 * "DELETE" method.
613 * Not safe. Idempotent. RFC7231, Section 4.3.5.
581 */ 614 */
582 MHD_METHOD_DELETE = 6, 615 MHD_METHOD_DELETE = 6,
583 616
@@ -746,6 +779,339 @@ enum MHD_Method
746 779
747}; 780};
748 781
782/** @} */ /* end of group methods */
783
784
785/**
786 * @defgroup postenc HTTP POST encodings
787 * See also: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4
788 * @{
789 */
790#define MHD_HTTP_POST_ENCODING_FORM_URLENCODED "application/x-www-form-urlencoded"
791#define MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA "multipart/form-data"
792
793/** @} */ /* end of group postenc */
794
795
796
797/**
798 * @defgroup headers HTTP headers
799 * These are the standard headers found in HTTP requests and responses.
800 * See: http://www.iana.org/assignments/message-headers/message-headers.xml
801 * Registry Version 2017-01-27
802 * @{
803 */
804
805/* Main HTTP headers. */
806/* Standard. RFC7231, Section 5.3.2 */
807#define MHD_HTTP_HEADER_ACCEPT "Accept"
808/* Standard. RFC7231, Section 5.3.3 */
809#define MHD_HTTP_HEADER_ACCEPT_CHARSET "Accept-Charset"
810/* Standard. RFC7231, Section 5.3.4; RFC7694, Section 3 */
811#define MHD_HTTP_HEADER_ACCEPT_ENCODING "Accept-Encoding"
812/* Standard. RFC7231, Section 5.3.5 */
813#define MHD_HTTP_HEADER_ACCEPT_LANGUAGE "Accept-Language"
814/* Standard. RFC7233, Section 2.3 */
815#define MHD_HTTP_HEADER_ACCEPT_RANGES "Accept-Ranges"
816/* Standard. RFC7234, Section 5.1 */
817#define MHD_HTTP_HEADER_AGE "Age"
818/* Standard. RFC7231, Section 7.4.1 */
819#define MHD_HTTP_HEADER_ALLOW "Allow"
820/* Standard. RFC7235, Section 4.2 */
821#define MHD_HTTP_HEADER_AUTHORIZATION "Authorization"
822/* Standard. RFC7234, Section 5.2 */
823#define MHD_HTTP_HEADER_CACHE_CONTROL "Cache-Control"
824/* Reserved. RFC7230, Section 8.1 */
825#define MHD_HTTP_HEADER_CLOSE "Close"
826/* Standard. RFC7230, Section 6.1 */
827#define MHD_HTTP_HEADER_CONNECTION "Connection"
828/* Standard. RFC7231, Section 3.1.2.2 */
829#define MHD_HTTP_HEADER_CONTENT_ENCODING "Content-Encoding"
830/* Standard. RFC7231, Section 3.1.3.2 */
831#define MHD_HTTP_HEADER_CONTENT_LANGUAGE "Content-Language"
832/* Standard. RFC7230, Section 3.3.2 */
833#define MHD_HTTP_HEADER_CONTENT_LENGTH "Content-Length"
834/* Standard. RFC7231, Section 3.1.4.2 */
835#define MHD_HTTP_HEADER_CONTENT_LOCATION "Content-Location"
836/* Standard. RFC7233, Section 4.2 */
837#define MHD_HTTP_HEADER_CONTENT_RANGE "Content-Range"
838/* Standard. RFC7231, Section 3.1.1.5 */
839#define MHD_HTTP_HEADER_CONTENT_TYPE "Content-Type"
840/* Standard. RFC7231, Section 7.1.1.2 */
841#define MHD_HTTP_HEADER_DATE "Date"
842/* Standard. RFC7232, Section 2.3 */
843#define MHD_HTTP_HEADER_ETAG "ETag"
844/* Standard. RFC7231, Section 5.1.1 */
845#define MHD_HTTP_HEADER_EXPECT "Expect"
846/* Standard. RFC7234, Section 5.3 */
847#define MHD_HTTP_HEADER_EXPIRES "Expires"
848/* Standard. RFC7231, Section 5.5.1 */
849#define MHD_HTTP_HEADER_FROM "From"
850/* Standard. RFC7230, Section 5.4 */
851#define MHD_HTTP_HEADER_HOST "Host"
852/* Standard. RFC7232, Section 3.1 */
853#define MHD_HTTP_HEADER_IF_MATCH "If-Match"
854/* Standard. RFC7232, Section 3.3 */
855#define MHD_HTTP_HEADER_IF_MODIFIED_SINCE "If-Modified-Since"
856/* Standard. RFC7232, Section 3.2 */
857#define MHD_HTTP_HEADER_IF_NONE_MATCH "If-None-Match"
858/* Standard. RFC7233, Section 3.2 */
859#define MHD_HTTP_HEADER_IF_RANGE "If-Range"
860/* Standard. RFC7232, Section 3.4 */
861#define MHD_HTTP_HEADER_IF_UNMODIFIED_SINCE "If-Unmodified-Since"
862/* Standard. RFC7232, Section 2.2 */
863#define MHD_HTTP_HEADER_LAST_MODIFIED "Last-Modified"
864/* Standard. RFC7231, Section 7.1.2 */
865#define MHD_HTTP_HEADER_LOCATION "Location"
866/* Standard. RFC7231, Section 5.1.2 */
867#define MHD_HTTP_HEADER_MAX_FORWARDS "Max-Forwards"
868/* Standard. RFC7231, Appendix A.1 */
869#define MHD_HTTP_HEADER_MIME_VERSION "MIME-Version"
870/* Standard. RFC7234, Section 5.4 */
871#define MHD_HTTP_HEADER_PRAGMA "Pragma"
872/* Standard. RFC7235, Section 4.3 */
873#define MHD_HTTP_HEADER_PROXY_AUTHENTICATE "Proxy-Authenticate"
874/* Standard. RFC7235, Section 4.4 */
875#define MHD_HTTP_HEADER_PROXY_AUTHORIZATION "Proxy-Authorization"
876/* Standard. RFC7233, Section 3.1 */
877#define MHD_HTTP_HEADER_RANGE "Range"
878/* Standard. RFC7231, Section 5.5.2 */
879#define MHD_HTTP_HEADER_REFERER "Referer"
880/* Standard. RFC7231, Section 7.1.3 */
881#define MHD_HTTP_HEADER_RETRY_AFTER "Retry-After"
882/* Standard. RFC7231, Section 7.4.2 */
883#define MHD_HTTP_HEADER_SERVER "Server"
884/* Standard. RFC7230, Section 4.3 */
885#define MHD_HTTP_HEADER_TE "TE"
886/* Standard. RFC7230, Section 4.4 */
887#define MHD_HTTP_HEADER_TRAILER "Trailer"
888/* Standard. RFC7230, Section 3.3.1 */
889#define MHD_HTTP_HEADER_TRANSFER_ENCODING "Transfer-Encoding"
890/* Standard. RFC7230, Section 6.7 */
891#define MHD_HTTP_HEADER_UPGRADE "Upgrade"
892/* Standard. RFC7231, Section 5.5.3 */
893#define MHD_HTTP_HEADER_USER_AGENT "User-Agent"
894/* Standard. RFC7231, Section 7.1.4 */
895#define MHD_HTTP_HEADER_VARY "Vary"
896/* Standard. RFC7230, Section 5.7.1 */
897#define MHD_HTTP_HEADER_VIA "Via"
898/* Standard. RFC7235, Section 4.1 */
899#define MHD_HTTP_HEADER_WWW_AUTHENTICATE "WWW-Authenticate"
900/* Standard. RFC7234, Section 5.5 */
901#define MHD_HTTP_HEADER_WARNING "Warning"
902
903/* Additional HTTP headers. */
904/* No category. RFC4229 */
905#define MHD_HTTP_HEADER_A_IM "A-IM"
906/* No category. RFC4229 */
907#define MHD_HTTP_HEADER_ACCEPT_ADDITIONS "Accept-Additions"
908/* Informational. RFC7089 */
909#define MHD_HTTP_HEADER_ACCEPT_DATETIME "Accept-Datetime"
910/* No category. RFC4229 */
911#define MHD_HTTP_HEADER_ACCEPT_FEATURES "Accept-Features"
912/* No category. RFC5789 */
913#define MHD_HTTP_HEADER_ACCEPT_PATCH "Accept-Patch"
914/* Standard. RFC7639, Section 2 */
915#define MHD_HTTP_HEADER_ALPN "ALPN"
916/* Standard. RFC7838 */
917#define MHD_HTTP_HEADER_ALT_SVC "Alt-Svc"
918/* Standard. RFC7838 */
919#define MHD_HTTP_HEADER_ALT_USED "Alt-Used"
920/* No category. RFC4229 */
921#define MHD_HTTP_HEADER_ALTERNATES "Alternates"
922/* No category. RFC4437 */
923#define MHD_HTTP_HEADER_APPLY_TO_REDIRECT_REF "Apply-To-Redirect-Ref"
924/* Experimental. RFC8053, Section 4 */
925#define MHD_HTTP_HEADER_AUTHENTICATION_CONTROL "Authentication-Control"
926/* Standard. RFC7615, Section 3 */
927#define MHD_HTTP_HEADER_AUTHENTICATION_INFO "Authentication-Info"
928/* No category. RFC4229 */
929#define MHD_HTTP_HEADER_C_EXT "C-Ext"
930/* No category. RFC4229 */
931#define MHD_HTTP_HEADER_C_MAN "C-Man"
932/* No category. RFC4229 */
933#define MHD_HTTP_HEADER_C_OPT "C-Opt"
934/* No category. RFC4229 */
935#define MHD_HTTP_HEADER_C_PEP "C-PEP"
936/* No category. RFC4229 */
937#define MHD_HTTP_HEADER_C_PEP_INFO "C-PEP-Info"
938/* Standard. RFC7809, Section 7.1 */
939#define MHD_HTTP_HEADER_CALDAV_TIMEZONES "CalDAV-Timezones"
940/* Obsoleted. RFC2068; RFC2616 */
941#define MHD_HTTP_HEADER_CONTENT_BASE "Content-Base"
942/* Standard. RFC6266 */
943#define MHD_HTTP_HEADER_CONTENT_DISPOSITION "Content-Disposition"
944/* No category. RFC4229 */
945#define MHD_HTTP_HEADER_CONTENT_ID "Content-ID"
946/* No category. RFC4229 */
947#define MHD_HTTP_HEADER_CONTENT_MD5 "Content-MD5"
948/* No category. RFC4229 */
949#define MHD_HTTP_HEADER_CONTENT_SCRIPT_TYPE "Content-Script-Type"
950/* No category. RFC4229 */
951#define MHD_HTTP_HEADER_CONTENT_STYLE_TYPE "Content-Style-Type"
952/* No category. RFC4229 */
953#define MHD_HTTP_HEADER_CONTENT_VERSION "Content-Version"
954/* Standard. RFC6265 */
955#define MHD_HTTP_HEADER_COOKIE "Cookie"
956/* Obsoleted. RFC2965; RFC6265 */
957#define MHD_HTTP_HEADER_COOKIE2 "Cookie2"
958/* Standard. RFC5323 */
959#define MHD_HTTP_HEADER_DASL "DASL"
960/* Standard. RFC4918 */
961#define MHD_HTTP_HEADER_DAV "DAV"
962/* No category. RFC4229 */
963#define MHD_HTTP_HEADER_DEFAULT_STYLE "Default-Style"
964/* No category. RFC4229 */
965#define MHD_HTTP_HEADER_DELTA_BASE "Delta-Base"
966/* Standard. RFC4918 */
967#define MHD_HTTP_HEADER_DEPTH "Depth"
968/* No category. RFC4229 */
969#define MHD_HTTP_HEADER_DERIVED_FROM "Derived-From"
970/* Standard. RFC4918 */
971#define MHD_HTTP_HEADER_DESTINATION "Destination"
972/* No category. RFC4229 */
973#define MHD_HTTP_HEADER_DIFFERENTIAL_ID "Differential-ID"
974/* No category. RFC4229 */
975#define MHD_HTTP_HEADER_DIGEST "Digest"
976/* No category. RFC4229 */
977#define MHD_HTTP_HEADER_EXT "Ext"
978/* Standard. RFC7239 */
979#define MHD_HTTP_HEADER_FORWARDED "Forwarded"
980/* No category. RFC4229 */
981#define MHD_HTTP_HEADER_GETPROFILE "GetProfile"
982/* Experimental. RFC7486, Section 6.1.1 */
983#define MHD_HTTP_HEADER_HOBAREG "Hobareg"
984/* Standard. RFC7540, Section 3.2.1 */
985#define MHD_HTTP_HEADER_HTTP2_SETTINGS "HTTP2-Settings"
986/* No category. RFC4229 */
987#define MHD_HTTP_HEADER_IM "IM"
988/* Standard. RFC4918 */
989#define MHD_HTTP_HEADER_IF "If"
990/* Standard. RFC6638 */
991#define MHD_HTTP_HEADER_IF_SCHEDULE_TAG_MATCH "If-Schedule-Tag-Match"
992/* No category. RFC4229 */
993#define MHD_HTTP_HEADER_KEEP_ALIVE "Keep-Alive"
994/* No category. RFC4229 */
995#define MHD_HTTP_HEADER_LABEL "Label"
996/* No category. RFC5988 */
997#define MHD_HTTP_HEADER_LINK "Link"
998/* Standard. RFC4918 */
999#define MHD_HTTP_HEADER_LOCK_TOKEN "Lock-Token"
1000/* No category. RFC4229 */
1001#define MHD_HTTP_HEADER_MAN "Man"
1002/* Informational. RFC7089 */
1003#define MHD_HTTP_HEADER_MEMENTO_DATETIME "Memento-Datetime"
1004/* No category. RFC4229 */
1005#define MHD_HTTP_HEADER_METER "Meter"
1006/* No category. RFC4229 */
1007#define MHD_HTTP_HEADER_NEGOTIATE "Negotiate"
1008/* No category. RFC4229 */
1009#define MHD_HTTP_HEADER_OPT "Opt"
1010/* Experimental. RFC8053, Section 3 */
1011#define MHD_HTTP_HEADER_OPTIONAL_WWW_AUTHENTICATE "Optional-WWW-Authenticate"
1012/* Standard. RFC4229 */
1013#define MHD_HTTP_HEADER_ORDERING_TYPE "Ordering-Type"
1014/* Standard. RFC6454 */
1015#define MHD_HTTP_HEADER_ORIGIN "Origin"
1016/* Standard. RFC4918 */
1017#define MHD_HTTP_HEADER_OVERWRITE "Overwrite"
1018/* No category. RFC4229 */
1019#define MHD_HTTP_HEADER_P3P "P3P"
1020/* No category. RFC4229 */
1021#define MHD_HTTP_HEADER_PEP "PEP"
1022/* No category. RFC4229 */
1023#define MHD_HTTP_HEADER_PICS_LABEL "PICS-Label"
1024/* No category. RFC4229 */
1025#define MHD_HTTP_HEADER_PEP_INFO "Pep-Info"
1026/* Standard. RFC4229 */
1027#define MHD_HTTP_HEADER_POSITION "Position"
1028/* Standard. RFC7240 */
1029#define MHD_HTTP_HEADER_PREFER "Prefer"
1030/* Standard. RFC7240 */
1031#define MHD_HTTP_HEADER_PREFERENCE_APPLIED "Preference-Applied"
1032/* No category. RFC4229 */
1033#define MHD_HTTP_HEADER_PROFILEOBJECT "ProfileObject"
1034/* No category. RFC4229 */
1035#define MHD_HTTP_HEADER_PROTOCOL "Protocol"
1036/* No category. RFC4229 */
1037#define MHD_HTTP_HEADER_PROTOCOL_INFO "Protocol-Info"
1038/* No category. RFC4229 */
1039#define MHD_HTTP_HEADER_PROTOCOL_QUERY "Protocol-Query"
1040/* No category. RFC4229 */
1041#define MHD_HTTP_HEADER_PROTOCOL_REQUEST "Protocol-Request"
1042/* Standard. RFC7615, Section 4 */
1043#define MHD_HTTP_HEADER_PROXY_AUTHENTICATION_INFO "Proxy-Authentication-Info"
1044/* No category. RFC4229 */
1045#define MHD_HTTP_HEADER_PROXY_FEATURES "Proxy-Features"
1046/* No category. RFC4229 */
1047#define MHD_HTTP_HEADER_PROXY_INSTRUCTION "Proxy-Instruction"
1048/* No category. RFC4229 */
1049#define MHD_HTTP_HEADER_PUBLIC "Public"
1050/* Standard. RFC7469 */
1051#define MHD_HTTP_HEADER_PUBLIC_KEY_PINS "Public-Key-Pins"
1052/* Standard. RFC7469 */
1053#define MHD_HTTP_HEADER_PUBLIC_KEY_PINS_REPORT_ONLY "Public-Key-Pins-Report-Only"
1054/* No category. RFC4437 */
1055#define MHD_HTTP_HEADER_REDIRECT_REF "Redirect-Ref"
1056/* No category. RFC4229 */
1057#define MHD_HTTP_HEADER_SAFE "Safe"
1058/* Standard. RFC6638 */
1059#define MHD_HTTP_HEADER_SCHEDULE_REPLY "Schedule-Reply"
1060/* Standard. RFC6638 */
1061#define MHD_HTTP_HEADER_SCHEDULE_TAG "Schedule-Tag"
1062/* Standard. RFC6455 */
1063#define MHD_HTTP_HEADER_SEC_WEBSOCKET_ACCEPT "Sec-WebSocket-Accept"
1064/* Standard. RFC6455 */
1065#define MHD_HTTP_HEADER_SEC_WEBSOCKET_EXTENSIONS "Sec-WebSocket-Extensions"
1066/* Standard. RFC6455 */
1067#define MHD_HTTP_HEADER_SEC_WEBSOCKET_KEY "Sec-WebSocket-Key"
1068/* Standard. RFC6455 */
1069#define MHD_HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL "Sec-WebSocket-Protocol"
1070/* Standard. RFC6455 */
1071#define MHD_HTTP_HEADER_SEC_WEBSOCKET_VERSION "Sec-WebSocket-Version"
1072/* No category. RFC4229 */
1073#define MHD_HTTP_HEADER_SECURITY_SCHEME "Security-Scheme"
1074/* Standard. RFC6265 */
1075#define MHD_HTTP_HEADER_SET_COOKIE "Set-Cookie"
1076/* Obsoleted. RFC2965; RFC6265 */
1077#define MHD_HTTP_HEADER_SET_COOKIE2 "Set-Cookie2"
1078/* No category. RFC4229 */
1079#define MHD_HTTP_HEADER_SETPROFILE "SetProfile"
1080/* Standard. RFC5023 */
1081#define MHD_HTTP_HEADER_SLUG "SLUG"
1082/* No category. RFC4229 */
1083#define MHD_HTTP_HEADER_SOAPACTION "SoapAction"
1084/* No category. RFC4229 */
1085#define MHD_HTTP_HEADER_STATUS_URI "Status-URI"
1086/* Standard. RFC6797 */
1087#define MHD_HTTP_HEADER_STRICT_TRANSPORT_SECURITY "Strict-Transport-Security"
1088/* No category. RFC4229 */
1089#define MHD_HTTP_HEADER_SURROGATE_CAPABILITY "Surrogate-Capability"
1090/* No category. RFC4229 */
1091#define MHD_HTTP_HEADER_SURROGATE_CONTROL "Surrogate-Control"
1092/* No category. RFC4229 */
1093#define MHD_HTTP_HEADER_TCN "TCN"
1094/* Standard. RFC4918 */
1095#define MHD_HTTP_HEADER_TIMEOUT "Timeout"
1096/* Standard. RFC8030, Section 5.4 */
1097#define MHD_HTTP_HEADER_TOPIC "Topic"
1098/* Standard. RFC8030, Section 5.2 */
1099#define MHD_HTTP_HEADER_TTL "TTL"
1100/* Standard. RFC8030, Section 5.3 */
1101#define MHD_HTTP_HEADER_URGENCY "Urgency"
1102/* No category. RFC4229 */
1103#define MHD_HTTP_HEADER_URI "URI"
1104/* No category. RFC4229 */
1105#define MHD_HTTP_HEADER_VARIANT_VARY "Variant-Vary"
1106/* No category. RFC4229 */
1107#define MHD_HTTP_HEADER_WANT_DIGEST "Want-Digest"
1108/* Informational. RFC7034 */
1109#define MHD_HTTP_HEADER_X_FRAME_OPTIONS "X-Frame-Options"
1110
1111/* Some provisional headers. */
1112#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN "Access-Control-Allow-Origin"
1113/** @} */ /* end of group headers */
1114
749 1115
750/** 1116/**
751 * A client has requested the given url using the given method 1117 * A client has requested the given url using the given method
@@ -1187,6 +1553,16 @@ MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon,
1187 1553
1188 1554
1189/** 1555/**
1556 * Use SHOUTcast. This will cause the response to begin
1557 * with the SHOUTcast "ICY" line instad of "HTTP".
1558 *
1559 * @param daemon daemon to set SHOUTcast option for
1560 */
1561_MHD_EXTERN void
1562MHD_daemon_enable_shoutcast (struct MHD_Daemon *daemon);
1563
1564
1565/**
1190 * Enable and configure TLS. 1566 * Enable and configure TLS.
1191 * 1567 *
1192 * @param daemon which instance should be configured 1568 * @param daemon which instance should be configured
@@ -1836,9 +2212,31 @@ enum MHD_HTTP_StatusCode {
1836 MHD_HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511 2212 MHD_HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511
1837 2213
1838}; 2214};
2215
2216
2217/**
2218 * Returns the string reason phrase for a response code.
2219 *
2220 * If we don't have a string for a status code, we give the first
2221 * message in that status code class.
2222 */
2223_MHD_EXTERN const char *
2224MHD_get_reason_phrase_for (enum MHD_HTTP_StatusCode code);
2225
1839/** @} */ /* end of group httpcode */ 2226/** @} */ /* end of group httpcode */
1840 2227
1841 2228
2229/**
2230 * @defgroup versions HTTP versions
2231 * These strings should be used to match against the first line of the
2232 * HTTP header.
2233 * @{
2234 */
2235#define MHD_HTTP_VERSION_1_0 "HTTP/1.0"
2236#define MHD_HTTP_VERSION_1_1 "HTTP/1.1"
2237
2238/** @} */ /* end of group versions */
2239
1842 2240
1843/** 2241/**
1844 * Suspend handling of network data for a given request. This can 2242 * Suspend handling of network data for a given request. This can
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index bba6b620..f982c70a 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -143,22 +143,22 @@ endif
143 143
144# TBD! 144# TBD!
145if HAVE_POSTPROCESSOR 145if HAVE_POSTPROCESSOR
146libmicrohttpd_la_SOURCES += \ 146#libmicrohttpd_la_SOURCES += \
147 postprocessor.c 147# postprocessor.c
148endif 148endif
149 149
150# TBD! 150# TBD!
151if ENABLE_DAUTH 151if ENABLE_DAUTH
152libmicrohttpd_la_SOURCES += \ 152#libmicrohttpd_la_SOURCES += \
153 digestauth.c \ 153# digestauth.c \
154 md5.c md5.h 154# md5.c md5.h
155endif 155endif
156 156
157# TBD! 157# TBD!
158if ENABLE_BAUTH 158if ENABLE_BAUTH
159libmicrohttpd_la_SOURCES += \ 159#libmicrohttpd_la_SOURCES += \
160 basicauth.c \ 160# basicauth.c \
161 base64.c base64.h 161# base64.c base64.h
162endif 162endif
163 163
164 164
diff --git a/src/lib/daemon_create.c b/src/lib/daemon_create.c
index f1042789..e124b745 100644
--- a/src/lib/daemon_create.c
+++ b/src/lib/daemon_create.c
@@ -23,6 +23,7 @@
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 */ 24 */
25#include "internal.h" 25#include "internal.h"
26#include "init.h"
26 27
27 28
28/** 29/**
@@ -95,6 +96,9 @@ MHD_daemon_create (MHD_RequestCallback cb,
95 memset (daemon, 96 memset (daemon,
96 0, 97 0,
97 sizeof (struct MHD_Daemon)); 98 sizeof (struct MHD_Daemon));
99#ifdef EPOLL_SUPPORT
100 daemon->epoll_itc_marker = "itc_marker";
101#endif
98 daemon->rc = cb; 102 daemon->rc = cb;
99 daemon->rc_cls = cb_cls; 103 daemon->rc_cls = cb_cls;
100 daemon->logger = &file_logger; 104 daemon->logger = &file_logger;
diff --git a/src/lib/daemon_destroy.c b/src/lib/daemon_destroy.c
index b1743088..1a8f7094 100644
--- a/src/lib/daemon_destroy.c
+++ b/src/lib/daemon_destroy.c
@@ -24,7 +24,63 @@
24 */ 24 */
25#include "internal.h" 25#include "internal.h"
26 26
27/* TODO: migrate logic below! */ 27
28/**
29 * Stop all worker threads from the worker pool.
30 *
31 * @param daemon master daemon controling the workers
32 */
33static void
34stop_workers (struct MHD_Daemon *daemon)
35{
36 MHD_socket fd;
37 unsigned int i;
38
39 mhd_assert (1 < daemon->worker_pool_size);
40 mhd_assert (1 < daemon->threading_model);
41 if (daemon->was_quiesced)
42 fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
43 else
44 fd = daemon->listen_socket;
45 /* Let workers shutdown in parallel. */
46 for (i = 0; i < daemon->worker_pool_size; i++)
47 {
48 daemon->worker_pool[i].shutdown = true;
49 if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
50 {
51 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc,
52 "e"))
53 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel."));
54 }
55 else
56 {
57 /* Better hope shutdown() works... */
58 mhd_assert (MHD_INVALID_SOCKET != fd);
59 }
60 }
61#ifdef HAVE_LISTEN_SHUTDOWN
62 if (MHD_INVALID_SOCKET != fd)
63 {
64 (void) shutdown (fd,
65 SHUT_RDWR);
66 }
67#endif /* HAVE_LISTEN_SHUTDOWN */
68 for (i = 0; i < daemon->worker_pool_size; ++i)
69 {
70 MHD_daemon_destroy (&daemon->worker_pool[i]);
71 }
72 free (daemon->worker_pool);
73 daemon->worker_pool = NULL;
74 /* FIXME: does this still hold? */
75 mhd_assert (MHD_ITC_IS_INVALID_(daemon->itc));
76#ifdef EPOLL_SUPPORT
77 mhd_assert (-1 == daemon->epoll_fd);
78#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
79 mhd_assert (-1 == daemon->epoll_upgrade_fd);
80#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
81#endif /* EPOLL_SUPPORT */
82}
83
28 84
29/** 85/**
30 * Shutdown and destroy an HTTP daemon. 86 * Shutdown and destroy an HTTP daemon.
@@ -36,7 +92,6 @@ void
36MHD_daemon_destroy (struct MHD_Daemon *daemon) 92MHD_daemon_destroy (struct MHD_Daemon *daemon)
37{ 93{
38 MHD_socket fd; 94 MHD_socket fd;
39 unsigned int i;
40 95
41 if (NULL == daemon) 96 if (NULL == daemon)
42 return; 97 return;
@@ -50,92 +105,60 @@ MHD_daemon_destroy (struct MHD_Daemon *daemon)
50 105
51 if (NULL != daemon->worker_pool) 106 if (NULL != daemon->worker_pool)
52 { /* Master daemon with worker pool. */ 107 { /* Master daemon with worker pool. */
53 mhd_assert (1 < daemon->worker_pool_size); 108 stop_workers (daemon);
54 mhd_assert (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD));
55
56 /* Let workers shutdown in parallel. */
57 for (i = 0; i < daemon->worker_pool_size; ++i)
58 {
59 daemon->worker_pool[i].shutdown = true;
60 if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
61 {
62 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "e"))
63 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel."));
64 }
65 else
66 mhd_assert (MHD_INVALID_SOCKET != fd);
67 }
68#ifdef HAVE_LISTEN_SHUTDOWN
69 if (MHD_INVALID_SOCKET != fd)
70 {
71 (void) shutdown (fd,
72 SHUT_RDWR);
73 }
74#endif /* HAVE_LISTEN_SHUTDOWN */
75 for (i = 0; i < daemon->worker_pool_size; ++i)
76 {
77 MHD_stop_daemon (&daemon->worker_pool[i]);
78 }
79 free (daemon->worker_pool);
80 mhd_assert (MHD_ITC_IS_INVALID_(daemon->itc));
81#ifdef EPOLL_SUPPORT
82 mhd_assert (-1 == daemon->epoll_fd);
83#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
84 mhd_assert (-1 == daemon->epoll_upgrade_fd);
85#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
86#endif /* EPOLL_SUPPORT */
87 } 109 }
88 else 110 else
89 { /* Worker daemon or single daemon. */ 111 {
90 if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) 112 mhd_assert (0 == daemon->worker_pool_size);
91 { /* Worker daemon or single daemon with internal thread(s). */ 113 /* Worker daemon or single-thread daemon. */
92 mhd_assert (0 == daemon->worker_pool_size); 114 if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_model)
93 if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options)) 115 {
116 /* Worker daemon or single daemon with internal thread(s). */
117 if (! daemon->disallow_suspend_resume)
94 resume_suspended_connections (daemon); 118 resume_suspended_connections (daemon);
95 119
96 if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) 120 /* Separate thread(s) is used for polling sockets. */
97 { 121 if (MHD_ITC_IS_VALID_(daemon->itc))
98 /* Separate thread(s) is used for polling sockets. */ 122 {
99 if (MHD_ITC_IS_VALID_(daemon->itc)) 123 if (! MHD_itc_activate_ (daemon->itc,
100 { 124 "e"))
101 if (! MHD_itc_activate_ (daemon->itc, "e")) 125 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
102 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel")); 126 }
103 } 127 else
104 else 128 {
105 {
106#ifdef HAVE_LISTEN_SHUTDOWN 129#ifdef HAVE_LISTEN_SHUTDOWN
107 if (MHD_INVALID_SOCKET != fd) 130 if (MHD_INVALID_SOCKET != fd)
108 { 131 {
109 if (NULL == daemon->master) 132 if (NULL == daemon->master)
110 (void) shutdown (fd, 133 (void) shutdown (fd,
111 SHUT_RDWR); 134 SHUT_RDWR);
112 } 135 }
113 else 136 else
114#endif /* HAVE_LISTEN_SHUTDOWN */ 137#endif /* HAVE_LISTEN_SHUTDOWN */
115 mhd_assert (false); /* Should never happen */ 138 mhd_assert (false); /* Should never happen */
116 } 139 }
117 140
118 if (! MHD_join_thread_ (daemon->pid.handle)) 141 if (! MHD_join_thread_ (daemon->pid.handle))
119 { 142 {
120 MHD_PANIC (_("Failed to join a thread\n")); 143 MHD_PANIC (_("Failed to join a thread\n"));
121 } 144 }
122 /* close_all_connections() was called in daemon thread. */ 145 /* close_all_connections() was called in daemon thread. */
123 } 146 }
124 }
125 else 147 else
126 { 148 {
127 /* No internal threads are used for polling sockets. */ 149 /* No internal threads are used for polling sockets
150 (external event loop) */
128 close_all_connections (daemon); 151 close_all_connections (daemon);
129 } 152 }
130 if (MHD_ITC_IS_VALID_ (daemon->itc)) 153 if (MHD_ITC_IS_VALID_ (daemon->itc))
131 MHD_itc_destroy_chk_ (daemon->itc); 154 MHD_itc_destroy_chk_ (daemon->itc);
132 155
133#ifdef EPOLL_SUPPORT 156#ifdef EPOLL_SUPPORT
134 if ( (0 != (daemon->options & MHD_USE_EPOLL)) && 157 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
135 (-1 != daemon->epoll_fd) ) 158 (-1 != daemon->epoll_fd) )
136 MHD_socket_close_chk_ (daemon->epoll_fd); 159 MHD_socket_close_chk_ (daemon->epoll_fd);
137#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 160#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
138 if ( (0 != (daemon->options & MHD_USE_EPOLL)) && 161 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
139 (-1 != daemon->epoll_upgrade_fd) ) 162 (-1 != daemon->epoll_upgrade_fd) )
140 MHD_socket_close_chk_ (daemon->epoll_upgrade_fd); 163 MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
141#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 164#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
@@ -154,16 +177,18 @@ MHD_daemon_destroy (struct MHD_Daemon *daemon)
154 177
155 /* TLS clean up */ 178 /* TLS clean up */
156#ifdef HTTPS_SUPPORT 179#ifdef HTTPS_SUPPORT
157 if (daemon->have_dhparams) 180 if (NULL != daemon->tls_api)
158 {
159 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
160 daemon->have_dhparams = false;
161 }
162 if (0 != (daemon->options & MHD_USE_TLS))
163 { 181 {
182#if FIXME_TLS_API
183 if (daemon->have_dhparams)
184 {
185 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
186 daemon->have_dhparams = false;
187 }
164 gnutls_priority_deinit (daemon->priority_cache); 188 gnutls_priority_deinit (daemon->priority_cache);
165 if (daemon->x509_cred) 189 if (daemon->x509_cred)
166 gnutls_certificate_free_credentials (daemon->x509_cred); 190 gnutls_certificate_free_credentials (daemon->x509_cred);
191#endif
167 } 192 }
168#endif /* HTTPS_SUPPORT */ 193#endif /* HTTPS_SUPPORT */
169 194
diff --git a/src/lib/daemon_options.c b/src/lib/daemon_options.c
index 4693b692..991b9898 100644
--- 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)
246 246
247 247
248/** 248/**
249 * Use SHOUTcast. This will cause the response to begin
250 * with the SHOUTcast "ICY" line instad of "HTTP".
251 *
252 * @param daemon daemon to set SHOUTcast option for
253 */
254_MHD_EXTERN void
255MHD_daemon_enable_shoutcast (struct MHD_Daemon *daemon)
256{
257 daemon->enable_shoutcast = true;
258}
259
260
261/**
249 * Accept connections from the given socket. Socket 262 * Accept connections from the given socket. Socket
250 * must be a TCP or UNIX domain (stream) socket. 263 * must be a TCP or UNIX domain (stream) socket.
251 * 264 *
diff --git a/src/lib/daemon_quiesce.c b/src/lib/daemon_quiesce.c
index 31104a7d..caad0a25 100644
--- a/src/lib/daemon_quiesce.c
+++ b/src/lib/daemon_quiesce.c
@@ -67,7 +67,7 @@ MHD_daemon_quiesce (struct MHD_Daemon *daemon)
67 { 67 {
68 unsigned int i; 68 unsigned int i;
69 69
70 for (i = 0; i < daemon->threading_model; i++) 70 for (i = 0; i < daemon->worker_pool_size; i++)
71 { 71 {
72 struct MHD_Daemon *worker = &daemon->worker_pool[i]; 72 struct MHD_Daemon *worker = &daemon->worker_pool[i];
73 73
diff --git a/src/lib/daemon_start.c b/src/lib/daemon_start.c
index 98126c68..ab4a6dd9 100644
--- a/src/lib/daemon_start.c
+++ b/src/lib/daemon_start.c
@@ -48,40 +48,17 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
48 48
49 /* Apply the socket options according to 49 /* Apply the socket options according to
50 listening_address_reuse. */ 50 listening_address_reuse. */
51 /* FIXME: used to be -1/0/1, now defined as a bool! 51 if (daemon->allow_address_reuse)
52 MISMATCH! */
53 if (0 == daemon->listening_address_reuse)
54 {
55#ifndef MHD_WINSOCK_SOCKETS
56 /* No user requirement, use "traditional" default SO_REUSEADDR
57 * on non-W32 platforms, and do not fail if it doesn't work.
58 * Don't use it on W32, because on W32 it will allow multiple
59 * bind to the same address:port, like SO_REUSEPORT on others. */
60 if (0 > setsockopt (listen_fd,
61 SOL_SOCKET,
62 SO_REUSEADDR,
63 (void*) &on, sizeof (on)))
64 {
65#ifdef HAVE_MESSAGES
66 MHD_DLOG (daemon,
67 MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED,
68 _("setsockopt failed: %s\n"),
69 MHD_socket_last_strerr_ ());
70#endif
71 }
72#endif /* ! MHD_WINSOCK_SOCKETS */
73 return MHD_SC_OK;
74 }
75 if (daemon->listening_address_reuse > 0)
76 { 52 {
77 /* User requested to allow reusing listening address:port. */ 53 /* User requested to allow reusing listening address:port. */
78#ifndef MHD_WINSOCK_SOCKETS 54#ifndef MHD_WINSOCK_SOCKETS
79 /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if 55 /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
80 * it doesn't work. */ 56 * it doesn't work. */
81 if (0 > setsockopt (listen_fd, 57 if (0 > setsockopt (daemon->listen_socket,
82 SOL_SOCKET, 58 SOL_SOCKET,
83 SO_REUSEADDR, 59 SO_REUSEADDR,
84 (void*)&on, sizeof (on))) 60 (void *) &on,
61 sizeof (on)))
85 { 62 {
86#ifdef HAVE_MESSAGES 63#ifdef HAVE_MESSAGES
87 MHD_DLOG (daemon, 64 MHD_DLOG (daemon,
@@ -91,6 +68,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
91#endif 68#endif
92 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED; 69 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED;
93 } 70 }
71 return MHD_SC_OK;
94#endif /* ! MHD_WINSOCK_SOCKETS */ 72#endif /* ! MHD_WINSOCK_SOCKETS */
95 /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms. 73 /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
96 * Fail if SO_REUSEPORT is not defined or setsockopt fails. 74 * Fail if SO_REUSEPORT is not defined or setsockopt fails.
@@ -98,7 +76,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
98 /* SO_REUSEADDR on W32 has the same semantics 76 /* SO_REUSEADDR on W32 has the same semantics
99 as SO_REUSEPORT on BSD/Linux */ 77 as SO_REUSEPORT on BSD/Linux */
100#if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) 78#if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
101 if (0 > setsockopt (listen_fd, 79 if (0 > setsockopt (daemon->listen_socket,
102 SOL_SOCKET, 80 SOL_SOCKET,
103#ifndef MHD_WINSOCK_SOCKETS 81#ifndef MHD_WINSOCK_SOCKETS
104 SO_REUSEPORT, 82 SO_REUSEPORT,
@@ -116,6 +94,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
116#endif 94#endif
117 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED; 95 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED;
118 } 96 }
97 return MHD_SC_OK;
119#else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ 98#else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
120 /* we're supposed to allow address:port re-use, but 99 /* we're supposed to allow address:port re-use, but
121 on this platform we cannot; fail hard */ 100 on this platform we cannot; fail hard */
@@ -128,7 +107,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
128#endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ 107#endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
129 } 108 }
130 109
131 /* if (daemon->listening_address_reuse < 0) */ 110 /* if (! daemon->allow_address_reuse) */
132 /* User requested to disallow reusing listening address:port. 111 /* User requested to disallow reusing listening address:port.
133 * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE 112 * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
134 * is used and Solaris with SO_EXCLBIND. 113 * is used and Solaris with SO_EXCLBIND.
@@ -155,6 +134,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
155#endif 134#endif
156 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED; 135 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED;
157 } 136 }
137 return MHD_SC_OK;
158#elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */ 138#elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
159#ifdef HAVE_MESSAGES 139#ifdef HAVE_MESSAGES
160 MHD_DLOG (daemon, 140 MHD_DLOG (daemon,
@@ -163,6 +143,7 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
163#endif 143#endif
164 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED; 144 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED;
165#endif /* MHD_WINSOCK_SOCKETS */ 145#endif /* MHD_WINSOCK_SOCKETS */
146 /* Not on WINSOCK, simply doing nothing will do */
166 return MHD_SC_OK; 147 return MHD_SC_OK;
167} 148}
168 149
@@ -183,81 +164,75 @@ open_listen_socket (struct MHD_Daemon *daemon)
183 int pf; 164 int pf;
184 bool use_v6; 165 bool use_v6;
185 166
186 if (MHD_INVALID_SOCKET != daemon->listen_fd) 167 if (MHD_INVALID_SOCKET != daemon->listen_socket)
187 return MHD_SC_OK; /* application opened it for us! */ 168 return MHD_SC_OK; /* application opened it for us! */
188 169
189 /* Determine address family */ 170 /* Determine address family */
190 if (MHD_AF_NONE != daemon->address_family) 171 switch (daemon->listen_af)
191 { 172 {
192 switch (daemon->address_family) 173 case MHD_AF_NONE:
174 if (0 == daemon->listen_sa_len)
193 { 175 {
194 case MHD_AF_NONE: 176 /* no listening desired, that's OK */
195 abort (); 177 return MHD_SC_OK;
196 case MHD_AF_AUTO: 178 }
197#if HAVE_INET6 179 /* we have a listen address, get AF from there! */
198 pf = PF_INET6; 180 switch (daemon->listen_sa.ss_family)
199 use_v6 = true; 181 {
200#else 182 case AF_INET:
201 pf = PF_INET; 183 pf = PF_INET;
202 use_v6 = false; 184 use_v6 = false;
203#endif
204 break;
205 case MHD_AF_INET:
206 use_v6 = false;
207 pf = PF_INET;
208 break; 185 break;
209 case MHD_AF_INET6: 186#ifdef AF_INET6
210 case MHD_AF_DUAL: 187 case AF_INET6:
211#if HAVE_INET6
212 pf = PF_INET6; 188 pf = PF_INET6;
213 use_v6 = true; 189 use_v6 = true;
214 break; 190 break;
215#else
216#ifdef HAVE_MESSAGES
217 MHD_DLOG (daemon,
218 MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD,
219 _("IPv6 not supported by this build\n"));
220#endif 191#endif
221 return MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD; 192#ifdef AF_UNIX
193 case AF_UNIX:
194 pf = PF_UNIX;
195 use_v6 = false;
196 break;
222#endif 197#endif
223 } 198 default:
224 } 199 return MHD_SC_AF_NOT_SUPPORTED_BY_BUILD;
225 else if (0 != daemon->listen_sa_len) 200 } /* switch on ss_family */
226 { 201 break; /* MHD_AF_NONE */
227 202 case MHD_AF_AUTO:
228 /* we have a listen address, get AF from there! */ 203#if HAVE_INET6
229 switch (daemon->listen_sa.ss_family) 204 pf = PF_INET6;
230 { 205 use_v6 = true;
231 case AF_INET: 206#else
232 pf = PF_INET; 207 pf = PF_INET;
233 use_v6 = false; 208 use_v6 = false;
234 break;
235#ifdef AF_INET6
236 case AF_INET6:
237 pf = PF_INET6;
238 use_v6 = true;
239 break;
240#endif 209#endif
241#ifdef AF_UNIX 210 break;
242 case AF_UNIX: 211 case MHD_AF_INET4:
243 pf = PF_UNIX; 212 use_v6 = false;
244 use_v6 = false; 213 pf = PF_INET;
214 break;
215 case MHD_AF_INET6:
216 case MHD_AF_DUAL:
217#if HAVE_INET6
218 pf = PF_INET6;
219 use_v6 = true;
220 break;
221#else
222#ifdef HAVE_MESSAGES
223 MHD_DLOG (daemon,
224 MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD,
225 _("IPv6 not supported by this build\n"));
226#endif
227 return MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD;
245#endif 228#endif
246 default:
247 return MHD_SC_AF_NOT_SUPPORTED_BY_BUILD;
248 }
249 }
250 else
251 {
252 /* no listening desired, that's OK */
253 return MHD_SC_OK;
254 } 229 }
255 230
256 /* try to open listen socket */ 231 /* try to open listen socket */
257 try_open_listen_socket: 232 try_open_listen_socket:
258 daemon->listen_socket = MHD_socket_create_listen_(pf); 233 daemon->listen_socket = MHD_socket_create_listen_(pf);
259 if ( (MHD_INVALID_SOCKET == daemon->listen_socket) && 234 if ( (MHD_INVALID_SOCKET == daemon->listen_socket) &&
260 (MHD_AF_AUTO == daemon->address_family) && 235 (MHD_AF_AUTO == daemon->listen_af) &&
261 (use_v6) ) 236 (use_v6) )
262 { 237 {
263 use_v6 = false; 238 use_v6 = false;
@@ -288,8 +263,8 @@ open_listen_socket (struct MHD_Daemon *daemon)
288 and may also be missing on older POSIX systems; good luck if you have any of those, 263 and may also be missing on older POSIX systems; good luck if you have any of those,
289 your IPv6 socket may then also bind against IPv4 anyway... */ 264 your IPv6 socket may then also bind against IPv4 anyway... */
290 const MHD_SCKT_OPT_BOOL_ v6_only = 265 const MHD_SCKT_OPT_BOOL_ v6_only =
291 (MHD_AF_INET6 == daemon->address_family); 266 (MHD_AF_INET6 == daemon->listen_af);
292 if (0 > setsockopt (listen_fd, 267 if (0 > setsockopt (daemon->listen_socket,
293 IPPROTO_IPV6, 268 IPPROTO_IPV6,
294 IPV6_V6ONLY, 269 IPV6_V6ONLY,
295 (const void *) &v6_only, 270 (const void *) &v6_only,
@@ -315,7 +290,7 @@ open_listen_socket (struct MHD_Daemon *daemon)
315 if (0 != daemon->listen_sa_len) 290 if (0 != daemon->listen_sa_len)
316 { 291 {
317 /* Bind address explicitly given */ 292 /* Bind address explicitly given */
318 sa = daemon->listen_sa; 293 sa = (const struct sockaddr *) &daemon->listen_sa;
319 addrlen = daemon->listen_sa_len; 294 addrlen = daemon->listen_sa_len;
320 } 295 }
321 else 296 else
@@ -359,7 +334,7 @@ open_listen_socket (struct MHD_Daemon *daemon)
359 sin4->sin_len = sizeof (struct sockaddr_in); 334 sin4->sin_len = sizeof (struct sockaddr_in);
360#endif 335#endif
361 } 336 }
362 sa = (const struct sockaddr *) ss; 337 sa = (const struct sockaddr *) &ss;
363 } 338 }
364 339
365 /* actually do the bind() */ 340 /* actually do the bind() */
@@ -374,13 +349,13 @@ open_listen_socket (struct MHD_Daemon *daemon)
374 { 349 {
375 case AF_INET: 350 case AF_INET:
376 if (addrlen == sizeof (struct sockaddr_in)) 351 if (addrlen == sizeof (struct sockaddr_in))
377 port = ntohs (((const struct sockaddr_in*)sa)->sin_port); 352 port = ntohs (((const struct sockaddr_in *) sa)->sin_port);
378 else 353 else
379 port = UINT16_MAX + 1; /* indicate size error */ 354 port = UINT16_MAX + 1; /* indicate size error */
380 break; 355 break;
381 case AF_INET6: 356 case AF_INET6:
382 if (addrlen == sizeof (struct sockaddr_in6)) 357 if (addrlen == sizeof (struct sockaddr_in6))
383 port = ntohs (((const struct sockaddr_in6*)sa)->sin_port); 358 port = ntohs (((const struct sockaddr_in6 *) sa)->sin6_port);
384 else 359 else
385 port = UINT16_MAX + 1; /* indicate size error */ 360 port = UINT16_MAX + 1; /* indicate size error */
386 break; 361 break;
@@ -404,8 +379,8 @@ open_listen_socket (struct MHD_Daemon *daemon)
404 if (0 != setsockopt (daemon->listen_socket, 379 if (0 != setsockopt (daemon->listen_socket,
405 IPPROTO_TCP, 380 IPPROTO_TCP,
406 TCP_FASTOPEN, 381 TCP_FASTOPEN,
407 &daemon->fastopen_queue_size, 382 &daemon->fo_queue_length,
408 sizeof (daemon->fastopen_queue_size))) 383 sizeof (daemon->fo_queue_length)))
409 { 384 {
410#ifdef HAVE_MESSAGES 385#ifdef HAVE_MESSAGES
411 MHD_DLOG (daemon, 386 MHD_DLOG (daemon,
@@ -421,7 +396,7 @@ open_listen_socket (struct MHD_Daemon *daemon)
421 396
422 /* setup listening */ 397 /* setup listening */
423 if (0 > listen (daemon->listen_socket, 398 if (0 > listen (daemon->listen_socket,
424 daemon->listen_backlog_size)) 399 daemon->listen_backlog))
425 { 400 {
426#ifdef HAVE_MESSAGES 401#ifdef HAVE_MESSAGES
427 MHD_DLOG (daemon, 402 MHD_DLOG (daemon,
@@ -449,7 +424,7 @@ get_listen_port_number (struct MHD_Daemon *daemon)
449 struct sockaddr_storage servaddr; 424 struct sockaddr_storage servaddr;
450 socklen_t addrlen; 425 socklen_t addrlen;
451 426
452 if ( (0 != daemon->port) || 427 if ( (0 != daemon->listen_port) ||
453 (MHD_INVALID_SOCKET == daemon->listen_socket) ) 428 (MHD_INVALID_SOCKET == daemon->listen_socket) )
454 return; /* nothing to be done */ 429 return; /* nothing to be done */
455 430
@@ -487,7 +462,7 @@ get_listen_port_number (struct MHD_Daemon *daemon)
487 { 462 {
488 struct sockaddr_in *s4 = (struct sockaddr_in *) &servaddr; 463 struct sockaddr_in *s4 = (struct sockaddr_in *) &servaddr;
489 464
490 daemon->port = ntohs (s4->sin_port); 465 daemon->listen_port = ntohs (s4->sin_port);
491 break; 466 break;
492 } 467 }
493#ifdef HAVE_INET6 468#ifdef HAVE_INET6
@@ -495,13 +470,13 @@ get_listen_port_number (struct MHD_Daemon *daemon)
495 { 470 {
496 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &servaddr; 471 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &servaddr;
497 472
498 daemon->port = ntohs(s6->sin6_port); 473 daemon->listen_port = ntohs(s6->sin6_port);
499 break; 474 break;
500 } 475 }
501#endif /* HAVE_INET6 */ 476#endif /* HAVE_INET6 */
502#ifdef AF_UNIX 477#ifdef AF_UNIX
503 case AF_UNIX: 478 case AF_UNIX:
504 daemon->port = 0; /* special value for UNIX domain sockets */ 479 daemon->listen_port = 0; /* special value for UNIX domain sockets */
505 break; 480 break;
506#endif 481#endif
507 default: 482 default:
@@ -510,12 +485,57 @@ get_listen_port_number (struct MHD_Daemon *daemon)
510 MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF, 485 MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF,
511 _("Unknown address family!\n")); 486 _("Unknown address family!\n"));
512#endif 487#endif
513 daemon->port = 0; /* ugh */ 488 daemon->listen_port = 0; /* ugh */
514 break; 489 break;
515 } 490 }
516} 491}
517 492
518 493
494#ifdef EPOLL_SUPPORT
495/**
496 * Setup file descriptor to be used for epoll() control.
497 *
498 * @param daemon the daemon to setup epoll FD for
499 * @return the epoll() fd to use
500 */
501static int
502setup_epoll_fd (struct MHD_Daemon *daemon)
503{
504 int fd;
505
506#ifndef HAVE_MESSAGES
507 (void)daemon; /* Mute compiler warning. */
508#endif /* ! HAVE_MESSAGES */
509
510#ifdef USE_EPOLL_CREATE1
511 fd = epoll_create1 (EPOLL_CLOEXEC);
512#else /* ! USE_EPOLL_CREATE1 */
513 fd = epoll_create (MAX_EVENTS);
514#endif /* ! USE_EPOLL_CREATE1 */
515 if (MHD_INVALID_SOCKET == fd)
516 {
517#ifdef HAVE_MESSAGES
518 MHD_DLOG (daemon,
519 MHD_SC_EPOLL_CTL_CREATE_FAILED,
520 _("Call to epoll_create1 failed: %s\n"),
521 MHD_socket_last_strerr_ ());
522#endif
523 return MHD_INVALID_SOCKET;
524 }
525#if !defined(USE_EPOLL_CREATE1)
526 if (! MHD_socket_noninheritable_ (fd))
527 {
528#ifdef HAVE_MESSAGES
529 MHD_DLOG (daemon,
530 MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED,
531 _("Failed to set noninheritable mode on epoll FD.\n"));
532#endif
533 }
534#endif /* ! USE_EPOLL_CREATE1 */
535 return fd;
536}
537
538
519/** 539/**
520 * Setup epoll() FD for the daemon and initialize it to listen 540 * Setup epoll() FD for the daemon and initialize it to listen
521 * on the listen FD. 541 * on the listen FD.
@@ -536,14 +556,14 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
536 if (-1 == daemon->epoll_fd) 556 if (-1 == daemon->epoll_fd)
537 return MHD_NO; 557 return MHD_NO;
538#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 558#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
539 if (0 != (MHD_ALLOW_UPGRADE & daemon->options)) 559 if (! daemon->disallow_upgrade)
540 { 560 {
541 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon); 561 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
542 if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd) 562 if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
543 return MHD_NO; 563 return MHD_NO;
544 } 564 }
545#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 565#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
546 if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_fd)) || 566 if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_socket)) ||
547 (daemon->was_quiesced) ) 567 (daemon->was_quiesced) )
548 return MHD_YES; /* non-listening daemon */ 568 return MHD_YES; /* non-listening daemon */
549 event.events = EPOLLIN; 569 event.events = EPOLLIN;
@@ -555,6 +575,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
555 { 575 {
556#ifdef HAVE_MESSAGES 576#ifdef HAVE_MESSAGES
557 MHD_DLOG (daemon, 577 MHD_DLOG (daemon,
578 MHD_SC_EPOLL_CTL_ADD_FAILED,
558 _("Call to epoll_ctl failed: %s\n"), 579 _("Call to epoll_ctl failed: %s\n"),
559 MHD_socket_last_strerr_ ()); 580 MHD_socket_last_strerr_ ());
560#endif 581#endif
@@ -564,7 +585,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
564 if (MHD_ITC_IS_VALID_(daemon->itc)) 585 if (MHD_ITC_IS_VALID_(daemon->itc))
565 { 586 {
566 event.events = EPOLLIN; 587 event.events = EPOLLIN;
567 event.data.ptr = (void *) epoll_itc_marker; 588 event.data.ptr = (void *) daemon->epoll_itc_marker;
568 if (0 != epoll_ctl (daemon->epoll_fd, 589 if (0 != epoll_ctl (daemon->epoll_fd,
569 EPOLL_CTL_ADD, 590 EPOLL_CTL_ADD,
570 MHD_itc_r_fd_ (daemon->itc), 591 MHD_itc_r_fd_ (daemon->itc),
@@ -572,6 +593,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
572 { 593 {
573#ifdef HAVE_MESSAGES 594#ifdef HAVE_MESSAGES
574 MHD_DLOG (daemon, 595 MHD_DLOG (daemon,
596 MHD_SC_EPOLL_CTL_ADD_FAILED,
575 _("Call to epoll_ctl failed: %s\n"), 597 _("Call to epoll_ctl failed: %s\n"),
576 MHD_socket_last_strerr_ ()); 598 MHD_socket_last_strerr_ ());
577#endif 599#endif
@@ -647,7 +669,7 @@ setup_thread_pool (struct MHD_Daemon *daemon)
647 / daemon->threading_model; 669 / daemon->threading_model;
648 unsigned int leftover_conns = daemon->global_connection_limit 670 unsigned int leftover_conns = daemon->global_connection_limit
649 % daemon->threading_model; 671 % daemon->threading_model;
650 unsigned int i; 672 int i;
651 enum MHD_StatusCode sc; 673 enum MHD_StatusCode sc;
652 674
653 /* Allocate memory for pooled objects */ 675 /* Allocate memory for pooled objects */
@@ -675,7 +697,7 @@ setup_thread_pool (struct MHD_Daemon *daemon)
675 * Thread indexes in [0, leftover_conns) each get one of the 697 * Thread indexes in [0, leftover_conns) each get one of the
676 * leftover connections. */ 698 * leftover connections. */
677 d->global_connection_limit = conns_per_thread; 699 d->global_connection_limit = conns_per_thread;
678 if (i < leftover_conns) 700 if (((unsigned int) i) < leftover_conns)
679 ++d->global_connection_limit; 701 ++d->global_connection_limit;
680 702
681 if (! daemon->disable_itc) 703 if (! daemon->disable_itc)
@@ -733,7 +755,7 @@ setup_thread_pool (struct MHD_Daemon *daemon)
733 /* Spawn the worker thread */ 755 /* Spawn the worker thread */
734 if (! MHD_create_named_thread_ (&d->pid, 756 if (! MHD_create_named_thread_ (&d->pid,
735 "MHD-worker", 757 "MHD-worker",
736 daemon->thread_stack_size, 758 daemon->thread_stack_limit_b,
737 &MHD_polling_thread, 759 &MHD_polling_thread,
738 d)) 760 d))
739 { 761 {
@@ -909,9 +931,9 @@ MHD_daemon_start (struct MHD_Daemon *daemon)
909 (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_model) 931 (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_model)
910 ? "MHD-listen" 932 ? "MHD-listen"
911 : "MHD-single", 933 : "MHD-single",
912 daemon->thread_stack_size, 934 daemon->thread_stack_limit_b,
913 &MHD_polling_thread, 935 &MHD_polling_thread,
914 daemon) ) 936 daemon) ) )
915 { 937 {
916#ifdef HAVE_MESSAGES 938#ifdef HAVE_MESSAGES
917 MHD_DLOG (daemon, 939 MHD_DLOG (daemon,
@@ -928,7 +950,10 @@ MHD_daemon_start (struct MHD_Daemon *daemon)
928 (MHD_INVALID_SOCKET != daemon->listen_socket) && 950 (MHD_INVALID_SOCKET != daemon->listen_socket) &&
929 (MHD_SC_OK != (sc = setup_thread_pool (daemon))) ) 951 (MHD_SC_OK != (sc = setup_thread_pool (daemon))) )
930 return sc; 952 return sc;
931 953
954 /* make sure we know our listen port (if any) */
955 get_listen_port_number (daemon);
956
932 return MHD_SC_OK; 957 return MHD_SC_OK;
933} 958}
934 959
diff --git a/src/lib/init.c b/src/lib/init.c
index 96b0cbec..cea006e8 100644
--- a/src/lib/init.c
+++ b/src/lib/init.c
@@ -119,6 +119,37 @@ MHD_check_global_init_ (void)
119 119
120 120
121/** 121/**
122 * Default implementation of the panic function,
123 * prints an error message and aborts.
124 *
125 * @param cls unused
126 * @param file name of the file with the problem
127 * @param line line number with the problem
128 * @param reason error message with details
129 */
130static void
131mhd_panic_std (void *cls,
132 const char *file,
133 unsigned int line,
134 const char *reason)
135{
136 (void)cls; /* Mute compiler warning. */
137#ifdef HAVE_MESSAGES
138 fprintf (stderr,
139 _("Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
140 file,
141 line,
142 reason);
143#else /* ! HAVE_MESSAGES */
144 (void)file; /* Mute compiler warning. */
145 (void)line; /* Mute compiler warning. */
146 (void)reason; /* Mute compiler warning. */
147#endif
148 abort ();
149}
150
151
152/**
122 * Initialize do setup work. 153 * Initialize do setup work.
123 */ 154 */
124void 155void
diff --git a/src/lib/internal.c b/src/lib/internal.c
index 4422d9ed..4ea0503d 100644
--- a/src/lib/internal.c
+++ b/src/lib/internal.c
@@ -173,8 +173,8 @@ MHD_http_unescape (char *val)
173 * Parse and unescape the arguments given by the client 173 * Parse and unescape the arguments given by the client
174 * as part of the HTTP request URI. 174 * as part of the HTTP request URI.
175 * 175 *
176 * @param request request to add headers to
176 * @param kind header kind to pass to @a cb 177 * @param kind header kind to pass to @a cb
177 * @param connection connection to add headers to
178 * @param[in,out] args argument URI string (after "?" in URI), 178 * @param[in,out] args argument URI string (after "?" in URI),
179 * clobbered in the process! 179 * clobbered in the process!
180 * @param cb function to call on each key-value pair found 180 * @param cb function to call on each key-value pair found
@@ -184,13 +184,13 @@ MHD_http_unescape (char *val)
184 * returned #MHD_YES) 184 * returned #MHD_YES)
185 */ 185 */
186int 186int
187MHD_parse_arguments_ (struct MHD_Connection *connection, 187MHD_parse_arguments_ (struct MHD_Request *request,
188 enum MHD_ValueKind kind, 188 enum MHD_ValueKind kind,
189 char *args, 189 char *args,
190 MHD_ArgumentIterator_ cb, 190 MHD_ArgumentIterator_ cb,
191 unsigned int *num_headers) 191 unsigned int *num_headers)
192{ 192{
193 struct MHD_Daemon *daemon = connection->daemon; 193 struct MHD_Daemon *daemon = request->daemon;
194 char *equals; 194 char *equals;
195 char *amper; 195 char *amper;
196 196
@@ -208,9 +208,9 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
208 /* last argument, without '=' */ 208 /* last argument, without '=' */
209 MHD_unescape_plus (args); 209 MHD_unescape_plus (args);
210 daemon->unescape_cb (daemon->unescape_cb_cls, 210 daemon->unescape_cb (daemon->unescape_cb_cls,
211 connection, 211 request,
212 args); 212 args);
213 if (MHD_YES != cb (connection, 213 if (MHD_YES != cb (request,
214 args, 214 args,
215 NULL, 215 NULL,
216 kind)) 216 kind))
@@ -223,13 +223,13 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
223 equals++; 223 equals++;
224 MHD_unescape_plus (args); 224 MHD_unescape_plus (args);
225 daemon->unescape_cb (daemon->unescape_cb_cls, 225 daemon->unescape_cb (daemon->unescape_cb_cls,
226 connection, 226 request,
227 args); 227 args);
228 MHD_unescape_plus (equals); 228 MHD_unescape_plus (equals);
229 daemon->unescape_cb (daemon->unescape_cb_cls, 229 daemon->unescape_cb (daemon->unescape_cb_cls,
230 connection, 230 request,
231 equals); 231 equals);
232 if (MHD_YES != cb (connection, 232 if (MHD_YES != cb (request,
233 args, 233 args,
234 equals, 234 equals,
235 kind)) 235 kind))
@@ -246,9 +246,9 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
246 /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */ 246 /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
247 MHD_unescape_plus (args); 247 MHD_unescape_plus (args);
248 daemon->unescape_cb (daemon->unescape_cb_cls, 248 daemon->unescape_cb (daemon->unescape_cb_cls,
249 connection, 249 request,
250 args); 250 args);
251 if (MHD_YES != cb (connection, 251 if (MHD_YES != cb (request,
252 args, 252 args,
253 NULL, 253 NULL,
254 kind)) 254 kind))
@@ -264,13 +264,13 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
264 equals++; 264 equals++;
265 MHD_unescape_plus (args); 265 MHD_unescape_plus (args);
266 daemon->unescape_cb (daemon->unescape_cb_cls, 266 daemon->unescape_cb (daemon->unescape_cb_cls,
267 connection, 267 request,
268 args); 268 args);
269 MHD_unescape_plus (equals); 269 MHD_unescape_plus (equals);
270 daemon->unescape_cb (daemon->unescape_cb_cls, 270 daemon->unescape_cb (daemon->unescape_cb_cls,
271 connection, 271 request,
272 equals); 272 equals);
273 if (MHD_YES != cb (connection, 273 if (MHD_YES != cb (request,
274 args, 274 args,
275 equals, 275 equals,
276 kind)) 276 kind))
diff --git a/src/lib/internal.h b/src/lib/internal.h
index 4ea6528a..5b147df8 100644
--- a/src/lib/internal.h
+++ b/src/lib/internal.h
@@ -33,6 +33,7 @@
33#include "microhttpd_tls.h" 33#include "microhttpd_tls.h"
34#include "mhd_assert.h" 34#include "mhd_assert.h"
35#include "mhd_compat.h" 35#include "mhd_compat.h"
36#include "mhd_itc.h"
36#include "mhd_mono_clock.h" 37#include "mhd_mono_clock.h"
37#include "memorypool.h" 38#include "memorypool.h"
38 39
@@ -1011,6 +1012,13 @@ struct MHD_Daemon
1011 */ 1012 */
1012 struct MHD_Connection *eready_tail; 1013 struct MHD_Connection *eready_tail;
1013 1014
1015#ifdef EPOLL_SUPPORT
1016 /**
1017 * Pointer to marker used to indicate ITC slot in epoll sets.
1018 */
1019 const char *epoll_itc_marker;
1020#endif
1021
1014#ifdef UPGRADE_SUPPORT 1022#ifdef UPGRADE_SUPPORT
1015 /** 1023 /**
1016 * Head of EDLL of upgraded connections ready for processing (in epoll mode). 1024 * Head of EDLL of upgraded connections ready for processing (in epoll mode).
@@ -1052,6 +1060,11 @@ struct MHD_Daemon
1052 unsigned int nonce_nc_size; 1060 unsigned int nonce_nc_size;
1053 1061
1054#endif 1062#endif
1063
1064 /**
1065 * The select thread handle (if we have internal select)
1066 */
1067 MHD_thread_handle_ID_ pid;
1055 1068
1056 /** 1069 /**
1057 * Socket address to bind to for the listen socket. 1070 * Socket address to bind to for the listen socket.
@@ -1286,12 +1299,22 @@ struct MHD_Daemon
1286 bool enable_turbo; 1299 bool enable_turbo;
1287 1300
1288 /** 1301 /**
1302 * MHD_daemon_quiesce() was run against this daemon.
1303 */
1304 bool was_quiesced;
1305
1306 /**
1289 * Allow reusing the address:port combination when binding. 1307 * Allow reusing the address:port combination when binding.
1290 * See #MHD_daemon_listen_allow_address_reuse(). 1308 * See #MHD_daemon_listen_allow_address_reuse().
1291 */ 1309 */
1292 bool allow_address_reuse; 1310 bool allow_address_reuse;
1293 1311
1294 /** 1312 /**
1313 * MHD should speak SHOUTcast instead of HTTP.
1314 */
1315 bool enable_shoutcast;
1316
1317 /**
1295 * Are we shutting down? 1318 * Are we shutting down?
1296 */ 1319 */
1297 volatile bool shutdown; 1320 volatile bool shutdown;
@@ -1463,7 +1486,7 @@ struct MHD_Response
1463 * Callback invoked when iterating over @a key / @a value 1486 * Callback invoked when iterating over @a key / @a value
1464 * argument pairs during parsing. 1487 * argument pairs during parsing.
1465 * 1488 *
1466 * @param connection context of the iteration 1489 * @param request context of the iteration
1467 * @param key 0-terminated key string, never NULL 1490 * @param key 0-terminated key string, never NULL
1468 * @param value 0-terminated value string, may be NULL 1491 * @param value 0-terminated value string, may be NULL
1469 * @param kind origin of the key-value pair 1492 * @param kind origin of the key-value pair
@@ -1471,7 +1494,7 @@ struct MHD_Response
1471 * #MHD_NO to signal failure (and abort iteration) 1494 * #MHD_NO to signal failure (and abort iteration)
1472 */ 1495 */
1473typedef int 1496typedef int
1474(*MHD_ArgumentIterator_)(struct MHD_Connection *connection, 1497(*MHD_ArgumentIterator_)(struct MHD_Request *request,
1475 const char *key, 1498 const char *key,
1476 const char *value, 1499 const char *value,
1477 enum MHD_ValueKind kind); 1500 enum MHD_ValueKind kind);
@@ -1481,8 +1504,8 @@ typedef int
1481 * Parse and unescape the arguments given by the client 1504 * Parse and unescape the arguments given by the client
1482 * as part of the HTTP request URI. 1505 * as part of the HTTP request URI.
1483 * 1506 *
1507 * @param request request to add headers to
1484 * @param kind header kind to pass to @a cb 1508 * @param kind header kind to pass to @a cb
1485 * @param connection connection to add headers to
1486 * @param[in,out] args argument URI string (after "?" in URI), 1509 * @param[in,out] args argument URI string (after "?" in URI),
1487 * clobbered in the process! 1510 * clobbered in the process!
1488 * @param cb function to call on each key-value pair found 1511 * @param cb function to call on each key-value pair found
@@ -1492,7 +1515,7 @@ typedef int
1492 * returned #MHD_YES) 1515 * returned #MHD_YES)
1493 */ 1516 */
1494int 1517int
1495MHD_parse_arguments_ (struct MHD_Connection *connection, 1518MHD_parse_arguments_ (struct MHD_Request *request,
1496 enum MHD_ValueKind kind, 1519 enum MHD_ValueKind kind,
1497 char *args, 1520 char *args,
1498 MHD_ArgumentIterator_ cb, 1521 MHD_ArgumentIterator_ cb,
diff --git a/src/lib/reason_phrase.c b/src/lib/reason_phrase.c
new file mode 100644
index 00000000..97ace0a3
--- /dev/null
+++ b/src/lib/reason_phrase.c
@@ -0,0 +1,182 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2007, 2011, 2017 Christian Grothoff, Karlson2k (Evgeny Grin)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19*/
20/**
21 * @file reason_phrase.c
22 * @brief Tables of the string response phrases
23 * @author Elliot Glaysher
24 * @author Christian Grothoff (minor code clean up)
25 * @author Karlson2k (Evgeny Grin)
26 */
27#include "internal.h"
28
29#ifndef NULL
30#define NULL ((void*)0)
31#endif
32
33static const char *const invalid_hundred[] = {
34 NULL
35};
36
37static const char *const one_hundred[] = {
38 "Continue",
39 "Switching Protocols",
40 "Processing"
41};
42
43static const char *const two_hundred[] = {
44 "OK",
45 "Created",
46 "Accepted",
47 "Non-Authoritative Information",
48 "No Content",
49 "Reset Content",
50 "Partial Content",
51 "Multi-Status",
52 "Already Reported",
53 "Unknown",
54 "Unknown", /* 210 */
55 "Unknown",
56 "Unknown",
57 "Unknown",
58 "Unknown",
59 "Unknown", /* 215 */
60 "Unknown",
61 "Unknown",
62 "Unknown",
63 "Unknown",
64 "Unknown", /* 220 */
65 "Unknown",
66 "Unknown",
67 "Unknown",
68 "Unknown",
69 "Unknown", /* 225 */
70 "IM Used"
71};
72
73static const char *const three_hundred[] = {
74 "Multiple Choices",
75 "Moved Permanently",
76 "Found",
77 "See Other",
78 "Not Modified",
79 "Use Proxy",
80 "Switch Proxy",
81 "Temporary Redirect",
82 "Permanent Redirect"
83};
84
85static const char *const four_hundred[] = {
86 "Bad Request",
87 "Unauthorized",
88 "Payment Required",
89 "Forbidden",
90 "Not Found",
91 "Method Not Allowed",
92 "Not Acceptable",
93 "Proxy Authentication Required",
94 "Request Timeout",
95 "Conflict",
96 "Gone",
97 "Length Required",
98 "Precondition Failed",
99 "Payload Too Large",
100 "URI Too Long",
101 "Unsupported Media Type",
102 "Range Not Satisfiable",
103 "Expectation Failed",
104 "Unknown",
105 "Unknown",
106 "Unknown", /* 420 */
107 "Misdirected Request",
108 "Unprocessable Entity",
109 "Locked",
110 "Failed Dependency",
111 "Unordered Collection",
112 "Upgrade Required",
113 "Unknown",
114 "Precondition Required",
115 "Too Many Requests",
116 "Unknown", /* 430 */
117 "Request Header Fields Too Large",
118 "Unknown",
119 "Unknown",
120 "Unknown",
121 "Unknown", /* 435 */
122 "Unknown",
123 "Unknown",
124 "Unknown",
125 "Unknown",
126 "Unknown", /* 440 */
127 "Unknown",
128 "Unknown",
129 "Unknown",
130 "No Response",
131 "Unknown", /* 445 */
132 "Unknown",
133 "Unknown",
134 "Unknown",
135 "Retry With",
136 "Blocked by Windows Parental Controls", /* 450 */
137 "Unavailable For Legal Reasons"
138};
139
140static const char *const five_hundred[] = {
141 "Internal Server Error",
142 "Not Implemented",
143 "Bad Gateway",
144 "Service Unavailable",
145 "Gateway Timeout",
146 "HTTP Version Not Supported",
147 "Variant Also Negotiates",
148 "Insufficient Storage",
149 "Loop Detected",
150 "Bandwidth Limit Exceeded",
151 "Not Extended",
152 "Network Authentication Required"
153};
154
155
156struct MHD_Reason_Block
157{
158 size_t max;
159 const char *const*data;
160};
161
162#define BLOCK(m) { (sizeof(m) / sizeof(char*)), m }
163
164static const struct MHD_Reason_Block reasons[] = {
165 BLOCK (invalid_hundred),
166 BLOCK (one_hundred),
167 BLOCK (two_hundred),
168 BLOCK (three_hundred),
169 BLOCK (four_hundred),
170 BLOCK (five_hundred),
171};
172
173
174const char *
175MHD_get_reason_phrase_for (enum MHD_HTTP_StatusCode code)
176{
177 if ( (code >= 100) &&
178 (code < 600) &&
179 (reasons[code / 100].max > (code % 100)) )
180 return reasons[code / 100].data[code % 100];
181 return "Unknown";
182}
diff --git a/src/lib/response_for_upgrade.c b/src/lib/response_for_upgrade.c
index 90e361b6..5de6518b 100644
--- 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,
77 response->total_size = MHD_SIZE_UNKNOWN; 77 response->total_size = MHD_SIZE_UNKNOWN;
78 response->reference_count = 1; 78 response->reference_count = 1;
79 if (MHD_NO == 79 if (MHD_NO ==
80 MHD_add_response_header (response, 80 MHD_response_add_header (response,
81 MHD_HTTP_HEADER_CONNECTION, 81 MHD_HTTP_HEADER_CONNECTION,
82 "Upgrade")) 82 "Upgrade"))
83 { 83 {
84 MHD_destroy_response (response); 84 MHD_response_queue_for_destroy (response);
85 return NULL; 85 return NULL;
86 } 86 }
87 return response; 87 return response;