diff options
-rw-r--r-- | configure.ac | 7 | ||||
-rw-r--r-- | src/include/microhttpd2.h | 40 | ||||
-rw-r--r-- | src/lib/connection_options.c | 16 | ||||
-rw-r--r-- | src/lib/daemon.c | 172 | ||||
-rw-r--r-- | src/lib/daemon_options.c | 713 | ||||
-rw-r--r-- | src/lib/internal.h | 412 | ||||
-rw-r--r-- | src/lib/request.c | 68 | ||||
-rw-r--r-- | src/microhttpd/daemon.c | 5 |
8 files changed, 1416 insertions, 17 deletions
diff --git a/configure.ac b/configure.ac index c3d28268..03aba82b 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -2003,6 +2003,13 @@ AC_SUBST(LDFLAGS) | |||
2003 | AC_SUBST([ac_configure_args]) | 2003 | AC_SUBST([ac_configure_args]) |
2004 | AC_SUBST([EMPTY_VAR], [[]]) | 2004 | AC_SUBST([EMPTY_VAR], [[]]) |
2005 | 2005 | ||
2006 | # We define the paths here, because MinGW/GCC expands paths | ||
2007 | # passed through the command line ("-DDIR=..."). This would | ||
2008 | # lead to hard-coded paths ("C:\mingw\mingw\bin...") that do | ||
2009 | # not contain the actual installation. | ||
2010 | AC_DEFINE_DIR([MHD_PLUGIN_INSTALL_PREFIX], [libdir/libmicrohttpd], [tls plugins]) | ||
2011 | |||
2012 | |||
2006 | AC_CONFIG_FILES([libmicrohttpd.pc | 2013 | AC_CONFIG_FILES([libmicrohttpd.pc |
2007 | w32/common/microhttpd_dll_res_vc.rc | 2014 | w32/common/microhttpd_dll_res_vc.rc |
2008 | po/configure.acT:po/configure.ac.in | 2015 | po/configure.acT:po/configure.ac.in |
diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h index d4330c32..4ee1b8d2 100644 --- a/src/include/microhttpd2.h +++ b/src/include/microhttpd2.h | |||
@@ -145,6 +145,17 @@ enum MHD_StatusCode | |||
145 | * supported by the selected backend. | 145 | * supported by the selected backend. |
146 | */ | 146 | */ |
147 | MHD_TLS_CIPHERS_INVALID = 50002 | 147 | MHD_TLS_CIPHERS_INVALID = 50002 |
148 | |||
149 | /** | ||
150 | * The application attempted to setup TLS paramters before | ||
151 | * enabling TLS. | ||
152 | */ | ||
153 | MHD_TLS_BACKEND_UNINITIALIZED = 50003, | ||
154 | |||
155 | /** | ||
156 | * The selected TLS backend does not yet support this operation. | ||
157 | */ | ||
158 | MHD_TLS_BACKEND_OPERATION_UNSUPPORTED = 50004, | ||
148 | 159 | ||
149 | }; | 160 | }; |
150 | 161 | ||
@@ -403,8 +414,9 @@ typedef struct MHD_Action * | |||
403 | * | 414 | * |
404 | * @param cb function to be called for incoming requests | 415 | * @param cb function to be called for incoming requests |
405 | * @param cb_cls closure for @a cb | 416 | * @param cb_cls closure for @a cb |
417 | * @return NULL on error | ||
406 | */ | 418 | */ |
407 | struct MHD_Daemon * | 419 | _MHD_EXTERN struct MHD_Daemon * |
408 | MHD_daemon_create (MHD_RequestCallback cb, | 420 | MHD_daemon_create (MHD_RequestCallback cb, |
409 | void *cb_cls); | 421 | void *cb_cls); |
410 | 422 | ||
@@ -621,7 +633,7 @@ enum MHD_AddressFamily | |||
621 | /** | 633 | /** |
622 | * Pick "best" available method automatically. | 634 | * Pick "best" available method automatically. |
623 | */ | 635 | */ |
624 | MHD_AF_AUTO, | 636 | MHD_AF_AUTO = 0, |
625 | 637 | ||
626 | /** | 638 | /** |
627 | * Use IPv4. | 639 | * Use IPv4. |
@@ -672,7 +684,7 @@ MHD_daemon_bind_port (struct MHD_Daemon *daemon, | |||
672 | _MHD_EXTERN void | 684 | _MHD_EXTERN void |
673 | MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon, | 685 | MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon, |
674 | const struct sockaddr *sa, | 686 | const struct sockaddr *sa, |
675 | size_t sa_lem); | 687 | size_t sa_len); |
676 | 688 | ||
677 | 689 | ||
678 | /** | 690 | /** |
@@ -683,8 +695,8 @@ MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon, | |||
683 | * @param listen_backlog backlog to use | 695 | * @param listen_backlog backlog to use |
684 | */ | 696 | */ |
685 | _MHD_EXTERN void | 697 | _MHD_EXTERN void |
686 | MHD_daemon_listen_queue (struct MHD_Daemon *daemon, | 698 | MHD_daemon_listen_backlog (struct MHD_Daemon *daemon, |
687 | int listen_backlog); | 699 | int listen_backlog); |
688 | 700 | ||
689 | 701 | ||
690 | /** | 702 | /** |
@@ -810,7 +822,7 @@ MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon, | |||
810 | * @param daemon which instance should be configured | 822 | * @param daemon which instance should be configured |
811 | * @param tls_backend which TLS backend should be used, | 823 | * @param tls_backend which TLS backend should be used, |
812 | * currently only "gnutls" is supported. You can | 824 | * currently only "gnutls" is supported. You can |
813 | * also specify "NULL" for best-available (which is the default). | 825 | * also specify NULL for best-available (which is the default). |
814 | * @param ciphers which ciphers should be used by TLS, default is | 826 | * @param ciphers which ciphers should be used by TLS, default is |
815 | * "NORMAL" | 827 | * "NORMAL" |
816 | * @return status code, #MHD_SC_OK upon success | 828 | * @return status code, #MHD_SC_OK upon success |
@@ -1054,8 +1066,6 @@ typedef void | |||
1054 | * @param daemon daemon to set callback for | 1066 | * @param daemon daemon to set callback for |
1055 | * @param ncc function to call to check the policy | 1067 | * @param ncc function to call to check the policy |
1056 | * @param ncc_cls closure for @a apc | 1068 | * @param ncc_cls closure for @a apc |
1057 | * @param ccc function to call upon completion, NULL for none | ||
1058 | * @param ccc_cls closure for @a ccc | ||
1059 | */ | 1069 | */ |
1060 | _MHD_EXTERN void | 1070 | _MHD_EXTERN void |
1061 | MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon, | 1071 | MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon, |
@@ -1064,7 +1074,7 @@ MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon, | |||
1064 | 1074 | ||
1065 | 1075 | ||
1066 | /** | 1076 | /** |
1067 | * Maximum memory size per connection (followed by a `size_t`). | 1077 | * Maximum memory size per connection. |
1068 | * Default is 32 kb (#MHD_POOL_SIZE_DEFAULT). | 1078 | * Default is 32 kb (#MHD_POOL_SIZE_DEFAULT). |
1069 | * Values above 128k are unlikely to result in much benefit, as half | 1079 | * Values above 128k are unlikely to result in much benefit, as half |
1070 | * of the memory will be typically used for IO, and TCP buffers are | 1080 | * of the memory will be typically used for IO, and TCP buffers are |
@@ -1178,15 +1188,15 @@ MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon, | |||
1178 | 1188 | ||
1179 | 1189 | ||
1180 | /** | 1190 | /** |
1181 | * Size of the internal array holding the map of the nonce and | 1191 | * Length of the internal array holding the map of the nonce and |
1182 | * the nonce counter. | 1192 | * the nonce counter. |
1183 | * | 1193 | * |
1184 | * @param daemon daemon to configure | 1194 | * @param daemon daemon to configure |
1185 | * @param nc_length desired array length | 1195 | * @param nc_length desired array length |
1186 | */ | 1196 | */ |
1187 | _MHD_EXTERN void | 1197 | _MHD_EXTERN void |
1188 | MHD_daemon_digest_auth_nc_size (struct MHD_Daemon *daemon, | 1198 | MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon, |
1189 | size_t stack_limit_b); | 1199 | size_t nc_length); |
1190 | 1200 | ||
1191 | 1201 | ||
1192 | /* ********************* connection options ************** */ | 1202 | /* ********************* connection options ************** */ |
@@ -1201,7 +1211,7 @@ MHD_daemon_digest_auth_nc_size (struct MHD_Daemon *daemon, | |||
1201 | * @param connection connection to configure timeout for | 1211 | * @param connection connection to configure timeout for |
1202 | * @param timeout_s new timeout in seconds | 1212 | * @param timeout_s new timeout in seconds |
1203 | */ | 1213 | */ |
1204 | struct MHD_ConnectionOption | 1214 | _MHD_EXTERN struct MHD_ConnectionOption |
1205 | MHD_connection_timeout (struct MHD_Connection *connection, | 1215 | MHD_connection_timeout (struct MHD_Connection *connection, |
1206 | unsigned int timeout_s); | 1216 | unsigned int timeout_s); |
1207 | 1217 | ||
@@ -1443,7 +1453,7 @@ MHD_request_resume (struct MHD_Request *request); | |||
1443 | * as a response *is* an action. As no memory is | 1453 | * as a response *is* an action. As no memory is |
1444 | * allocated, this operation cannot fail. | 1454 | * allocated, this operation cannot fail. |
1445 | */ | 1455 | */ |
1446 | struct MHD_Action * | 1456 | _MHD_EXTERN struct MHD_Action * |
1447 | MHD_action_from_response (struct MHD_Response *response, | 1457 | MHD_action_from_response (struct MHD_Response *response, |
1448 | enum MHD_bool destroy_after_use); | 1458 | enum MHD_bool destroy_after_use); |
1449 | 1459 | ||
@@ -1484,7 +1494,7 @@ typedef void | |||
1484 | * @param termination_cb function to call | 1494 | * @param termination_cb function to call |
1485 | * @param termination_cb_cls closure for @e termination_cb | 1495 | * @param termination_cb_cls closure for @e termination_cb |
1486 | */ | 1496 | */ |
1487 | void | 1497 | _MHD_EXTERN void |
1488 | MHD_response_option_termination_callback (struct MHD_Response *response, | 1498 | MHD_response_option_termination_callback (struct MHD_Response *response, |
1489 | MHD_RequestTerminationCallback termination_cb, | 1499 | MHD_RequestTerminationCallback termination_cb, |
1490 | void *termination_cb_cls); | 1500 | void *termination_cb_cls); |
diff --git a/src/lib/connection_options.c b/src/lib/connection_options.c new file mode 100644 index 00000000..163c956a --- /dev/null +++ b/src/lib/connection_options.c | |||
@@ -0,0 +1,16 @@ | |||
1 | |||
2 | /** | ||
3 | * Generate option to set a custom timeout for the given connection. | ||
4 | * Specified as the number of seconds. Use zero for no timeout. If | ||
5 | * timeout was set to zero (or unset) before, setting of a new value | ||
6 | * by MHD_connection_set_option() will reset timeout timer. | ||
7 | * | ||
8 | * @param connection connection to configure timeout for | ||
9 | * @param timeout_s new timeout in seconds | ||
10 | */ | ||
11 | struct MHD_ConnectionOption | ||
12 | MHD_connection_timeout (struct MHD_Connection *connection, | ||
13 | unsigned int timeout_s); | ||
14 | |||
15 | |||
16 | |||
diff --git a/src/lib/daemon.c b/src/lib/daemon.c new file mode 100644 index 00000000..6396cf9f --- /dev/null +++ b/src/lib/daemon.c | |||
@@ -0,0 +1,172 @@ | |||
1 | /* | ||
2 | This file is part of libmicrohttpd | ||
3 | Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff | ||
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 lib/daemon.c | ||
22 | * @brief main functions to create, start, quiesce and destroy a daemon | ||
23 | * @author Christian Grothoff | ||
24 | */ | ||
25 | #include "internal.h" | ||
26 | |||
27 | |||
28 | /** | ||
29 | * Logging implementation that logs to a file given | ||
30 | * as the @a cls. | ||
31 | * | ||
32 | * @param cls a `FILE *` to log to | ||
33 | * @param sc status code of the event (ignored) | ||
34 | * @param fm format string (`printf()`-style) | ||
35 | * @param ap arguments to @a fm | ||
36 | * @ingroup logging | ||
37 | */ | ||
38 | static void | ||
39 | file_logger (void *cls, | ||
40 | enum MHD_StatusCode sc, | ||
41 | const char *fm, | ||
42 | va_list ap) | ||
43 | { | ||
44 | FILE *f = cls; | ||
45 | |||
46 | (void) sc; | ||
47 | (void) vfprintf (f, | ||
48 | fm, | ||
49 | ap); | ||
50 | } | ||
51 | |||
52 | |||
53 | /** | ||
54 | * Process escape sequences ('%HH') Updates val in place; the | ||
55 | * result should be UTF-8 encoded and cannot be larger than the input. | ||
56 | * The result must also still be 0-terminated. | ||
57 | * | ||
58 | * @param cls closure (use NULL) | ||
59 | * @param req handle to request, not used | ||
60 | * @param val value to unescape (modified in the process) | ||
61 | * @return length of the resulting val (strlen(val) maybe | ||
62 | * shorter afterwards due to elimination of escape sequences) | ||
63 | */ | ||
64 | static size_t | ||
65 | unescape_wrapper (void *cls, | ||
66 | struct MHD_Request *req, | ||
67 | char *val) | ||
68 | { | ||
69 | (void) cls; /* Mute compiler warning. */ | ||
70 | (void) req; /* Mute compiler warning. */ | ||
71 | return MHD_http_unescape (val); | ||
72 | } | ||
73 | |||
74 | |||
75 | /** | ||
76 | * Create (but do not yet start) an MHD daemon. | ||
77 | * Usually, you will want to set various options before | ||
78 | * starting the daemon with #MHD_daemon_start(). | ||
79 | * | ||
80 | * @param cb function to be called for incoming requests | ||
81 | * @param cb_cls closure for @a cb | ||
82 | * @return NULL on error | ||
83 | */ | ||
84 | struct MHD_Daemon * | ||
85 | MHD_daemon_create (MHD_RequestCallback cb, | ||
86 | void *cb_cls) | ||
87 | { | ||
88 | struct MHD_Daemon *daemon; | ||
89 | |||
90 | MHD_check_global_init_(); | ||
91 | if (NULL == cb) | ||
92 | return NULL; | ||
93 | if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon)))) | ||
94 | return NULL; | ||
95 | memset (daemon, | ||
96 | 0, | ||
97 | sizeof (struct MHD_Daemon)); | ||
98 | daemon->rc = cb; | ||
99 | daemon->rc_cls = cb_cls; | ||
100 | daemon->logger = &file_logger; | ||
101 | daemon->logger_cls = stderr; | ||
102 | daemon->unescape_cb = &unescape_wrapper; | ||
103 | daemon->tls_ciphers = TLS_CIPHERS_DEFAULT; | ||
104 | daemon->connection_memory_limit_b = MHD_POOL_SIZE_DEFAULT; | ||
105 | daemon->connection_memory_increment_b = BUF_INC_SIZE_DEFAULT; | ||
106 | #if ENABLE_DAUTH | ||
107 | daemon->digest_nc_length = DIGEST_NC_LENGTH_DEFAULT; | ||
108 | #endif | ||
109 | daemon->listen_backlog = LISTEN_BACKLOG_DEFAULT; | ||
110 | daemon->fo_queue_length = FO_QUEUE_LENGTH_DEFAULT; | ||
111 | daemon->listen_socket = MHD_INVALID_SOCKET; | ||
112 | return daemon; | ||
113 | } | ||
114 | |||
115 | |||
116 | /** | ||
117 | * Start a webserver. | ||
118 | * | ||
119 | * @param daemon daemon to start; you can no longer set | ||
120 | * options on this daemon after this call! | ||
121 | * @return #MHD_SC_OK on success | ||
122 | * @ingroup event | ||
123 | */ | ||
124 | enum MHD_StatusCode | ||
125 | MHD_daemon_start (struct MHD_Daemon *daemon) | ||
126 | { | ||
127 | |||
128 | return -1; | ||
129 | } | ||
130 | |||
131 | |||
132 | /** | ||
133 | * Stop accepting connections from the listening socket. Allows | ||
134 | * clients to continue processing, but stops accepting new | ||
135 | * connections. Note that the caller is responsible for closing the | ||
136 | * returned socket; however, if MHD is run using threads (anything but | ||
137 | * external select mode), it must not be closed until AFTER | ||
138 | * #MHD_stop_daemon has been called (as it is theoretically possible | ||
139 | * that an existing thread is still using it). | ||
140 | * | ||
141 | * Note that some thread modes require the caller to have passed | ||
142 | * #MHD_USE_ITC when using this API. If this daemon is | ||
143 | * in one of those modes and this option was not given to | ||
144 | * #MHD_start_daemon, this function will return #MHD_INVALID_SOCKET. | ||
145 | * | ||
146 | * @param daemon daemon to stop accepting new connections for | ||
147 | * @return old listen socket on success, #MHD_INVALID_SOCKET if | ||
148 | * the daemon was already not listening anymore, or | ||
149 | * was never started | ||
150 | * @ingroup specialized | ||
151 | */ | ||
152 | MHD_socket | ||
153 | MHD_daemon_quiesce (struct MHD_Daemon *daemon) | ||
154 | { | ||
155 | return -1; | ||
156 | } | ||
157 | |||
158 | |||
159 | /** | ||
160 | * Shutdown and destroy an HTTP daemon. | ||
161 | * | ||
162 | * @param daemon daemon to stop | ||
163 | * @ingroup event | ||
164 | */ | ||
165 | void | ||
166 | MHD_daemon_destroy (struct MHD_Daemon *daemon) | ||
167 | { | ||
168 | free (daemon); | ||
169 | } | ||
170 | |||
171 | |||
172 | /* end of daemon.c */ | ||
diff --git a/src/lib/daemon_options.c b/src/lib/daemon_options.c new file mode 100644 index 00000000..576779e3 --- /dev/null +++ b/src/lib/daemon_options.c | |||
@@ -0,0 +1,713 @@ | |||
1 | /* | ||
2 | This file is part of libmicrohttpd | ||
3 | Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff | ||
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 lib/daemon_options.c | ||
22 | * @brief boring functions to manipulate daemon options | ||
23 | * @author Christian Grothoff | ||
24 | */ | ||
25 | #include "internal.h" | ||
26 | |||
27 | |||
28 | /** | ||
29 | * Set logging method. Specify NULL to disable logging entirely. By | ||
30 | * default (if this option is not given), we log error messages to | ||
31 | * stderr. | ||
32 | * | ||
33 | * @param daemon which instance to setup logging for | ||
34 | * @param logger function to invoke | ||
35 | * @param logger_cls closure for @a logger | ||
36 | */ | ||
37 | void | ||
38 | MHD_daemon_set_logger (struct MHD_Daemon *daemon, | ||
39 | MHD_LoggingCallback logger, | ||
40 | void *logger_cls) | ||
41 | { | ||
42 | daemon->logger = logger; | ||
43 | daemon->logger_cls = logger_cls; | ||
44 | } | ||
45 | |||
46 | |||
47 | /** | ||
48 | * Suppress use of "Date" header as this system has no RTC. | ||
49 | * | ||
50 | * @param daemon which instance to disable clock for. | ||
51 | */ | ||
52 | void | ||
53 | MHD_daemon_suppress_date_no_clock (struct MHD_Daemon *daemon) | ||
54 | { | ||
55 | daemon->suppress_date = true; | ||
56 | } | ||
57 | |||
58 | |||
59 | /** | ||
60 | * Disable use of inter-thread communication channel. | ||
61 | * #MHD_daemon_disable_itc() can be used with | ||
62 | * #MHD_daemon_thread_internal() to perform some additional | ||
63 | * optimizations (in particular, not creating a pipe for IPC | ||
64 | * signalling). If it is used, certain functions like | ||
65 | * #MHD_daemon_quiesce() or #MHD_connection_add() or | ||
66 | * #MHD_action_suspend() cannot be used anymore. | ||
67 | * #MHD_daemon_disable_itc() is not beneficial on platforms where | ||
68 | * select()/poll()/other signal shutdown() of a listen socket. | ||
69 | * | ||
70 | * You should only use this function if you are sure you do | ||
71 | * satisfy all of its requirements and need a generally minor | ||
72 | * boost in performance. | ||
73 | * | ||
74 | * @param daemon which instance to disable itc for | ||
75 | */ | ||
76 | void | ||
77 | MHD_daemon_disable_itc (struct MHD_Daemon *daemon) | ||
78 | { | ||
79 | daemon->disable_itc = true; | ||
80 | } | ||
81 | |||
82 | |||
83 | /** | ||
84 | * Enable `turbo`. Disables certain calls to `shutdown()`, | ||
85 | * enables aggressive non-blocking optimistic reads and | ||
86 | * other potentially unsafe optimizations. | ||
87 | * Most effects only happen with #MHD_ELS_EPOLL. | ||
88 | * | ||
89 | * @param daemon which instance to enable turbo for | ||
90 | */ | ||
91 | void | ||
92 | MHD_daemon_enable_turbo (struct MHD_Daemon *daemon) | ||
93 | { | ||
94 | daemon->enable_turbo = true; | ||
95 | } | ||
96 | |||
97 | |||
98 | /** | ||
99 | * Disable #MHD_action_suspend() functionality. | ||
100 | * | ||
101 | * You should only use this function if you are sure you do | ||
102 | * satisfy all of its requirements and need a generally minor | ||
103 | * boost in performance. | ||
104 | * | ||
105 | * @param daemon which instance to disable suspend for | ||
106 | */ | ||
107 | void | ||
108 | MHD_daemon_disallow_suspend_resume (struct MHD_Daemon *daemon) | ||
109 | { | ||
110 | daemon->disallow_suspend_resume = true; | ||
111 | } | ||
112 | |||
113 | |||
114 | /** | ||
115 | * You need to set this option if you want to disable use of HTTP "Upgrade". | ||
116 | * "Upgrade" may require usage of additional internal resources, | ||
117 | * which we can avoid providing if they will not be used. | ||
118 | * | ||
119 | * You should only use this function if you are sure you do | ||
120 | * satisfy all of its requirements and need a generally minor | ||
121 | * boost in performance. | ||
122 | * | ||
123 | * @param daemon which instance to enable suspend/resume for | ||
124 | */ | ||
125 | void | ||
126 | MHD_daemon_disallow_upgrade (struct MHD_Daemon *daemon) | ||
127 | { | ||
128 | daemon->disallow_upgrade; | ||
129 | } | ||
130 | |||
131 | |||
132 | /** | ||
133 | * Configure TCP_FASTOPEN option, including setting a | ||
134 | * custom @a queue_length. | ||
135 | * | ||
136 | * Note that having a larger queue size can cause resource exhaustion | ||
137 | * attack as the TCP stack has to now allocate resources for the SYN | ||
138 | * packet along with its DATA. | ||
139 | * | ||
140 | * @param daemon which instance to configure TCP_FASTOPEN for | ||
141 | * @param fom under which conditions should we use TCP_FASTOPEN? | ||
142 | * @param queue_length queue length to use, default is 50 if this | ||
143 | * option is never given. | ||
144 | * @return #MHD_YES upon success, #MHD_NO if #MHD_FOM_REQUIRE was | ||
145 | * given, but TCP_FASTOPEN is not available on the platform | ||
146 | */ | ||
147 | enum MHD_Bool | ||
148 | MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon, | ||
149 | enum MHD_FastOpenMethod fom, | ||
150 | unsigned int queue_length) | ||
151 | { | ||
152 | daemon->fast_open_method = fom; | ||
153 | daemon->fast_open_queue_length = queue_length; | ||
154 | switch (fom) | ||
155 | { | ||
156 | case MHD_FOM_DISABLE: | ||
157 | return MHD_YES; | ||
158 | case MHD_FOM_AUTO: | ||
159 | return MHD_YES; | ||
160 | case MHD_FOM_REQUIRE: | ||
161 | #ifdef TCP_FASTOPEN | ||
162 | return MHD_YES; | ||
163 | #else | ||
164 | return MHD_NO; | ||
165 | #endif | ||
166 | } | ||
167 | } | ||
168 | |||
169 | |||
170 | /** | ||
171 | * Bind to the given TCP port and address family. | ||
172 | * | ||
173 | * Ineffective in conjunction with #MHD_daemon_listen_socket(). | ||
174 | * Ineffective in conjunction with #MHD_daemon_bind_sa(). | ||
175 | * | ||
176 | * If neither this option nor the other two mentioned above | ||
177 | * is specified, MHD will simply not listen on any socket! | ||
178 | * | ||
179 | * @param daemon which instance to configure the TCP port for | ||
180 | * @param af address family to use | ||
181 | * @param port port to use, 0 to bind to a random (free) port | ||
182 | */ | ||
183 | void | ||
184 | MHD_daemon_bind_port (struct MHD_Daemon *daemon, | ||
185 | enum MHD_AddressFamily af, | ||
186 | uint16_t port) | ||
187 | { | ||
188 | daemon->listen_af = af; | ||
189 | daemon->listen_port = port; | ||
190 | } | ||
191 | |||
192 | |||
193 | /** | ||
194 | * Bind to the given socket address. | ||
195 | * Ineffective in conjunction with #MHD_daemon_listen_socket(). | ||
196 | * | ||
197 | * @param daemon which instance to configure the binding address for | ||
198 | * @param sa address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6) | ||
199 | * or even a UNIX domain socket (AF_UNIX) | ||
200 | * @param sa_len number of bytes in @a sa | ||
201 | */ | ||
202 | void | ||
203 | MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon, | ||
204 | const struct sockaddr *sa, | ||
205 | size_t sa_len) | ||
206 | { | ||
207 | daemon->sa_given = true; | ||
208 | memcpy (&daemon->listen_sa, | ||
209 | sa, | ||
210 | sa_len); | ||
211 | daemon->listen_sa_len = sa_len; | ||
212 | } | ||
213 | |||
214 | |||
215 | /** | ||
216 | * Use the given backlog for the listen() call. | ||
217 | * Ineffective in conjunction with #MHD_daemon_listen_socket(). | ||
218 | * | ||
219 | * @param daemon which instance to configure the backlog for | ||
220 | * @param listen_backlog backlog to use | ||
221 | */ | ||
222 | void | ||
223 | MHD_daemon_listen_backlog (struct MHD_Daemon *daemon, | ||
224 | int listen_backlog) | ||
225 | { | ||
226 | daemon->listen_backlog = listen_backlog; | ||
227 | } | ||
228 | |||
229 | |||
230 | /** | ||
231 | * If present true, allow reusing address:port socket (by using | ||
232 | * SO_REUSEPORT on most platform, or platform-specific ways). If | ||
233 | * present and set to false, disallow reusing address:port socket | ||
234 | * (does nothing on most plaform, but uses SO_EXCLUSIVEADDRUSE on | ||
235 | * Windows). | ||
236 | * Ineffective in conjunction with #MHD_daemon_listen_socket(). | ||
237 | * | ||
238 | * @param daemon daemon to configure address reuse for | ||
239 | */ | ||
240 | void | ||
241 | MHD_daemon_listen_allow_address_reuse (struct MHD_Daemon *daemon) | ||
242 | { | ||
243 | daemon->allow_address_reuse = true; | ||
244 | } | ||
245 | |||
246 | |||
247 | /** | ||
248 | * Accept connections from the given socket. Socket | ||
249 | * must be a TCP or UNIX domain (stream) socket. | ||
250 | * | ||
251 | * Unless -1 is given, this disables other listen options, including | ||
252 | * #MHD_daemon_bind_sa(), #MHD_daemon_bind_port(), | ||
253 | * #MHD_daemon_listen_queue() and | ||
254 | * #MHD_daemon_listen_allow_address_reuse(). | ||
255 | * | ||
256 | * @param daemon daemon to set listen socket for | ||
257 | * @param listen_socket listen socket to use, | ||
258 | * MHD_INVALID_SOCKET value will cause this call to be | ||
259 | * ignored (other binding options may still be effective) | ||
260 | */ | ||
261 | void | ||
262 | MHD_daemon_listen_socket (struct MHD_Daemon *daemon, | ||
263 | MHD_socket listen_socket) | ||
264 | { | ||
265 | daemon->listen_socket = listen_socket; | ||
266 | } | ||
267 | |||
268 | |||
269 | /** | ||
270 | * Force use of a particular event loop system call. | ||
271 | * | ||
272 | * @param daemon daemon to set event loop style for | ||
273 | * @param els event loop syscall to use | ||
274 | * @return #MHD_NO on failure, #MHD_YES on success | ||
275 | */ | ||
276 | enum MHD_Bool | ||
277 | MHD_daemon_event_loop (struct MHD_Daemon *daemon, | ||
278 | enum MHD_EventLoopSyscall els) | ||
279 | { | ||
280 | switch (els) | ||
281 | { | ||
282 | case MHD_ELS_AUTO: | ||
283 | break; /* should always be OK */ | ||
284 | case MHD_ELS_SELECT: | ||
285 | break; /* should always be OK */ | ||
286 | case MHD_ELS_POLL: | ||
287 | #ifdef HAVE_POLL | ||
288 | break; | ||
289 | #else | ||
290 | return MHD_NO; /* not supported */ | ||
291 | #endif | ||
292 | case MHD_ELS_EPOLL: | ||
293 | #ifdef EPOLL_SUPPORT | ||
294 | break; | ||
295 | #else | ||
296 | return MHD_NO; /* not supported */ | ||
297 | #endif | ||
298 | default: | ||
299 | return MHD_NO; /* not supported (presumably future ABI extension) */ | ||
300 | } | ||
301 | daemon->event_loop_syscall = els; | ||
302 | return MHD_YES; | ||
303 | } | ||
304 | |||
305 | |||
306 | /** | ||
307 | * Set how strictly MHD will enforce the HTTP protocol. | ||
308 | * | ||
309 | * @param daemon daemon to configure strictness for | ||
310 | * @param sl how strict should we be | ||
311 | */ | ||
312 | void | ||
313 | MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon, | ||
314 | enum MHD_ProtocolStrictLevel sl) | ||
315 | { | ||
316 | daemon->protocol_strict_level = sl; | ||
317 | } | ||
318 | |||
319 | |||
320 | /** | ||
321 | * Enable and configure TLS. | ||
322 | * | ||
323 | * @param daemon which instance should be configured | ||
324 | * @param tls_backend which TLS backend should be used, | ||
325 | * currently only "gnutls" is supported. You can | ||
326 | * also specify NULL for best-available (which is the default). | ||
327 | * @param ciphers which ciphers should be used by TLS, default is | ||
328 | * "NORMAL" | ||
329 | * @return status code, #MHD_SC_OK upon success | ||
330 | * #MHD_TLS_BACKEND_UNSUPPORTED if the @a backend is unknown | ||
331 | * #MHD_TLS_DISABLED if this build of MHD does not support TLS | ||
332 | * #MHD_TLS_CIPHERS_INVALID if the given @a ciphers are not supported | ||
333 | * by this backend | ||
334 | */ | ||
335 | enum MHD_StatusCode | ||
336 | MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon, | ||
337 | const char *tls_backend, | ||
338 | const char *ciphers) | ||
339 | { | ||
340 | #ifndef HTTPS_SUPPORT | ||
341 | return MHD_TLS_DISABLED; | ||
342 | #else | ||
343 | char filename[1024]; | ||
344 | int res; | ||
345 | MHD_TLS_PluginInit init; | ||
346 | |||
347 | /* todo: .dll on W32? */ | ||
348 | res = MHD_snprintf (filename, | ||
349 | sizeof (filename), | ||
350 | "%s/libmicrohttpd_tls_%s.so", | ||
351 | MHD_PLUGIN_INSTALL_PREFIX, | ||
352 | tls_backend); | ||
353 | if (0 >= res) | ||
354 | return MHD_BACKEND_UNSUPPORTED; /* string too long? */ | ||
355 | if (NULL == | ||
356 | (daemon->tls_backend_lib = dlopen (filename, | ||
357 | RTLD_NOW | RTLD_LOCAL))) | ||
358 | return MHD_BACKEND_UNSUPPORTED; /* plugin not found */ | ||
359 | if (NULL == (init = dlsym (daemon->tls_backend_lib, | ||
360 | "MHD_TLS_init_" MHD_TLS_ABI_VERSION_STR))) | ||
361 | |||
362 | { | ||
363 | dlclose (daemon->tls_backend_lib); | ||
364 | daemon->tls_backend_lib = NULL; | ||
365 | return MHD_BACKEND_UNSUPPORTED; /* possibly wrong version installed */ | ||
366 | } | ||
367 | if (NULL == (daemon->tls_backend = init (ciphers))) | ||
368 | { | ||
369 | dlclose (daemon->tls_backend_lib); | ||
370 | daemon->tls_backend_lib = NULL; | ||
371 | return MHD_CIPHERS_INVALID; /* possibly wrong version installed */ | ||
372 | } | ||
373 | return MHD_SC_OK; | ||
374 | #endif | ||
375 | } | ||
376 | |||
377 | |||
378 | /** | ||
379 | * Provide TLS key and certificate data in-memory. | ||
380 | * | ||
381 | * @param daemon which instance should be configured | ||
382 | * @param mem_key private key (key.pem) to be used by the | ||
383 | * HTTPS daemon. Must be the actual data in-memory, not a filename. | ||
384 | * @param mem_cert certificate (cert.pem) to be used by the | ||
385 | * HTTPS daemon. Must be the actual data in-memory, not a filename. | ||
386 | * @param pass passphrase phrase to decrypt 'key.pem', NULL | ||
387 | * if @param mem_key is in cleartext already | ||
388 | * @return #MHD_SC_OK upon success; MHD_BACKEND_UNINITIALIZED | ||
389 | * if the TLS backend is not yet setup. | ||
390 | */ | ||
391 | enum MHD_StatusCode | ||
392 | MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon, | ||
393 | const char *mem_key, | ||
394 | const char *mem_cert, | ||
395 | const char *pass) | ||
396 | { | ||
397 | struct MHD_TLS_Plugin *plugin; | ||
398 | |||
399 | if (NULL == (plugin = daemon->tls_backend)) | ||
400 | return MHD_TLS_BACKEND_UNINITIALIZED; | ||
401 | return plugin->init_kcp (plugin->cls, | ||
402 | mem_key, | ||
403 | mem_cert, | ||
404 | pass); | ||
405 | } | ||
406 | |||
407 | |||
408 | /** | ||
409 | * Configure DH parameters (dh.pem) to use for the TLS key | ||
410 | * exchange. | ||
411 | * | ||
412 | * @param daemon daemon to configure tls for | ||
413 | * @param dh parameters to use | ||
414 | * @return #MHD_SC_OK upon success; MHD_BACKEND_UNINITIALIZED | ||
415 | * if the TLS backend is not yet setup. | ||
416 | */ | ||
417 | enum MHD_StatusCode | ||
418 | MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon, | ||
419 | const char *dh) | ||
420 | { | ||
421 | struct MHD_TLS_Plugin *plugin; | ||
422 | |||
423 | if (NULL == (plugin = daemon->tls_backend)) | ||
424 | return MHD_TLS_BACKEND_UNINITIALIZED; | ||
425 | return plugin->init_dhparams (plugin->cls, | ||
426 | dh); | ||
427 | } | ||
428 | |||
429 | |||
430 | /** | ||
431 | * Memory pointer for the certificate (ca.pem) to be used by the | ||
432 | * HTTPS daemon for client authentification. | ||
433 | * | ||
434 | * @param daemon daemon to configure tls for | ||
435 | * @param mem_trust memory pointer to the certificate | ||
436 | * @return #MHD_SC_OK upon success; MHD_BACKEND_UNINITIALIZED | ||
437 | * if the TLS backend is not yet setup. | ||
438 | */ | ||
439 | enum MHD_StatusCode | ||
440 | MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon, | ||
441 | const char *mem_trust) | ||
442 | { | ||
443 | struct MHD_TLS_Plugin *plugin; | ||
444 | |||
445 | if (NULL == (plugin = daemon->tls_backend)) | ||
446 | return MHD_TLS_BACKEND_UNINITIALIZED; | ||
447 | return plugin->init_mem_trust (plugin->cls, | ||
448 | mem_trust); | ||
449 | } | ||
450 | |||
451 | |||
452 | /** | ||
453 | * Configure daemon credentials type for GnuTLS. | ||
454 | * | ||
455 | * @param gnutls_credentials must be a value of | ||
456 | * type `gnutls_credentials_type_t` | ||
457 | * @return #MHD_SC_OK upon success; TODO: define failure modes | ||
458 | */ | ||
459 | enum MHD_StatusCode | ||
460 | MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon, | ||
461 | int gnutls_credentials) | ||
462 | { | ||
463 | struct MHD_TLS_Plugin *plugin; | ||
464 | |||
465 | if (NULL == (plugin = daemon->tls_backend)) | ||
466 | return MHD_TLS_BACKEND_UNINITIALIZED; | ||
467 | return MHD_TLS_BACKEND_OPERATION_UNSUPPORTED; | ||
468 | } | ||
469 | |||
470 | |||
471 | /** | ||
472 | * Provide TLS key and certificate data via callback. | ||
473 | * | ||
474 | * Use a callback to determine which X.509 certificate should be used | ||
475 | * for a given HTTPS connection. This option provides an alternative | ||
476 | * to #MHD_daemon_tls_key_and_cert_from_memory(). You must use this | ||
477 | * version if multiple domains are to be hosted at the same IP address | ||
478 | * using TLS's Server Name Indication (SNI) extension. In this case, | ||
479 | * the callback is expected to select the correct certificate based on | ||
480 | * the SNI information provided. The callback is expected to access | ||
481 | * the SNI data using `gnutls_server_name_get()`. Using this option | ||
482 | * requires GnuTLS 3.0 or higher. | ||
483 | * | ||
484 | * @param daemon daemon to configure callback for | ||
485 | * @param cb must be of type `gnutls_certificate_retrieve_function2 *`. | ||
486 | */ | ||
487 | void | ||
488 | MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon, | ||
489 | void *cb) | ||
490 | { | ||
491 | struct MHD_TLS_Plugin *plugin; | ||
492 | |||
493 | if (NULL == (plugin = daemon->tls_backend)) | ||
494 | return MHD_TLS_BACKEND_UNINITIALIZED; | ||
495 | return MHD_TLS_BACKEND_OPERATION_UNSUPPORTED; | ||
496 | } | ||
497 | |||
498 | |||
499 | /** | ||
500 | * Specify threading model to use. | ||
501 | * | ||
502 | * @param daemon daemon to configure | ||
503 | * @param tm model to use (positive values indicate the | ||
504 | * number of worker threads to be used) | ||
505 | */ | ||
506 | void | ||
507 | MHD_daemon_threading_model (struct MHD_Daemon *daemon, | ||
508 | enum MHD_ThreadingModel tm) | ||
509 | { | ||
510 | daemon->threading_model = tm; | ||
511 | } | ||
512 | |||
513 | |||
514 | /** | ||
515 | * Set a policy callback that accepts/rejects connections | ||
516 | * based on the client's IP address. This function will be called | ||
517 | * before a connection object is created. | ||
518 | * | ||
519 | * @param daemon daemon to set policy for | ||
520 | * @param apc function to call to check the policy | ||
521 | * @param apc_cls closure for @a apc | ||
522 | */ | ||
523 | void | ||
524 | MHD_daemon_accept_policy (struct MHD_Daemon *daemon, | ||
525 | MHD_AcceptPolicyCallback apc, | ||
526 | void *apc_cls) | ||
527 | { | ||
528 | daemon->accept_policy_cb = apc; | ||
529 | daemon->accept_policy_cb_cls = apc_cls; | ||
530 | } | ||
531 | |||
532 | |||
533 | /** | ||
534 | * Register a callback to be called first for every request | ||
535 | * (before any parsing of the header). Makes it easy to | ||
536 | * log the full URL. | ||
537 | * | ||
538 | * @param daemon daemon for which to set the logger | ||
539 | * @param cb function to call | ||
540 | * @param cb_cls closure for @a cb | ||
541 | */ | ||
542 | void | ||
543 | MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon, | ||
544 | MHD_EarlyUriLogCallback cb, | ||
545 | void *cb_cls) | ||
546 | { | ||
547 | daemon->early_uri_logger_cb = cb; | ||
548 | daemon->early_uri_logger_cb_cls = cb_cls; | ||
549 | } | ||
550 | |||
551 | |||
552 | /** | ||
553 | * Register a function that should be called whenever a connection is | ||
554 | * started or closed. | ||
555 | * | ||
556 | * @param daemon daemon to set callback for | ||
557 | * @param ncc function to call to check the policy | ||
558 | * @param ncc_cls closure for @a apc | ||
559 | */ | ||
560 | void | ||
561 | MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon, | ||
562 | MHD_NotifyConnectionCallback ncc, | ||
563 | void *ncc_cls) | ||
564 | { | ||
565 | daemon->notify_connection_cb = ncc; | ||
566 | daemon->notify_connection_cb_cls = ncc_cls; | ||
567 | } | ||
568 | |||
569 | |||
570 | /** | ||
571 | * Maximum memory size per connection. | ||
572 | * Default is 32 kb (#MHD_POOL_SIZE_DEFAULT). | ||
573 | * Values above 128k are unlikely to result in much benefit, as half | ||
574 | * of the memory will be typically used for IO, and TCP buffers are | ||
575 | * unlikely to support window sizes above 64k on most systems. | ||
576 | * | ||
577 | * @param daemon daemon to configure | ||
578 | * @param memory_limit_b connection memory limit to use in bytes | ||
579 | * @param memory_increment_b increment to use when growing the read buffer, must be smaller than @a memory_limit_b | ||
580 | */ | ||
581 | void | ||
582 | MHD_daemon_connection_memory_limit (struct MHD_Daemon *daemon, | ||
583 | size_t memory_limit_b, | ||
584 | size_t memory_increment_b) | ||
585 | { | ||
586 | if (memory_increment_b >= memory_limit_b) | ||
587 | MHD_PANIC ("sane memory increment must be below memory limit"); | ||
588 | daemon->connection_memory_limit_b = memory_limit_b; | ||
589 | daemon->connection_memory_increment_b = memory_increment_b; | ||
590 | } | ||
591 | |||
592 | |||
593 | /** | ||
594 | * Desired size of the stack for threads created by MHD. Use 0 for | ||
595 | * system default. Only useful if the selected threading model | ||
596 | * is not #MHD_TM_EXTERNAL_EVENT_LOOP. | ||
597 | * | ||
598 | * @param daemon daemon to configure | ||
599 | * @param stack_limit_b stack size to use in bytes | ||
600 | */ | ||
601 | void | ||
602 | MHD_daemon_thread_stack_size (struct MHD_Daemon *daemon, | ||
603 | size_t stack_limit_b) | ||
604 | { | ||
605 | daemon->thread_stack_limit_b = stack_limit_b; | ||
606 | } | ||
607 | |||
608 | |||
609 | /** | ||
610 | * Set maximum number of concurrent connections to accept. If not | ||
611 | * given, MHD will not enforce any limits (modulo running into | ||
612 | * OS limits). Values of 0 mean no limit. | ||
613 | * | ||
614 | * @param daemon daemon to configure | ||
615 | * @param global_connection_limit maximum number of (concurrent) | ||
616 | connections | ||
617 | * @param ip_connection_limit limit on the number of (concurrent) | ||
618 | * connections made to the server from the same IP address. | ||
619 | * Can be used to prevent one IP from taking over all of | ||
620 | * the allowed connections. If the same IP tries to | ||
621 | * establish more than the specified number of | ||
622 | * connections, they will be immediately rejected. | ||
623 | */ | ||
624 | void | ||
625 | MHD_daemon_connection_limits (struct MHD_Daemon *daemon, | ||
626 | unsigned int global_connection_limit, | ||
627 | unsigned int ip_connection_limit) | ||
628 | { | ||
629 | daemon->global_connection_limit = global_connection_limit; | ||
630 | daemon->ip_connection_limit = ip_connection_limit; | ||
631 | } | ||
632 | |||
633 | |||
634 | /** | ||
635 | * After how many seconds of inactivity should a | ||
636 | * connection automatically be timed out? | ||
637 | * Use zero for no timeout, which is also the (unsafe!) default. | ||
638 | * | ||
639 | * @param daemon daemon to configure | ||
640 | * @param timeout_s number of seconds of timeout to use | ||
641 | */ | ||
642 | void | ||
643 | MHD_daemon_connection_default_timeout (struct MHD_Daemon *daemon, | ||
644 | unsigned int timeout_s) | ||
645 | { | ||
646 | daemon->connection_default_timeout_s = timeout_s; | ||
647 | } | ||
648 | |||
649 | |||
650 | /** | ||
651 | * Specify a function that should be called for unescaping escape | ||
652 | * sequences in URIs and URI arguments. Note that this function | ||
653 | * will NOT be used by the `struct MHD_PostProcessor`. If this | ||
654 | * option is not specified, the default method will be used which | ||
655 | * decodes escape sequences of the form "%HH". | ||
656 | * | ||
657 | * @param daemon daemon to configure | ||
658 | * @param unescape_cb function to use, NULL for default | ||
659 | * @param unescape_cb_cls closure for @a unescape_cb | ||
660 | */ | ||
661 | void | ||
662 | MHD_daemon_unescape_cb (struct MHD_Daemon *daemon, | ||
663 | MHD_UnescapeCallback unescape_cb, | ||
664 | void *unescape_cb_cls) | ||
665 | { | ||
666 | daemon->unescape_cb = unescape_cb; | ||
667 | daemon->unescape_cb_cls = unescape_cb_cls; | ||
668 | } | ||
669 | |||
670 | |||
671 | /** | ||
672 | * Set random values to be used by the Digest Auth module. Note that | ||
673 | * the application must ensure that @a buf remains allocated and | ||
674 | * unmodified while the deamon is running. | ||
675 | * | ||
676 | * @param daemon daemon to configure | ||
677 | * @param buf_size number of bytes in @a buf | ||
678 | * @param buf entropy buffer | ||
679 | */ | ||
680 | void | ||
681 | MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon, | ||
682 | size_t buf_size, | ||
683 | const void *buf) | ||
684 | { | ||
685 | #if ENABLE_DAUTH | ||
686 | daemon->digest_auth_random_buf = buf; | ||
687 | daemon->digest_auth_random_buf_size = buf_size; | ||
688 | #else | ||
689 | MHD_PANIC ("digest authentication not supported by this build"); | ||
690 | #endif | ||
691 | } | ||
692 | |||
693 | |||
694 | /** | ||
695 | * Length of the internal array holding the map of the nonce and | ||
696 | * the nonce counter. | ||
697 | * | ||
698 | * @param daemon daemon to configure | ||
699 | * @param nc_length desired array length | ||
700 | */ | ||
701 | void | ||
702 | MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon, | ||
703 | size_t nc_length) | ||
704 | { | ||
705 | #if ENABLE_DAUTH | ||
706 | daemon->digest_nc_length = nc_length; | ||
707 | #else | ||
708 | MHD_PANIC ("digest authentication not supported by this build"); | ||
709 | #endif | ||
710 | } | ||
711 | |||
712 | |||
713 | /* end of daemon_options.c */ | ||
diff --git a/src/lib/internal.h b/src/lib/internal.h new file mode 100644 index 00000000..8de88598 --- /dev/null +++ b/src/lib/internal.h | |||
@@ -0,0 +1,412 @@ | |||
1 | /* | ||
2 | This file is part of libmicrohttpd | ||
3 | Copyright (C) 2007-2017 Daniel Pittman and Christian Grothoff | ||
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 microhttpd/internal.h | ||
22 | * @brief internal shared structures | ||
23 | * @author Daniel Pittman | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | #ifndef INTERNAL_H | ||
28 | #define INTERNAL_H | ||
29 | |||
30 | #include "mhd_options.h" | ||
31 | #include "platform.h" | ||
32 | #include "microhttpd2.h" | ||
33 | #include "microhttpd_tls.h" | ||
34 | #include "mhd_assert.h" | ||
35 | |||
36 | #ifdef HTTPS_SUPPORT | ||
37 | #include <gnutls/gnutls.h> | ||
38 | #if GNUTLS_VERSION_MAJOR >= 3 | ||
39 | #include <gnutls/abstract.h> | ||
40 | #endif | ||
41 | #endif /* HTTPS_SUPPORT */ | ||
42 | |||
43 | #ifdef HAVE_STDBOOL_H | ||
44 | #include <stdbool.h> | ||
45 | #endif | ||
46 | #ifdef MHD_PANIC | ||
47 | /* Override any defined MHD_PANIC macro with proper one */ | ||
48 | #undef MHD_PANIC | ||
49 | #endif /* MHD_PANIC */ | ||
50 | |||
51 | #ifdef HAVE_MESSAGES | ||
52 | /** | ||
53 | * Trigger 'panic' action based on fatal errors. | ||
54 | * | ||
55 | * @param msg error message (const char *) | ||
56 | */ | ||
57 | #define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, msg); BUILTIN_NOT_REACHED; } while (0) | ||
58 | #else | ||
59 | /** | ||
60 | * Trigger 'panic' action based on fatal errors. | ||
61 | * | ||
62 | * @param msg error message (const char *) | ||
63 | */ | ||
64 | #define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); BUILTIN_NOT_REACHED; } while (0) | ||
65 | #endif | ||
66 | |||
67 | #include "mhd_threads.h" | ||
68 | #include "mhd_locks.h" | ||
69 | #include "mhd_sockets.h" | ||
70 | #include "mhd_itc_types.h" | ||
71 | |||
72 | |||
73 | /** | ||
74 | * Close FD and abort execution if error is detected. | ||
75 | * @param fd the FD to close | ||
76 | */ | ||
77 | #define MHD_fd_close_chk_(fd) do { \ | ||
78 | if (0 == close ((fd)) && (EBADF == errno)) \ | ||
79 | MHD_PANIC(_("Failed to close FD.\n")); \ | ||
80 | } while(0) | ||
81 | |||
82 | /** | ||
83 | * Should we perform additional sanity checks at runtime (on our internal | ||
84 | * invariants)? This may lead to aborts, but can be useful for debugging. | ||
85 | */ | ||
86 | #define EXTRA_CHECKS MHD_NO | ||
87 | |||
88 | #define MHD_MAX(a,b) (((a)<(b)) ? (b) : (a)) | ||
89 | #define MHD_MIN(a,b) (((a)<(b)) ? (a) : (b)) | ||
90 | |||
91 | |||
92 | /** | ||
93 | * Minimum size by which MHD tries to increment read/write buffers. | ||
94 | * We usually begin with half the available pool space for the | ||
95 | * IO-buffer, but if absolutely needed we additively grow by the | ||
96 | * number of bytes given here (up to -- theoretically -- the full pool | ||
97 | * space). | ||
98 | */ | ||
99 | #define MHD_BUF_INC_SIZE 1024 | ||
100 | |||
101 | |||
102 | /** | ||
103 | * Handler for fatal errors. | ||
104 | */ | ||
105 | extern MHD_PanicCallback mhd_panic; | ||
106 | |||
107 | /** | ||
108 | * Closure argument for "mhd_panic". | ||
109 | */ | ||
110 | extern void *mhd_panic_cls; | ||
111 | |||
112 | /* If we have Clang or gcc >= 4.5, use __buildin_unreachable() */ | ||
113 | #if defined(__clang__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) | ||
114 | #define BUILTIN_NOT_REACHED __builtin_unreachable() | ||
115 | #elif defined(_MSC_FULL_VER) | ||
116 | #define BUILTIN_NOT_REACHED __assume(0) | ||
117 | #else | ||
118 | #define BUILTIN_NOT_REACHED | ||
119 | #endif | ||
120 | |||
121 | #ifndef MHD_STATICSTR_LEN_ | ||
122 | /** | ||
123 | * Determine length of static string / macro strings at compile time. | ||
124 | */ | ||
125 | #define MHD_STATICSTR_LEN_(macro) (sizeof(macro)/sizeof(char) - 1) | ||
126 | #endif /* ! MHD_STATICSTR_LEN_ */ | ||
127 | |||
128 | |||
129 | /** | ||
130 | * State kept for each MHD daemon. All connections are kept in two | ||
131 | * doubly-linked lists. The first one reflects the state of the | ||
132 | * connection in terms of what operations we are waiting for (read, | ||
133 | * write, locally blocked, cleanup) whereas the second is about its | ||
134 | * timeout state (default or custom). | ||
135 | */ | ||
136 | struct MHD_Daemon | ||
137 | { | ||
138 | /** | ||
139 | * Function to call to handle incoming requests. | ||
140 | */ | ||
141 | MHD_RequestCallback rc; | ||
142 | |||
143 | /** | ||
144 | * Closure for @e rc. | ||
145 | */ | ||
146 | void *rc_cls; | ||
147 | |||
148 | /** | ||
149 | * Function to call for logging. | ||
150 | */ | ||
151 | MHD_LoggingCallback logger; | ||
152 | |||
153 | /** | ||
154 | * Closure for @e logger. | ||
155 | */ | ||
156 | void *logger_cls; | ||
157 | |||
158 | /** | ||
159 | * Function to call to accept/reject connections based on | ||
160 | * the client's IP address. | ||
161 | */ | ||
162 | MHD_AcceptPolicyCallback accept_policy_cb; | ||
163 | |||
164 | /** | ||
165 | * Closure for @e accept_policy_cb. | ||
166 | */ | ||
167 | void *accept_policy_cb_cls; | ||
168 | |||
169 | /** | ||
170 | * Function to call on the full URL early for logging. | ||
171 | */ | ||
172 | MHD_EarlyUriLogCallback early_uri_logger_cb; | ||
173 | |||
174 | /** | ||
175 | * Closure for @e early_uri_logger_cb. | ||
176 | */ | ||
177 | void *early_uri_logger_cls; | ||
178 | |||
179 | /** | ||
180 | * Function to call whenever a connection is started or | ||
181 | * closed. | ||
182 | */ | ||
183 | MHD_NotifyConnectionCallback notify_connection_cb; | ||
184 | |||
185 | /** | ||
186 | * Closure for @e notify_connection_cb. | ||
187 | */ | ||
188 | void *notify_connection_cb_cls; | ||
189 | |||
190 | /** | ||
191 | * Function to call to unescape sequences in URIs and URI arguments. | ||
192 | * See #MHD_daemon_unescape_cb(). | ||
193 | */ | ||
194 | MHD_UnescapeCallback unescape_cb; | ||
195 | |||
196 | /** | ||
197 | * Closure for @e unescape_cb. | ||
198 | */ | ||
199 | void *unescape_cb_cls; | ||
200 | |||
201 | #if HTTPS_SUPPORT | ||
202 | /** | ||
203 | * Which TLS backend should be used. NULL for no TLS. | ||
204 | * This is merely the handle to the dlsym() object, not | ||
205 | * the API. | ||
206 | */ | ||
207 | void *tls_backend_lib; | ||
208 | |||
209 | /** | ||
210 | * Callback functions to use for TLS operations. | ||
211 | */ | ||
212 | struct MHD_TLS_Plugin *tls_api; | ||
213 | #endif | ||
214 | #if ENABLE_DAUTH | ||
215 | |||
216 | /** | ||
217 | * Random values to be used by digest authentication module. | ||
218 | * Size given in @e digest_auth_random_buf_size. | ||
219 | */ | ||
220 | const void *digest_auth_random_buf; | ||
221 | #endif | ||
222 | |||
223 | /** | ||
224 | * Socket address to bind to for the listen socket. | ||
225 | */ | ||
226 | struct sockaddr_storage listen_sa; | ||
227 | |||
228 | /** | ||
229 | * Number of (valid) bytes in @e listen_sa. Zero | ||
230 | * if @e listen_sa is not initialized. | ||
231 | */ | ||
232 | size_t listen_sa_len; | ||
233 | |||
234 | /** | ||
235 | * Buffer size to use for each connection. Default | ||
236 | * is #MHD_POOL_SIZE_DEFAULT. | ||
237 | */ | ||
238 | size_t connection_memory_limit_b; | ||
239 | |||
240 | /** | ||
241 | * Default minimum size by which MHD tries to increment read/write | ||
242 | * buffers. We usually begin with half the available pool space for | ||
243 | * the IO-buffer, but if absolutely needed we additively grow by the | ||
244 | * number of bytes given here (up to -- theoretically -- the full pool | ||
245 | * space). | ||
246 | */ | ||
247 | #define BUF_INC_SIZE_DEFAULT 1024 | ||
248 | |||
249 | /** | ||
250 | * Increment to use when growing the read buffer. Smaller | ||
251 | * than @e connection_memory_limit_b. | ||
252 | */ | ||
253 | size_t connection_memory_increment_b; | ||
254 | |||
255 | /** | ||
256 | * Desired size of the stack for threads created by MHD, | ||
257 | * 0 for system default. | ||
258 | */ | ||
259 | size_t thread_stack_limit_b; | ||
260 | |||
261 | #if ENABLE_DAUTH | ||
262 | |||
263 | /** | ||
264 | * Size of @e digest_auth_random_buf. | ||
265 | */ | ||
266 | size_t digest_auth_random_buf_size; | ||
267 | |||
268 | /** | ||
269 | * Default value for @e digest_nc_length. | ||
270 | */ | ||
271 | #define DIGEST_NC_LENGTH_DEFAULT 4 | ||
272 | |||
273 | /** | ||
274 | * Desired length of the internal array with the nonce and | ||
275 | * nonce counters for digest authentication. | ||
276 | */ | ||
277 | size_t digest_nc_length; | ||
278 | #endif | ||
279 | |||
280 | /** | ||
281 | * Default value we use for the listen backlog. | ||
282 | */ | ||
283 | #ifdef SOMAXCONN | ||
284 | #define LISTEN_BACKLOG_DEFAULT SOMAXCONN | ||
285 | #else /* !SOMAXCONN */ | ||
286 | #define LISTEN_BACKLOG_DEFAULT 511 | ||
287 | #endif | ||
288 | |||
289 | /** | ||
290 | * Backlog argument to use for listen. See | ||
291 | * #MHD_daemon_listen_backlog(). | ||
292 | */ | ||
293 | int listen_backlog; | ||
294 | |||
295 | /** | ||
296 | * Default queue length to use with fast open. | ||
297 | */ | ||
298 | #define FO_QUEUE_LENGTH_DEFAULT 50 | ||
299 | |||
300 | /** | ||
301 | * Queue length to use with fast open. | ||
302 | */ | ||
303 | unsigned int fo_queue_length; | ||
304 | |||
305 | /** | ||
306 | * Maximum number of connections MHD accepts. 0 for unlimited. | ||
307 | */ | ||
308 | unsigned int global_connection_limit; | ||
309 | |||
310 | /** | ||
311 | * Maximum number of connections we accept per IP, 0 for unlimited. | ||
312 | */ | ||
313 | unsigned int ip_connection_limit; | ||
314 | |||
315 | /** | ||
316 | * Default timeout in seconds for idle connections. | ||
317 | */ | ||
318 | unsigned int connection_default_timeout_s; | ||
319 | |||
320 | /** | ||
321 | * Listen socket we should use, MHD_INVALID_SOCKET means | ||
322 | * we are to initialize the socket from the other options given. | ||
323 | */ | ||
324 | MHD_socket listen_socket; | ||
325 | |||
326 | /** | ||
327 | * Which threading model do we use? Postive | ||
328 | * numbers indicate the number of worker threads to be used. | ||
329 | */ | ||
330 | enum MHD_ThreadingModel threading_model; | ||
331 | |||
332 | /** | ||
333 | * When should we use TCP_FASTOPEN? | ||
334 | * See #MHD_daemon_tcp_fastopen(). | ||
335 | */ | ||
336 | enum MHD_FastOpenMethod fast_open_method; | ||
337 | |||
338 | /** | ||
339 | * Address family to use when listening. | ||
340 | * Default is #MHD_AF_AUTO. | ||
341 | */ | ||
342 | enum MHD_AddressFamily listen_af; | ||
343 | |||
344 | /** | ||
345 | * Sets active/desired style of the event loop. | ||
346 | * (Auto only possible during initialization, later set to | ||
347 | * the actual style we use.) | ||
348 | */ | ||
349 | enum MHD_EventLoopSyscall event_loop_syscall; | ||
350 | |||
351 | /** | ||
352 | * How strictly do we enforce the HTTP protocol? | ||
353 | * See #MHD_daemon_protocol_strict_level(). | ||
354 | */ | ||
355 | enum MHD_ProtocolStrictLevel protocol_strict_level; | ||
356 | |||
357 | /** | ||
358 | * On which port should we listen on? Only effective if we were not | ||
359 | * given a listen socket or a full address via | ||
360 | * #MHD_daemon_bind_sa(). 0 means not set, which means to default | ||
361 | * to 80 (http) or 443 (https) respectively. | ||
362 | */ | ||
363 | uint16_t listen_port; | ||
364 | |||
365 | /** | ||
366 | * Suppress generating the "Date:" header, this system | ||
367 | * lacks an RTC (or developer is hyper-optimizing). See | ||
368 | * #MHD_daemon_suppress_date_no_clock(). | ||
369 | */ | ||
370 | bool suppress_date; | ||
371 | |||
372 | /** | ||
373 | * The use of the inter-thread communication channel is disabled. | ||
374 | * See #MHD_daemon_disable_itc(). | ||
375 | */ | ||
376 | bool disable_itc; | ||
377 | |||
378 | /** | ||
379 | * Disable #MHD_action_suspend() functionality. See | ||
380 | * #MHD_daemon_disallow_suspend_resume(). | ||
381 | */ | ||
382 | bool disallow_suspend_resume; | ||
383 | |||
384 | /** | ||
385 | * Disable #MHD_action_upgrade() functionality. See | ||
386 | * #MHD_daemon_disallow_upgrade(). | ||
387 | */ | ||
388 | bool disallow_upgrade; | ||
389 | |||
390 | /** | ||
391 | * Disables optional calls to `shutdown()` and enables aggressive | ||
392 | * non-blocking optimistic reads and other potentially unsafe | ||
393 | * optimizations. See #MHD_daemon_enable_turbo(). | ||
394 | */ | ||
395 | bool enable_turbo; | ||
396 | |||
397 | /** | ||
398 | * Allow reusing the address:port combination when binding. | ||
399 | * See #MHD_daemon_listen_allow_address_reuse(). | ||
400 | */ | ||
401 | bool allow_address_reuse; | ||
402 | |||
403 | |||
404 | |||
405 | }; | ||
406 | |||
407 | |||
408 | |||
409 | |||
410 | |||
411 | |||
412 | #endif | ||
diff --git a/src/lib/request.c b/src/lib/request.c new file mode 100644 index 00000000..8af35b28 --- /dev/null +++ b/src/lib/request.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /** | ||
2 | * Get all of the headers from the request. | ||
3 | * | ||
4 | * @param request request to get values from | ||
5 | * @param kind types of values to iterate over, can be a bitmask | ||
6 | * @param iterator callback to call on each header; | ||
7 | * maybe NULL (then just count headers) | ||
8 | * @param iterator_cls extra argument to @a iterator | ||
9 | * @return number of entries iterated over | ||
10 | * @ingroup request | ||
11 | */ | ||
12 | _MHD_EXTERN unsigned int | ||
13 | MHD_request_get_values (struct MHD_Request *request, | ||
14 | enum MHD_ValueKind kind, | ||
15 | MHD_KeyValueIterator iterator, | ||
16 | void *iterator_cls); | ||
17 | |||
18 | |||
19 | /** | ||
20 | * This function can be used to add an entry to the HTTP headers of a | ||
21 | * request (so that the #MHD_request_get_values function will | ||
22 | * return them -- and the `struct MHD_PostProcessor` will also see | ||
23 | * them). This maybe required in certain situations (see Mantis | ||
24 | * #1399) where (broken) HTTP implementations fail to supply values | ||
25 | * needed by the post processor (or other parts of the application). | ||
26 | * | ||
27 | * This function MUST only be called from within the | ||
28 | * request callbacks (otherwise, access maybe improperly | ||
29 | * synchronized). Furthermore, the client must guarantee that the key | ||
30 | * and value arguments are 0-terminated strings that are NOT freed | ||
31 | * until the connection is closed. (The easiest way to do this is by | ||
32 | * passing only arguments to permanently allocated strings.). | ||
33 | * | ||
34 | * @param request the request for which a | ||
35 | * value should be set | ||
36 | * @param kind kind of the value | ||
37 | * @param key key for the value | ||
38 | * @param value the value itself | ||
39 | * @return #MHD_NO if the operation could not be | ||
40 | * performed due to insufficient memory; | ||
41 | * #MHD_YES on success | ||
42 | * @ingroup request | ||
43 | */ | ||
44 | _MHD_EXTERN enum MHD_Bool | ||
45 | MHD_request_set_value (struct MHD_Request *request, | ||
46 | enum MHD_ValueKind kind, | ||
47 | const char *key, | ||
48 | const char *value); | ||
49 | |||
50 | |||
51 | /** | ||
52 | * Get a particular header value. If multiple | ||
53 | * values match the kind, return any one of them. | ||
54 | * | ||
55 | * @param request request to get values from | ||
56 | * @param kind what kind of value are we looking for | ||
57 | * @param key the header to look for, NULL to lookup 'trailing' value without a key | ||
58 | * @return NULL if no such item was found | ||
59 | * @ingroup request | ||
60 | */ | ||
61 | _MHD_EXTERN const char * | ||
62 | MHD_request_lookup_value (struct MHD_Request *request, | ||
63 | enum MHD_ValueKind kind, | ||
64 | const char *key); | ||
65 | |||
66 | |||
67 | |||
68 | |||
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 56cd4538..fdc81ccc 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -4456,8 +4456,8 @@ unescape_wrapper (void *cls, | |||
4456 | struct MHD_Connection *connection, | 4456 | struct MHD_Connection *connection, |
4457 | char *val) | 4457 | char *val) |
4458 | { | 4458 | { |
4459 | (void)cls; /* Mute compiler warning. */ | 4459 | (void) cls; /* Mute compiler warning. */ |
4460 | (void)connection; /* Mute compiler warning. */ | 4460 | (void) connection; /* Mute compiler warning. */ |
4461 | return MHD_http_unescape (val); | 4461 | return MHD_http_unescape (val); |
4462 | } | 4462 | } |
4463 | 4463 | ||
@@ -5425,6 +5425,7 @@ MHD_start_daemon_va (unsigned int flags, | |||
5425 | MHD_DLOG (daemon, _("Using debug build of libmicrohttpd.\n") ); | 5425 | MHD_DLOG (daemon, _("Using debug build of libmicrohttpd.\n") ); |
5426 | #endif /* HAVE_MESSAGES */ | 5426 | #endif /* HAVE_MESSAGES */ |
5427 | #endif /* ! NDEBUG */ | 5427 | #endif /* ! NDEBUG */ |
5428 | |||
5428 | if ( (0 != (*pflags & MHD_USE_ITC)) && | 5429 | if ( (0 != (*pflags & MHD_USE_ITC)) && |
5429 | (0 == daemon->worker_pool_size) ) | 5430 | (0 == daemon->worker_pool_size) ) |
5430 | { | 5431 | { |