aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/action_continue.c4
-rw-r--r--src/lib/action_from_response.c53
-rw-r--r--src/lib/action_parse_post.c4
-rw-r--r--src/lib/action_process_upload.c8
-rw-r--r--src/lib/action_suspend.c70
-rw-r--r--src/lib/base64.c55
-rw-r--r--src/lib/base64.h2
-rw-r--r--src/lib/connection_add.c1204
-rw-r--r--src/lib/connection_add.h4
-rw-r--r--src/lib/connection_call_handlers.c4026
-rw-r--r--src/lib/connection_call_handlers.h12
-rw-r--r--src/lib/connection_cleanup.c132
-rw-r--r--src/lib/connection_cleanup.h6
-rw-r--r--src/lib/connection_close.c58
-rw-r--r--src/lib/connection_close.h4
-rw-r--r--src/lib/connection_finish_forward.c46
-rw-r--r--src/lib/connection_finish_forward.h2
-rw-r--r--src/lib/connection_info.c12
-rw-r--r--src/lib/connection_options.c70
-rw-r--r--src/lib/connection_update_last_activity.c11
-rw-r--r--src/lib/connection_update_last_activity.h2
-rw-r--r--src/lib/daemon_close_all_connections.c179
-rw-r--r--src/lib/daemon_close_all_connections.h2
-rw-r--r--src/lib/daemon_create.c50
-rw-r--r--src/lib/daemon_destroy.c158
-rw-r--r--src/lib/daemon_epoll.c533
-rw-r--r--src/lib/daemon_epoll.h4
-rw-r--r--src/lib/daemon_get_timeout.c78
-rw-r--r--src/lib/daemon_info.c98
-rw-r--r--src/lib/daemon_ip_limit.c120
-rw-r--r--src/lib/daemon_ip_limit.h12
-rw-r--r--src/lib/daemon_options.c140
-rw-r--r--src/lib/daemon_poll.c368
-rw-r--r--src/lib/daemon_poll.h14
-rw-r--r--src/lib/daemon_quiesce.c103
-rw-r--r--src/lib/daemon_run.c36
-rw-r--r--src/lib/daemon_select.c699
-rw-r--r--src/lib/daemon_select.h6
-rw-r--r--src/lib/daemon_start.c1013
-rw-r--r--src/lib/init.c40
-rw-r--r--src/lib/init.h2
-rw-r--r--src/lib/internal.c288
-rw-r--r--src/lib/internal.h161
-rw-r--r--src/lib/md5.c226
-rw-r--r--src/lib/md5.h24
-rw-r--r--src/lib/memorypool.c118
-rw-r--r--src/lib/memorypool.h12
-rw-r--r--src/lib/mhd_assert.h16
-rw-r--r--src/lib/mhd_byteorder.h47
-rw-r--r--src/lib/mhd_compat.c24
-rw-r--r--src/lib/mhd_compat.h18
-rw-r--r--src/lib/mhd_itc.c6
-rw-r--r--src/lib/mhd_itc.h103
-rw-r--r--src/lib/mhd_itc_types.h2
-rw-r--r--src/lib/mhd_limits.h38
-rw-r--r--src/lib/mhd_locks.h47
-rw-r--r--src/lib/mhd_mono_clock.c178
-rw-r--r--src/lib/mhd_mono_clock.h6
-rw-r--r--src/lib/mhd_sockets.c239
-rw-r--r--src/lib/mhd_sockets.h239
-rw-r--r--src/lib/mhd_str.c347
-rw-r--r--src/lib/mhd_str.h103
-rw-r--r--src/lib/mhd_threads.c162
-rw-r--r--src/lib/mhd_threads.h78
-rw-r--r--src/lib/reason_phrase.c2
-rw-r--r--src/lib/request.c72
-rw-r--r--src/lib/request_info.c12
-rw-r--r--src/lib/request_resume.c185
-rw-r--r--src/lib/request_resume.h2
-rw-r--r--src/lib/response.c126
-rw-r--r--src/lib/response_for_upgrade.c20
-rw-r--r--src/lib/response_from_buffer.c46
-rw-r--r--src/lib/response_from_callback.c14
-rw-r--r--src/lib/response_from_fd.c85
-rw-r--r--src/lib/response_options.c5
-rw-r--r--src/lib/sysfdsetsize.c2
-rw-r--r--src/lib/tsearch.c122
-rw-r--r--src/lib/tsearch.h24
-rw-r--r--src/lib/upgrade_process.c491
-rw-r--r--src/lib/upgrade_process.h2
-rw-r--r--src/lib/version.c155
81 files changed, 6732 insertions, 6555 deletions
diff --git a/src/lib/action_continue.c b/src/lib/action_continue.c
index 20c351ad..9d98940b 100644
--- a/src/lib/action_continue.c
+++ b/src/lib/action_continue.c
@@ -35,11 +35,11 @@
35 */ 35 */
36static enum MHD_StatusCode 36static enum MHD_StatusCode
37cont_action (void *cls, 37cont_action (void *cls,
38 struct MHD_Request *request) 38 struct MHD_Request *request)
39{ 39{
40 (void) cls; 40 (void) cls;
41 (void) request; 41 (void) request;
42 /* not sure yet, but this function body may 42 /* not sure yet, but this function body may
43 just legitimately stay empty... */ 43 just legitimately stay empty... */
44 return MHD_SC_OK; 44 return MHD_SC_OK;
45} 45}
diff --git a/src/lib/action_from_response.c b/src/lib/action_from_response.c
index 43f33cb5..6253fb22 100644
--- a/src/lib/action_from_response.c
+++ b/src/lib/action_from_response.c
@@ -36,7 +36,7 @@
36 */ 36 */
37static enum MHD_StatusCode 37static enum MHD_StatusCode
38response_action (void *cls, 38response_action (void *cls,
39 struct MHD_Request *request) 39 struct MHD_Request *request)
40{ 40{
41 struct MHD_Response *response = cls; 41 struct MHD_Response *response = cls;
42 struct MHD_Daemon *daemon = request->daemon; 42 struct MHD_Daemon *daemon = request->daemon;
@@ -49,14 +49,15 @@ response_action (void *cls,
49#ifdef UPGRADE_SUPPORT 49#ifdef UPGRADE_SUPPORT
50 if ( (NULL != response->upgrade_handler) && 50 if ( (NULL != response->upgrade_handler) &&
51 daemon->disallow_upgrade ) 51 daemon->disallow_upgrade )
52 { 52 {
53#ifdef HAVE_MESSAGES 53#ifdef HAVE_MESSAGES
54 MHD_DLOG (daemon, 54 MHD_DLOG (daemon,
55 MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED, 55 MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED,
56 _("Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n")); 56 _ (
57 "Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n"));
57#endif 58#endif
58 return MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED; 59 return MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED;
59 } 60 }
60#endif /* UPGRADE_SUPPORT */ 61#endif /* UPGRADE_SUPPORT */
61 request->response = response; 62 request->response = response;
62#if defined(_MHD_HAVE_SENDFILE) 63#if defined(_MHD_HAVE_SENDFILE)
@@ -74,21 +75,21 @@ response_action (void *cls,
74 (MHD_HTTP_OK > response->status_code) || 75 (MHD_HTTP_OK > response->status_code) ||
75 (MHD_HTTP_NO_CONTENT == response->status_code) || 76 (MHD_HTTP_NO_CONTENT == response->status_code) ||
76 (MHD_HTTP_NOT_MODIFIED == response->status_code) ) 77 (MHD_HTTP_NOT_MODIFIED == response->status_code) )
77 { 78 {
78 /* if this is a "HEAD" request, or a status code for 79 /* if this is a "HEAD" request, or a status code for
79 which a body is not allowed, pretend that we 80 which a body is not allowed, pretend that we
80 have already sent the full message body. */ 81 have already sent the full message body. */
81 request->response_write_position = response->total_size; 82 request->response_write_position = response->total_size;
82 } 83 }
83 if ( (MHD_REQUEST_HEADERS_PROCESSED == request->state) && 84 if ( (MHD_REQUEST_HEADERS_PROCESSED == request->state) &&
84 ( (MHD_METHOD_POST == request->method) || 85 ( (MHD_METHOD_POST == request->method) ||
85 (MHD_METHOD_PUT == request->method) ) ) 86 (MHD_METHOD_PUT == request->method) ) )
86 { 87 {
87 /* response was queued "early", refuse to read body / footers or 88 /* response was queued "early", refuse to read body / footers or
88 further requests! */ 89 further requests! */
89 request->connection->read_closed = true; 90 request->connection->read_closed = true;
90 request->state = MHD_REQUEST_FOOTERS_RECEIVED; 91 request->state = MHD_REQUEST_FOOTERS_RECEIVED;
91 } 92 }
92 if (! request->in_idle) 93 if (! request->in_idle)
93 (void) MHD_request_handle_idle_ (request); 94 (void) MHD_request_handle_idle_ (request);
94 return MHD_SC_OK; 95 return MHD_SC_OK;
@@ -114,16 +115,16 @@ response_action (void *cls,
114 */ 115 */
115_MHD_EXTERN const struct MHD_Action * 116_MHD_EXTERN const struct MHD_Action *
116MHD_action_from_response (struct MHD_Response *response, 117MHD_action_from_response (struct MHD_Response *response,
117 enum MHD_Bool destroy_after_use) 118 enum MHD_Bool destroy_after_use)
118{ 119{
119 response->action.action = &response_action; 120 response->action.action = &response_action;
120 response->action.action_cls = response; 121 response->action.action_cls = response;
121 if (! destroy_after_use) 122 if (! destroy_after_use)
122 { 123 {
123 MHD_mutex_lock_chk_ (&response->mutex); 124 MHD_mutex_lock_chk_ (&response->mutex);
124 response->reference_count++; 125 response->reference_count++;
125 MHD_mutex_unlock_chk_ (&response->mutex); 126 MHD_mutex_unlock_chk_ (&response->mutex);
126 } 127 }
127 return &response->action; 128 return &response->action;
128} 129}
129 130
diff --git a/src/lib/action_parse_post.c b/src/lib/action_parse_post.c
index c60e793d..53757933 100644
--- a/src/lib/action_parse_post.c
+++ b/src/lib/action_parse_post.c
@@ -52,8 +52,8 @@
52 */ 52 */
53const struct MHD_Action * 53const struct MHD_Action *
54MHD_action_parse_post (size_t buffer_size, 54MHD_action_parse_post (size_t buffer_size,
55 MHD_PostDataIterator iter, 55 MHD_PostDataIterator iter,
56 void *iter_cls) 56 void *iter_cls)
57{ 57{
58 return NULL; /* not yet implemented */ 58 return NULL; /* not yet implemented */
59} 59}
diff --git a/src/lib/action_process_upload.c b/src/lib/action_process_upload.c
index cafd5d3c..0e9722cd 100644
--- a/src/lib/action_process_upload.c
+++ b/src/lib/action_process_upload.c
@@ -49,13 +49,13 @@ struct UploadAction
49 * 49 *
50 * @param cls the `struct UploadAction` with the 50 * @param cls the `struct UploadAction` with the
51 * function we are to call for upload data 51 * function we are to call for upload data
52 * @param request the request for which we are to process 52 * @param request the request for which we are to process
53 * upload data 53 * upload data
54 * @return #MHD_SC_OK on success 54 * @return #MHD_SC_OK on success
55 */ 55 */
56static enum MHD_StatusCode 56static enum MHD_StatusCode
57upload_action (void *cls, 57upload_action (void *cls,
58 struct MHD_Request *request) 58 struct MHD_Request *request)
59{ 59{
60 struct UploadAction *ua = cls; 60 struct UploadAction *ua = cls;
61 61
@@ -75,7 +75,7 @@ upload_action (void *cls,
75 */ 75 */
76const struct MHD_Action * 76const struct MHD_Action *
77MHD_action_process_upload (MHD_UploadCallback uc, 77MHD_action_process_upload (MHD_UploadCallback uc,
78 void *uc_cls) 78 void *uc_cls)
79{ 79{
80 struct UploadAction *ua; 80 struct UploadAction *ua;
81 81
@@ -90,5 +90,3 @@ MHD_action_process_upload (MHD_UploadCallback uc,
90 90
91 91
92/* end of action_process_upload.c */ 92/* end of action_process_upload.c */
93
94
diff --git a/src/lib/action_suspend.c b/src/lib/action_suspend.c
index bf5adc34..c176e494 100644
--- a/src/lib/action_suspend.c
+++ b/src/lib/action_suspend.c
@@ -35,7 +35,7 @@
35 */ 35 */
36static enum MHD_StatusCode 36static enum MHD_StatusCode
37suspend_action (void *cls, 37suspend_action (void *cls,
38 struct MHD_Request *request) 38 struct MHD_Request *request)
39{ 39{
40 (void) cls; 40 (void) cls;
41 struct MHD_Connection *connection = request->connection; 41 struct MHD_Connection *connection = request->connection;
@@ -43,24 +43,24 @@ suspend_action (void *cls,
43 43
44 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 44 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
45 if (connection->resuming) 45 if (connection->resuming)
46 { 46 {
47 /* suspending again while we didn't even complete resuming yet */ 47 /* suspending again while we didn't even complete resuming yet */
48 connection->resuming = false; 48 connection->resuming = false;
49 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 49 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
50 return MHD_SC_OK; 50 return MHD_SC_OK;
51 } 51 }
52 if (daemon->threading_mode != MHD_TM_THREAD_PER_CONNECTION) 52 if (daemon->threading_mode != MHD_TM_THREAD_PER_CONNECTION)
53 { 53 {
54 if (connection->connection_timeout == 54 if (connection->connection_timeout ==
55 daemon->connection_default_timeout) 55 daemon->connection_default_timeout)
56 XDLL_remove (daemon->normal_timeout_head, 56 XDLL_remove (daemon->normal_timeout_head,
57 daemon->normal_timeout_tail, 57 daemon->normal_timeout_tail,
58 connection); 58 connection);
59 else 59 else
60 XDLL_remove (daemon->manual_timeout_head, 60 XDLL_remove (daemon->manual_timeout_head,
61 daemon->manual_timeout_tail, 61 daemon->manual_timeout_tail,
62 connection); 62 connection);
63 } 63 }
64 DLL_remove (daemon->connections_head, 64 DLL_remove (daemon->connections_head,
65 daemon->connections_tail, 65 daemon->connections_tail,
66 connection); 66 connection);
@@ -71,25 +71,25 @@ suspend_action (void *cls,
71 connection->suspended = true; 71 connection->suspended = true;
72#ifdef EPOLL_SUPPORT 72#ifdef EPOLL_SUPPORT
73 if (MHD_ELS_EPOLL == daemon->event_loop_syscall) 73 if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
74 {
75 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
76 {
77 EDLL_remove (daemon->eready_head,
78 daemon->eready_tail,
79 connection);
80 connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
81 }
82 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
74 { 83 {
75 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 84 if (0 != epoll_ctl (daemon->epoll_fd,
76 { 85 EPOLL_CTL_DEL,
77 EDLL_remove (daemon->eready_head, 86 connection->socket_fd,
78 daemon->eready_tail, 87 NULL))
79 connection); 88 MHD_PANIC (_ ("Failed to remove FD from epoll set\n"));
80 connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; 89 connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
81 }
82 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
83 {
84 if (0 != epoll_ctl (daemon->epoll_fd,
85 EPOLL_CTL_DEL,
86 connection->socket_fd,
87 NULL))
88 MHD_PANIC (_("Failed to remove FD from epoll set\n"));
89 connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
90 }
91 connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
92 } 90 }
91 connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
92 }
93#endif 93#endif
94 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 94 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
95 return MHD_SC_OK; 95 return MHD_SC_OK;
diff --git a/src/lib/base64.c b/src/lib/base64.c
index 3dc7a142..d7d1ec92 100644
--- a/src/lib/base64.c
+++ b/src/lib/base64.c
@@ -9,45 +9,46 @@
9#include "base64.h" 9#include "base64.h"
10 10
11static const char base64_digits[] = 11static const char base64_digits[] =
12 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
13 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
14 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 14 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
15 0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15 0, 0, 0, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
16 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 16 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26,
17 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 17 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
18 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
21 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
23 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 23 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
24 24
25 25
26char * 26char *
27BASE64Decode(const char* src) 27BASE64Decode (const char*src)
28{ 28{
29 size_t in_len = strlen (src); 29 size_t in_len = strlen (src);
30 char* dest; 30 char*dest;
31 char* result; 31 char*result;
32 32
33 if (in_len % 4) 33 if (in_len % 4)
34 { 34 {
35 /* Wrong base64 string length */ 35 /* Wrong base64 string length */
36 return NULL; 36 return NULL;
37 } 37 }
38 result = dest = malloc(in_len / 4 * 3 + 1); 38 result = dest = malloc (in_len / 4 * 3 + 1);
39 if (NULL == result) 39 if (NULL == result)
40 return NULL; /* out of memory */ 40 return NULL; /* out of memory */
41 while (*src) { 41 while (*src)
42 char a = base64_digits[(unsigned char)*(src++)]; 42 {
43 char b = base64_digits[(unsigned char)*(src++)]; 43 char a = base64_digits[(unsigned char) *(src++)];
44 char c = base64_digits[(unsigned char)*(src++)]; 44 char b = base64_digits[(unsigned char) *(src++)];
45 char d = base64_digits[(unsigned char)*(src++)]; 45 char c = base64_digits[(unsigned char) *(src++)];
46 char d = base64_digits[(unsigned char) *(src++)];
46 *(dest++) = (a << 2) | ((b & 0x30) >> 4); 47 *(dest++) = (a << 2) | ((b & 0x30) >> 4);
47 if (c == (char)-1) 48 if (c == (char) -1)
48 break; 49 break;
49 *(dest++) = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2); 50 *(dest++) = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2);
50 if (d == (char)-1) 51 if (d == (char) -1)
51 break; 52 break;
52 *(dest++) = ((c & 0x03) << 6) | d; 53 *(dest++) = ((c & 0x03) << 6) | d;
53 } 54 }
diff --git a/src/lib/base64.h b/src/lib/base64.h
index ba96ca0c..65042c0b 100644
--- a/src/lib/base64.h
+++ b/src/lib/base64.h
@@ -12,6 +12,6 @@
12#include "platform.h" 12#include "platform.h"
13 13
14char * 14char *
15BASE64Decode(const char* src); 15BASE64Decode (const char*src);
16 16
17#endif /* !BASE64_H */ 17#endif /* !BASE64_H */
diff --git a/src/lib/connection_add.c b/src/lib/connection_add.c
index cd933d06..aaf04712 100644
--- a/src/lib/connection_add.c
+++ b/src/lib/connection_add.c
@@ -53,14 +53,14 @@ thread_main_connection_upgrade (struct MHD_Connection *con)
53 with the socket; */ 53 with the socket; */
54 if ( (NULL != daemon->tls_api) && 54 if ( (NULL != daemon->tls_api) &&
55 (MHD_ELS_POLL != daemon->event_loop_syscall) ) 55 (MHD_ELS_POLL != daemon->event_loop_syscall) )
56 { 56 {
57 MHD_daemon_upgrade_connection_with_select_ (con); 57 MHD_daemon_upgrade_connection_with_select_ (con);
58 } 58 }
59#ifdef HAVE_POLL 59#ifdef HAVE_POLL
60 else if (NULL != daemon->tls_api) 60 else if (NULL != daemon->tls_api)
61 { 61 {
62 MHD_daemon_upgrade_connection_with_poll_ (con); 62 MHD_daemon_upgrade_connection_with_poll_ (con);
63 } 63 }
64#endif 64#endif
65 /* end HTTPS */ 65 /* end HTTPS */
66#endif /* HTTPS_SUPPORT */ 66#endif /* HTTPS_SUPPORT */
@@ -111,342 +111,344 @@ thread_main_handle_connection (void *data)
111#endif /* ! HAVE_POLL */ 111#endif /* ! HAVE_POLL */
112 bool was_suspended = false; 112 bool was_suspended = false;
113 113
114 MHD_thread_init_(&con->pid); 114 MHD_thread_init_ (&con->pid);
115 115
116 while ( (! daemon->shutdown) && 116 while ( (! daemon->shutdown) &&
117 (MHD_REQUEST_CLOSED != con->request.state) ) 117 (MHD_REQUEST_CLOSED != con->request.state) )
118 { 118 {
119 const time_t timeout = daemon->connection_default_timeout; 119 const time_t timeout = daemon->connection_default_timeout;
120#ifdef UPGRADE_SUPPORT 120#ifdef UPGRADE_SUPPORT
121 struct MHD_UpgradeResponseHandle * const urh = con->request.urh; 121 struct MHD_UpgradeResponseHandle *const urh = con->request.urh;
122#else /* ! UPGRADE_SUPPORT */ 122#else /* ! UPGRADE_SUPPORT */
123 static const void * const urh = NULL; 123 static const void *const urh = NULL;
124#endif /* ! UPGRADE_SUPPORT */ 124#endif /* ! UPGRADE_SUPPORT */
125 125
126 if ( (con->suspended) && 126 if ( (con->suspended) &&
127 (NULL == urh) ) 127 (NULL == urh) )
128 {
129 /* Connection was suspended, wait for resume. */
130 was_suspended = true;
131 if (! use_poll)
132 {
133 FD_ZERO (&rs);
134 if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
135 &rs,
136 NULL,
137 FD_SETSIZE))
128 { 138 {
129 /* Connection was suspended, wait for resume. */
130 was_suspended = true;
131 if (! use_poll)
132 {
133 FD_ZERO (&rs);
134 if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
135 &rs,
136 NULL,
137 FD_SETSIZE))
138 {
139 #ifdef HAVE_MESSAGES 139 #ifdef HAVE_MESSAGES
140 MHD_DLOG (con->daemon, 140 MHD_DLOG (con->daemon,
141 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, 141 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
142 _("Failed to add FD to fd_set\n")); 142 _ ("Failed to add FD to fd_set\n"));
143 #endif 143 #endif
144 goto exit; 144 goto exit;
145 } 145 }
146 if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1, 146 if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1,
147 &rs, 147 &rs,
148 NULL, 148 NULL,
149 NULL, 149 NULL,
150 NULL)) 150 NULL))
151 { 151 {
152 const int err = MHD_socket_get_error_(); 152 const int err = MHD_socket_get_error_ ();
153 153
154 if (MHD_SCKT_ERR_IS_EINTR_(err)) 154 if (MHD_SCKT_ERR_IS_EINTR_ (err))
155 continue; 155 continue;
156#ifdef HAVE_MESSAGES 156#ifdef HAVE_MESSAGES
157 MHD_DLOG (con->daemon, 157 MHD_DLOG (con->daemon,
158 MHD_SC_UNEXPECTED_SELECT_ERROR, 158 MHD_SC_UNEXPECTED_SELECT_ERROR,
159 _("Error during select (%d): `%s'\n"), 159 _ ("Error during select (%d): `%s'\n"),
160 err, 160 err,
161 MHD_socket_strerr_ (err)); 161 MHD_socket_strerr_ (err));
162#endif 162#endif
163 break; 163 break;
164 } 164 }
165 } 165 }
166#ifdef HAVE_POLL 166#ifdef HAVE_POLL
167 else /* use_poll */ 167 else /* use_poll */
168 { 168 {
169 p[0].events = POLLIN; 169 p[0].events = POLLIN;
170 p[0].fd = MHD_itc_r_fd_ (daemon->itc); 170 p[0].fd = MHD_itc_r_fd_ (daemon->itc);
171 p[0].revents = 0; 171 p[0].revents = 0;
172 if (0 > MHD_sys_poll_ (p, 172 if (0 > MHD_sys_poll_ (p,
173 1, 173 1,
174 -1)) 174 -1))
175 { 175 {
176 if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_)) 176 if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_))
177 continue; 177 continue;
178#ifdef HAVE_MESSAGES 178#ifdef HAVE_MESSAGES
179 MHD_DLOG (con->daemon, 179 MHD_DLOG (con->daemon,
180 MHD_SC_UNEXPECTED_POLL_ERROR, 180 MHD_SC_UNEXPECTED_POLL_ERROR,
181 _("Error during poll: `%s'\n"), 181 _ ("Error during poll: `%s'\n"),
182 MHD_socket_last_strerr_ ()); 182 MHD_socket_last_strerr_ ());
183#endif 183#endif
184 break; 184 break;
185 } 185 }
186 } 186 }
187#endif /* HAVE_POLL */ 187#endif /* HAVE_POLL */
188 MHD_itc_clear_ (daemon->itc); 188 MHD_itc_clear_ (daemon->itc);
189 continue; /* Check again for resume. */ 189 continue; /* Check again for resume. */
190 } /* End of "suspended" branch. */ 190 } /* End of "suspended" branch. */
191 191
192 if (was_suspended) 192 if (was_suspended)
193 { 193 {
194 MHD_connection_update_last_activity_ (con); /* Reset timeout timer. */ 194 MHD_connection_update_last_activity_ (con); /* Reset timeout timer. */
195 /* Process response queued during suspend and update states. */ 195 /* Process response queued during suspend and update states. */
196 MHD_request_handle_idle_ (&con->request); 196 MHD_request_handle_idle_ (&con->request);
197 was_suspended = false; 197 was_suspended = false;
198 } 198 }
199 199
200 tvp = NULL; 200 tvp = NULL;
201 201
202 if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->request.event_loop_info) 202 if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->request.event_loop_info)
203#ifdef HTTPS_SUPPORT 203#ifdef HTTPS_SUPPORT
204 || ( (con->tls_read_ready) && 204 || ( (con->tls_read_ready) &&
205 (MHD_EVENT_LOOP_INFO_READ == con->request.event_loop_info) ) 205 (MHD_EVENT_LOOP_INFO_READ == con->request.event_loop_info) )
206#endif /* HTTPS_SUPPORT */ 206#endif /* HTTPS_SUPPORT */
207 ) 207 )
208 { 208 {
209 /* do not block: more data may be inside of TLS buffers waiting or 209 /* do not block: more data may be inside of TLS buffers waiting or
210 * application must provide response data */ 210 * application must provide response data */
211 tv.tv_sec = 0; 211 tv.tv_sec = 0;
212 tv.tv_usec = 0; 212 tv.tv_usec = 0;
213 tvp = &tv; 213 tvp = &tv;
214 } 214 }
215 if ( (NULL == tvp) && 215 if ( (NULL == tvp) &&
216 (timeout > 0) ) 216 (timeout > 0) )
217 { 217 {
218 now = MHD_monotonic_sec_counter(); 218 now = MHD_monotonic_sec_counter ();
219 if (now - con->last_activity > timeout) 219 if (now - con->last_activity > timeout)
220 tv.tv_sec = 0; 220 tv.tv_sec = 0;
221 else 221 else
222 { 222 {
223 const time_t seconds_left = timeout - (now - con->last_activity); 223 const time_t seconds_left = timeout - (now - con->last_activity);
224#if !defined(_WIN32) || defined(__CYGWIN__) 224#if ! defined(_WIN32) || defined(__CYGWIN__)
225 tv.tv_sec = seconds_left; 225 tv.tv_sec = seconds_left;
226#else /* _WIN32 && !__CYGWIN__ */ 226#else /* _WIN32 && !__CYGWIN__ */
227 if (seconds_left > TIMEVAL_TV_SEC_MAX) 227 if (seconds_left > TIMEVAL_TV_SEC_MAX)
228 tv.tv_sec = TIMEVAL_TV_SEC_MAX; 228 tv.tv_sec = TIMEVAL_TV_SEC_MAX;
229 else 229 else
230 tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left; 230 tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left;
231#endif /* _WIN32 && ! __CYGWIN__ */ 231#endif /* _WIN32 && ! __CYGWIN__ */
232 } 232 }
233 tv.tv_usec = 0; 233 tv.tv_usec = 0;
234 tvp = &tv; 234 tvp = &tv;
235 } 235 }
236 if (! use_poll) 236 if (! use_poll)
237 { 237 {
238 /* use select */ 238 /* use select */
239 bool err_state = false; 239 bool err_state = false;
240 240
241 FD_ZERO (&rs); 241 FD_ZERO (&rs);
242 FD_ZERO (&ws); 242 FD_ZERO (&ws);
243 FD_ZERO (&es); 243 FD_ZERO (&es);
244 maxsock = MHD_INVALID_SOCKET; 244 maxsock = MHD_INVALID_SOCKET;
245 switch (con->request.event_loop_info) 245 switch (con->request.event_loop_info)
246 { 246 {
247 case MHD_EVENT_LOOP_INFO_READ: 247 case MHD_EVENT_LOOP_INFO_READ:
248 if (! MHD_add_to_fd_set_ (con->socket_fd, 248 if (! MHD_add_to_fd_set_ (con->socket_fd,
249 &rs, 249 &rs,
250 &maxsock, 250 &maxsock,
251 FD_SETSIZE)) 251 FD_SETSIZE))
252 err_state = true; 252 err_state = true;
253 break; 253 break;
254 case MHD_EVENT_LOOP_INFO_WRITE: 254 case MHD_EVENT_LOOP_INFO_WRITE:
255 if (! MHD_add_to_fd_set_ (con->socket_fd, 255 if (! MHD_add_to_fd_set_ (con->socket_fd,
256 &ws, 256 &ws,
257 &maxsock, 257 &maxsock,
258 FD_SETSIZE)) 258 FD_SETSIZE))
259 err_state = true; 259 err_state = true;
260 break; 260 break;
261 case MHD_EVENT_LOOP_INFO_BLOCK: 261 case MHD_EVENT_LOOP_INFO_BLOCK:
262 if (! MHD_add_to_fd_set_ (con->socket_fd, 262 if (! MHD_add_to_fd_set_ (con->socket_fd,
263 &es, 263 &es,
264 &maxsock, 264 &maxsock,
265 FD_SETSIZE)) 265 FD_SETSIZE))
266 err_state = true; 266 err_state = true;
267 break; 267 break;
268 case MHD_EVENT_LOOP_INFO_CLEANUP: 268 case MHD_EVENT_LOOP_INFO_CLEANUP:
269 /* how did we get here!? */ 269 /* how did we get here!? */
270 goto exit; 270 goto exit;
271 } 271 }
272#if WINDOWS 272#if WINDOWS
273 if (MHD_ITC_IS_VALID_(daemon->itc) ) 273 if (MHD_ITC_IS_VALID_ (daemon->itc) )
274 { 274 {
275 if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), 275 if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
276 &rs, 276 &rs,
277 &maxsock, 277 &maxsock,
278 FD_SETSIZE)) 278 FD_SETSIZE))
279 err_state = 1; 279 err_state = 1;
280 } 280 }
281#endif 281#endif
282 if (err_state) 282 if (err_state)
283 { 283 {
284#ifdef HAVE_MESSAGES 284#ifdef HAVE_MESSAGES
285 MHD_DLOG (con->daemon, 285 MHD_DLOG (con->daemon,
286 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, 286 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
287 _("Failed to add FD to fd_set\n")); 287 _ ("Failed to add FD to fd_set\n"));
288#endif 288#endif
289 goto exit; 289 goto exit;
290 } 290 }
291 291
292 num_ready = MHD_SYS_select_ (maxsock + 1, 292 num_ready = MHD_SYS_select_ (maxsock + 1,
293 &rs, 293 &rs,
294 &ws, 294 &ws,
295 &es, 295 &es,
296 tvp); 296 tvp);
297 if (num_ready < 0) 297 if (num_ready < 0)
298 { 298 {
299 const int err = MHD_socket_get_error_(); 299 const int err = MHD_socket_get_error_ ();
300 300
301 if (MHD_SCKT_ERR_IS_EINTR_(err)) 301 if (MHD_SCKT_ERR_IS_EINTR_ (err))
302 continue; 302 continue;
303#ifdef HAVE_MESSAGES 303#ifdef HAVE_MESSAGES
304 MHD_DLOG (con->daemon, 304 MHD_DLOG (con->daemon,
305 MHD_SC_UNEXPECTED_SELECT_ERROR, 305 MHD_SC_UNEXPECTED_SELECT_ERROR,
306 _("Error during select (%d): `%s'\n"), 306 _ ("Error during select (%d): `%s'\n"),
307 err, 307 err,
308 MHD_socket_strerr_ (err)); 308 MHD_socket_strerr_ (err));
309#endif 309#endif
310 break; 310 break;
311 } 311 }
312#if WINDOWS 312#if WINDOWS
313 /* Clear ITC before other processing so additional 313 /* Clear ITC before other processing so additional
314 * signals will trigger select() again */ 314 * signals will trigger select() again */
315 if ( (MHD_ITC_IS_VALID_(daemon->itc)) && 315 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
316 (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), 316 (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
317 &rs)) ) 317 &rs)) )
318 MHD_itc_clear_ (daemon->itc); 318 MHD_itc_clear_ (daemon->itc);
319#endif 319#endif
320 if (MHD_NO == 320 if (MHD_NO ==
321 MHD_connection_call_handlers_ (con, 321 MHD_connection_call_handlers_ (con,
322 FD_ISSET (con->socket_fd, 322 FD_ISSET (con->socket_fd,
323 &rs), 323 &rs),
324 FD_ISSET (con->socket_fd, 324 FD_ISSET (con->socket_fd,
325 &ws), 325 &ws),
326 FD_ISSET (con->socket_fd, 326 FD_ISSET (con->socket_fd,
327 &es)) ) 327 &es)) )
328 goto exit; 328 goto exit;
329 } 329 }
330#ifdef HAVE_POLL 330#ifdef HAVE_POLL
331 else 331 else
332 { 332 {
333 /* use poll */ 333 /* use poll */
334 memset (&p, 334 memset (&p,
335 0, 335 0,
336 sizeof (p)); 336 sizeof (p));
337 p[0].fd = con->socket_fd; 337 p[0].fd = con->socket_fd;
338 switch (con->request.event_loop_info) 338 switch (con->request.event_loop_info)
339 { 339 {
340 case MHD_EVENT_LOOP_INFO_READ: 340 case MHD_EVENT_LOOP_INFO_READ:
341 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; 341 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
342 break; 342 break;
343 case MHD_EVENT_LOOP_INFO_WRITE: 343 case MHD_EVENT_LOOP_INFO_WRITE:
344 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; 344 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
345 break; 345 break;
346 case MHD_EVENT_LOOP_INFO_BLOCK: 346 case MHD_EVENT_LOOP_INFO_BLOCK:
347 p[0].events |= MHD_POLL_EVENTS_ERR_DISC; 347 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
348 break; 348 break;
349 case MHD_EVENT_LOOP_INFO_CLEANUP: 349 case MHD_EVENT_LOOP_INFO_CLEANUP:
350 /* how did we get here!? */ 350 /* how did we get here!? */
351 goto exit; 351 goto exit;
352 } 352 }
353#if WINDOWS 353#if WINDOWS
354 extra_slot = 0; 354 extra_slot = 0;
355 if (MHD_ITC_IS_VALID_(daemon->itc)) 355 if (MHD_ITC_IS_VALID_ (daemon->itc))
356 { 356 {
357 p[1].events |= POLLIN; 357 p[1].events |= POLLIN;
358 p[1].fd = MHD_itc_r_fd_ (daemon->itc); 358 p[1].fd = MHD_itc_r_fd_ (daemon->itc);
359 p[1].revents = 0; 359 p[1].revents = 0;
360 extra_slot = 1; 360 extra_slot = 1;
361 } 361 }
362#endif 362#endif
363 if (MHD_sys_poll_ (p, 363 if (MHD_sys_poll_ (p,
364#if WINDOWS 364#if WINDOWS
365 1 + extra_slot, 365 1 + extra_slot,
366#else 366#else
367 1, 367 1,
368#endif 368#endif
369 (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) 369 (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
370 { 370 {
371 if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_)) 371 if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_))
372 continue; 372 continue;
373#ifdef HAVE_MESSAGES 373#ifdef HAVE_MESSAGES
374 MHD_DLOG (con->daemon, 374 MHD_DLOG (con->daemon,
375 MHD_SC_UNEXPECTED_POLL_ERROR, 375 MHD_SC_UNEXPECTED_POLL_ERROR,
376 _("Error during poll: `%s'\n"), 376 _ ("Error during poll: `%s'\n"),
377 MHD_socket_last_strerr_ ()); 377 MHD_socket_last_strerr_ ());
378#endif 378#endif
379 break; 379 break;
380 } 380 }
381#if WINDOWS 381#if WINDOWS
382 /* Clear ITC before other processing so additional 382 /* Clear ITC before other processing so additional
383 * signals will trigger poll() again */ 383 * signals will trigger poll() again */
384 if ( (MHD_ITC_IS_VALID_(daemon->itc)) && 384 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
385 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) ) 385 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
386 MHD_itc_clear_ (daemon->itc); 386 MHD_itc_clear_ (daemon->itc);
387#endif 387#endif
388 if (MHD_NO == 388 if (MHD_NO ==
389 MHD_connection_call_handlers_ (con, 389 MHD_connection_call_handlers_ (con,
390 0 != (p[0].revents & POLLIN), 390 (0 != (p[0].revents & POLLIN)),
391 0 != (p[0].revents & POLLOUT), 391 (0 != (p[0].revents & POLLOUT)),
392 0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC)))) 392 (0 != (p[0].revents & (POLLERR
393 goto exit; 393 |
394 } 394 MHD_POLL_REVENTS_ERR_DISC))) ))
395 goto exit;
396 }
395#endif 397#endif
396#ifdef UPGRADE_SUPPORT 398#ifdef UPGRADE_SUPPORT
397 if (MHD_REQUEST_UPGRADE == con->request.state) 399 if (MHD_REQUEST_UPGRADE == con->request.state)
398 { 400 {
399 /* Normal HTTP processing is finished, 401 /* Normal HTTP processing is finished,
400 * notify application. */ 402 * notify application. */
401 if (NULL != con->request.response->termination_cb) 403 if (NULL != con->request.response->termination_cb)
402 con->request.response->termination_cb 404 con->request.response->termination_cb
403 (con->request.response->termination_cb_cls, 405 (con->request.response->termination_cb_cls,
404 MHD_REQUEST_TERMINATED_COMPLETED_OK, 406 MHD_REQUEST_TERMINATED_COMPLETED_OK,
405 con->request.client_context); 407 con->request.client_context);
406 thread_main_connection_upgrade (con); 408 thread_main_connection_upgrade (con);
407 /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */ 409 /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */
408 410
409 /* "Upgraded" data will not be used in this thread from this point. */ 411 /* "Upgraded" data will not be used in this thread from this point. */
410 con->request.urh->clean_ready = true; 412 con->request.urh->clean_ready = true;
411 /* If 'urh->was_closed' set to true, connection will be 413 /* If 'urh->was_closed' set to true, connection will be
412 * moved immediately to cleanup list. Otherwise connection 414 * moved immediately to cleanup list. Otherwise connection
413 * will stay in suspended list until 'urh' will be marked 415 * will stay in suspended list until 'urh' will be marked
414 * with 'was_closed' by application. */ 416 * with 'was_closed' by application. */
415 MHD_request_resume (&con->request); 417 MHD_request_resume (&con->request);
416 418
417 /* skip usual clean up */ 419 /* skip usual clean up */
418 return (MHD_THRD_RTRN_TYPE_) 0; 420 return (MHD_THRD_RTRN_TYPE_) 0;
419 }
420#endif /* UPGRADE_SUPPORT */
421 } 421 }
422#endif /* UPGRADE_SUPPORT */
423 }
422#if DEBUG_CLOSE 424#if DEBUG_CLOSE
423#ifdef HAVE_MESSAGES 425#ifdef HAVE_MESSAGES
424 MHD_DLOG (con->daemon, 426 MHD_DLOG (con->daemon,
425 MHD_SC_THREAD_TERMINATING, 427 MHD_SC_THREAD_TERMINATING,
426 _("Processing thread terminating. Closing connection\n")); 428 _ ("Processing thread terminating. Closing connection\n"));
427#endif 429#endif
428#endif 430#endif
429 if (MHD_REQUEST_CLOSED != con->request.state) 431 if (MHD_REQUEST_CLOSED != con->request.state)
430 MHD_connection_close_ (con, 432 MHD_connection_close_ (con,
431 (daemon->shutdown) ? 433 (daemon->shutdown) ?
432 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN: 434 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN :
433 MHD_REQUEST_TERMINATED_WITH_ERROR); 435 MHD_REQUEST_TERMINATED_WITH_ERROR);
434 MHD_request_handle_idle_ (&con->request); 436 MHD_request_handle_idle_ (&con->request);
435exit: 437exit:
436 if (NULL != con->request.response) 438 if (NULL != con->request.response)
437 { 439 {
438 MHD_response_queue_for_destroy (con->request.response); 440 MHD_response_queue_for_destroy (con->request.response);
439 con->request.response = NULL; 441 con->request.response = NULL;
440 } 442 }
441 443
442 if (MHD_INVALID_SOCKET != con->socket_fd) 444 if (MHD_INVALID_SOCKET != con->socket_fd)
443 { 445 {
444 shutdown (con->socket_fd, 446 shutdown (con->socket_fd,
445 SHUT_WR); 447 SHUT_WR);
446 /* 'socket_fd' can be used in other thread to signal shutdown. 448 /* 'socket_fd' can be used in other thread to signal shutdown.
447 * To avoid data races, do not close socket here. Daemon will 449 * To avoid data races, do not close socket here. Daemon will
448 * use more connections only after cleanup anyway. */ 450 * use more connections only after cleanup anyway. */
449 } 451 }
450 return (MHD_THRD_RTRN_TYPE_) 0; 452 return (MHD_THRD_RTRN_TYPE_) 0;
451} 453}
452 454
@@ -469,9 +471,9 @@ recv_param_adapter (struct MHD_Connection *connection,
469 471
470 if ( (MHD_INVALID_SOCKET == connection->socket_fd) || 472 if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
471 (MHD_REQUEST_CLOSED == connection->request.state) ) 473 (MHD_REQUEST_CLOSED == connection->request.state) )
472 { 474 {
473 return MHD_ERR_NOTCONN_; 475 return MHD_ERR_NOTCONN_;
474 } 476 }
475 if (i > MHD_SCKT_SEND_MAX_SIZE_) 477 if (i > MHD_SCKT_SEND_MAX_SIZE_)
476 i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */ 478 i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */
477 479
@@ -479,25 +481,25 @@ recv_param_adapter (struct MHD_Connection *connection,
479 other, 481 other,
480 i); 482 i);
481 if (0 > ret) 483 if (0 > ret)
484 {
485 const int err = MHD_socket_get_error_ ();
486 if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
482 { 487 {
483 const int err = MHD_socket_get_error_ ();
484 if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
485 {
486#ifdef EPOLL_SUPPORT 488#ifdef EPOLL_SUPPORT
487 /* Got EAGAIN --- no longer read-ready */ 489 /* Got EAGAIN --- no longer read-ready */
488 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; 490 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
489#endif /* EPOLL_SUPPORT */ 491#endif /* EPOLL_SUPPORT */
490 return MHD_ERR_AGAIN_; 492 return MHD_ERR_AGAIN_;
491 }
492 if (MHD_SCKT_ERR_IS_EINTR_ (err))
493 return MHD_ERR_AGAIN_;
494 if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
495 return MHD_ERR_CONNRESET_;
496 /* Treat any other error as hard error. */
497 return MHD_ERR_NOTCONN_;
498 } 493 }
494 if (MHD_SCKT_ERR_IS_EINTR_ (err))
495 return MHD_ERR_AGAIN_;
496 if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
497 return MHD_ERR_CONNRESET_;
498 /* Treat any other error as hard error. */
499 return MHD_ERR_NOTCONN_;
500 }
499#ifdef EPOLL_SUPPORT 501#ifdef EPOLL_SUPPORT
500 else if (i > (size_t)ret) 502 else if (i > (size_t) ret)
501 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; 503 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
502#endif /* EPOLL_SUPPORT */ 504#endif /* EPOLL_SUPPORT */
503 return ret; 505 return ret;
@@ -522,9 +524,9 @@ send_param_adapter (struct MHD_Connection *connection,
522 524
523 if ( (MHD_INVALID_SOCKET == connection->socket_fd) || 525 if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
524 (MHD_REQUEST_CLOSED == connection->request.state) ) 526 (MHD_REQUEST_CLOSED == connection->request.state) )
525 { 527 {
526 return MHD_ERR_NOTCONN_; 528 return MHD_ERR_NOTCONN_;
527 } 529 }
528 if (i > MHD_SCKT_SEND_MAX_SIZE_) 530 if (i > MHD_SCKT_SEND_MAX_SIZE_)
529 i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */ 531 i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */
530 532
@@ -532,26 +534,26 @@ send_param_adapter (struct MHD_Connection *connection,
532 other, 534 other,
533 i); 535 i);
534 if (0 > ret) 536 if (0 > ret)
535 { 537 {
536 const int err = MHD_socket_get_error_(); 538 const int err = MHD_socket_get_error_ ();
537 539
538 if (MHD_SCKT_ERR_IS_EAGAIN_(err)) 540 if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
539 { 541 {
540#ifdef EPOLL_SUPPORT 542#ifdef EPOLL_SUPPORT
541 /* EAGAIN --- no longer write-ready */ 543 /* EAGAIN --- no longer write-ready */
542 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 544 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
543#endif /* EPOLL_SUPPORT */ 545#endif /* EPOLL_SUPPORT */
544 return MHD_ERR_AGAIN_; 546 return MHD_ERR_AGAIN_;
545 }
546 if (MHD_SCKT_ERR_IS_EINTR_ (err))
547 return MHD_ERR_AGAIN_;
548 if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
549 return MHD_ERR_CONNRESET_;
550 /* Treat any other error as hard error. */
551 return MHD_ERR_NOTCONN_;
552 } 547 }
548 if (MHD_SCKT_ERR_IS_EINTR_ (err))
549 return MHD_ERR_AGAIN_;
550 if (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_ECONNRESET_))
551 return MHD_ERR_CONNRESET_;
552 /* Treat any other error as hard error. */
553 return MHD_ERR_NOTCONN_;
554 }
553#ifdef EPOLL_SUPPORT 555#ifdef EPOLL_SUPPORT
554 else if (i > (size_t)ret) 556 else if (i > (size_t) ret)
555 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 557 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
556#endif /* EPOLL_SUPPORT */ 558#endif /* EPOLL_SUPPORT */
557 return ret; 559 return ret;
@@ -582,11 +584,11 @@ send_param_adapter (struct MHD_Connection *connection,
582 */ 584 */
583static enum MHD_StatusCode 585static enum MHD_StatusCode
584internal_add_connection (struct MHD_Daemon *daemon, 586internal_add_connection (struct MHD_Daemon *daemon,
585 MHD_socket client_socket, 587 MHD_socket client_socket,
586 const struct sockaddr *addr, 588 const struct sockaddr *addr,
587 socklen_t addrlen, 589 socklen_t addrlen,
588 bool external_add, 590 bool external_add,
589 bool non_blck) 591 bool non_blck)
590{ 592{
591 enum MHD_StatusCode sc; 593 enum MHD_StatusCode sc;
592 struct MHD_Connection *connection; 594 struct MHD_Connection *connection;
@@ -594,78 +596,78 @@ internal_add_connection (struct MHD_Daemon *daemon,
594 596
595 /* Direct add to master daemon could happen only with "external" add mode. */ 597 /* Direct add to master daemon could happen only with "external" add mode. */
596 mhd_assert ( (NULL == daemon->worker_pool) || 598 mhd_assert ( (NULL == daemon->worker_pool) ||
597 (external_add) ); 599 (external_add) );
598 if ( (external_add) && 600 if ( (external_add) &&
599 (NULL != daemon->worker_pool) ) 601 (NULL != daemon->worker_pool) )
600 { 602 {
601 unsigned int i; 603 unsigned int i;
602 604
603 /* have a pool, try to find a pool with capacity; we use the 605 /* have a pool, try to find a pool with capacity; we use the
604 socket as the initial offset into the pool for load 606 socket as the initial offset into the pool for load
605 balancing */ 607 balancing */
606 for (i = 0; i < daemon->worker_pool_size; ++i) 608 for (i = 0; i < daemon->worker_pool_size; ++i)
607 { 609 {
608 struct MHD_Daemon * const worker = 610 struct MHD_Daemon *const worker =
609 &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size]; 611 &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size];
610 if (worker->connections < worker->global_connection_limit) 612 if (worker->connections < worker->global_connection_limit)
611 return internal_add_connection (worker, 613 return internal_add_connection (worker,
612 client_socket, 614 client_socket,
613 addr, 615 addr,
614 addrlen, 616 addrlen,
615 true, 617 true,
616 non_blck); 618 non_blck);
617 } 619 }
618 /* all pools are at their connection limit, must refuse */ 620 /* all pools are at their connection limit, must refuse */
619 MHD_socket_close_chk_ (client_socket); 621 MHD_socket_close_chk_ (client_socket);
620#if ENFILE 622#if ENFILE
621 errno = ENFILE; 623 errno = ENFILE;
622#endif 624#endif
623 return MHD_SC_LIMIT_CONNECTIONS_REACHED; 625 return MHD_SC_LIMIT_CONNECTIONS_REACHED;
624 } 626 }
625 627
626 if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket, 628 if ( (! MHD_SCKT_FD_FITS_FDSET_ (client_socket,
627 NULL)) && 629 NULL)) &&
628 (MHD_ELS_SELECT == daemon->event_loop_syscall) ) 630 (MHD_ELS_SELECT == daemon->event_loop_syscall) )
629 { 631 {
630#ifdef HAVE_MESSAGES 632#ifdef HAVE_MESSAGES
631 MHD_DLOG (daemon, 633 MHD_DLOG (daemon,
632 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, 634 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
633 _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), 635 _ ("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
634 (int) client_socket, 636 (int) client_socket,
635 (int) FD_SETSIZE); 637 (int) FD_SETSIZE);
636#endif 638#endif
637 MHD_socket_close_chk_ (client_socket); 639 MHD_socket_close_chk_ (client_socket);
638#if EINVAL 640#if EINVAL
639 errno = EINVAL; 641 errno = EINVAL;
640#endif 642#endif
641 return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; 643 return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
642 } 644 }
643 645
644#ifdef MHD_socket_nosignal_ 646#ifdef MHD_socket_nosignal_
645 if (! MHD_socket_nosignal_ (client_socket)) 647 if (! MHD_socket_nosignal_ (client_socket))
646 { 648 {
647#ifdef HAVE_MESSAGES 649#ifdef HAVE_MESSAGES
648 MHD_DLOG (daemon, 650 MHD_DLOG (daemon,
649 MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED, 651 MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED,
650 _("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"), 652 _ ("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
651 MHD_socket_last_strerr_()); 653 MHD_socket_last_strerr_ ());
652#endif 654#endif
653#ifndef MSG_NOSIGNAL 655#ifndef MSG_NOSIGNAL
654 /* Cannot use socket as it can produce SIGPIPE. */ 656 /* Cannot use socket as it can produce SIGPIPE. */
655#ifdef ENOTSOCK 657#ifdef ENOTSOCK
656 errno = ENOTSOCK; 658 errno = ENOTSOCK;
657#endif /* ENOTSOCK */ 659#endif /* ENOTSOCK */
658 return MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED; 660 return MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED;
659#endif /* ! MSG_NOSIGNAL */ 661#endif /* ! MSG_NOSIGNAL */
660 } 662 }
661#endif /* MHD_socket_nosignal_ */ 663#endif /* MHD_socket_nosignal_ */
662 664
663 665
664#ifdef HAVE_MESSAGES 666#ifdef HAVE_MESSAGES
665#if DEBUG_CONNECT 667#if DEBUG_CONNECT
666 MHD_DLOG (daemon, 668 MHD_DLOG (daemon,
667 MHD_SC_CONNECTION_ACCEPTED, 669 MHD_SC_CONNECTION_ACCEPTED,
668 _("Accepted connection on socket %d\n"), 670 _ ("Accepted connection on socket %d\n"),
669 client_socket); 671 client_socket);
670#endif 672#endif
671#endif 673#endif
@@ -673,82 +675,83 @@ internal_add_connection (struct MHD_Daemon *daemon,
673 (MHD_NO == MHD_ip_limit_add (daemon, 675 (MHD_NO == MHD_ip_limit_add (daemon,
674 addr, 676 addr,
675 addrlen)) ) 677 addrlen)) )
676 { 678 {
677 /* above connection limit - reject */ 679 /* above connection limit - reject */
678#ifdef HAVE_MESSAGES 680#ifdef HAVE_MESSAGES
679 MHD_DLOG (daemon, 681 MHD_DLOG (daemon,
680 MHD_SC_LIMIT_CONNECTIONS_REACHED, 682 MHD_SC_LIMIT_CONNECTIONS_REACHED,
681 _("Server reached connection limit. Closing inbound connection.\n")); 683 _ (
684 "Server reached connection limit. Closing inbound connection.\n"));
682#endif 685#endif
683 MHD_socket_close_chk_ (client_socket); 686 MHD_socket_close_chk_ (client_socket);
684#if ENFILE 687#if ENFILE
685 errno = ENFILE; 688 errno = ENFILE;
686#endif 689#endif
687 return MHD_SC_LIMIT_CONNECTIONS_REACHED; 690 return MHD_SC_LIMIT_CONNECTIONS_REACHED;
688 } 691 }
689 692
690 /* apply connection acceptance policy if present */ 693 /* apply connection acceptance policy if present */
691 if ( (NULL != daemon->accept_policy_cb) && 694 if ( (NULL != daemon->accept_policy_cb) &&
692 (MHD_NO == 695 (MHD_NO ==
693 daemon->accept_policy_cb (daemon->accept_policy_cb_cls, 696 daemon->accept_policy_cb (daemon->accept_policy_cb_cls,
694 addr, 697 addr,
695 addrlen)) ) 698 addrlen)) )
696 { 699 {
697#if DEBUG_CLOSE 700#if DEBUG_CLOSE
698#ifdef HAVE_MESSAGES 701#ifdef HAVE_MESSAGES
699 MHD_DLOG (daemon, 702 MHD_DLOG (daemon,
700 MHD_SC_ACCEPT_POLICY_REJECTED, 703 MHD_SC_ACCEPT_POLICY_REJECTED,
701 _("Connection rejected by application. Closing connection.\n")); 704 _ ("Connection rejected by application. Closing connection.\n"));
702#endif 705#endif
703#endif 706#endif
704 MHD_socket_close_chk_ (client_socket); 707 MHD_socket_close_chk_ (client_socket);
705 MHD_ip_limit_del (daemon, 708 MHD_ip_limit_del (daemon,
706 addr, 709 addr,
707 addrlen); 710 addrlen);
708#if EACCESS 711#if EACCESS
709 errno = EACCESS; 712 errno = EACCESS;
710#endif 713#endif
711 return MHD_SC_ACCEPT_POLICY_REJECTED; 714 return MHD_SC_ACCEPT_POLICY_REJECTED;
712 } 715 }
713 716
714 if (NULL == 717 if (NULL ==
715 (connection = MHD_calloc_ (1, 718 (connection = MHD_calloc_ (1,
716 sizeof (struct MHD_Connection)))) 719 sizeof (struct MHD_Connection))))
717 { 720 {
718 eno = errno; 721 eno = errno;
719#ifdef HAVE_MESSAGES 722#ifdef HAVE_MESSAGES
720 MHD_DLOG (daemon, 723 MHD_DLOG (daemon,
721 MHD_SC_CONNECTION_MALLOC_FAILURE, 724 MHD_SC_CONNECTION_MALLOC_FAILURE,
722 "Error allocating memory: %s\n", 725 "Error allocating memory: %s\n",
723 MHD_strerror_ (errno)); 726 MHD_strerror_ (errno));
724#endif 727#endif
725 MHD_socket_close_chk_ (client_socket); 728 MHD_socket_close_chk_ (client_socket);
726 MHD_ip_limit_del (daemon, 729 MHD_ip_limit_del (daemon,
727 addr, 730 addr,
728 addrlen); 731 addrlen);
729 errno = eno; 732 errno = eno;
730 return MHD_SC_CONNECTION_MALLOC_FAILURE; 733 return MHD_SC_CONNECTION_MALLOC_FAILURE;
731 } 734 }
732 connection->pool 735 connection->pool
733 = MHD_pool_create (daemon->connection_memory_limit_b); 736 = MHD_pool_create (daemon->connection_memory_limit_b);
734 if (NULL == connection->pool) 737 if (NULL == connection->pool)
735 { 738 {
736#ifdef HAVE_MESSAGES 739#ifdef HAVE_MESSAGES
737 MHD_DLOG (daemon, 740 MHD_DLOG (daemon,
738 MHD_SC_POOL_MALLOC_FAILURE, 741 MHD_SC_POOL_MALLOC_FAILURE,
739 _("Error allocating memory: %s\n"), 742 _ ("Error allocating memory: %s\n"),
740 MHD_strerror_ (errno)); 743 MHD_strerror_ (errno));
741#endif 744#endif
742 MHD_socket_close_chk_ (client_socket); 745 MHD_socket_close_chk_ (client_socket);
743 MHD_ip_limit_del (daemon, 746 MHD_ip_limit_del (daemon,
744 addr, 747 addr,
745 addrlen); 748 addrlen);
746 free (connection); 749 free (connection);
747#if ENOMEM 750#if ENOMEM
748 errno = ENOMEM; 751 errno = ENOMEM;
749#endif 752#endif
750 return MHD_SC_POOL_MALLOC_FAILURE; 753 return MHD_SC_POOL_MALLOC_FAILURE;
751 } 754 }
752 755
753 connection->connection_timeout = daemon->connection_default_timeout; 756 connection->connection_timeout = daemon->connection_default_timeout;
754 memcpy (&connection->addr, 757 memcpy (&connection->addr,
@@ -758,148 +761,151 @@ internal_add_connection (struct MHD_Daemon *daemon,
758 connection->socket_fd = client_socket; 761 connection->socket_fd = client_socket;
759 connection->sk_nonblck = non_blck; 762 connection->sk_nonblck = non_blck;
760 connection->daemon = daemon; 763 connection->daemon = daemon;
761 connection->last_activity = MHD_monotonic_sec_counter(); 764 connection->last_activity = MHD_monotonic_sec_counter ();
762 765
763#ifdef HTTPS_SUPPORT 766#ifdef HTTPS_SUPPORT
764 if (NULL != daemon->tls_api) 767 if (NULL != daemon->tls_api)
768 {
769 connection->tls_cs
770 = daemon->tls_api->setup_connection (daemon->tls_api->cls,
771 NULL /* FIXME */);
772 if (NULL == connection->tls_cs)
765 { 773 {
766 connection->tls_cs 774 eno = EINVAL;
767 = daemon->tls_api->setup_connection (daemon->tls_api->cls, 775 sc = -1; // FIXME!
768 NULL /* FIXME */); 776 goto cleanup;
769 if (NULL == connection->tls_cs)
770 {
771 eno = EINVAL;
772 sc = -1; // FIXME!
773 goto cleanup;
774 }
775 } 777 }
778 }
776 else 779 else
777#endif /* ! HTTPS_SUPPORT */ 780#endif /* ! HTTPS_SUPPORT */
778 { 781 {
779 /* set default connection handlers */ 782 /* set default connection handlers */
780 connection->recv_cls = &recv_param_adapter; 783 connection->recv_cls = &recv_param_adapter;
781 connection->send_cls = &send_param_adapter; 784 connection->send_cls = &send_param_adapter;
782 } 785 }
783 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 786 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
784 /* Firm check under lock. */ 787 /* Firm check under lock. */
785 if (daemon->connections >= daemon->global_connection_limit) 788 if (daemon->connections >= daemon->global_connection_limit)
786 { 789 {
787 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 790 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
788 /* above connection limit - reject */ 791 /* above connection limit - reject */
789#ifdef HAVE_MESSAGES 792#ifdef HAVE_MESSAGES
790 MHD_DLOG (daemon, 793 MHD_DLOG (daemon,
791 MHD_SC_LIMIT_CONNECTIONS_REACHED, 794 MHD_SC_LIMIT_CONNECTIONS_REACHED,
792 _("Server reached connection limit. Closing inbound connection.\n")); 795 _ (
796 "Server reached connection limit. Closing inbound connection.\n"));
793#endif 797#endif
794#if ENFILE 798#if ENFILE
795 eno = ENFILE; 799 eno = ENFILE;
796#endif 800#endif
797 sc = MHD_SC_LIMIT_CONNECTIONS_REACHED; 801 sc = MHD_SC_LIMIT_CONNECTIONS_REACHED;
798 goto cleanup; 802 goto cleanup;
799 } 803 }
800 daemon->connections++; 804 daemon->connections++;
801 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) 805 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
802 { 806 {
803 XDLL_insert (daemon->normal_timeout_head, 807 XDLL_insert (daemon->normal_timeout_head,
804 daemon->normal_timeout_tail, 808 daemon->normal_timeout_tail,
805 connection); 809 connection);
806 } 810 }
807 DLL_insert (daemon->connections_head, 811 DLL_insert (daemon->connections_head,
808 daemon->connections_tail, 812 daemon->connections_tail,
809 connection); 813 connection);
810 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 814 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
811 815
812 if (NULL != daemon->notify_connection_cb) 816 if (NULL != daemon->notify_connection_cb)
813 daemon->notify_connection_cb (daemon->notify_connection_cb_cls, 817 daemon->notify_connection_cb (daemon->notify_connection_cb_cls,
814 connection, 818 connection,
815 MHD_CONNECTION_NOTIFY_STARTED); 819 MHD_CONNECTION_NOTIFY_STARTED);
816 820
817 /* attempt to create handler thread */ 821 /* attempt to create handler thread */
818 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) 822 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
823 {
824 if (! MHD_create_named_thread_ (&connection->pid,
825 "MHD-connection",
826 daemon->thread_stack_limit_b,
827 &thread_main_handle_connection,
828 connection))
819 { 829 {
820 if (! MHD_create_named_thread_ (&connection->pid, 830 eno = errno;
821 "MHD-connection",
822 daemon->thread_stack_limit_b,
823 &thread_main_handle_connection,
824 connection))
825 {
826 eno = errno;
827#ifdef HAVE_MESSAGES 831#ifdef HAVE_MESSAGES
828 MHD_DLOG (daemon, 832 MHD_DLOG (daemon,
829 MHD_SC_THREAD_LAUNCH_FAILURE, 833 MHD_SC_THREAD_LAUNCH_FAILURE,
830 "Failed to create a thread: %s\n", 834 "Failed to create a thread: %s\n",
831 MHD_strerror_ (eno)); 835 MHD_strerror_ (eno));
832#endif 836#endif
833 sc = MHD_SC_THREAD_LAUNCH_FAILURE; 837 sc = MHD_SC_THREAD_LAUNCH_FAILURE;
834 goto cleanup; 838 goto cleanup;
835 }
836 } 839 }
840 }
837 else 841 else
838 { 842 {
839 connection->pid = daemon->pid; 843 connection->pid = daemon->pid;
840 } 844 }
841#ifdef EPOLL_SUPPORT 845#ifdef EPOLL_SUPPORT
842 if (MHD_ELS_EPOLL == daemon->event_loop_syscall) 846 if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
843 { 847 {
844 if ( (! daemon->enable_turbo) || 848 if ( (! daemon->enable_turbo) ||
845 (external_add)) 849 (external_add))
846 { /* Do not manipulate EReady DL-list in 'external_add' mode. */ 850 { /* Do not manipulate EReady DL-list in 'external_add' mode. */
847 struct epoll_event event; 851 struct epoll_event event;
848 852
849 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; 853 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
850 event.data.ptr = connection; 854 event.data.ptr = connection;
851 if (0 != epoll_ctl (daemon->epoll_fd, 855 if (0 != epoll_ctl (daemon->epoll_fd,
852 EPOLL_CTL_ADD, 856 EPOLL_CTL_ADD,
853 client_socket, 857 client_socket,
854 &event)) 858 &event))
855 { 859 {
856 eno = errno; 860 eno = errno;
857#ifdef HAVE_MESSAGES 861#ifdef HAVE_MESSAGES
858 MHD_DLOG (daemon, 862 MHD_DLOG (daemon,
859 MHD_SC_EPOLL_CTL_ADD_FAILED, 863 MHD_SC_EPOLL_CTL_ADD_FAILED,
860 _("Call to epoll_ctl failed: %s\n"), 864 _ ("Call to epoll_ctl failed: %s\n"),
861 MHD_socket_last_strerr_ ()); 865 MHD_socket_last_strerr_ ());
862#endif 866#endif
863 sc = MHD_SC_EPOLL_CTL_ADD_FAILED; 867 sc = MHD_SC_EPOLL_CTL_ADD_FAILED;
864 goto cleanup; 868 goto cleanup;
865 } 869 }
866 connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; 870 connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
867 } 871 }
868 else 872 else
869 { 873 {
870 connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY 874 connection->epoll_state |= MHD_EPOLL_STATE_READ_READY
871 | MHD_EPOLL_STATE_IN_EREADY_EDLL; 875 | MHD_EPOLL_STATE_WRITE_READY
872 EDLL_insert (daemon->eready_head, 876 | MHD_EPOLL_STATE_IN_EREADY_EDLL;
873 daemon->eready_tail, 877 EDLL_insert (daemon->eready_head,
874 connection); 878 daemon->eready_tail,
875 } 879 connection);
876 } 880 }
881 }
877 else /* This 'else' is combined with next 'if'. */ 882 else /* This 'else' is combined with next 'if'. */
878#endif 883#endif
879 if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) && 884 if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) &&
880 (external_add) && 885 (external_add) &&
881 (MHD_ITC_IS_VALID_(daemon->itc)) && 886 (MHD_ITC_IS_VALID_ (daemon->itc)) &&
882 (! MHD_itc_activate_ (daemon->itc, 887 (! MHD_itc_activate_ (daemon->itc,
883 "n")) ) 888 "n")) )
884 { 889 {
885#ifdef HAVE_MESSAGES 890#ifdef HAVE_MESSAGES
886 MHD_DLOG (daemon, 891 MHD_DLOG (daemon,
887 MHD_SC_ITC_USE_FAILED, 892 MHD_SC_ITC_USE_FAILED,
888 _("Failed to signal new connection via inter-thread communication channel (not necessarily fatal, continuing anyway).")); 893 _ (
894 "Failed to signal new connection via inter-thread communication channel (not necessarily fatal, continuing anyway)."));
889#endif 895#endif
890 } 896 }
891 return MHD_SC_OK; 897 return MHD_SC_OK;
892 898
893 cleanup: 899cleanup:
894 if (NULL != daemon->notify_connection_cb) 900 if (NULL != daemon->notify_connection_cb)
895 daemon->notify_connection_cb (daemon->notify_connection_cb_cls, 901 daemon->notify_connection_cb (daemon->notify_connection_cb_cls,
896 connection, 902 connection,
897 MHD_CONNECTION_NOTIFY_CLOSED); 903 MHD_CONNECTION_NOTIFY_CLOSED);
898#ifdef HTTPS_SUPPORT 904#ifdef HTTPS_SUPPORT
899 if ( (NULL != daemon->tls_api) && 905 if ( (NULL != daemon->tls_api) &&
900 (NULL != connection->tls_cs) ) 906 (NULL != connection->tls_cs) )
901 daemon->tls_api->teardown_connection (daemon->tls_api->cls, 907 daemon->tls_api->teardown_connection (daemon->tls_api->cls,
902 connection->tls_cs); 908 connection->tls_cs);
903#endif /* HTTPS_SUPPORT */ 909#endif /* HTTPS_SUPPORT */
904 MHD_socket_close_chk_ (client_socket); 910 MHD_socket_close_chk_ (client_socket);
905 MHD_ip_limit_del (daemon, 911 MHD_ip_limit_del (daemon,
@@ -907,14 +913,14 @@ internal_add_connection (struct MHD_Daemon *daemon,
907 addrlen); 913 addrlen);
908 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 914 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
909 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) 915 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
910 { 916 {
911 XDLL_remove (daemon->normal_timeout_head, 917 XDLL_remove (daemon->normal_timeout_head,
912 daemon->normal_timeout_tail, 918 daemon->normal_timeout_tail,
913 connection); 919 connection);
914 } 920 }
915 DLL_remove (daemon->connections_head, 921 DLL_remove (daemon->connections_head,
916 daemon->connections_tail, 922 daemon->connections_tail,
917 connection); 923 connection);
918 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 924 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
919 MHD_pool_destroy (connection->pool); 925 MHD_pool_destroy (connection->pool);
920 free (connection); 926 free (connection);
@@ -954,42 +960,42 @@ internal_add_connection (struct MHD_Daemon *daemon,
954 */ 960 */
955enum MHD_StatusCode 961enum MHD_StatusCode
956MHD_daemon_add_connection (struct MHD_Daemon *daemon, 962MHD_daemon_add_connection (struct MHD_Daemon *daemon,
957 MHD_socket client_socket, 963 MHD_socket client_socket,
958 const struct sockaddr *addr, 964 const struct sockaddr *addr,
959 socklen_t addrlen) 965 socklen_t addrlen)
960{ 966{
961 bool sk_nonbl; 967 bool sk_nonbl;
962 968
963 if (! MHD_socket_nonblocking_ (client_socket)) 969 if (! MHD_socket_nonblocking_ (client_socket))
964 { 970 {
965#ifdef HAVE_MESSAGES 971#ifdef HAVE_MESSAGES
966 MHD_DLOG (daemon, 972 MHD_DLOG (daemon,
967 MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED, 973 MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED,
968 _("Failed to set nonblocking mode on new client socket: %s\n"), 974 _ ("Failed to set nonblocking mode on new client socket: %s\n"),
969 MHD_socket_last_strerr_()); 975 MHD_socket_last_strerr_ ());
970#endif 976#endif
971 sk_nonbl = false; 977 sk_nonbl = false;
972 } 978 }
973 else 979 else
974 { 980 {
975 sk_nonbl = true; 981 sk_nonbl = true;
976 } 982 }
977 983
978 if ( (daemon->enable_turbo) && 984 if ( (daemon->enable_turbo) &&
979 (! MHD_socket_noninheritable_ (client_socket)) ) 985 (! MHD_socket_noninheritable_ (client_socket)) )
980 { 986 {
981#ifdef HAVE_MESSAGES 987#ifdef HAVE_MESSAGES
982 MHD_DLOG (daemon, 988 MHD_DLOG (daemon,
983 MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED, 989 MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED,
984 _("Failed to set noninheritable mode on new client socket.\n")); 990 _ ("Failed to set noninheritable mode on new client socket.\n"));
985#endif 991#endif
986 } 992 }
987 return internal_add_connection (daemon, 993 return internal_add_connection (daemon,
988 client_socket, 994 client_socket,
989 addr, 995 addr,
990 addrlen, 996 addrlen,
991 true, 997 true,
992 sk_nonbl); 998 sk_nonbl);
993} 999}
994 1000
995 1001
@@ -1033,94 +1039,98 @@ MHD_accept_connection_ (struct MHD_Daemon *daemon)
1033#endif /* ! USE_ACCEPT4 */ 1039#endif /* ! USE_ACCEPT4 */
1034 if ( (MHD_INVALID_SOCKET == s) || 1040 if ( (MHD_INVALID_SOCKET == s) ||
1035 (addrlen <= 0) ) 1041 (addrlen <= 0) )
1036 { 1042 {
1037 const int err = MHD_socket_get_error_ (); 1043 const int err = MHD_socket_get_error_ ();
1038 1044
1039 /* This could be a common occurance with multiple worker threads */ 1045 /* This could be a common occurance with multiple worker threads */
1040 if (MHD_SCKT_ERR_IS_ (err, 1046 if (MHD_SCKT_ERR_IS_ (err,
1041 MHD_SCKT_EINVAL_)) 1047 MHD_SCKT_EINVAL_))
1042 return MHD_SC_DAEMON_ALREADY_SHUTDOWN; /* can happen during shutdown, let's hope this is the cause... */ 1048 return MHD_SC_DAEMON_ALREADY_SHUTDOWN; /* can happen during shutdown, let's hope this is the cause... */
1043 if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)) 1049 if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_ (err))
1044 return MHD_SC_ACCEPT_FAST_DISCONNECT; /* do not print error if client just disconnected early */ 1050 return MHD_SC_ACCEPT_FAST_DISCONNECT; /* do not print error if client just disconnected early */
1045 if (MHD_SCKT_ERR_IS_EAGAIN_ (err) ) 1051 if (MHD_SCKT_ERR_IS_EAGAIN_ (err) )
1046 return MHD_SC_ACCEPT_FAILED_EAGAIN; 1052 return MHD_SC_ACCEPT_FAILED_EAGAIN;
1047 if (MHD_INVALID_SOCKET != s) 1053 if (MHD_INVALID_SOCKET != s)
1048 { 1054 {
1049 MHD_socket_close_chk_ (s); 1055 MHD_socket_close_chk_ (s);
1050 } 1056 }
1051 if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) 1057 if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) )
1052 { 1058 {
1053 /* system/process out of resources */ 1059 /* system/process out of resources */
1054 if (0 == daemon->connections) 1060 if (0 == daemon->connections)
1055 { 1061 {
1056#ifdef HAVE_MESSAGES 1062#ifdef HAVE_MESSAGES
1057 /* Not setting 'at_limit' flag, as there is no way it 1063 /* Not setting 'at_limit' flag, as there is no way it
1058 would ever be cleared. Instead trying to produce 1064 would ever be cleared. Instead trying to produce
1059 bit fat ugly warning. */ 1065 bit fat ugly warning. */
1060 MHD_DLOG (daemon, 1066 MHD_DLOG (daemon,
1061 MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY, 1067 MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY,
1062 _("Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n")); 1068 _ (
1069 "Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n"));
1063#endif 1070#endif
1064 return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY; 1071 return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY;
1065 } 1072 }
1066 else 1073 else
1067 { 1074 {
1068 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 1075 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
1069 daemon->at_limit = true; 1076 daemon->at_limit = true;
1070 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 1077 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
1071#ifdef HAVE_MESSAGES 1078#ifdef HAVE_MESSAGES
1072 MHD_DLOG (daemon, 1079 MHD_DLOG (daemon,
1073 MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED, 1080 MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED,
1074 _("Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"), 1081 _ (
1075 (unsigned int) daemon->connections); 1082 "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
1083 (unsigned int) daemon->connections);
1076#endif 1084#endif
1077 return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED; 1085 return MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED;
1078 } 1086 }
1079 } 1087 }
1080#ifdef HAVE_MESSAGES 1088#ifdef HAVE_MESSAGES
1081 MHD_DLOG (daemon, 1089 MHD_DLOG (daemon,
1082 MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY, 1090 MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY,
1083 _("Error accepting connection: %s\n"), 1091 _ ("Error accepting connection: %s\n"),
1084 MHD_socket_strerr_(err)); 1092 MHD_socket_strerr_ (err));
1085#endif 1093#endif
1086 return MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY; 1094 return MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY;
1087 } 1095 }
1088#if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) 1096#if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK)
1089 if (! MHD_socket_nonblocking_ (s)) 1097 if (! MHD_socket_nonblocking_ (s))
1090 { 1098 {
1091#ifdef HAVE_MESSAGES 1099#ifdef HAVE_MESSAGES
1092 MHD_DLOG (daemon, 1100 MHD_DLOG (daemon,
1093 MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED, 1101 MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED,
1094 _("Failed to set nonblocking mode on incoming connection socket: %s\n"), 1102 _ (
1095 MHD_socket_last_strerr_()); 1103 "Failed to set nonblocking mode on incoming connection socket: %s\n"),
1104 MHD_socket_last_strerr_ ());
1096#endif 1105#endif
1097 } 1106 }
1098 else 1107 else
1099 sk_nonbl = true; 1108 sk_nonbl = true;
1100#endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */ 1109#endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */
1101#if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC) 1110#if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC)
1102 if (! MHD_socket_noninheritable_ (s)) 1111 if (! MHD_socket_noninheritable_ (s))
1103 { 1112 {
1104#ifdef HAVE_MESSAGES 1113#ifdef HAVE_MESSAGES
1105 MHD_DLOG (daemon, 1114 MHD_DLOG (daemon,
1106 MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED, 1115 MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED,
1107 _("Failed to set noninheritable mode on incoming connection socket.\n")); 1116 _ (
1117 "Failed to set noninheritable mode on incoming connection socket.\n"));
1108#endif 1118#endif
1109 } 1119 }
1110#endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */ 1120#endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */
1111#ifdef HAVE_MESSAGES 1121#ifdef HAVE_MESSAGES
1112#if DEBUG_CONNECT 1122#if DEBUG_CONNECT
1113 MHD_DLOG (daemon, 1123 MHD_DLOG (daemon,
1114 MHD_SC_CONNECTION_ACCEPTED, 1124 MHD_SC_CONNECTION_ACCEPTED,
1115 _("Accepted connection on socket %d\n"), 1125 _ ("Accepted connection on socket %d\n"),
1116 s); 1126 s);
1117#endif 1127#endif
1118#endif 1128#endif
1119 return internal_add_connection (daemon, 1129 return internal_add_connection (daemon,
1120 s, 1130 s,
1121 addr, 1131 addr,
1122 addrlen, 1132 addrlen,
1123 false, 1133 false,
1124 sk_nonbl); 1134 sk_nonbl);
1125} 1135}
1126 1136
diff --git a/src/lib/connection_add.h b/src/lib/connection_add.h
index 6957fd77..de8abd9a 100644
--- a/src/lib/connection_add.h
+++ b/src/lib/connection_add.h
@@ -32,10 +32,10 @@
32 * that process daemon's select()/poll()/etc. 32 * that process daemon's select()/poll()/etc.
33 * 33 *
34 * @param daemon handle with the listen socket 34 * @param daemon handle with the listen socket
35 * @return #MHD_SC_OK on success 35 * @return #MHD_SC_OK on success
36 */ 36 */
37enum MHD_StatusCode 37enum MHD_StatusCode
38MHD_accept_connection_ (struct MHD_Daemon *daemon) 38MHD_accept_connection_ (struct MHD_Daemon *daemon)
39 MHD_NONNULL (1); 39MHD_NONNULL (1);
40 40
41#endif 41#endif
diff --git a/src/lib/connection_call_handlers.c b/src/lib/connection_call_handlers.c
index af8860d6..c4fb448e 100644
--- a/src/lib/connection_call_handlers.c
+++ b/src/lib/connection_call_handlers.c
@@ -56,7 +56,8 @@
56 * minimal. 56 * minimal.
57 */ 57 */
58#ifdef HAVE_MESSAGES 58#ifdef HAVE_MESSAGES
59#define REQUEST_TOO_BIG "<html><head><title>Request too big</title></head><body>Your HTTP header was too big for the memory constraints of this webserver.</body></html>" 59#define REQUEST_TOO_BIG \
60 "<html><head><title>Request too big</title></head><body>Your HTTP header was too big for the memory constraints of this webserver.</body></html>"
60#else 61#else
61#define REQUEST_TOO_BIG "" 62#define REQUEST_TOO_BIG ""
62#endif 63#endif
@@ -69,7 +70,8 @@
69 * minimal. 70 * minimal.
70 */ 71 */
71#ifdef HAVE_MESSAGES 72#ifdef HAVE_MESSAGES
72#define REQUEST_LACKS_HOST "<html><head><title>&quot;Host:&quot; header required</title></head><body>In HTTP 1.1, requests must include a &quot;Host:&quot; header, and your HTTP 1.1 request lacked such a header.</body></html>" 73#define REQUEST_LACKS_HOST \
74 "<html><head><title>&quot;Host:&quot; header required</title></head><body>In HTTP 1.1, requests must include a &quot;Host:&quot; header, and your HTTP 1.1 request lacked such a header.</body></html>"
73#else 75#else
74#define REQUEST_LACKS_HOST "" 76#define REQUEST_LACKS_HOST ""
75#endif 77#endif
@@ -82,7 +84,8 @@
82 * minimal. 84 * minimal.
83 */ 85 */
84#ifdef HAVE_MESSAGES 86#ifdef HAVE_MESSAGES
85#define REQUEST_MALFORMED "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>" 87#define REQUEST_MALFORMED \
88 "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>"
86#else 89#else
87#define REQUEST_MALFORMED "" 90#define REQUEST_MALFORMED ""
88#endif 91#endif
@@ -94,7 +97,8 @@
94 * minimal. 97 * minimal.
95 */ 98 */
96#ifdef HAVE_MESSAGES 99#ifdef HAVE_MESSAGES
97#define INTERNAL_ERROR "<html><head><title>Internal server error</title></head><body>Please ask the developer of this Web server to carefully read the GNU libmicrohttpd documentation about connection management and blocking.</body></html>" 100#define INTERNAL_ERROR \
101 "<html><head><title>Internal server error</title></head><body>Please ask the developer of this Web server to carefully read the GNU libmicrohttpd documentation about connection management and blocking.</body></html>"
98#else 102#else
99#define INTERNAL_ERROR "" 103#define INTERNAL_ERROR ""
100#endif 104#endif
@@ -128,17 +132,18 @@ MHD_conn_init_static_ (void)
128#ifdef SF_FLAGS 132#ifdef SF_FLAGS
129 long sys_page_size = sysconf (_SC_PAGESIZE); 133 long sys_page_size = sysconf (_SC_PAGESIZE);
130 if (0 > sys_page_size) 134 if (0 > sys_page_size)
131 { /* Failed to get page size. */ 135 { /* Failed to get page size. */
132 freebsd_sendfile_flags_ = SF_NODISKIO; 136 freebsd_sendfile_flags_ = SF_NODISKIO;
133 freebsd_sendfile_flags_thd_p_c_ = SF_NODISKIO; 137 freebsd_sendfile_flags_thd_p_c_ = SF_NODISKIO;
134 } 138 }
135 else 139 else
136 { 140 {
137 freebsd_sendfile_flags_ = 141 freebsd_sendfile_flags_ =
138 SF_FLAGS((uint16_t)(MHD_SENFILE_CHUNK_ / sys_page_size), SF_NODISKIO); 142 SF_FLAGS ((uint16_t) (MHD_SENFILE_CHUNK_ / sys_page_size), SF_NODISKIO);
139 freebsd_sendfile_flags_thd_p_c_ = 143 freebsd_sendfile_flags_thd_p_c_ =
140 SF_FLAGS((uint16_t)(MHD_SENFILE_CHUNK_THR_P_C_ / sys_page_size), SF_NODISKIO); 144 SF_FLAGS ((uint16_t) (MHD_SENFILE_CHUNK_THR_P_C_ / sys_page_size),
141 } 145 SF_NODISKIO);
146 }
142#endif /* SF_FLAGS */ 147#endif /* SF_FLAGS */
143} 148}
144#endif /* HAVE_FREEBSD_SENDFILE */ 149#endif /* HAVE_FREEBSD_SENDFILE */
@@ -161,13 +166,13 @@ MHD_conn_init_static_ (void)
161 */ 166 */
162static void 167static void
163connection_close_error (struct MHD_Connection *connection, 168connection_close_error (struct MHD_Connection *connection,
164 enum MHD_StatusCode sc, 169 enum MHD_StatusCode sc,
165 const char *emsg) 170 const char *emsg)
166{ 171{
167#ifdef HAVE_MESSAGES 172#ifdef HAVE_MESSAGES
168 if (NULL != emsg) 173 if (NULL != emsg)
169 MHD_DLOG (connection->daemon, 174 MHD_DLOG (connection->daemon,
170 sc, 175 sc,
171 emsg); 176 emsg);
172#else /* ! HAVE_MESSAGES */ 177#else /* ! HAVE_MESSAGES */
173 (void) emsg; /* Mute compiler warning. */ 178 (void) emsg; /* Mute compiler warning. */
@@ -209,8 +214,8 @@ try_grow_read_buffer (struct MHD_Request *request)
209 if (0 == request->read_buffer_size) 214 if (0 == request->read_buffer_size)
210 new_size = daemon->connection_memory_limit_b / 2; 215 new_size = daemon->connection_memory_limit_b / 2;
211 else 216 else
212 new_size = request->read_buffer_size + 217 new_size = request->read_buffer_size
213 daemon->connection_memory_increment_b; 218 + daemon->connection_memory_increment_b;
214 buf = MHD_pool_reallocate (request->connection->pool, 219 buf = MHD_pool_reallocate (request->connection->pool,
215 request->read_buffer, 220 request->read_buffer,
216 request->read_buffer_size, 221 request->read_buffer_size,
@@ -245,16 +250,16 @@ MHD_request_handle_read_ (struct MHD_Request *request)
245 struct MHD_TLS_Plugin *tls; 250 struct MHD_TLS_Plugin *tls;
246 251
247 if ( (NULL != (tls = daemon->tls_api)) && 252 if ( (NULL != (tls = daemon->tls_api)) &&
248 (! tls->handshake (tls->cls, 253 (! tls->handshake (tls->cls,
249 connection->tls_cs)) ) 254 connection->tls_cs)) )
250 return; 255 return;
251 } 256 }
252#endif /* HTTPS_SUPPORT */ 257#endif /* HTTPS_SUPPORT */
253 258
254 /* make sure "read" has a reasonable number of bytes 259 /* make sure "read" has a reasonable number of bytes
255 in buffer to use per system call (if possible) */ 260 in buffer to use per system call (if possible) */
256 if (request->read_buffer_offset + 261 if (request->read_buffer_offset
257 daemon->connection_memory_increment_b > 262 + daemon->connection_memory_increment_b >
258 request->read_buffer_size) 263 request->read_buffer_size)
259 try_grow_read_buffer (request); 264 try_grow_read_buffer (request);
260 265
@@ -263,82 +268,84 @@ MHD_request_handle_read_ (struct MHD_Request *request)
263 bytes_read = connection->recv_cls (connection, 268 bytes_read = connection->recv_cls (connection,
264 &request->read_buffer 269 &request->read_buffer
265 [request->read_buffer_offset], 270 [request->read_buffer_offset],
266 request->read_buffer_size - 271 request->read_buffer_size
267 request->read_buffer_offset); 272 - request->read_buffer_offset);
268 if (bytes_read < 0) 273 if (bytes_read < 0)
274 {
275 if (MHD_ERR_AGAIN_ == bytes_read)
276 return; /* No new data to process. */
277 if (MHD_ERR_CONNRESET_ == bytes_read)
269 { 278 {
270 if (MHD_ERR_AGAIN_ == bytes_read)
271 return; /* No new data to process. */
272 if (MHD_ERR_CONNRESET_ == bytes_read)
273 {
274 CONNECTION_CLOSE_ERROR (connection,
275 (MHD_REQUEST_INIT == request->state)
276 ? MHD_SC_CONNECTION_CLOSED
277 : MHD_SC_CONNECTION_RESET_CLOSED,
278 (MHD_REQUEST_INIT == request->state)
279 ? NULL
280 : _("Socket disconnected while reading request.\n"));
281 return;
282 }
283 CONNECTION_CLOSE_ERROR (connection, 279 CONNECTION_CLOSE_ERROR (connection,
284 (MHD_REQUEST_INIT == request->state)
285 ? MHD_SC_CONNECTION_CLOSED
286 : MHD_SC_CONNECTION_READ_FAIL_CLOSED,
287 (MHD_REQUEST_INIT == request->state) 280 (MHD_REQUEST_INIT == request->state)
288 ? NULL 281 ? MHD_SC_CONNECTION_CLOSED
289 : _("Connection socket is closed due to error when reading request.\n")); 282 : MHD_SC_CONNECTION_RESET_CLOSED,
283 (MHD_REQUEST_INIT == request->state)
284 ? NULL
285 : _ (
286 "Socket disconnected while reading request.\n"));
290 return; 287 return;
291 } 288 }
289 CONNECTION_CLOSE_ERROR (connection,
290 (MHD_REQUEST_INIT == request->state)
291 ? MHD_SC_CONNECTION_CLOSED
292 : MHD_SC_CONNECTION_READ_FAIL_CLOSED,
293 (MHD_REQUEST_INIT == request->state)
294 ? NULL
295 : _ (
296 "Connection socket is closed due to error when reading request.\n"));
297 return;
298 }
292 299
293 if (0 == bytes_read) 300 if (0 == bytes_read)
294 { /* Remote side closed connection. */ 301 { /* Remote side closed connection. */
295 connection->read_closed = true; 302 connection->read_closed = true;
296 MHD_connection_close_ (connection, 303 MHD_connection_close_ (connection,
297 MHD_REQUEST_TERMINATED_CLIENT_ABORT); 304 MHD_REQUEST_TERMINATED_CLIENT_ABORT);
298 return; 305 return;
299 } 306 }
300 request->read_buffer_offset += bytes_read; 307 request->read_buffer_offset += bytes_read;
301 MHD_connection_update_last_activity_ (connection); 308 MHD_connection_update_last_activity_ (connection);
302#if DEBUG_STATES 309#if DEBUG_STATES
303 MHD_DLOG (daemon, 310 MHD_DLOG (daemon,
304 MHD_SC_STATE_MACHINE_STATUS_REPORT, 311 MHD_SC_STATE_MACHINE_STATUS_REPORT,
305 _("In function %s handling connection at state: %s\n"), 312 _ ("In function %s handling connection at state: %s\n"),
306 __FUNCTION__, 313 __FUNCTION__,
307 MHD_state_to_string (request->state)); 314 MHD_state_to_string (request->state));
308#endif 315#endif
309 switch (request->state) 316 switch (request->state)
317 {
318 case MHD_REQUEST_INIT:
319 case MHD_REQUEST_URL_RECEIVED:
320 case MHD_REQUEST_HEADER_PART_RECEIVED:
321 case MHD_REQUEST_HEADERS_RECEIVED:
322 case MHD_REQUEST_HEADERS_PROCESSED:
323 case MHD_REQUEST_CONTINUE_SENDING:
324 case MHD_REQUEST_CONTINUE_SENT:
325 case MHD_REQUEST_BODY_RECEIVED:
326 case MHD_REQUEST_FOOTER_PART_RECEIVED:
327 /* nothing to do but default action */
328 if (connection->read_closed)
310 { 329 {
311 case MHD_REQUEST_INIT: 330 MHD_connection_close_ (connection,
312 case MHD_REQUEST_URL_RECEIVED: 331 MHD_REQUEST_TERMINATED_READ_ERROR);
313 case MHD_REQUEST_HEADER_PART_RECEIVED: 332 }
314 case MHD_REQUEST_HEADERS_RECEIVED: 333 return;
315 case MHD_REQUEST_HEADERS_PROCESSED: 334 case MHD_REQUEST_CLOSED:
316 case MHD_REQUEST_CONTINUE_SENDING: 335 return;
317 case MHD_REQUEST_CONTINUE_SENT:
318 case MHD_REQUEST_BODY_RECEIVED:
319 case MHD_REQUEST_FOOTER_PART_RECEIVED:
320 /* nothing to do but default action */
321 if (connection->read_closed)
322 {
323 MHD_connection_close_ (connection,
324 MHD_REQUEST_TERMINATED_READ_ERROR);
325 }
326 return;
327 case MHD_REQUEST_CLOSED:
328 return;
329#ifdef UPGRADE_SUPPORT 336#ifdef UPGRADE_SUPPORT
330 case MHD_REQUEST_UPGRADE: 337 case MHD_REQUEST_UPGRADE:
331 mhd_assert (0); 338 mhd_assert (0);
332 return; 339 return;
333#endif /* UPGRADE_SUPPORT */ 340#endif /* UPGRADE_SUPPORT */
334 default: 341 default:
335 /* shrink read buffer to how much is actually used */ 342 /* shrink read buffer to how much is actually used */
336 MHD_pool_reallocate (connection->pool, 343 MHD_pool_reallocate (connection->pool,
337 request->read_buffer, 344 request->read_buffer,
338 request->read_buffer_size + 1, 345 request->read_buffer_size + 1,
339 request->read_buffer_offset); 346 request->read_buffer_offset);
340 break; 347 break;
341 } 348 }
342 return; 349 return;
343} 350}
344 351
@@ -361,9 +368,9 @@ sendfile_adapter (struct MHD_Connection *connection)
361 uint64_t left; 368 uint64_t left;
362 uint64_t offsetu64; 369 uint64_t offsetu64;
363#ifndef HAVE_SENDFILE64 370#ifndef HAVE_SENDFILE64
364 const uint64_t max_off_t = (uint64_t)OFF_T_MAX; 371 const uint64_t max_off_t = (uint64_t) OFF_T_MAX;
365#else /* HAVE_SENDFILE64 */ 372#else /* HAVE_SENDFILE64 */
366 const uint64_t max_off_t = (uint64_t)OFF64_T_MAX; 373 const uint64_t max_off_t = (uint64_t) OFF64_T_MAX;
367#endif /* HAVE_SENDFILE64 */ 374#endif /* HAVE_SENDFILE64 */
368#ifdef MHD_LINUX_SOLARIS_SENDFILE 375#ifdef MHD_LINUX_SOLARIS_SENDFILE
369#ifndef HAVE_SENDFILE64 376#ifndef HAVE_SENDFILE64
@@ -379,8 +386,10 @@ sendfile_adapter (struct MHD_Connection *connection)
379#ifdef HAVE_DARWIN_SENDFILE 386#ifdef HAVE_DARWIN_SENDFILE
380 off_t len; 387 off_t len;
381#endif /* HAVE_DARWIN_SENDFILE */ 388#endif /* HAVE_DARWIN_SENDFILE */
382 const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode); 389 const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION ==
383 const size_t chunk_size = used_thr_p_c ? MHD_SENFILE_CHUNK_THR_P_C_ : MHD_SENFILE_CHUNK_; 390 daemon->threading_mode);
391 const size_t chunk_size = used_thr_p_c ? MHD_SENFILE_CHUNK_THR_P_C_ :
392 MHD_SENFILE_CHUNK_;
384 size_t send_size = 0; 393 size_t send_size = 0;
385 394
386 mhd_assert (MHD_resp_sender_sendfile == request->resp_sender); 395 mhd_assert (MHD_resp_sender_sendfile == request->resp_sender);
@@ -390,10 +399,10 @@ sendfile_adapter (struct MHD_Connection *connection)
390 * use 128KiB chunks (2MiB for thread-per-connection). */ 399 * use 128KiB chunks (2MiB for thread-per-connection). */
391 send_size = (left > chunk_size) ? chunk_size : (size_t) left; 400 send_size = (left > chunk_size) ? chunk_size : (size_t) left;
392 if (max_off_t < offsetu64) 401 if (max_off_t < offsetu64)
393 { /* Retry to send with standard 'send()'. */ 402 { /* Retry to send with standard 'send()'. */
394 request->resp_sender = MHD_resp_sender_std; 403 request->resp_sender = MHD_resp_sender_std;
395 return MHD_ERR_AGAIN_; 404 return MHD_ERR_AGAIN_;
396 } 405 }
397#ifdef MHD_LINUX_SOLARIS_SENDFILE 406#ifdef MHD_LINUX_SOLARIS_SENDFILE
398#ifndef HAVE_SENDFILE64 407#ifndef HAVE_SENDFILE64
399 offset = (off_t) offsetu64; 408 offset = (off_t) offsetu64;
@@ -409,54 +418,54 @@ sendfile_adapter (struct MHD_Connection *connection)
409 send_size); 418 send_size);
410#endif /* HAVE_SENDFILE64 */ 419#endif /* HAVE_SENDFILE64 */
411 if (0 > ret) 420 if (0 > ret)
412 { 421 {
413 const int err = MHD_socket_get_error_(); 422 const int err = MHD_socket_get_error_ ();
414 423
415 if (MHD_SCKT_ERR_IS_EAGAIN_(err)) 424 if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
416 { 425 {
417#ifdef EPOLL_SUPPORT 426#ifdef EPOLL_SUPPORT
418 /* EAGAIN --- no longer write-ready */ 427 /* EAGAIN --- no longer write-ready */
419 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 428 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
420#endif /* EPOLL_SUPPORT */ 429#endif /* EPOLL_SUPPORT */
421 return MHD_ERR_AGAIN_; 430 return MHD_ERR_AGAIN_;
422 } 431 }
423 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 432 if (MHD_SCKT_ERR_IS_EINTR_ (err))
424 return MHD_ERR_AGAIN_; 433 return MHD_ERR_AGAIN_;
425#ifdef HAVE_LINUX_SENDFILE 434#ifdef HAVE_LINUX_SENDFILE
426 if (MHD_SCKT_ERR_IS_(err, 435 if (MHD_SCKT_ERR_IS_ (err,
427 MHD_SCKT_EBADF_)) 436 MHD_SCKT_EBADF_))
428 return MHD_ERR_BADF_; 437 return MHD_ERR_BADF_;
429 /* sendfile() failed with EINVAL if mmap()-like operations are not 438 /* sendfile() failed with EINVAL if mmap()-like operations are not
430 supported for FD or other 'unusual' errors occurred, so we should try 439 supported for FD or other 'unusual' errors occurred, so we should try
431 to fall back to 'SEND'; see also this thread for info on 440 to fall back to 'SEND'; see also this thread for info on
432 odd libc/Linux behavior with sendfile: 441 odd libc/Linux behavior with sendfile:
433 http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */ 442 http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */
443 request->resp_sender = MHD_resp_sender_std;
444 return MHD_ERR_AGAIN_;
445#else /* HAVE_SOLARIS_SENDFILE */
446 if ( (EAFNOSUPPORT == err) ||
447 (EINVAL == err) ||
448 (EOPNOTSUPP == err) )
449 { /* Retry with standard file reader. */
434 request->resp_sender = MHD_resp_sender_std; 450 request->resp_sender = MHD_resp_sender_std;
435 return MHD_ERR_AGAIN_; 451 return MHD_ERR_AGAIN_;
436#else /* HAVE_SOLARIS_SENDFILE */
437 if ( (EAFNOSUPPORT == err) ||
438 (EINVAL == err) ||
439 (EOPNOTSUPP == err) )
440 { /* Retry with standard file reader. */
441 request->resp_sender = MHD_resp_sender_std;
442 return MHD_ERR_AGAIN_;
443 }
444 if ( (ENOTCONN == err) ||
445 (EPIPE == err) )
446 {
447 return MHD_ERR_CONNRESET_;
448 }
449 return MHD_ERR_BADF_; /* Fail hard */
450#endif /* HAVE_SOLARIS_SENDFILE */
451 } 452 }
453 if ( (ENOTCONN == err) ||
454 (EPIPE == err) )
455 {
456 return MHD_ERR_CONNRESET_;
457 }
458 return MHD_ERR_BADF_; /* Fail hard */
459#endif /* HAVE_SOLARIS_SENDFILE */
460 }
452#ifdef EPOLL_SUPPORT 461#ifdef EPOLL_SUPPORT
453 else if (send_size > (size_t)ret) 462 else if (send_size > (size_t) ret)
454 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 463 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
455#endif /* EPOLL_SUPPORT */ 464#endif /* EPOLL_SUPPORT */
456#elif defined(HAVE_FREEBSD_SENDFILE) 465#elif defined(HAVE_FREEBSD_SENDFILE)
457#ifdef SF_FLAGS 466#ifdef SF_FLAGS
458 flags = used_thr_p_c ? 467 flags = used_thr_p_c ?
459 freebsd_sendfile_flags_thd_p_c_ : freebsd_sendfile_flags_; 468 freebsd_sendfile_flags_thd_p_c_ : freebsd_sendfile_flags_;
460#endif /* SF_FLAGS */ 469#endif /* SF_FLAGS */
461 if (0 != sendfile (file_fd, 470 if (0 != sendfile (file_fd,
462 connection->socket_fd, 471 connection->socket_fd,
@@ -465,26 +474,26 @@ sendfile_adapter (struct MHD_Connection *connection)
465 NULL, 474 NULL,
466 &sent_bytes, 475 &sent_bytes,
467 flags)) 476 flags))
477 {
478 const int err = MHD_socket_get_error_ ();
479 if (MHD_SCKT_ERR_IS_EAGAIN_ (err) ||
480 MHD_SCKT_ERR_IS_EINTR_ (err) ||
481 (EBUSY == err) )
468 { 482 {
469 const int err = MHD_socket_get_error_(); 483 mhd_assert (SSIZE_MAX >= sent_bytes);
470 if (MHD_SCKT_ERR_IS_EAGAIN_(err) || 484 if (0 != sent_bytes)
471 MHD_SCKT_ERR_IS_EINTR_(err) || 485 return (ssize_t) sent_bytes;
472 EBUSY == err)
473 {
474 mhd_assert (SSIZE_MAX >= sent_bytes);
475 if (0 != sent_bytes)
476 return (ssize_t)sent_bytes;
477 486
478 return MHD_ERR_AGAIN_;
479 }
480 /* Some unrecoverable error. Possibly file FD is not suitable
481 * for sendfile(). Retry with standard send(). */
482 request->resp_sender = MHD_resp_sender_std;
483 return MHD_ERR_AGAIN_; 487 return MHD_ERR_AGAIN_;
484 } 488 }
489 /* Some unrecoverable error. Possibly file FD is not suitable
490 * for sendfile(). Retry with standard send(). */
491 request->resp_sender = MHD_resp_sender_std;
492 return MHD_ERR_AGAIN_;
493 }
485 mhd_assert (0 < sent_bytes); 494 mhd_assert (0 < sent_bytes);
486 mhd_assert (SSIZE_MAX >= sent_bytes); 495 mhd_assert (SSIZE_MAX >= sent_bytes);
487 ret = (ssize_t)sent_bytes; 496 ret = (ssize_t) sent_bytes;
488#elif defined(HAVE_DARWIN_SENDFILE) 497#elif defined(HAVE_DARWIN_SENDFILE)
489 len = (off_t) send_size; /* chunk always fit */ 498 len = (off_t) send_size; /* chunk always fit */
490 if (0 != sendfile (file_fd, 499 if (0 != sendfile (file_fd,
@@ -493,35 +502,35 @@ sendfile_adapter (struct MHD_Connection *connection)
493 &len, 502 &len,
494 NULL, 503 NULL,
495 0)) 504 0))
505 {
506 const int err = MHD_socket_get_error_ ();
507 if (MHD_SCKT_ERR_IS_EAGAIN_ (err) ||
508 MHD_SCKT_ERR_IS_EINTR_ (err))
496 { 509 {
497 const int err = MHD_socket_get_error_(); 510 mhd_assert (0 <= len);
498 if (MHD_SCKT_ERR_IS_EAGAIN_(err) || 511 mhd_assert (SSIZE_MAX >= len);
499 MHD_SCKT_ERR_IS_EINTR_(err)) 512 mhd_assert (send_size >= (size_t) len);
500 { 513 if (0 != len)
501 mhd_assert (0 <= len); 514 return (ssize_t) len;
502 mhd_assert (SSIZE_MAX >= len);
503 mhd_assert (send_size >= (size_t)len);
504 if (0 != len)
505 return (ssize_t)len;
506 515
507 return MHD_ERR_AGAIN_; 516 return MHD_ERR_AGAIN_;
508 } 517 }
509 if (ENOTCONN == err || 518 if ((ENOTCONN == err) ||
510 EPIPE == err) 519 (EPIPE == err) )
511 return MHD_ERR_CONNRESET_; 520 return MHD_ERR_CONNRESET_;
512 if (ENOTSUP == err || 521 if ((ENOTSUP == err) ||
513 EOPNOTSUPP == err) 522 (EOPNOTSUPP == err) )
514 { /* This file FD is not suitable for sendfile(). 523 { /* This file FD is not suitable for sendfile().
515 * Retry with standard send(). */ 524 * Retry with standard send(). */
516 request->resp_sender = MHD_resp_sender_std; 525 request->resp_sender = MHD_resp_sender_std;
517 return MHD_ERR_AGAIN_; 526 return MHD_ERR_AGAIN_;
518 }
519 return MHD_ERR_BADF_; /* Return hard error. */
520 } 527 }
528 return MHD_ERR_BADF_; /* Return hard error. */
529 }
521 mhd_assert (0 <= len); 530 mhd_assert (0 <= len);
522 mhd_assert (SSIZE_MAX >= len); 531 mhd_assert (SSIZE_MAX >= len);
523 mhd_assert (send_size >= (size_t)len); 532 mhd_assert (send_size >= (size_t) len);
524 ret = (ssize_t)len; 533 ret = (ssize_t) len;
525#endif /* HAVE_FREEBSD_SENDFILE */ 534#endif /* HAVE_FREEBSD_SENDFILE */
526 return ret; 535 return ret;
527} 536}
@@ -547,7 +556,7 @@ check_write_done (struct MHD_Request *request,
547 request->write_buffer_send_offset = 0; 556 request->write_buffer_send_offset = 0;
548 request->state = next_state; 557 request->state = next_state;
549 MHD_pool_reallocate (request->connection->pool, 558 MHD_pool_reallocate (request->connection->pool,
550 request->write_buffer, 559 request->write_buffer,
551 request->write_buffer_size, 560 request->write_buffer_size,
552 0); 561 0);
553 request->write_buffer = NULL; 562 request->write_buffer = NULL;
@@ -579,47 +588,48 @@ try_ready_normal_body (struct MHD_Request *request)
579 (request->response_write_position == response->total_size) ) 588 (request->response_write_position == response->total_size) )
580 return true; /* 0-byte response is always ready */ 589 return true; /* 0-byte response is always ready */
581 if ( (response->data_start <= 590 if ( (response->data_start <=
582 request->response_write_position) && 591 request->response_write_position) &&
583 (response->data_size + response->data_start > 592 (response->data_size + response->data_start >
584 request->response_write_position) ) 593 request->response_write_position) )
585 return true; /* response already ready */ 594 return true; /* response already ready */
586#if defined(_MHD_HAVE_SENDFILE) 595#if defined(_MHD_HAVE_SENDFILE)
587 if (MHD_resp_sender_sendfile == request->resp_sender) 596 if (MHD_resp_sender_sendfile == request->resp_sender)
588 { 597 {
589 /* will use sendfile, no need to bother response crc */ 598 /* will use sendfile, no need to bother response crc */
590 return true; 599 return true;
591 } 600 }
592#endif /* _MHD_HAVE_SENDFILE */ 601#endif /* _MHD_HAVE_SENDFILE */
593 602
594 ret = response->crc (response->crc_cls, 603 ret = response->crc (response->crc_cls,
595 request->response_write_position, 604 request->response_write_position,
596 response->data, 605 response->data,
597 (size_t) MHD_MIN ((uint64_t) response->data_buffer_size, 606 (size_t) MHD_MIN ((uint64_t) response->data_buffer_size,
598 response->total_size - 607 response->total_size
599 request->response_write_position)); 608 - request->response_write_position));
600 if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) || 609 if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) ||
601 (((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret) ) 610 (((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret) )
602 { 611 {
603 /* either error or http 1.0 transfer, close socket! */ 612 /* either error or http 1.0 transfer, close socket! */
604 response->total_size = request->response_write_position; 613 response->total_size = request->response_write_position;
605 MHD_mutex_unlock_chk_ (&response->mutex); 614 MHD_mutex_unlock_chk_ (&response->mutex);
606 if ( ((ssize_t)MHD_CONTENT_READER_END_OF_STREAM) == ret) 615 if ( ((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret)
607 MHD_connection_close_ (connection, 616 MHD_connection_close_ (connection,
608 MHD_REQUEST_TERMINATED_COMPLETED_OK); 617 MHD_REQUEST_TERMINATED_COMPLETED_OK);
609 else 618 else
610 CONNECTION_CLOSE_ERROR (connection, 619 CONNECTION_CLOSE_ERROR (connection,
611 MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED, 620 MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED,
612 _("Closing connection (application reported error generating data)\n")); 621 _ (
613 return false; 622 "Closing connection (application reported error generating data)\n"));
614 } 623 return false;
624 }
615 response->data_start = request->response_write_position; 625 response->data_start = request->response_write_position;
616 response->data_size = ret; 626 response->data_size = ret;
617 if (0 == ret) 627 if (0 == ret)
618 { 628 {
619 request->state = MHD_REQUEST_NORMAL_BODY_UNREADY; 629 request->state = MHD_REQUEST_NORMAL_BODY_UNREADY;
620 MHD_mutex_unlock_chk_ (&response->mutex); 630 MHD_mutex_unlock_chk_ (&response->mutex);
621 return false; 631 return false;
622 } 632 }
623 return true; 633 return true;
624} 634}
625 635
@@ -647,93 +657,94 @@ try_ready_chunked_body (struct MHD_Request *request)
647 if (NULL == response->crc) 657 if (NULL == response->crc)
648 return true; 658 return true;
649 if (0 == request->write_buffer_size) 659 if (0 == request->write_buffer_size)
650 { 660 {
651 size = MHD_MIN (daemon->connection_memory_limit_b, 661 size = MHD_MIN (daemon->connection_memory_limit_b,
652 2 * (0xFFFFFF + sizeof(cbuf) + 2)); 662 2 * (0xFFFFFF + sizeof(cbuf) + 2));
653 do 663 do
654 { 664 {
655 size /= 2; 665 size /= 2;
656 if (size < 128) 666 if (size < 128)
657 { 667 {
658 MHD_mutex_unlock_chk_ (&response->mutex); 668 MHD_mutex_unlock_chk_ (&response->mutex);
659 /* not enough memory */ 669 /* not enough memory */
660 CONNECTION_CLOSE_ERROR (connection, 670 CONNECTION_CLOSE_ERROR (connection,
661 MHD_SC_CONNECTION_POOL_MALLOC_FAILURE, 671 MHD_SC_CONNECTION_POOL_MALLOC_FAILURE,
662 _("Closing connection (out of memory)\n")); 672 _ ("Closing connection (out of memory)\n"));
663 return false; 673 return false;
664 } 674 }
665 buf = MHD_pool_allocate (connection->pool, 675 buf = MHD_pool_allocate (connection->pool,
666 size, 676 size,
667 MHD_NO); 677 MHD_NO);
668 } 678 }
669 while (NULL == buf); 679 while (NULL == buf);
670 request->write_buffer_size = size; 680 request->write_buffer_size = size;
671 request->write_buffer = buf; 681 request->write_buffer = buf;
672 } 682 }
673 683
674 if (0 == response->total_size) 684 if (0 == response->total_size)
675 ret = 0; /* response must be empty, don't bother calling crc */ 685 ret = 0; /* response must be empty, don't bother calling crc */
676 else if ( (response->data_start <= 686 else if ( (response->data_start <=
677 request->response_write_position) && 687 request->response_write_position) &&
678 (response->data_start + response->data_size > 688 (response->data_start + response->data_size >
679 request->response_write_position) ) 689 request->response_write_position) )
680 { 690 {
681 /* difference between response_write_position and data_start is less 691 /* difference between response_write_position and data_start is less
682 than data_size which is size_t type, no need to check for overflow */ 692 than data_size which is size_t type, no need to check for overflow */
683 const size_t data_write_offset 693 const size_t data_write_offset
684 = (size_t)(request->response_write_position - response->data_start); 694 = (size_t) (request->response_write_position - response->data_start);
685 /* buffer already ready, use what is there for the chunk */ 695 /* buffer already ready, use what is there for the chunk */
686 ret = response->data_size - data_write_offset; 696 ret = response->data_size - data_write_offset;
687 if ( ((size_t) ret) > request->write_buffer_size - sizeof (cbuf) - 2 ) 697 if ( ((size_t) ret) > request->write_buffer_size - sizeof (cbuf) - 2 )
688 ret = request->write_buffer_size - sizeof (cbuf) - 2; 698 ret = request->write_buffer_size - sizeof (cbuf) - 2;
689 memcpy (&request->write_buffer[sizeof (cbuf)], 699 memcpy (&request->write_buffer[sizeof (cbuf)],
690 &response->data[data_write_offset], 700 &response->data[data_write_offset],
691 ret); 701 ret);
692 } 702 }
693 else 703 else
694 { 704 {
695 /* buffer not in range, try to fill it */ 705 /* buffer not in range, try to fill it */
696 ret = response->crc (response->crc_cls, 706 ret = response->crc (response->crc_cls,
697 request->response_write_position, 707 request->response_write_position,
698 &request->write_buffer[sizeof (cbuf)], 708 &request->write_buffer[sizeof (cbuf)],
699 request->write_buffer_size - sizeof (cbuf) - 2); 709 request->write_buffer_size - sizeof (cbuf) - 2);
700 } 710 }
701 if ( ((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret) 711 if ( ((ssize_t) MHD_CONTENT_READER_END_WITH_ERROR) == ret)
702 { 712 {
703 /* error, close socket! */ 713 /* error, close socket! */
704 response->total_size = request->response_write_position; 714 response->total_size = request->response_write_position;
705 MHD_mutex_unlock_chk_ (&response->mutex); 715 MHD_mutex_unlock_chk_ (&response->mutex);
706 CONNECTION_CLOSE_ERROR (connection, 716 CONNECTION_CLOSE_ERROR (connection,
707 MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED, 717 MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED,
708 _("Closing connection (application error generating response)\n")); 718 _ (
709 return false; 719 "Closing connection (application error generating response)\n"));
710 } 720 return false;
721 }
711 if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) || 722 if ( (((ssize_t) MHD_CONTENT_READER_END_OF_STREAM) == ret) ||
712 (0 == response->total_size) ) 723 (0 == response->total_size) )
713 { 724 {
714 /* end of message, signal other side! */ 725 /* end of message, signal other side! */
715 memcpy (request->write_buffer, 726 memcpy (request->write_buffer,
716 "0\r\n", 727 "0\r\n",
717 3); 728 3);
718 request->write_buffer_append_offset = 3; 729 request->write_buffer_append_offset = 3;
719 request->write_buffer_send_offset = 0; 730 request->write_buffer_send_offset = 0;
720 response->total_size = request->response_write_position; 731 response->total_size = request->response_write_position;
721 return true; 732 return true;
722 } 733 }
723 if (0 == ret) 734 if (0 == ret)
724 { 735 {
725 request->state = MHD_REQUEST_CHUNKED_BODY_UNREADY; 736 request->state = MHD_REQUEST_CHUNKED_BODY_UNREADY;
726 MHD_mutex_unlock_chk_ (&response->mutex); 737 MHD_mutex_unlock_chk_ (&response->mutex);
727 return false; 738 return false;
728 } 739 }
729 if (ret > 0xFFFFFF) 740 if (ret > 0xFFFFFF)
730 ret = 0xFFFFFF; 741 ret = 0xFFFFFF;
731 cblen = MHD_snprintf_(cbuf, 742 cblen = MHD_snprintf_ (cbuf,
732 sizeof (cbuf), 743 sizeof (cbuf),
733 "%X\r\n", 744 "%X\r\n",
734 (unsigned int) ret); 745 (unsigned int) ret);
735 mhd_assert(cblen > 0); 746 mhd_assert (cblen > 0);
736 mhd_assert((size_t)cblen < sizeof(cbuf)); 747 mhd_assert ((size_t) cblen < sizeof(cbuf));
737 memcpy (&request->write_buffer[sizeof (cbuf) - cblen], 748 memcpy (&request->write_buffer[sizeof (cbuf) - cblen],
738 cbuf, 749 cbuf,
739 cblen); 750 cblen);
@@ -768,221 +779,224 @@ MHD_request_handle_write_ (struct MHD_Request *request)
768 struct MHD_TLS_Plugin *tls; 779 struct MHD_TLS_Plugin *tls;
769 780
770 if ( (NULL != (tls = daemon->tls_api)) && 781 if ( (NULL != (tls = daemon->tls_api)) &&
771 (! tls->handshake (tls->cls, 782 (! tls->handshake (tls->cls,
772 connection->tls_cs)) ) 783 connection->tls_cs)) )
773 return; 784 return;
774 } 785 }
775#endif /* HTTPS_SUPPORT */ 786#endif /* HTTPS_SUPPORT */
776 787
777#if DEBUG_STATES 788#if DEBUG_STATES
778 MHD_DLOG (daemon, 789 MHD_DLOG (daemon,
779 MHD_SC_STATE_MACHINE_STATUS_REPORT, 790 MHD_SC_STATE_MACHINE_STATUS_REPORT,
780 _("In function %s handling connection at state: %s\n"), 791 _ ("In function %s handling connection at state: %s\n"),
781 __FUNCTION__, 792 __FUNCTION__,
782 MHD_state_to_string (request->state)); 793 MHD_state_to_string (request->state));
783#endif 794#endif
784 switch (request->state) 795 switch (request->state)
785 { 796 {
786 case MHD_REQUEST_INIT: 797 case MHD_REQUEST_INIT:
787 case MHD_REQUEST_URL_RECEIVED: 798 case MHD_REQUEST_URL_RECEIVED:
788 case MHD_REQUEST_HEADER_PART_RECEIVED: 799 case MHD_REQUEST_HEADER_PART_RECEIVED:
789 case MHD_REQUEST_HEADERS_RECEIVED: 800 case MHD_REQUEST_HEADERS_RECEIVED:
790 mhd_assert (0); 801 mhd_assert (0);
791 return; 802 return;
792 case MHD_REQUEST_HEADERS_PROCESSED: 803 case MHD_REQUEST_HEADERS_PROCESSED:
793 return; 804 return;
794 case MHD_REQUEST_CONTINUE_SENDING: 805 case MHD_REQUEST_CONTINUE_SENDING:
795 ret = connection->send_cls (connection, 806 ret = connection->send_cls (connection,
796 &HTTP_100_CONTINUE 807 &HTTP_100_CONTINUE
797 [request->continue_message_write_offset], 808 [request->continue_message_write_offset],
798 MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE) - 809 MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)
799 request->continue_message_write_offset); 810 - request->continue_message_write_offset);
800 if (ret < 0) 811 if (ret < 0)
801 { 812 {
802 if (MHD_ERR_AGAIN_ == ret) 813 if (MHD_ERR_AGAIN_ == ret)
803 return; 814 return;
804#ifdef HAVE_MESSAGES 815#ifdef HAVE_MESSAGES
805 MHD_DLOG (daemon, 816 MHD_DLOG (daemon,
806 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, 817 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
807 _("Failed to send data in request for %s.\n"), 818 _ ("Failed to send data in request for %s.\n"),
808 request->url); 819 request->url);
809#endif 820#endif
810 CONNECTION_CLOSE_ERROR (connection, 821 CONNECTION_CLOSE_ERROR (connection,
811 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, 822 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
812 NULL); 823 NULL);
813 return;
814 }
815 request->continue_message_write_offset += ret;
816 MHD_connection_update_last_activity_ (connection);
817 return;
818 case MHD_REQUEST_CONTINUE_SENT:
819 case MHD_REQUEST_BODY_RECEIVED:
820 case MHD_REQUEST_FOOTER_PART_RECEIVED:
821 case MHD_REQUEST_FOOTERS_RECEIVED:
822 mhd_assert (0);
823 return; 824 return;
824 case MHD_REQUEST_HEADERS_SENDING: 825 }
825 ret = connection->send_cls (connection, 826 request->continue_message_write_offset += ret;
826 &request->write_buffer 827 MHD_connection_update_last_activity_ (connection);
827 [request->write_buffer_send_offset], 828 return;
828 request->write_buffer_append_offset - 829 case MHD_REQUEST_CONTINUE_SENT:
829 request->write_buffer_send_offset); 830 case MHD_REQUEST_BODY_RECEIVED:
830 if (ret < 0) 831 case MHD_REQUEST_FOOTER_PART_RECEIVED:
831 { 832 case MHD_REQUEST_FOOTERS_RECEIVED:
832 if (MHD_ERR_AGAIN_ == ret) 833 mhd_assert (0);
833 return; 834 return;
834 CONNECTION_CLOSE_ERROR (connection, 835 case MHD_REQUEST_HEADERS_SENDING:
835 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, 836 ret = connection->send_cls (connection,
836 _("Connection was closed while sending response headers.\n")); 837 &request->write_buffer
837 return; 838 [request->write_buffer_send_offset],
838 } 839 request->write_buffer_append_offset
839 request->write_buffer_send_offset += ret; 840 - request->write_buffer_send_offset);
840 MHD_connection_update_last_activity_ (connection); 841 if (ret < 0)
841 if (MHD_REQUEST_HEADERS_SENDING != request->state) 842 {
843 if (MHD_ERR_AGAIN_ == ret)
842 return; 844 return;
843 check_write_done (request, 845 CONNECTION_CLOSE_ERROR (connection,
844 MHD_REQUEST_HEADERS_SENT); 846 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
847 _ (
848 "Connection was closed while sending response headers.\n"));
845 return; 849 return;
846 case MHD_REQUEST_HEADERS_SENT: 850 }
851 request->write_buffer_send_offset += ret;
852 MHD_connection_update_last_activity_ (connection);
853 if (MHD_REQUEST_HEADERS_SENDING != request->state)
847 return; 854 return;
848 case MHD_REQUEST_NORMAL_BODY_READY: 855 check_write_done (request,
849 response = request->response; 856 MHD_REQUEST_HEADERS_SENT);
850 if (request->response_write_position < 857 return;
851 request->response->total_size) 858 case MHD_REQUEST_HEADERS_SENT:
852 { 859 return;
853 uint64_t data_write_offset; 860 case MHD_REQUEST_NORMAL_BODY_READY:
854 861 response = request->response;
855 if (NULL != response->crc) 862 if (request->response_write_position <
856 MHD_mutex_lock_chk_ (&response->mutex); 863 request->response->total_size)
857 if (! try_ready_normal_body (request)) 864 {
858 { 865 uint64_t data_write_offset;
859 /* mutex was already unlocked by try_ready_normal_body */ 866
860 return; 867 if (NULL != response->crc)
861 } 868 MHD_mutex_lock_chk_ (&response->mutex);
869 if (! try_ready_normal_body (request))
870 {
871 /* mutex was already unlocked by try_ready_normal_body */
872 return;
873 }
862#if defined(_MHD_HAVE_SENDFILE) 874#if defined(_MHD_HAVE_SENDFILE)
863 if (MHD_resp_sender_sendfile == request->resp_sender) 875 if (MHD_resp_sender_sendfile == request->resp_sender)
864 { 876 {
865 ret = sendfile_adapter (connection); 877 ret = sendfile_adapter (connection);
866 } 878 }
867 else 879 else
868#else /* ! _MHD_HAVE_SENDFILE */ 880#else /* ! _MHD_HAVE_SENDFILE */
869 if (1) 881 if (1)
870#endif /* ! _MHD_HAVE_SENDFILE */ 882#endif /* ! _MHD_HAVE_SENDFILE */
871 { 883 {
872 data_write_offset = request->response_write_position 884 data_write_offset = request->response_write_position
873 - response->data_start; 885 - response->data_start;
874 if (data_write_offset > (uint64_t)SIZE_MAX) 886 if (data_write_offset > (uint64_t) SIZE_MAX)
875 MHD_PANIC (_("Data offset exceeds limit")); 887 MHD_PANIC (_ ("Data offset exceeds limit"));
876 ret = connection->send_cls (connection, 888 ret = connection->send_cls (connection,
877 &response->data 889 &response->data
878 [(size_t)data_write_offset], 890 [(size_t) data_write_offset],
879 response->data_size - 891 response->data_size
880 (size_t)data_write_offset); 892 - (size_t) data_write_offset);
881#if DEBUG_SEND_DATA 893#if DEBUG_SEND_DATA
882 if (ret > 0) 894 if (ret > 0)
883 fprintf (stderr, 895 fprintf (stderr,
884 _("Sent %d-byte DATA response: `%.*s'\n"), 896 _ ("Sent %d-byte DATA response: `%.*s'\n"),
885 (int) ret, 897 (int) ret,
886 (int) ret, 898 (int) ret,
887 &response->data[request->response_write_position - 899 &response->data[request->response_write_position
888 response->data_start]); 900 - response->data_start]);
889#endif 901#endif
890 } 902 }
891 if (NULL != response->crc) 903 if (NULL != response->crc)
892 MHD_mutex_unlock_chk_ (&response->mutex); 904 MHD_mutex_unlock_chk_ (&response->mutex);
893 if (ret < 0)
894 {
895 if (MHD_ERR_AGAIN_ == ret)
896 return;
897#ifdef HAVE_MESSAGES
898 MHD_DLOG (daemon,
899 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
900 _("Failed to send data in request for `%s'.\n"),
901 request->url);
902#endif
903 CONNECTION_CLOSE_ERROR (connection,
904 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
905 NULL);
906 return;
907 }
908 request->response_write_position += ret;
909 MHD_connection_update_last_activity_ (connection);
910 }
911 if (request->response_write_position ==
912 request->response->total_size)
913 request->state = MHD_REQUEST_FOOTERS_SENT; /* have no footers */
914 return;
915 case MHD_REQUEST_NORMAL_BODY_UNREADY:
916 mhd_assert (0);
917 return;
918 case MHD_REQUEST_CHUNKED_BODY_READY:
919 ret = connection->send_cls (connection,
920 &request->write_buffer
921 [request->write_buffer_send_offset],
922 request->write_buffer_append_offset -
923 request->write_buffer_send_offset);
924 if (ret < 0) 905 if (ret < 0)
925 { 906 {
926 if (MHD_ERR_AGAIN_ == ret) 907 if (MHD_ERR_AGAIN_ == ret)
927 return;
928 CONNECTION_CLOSE_ERROR (connection,
929 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
930 _("Connection was closed while sending response body.\n"));
931 return; 908 return;
932 } 909#ifdef HAVE_MESSAGES
933 request->write_buffer_send_offset += ret; 910 MHD_DLOG (daemon,
911 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
912 _ ("Failed to send data in request for `%s'.\n"),
913 request->url);
914#endif
915 CONNECTION_CLOSE_ERROR (connection,
916 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
917 NULL);
918 return;
919 }
920 request->response_write_position += ret;
934 MHD_connection_update_last_activity_ (connection); 921 MHD_connection_update_last_activity_ (connection);
935 if (MHD_REQUEST_CHUNKED_BODY_READY != request->state) 922 }
923 if (request->response_write_position ==
924 request->response->total_size)
925 request->state = MHD_REQUEST_FOOTERS_SENT; /* have no footers */
926 return;
927 case MHD_REQUEST_NORMAL_BODY_UNREADY:
928 mhd_assert (0);
929 return;
930 case MHD_REQUEST_CHUNKED_BODY_READY:
931 ret = connection->send_cls (connection,
932 &request->write_buffer
933 [request->write_buffer_send_offset],
934 request->write_buffer_append_offset
935 - request->write_buffer_send_offset);
936 if (ret < 0)
937 {
938 if (MHD_ERR_AGAIN_ == ret)
936 return; 939 return;
937 check_write_done (request, 940 CONNECTION_CLOSE_ERROR (connection,
938 (request->response->total_size == 941 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
939 request->response_write_position) ? 942 _ (
940 MHD_REQUEST_BODY_SENT : 943 "Connection was closed while sending response body.\n"));
941 MHD_REQUEST_CHUNKED_BODY_UNREADY);
942 return; 944 return;
943 case MHD_REQUEST_CHUNKED_BODY_UNREADY: 945 }
944 case MHD_REQUEST_BODY_SENT: 946 request->write_buffer_send_offset += ret;
945 mhd_assert (0); 947 MHD_connection_update_last_activity_ (connection);
948 if (MHD_REQUEST_CHUNKED_BODY_READY != request->state)
946 return; 949 return;
947 case MHD_REQUEST_FOOTERS_SENDING: 950 check_write_done (request,
948 ret = connection->send_cls (connection, 951 (request->response->total_size ==
949 &request->write_buffer 952 request->response_write_position) ?
950 [request->write_buffer_send_offset], 953 MHD_REQUEST_BODY_SENT :
951 request->write_buffer_append_offset - 954 MHD_REQUEST_CHUNKED_BODY_UNREADY);
952 request->write_buffer_send_offset); 955 return;
953 if (ret < 0) 956 case MHD_REQUEST_CHUNKED_BODY_UNREADY:
954 { 957 case MHD_REQUEST_BODY_SENT:
955 if (MHD_ERR_AGAIN_ == ret) 958 mhd_assert (0);
956 return; 959 return;
957 CONNECTION_CLOSE_ERROR (connection, 960 case MHD_REQUEST_FOOTERS_SENDING:
958 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED, 961 ret = connection->send_cls (connection,
959 _("Connection was closed while sending response body.\n")); 962 &request->write_buffer
960 return; 963 [request->write_buffer_send_offset],
961 } 964 request->write_buffer_append_offset
962 request->write_buffer_send_offset += ret; 965 - request->write_buffer_send_offset);
963 MHD_connection_update_last_activity_ (connection); 966 if (ret < 0)
964 if (MHD_REQUEST_FOOTERS_SENDING != request->state) 967 {
968 if (MHD_ERR_AGAIN_ == ret)
965 return; 969 return;
966 check_write_done (request, 970 CONNECTION_CLOSE_ERROR (connection,
967 MHD_REQUEST_FOOTERS_SENT); 971 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
968 return; 972 _ (
969 case MHD_REQUEST_FOOTERS_SENT: 973 "Connection was closed while sending response body.\n"));
970 mhd_assert (0);
971 return; 974 return;
972 case MHD_REQUEST_CLOSED: 975 }
976 request->write_buffer_send_offset += ret;
977 MHD_connection_update_last_activity_ (connection);
978 if (MHD_REQUEST_FOOTERS_SENDING != request->state)
973 return; 979 return;
980 check_write_done (request,
981 MHD_REQUEST_FOOTERS_SENT);
982 return;
983 case MHD_REQUEST_FOOTERS_SENT:
984 mhd_assert (0);
985 return;
986 case MHD_REQUEST_CLOSED:
987 return;
974#ifdef UPGRADE_SUPPORT 988#ifdef UPGRADE_SUPPORT
975 case MHD_REQUEST_UPGRADE: 989 case MHD_REQUEST_UPGRADE:
976 mhd_assert (0); 990 mhd_assert (0);
977 return; 991 return;
978#endif /* UPGRADE_SUPPORT */ 992#endif /* UPGRADE_SUPPORT */
979 default: 993 default:
980 mhd_assert (0); 994 mhd_assert (0);
981 CONNECTION_CLOSE_ERROR (connection, 995 CONNECTION_CLOSE_ERROR (connection,
982 MHD_SC_STATEMACHINE_FAILURE_CONNECTION_CLOSED, 996 MHD_SC_STATEMACHINE_FAILURE_CONNECTION_CLOSED,
983 _("Internal error\n")); 997 _ ("Internal error\n"));
984 break; 998 break;
985 } 999 }
986} 1000}
987 1001
988 1002
@@ -1001,9 +1015,9 @@ MHD_request_handle_write_ (struct MHD_Request *request)
1001 */ 1015 */
1002static bool 1016static bool
1003MHD_lookup_header_token_ci (const struct MHD_Request *request, 1017MHD_lookup_header_token_ci (const struct MHD_Request *request,
1004 const char *header, 1018 const char *header,
1005 const char *token, 1019 const char *token,
1006 size_t token_len) 1020 size_t token_len)
1007{ 1021{
1008 struct MHD_HTTP_Header *pos; 1022 struct MHD_HTTP_Header *pos;
1009 1023
@@ -1014,16 +1028,16 @@ MHD_lookup_header_token_ci (const struct MHD_Request *request,
1014 (0 == token[0]) ) 1028 (0 == token[0]) )
1015 return false; 1029 return false;
1016 for (pos = request->headers_received; NULL != pos; pos = pos->next) 1030 for (pos = request->headers_received; NULL != pos; pos = pos->next)
1017 { 1031 {
1018 if ( (0 != (pos->kind & MHD_HEADER_KIND)) && 1032 if ( (0 != (pos->kind & MHD_HEADER_KIND)) &&
1019 ( (header == pos->header) || 1033 ( (header == pos->header) ||
1020 (MHD_str_equal_caseless_(header, 1034 (MHD_str_equal_caseless_ (header,
1021 pos->header)) ) && 1035 pos->header)) ) &&
1022 (MHD_str_has_token_caseless_ (pos->value, 1036 (MHD_str_has_token_caseless_ (pos->value,
1023 token, 1037 token,
1024 token_len)) ) 1038 token_len)) )
1025 return true; 1039 return true;
1026 } 1040 }
1027 return false; 1041 return false;
1028} 1042}
1029 1043
@@ -1040,7 +1054,7 @@ MHD_lookup_header_token_ci (const struct MHD_Request *request,
1040 * false otherwise 1054 * false otherwise
1041 */ 1055 */
1042#define MHD_lookup_header_s_token_ci(r,h,tkn) \ 1056#define MHD_lookup_header_s_token_ci(r,h,tkn) \
1043 MHD_lookup_header_token_ci((r),(h),(tkn),MHD_STATICSTR_LEN_(tkn)) 1057 MHD_lookup_header_token_ci ((r),(h),(tkn),MHD_STATICSTR_LEN_ (tkn))
1044 1058
1045 1059
1046/** 1060/**
@@ -1071,27 +1085,27 @@ keepalive_possible (struct MHD_Request *request)
1071 return false; 1085 return false;
1072 1086
1073 if (MHD_str_equal_caseless_ (request->version_s, 1087 if (MHD_str_equal_caseless_ (request->version_s,
1074 MHD_HTTP_VERSION_1_1)) 1088 MHD_HTTP_VERSION_1_1))
1075 { 1089 {
1076 if (MHD_lookup_header_s_token_ci (request, 1090 if (MHD_lookup_header_s_token_ci (request,
1077 MHD_HTTP_HEADER_CONNECTION, 1091 MHD_HTTP_HEADER_CONNECTION,
1078 "upgrade")) 1092 "upgrade"))
1079 return false;
1080 if (MHD_lookup_header_s_token_ci (request,
1081 MHD_HTTP_HEADER_CONNECTION,
1082 "close"))
1083 return false;
1084 return true;
1085 }
1086 if (MHD_str_equal_caseless_ (request->version_s,
1087 MHD_HTTP_VERSION_1_0))
1088 {
1089 if (MHD_lookup_header_s_token_ci (request,
1090 MHD_HTTP_HEADER_CONNECTION,
1091 "Keep-Alive"))
1092 return true;
1093 return false; 1093 return false;
1094 } 1094 if (MHD_lookup_header_s_token_ci (request,
1095 MHD_HTTP_HEADER_CONNECTION,
1096 "close"))
1097 return false;
1098 return true;
1099 }
1100 if (MHD_str_equal_caseless_ (request->version_s,
1101 MHD_HTTP_VERSION_1_0))
1102 {
1103 if (MHD_lookup_header_s_token_ci (request,
1104 MHD_HTTP_HEADER_CONNECTION,
1105 "Keep-Alive"))
1106 return true;
1107 return false;
1108 }
1095 return false; 1109 return false;
1096} 1110}
1097 1111
@@ -1105,7 +1119,7 @@ keepalive_possible (struct MHD_Request *request)
1105 */ 1119 */
1106static void 1120static void
1107get_date_string (char *date, 1121get_date_string (char *date,
1108 size_t date_len) 1122 size_t date_len)
1109{ 1123{
1110 static const char *const days[] = { 1124 static const char *const days[] = {
1111 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 1125 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
@@ -1116,8 +1130,9 @@ get_date_string (char *date,
1116 }; 1130 };
1117 struct tm now; 1131 struct tm now;
1118 time_t t; 1132 time_t t;
1119#if !defined(HAVE_C11_GMTIME_S) && !defined(HAVE_W32_GMTIME_S) && !defined(HAVE_GMTIME_R) 1133#if ! defined(HAVE_C11_GMTIME_S) && ! defined(HAVE_W32_GMTIME_S) && \
1120 struct tm* pNow; 1134 ! defined(HAVE_GMTIME_R)
1135 struct tm*pNow;
1121#endif 1136#endif
1122 1137
1123 date[0] = 0; 1138 date[0] = 0;
@@ -1131,25 +1146,25 @@ get_date_string (char *date,
1131 &t)) 1146 &t))
1132 return; 1147 return;
1133#elif defined(HAVE_GMTIME_R) 1148#elif defined(HAVE_GMTIME_R)
1134 if (NULL == gmtime_r(&t, 1149 if (NULL == gmtime_r (&t,
1135 &now)) 1150 &now))
1136 return; 1151 return;
1137#else 1152#else
1138 pNow = gmtime(&t); 1153 pNow = gmtime (&t);
1139 if (NULL == pNow) 1154 if (NULL == pNow)
1140 return; 1155 return;
1141 now = *pNow; 1156 now = *pNow;
1142#endif 1157#endif
1143 MHD_snprintf_ (date, 1158 MHD_snprintf_ (date,
1144 date_len, 1159 date_len,
1145 "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n", 1160 "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n",
1146 days[now.tm_wday % 7], 1161 days[now.tm_wday % 7],
1147 (unsigned int) now.tm_mday, 1162 (unsigned int) now.tm_mday,
1148 mons[now.tm_mon % 12], 1163 mons[now.tm_mon % 12],
1149 (unsigned int) (1900 + now.tm_year), 1164 (unsigned int) (1900 + now.tm_year),
1150 (unsigned int) now.tm_hour, 1165 (unsigned int) now.tm_hour,
1151 (unsigned int) now.tm_min, 1166 (unsigned int) now.tm_min,
1152 (unsigned int) now.tm_sec); 1167 (unsigned int) now.tm_sec);
1153} 1168}
1154 1169
1155 1170
@@ -1168,9 +1183,9 @@ get_date_string (char *date,
1168 */ 1183 */
1169static bool 1184static bool
1170check_response_header_token_ci (const struct MHD_Response *response, 1185check_response_header_token_ci (const struct MHD_Response *response,
1171 const char *key, 1186 const char *key,
1172 const char *token, 1187 const char *token,
1173 size_t token_len) 1188 size_t token_len)
1174{ 1189{
1175 struct MHD_HTTP_Header *pos; 1190 struct MHD_HTTP_Header *pos;
1176 1191
@@ -1183,15 +1198,15 @@ check_response_header_token_ci (const struct MHD_Response *response,
1183 for (pos = response->first_header; 1198 for (pos = response->first_header;
1184 NULL != pos; 1199 NULL != pos;
1185 pos = pos->next) 1200 pos = pos->next)
1186 { 1201 {
1187 if ( (pos->kind == MHD_HEADER_KIND) && 1202 if ( (pos->kind == MHD_HEADER_KIND) &&
1188 MHD_str_equal_caseless_ (pos->header, 1203 MHD_str_equal_caseless_ (pos->header,
1189 key) && 1204 key) &&
1190 MHD_str_has_token_caseless_ (pos->value, 1205 MHD_str_has_token_caseless_ (pos->value,
1191 token, 1206 token,
1192 token_len) ) 1207 token_len) )
1193 return true; 1208 return true;
1194 } 1209 }
1195 return false; 1210 return false;
1196} 1211}
1197 1212
@@ -1208,7 +1223,7 @@ check_response_header_token_ci (const struct MHD_Response *response,
1208 * false otherwise 1223 * false otherwise
1209 */ 1224 */
1210#define check_response_header_s_token_ci(r,k,tkn) \ 1225#define check_response_header_s_token_ci(r,k,tkn) \
1211 check_response_header_token_ci((r),(k),(tkn),MHD_STATICSTR_LEN_(tkn)) 1226 check_response_header_token_ci ((r),(k),(tkn),MHD_STATICSTR_LEN_ (tkn))
1212 1227
1213 1228
1214/** 1229/**
@@ -1248,58 +1263,58 @@ build_header_response (struct MHD_Request *request)
1248 1263
1249 mhd_assert (NULL != request->version_s); 1264 mhd_assert (NULL != request->version_s);
1250 if (0 == request->version_s[0]) 1265 if (0 == request->version_s[0])
1251 { 1266 {
1252 data = MHD_pool_allocate (connection->pool, 1267 data = MHD_pool_allocate (connection->pool,
1253 0, 1268 0,
1254 MHD_YES); 1269 MHD_YES);
1255 request->write_buffer = data; 1270 request->write_buffer = data;
1256 request->write_buffer_append_offset = 0; 1271 request->write_buffer_append_offset = 0;
1257 request->write_buffer_send_offset = 0; 1272 request->write_buffer_send_offset = 0;
1258 request->write_buffer_size = 0; 1273 request->write_buffer_size = 0;
1259 return true; 1274 return true;
1260 } 1275 }
1261 if (MHD_REQUEST_FOOTERS_RECEIVED == request->state) 1276 if (MHD_REQUEST_FOOTERS_RECEIVED == request->state)
1262 { 1277 {
1263 const char *reason_phrase; 1278 const char *reason_phrase;
1264 const char *version; 1279 const char *version;
1265 1280
1266 reason_phrase 1281 reason_phrase
1267 = MHD_get_reason_phrase_for (response->status_code); 1282 = MHD_get_reason_phrase_for (response->status_code);
1268 version 1283 version
1269 = (response->icy) 1284 = (response->icy)
1270 ? "ICY" 1285 ? "ICY"
1271 : ( (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_0, 1286 : ( (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_0,
1272 request->version_s)) 1287 request->version_s))
1273 ? MHD_HTTP_VERSION_1_0 1288 ? MHD_HTTP_VERSION_1_0
1274 : MHD_HTTP_VERSION_1_1); 1289 : MHD_HTTP_VERSION_1_1);
1275 MHD_snprintf_ (code, 1290 MHD_snprintf_ (code,
1276 sizeof (code), 1291 sizeof (code),
1277 "%s %u %s\r\n", 1292 "%s %u %s\r\n",
1278 version, 1293 version,
1279 response->status_code, 1294 response->status_code,
1280 reason_phrase); 1295 reason_phrase);
1281 off = strlen (code); 1296 off = strlen (code);
1282 /* estimate size */ 1297 /* estimate size */
1283 size = off + 2; /* +2 for extra "\r\n" at the end */ 1298 size = off + 2; /* +2 for extra "\r\n" at the end */
1284 kind = MHD_HEADER_KIND; 1299 kind = MHD_HEADER_KIND;
1285 if ( (! daemon->suppress_date) && 1300 if ( (! daemon->suppress_date) &&
1286 (NULL == MHD_response_get_header (response, 1301 (NULL == MHD_response_get_header (response,
1287 MHD_HTTP_HEADER_DATE)) ) 1302 MHD_HTTP_HEADER_DATE)) )
1288 get_date_string (date, 1303 get_date_string (date,
1289 sizeof (date)); 1304 sizeof (date));
1290 else 1305 else
1291 date[0] = '\0'; 1306 date[0] = '\0';
1292 datelen = strlen (date); 1307 datelen = strlen (date);
1293 size += datelen; 1308 size += datelen;
1294 } 1309 }
1295 else 1310 else
1296 { 1311 {
1297 /* 2 bytes for final CRLF of a Chunked-Body */ 1312 /* 2 bytes for final CRLF of a Chunked-Body */
1298 size = 2; 1313 size = 2;
1299 kind = MHD_FOOTER_KIND; 1314 kind = MHD_FOOTER_KIND;
1300 off = 0; 1315 off = 0;
1301 datelen = 0; 1316 datelen = 0;
1302 } 1317 }
1303 1318
1304 /* calculate extra headers we need to add, such as 'Connection: close', 1319 /* calculate extra headers we need to add, such as 'Connection: close',
1305 first see what was explicitly requested by the application */ 1320 first see what was explicitly requested by the application */
@@ -1309,153 +1324,154 @@ build_header_response (struct MHD_Request *request)
1309 must_add_content_length = false; 1324 must_add_content_length = false;
1310 response_has_close = false; 1325 response_has_close = false;
1311 switch (request->state) 1326 switch (request->state)
1312 { 1327 {
1313 case MHD_REQUEST_FOOTERS_RECEIVED: 1328 case MHD_REQUEST_FOOTERS_RECEIVED:
1314 response_has_close 1329 response_has_close
1315 = check_response_header_s_token_ci (response, 1330 = check_response_header_s_token_ci (response,
1316 MHD_HTTP_HEADER_CONNECTION, 1331 MHD_HTTP_HEADER_CONNECTION,
1317 "close"); 1332 "close");
1318 response_has_keepalive 1333 response_has_keepalive
1319 = check_response_header_s_token_ci (response, 1334 = check_response_header_s_token_ci (response,
1320 MHD_HTTP_HEADER_CONNECTION, 1335 MHD_HTTP_HEADER_CONNECTION,
1321 "Keep-Alive"); 1336 "Keep-Alive");
1322 client_requested_close 1337 client_requested_close
1323 = MHD_lookup_header_s_token_ci (request, 1338 = MHD_lookup_header_s_token_ci (request,
1324 MHD_HTTP_HEADER_CONNECTION, 1339 MHD_HTTP_HEADER_CONNECTION,
1325 "close"); 1340 "close");
1326 1341
1327 if (response->v10_only) 1342 if (response->v10_only)
1328 request->keepalive = MHD_CONN_MUST_CLOSE; 1343 request->keepalive = MHD_CONN_MUST_CLOSE;
1329#ifdef UPGRADE_SUPPORT 1344#ifdef UPGRADE_SUPPORT
1330 else if (NULL != response->upgrade_handler) 1345 else if (NULL != response->upgrade_handler)
1331 /* If this connection will not be "upgraded", it must be closed. */ 1346 /* If this connection will not be "upgraded", it must be closed. */
1332 request->keepalive = MHD_CONN_MUST_CLOSE; 1347 request->keepalive = MHD_CONN_MUST_CLOSE;
1333#endif /* UPGRADE_SUPPORT */ 1348#endif /* UPGRADE_SUPPORT */
1334 1349
1335 /* now analyze chunked encoding situation */ 1350 /* now analyze chunked encoding situation */
1336 request->have_chunked_upload = false; 1351 request->have_chunked_upload = false;
1337 1352
1338 if ( (MHD_SIZE_UNKNOWN == response->total_size) && 1353 if ( (MHD_SIZE_UNKNOWN == response->total_size) &&
1339#ifdef UPGRADE_SUPPORT 1354#ifdef UPGRADE_SUPPORT
1340 (NULL == response->upgrade_handler) && 1355 (NULL == response->upgrade_handler) &&
1341#endif /* UPGRADE_SUPPORT */ 1356#endif /* UPGRADE_SUPPORT */
1342 (! response_has_close) && 1357 (! response_has_close) &&
1343 (! client_requested_close) ) 1358 (! client_requested_close) )
1359 {
1360 /* size is unknown, and close was not explicitly requested;
1361 need to either to HTTP 1.1 chunked encoding or
1362 close the connection */
1363 /* 'close' header doesn't exist yet, see if we need to add one;
1364 if the client asked for a close, no need to start chunk'ing */
1365 if ( (keepalive_possible (request)) &&
1366 (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1,
1367 request->version_s)) )
1368 {
1369 have_encoding
1370 = MHD_response_get_header (response,
1371 MHD_HTTP_HEADER_TRANSFER_ENCODING);
1372 if (NULL == have_encoding)
1344 { 1373 {
1345 /* size is unknown, and close was not explicitly requested; 1374 must_add_chunked_encoding = true;
1346 need to either to HTTP 1.1 chunked encoding or 1375 request->have_chunked_upload = true;
1347 close the connection */
1348 /* 'close' header doesn't exist yet, see if we need to add one;
1349 if the client asked for a close, no need to start chunk'ing */
1350 if ( (keepalive_possible (request)) &&
1351 (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1,
1352 request->version_s)) )
1353 {
1354 have_encoding
1355 = MHD_response_get_header (response,
1356 MHD_HTTP_HEADER_TRANSFER_ENCODING);
1357 if (NULL == have_encoding)
1358 {
1359 must_add_chunked_encoding = true;
1360 request->have_chunked_upload = true;
1361 }
1362 else if (MHD_str_equal_caseless_ (have_encoding,
1363 "identity"))
1364 {
1365 /* application forced identity encoding, can't do 'chunked' */
1366 must_add_close = true;
1367 }
1368 else
1369 {
1370 request->have_chunked_upload = true;
1371 }
1372 }
1373 else
1374 {
1375 /* Keep alive or chunking not possible
1376 => set close header if not present */
1377 if (! response_has_close)
1378 must_add_close = true;
1379 }
1380 } 1376 }
1381 1377 else if (MHD_str_equal_caseless_ (have_encoding,
1382 /* check for other reasons to add 'close' header */ 1378 "identity"))
1383 if ( ( (client_requested_close) ||
1384 (connection->read_closed) ||
1385 (MHD_CONN_MUST_CLOSE == request->keepalive)) &&
1386 (! response_has_close) &&
1387#ifdef UPGRADE_SUPPORT
1388 (NULL == response->upgrade_handler) &&
1389#endif /* UPGRADE_SUPPORT */
1390 (! response->v10_only) )
1391 must_add_close = true;
1392
1393 /* check if we should add a 'content length' header */
1394 have_content_length
1395 = MHD_response_get_header (response,
1396 MHD_HTTP_HEADER_CONTENT_LENGTH);
1397
1398 /* MHD_HTTP_NO_CONTENT, MHD_HTTP_NOT_MODIFIED and 1xx-status
1399 codes SHOULD NOT have a Content-Length according to spec;
1400 also chunked encoding / unknown length or CONNECT... */
1401 if ( (MHD_SIZE_UNKNOWN != response->total_size) &&
1402 (MHD_HTTP_NO_CONTENT != response->status_code) &&
1403 (MHD_HTTP_NOT_MODIFIED != response->status_code) &&
1404 (MHD_HTTP_OK <= response->status_code) &&
1405 (NULL == have_content_length) &&
1406 (request->method != MHD_METHOD_CONNECT) )
1407 { 1379 {
1408 /* 1380 /* application forced identity encoding, can't do 'chunked' */
1409 Here we add a content-length if one is missing; however, 1381 must_add_close = true;
1410 for 'connect' methods, the responses MUST NOT include a
1411 content-length header *if* the response code is 2xx (in
1412 which case we expect there to be no body). Still,
1413 as we don't know the response code here in some cases, we
1414 simply only force adding a content-length header if this
1415 is not a 'connect' or if the response is not empty
1416 (which is kind of more sane, because if some crazy
1417 application did return content with a 2xx status code,
1418 then having a content-length might again be a good idea).
1419
1420 Note that the change from 'SHOULD NOT' to 'MUST NOT' is
1421 a recent development of the HTTP 1.1 specification.
1422 */
1423 content_length_len
1424 = MHD_snprintf_ (content_length_buf,
1425 sizeof (content_length_buf),
1426 MHD_HTTP_HEADER_CONTENT_LENGTH ": " MHD_UNSIGNED_LONG_LONG_PRINTF "\r\n",
1427 (MHD_UNSIGNED_LONG_LONG) response->total_size);
1428 must_add_content_length = true;
1429 } 1382 }
1430 1383 else
1431 /* check for adding keep alive */ 1384 {
1432 if ( (! response_has_keepalive) && 1385 request->have_chunked_upload = true;
1433 (! response_has_close) && 1386 }
1434 (! must_add_close) && 1387 }
1435 (MHD_CONN_MUST_CLOSE != request->keepalive) && 1388 else
1389 {
1390 /* Keep alive or chunking not possible
1391 => set close header if not present */
1392 if (! response_has_close)
1393 must_add_close = true;
1394 }
1395 }
1396
1397 /* check for other reasons to add 'close' header */
1398 if ( ( (client_requested_close) ||
1399 (connection->read_closed) ||
1400 (MHD_CONN_MUST_CLOSE == request->keepalive)) &&
1401 (! response_has_close) &&
1436#ifdef UPGRADE_SUPPORT 1402#ifdef UPGRADE_SUPPORT
1437 (NULL == response->upgrade_handler) && 1403 (NULL == response->upgrade_handler) &&
1438#endif /* UPGRADE_SUPPORT */ 1404#endif /* UPGRADE_SUPPORT */
1439 (keepalive_possible (request)) ) 1405 (! response->v10_only) )
1440 must_add_keep_alive = true; 1406 must_add_close = true;
1441 break; 1407
1442 case MHD_REQUEST_BODY_SENT: 1408 /* check if we should add a 'content length' header */
1443 response_has_keepalive = false; 1409 have_content_length
1444 break; 1410 = MHD_response_get_header (response,
1445 default: 1411 MHD_HTTP_HEADER_CONTENT_LENGTH);
1446 mhd_assert (0); 1412
1447 return MHD_NO; 1413 /* MHD_HTTP_NO_CONTENT, MHD_HTTP_NOT_MODIFIED and 1xx-status
1448 } 1414 codes SHOULD NOT have a Content-Length according to spec;
1415 also chunked encoding / unknown length or CONNECT... */
1416 if ( (MHD_SIZE_UNKNOWN != response->total_size) &&
1417 (MHD_HTTP_NO_CONTENT != response->status_code) &&
1418 (MHD_HTTP_NOT_MODIFIED != response->status_code) &&
1419 (MHD_HTTP_OK <= response->status_code) &&
1420 (NULL == have_content_length) &&
1421 (request->method != MHD_METHOD_CONNECT) )
1422 {
1423 /*
1424 Here we add a content-length if one is missing; however,
1425 for 'connect' methods, the responses MUST NOT include a
1426 content-length header *if* the response code is 2xx (in
1427 which case we expect there to be no body). Still,
1428 as we don't know the response code here in some cases, we
1429 simply only force adding a content-length header if this
1430 is not a 'connect' or if the response is not empty
1431 (which is kind of more sane, because if some crazy
1432 application did return content with a 2xx status code,
1433 then having a content-length might again be a good idea).
1434
1435 Note that the change from 'SHOULD NOT' to 'MUST NOT' is
1436 a recent development of the HTTP 1.1 specification.
1437 */
1438 content_length_len
1439 = MHD_snprintf_ (content_length_buf,
1440 sizeof (content_length_buf),
1441 MHD_HTTP_HEADER_CONTENT_LENGTH ": "
1442 MHD_UNSIGNED_LONG_LONG_PRINTF "\r\n",
1443 (MHD_UNSIGNED_LONG_LONG) response->total_size);
1444 must_add_content_length = true;
1445 }
1446
1447 /* check for adding keep alive */
1448 if ( (! response_has_keepalive) &&
1449 (! response_has_close) &&
1450 (! must_add_close) &&
1451 (MHD_CONN_MUST_CLOSE != request->keepalive) &&
1452#ifdef UPGRADE_SUPPORT
1453 (NULL == response->upgrade_handler) &&
1454#endif /* UPGRADE_SUPPORT */
1455 (keepalive_possible (request)) )
1456 must_add_keep_alive = true;
1457 break;
1458 case MHD_REQUEST_BODY_SENT:
1459 response_has_keepalive = false;
1460 break;
1461 default:
1462 mhd_assert (0);
1463 return MHD_NO;
1464 }
1449 1465
1450 if (MHD_CONN_MUST_CLOSE != request->keepalive) 1466 if (MHD_CONN_MUST_CLOSE != request->keepalive)
1451 { 1467 {
1452 if ( (must_add_close) || 1468 if ( (must_add_close) ||
1453 (response_has_close) ) 1469 (response_has_close) )
1454 request->keepalive = MHD_CONN_MUST_CLOSE; 1470 request->keepalive = MHD_CONN_MUST_CLOSE;
1455 else if ( (must_add_keep_alive) || 1471 else if ( (must_add_keep_alive) ||
1456 (response_has_keepalive) ) 1472 (response_has_keepalive) )
1457 request->keepalive = MHD_CONN_USE_KEEPALIVE; 1473 request->keepalive = MHD_CONN_USE_KEEPALIVE;
1458 } 1474 }
1459 1475
1460 if (must_add_close) 1476 if (must_add_close)
1461 size += MHD_STATICSTR_LEN_ ("Connection: close\r\n"); 1477 size += MHD_STATICSTR_LEN_ ("Connection: close\r\n");
@@ -1469,91 +1485,91 @@ build_header_response (struct MHD_Request *request)
1469 mhd_assert (! (must_add_chunked_encoding && must_add_content_length) ); 1485 mhd_assert (! (must_add_chunked_encoding && must_add_content_length) );
1470 1486
1471 for (pos = response->first_header; NULL != pos; pos = pos->next) 1487 for (pos = response->first_header; NULL != pos; pos = pos->next)
1472 { 1488 {
1473 /* TODO: add proper support for excluding "Keep-Alive" token. */ 1489 /* TODO: add proper support for excluding "Keep-Alive" token. */
1474 if ( (pos->kind == kind) && 1490 if ( (pos->kind == kind) &&
1475 (! ( (must_add_close) && 1491 (! ( (must_add_close) &&
1476 (response_has_keepalive) && 1492 (response_has_keepalive) &&
1477 (MHD_str_equal_caseless_(pos->header, 1493 (MHD_str_equal_caseless_ (pos->header,
1478 MHD_HTTP_HEADER_CONNECTION)) && 1494 MHD_HTTP_HEADER_CONNECTION)) &&
1479 (MHD_str_equal_caseless_(pos->value, 1495 (MHD_str_equal_caseless_ (pos->value,
1480 "Keep-Alive")) ) ) ) 1496 "Keep-Alive")) ) ) )
1481 size += strlen (pos->header) + strlen (pos->value) + 4; /* colon, space, linefeeds */ 1497 size += strlen (pos->header) + strlen (pos->value) + 4; /* colon, space, linefeeds */
1482 } 1498 }
1483 /* produce data */ 1499 /* produce data */
1484 data = MHD_pool_allocate (connection->pool, 1500 data = MHD_pool_allocate (connection->pool,
1485 size + 1, 1501 size + 1,
1486 MHD_NO); 1502 MHD_NO);
1487 if (NULL == data) 1503 if (NULL == data)
1488 { 1504 {
1489#ifdef HAVE_MESSAGES 1505#ifdef HAVE_MESSAGES
1490 MHD_DLOG (daemon, 1506 MHD_DLOG (daemon,
1491 MHD_SC_CONNECTION_POOL_MALLOC_FAILURE, 1507 MHD_SC_CONNECTION_POOL_MALLOC_FAILURE,
1492 "Not enough memory for write!\n"); 1508 "Not enough memory for write!\n");
1493#endif 1509#endif
1494 return false; 1510 return false;
1495 } 1511 }
1496 if (MHD_REQUEST_FOOTERS_RECEIVED == request->state) 1512 if (MHD_REQUEST_FOOTERS_RECEIVED == request->state)
1497 { 1513 {
1498 memcpy (data, 1514 memcpy (data,
1499 code, 1515 code,
1500 off); 1516 off);
1501 } 1517 }
1502 if (must_add_close) 1518 if (must_add_close)
1503 { 1519 {
1504 /* we must add the 'Connection: close' header */ 1520 /* we must add the 'Connection: close' header */
1505 memcpy (&data[off], 1521 memcpy (&data[off],
1506 "Connection: close\r\n", 1522 "Connection: close\r\n",
1507 MHD_STATICSTR_LEN_ ("Connection: close\r\n")); 1523 MHD_STATICSTR_LEN_ ("Connection: close\r\n"));
1508 off += MHD_STATICSTR_LEN_ ("Connection: close\r\n"); 1524 off += MHD_STATICSTR_LEN_ ("Connection: close\r\n");
1509 } 1525 }
1510 if (must_add_keep_alive) 1526 if (must_add_keep_alive)
1511 { 1527 {
1512 /* we must add the 'Connection: Keep-Alive' header */ 1528 /* we must add the 'Connection: Keep-Alive' header */
1513 memcpy (&data[off], 1529 memcpy (&data[off],
1514 "Connection: Keep-Alive\r\n", 1530 "Connection: Keep-Alive\r\n",
1515 MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n")); 1531 MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n"));
1516 off += MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n"); 1532 off += MHD_STATICSTR_LEN_ ("Connection: Keep-Alive\r\n");
1517 } 1533 }
1518 if (must_add_chunked_encoding) 1534 if (must_add_chunked_encoding)
1519 { 1535 {
1520 /* we must add the 'Transfer-Encoding: chunked' header */ 1536 /* we must add the 'Transfer-Encoding: chunked' header */
1521 memcpy (&data[off], 1537 memcpy (&data[off],
1522 "Transfer-Encoding: chunked\r\n", 1538 "Transfer-Encoding: chunked\r\n",
1523 MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n")); 1539 MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n"));
1524 off += MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n"); 1540 off += MHD_STATICSTR_LEN_ ("Transfer-Encoding: chunked\r\n");
1525 } 1541 }
1526 if (must_add_content_length) 1542 if (must_add_content_length)
1527 { 1543 {
1528 /* we must add the 'Content-Length' header */ 1544 /* we must add the 'Content-Length' header */
1529 memcpy (&data[off], 1545 memcpy (&data[off],
1530 content_length_buf, 1546 content_length_buf,
1531 content_length_len); 1547 content_length_len);
1532 off += content_length_len; 1548 off += content_length_len;
1533 } 1549 }
1534 for (pos = response->first_header; NULL != pos; pos = pos->next) 1550 for (pos = response->first_header; NULL != pos; pos = pos->next)
1535 { 1551 {
1536 /* TODO: add proper support for excluding "Keep-Alive" token. */ 1552 /* TODO: add proper support for excluding "Keep-Alive" token. */
1537 if ( (pos->kind == kind) && 1553 if ( (pos->kind == kind) &&
1538 (! ( (must_add_close) && 1554 (! ( (must_add_close) &&
1539 (response_has_keepalive) && 1555 (response_has_keepalive) &&
1540 (MHD_str_equal_caseless_(pos->header, 1556 (MHD_str_equal_caseless_ (pos->header,
1541 MHD_HTTP_HEADER_CONNECTION)) && 1557 MHD_HTTP_HEADER_CONNECTION)) &&
1542 (MHD_str_equal_caseless_(pos->value, 1558 (MHD_str_equal_caseless_ (pos->value,
1543 "Keep-Alive")) ) ) ) 1559 "Keep-Alive")) ) ) )
1544 off += MHD_snprintf_ (&data[off], 1560 off += MHD_snprintf_ (&data[off],
1545 size - off, 1561 size - off,
1546 "%s: %s\r\n", 1562 "%s: %s\r\n",
1547 pos->header, 1563 pos->header,
1548 pos->value); 1564 pos->value);
1549 } 1565 }
1550 if (MHD_REQUEST_FOOTERS_RECEIVED == request->state) 1566 if (MHD_REQUEST_FOOTERS_RECEIVED == request->state)
1551 { 1567 {
1552 memcpy (&data[off], 1568 memcpy (&data[off],
1553 date, 1569 date,
1554 datelen); 1570 datelen);
1555 off += datelen; 1571 off += datelen;
1556 } 1572 }
1557 memcpy (&data[off], 1573 memcpy (&data[off],
1558 "\r\n", 1574 "\r\n",
1559 2); 1575 2);
@@ -1584,50 +1600,52 @@ build_header_response (struct MHD_Request *request)
1584 */ 1600 */
1585static void 1601static void
1586transmit_error_response (struct MHD_Request *request, 1602transmit_error_response (struct MHD_Request *request,
1587 enum MHD_StatusCode ec, 1603 enum MHD_StatusCode ec,
1588 enum MHD_HTTP_StatusCode status_code, 1604 enum MHD_HTTP_StatusCode status_code,
1589 const char *message) 1605 const char *message)
1590{ 1606{
1591 struct MHD_Response *response; 1607 struct MHD_Response *response;
1592 1608
1593 if (NULL == request->version_s) 1609 if (NULL == request->version_s)
1594 { 1610 {
1595 /* we were unable to process the full header line, so we don't 1611 /* we were unable to process the full header line, so we don't
1596 really know what version the client speaks; assume 1.0 */ 1612 really know what version the client speaks; assume 1.0 */
1597 request->version_s = MHD_HTTP_VERSION_1_0; 1613 request->version_s = MHD_HTTP_VERSION_1_0;
1598 } 1614 }
1599 request->state = MHD_REQUEST_FOOTERS_RECEIVED; 1615 request->state = MHD_REQUEST_FOOTERS_RECEIVED;
1600 request->connection->read_closed = true; 1616 request->connection->read_closed = true;
1601#ifdef HAVE_MESSAGES 1617#ifdef HAVE_MESSAGES
1602 MHD_DLOG (request->daemon, 1618 MHD_DLOG (request->daemon,
1603 ec, 1619 ec,
1604 _("Error processing request (HTTP response code is %u (`%s')). Closing connection.\n"), 1620 _ (
1621 "Error processing request (HTTP response code is %u (`%s')). Closing connection.\n"),
1605 status_code, 1622 status_code,
1606 message); 1623 message);
1607#endif 1624#endif
1608 if (NULL != request->response) 1625 if (NULL != request->response)
1609 { 1626 {
1610 MHD_response_queue_for_destroy (request->response); 1627 MHD_response_queue_for_destroy (request->response);
1611 request->response = NULL; 1628 request->response = NULL;
1612 } 1629 }
1613 response = MHD_response_from_buffer (status_code, 1630 response = MHD_response_from_buffer (status_code,
1614 strlen (message), 1631 strlen (message),
1615 (void *) message, 1632 (void *) message,
1616 MHD_RESPMEM_PERSISTENT); 1633 MHD_RESPMEM_PERSISTENT);
1617 request->response = response; 1634 request->response = response;
1618 /* Do not reuse this connection. */ 1635 /* Do not reuse this connection. */
1619 request->keepalive = MHD_CONN_MUST_CLOSE; 1636 request->keepalive = MHD_CONN_MUST_CLOSE;
1620 if (! build_header_response (request)) 1637 if (! build_header_response (request))
1621 { 1638 {
1622 /* oops - close! */ 1639 /* oops - close! */
1623 CONNECTION_CLOSE_ERROR (request->connection, 1640 CONNECTION_CLOSE_ERROR (request->connection,
1624 ec, 1641 ec,
1625 _("Closing connection (failed to create response header)\n")); 1642 _ (
1626 } 1643 "Closing connection (failed to create response header)\n"));
1644 }
1627 else 1645 else
1628 { 1646 {
1629 request->state = MHD_REQUEST_HEADERS_SENDING; 1647 request->state = MHD_REQUEST_HEADERS_SENDING;
1630 } 1648 }
1631} 1649}
1632 1650
1633 1651
@@ -1640,7 +1658,8 @@ transmit_error_response (struct MHD_Request *request,
1640static enum MHD_Method 1658static enum MHD_Method
1641method_string_to_enum (const char *method) 1659method_string_to_enum (const char *method)
1642{ 1660{
1643 static const struct { 1661 static const struct
1662 {
1644 const char *key; 1663 const char *key;
1645 enum MHD_Method value; 1664 enum MHD_Method value;
1646 } methods[] = { 1665 } methods[] = {
@@ -1685,10 +1704,10 @@ method_string_to_enum (const char *method)
1685 }; 1704 };
1686 unsigned int i; 1705 unsigned int i;
1687 1706
1688 for (i=0;NULL != methods[i].key;i++) 1707 for (i = 0; NULL != methods[i].key; i++)
1689 if (0 == 1708 if (0 ==
1690 MHD_str_equal_caseless_ (method, 1709 MHD_str_equal_caseless_ (method,
1691 methods[i].key)) 1710 methods[i].key))
1692 return methods[i].value; 1711 return methods[i].value;
1693 return MHD_METHOD_UNKNOWN; 1712 return MHD_METHOD_UNKNOWN;
1694} 1713}
@@ -1706,27 +1725,27 @@ method_string_to_enum (const char *method)
1706 */ 1725 */
1707static bool 1726static bool
1708request_add_header (struct MHD_Request *request, 1727request_add_header (struct MHD_Request *request,
1709 const char *key, 1728 const char *key,
1710 const char *value, 1729 const char *value,
1711 enum MHD_ValueKind kind) 1730 enum MHD_ValueKind kind)
1712{ 1731{
1713 if (MHD_NO == 1732 if (MHD_NO ==
1714 MHD_request_set_value (request, 1733 MHD_request_set_value (request,
1715 kind, 1734 kind,
1716 key, 1735 key,
1717 value)) 1736 value))
1718 { 1737 {
1719#ifdef HAVE_MESSAGES 1738#ifdef HAVE_MESSAGES
1720 MHD_DLOG (request->daemon, 1739 MHD_DLOG (request->daemon,
1721 MHD_SC_CONNECTION_POOL_MALLOC_FAILURE, 1740 MHD_SC_CONNECTION_POOL_MALLOC_FAILURE,
1722 _("Not enough memory in pool to allocate header record!\n")); 1741 _ ("Not enough memory in pool to allocate header record!\n"));
1723#endif 1742#endif
1724 transmit_error_response (request, 1743 transmit_error_response (request,
1725 MHD_SC_CLIENT_HEADER_TOO_BIG, 1744 MHD_SC_CLIENT_HEADER_TOO_BIG,
1726 MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, 1745 MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
1727 REQUEST_TOO_BIG); 1746 REQUEST_TOO_BIG);
1728 return false; 1747 return false;
1729 } 1748 }
1730 return true; 1749 return true;
1731} 1750}
1732 1751
@@ -1763,76 +1782,76 @@ parse_initial_message_line (struct MHD_Request *request,
1763 /* Skip any spaces. Not required by standard but allow 1782 /* Skip any spaces. Not required by standard but allow
1764 to be more tolerant. */ 1783 to be more tolerant. */
1765 while ( (' ' == uri[0]) && 1784 while ( (' ' == uri[0]) &&
1766 ( (size_t)(uri - line) < line_len) ) 1785 ( (size_t) (uri - line) < line_len) )
1767 uri++; 1786 uri++;
1768 if ((size_t)(uri - line) == line_len) 1787 if ((size_t) (uri - line) == line_len)
1769 { 1788 {
1770 curi = ""; 1789 curi = "";
1771 uri = NULL; 1790 uri = NULL;
1772 request->version_s = ""; 1791 request->version_s = "";
1773 args = NULL; 1792 args = NULL;
1774 url_end = line_len - (line - uri); // EH, this is garbage. FIXME! 1793 url_end = line_len - (line - uri); // EH, this is garbage. FIXME!
1775 } 1794 }
1776 else 1795 else
1796 {
1797 curi = uri;
1798 /* Search from back to accept misformed URI with space */
1799 http_version = line + line_len - 1;
1800 /* Skip any trailing spaces */
1801 while ( (' ' == http_version[0]) &&
1802 (http_version > uri) )
1803 http_version--;
1804 /* Find first space in reverse direction */
1805 while ( (' ' != http_version[0]) &&
1806 (http_version > uri) )
1807 http_version--;
1808 if (http_version > uri)
1809 {
1810 http_version[0] = '\0';
1811 request->version_s = http_version + 1;
1812 args = memchr (uri,
1813 '?',
1814 http_version - uri);
1815 }
1816 else
1777 { 1817 {
1778 curi = uri; 1818 request->version_s = "";
1779 /* Search from back to accept misformed URI with space */ 1819 args = memchr (uri,
1780 http_version = line + line_len - 1; 1820 '?',
1781 /* Skip any trailing spaces */ 1821 line_len - (uri - line));
1782 while ( (' ' == http_version[0]) &&
1783 (http_version > uri) )
1784 http_version--;
1785 /* Find first space in reverse direction */
1786 while ( (' ' != http_version[0]) &&
1787 (http_version > uri) )
1788 http_version--;
1789 if (http_version > uri)
1790 {
1791 http_version[0] = '\0';
1792 request->version_s = http_version + 1;
1793 args = memchr (uri,
1794 '?',
1795 http_version - uri);
1796 }
1797 else
1798 {
1799 request->version_s = "";
1800 args = memchr (uri,
1801 '?',
1802 line_len - (uri - line));
1803 }
1804 url_end = http_version - uri;
1805 } 1822 }
1823 url_end = http_version - uri;
1824 }
1806 if ( (MHD_PSL_STRICT == daemon->protocol_strict_level) && 1825 if ( (MHD_PSL_STRICT == daemon->protocol_strict_level) &&
1807 (NULL != memchr (curi, 1826 (NULL != memchr (curi,
1808 ' ', 1827 ' ',
1809 url_end)) ) 1828 url_end)) )
1810 { 1829 {
1811 /* space exists in URI and we are supposed to be strict, reject */ 1830 /* space exists in URI and we are supposed to be strict, reject */
1812 return MHD_NO; 1831 return MHD_NO;
1813 } 1832 }
1814 if (NULL != daemon->early_uri_logger_cb) 1833 if (NULL != daemon->early_uri_logger_cb)
1815 { 1834 {
1816 request->client_context 1835 request->client_context
1817 = daemon->early_uri_logger_cb (daemon->early_uri_logger_cb_cls, 1836 = daemon->early_uri_logger_cb (daemon->early_uri_logger_cb_cls,
1818 curi, 1837 curi,
1819 request); 1838 request);
1820 } 1839 }
1821 if (NULL != args) 1840 if (NULL != args)
1822 { 1841 {
1823 args[0] = '\0'; 1842 args[0] = '\0';
1824 args++; 1843 args++;
1825 /* note that this call clobbers 'args' */ 1844 /* note that this call clobbers 'args' */
1826 MHD_parse_arguments_ (request, 1845 MHD_parse_arguments_ (request,
1827 MHD_GET_ARGUMENT_KIND, 1846 MHD_GET_ARGUMENT_KIND,
1828 args, 1847 args,
1829 &request_add_header, 1848 &request_add_header,
1830 &unused_num_headers); 1849 &unused_num_headers);
1831 } 1850 }
1832 if (NULL != uri) 1851 if (NULL != uri)
1833 daemon->unescape_cb (daemon->unescape_cb_cls, 1852 daemon->unescape_cb (daemon->unescape_cb_cls,
1834 request, 1853 request,
1835 uri); 1854 uri);
1836 request->url = curi; 1855 request->url = curi;
1837 return true; 1856 return true;
1838} 1857}
@@ -1856,43 +1875,46 @@ process_header_line (struct MHD_Request *request,
1856 1875
1857 /* line should be normal header line, find colon */ 1876 /* line should be normal header line, find colon */
1858 colon = strchr (line, 1877 colon = strchr (line,
1859 ':'); 1878 ':');
1860 if (NULL == colon) 1879 if (NULL == colon)
1880 {
1881 /* error in header line, die hard */
1882 CONNECTION_CLOSE_ERROR (connection,
1883 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
1884 _ (
1885 "Received malformed line (no colon). Closing connection.\n"));
1886 return false;
1887 }
1888 if (MHD_PSL_PERMISSIVE != request->daemon->protocol_strict_level)
1889 {
1890 /* check for whitespace before colon, which is not allowed
1891 by RFC 7230 section 3.2.4; we count space ' ' and
1892 tab '\t', but not '\r\n' as those would have ended the line. */
1893 const char *white;
1894
1895 white = strchr (line,
1896 (unsigned char) ' ');
1897 if ( (NULL != white) &&
1898 (white < colon) )
1861 { 1899 {
1862 /* error in header line, die hard */
1863 CONNECTION_CLOSE_ERROR (connection, 1900 CONNECTION_CLOSE_ERROR (connection,
1864 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, 1901 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
1865 _("Received malformed line (no colon). Closing connection.\n")); 1902 _ (
1903 "Whitespace before colon forbidden by RFC 7230. Closing connection.\n"));
1866 return false; 1904 return false;
1867 } 1905 }
1868 if (MHD_PSL_PERMISSIVE != request->daemon->protocol_strict_level) 1906 white = strchr (line,
1907 (unsigned char) '\t');
1908 if ( (NULL != white) &&
1909 (white < colon) )
1869 { 1910 {
1870 /* check for whitespace before colon, which is not allowed 1911 CONNECTION_CLOSE_ERROR (connection,
1871 by RFC 7230 section 3.2.4; we count space ' ' and 1912 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
1872 tab '\t', but not '\r\n' as those would have ended the line. */ 1913 _ (
1873 const char *white; 1914 "Tab before colon forbidden by RFC 7230. Closing connection.\n"));
1874 1915 return false;
1875 white = strchr (line,
1876 (unsigned char) ' ');
1877 if ( (NULL != white) &&
1878 (white < colon) )
1879 {
1880 CONNECTION_CLOSE_ERROR (connection,
1881 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
1882 _("Whitespace before colon forbidden by RFC 7230. Closing connection.\n"));
1883 return false;
1884 }
1885 white = strchr (line,
1886 (unsigned char) '\t');
1887 if ( (NULL != white) &&
1888 (white < colon) )
1889 {
1890 CONNECTION_CLOSE_ERROR (connection,
1891 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
1892 _("Tab before colon forbidden by RFC 7230. Closing connection.\n"));
1893 return false;
1894 }
1895 } 1916 }
1917 }
1896 /* zero-terminate header */ 1918 /* zero-terminate header */
1897 colon[0] = '\0'; 1919 colon[0] = '\0';
1898 colon++; /* advance to value */ 1920 colon++; /* advance to value */
@@ -1935,69 +1957,69 @@ process_broken_line (struct MHD_Request *request,
1935 last = request->last; 1957 last = request->last;
1936 if ( (' ' == line[0]) || 1958 if ( (' ' == line[0]) ||
1937 ('\t' == line[0]) ) 1959 ('\t' == line[0]) )
1938 { 1960 {
1939 /* value was continued on the next line, see 1961 /* value was continued on the next line, see
1940 http://www.jmarshall.com/easy/http/ */ 1962 http://www.jmarshall.com/easy/http/ */
1941 last_len = strlen (last); 1963 last_len = strlen (last);
1942 /* skip whitespace at start of 2nd line */ 1964 /* skip whitespace at start of 2nd line */
1943 tmp = line; 1965 tmp = line;
1944 while ( (' ' == tmp[0]) || 1966 while ( (' ' == tmp[0]) ||
1945 ('\t' == tmp[0]) ) 1967 ('\t' == tmp[0]) )
1946 tmp++; 1968 tmp++;
1947 tmp_len = strlen (tmp); 1969 tmp_len = strlen (tmp);
1948 /* FIXME: we might be able to do this better (faster!), as most 1970 /* FIXME: we might be able to do this better (faster!), as most
1949 likely 'last' and 'line' should already be adjacent in 1971 likely 'last' and 'line' should already be adjacent in
1950 memory; however, doing this right gets tricky if we have a 1972 memory; however, doing this right gets tricky if we have a
1951 value continued over multiple lines (in which case we need to 1973 value continued over multiple lines (in which case we need to
1952 record how often we have done this so we can check for 1974 record how often we have done this so we can check for
1953 adjacency); also, in the case where these are not adjacent 1975 adjacency); also, in the case where these are not adjacent
1954 (not sure how it can happen!), we would want to allocate from 1976 (not sure how it can happen!), we would want to allocate from
1955 the end of the pool, so as to not destroy the read-buffer's 1977 the end of the pool, so as to not destroy the read-buffer's
1956 ability to grow nicely. */ 1978 ability to grow nicely. */
1957 last = MHD_pool_reallocate (connection->pool, 1979 last = MHD_pool_reallocate (connection->pool,
1958 last, 1980 last,
1959 last_len + 1, 1981 last_len + 1,
1960 last_len + tmp_len + 1); 1982 last_len + tmp_len + 1);
1961 if (NULL == last) 1983 if (NULL == last)
1962 {
1963 transmit_error_response (request,
1964 MHD_SC_CLIENT_HEADER_TOO_BIG,
1965 MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
1966 REQUEST_TOO_BIG);
1967 return MHD_NO;
1968 }
1969 memcpy (&last[last_len],
1970 tmp,
1971 tmp_len + 1);
1972 request->last = last;
1973 return MHD_YES; /* possibly more than 2 lines... */
1974 }
1975 mhd_assert ( (NULL != last) &&
1976 (NULL != request->colon) );
1977 if (! request_add_header (request,
1978 last,
1979 request->colon,
1980 kind))
1981 { 1984 {
1982 transmit_error_response (request, 1985 transmit_error_response (request,
1983 MHD_SC_CLIENT_HEADER_TOO_BIG, 1986 MHD_SC_CLIENT_HEADER_TOO_BIG,
1984 MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, 1987 MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
1985 REQUEST_TOO_BIG); 1988 REQUEST_TOO_BIG);
1986 return false; 1989 return MHD_NO;
1987 } 1990 }
1991 memcpy (&last[last_len],
1992 tmp,
1993 tmp_len + 1);
1994 request->last = last;
1995 return MHD_YES; /* possibly more than 2 lines... */
1996 }
1997 mhd_assert ( (NULL != last) &&
1998 (NULL != request->colon) );
1999 if (! request_add_header (request,
2000 last,
2001 request->colon,
2002 kind))
2003 {
2004 transmit_error_response (request,
2005 MHD_SC_CLIENT_HEADER_TOO_BIG,
2006 MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
2007 REQUEST_TOO_BIG);
2008 return false;
2009 }
1988 /* we still have the current line to deal with... */ 2010 /* we still have the current line to deal with... */
1989 if ('\0' != line[0]) 2011 if ('\0' != line[0])
2012 {
2013 if (! process_header_line (request,
2014 line))
1990 { 2015 {
1991 if (! process_header_line (request, 2016 transmit_error_response (request,
1992 line)) 2017 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
1993 { 2018 MHD_HTTP_BAD_REQUEST,
1994 transmit_error_response (request, 2019 REQUEST_MALFORMED);
1995 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED, 2020 return false;
1996 MHD_HTTP_BAD_REQUEST,
1997 REQUEST_MALFORMED);
1998 return false;
1999 }
2000 } 2021 }
2022 }
2001 return true; 2023 return true;
2002} 2024}
2003 2025
@@ -2032,22 +2054,22 @@ get_next_header_line (struct MHD_Request *request,
2032 pos++; 2054 pos++;
2033 if ( (pos == request->read_buffer_offset - 1) && 2055 if ( (pos == request->read_buffer_offset - 1) &&
2034 ('\n' != rbuf[pos]) ) 2056 ('\n' != rbuf[pos]) )
2057 {
2058 /* not found, consider growing... */
2059 if ( (request->read_buffer_offset == request->read_buffer_size) &&
2060 (! try_grow_read_buffer (request)) )
2035 { 2061 {
2036 /* not found, consider growing... */ 2062 transmit_error_response (request,
2037 if ( (request->read_buffer_offset == request->read_buffer_size) && 2063 MHD_SC_CLIENT_HEADER_TOO_BIG,
2038 (! try_grow_read_buffer (request)) ) 2064 (NULL != request->url)
2039 { 2065 ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
2040 transmit_error_response (request, 2066 : MHD_HTTP_URI_TOO_LONG,
2041 MHD_SC_CLIENT_HEADER_TOO_BIG, 2067 REQUEST_TOO_BIG);
2042 (NULL != request->url)
2043 ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
2044 : MHD_HTTP_URI_TOO_LONG,
2045 REQUEST_TOO_BIG);
2046 }
2047 if (line_len)
2048 *line_len = 0;
2049 return NULL;
2050 } 2068 }
2069 if (line_len)
2070 *line_len = 0;
2071 return NULL;
2072 }
2051 2073
2052 if (line_len) 2074 if (line_len)
2053 *line_len = pos; 2075 *line_len = pos;
@@ -2083,7 +2105,7 @@ get_next_header_line (struct MHD_Request *request,
2083 * @return true if force push is possible, false otherwise 2105 * @return true if force push is possible, false otherwise
2084 */ 2106 */
2085static bool 2107static bool
2086socket_flush_possible(struct MHD_Connection *connection) 2108socket_flush_possible (struct MHD_Connection *connection)
2087{ 2109{
2088 (void) connection; /* Mute compiler warning. */ 2110 (void) connection; /* Mute compiler warning. */
2089#if defined(TCP_CORK) || defined(TCP_PUSH) 2111#if defined(TCP_CORK) || defined(TCP_PUSH)
@@ -2105,21 +2127,21 @@ static bool
2105socket_start_extra_buffering (struct MHD_Connection *connection) 2127socket_start_extra_buffering (struct MHD_Connection *connection)
2106{ 2128{
2107 bool res = false; 2129 bool res = false;
2108 (void)connection; /* Mute compiler warning. */ 2130 (void) connection; /* Mute compiler warning. */
2109#if defined(TCP_CORK) || defined(TCP_NOPUSH) 2131#if defined(TCP_CORK) || defined(TCP_NOPUSH)
2110 const MHD_SCKT_OPT_BOOL_ on_val = 1; 2132 const MHD_SCKT_OPT_BOOL_ on_val = 1;
2111#if defined(TCP_NODELAY) 2133#if defined(TCP_NODELAY)
2112 const MHD_SCKT_OPT_BOOL_ off_val = 0; 2134 const MHD_SCKT_OPT_BOOL_ off_val = 0;
2113#endif /* TCP_NODELAY */ 2135#endif /* TCP_NODELAY */
2114 mhd_assert(NULL != connection); 2136 mhd_assert (NULL != connection);
2115#if defined(TCP_NOPUSH) && !defined(TCP_CORK) 2137#if defined(TCP_NOPUSH) && ! defined(TCP_CORK)
2116 /* Buffer data before sending */ 2138 /* Buffer data before sending */
2117 res = (0 == setsockopt (connection->socket_fd, 2139 res = (0 == setsockopt (connection->socket_fd,
2118 IPPROTO_TCP, 2140 IPPROTO_TCP,
2119 TCP_NOPUSH, 2141 TCP_NOPUSH,
2120 (const void *) &on_val, 2142 (const void *) &on_val,
2121 sizeof (on_val))) 2143 sizeof (on_val)))
2122 ? true : false; 2144 ? true : false;
2123#if defined(TCP_NODELAY) 2145#if defined(TCP_NODELAY)
2124 /* Enable Nagle's algorithm */ 2146 /* Enable Nagle's algorithm */
2125 /* TCP_NODELAY may interfere with TCP_NOPUSH */ 2147 /* TCP_NODELAY may interfere with TCP_NOPUSH */
@@ -2128,7 +2150,7 @@ socket_start_extra_buffering (struct MHD_Connection *connection)
2128 TCP_NODELAY, 2150 TCP_NODELAY,
2129 (const void *) &off_val, 2151 (const void *) &off_val,
2130 sizeof (off_val))) 2152 sizeof (off_val)))
2131 ? true : false; 2153 ? true : false;
2132#endif /* TCP_NODELAY */ 2154#endif /* TCP_NODELAY */
2133#else /* TCP_CORK */ 2155#else /* TCP_CORK */
2134#if defined(TCP_NODELAY) 2156#if defined(TCP_NODELAY)
@@ -2147,7 +2169,7 @@ socket_start_extra_buffering (struct MHD_Connection *connection)
2147 TCP_CORK, 2169 TCP_CORK,
2148 (const void *) &on_val, 2170 (const void *) &on_val,
2149 sizeof (on_val))) 2171 sizeof (on_val)))
2150 ? true : false; 2172 ? true : false;
2151#endif /* TCP_CORK */ 2173#endif /* TCP_CORK */
2152#endif /* TCP_CORK || TCP_NOPUSH */ 2174#endif /* TCP_CORK || TCP_NOPUSH */
2153 return res; 2175 return res;
@@ -2170,8 +2192,8 @@ socket_start_no_buffering (struct MHD_Connection *connection)
2170 const MHD_SCKT_OPT_BOOL_ off_val = 0; 2192 const MHD_SCKT_OPT_BOOL_ off_val = 0;
2171#endif /* TCP_CORK || TCP_NOPUSH */ 2193#endif /* TCP_CORK || TCP_NOPUSH */
2172 2194
2173 (void)connection; /* Mute compiler warning. */ 2195 (void) connection; /* Mute compiler warning. */
2174 mhd_assert(NULL != connection); 2196 mhd_assert (NULL != connection);
2175#if defined(TCP_CORK) 2197#if defined(TCP_CORK)
2176 /* Allow partial packets */ 2198 /* Allow partial packets */
2177 res &= (0 == setsockopt (connection->socket_fd, 2199 res &= (0 == setsockopt (connection->socket_fd,
@@ -2179,7 +2201,7 @@ socket_start_no_buffering (struct MHD_Connection *connection)
2179 TCP_CORK, 2201 TCP_CORK,
2180 (const void *) &off_val, 2202 (const void *) &off_val,
2181 sizeof (off_val))) 2203 sizeof (off_val)))
2182 ? true : false; 2204 ? true : false;
2183#endif /* TCP_CORK */ 2205#endif /* TCP_CORK */
2184#if defined(TCP_NODELAY) 2206#if defined(TCP_NODELAY)
2185 /* Disable Nagle's algorithm for sending packets without delay */ 2207 /* Disable Nagle's algorithm for sending packets without delay */
@@ -2188,16 +2210,16 @@ socket_start_no_buffering (struct MHD_Connection *connection)
2188 TCP_NODELAY, 2210 TCP_NODELAY,
2189 (const void *) &on_val, 2211 (const void *) &on_val,
2190 sizeof (on_val))) 2212 sizeof (on_val)))
2191 ? true : false; 2213 ? true : false;
2192#endif /* TCP_NODELAY */ 2214#endif /* TCP_NODELAY */
2193#if defined(TCP_NOPUSH) && !defined(TCP_CORK) 2215#if defined(TCP_NOPUSH) && ! defined(TCP_CORK)
2194 /* Disable extra buffering */ 2216 /* Disable extra buffering */
2195 res &= (0 == setsockopt (connection->socket_fd, 2217 res &= (0 == setsockopt (connection->socket_fd,
2196 IPPROTO_TCP, 2218 IPPROTO_TCP,
2197 TCP_NOPUSH, 2219 TCP_NOPUSH,
2198 (const void *) &off_val, 2220 (const void *) &off_val,
2199 sizeof (off_val))) 2221 sizeof (off_val)))
2200 ? true : false; 2222 ? true : false;
2201#endif /* TCP_NOPUSH && !TCP_CORK */ 2223#endif /* TCP_NOPUSH && !TCP_CORK */
2202 return res; 2224 return res;
2203#else /* !TCP_NODELAY */ 2225#else /* !TCP_NODELAY */
@@ -2217,21 +2239,21 @@ static bool
2217socket_start_no_buffering_flush (struct MHD_Connection *connection) 2239socket_start_no_buffering_flush (struct MHD_Connection *connection)
2218{ 2240{
2219 bool res = true; 2241 bool res = true;
2220#if defined(TCP_NOPUSH) && !defined(TCP_CORK) 2242#if defined(TCP_NOPUSH) && ! defined(TCP_CORK)
2221 const int dummy = 0; 2243 const int dummy = 0;
2222#endif /* !TCP_CORK */ 2244#endif /* !TCP_CORK */
2223 2245
2224 if (NULL == connection) 2246 if (NULL == connection)
2225 return false; /* FIXME: use MHD_NONNULL? */ 2247 return false; /* FIXME: use MHD_NONNULL? */
2226 res = socket_start_no_buffering (connection); 2248 res = socket_start_no_buffering (connection);
2227#if defined(TCP_NOPUSH) && !defined(TCP_CORK) 2249#if defined(TCP_NOPUSH) && ! defined(TCP_CORK)
2228 /* Force flush data with zero send otherwise Darwin and some BSD systems 2250 /* Force flush data with zero send otherwise Darwin and some BSD systems
2229 will add 5 seconds delay. Not required with TCP_CORK as switching off 2251 will add 5 seconds delay. Not required with TCP_CORK as switching off
2230 TCP_CORK always flushes socket buffer. */ 2252 TCP_CORK always flushes socket buffer. */
2231 res &= (0 <= MHD_send_ (connection->socket_fd, 2253 res &= (0 <= MHD_send_ (connection->socket_fd,
2232 &dummy, 2254 &dummy,
2233 0)) 2255 0))
2234 ? true : false; 2256 ? true : false;
2235#endif /* TCP_NOPUSH && !TCP_CORK*/ 2257#endif /* TCP_NOPUSH && !TCP_CORK*/
2236 return res; 2258 return res;
2237} 2259}
@@ -2254,7 +2276,7 @@ socket_start_normal_buffering (struct MHD_Connection *connection)
2254 socklen_t param_size = sizeof (cork_val); 2276 socklen_t param_size = sizeof (cork_val);
2255#endif /* TCP_CORK */ 2277#endif /* TCP_CORK */
2256 2278
2257 mhd_assert(NULL != connection); 2279 mhd_assert (NULL != connection);
2258#if defined(TCP_CORK) 2280#if defined(TCP_CORK)
2259 /* Allow partial packets */ 2281 /* Allow partial packets */
2260 /* Disabling TCP_CORK will flush partial packet even if TCP_CORK wasn't enabled before 2282 /* Disabling TCP_CORK will flush partial packet even if TCP_CORK wasn't enabled before
@@ -2262,7 +2284,7 @@ socket_start_normal_buffering (struct MHD_Connection *connection)
2262 if ( (0 != getsockopt (connection->socket_fd, 2284 if ( (0 != getsockopt (connection->socket_fd,
2263 IPPROTO_TCP, 2285 IPPROTO_TCP,
2264 TCP_CORK, 2286 TCP_CORK,
2265 (void*)&cork_val, 2287 (void*) &cork_val,
2266 &param_size)) || 2288 &param_size)) ||
2267 (0 != cork_val)) 2289 (0 != cork_val))
2268 res &= (0 == setsockopt (connection->socket_fd, 2290 res &= (0 == setsockopt (connection->socket_fd,
@@ -2270,7 +2292,7 @@ socket_start_normal_buffering (struct MHD_Connection *connection)
2270 TCP_CORK, 2292 TCP_CORK,
2271 (const void *) &off_val, 2293 (const void *) &off_val,
2272 sizeof (off_val))) 2294 sizeof (off_val)))
2273 ? true : false; 2295 ? true : false;
2274#elif defined(TCP_NOPUSH) 2296#elif defined(TCP_NOPUSH)
2275 /* Disable extra buffering */ 2297 /* Disable extra buffering */
2276 /* No need to check current value as disabling TCP_NOPUSH will not flush partial 2298 /* No need to check current value as disabling TCP_NOPUSH will not flush partial
@@ -2280,7 +2302,7 @@ socket_start_normal_buffering (struct MHD_Connection *connection)
2280 TCP_NOPUSH, 2302 TCP_NOPUSH,
2281 (const void *) &off_val, 2303 (const void *) &off_val,
2282 sizeof (off_val))) 2304 sizeof (off_val)))
2283 ? true : false; 2305 ? true : false;
2284#endif /* TCP_NOPUSH && !TCP_CORK */ 2306#endif /* TCP_NOPUSH && !TCP_CORK */
2285 /* Enable Nagle's algorithm for normal buffering */ 2307 /* Enable Nagle's algorithm for normal buffering */
2286 res &= (0 == setsockopt (connection->socket_fd, 2308 res &= (0 == setsockopt (connection->socket_fd,
@@ -2288,7 +2310,7 @@ socket_start_normal_buffering (struct MHD_Connection *connection)
2288 TCP_NODELAY, 2310 TCP_NODELAY,
2289 (const void *) &off_val, 2311 (const void *) &off_val,
2290 sizeof (off_val))) 2312 sizeof (off_val)))
2291 ? true : false; 2313 ? true : false;
2292 return res; 2314 return res;
2293#else /* !TCP_NODELAY */ 2315#else /* !TCP_NODELAY */
2294 return false; 2316 return false;
@@ -2309,16 +2331,17 @@ need_100_continue (struct MHD_Request *request)
2309 const char *expect; 2331 const char *expect;
2310 2332
2311 return ( (NULL == request->response) && 2333 return ( (NULL == request->response) &&
2312 (NULL != request->version_s) && 2334 (NULL != request->version_s) &&
2313 (MHD_str_equal_caseless_(request->version_s, 2335 (MHD_str_equal_caseless_ (request->version_s,
2314 MHD_HTTP_VERSION_1_1)) && 2336 MHD_HTTP_VERSION_1_1)) &&
2315 (NULL != (expect = MHD_request_lookup_value (request, 2337 (NULL != (expect = MHD_request_lookup_value (request,
2316 MHD_HEADER_KIND, 2338 MHD_HEADER_KIND,
2317 MHD_HTTP_HEADER_EXPECT))) && 2339 MHD_HTTP_HEADER_EXPECT)))
2318 (MHD_str_equal_caseless_(expect, 2340 &&
2319 "100-continue")) && 2341 (MHD_str_equal_caseless_ (expect,
2320 (request->continue_message_write_offset < 2342 "100-continue")) &&
2321 MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)) ); 2343 (request->continue_message_write_offset <
2344 MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)) );
2322} 2345}
2323 2346
2324 2347
@@ -2342,94 +2365,94 @@ parse_cookie_header (struct MHD_Request *request)
2342 int quotes; 2365 int quotes;
2343 2366
2344 hdr = MHD_request_lookup_value (request, 2367 hdr = MHD_request_lookup_value (request,
2345 MHD_HEADER_KIND, 2368 MHD_HEADER_KIND,
2346 MHD_HTTP_HEADER_COOKIE); 2369 MHD_HTTP_HEADER_COOKIE);
2347 if (NULL == hdr) 2370 if (NULL == hdr)
2348 return true; 2371 return true;
2349 cpy = MHD_pool_allocate (request->connection->pool, 2372 cpy = MHD_pool_allocate (request->connection->pool,
2350 strlen (hdr) + 1, 2373 strlen (hdr) + 1,
2351 MHD_YES); 2374 MHD_YES);
2352 if (NULL == cpy) 2375 if (NULL == cpy)
2353 { 2376 {
2354#ifdef HAVE_MESSAGES 2377#ifdef HAVE_MESSAGES
2355 MHD_DLOG (request->daemon, 2378 MHD_DLOG (request->daemon,
2356 MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE, 2379 MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE,
2357 _("Not enough memory in pool to parse cookies!\n")); 2380 _ ("Not enough memory in pool to parse cookies!\n"));
2358#endif 2381#endif
2359 transmit_error_response (request, 2382 transmit_error_response (request,
2360 MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE, 2383 MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE,
2361 MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE, 2384 MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE,
2362 REQUEST_TOO_BIG); 2385 REQUEST_TOO_BIG);
2363 return false; 2386 return false;
2364 } 2387 }
2365 memcpy (cpy, 2388 memcpy (cpy,
2366 hdr, 2389 hdr,
2367 strlen (hdr) + 1); 2390 strlen (hdr) + 1);
2368 pos = cpy; 2391 pos = cpy;
2369 while (NULL != pos) 2392 while (NULL != pos)
2370 { 2393 {
2371 while (' ' == *pos) 2394 while (' ' == *pos)
2372 pos++; /* skip spaces */ 2395 pos++; /* skip spaces */
2373 2396
2374 sce = pos; 2397 sce = pos;
2375 while ( ((*sce) != '\0') && 2398 while ( ((*sce) != '\0') &&
2376 ((*sce) != ',') && 2399 ((*sce) != ',') &&
2377 ((*sce) != ';') && 2400 ((*sce) != ';') &&
2378 ((*sce) != '=') ) 2401 ((*sce) != '=') )
2379 sce++; 2402 sce++;
2380 /* remove tailing whitespace (if any) from key */ 2403 /* remove tailing whitespace (if any) from key */
2381 ekill = sce - 1; 2404 ekill = sce - 1;
2382 while ( (*ekill == ' ') && 2405 while ( (*ekill == ' ') &&
2383 (ekill >= pos) ) 2406 (ekill >= pos) )
2384 *(ekill--) = '\0'; 2407 *(ekill--) = '\0';
2385 old = *sce; 2408 old = *sce;
2386 *sce = '\0'; 2409 *sce = '\0';
2387 if (old != '=') 2410 if (old != '=')
2388 { 2411 {
2389 /* value part omitted, use empty string... */ 2412 /* value part omitted, use empty string... */
2390 if (! request_add_header (request,
2391 pos,
2392 "",
2393 MHD_COOKIE_KIND))
2394 return false;
2395 if (old == '\0')
2396 break;
2397 pos = sce + 1;
2398 continue;
2399 }
2400 equals = sce + 1;
2401 quotes = 0;
2402 semicolon = equals;
2403 while ( ('\0' != semicolon[0]) &&
2404 ( (0 != quotes) ||
2405 ( (';' != semicolon[0]) &&
2406 (',' != semicolon[0]) ) ) )
2407 {
2408 if ('"' == semicolon[0])
2409 quotes = (quotes + 1) & 1;
2410 semicolon++;
2411 }
2412 if ('\0' == semicolon[0])
2413 semicolon = NULL;
2414 if (NULL != semicolon)
2415 {
2416 semicolon[0] = '\0';
2417 semicolon++;
2418 }
2419 /* remove quotes */
2420 if ( ('"' == equals[0]) &&
2421 ('"' == equals[strlen (equals) - 1]) )
2422 {
2423 equals[strlen (equals) - 1] = '\0';
2424 equals++;
2425 }
2426 if (! request_add_header (request, 2413 if (! request_add_header (request,
2427 pos, 2414 pos,
2428 equals, 2415 "",
2429 MHD_COOKIE_KIND)) 2416 MHD_COOKIE_KIND))
2430 return false; 2417 return false;
2431 pos = semicolon; 2418 if (old == '\0')
2432 } 2419 break;
2420 pos = sce + 1;
2421 continue;
2422 }
2423 equals = sce + 1;
2424 quotes = 0;
2425 semicolon = equals;
2426 while ( ('\0' != semicolon[0]) &&
2427 ( (0 != quotes) ||
2428 ( (';' != semicolon[0]) &&
2429 (',' != semicolon[0]) ) ) )
2430 {
2431 if ('"' == semicolon[0])
2432 quotes = (quotes + 1) & 1;
2433 semicolon++;
2434 }
2435 if ('\0' == semicolon[0])
2436 semicolon = NULL;
2437 if (NULL != semicolon)
2438 {
2439 semicolon[0] = '\0';
2440 semicolon++;
2441 }
2442 /* remove quotes */
2443 if ( ('"' == equals[0]) &&
2444 ('"' == equals[strlen (equals) - 1]) )
2445 {
2446 equals[strlen (equals) - 1] = '\0';
2447 equals++;
2448 }
2449 if (! request_add_header (request,
2450 pos,
2451 equals,
2452 MHD_COOKIE_KIND))
2453 return false;
2454 pos = semicolon;
2455 }
2433 return true; 2456 return true;
2434} 2457}
2435 2458
@@ -2454,64 +2477,64 @@ parse_request_headers (struct MHD_Request *request)
2454 parse_cookie_header (request); /* FIXME: return value ignored! */ 2477 parse_cookie_header (request); /* FIXME: return value ignored! */
2455 if ( (MHD_PSL_STRICT == daemon->protocol_strict_level) && 2478 if ( (MHD_PSL_STRICT == daemon->protocol_strict_level) &&
2456 (NULL != request->version_s) && 2479 (NULL != request->version_s) &&
2457 (MHD_str_equal_caseless_(MHD_HTTP_VERSION_1_1, 2480 (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1,
2458 request->version_s)) && 2481 request->version_s)) &&
2459 (NULL == 2482 (NULL ==
2460 MHD_request_lookup_value (request, 2483 MHD_request_lookup_value (request,
2461 MHD_HEADER_KIND, 2484 MHD_HEADER_KIND,
2462 MHD_HTTP_HEADER_HOST)) ) 2485 MHD_HTTP_HEADER_HOST)) )
2463 { 2486 {
2464 /* die, http 1.1 request without host and we are pedantic */ 2487 /* die, http 1.1 request without host and we are pedantic */
2465 request->state = MHD_REQUEST_FOOTERS_RECEIVED; 2488 request->state = MHD_REQUEST_FOOTERS_RECEIVED;
2466 connection->read_closed = true; 2489 connection->read_closed = true;
2467#ifdef HAVE_MESSAGES 2490#ifdef HAVE_MESSAGES
2468 MHD_DLOG (daemon, 2491 MHD_DLOG (daemon,
2469 MHD_SC_HOST_HEADER_MISSING, 2492 MHD_SC_HOST_HEADER_MISSING,
2470 _("Received HTTP 1.1 request without `Host' header.\n")); 2493 _ ("Received HTTP 1.1 request without `Host' header.\n"));
2471#endif 2494#endif
2472 mhd_assert (NULL == request->response); 2495 mhd_assert (NULL == request->response);
2473 response = 2496 response =
2474 MHD_response_from_buffer (MHD_HTTP_BAD_REQUEST, 2497 MHD_response_from_buffer (MHD_HTTP_BAD_REQUEST,
2475 MHD_STATICSTR_LEN_ (REQUEST_LACKS_HOST), 2498 MHD_STATICSTR_LEN_ (REQUEST_LACKS_HOST),
2476 REQUEST_LACKS_HOST, 2499 REQUEST_LACKS_HOST,
2477 MHD_RESPMEM_PERSISTENT); 2500 MHD_RESPMEM_PERSISTENT);
2478 request->response = response; 2501 request->response = response;
2479 // FIXME: state machine advance? 2502 // FIXME: state machine advance?
2480 return; 2503 return;
2481 } 2504 }
2482 2505
2483 request->remaining_upload_size = 0; 2506 request->remaining_upload_size = 0;
2484 enc = MHD_request_lookup_value (request, 2507 enc = MHD_request_lookup_value (request,
2485 MHD_HEADER_KIND, 2508 MHD_HEADER_KIND,
2486 MHD_HTTP_HEADER_TRANSFER_ENCODING); 2509 MHD_HTTP_HEADER_TRANSFER_ENCODING);
2487 if (NULL != enc) 2510 if (NULL != enc)
2488 { 2511 {
2489 request->remaining_upload_size = MHD_SIZE_UNKNOWN; 2512 request->remaining_upload_size = MHD_SIZE_UNKNOWN;
2490 if (MHD_str_equal_caseless_ (enc, 2513 if (MHD_str_equal_caseless_ (enc,
2491 "chunked")) 2514 "chunked"))
2492 request->have_chunked_upload = true; 2515 request->have_chunked_upload = true;
2493 return; 2516 return;
2494 } 2517 }
2495 clen = MHD_request_lookup_value (request, 2518 clen = MHD_request_lookup_value (request,
2496 MHD_HEADER_KIND, 2519 MHD_HEADER_KIND,
2497 MHD_HTTP_HEADER_CONTENT_LENGTH); 2520 MHD_HTTP_HEADER_CONTENT_LENGTH);
2498 if (NULL == clen) 2521 if (NULL == clen)
2499 return; 2522 return;
2500 end = clen + MHD_str_to_uint64_ (clen, 2523 end = clen + MHD_str_to_uint64_ (clen,
2501 &request->remaining_upload_size); 2524 &request->remaining_upload_size);
2502 if ( (clen == end) || 2525 if ( (clen == end) ||
2503 ('\0' != *end) ) 2526 ('\0' != *end) )
2504 { 2527 {
2505 request->remaining_upload_size = 0; 2528 request->remaining_upload_size = 0;
2506#ifdef HAVE_MESSAGES 2529#ifdef HAVE_MESSAGES
2507 MHD_DLOG (request->daemon, 2530 MHD_DLOG (request->daemon,
2508 MHD_SC_CONTENT_LENGTH_MALFORMED, 2531 MHD_SC_CONTENT_LENGTH_MALFORMED,
2509 "Failed to parse `Content-Length' header. Closing connection.\n"); 2532 "Failed to parse `Content-Length' header. Closing connection.\n");
2510#endif 2533#endif
2511 CONNECTION_CLOSE_ERROR (connection, 2534 CONNECTION_CLOSE_ERROR (connection,
2512 MHD_SC_CONTENT_LENGTH_MALFORMED, 2535 MHD_SC_CONTENT_LENGTH_MALFORMED,
2513 NULL); 2536 NULL);
2514 } 2537 }
2515} 2538}
2516 2539
2517 2540
@@ -2531,19 +2554,20 @@ call_request_handler (struct MHD_Request *request)
2531 if (NULL != request->response) 2554 if (NULL != request->response)
2532 return; /* already queued a response */ 2555 return; /* already queued a response */
2533 if (NULL == (action = 2556 if (NULL == (action =
2534 daemon->rc (daemon->rc_cls, 2557 daemon->rc (daemon->rc_cls,
2535 request, 2558 request,
2536 request->url, 2559 request->url,
2537 request->method))) 2560 request->method)))
2538 { 2561 {
2539 /* serious internal error, close connection */ 2562 /* serious internal error, close connection */
2540 CONNECTION_CLOSE_ERROR (connection, 2563 CONNECTION_CLOSE_ERROR (connection,
2541 MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED, 2564 MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED,
2542 _("Application reported internal error, closing connection.\n")); 2565 _ (
2543 return; 2566 "Application reported internal error, closing connection.\n"));
2544 } 2567 return;
2568 }
2545 action->action (action->action_cls, 2569 action->action (action->action_cls,
2546 request); 2570 request);
2547} 2571}
2548 2572
2549 2573
@@ -2568,208 +2592,212 @@ process_request_body (struct MHD_Request *request)
2568 buffer_head = request->read_buffer; 2592 buffer_head = request->read_buffer;
2569 available = request->read_buffer_offset; 2593 available = request->read_buffer_offset;
2570 do 2594 do
2571 { 2595 {
2572 size_t to_be_processed; 2596 size_t to_be_processed;
2573 size_t left_unprocessed; 2597 size_t left_unprocessed;
2574 size_t processed_size; 2598 size_t processed_size;
2575 2599
2576 instant_retry = false; 2600 instant_retry = false;
2577 if ( (request->have_chunked_upload) && 2601 if ( (request->have_chunked_upload) &&
2578 (MHD_SIZE_UNKNOWN == request->remaining_upload_size) ) 2602 (MHD_SIZE_UNKNOWN == request->remaining_upload_size) )
2603 {
2604 if ( (request->current_chunk_offset == request->current_chunk_size) &&
2605 (0LLU != request->current_chunk_offset) &&
2606 (available >= 2) )
2607 {
2608 size_t i;
2609
2610 /* skip new line at the *end* of a chunk */
2611 i = 0;
2612 if ( ('\r' == buffer_head[i]) ||
2613 ('\n' == buffer_head[i]) )
2614 i++; /* skip 1st part of line feed */
2615 if ( ('\r' == buffer_head[i]) ||
2616 ('\n' == buffer_head[i]) )
2617 i++; /* skip 2nd part of line feed */
2618 if (0 == i)
2579 { 2619 {
2580 if ( (request->current_chunk_offset == request->current_chunk_size) && 2620 /* malformed encoding */
2581 (0LLU != request->current_chunk_offset) && 2621 CONNECTION_CLOSE_ERROR (connection,
2582 (available >= 2) ) 2622 MHD_SC_CHUNKED_ENCODING_MALFORMED,
2583 { 2623 _ (
2584 size_t i; 2624 "Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
2585 2625 return;
2586 /* skip new line at the *end* of a chunk */
2587 i = 0;
2588 if ( ('\r' == buffer_head[i]) ||
2589 ('\n' == buffer_head[i]) )
2590 i++; /* skip 1st part of line feed */
2591 if ( ('\r' == buffer_head[i]) ||
2592 ('\n' == buffer_head[i]) )
2593 i++; /* skip 2nd part of line feed */
2594 if (0 == i)
2595 {
2596 /* malformed encoding */
2597 CONNECTION_CLOSE_ERROR (connection,
2598 MHD_SC_CHUNKED_ENCODING_MALFORMED,
2599 _("Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
2600 return;
2601 }
2602 available -= i;
2603 buffer_head += i;
2604 request->current_chunk_offset = 0;
2605 request->current_chunk_size = 0;
2606 }
2607 if (request->current_chunk_offset <
2608 request->current_chunk_size)
2609 {
2610 uint64_t cur_chunk_left;
2611
2612 /* we are in the middle of a chunk, give
2613 as much as possible to the client (without
2614 crossing chunk boundaries) */
2615 cur_chunk_left
2616 = request->current_chunk_size - request->current_chunk_offset;
2617 if (cur_chunk_left > available)
2618 {
2619 to_be_processed = available;
2620 }
2621 else
2622 { /* cur_chunk_left <= (size_t)available */
2623 to_be_processed = (size_t)cur_chunk_left;
2624 if (available > to_be_processed)
2625 instant_retry = true;
2626 }
2627 }
2628 else
2629 {
2630 size_t i;
2631 size_t end_size;
2632 bool malformed;
2633
2634 /* we need to read chunk boundaries */
2635 i = 0;
2636 while (i < available)
2637 {
2638 if ( ('\r' == buffer_head[i]) ||
2639 ('\n' == buffer_head[i]) ||
2640 (';' == buffer_head[i]) )
2641 break;
2642 i++;
2643 if (i >= 16)
2644 break;
2645 }
2646 end_size = i;
2647 /* find beginning of CRLF (skip over chunk extensions) */
2648 if (';' == buffer_head[i])
2649 {
2650 while (i < available)
2651 {
2652 if ( ('\r' == buffer_head[i]) ||
2653 ('\n' == buffer_head[i]) )
2654 break;
2655 i++;
2656 }
2657 }
2658 /* take '\n' into account; if '\n' is the unavailable
2659 character, we will need to wait until we have it
2660 before going further */
2661 if ( (i + 1 >= available) &&
2662 ! ( (1 == i) &&
2663 (2 == available) &&
2664 ('0' == buffer_head[0]) ) )
2665 break; /* need more data... */
2666 i++;
2667 malformed = (end_size >= 16);
2668 if (! malformed)
2669 {
2670 size_t num_dig = MHD_strx_to_uint64_n_ (buffer_head,
2671 end_size,
2672 &request->current_chunk_size);
2673 malformed = (end_size != num_dig);
2674 }
2675 if (malformed)
2676 {
2677 /* malformed encoding */
2678 CONNECTION_CLOSE_ERROR (connection,
2679 MHD_SC_CHUNKED_ENCODING_MALFORMED,
2680 _("Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
2681 return;
2682 }
2683 /* skip 2nd part of line feed */
2684 if ( (i < available) &&
2685 ( ('\r' == buffer_head[i]) ||
2686 ('\n' == buffer_head[i]) ) )
2687 i++;
2688
2689 buffer_head += i;
2690 available -= i;
2691 request->current_chunk_offset = 0;
2692
2693 if (available > 0)
2694 instant_retry = true;
2695 if (0LLU == request->current_chunk_size)
2696 {
2697 request->remaining_upload_size = 0;
2698 break;
2699 }
2700 continue;
2701 }
2702 } 2626 }
2627 available -= i;
2628 buffer_head += i;
2629 request->current_chunk_offset = 0;
2630 request->current_chunk_size = 0;
2631 }
2632 if (request->current_chunk_offset <
2633 request->current_chunk_size)
2634 {
2635 uint64_t cur_chunk_left;
2636
2637 /* we are in the middle of a chunk, give
2638 as much as possible to the client (without
2639 crossing chunk boundaries) */
2640 cur_chunk_left
2641 = request->current_chunk_size - request->current_chunk_offset;
2642 if (cur_chunk_left > available)
2643 {
2644 to_be_processed = available;
2645 }
2646 else
2647 { /* cur_chunk_left <= (size_t)available */
2648 to_be_processed = (size_t) cur_chunk_left;
2649 if (available > to_be_processed)
2650 instant_retry = true;
2651 }
2652 }
2703 else 2653 else
2654 {
2655 size_t i;
2656 size_t end_size;
2657 bool malformed;
2658
2659 /* we need to read chunk boundaries */
2660 i = 0;
2661 while (i < available)
2704 { 2662 {
2705 /* no chunked encoding, give all to the client */ 2663 if ( ('\r' == buffer_head[i]) ||
2706 if ( (0 != request->remaining_upload_size) && 2664 ('\n' == buffer_head[i]) ||
2707 (MHD_SIZE_UNKNOWN != request->remaining_upload_size) && 2665 (';' == buffer_head[i]) )
2708 (request->remaining_upload_size < available) ) 2666 break;
2709 { 2667 i++;
2710 to_be_processed = (size_t)request->remaining_upload_size; 2668 if (i >= 16)
2711 } 2669 break;
2712 else
2713 {
2714 /**
2715 * 1. no chunked encoding, give all to the client
2716 * 2. client may send large chunked data, but only a smaller part is available at one time.
2717 */
2718 to_be_processed = available;
2719 }
2720 } 2670 }
2721 left_unprocessed = to_be_processed; 2671 end_size = i;
2722#if FIXME_OLD_STYLE 2672 /* find beginning of CRLF (skip over chunk extensions) */
2723 if (MHD_NO == 2673 if (';' == buffer_head[i])
2724 daemon->rc (daemon->rc_cls, 2674 {
2725 request, 2675 while (i < available)
2726 request->url, 2676 {
2727 request->method, 2677 if ( ('\r' == buffer_head[i]) ||
2728 request->version, 2678 ('\n' == buffer_head[i]) )
2729 buffer_head, 2679 break;
2730 &left_unprocessed, 2680 i++;
2731 &request->client_context)) 2681 }
2682 }
2683 /* take '\n' into account; if '\n' is the unavailable
2684 character, we will need to wait until we have it
2685 before going further */
2686 if ( (i + 1 >= available) &&
2687 ! ( (1 == i) &&
2688 (2 == available) &&
2689 ('0' == buffer_head[0]) ) )
2690 break; /* need more data... */
2691 i++;
2692 malformed = (end_size >= 16);
2693 if (! malformed)
2694 {
2695 size_t num_dig = MHD_strx_to_uint64_n_ (buffer_head,
2696 end_size,
2697 &request->current_chunk_size);
2698 malformed = (end_size != num_dig);
2699 }
2700 if (malformed)
2732 { 2701 {
2733 /* serious internal error, close connection */ 2702 /* malformed encoding */
2734 CONNECTION_CLOSE_ERROR (connection, 2703 CONNECTION_CLOSE_ERROR (connection,
2735 MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED, 2704 MHD_SC_CHUNKED_ENCODING_MALFORMED,
2736 _("Application reported internal error, closing connection.\n")); 2705 _ (
2706 "Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
2737 return; 2707 return;
2738 } 2708 }
2709 /* skip 2nd part of line feed */
2710 if ( (i < available) &&
2711 ( ('\r' == buffer_head[i]) ||
2712 ('\n' == buffer_head[i]) ) )
2713 i++;
2714
2715 buffer_head += i;
2716 available -= i;
2717 request->current_chunk_offset = 0;
2718
2719 if (available > 0)
2720 instant_retry = true;
2721 if (0LLU == request->current_chunk_size)
2722 {
2723 request->remaining_upload_size = 0;
2724 break;
2725 }
2726 continue;
2727 }
2728 }
2729 else
2730 {
2731 /* no chunked encoding, give all to the client */
2732 if ( (0 != request->remaining_upload_size) &&
2733 (MHD_SIZE_UNKNOWN != request->remaining_upload_size) &&
2734 (request->remaining_upload_size < available) )
2735 {
2736 to_be_processed = (size_t) request->remaining_upload_size;
2737 }
2738 else
2739 {
2740 /**
2741 * 1. no chunked encoding, give all to the client
2742 * 2. client may send large chunked data, but only a smaller part is available at one time.
2743 */
2744 to_be_processed = available;
2745 }
2746 }
2747 left_unprocessed = to_be_processed;
2748#if FIXME_OLD_STYLE
2749 if (MHD_NO ==
2750 daemon->rc (daemon->rc_cls,
2751 request,
2752 request->url,
2753 request->method,
2754 request->version,
2755 buffer_head,
2756 &left_unprocessed,
2757 &request->client_context))
2758 {
2759 /* serious internal error, close connection */
2760 CONNECTION_CLOSE_ERROR (connection,
2761 MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED,
2762 _ (
2763 "Application reported internal error, closing connection.\n"));
2764 return;
2765 }
2739#endif 2766#endif
2740 if (left_unprocessed > to_be_processed) 2767 if (left_unprocessed > to_be_processed)
2741 mhd_panic (mhd_panic_cls, 2768 mhd_panic (mhd_panic_cls,
2742 __FILE__, 2769 __FILE__,
2743 __LINE__ 2770 __LINE__
2744#ifdef HAVE_MESSAGES 2771#ifdef HAVE_MESSAGES
2745 , _("libmicrohttpd API violation") 2772 , _ ("libmicrohttpd API violation")
2746#else 2773#else
2747 , NULL 2774 , NULL
2748#endif 2775#endif
2749 ); 2776 );
2750 if (0 != left_unprocessed) 2777 if (0 != left_unprocessed)
2751 { 2778 {
2752 instant_retry = false; /* client did not process everything */ 2779 instant_retry = false; /* client did not process everything */
2753#ifdef HAVE_MESSAGES 2780#ifdef HAVE_MESSAGES
2754 /* client did not process all upload data, complain if 2781 /* client did not process all upload data, complain if
2755 the setup was incorrect, which may prevent us from 2782 the setup was incorrect, which may prevent us from
2756 handling the rest of the request */ 2783 handling the rest of the request */
2757 if ( (MHD_TM_EXTERNAL_EVENT_LOOP == daemon->threading_mode) && 2784 if ( (MHD_TM_EXTERNAL_EVENT_LOOP == daemon->threading_mode) &&
2758 (! connection->suspended) ) 2785 (! connection->suspended) )
2759 MHD_DLOG (daemon, 2786 MHD_DLOG (daemon,
2760 MHD_SC_APPLICATION_HUNG_CONNECTION, 2787 MHD_SC_APPLICATION_HUNG_CONNECTION,
2761 _("WARNING: incomplete upload processing and connection not suspended may result in hung connection.\n")); 2788 _ (
2789 "WARNING: incomplete upload processing and connection not suspended may result in hung connection.\n"));
2762#endif 2790#endif
2763 }
2764 processed_size = to_be_processed - left_unprocessed;
2765 if (request->have_chunked_upload)
2766 request->current_chunk_offset += processed_size;
2767 /* dh left "processed" bytes in buffer for next time... */
2768 buffer_head += processed_size;
2769 available -= processed_size;
2770 if (MHD_SIZE_UNKNOWN != request->remaining_upload_size)
2771 request->remaining_upload_size -= processed_size;
2772 } 2791 }
2792 processed_size = to_be_processed - left_unprocessed;
2793 if (request->have_chunked_upload)
2794 request->current_chunk_offset += processed_size;
2795 /* dh left "processed" bytes in buffer for next time... */
2796 buffer_head += processed_size;
2797 available -= processed_size;
2798 if (MHD_SIZE_UNKNOWN != request->remaining_upload_size)
2799 request->remaining_upload_size -= processed_size;
2800 }
2773 while (instant_retry); 2801 while (instant_retry);
2774 if (available > 0) 2802 if (available > 0)
2775 memmove (request->read_buffer, 2803 memmove (request->read_buffer,
@@ -2796,58 +2824,59 @@ cleanup_connection (struct MHD_Connection *connection)
2796 return; /* Prevent double cleanup. */ 2824 return; /* Prevent double cleanup. */
2797 connection->request.in_cleanup = true; 2825 connection->request.in_cleanup = true;
2798 if (NULL != connection->request.response) 2826 if (NULL != connection->request.response)
2799 { 2827 {
2800 MHD_response_queue_for_destroy (connection->request.response); 2828 MHD_response_queue_for_destroy (connection->request.response);
2801 connection->request.response = NULL; 2829 connection->request.response = NULL;
2802 } 2830 }
2803 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 2831 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
2804 if (connection->suspended) 2832 if (connection->suspended)
2805 { 2833 {
2806 DLL_remove (daemon->suspended_connections_head, 2834 DLL_remove (daemon->suspended_connections_head,
2807 daemon->suspended_connections_tail, 2835 daemon->suspended_connections_tail,
2808 connection); 2836 connection);
2809 connection->suspended = false; 2837 connection->suspended = false;
2810 } 2838 }
2811 else 2839 else
2840 {
2841 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
2812 { 2842 {
2813 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) 2843 if (connection->connection_timeout ==
2814 { 2844 daemon->connection_default_timeout)
2815 if (connection->connection_timeout == 2845 XDLL_remove (daemon->normal_timeout_head,
2816 daemon->connection_default_timeout) 2846 daemon->normal_timeout_tail,
2817 XDLL_remove (daemon->normal_timeout_head, 2847 connection);
2818 daemon->normal_timeout_tail, 2848 else
2819 connection); 2849 XDLL_remove (daemon->manual_timeout_head,
2820 else 2850 daemon->manual_timeout_tail,
2821 XDLL_remove (daemon->manual_timeout_head, 2851 connection);
2822 daemon->manual_timeout_tail,
2823 connection);
2824 }
2825 DLL_remove (daemon->connections_head,
2826 daemon->connections_tail,
2827 connection);
2828 } 2852 }
2853 DLL_remove (daemon->connections_head,
2854 daemon->connections_tail,
2855 connection);
2856 }
2829 DLL_insert (daemon->cleanup_head, 2857 DLL_insert (daemon->cleanup_head,
2830 daemon->cleanup_tail, 2858 daemon->cleanup_tail,
2831 connection); 2859 connection);
2832 connection->resuming = false; 2860 connection->resuming = false;
2833 connection->request.in_idle = false; 2861 connection->request.in_idle = false;
2834 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 2862 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
2835 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) 2863 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
2864 {
2865 /* if we were at the connection limit before and are in
2866 thread-per-connection mode, signal the main thread
2867 to resume accepting connections */
2868 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
2869 (! MHD_itc_activate_ (daemon->itc,
2870 "c")) )
2836 { 2871 {
2837 /* if we were at the connection limit before and are in
2838 thread-per-connection mode, signal the main thread
2839 to resume accepting connections */
2840 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
2841 (! MHD_itc_activate_ (daemon->itc,
2842 "c")) )
2843 {
2844#ifdef HAVE_MESSAGES 2872#ifdef HAVE_MESSAGES
2845 MHD_DLOG (daemon, 2873 MHD_DLOG (daemon,
2846 MHD_SC_ITC_USE_FAILED, 2874 MHD_SC_ITC_USE_FAILED,
2847 _("Failed to signal end of connection via inter-thread communication channel")); 2875 _ (
2876 "Failed to signal end of connection via inter-thread communication channel"));
2848#endif 2877#endif
2849 }
2850 } 2878 }
2879 }
2851} 2880}
2852 2881
2853 2882
@@ -2870,31 +2899,31 @@ connection_epoll_update_ (struct MHD_Connection *connection)
2870 (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) && 2899 (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
2871 ( ( (MHD_EVENT_LOOP_INFO_WRITE == connection->request.event_loop_info) && 2900 ( ( (MHD_EVENT_LOOP_INFO_WRITE == connection->request.event_loop_info) &&
2872 (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY))) || 2901 (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY))) ||
2873 ( (MHD_EVENT_LOOP_INFO_READ == connection->request.event_loop_info) && 2902 ( (MHD_EVENT_LOOP_INFO_READ == connection->request.event_loop_info) &&
2874 (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ) ) 2903 (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ) )
2904 {
2905 /* add to epoll set */
2906 struct epoll_event event;
2907
2908 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2909 event.data.ptr = connection;
2910 if (0 != epoll_ctl (daemon->epoll_fd,
2911 EPOLL_CTL_ADD,
2912 connection->socket_fd,
2913 &event))
2875 { 2914 {
2876 /* add to epoll set */
2877 struct epoll_event event;
2878
2879 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2880 event.data.ptr = connection;
2881 if (0 != epoll_ctl (daemon->epoll_fd,
2882 EPOLL_CTL_ADD,
2883 connection->socket_fd,
2884 &event))
2885 {
2886#ifdef HAVE_MESSAGES 2915#ifdef HAVE_MESSAGES
2887 MHD_DLOG (daemon, 2916 MHD_DLOG (daemon,
2888 MHD_SC_EPOLL_CTL_ADD_FAILED, 2917 MHD_SC_EPOLL_CTL_ADD_FAILED,
2889 _("Call to epoll_ctl failed: %s\n"), 2918 _ ("Call to epoll_ctl failed: %s\n"),
2890 MHD_socket_last_strerr_ ()); 2919 MHD_socket_last_strerr_ ());
2891#endif 2920#endif
2892 connection->request.state = MHD_REQUEST_CLOSED; 2921 connection->request.state = MHD_REQUEST_CLOSED;
2893 cleanup_connection (connection); 2922 cleanup_connection (connection);
2894 return false; 2923 return false;
2895 }
2896 connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
2897 } 2924 }
2925 connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
2926 }
2898 return true; 2927 return true;
2899} 2928}
2900#endif 2929#endif
@@ -2922,142 +2951,142 @@ connection_update_event_loop_info (struct MHD_Connection *connection)
2922 struct MHD_TLS_Plugin *tls; 2951 struct MHD_TLS_Plugin *tls;
2923 2952
2924 if ( (NULL != (tls = daemon->tls_api)) && 2953 if ( (NULL != (tls = daemon->tls_api)) &&
2925 (tls->update_event_loop_info (tls->cls, 2954 (tls->update_event_loop_info (tls->cls,
2926 connection->tls_cs, 2955 connection->tls_cs,
2927 &request->event_loop_info)) ) 2956 &request->event_loop_info)) )
2928 return; /* TLS has decided what to do */ 2957 return; /* TLS has decided what to do */
2929 } 2958 }
2930#endif /* HTTPS_SUPPORT */ 2959#endif /* HTTPS_SUPPORT */
2931 while (1) 2960 while (1)
2932 { 2961 {
2933#if DEBUG_STATES 2962#if DEBUG_STATES
2934 MHD_DLOG (daemon, 2963 MHD_DLOG (daemon,
2935 MHD_SC_STATE_MACHINE_STATUS_REPORT, 2964 MHD_SC_STATE_MACHINE_STATUS_REPORT,
2936 _("In function %s handling connection at state: %s\n"), 2965 _ ("In function %s handling connection at state: %s\n"),
2937 __FUNCTION__, 2966 __FUNCTION__,
2938 MHD_state_to_string (request->state)); 2967 MHD_state_to_string (request->state));
2939#endif 2968#endif
2940 switch (request->state) 2969 switch (request->state)
2970 {
2971 case MHD_REQUEST_INIT:
2972 case MHD_REQUEST_URL_RECEIVED:
2973 case MHD_REQUEST_HEADER_PART_RECEIVED:
2974 /* while reading headers, we always grow the
2975 read buffer if needed, no size-check required */
2976 if ( (request->read_buffer_offset == request->read_buffer_size) &&
2977 (! try_grow_read_buffer (request)) )
2978 {
2979 transmit_error_response (request,
2980 MHD_SC_CLIENT_HEADER_TOO_BIG,
2981 (NULL != request->url)
2982 ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
2983 : MHD_HTTP_URI_TOO_LONG,
2984 REQUEST_TOO_BIG);
2985 continue;
2986 }
2987 if (! connection->read_closed)
2988 request->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
2989 else
2990 request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
2991 break;
2992 case MHD_REQUEST_HEADERS_RECEIVED:
2993 mhd_assert (0);
2994 break;
2995 case MHD_REQUEST_HEADERS_PROCESSED:
2996 mhd_assert (0);
2997 break;
2998 case MHD_REQUEST_CONTINUE_SENDING:
2999 request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
3000 break;
3001 case MHD_REQUEST_CONTINUE_SENT:
3002 if (request->read_buffer_offset == request->read_buffer_size)
3003 {
3004 if ( (! try_grow_read_buffer (request)) &&
3005 (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) )
2941 { 3006 {
2942 case MHD_REQUEST_INIT: 3007 /* failed to grow the read buffer, and the client
2943 case MHD_REQUEST_URL_RECEIVED: 3008 which is supposed to handle the received data in
2944 case MHD_REQUEST_HEADER_PART_RECEIVED: 3009 a *blocking* fashion (in this mode) did not
2945 /* while reading headers, we always grow the 3010 handle the data as it was supposed to!
2946 read buffer if needed, no size-check required */ 3011
2947 if ( (request->read_buffer_offset == request->read_buffer_size) && 3012 => we would either have to do busy-waiting
2948 (! try_grow_read_buffer (request)) ) 3013 (on the client, which would likely fail),
2949 { 3014 or if we do nothing, we would just timeout
2950 transmit_error_response (request, 3015 on the connection (if a timeout is even set!).
2951 MHD_SC_CLIENT_HEADER_TOO_BIG, 3016
2952 (NULL != request->url) 3017 Solution: we kill the connection with an error */
2953 ? MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE 3018 transmit_error_response (request,
2954 : MHD_HTTP_URI_TOO_LONG, 3019 MHD_SC_APPLICATION_HUNG_CONNECTION_CLOSED,
2955 REQUEST_TOO_BIG); 3020 MHD_HTTP_INTERNAL_SERVER_ERROR,
2956 continue; 3021 INTERNAL_ERROR);
2957 } 3022 continue;
2958 if (! connection->read_closed)
2959 request->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
2960 else
2961 request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
2962 break;
2963 case MHD_REQUEST_HEADERS_RECEIVED:
2964 mhd_assert (0);
2965 break;
2966 case MHD_REQUEST_HEADERS_PROCESSED:
2967 mhd_assert (0);
2968 break;
2969 case MHD_REQUEST_CONTINUE_SENDING:
2970 request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
2971 break;
2972 case MHD_REQUEST_CONTINUE_SENT:
2973 if (request->read_buffer_offset == request->read_buffer_size)
2974 {
2975 if ( (! try_grow_read_buffer (request)) &&
2976 (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) )
2977 {
2978 /* failed to grow the read buffer, and the client
2979 which is supposed to handle the received data in
2980 a *blocking* fashion (in this mode) did not
2981 handle the data as it was supposed to!
2982
2983 => we would either have to do busy-waiting
2984 (on the client, which would likely fail),
2985 or if we do nothing, we would just timeout
2986 on the connection (if a timeout is even set!).
2987
2988 Solution: we kill the connection with an error */
2989 transmit_error_response (request,
2990 MHD_SC_APPLICATION_HUNG_CONNECTION_CLOSED,
2991 MHD_HTTP_INTERNAL_SERVER_ERROR,
2992 INTERNAL_ERROR);
2993 continue;
2994 }
2995 }
2996 if ( (request->read_buffer_offset < request->read_buffer_size) &&
2997 (! connection->read_closed) )
2998 request->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
2999 else
3000 request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
3001 break;
3002 case MHD_REQUEST_BODY_RECEIVED:
3003 case MHD_REQUEST_FOOTER_PART_RECEIVED:
3004 /* while reading footers, we always grow the
3005 read buffer if needed, no size-check required */
3006 if (connection->read_closed)
3007 {
3008 CONNECTION_CLOSE_ERROR (connection,
3009 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
3010 NULL);
3011 continue;
3012 }
3013 request->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
3014 /* transition to FOOTERS_RECEIVED
3015 happens in read handler */
3016 break;
3017 case MHD_REQUEST_FOOTERS_RECEIVED:
3018 request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
3019 break;
3020 case MHD_REQUEST_HEADERS_SENDING:
3021 /* headers in buffer, keep writing */
3022 request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
3023 break;
3024 case MHD_REQUEST_HEADERS_SENT:
3025 mhd_assert (0);
3026 break;
3027 case MHD_REQUEST_NORMAL_BODY_READY:
3028 request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
3029 break;
3030 case MHD_REQUEST_NORMAL_BODY_UNREADY:
3031 request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
3032 break;
3033 case MHD_REQUEST_CHUNKED_BODY_READY:
3034 request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
3035 break;
3036 case MHD_REQUEST_CHUNKED_BODY_UNREADY:
3037 request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
3038 break;
3039 case MHD_REQUEST_BODY_SENT:
3040 mhd_assert (0);
3041 break;
3042 case MHD_REQUEST_FOOTERS_SENDING:
3043 request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
3044 break;
3045 case MHD_REQUEST_FOOTERS_SENT:
3046 mhd_assert (0);
3047 break;
3048 case MHD_REQUEST_CLOSED:
3049 request->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
3050 return; /* do nothing, not even reading */
3051#ifdef UPGRADE_SUPPORT
3052 case MHD_REQUEST_UPGRADE:
3053 mhd_assert (0);
3054 break;
3055#endif /* UPGRADE_SUPPORT */
3056 default:
3057 mhd_assert (0);
3058 } 3023 }
3024 }
3025 if ( (request->read_buffer_offset < request->read_buffer_size) &&
3026 (! connection->read_closed) )
3027 request->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
3028 else
3029 request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
3030 break;
3031 case MHD_REQUEST_BODY_RECEIVED:
3032 case MHD_REQUEST_FOOTER_PART_RECEIVED:
3033 /* while reading footers, we always grow the
3034 read buffer if needed, no size-check required */
3035 if (connection->read_closed)
3036 {
3037 CONNECTION_CLOSE_ERROR (connection,
3038 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
3039 NULL);
3040 continue;
3041 }
3042 request->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
3043 /* transition to FOOTERS_RECEIVED
3044 happens in read handler */
3045 break;
3046 case MHD_REQUEST_FOOTERS_RECEIVED:
3047 request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
3048 break;
3049 case MHD_REQUEST_HEADERS_SENDING:
3050 /* headers in buffer, keep writing */
3051 request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
3052 break;
3053 case MHD_REQUEST_HEADERS_SENT:
3054 mhd_assert (0);
3055 break;
3056 case MHD_REQUEST_NORMAL_BODY_READY:
3057 request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
3058 break;
3059 case MHD_REQUEST_NORMAL_BODY_UNREADY:
3060 request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
3061 break;
3062 case MHD_REQUEST_CHUNKED_BODY_READY:
3063 request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
3064 break;
3065 case MHD_REQUEST_CHUNKED_BODY_UNREADY:
3066 request->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
3067 break;
3068 case MHD_REQUEST_BODY_SENT:
3069 mhd_assert (0);
3070 break;
3071 case MHD_REQUEST_FOOTERS_SENDING:
3072 request->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
3059 break; 3073 break;
3074 case MHD_REQUEST_FOOTERS_SENT:
3075 mhd_assert (0);
3076 break;
3077 case MHD_REQUEST_CLOSED:
3078 request->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
3079 return; /* do nothing, not even reading */
3080#ifdef UPGRADE_SUPPORT
3081 case MHD_REQUEST_UPGRADE:
3082 mhd_assert (0);
3083 break;
3084#endif /* UPGRADE_SUPPORT */
3085 default:
3086 mhd_assert (0);
3060 } 3087 }
3088 break;
3089 }
3061} 3090}
3062 3091
3063 3092
@@ -3082,491 +3111,494 @@ MHD_request_handle_idle_ (struct MHD_Request *request)
3082 3111
3083 request->in_idle = true; 3112 request->in_idle = true;
3084 while (! connection->suspended) 3113 while (! connection->suspended)
3085 { 3114 {
3086#ifdef HTTPS_SUPPORT 3115#ifdef HTTPS_SUPPORT
3087 struct MHD_TLS_Plugin *tls; 3116 struct MHD_TLS_Plugin *tls;
3088 3117
3089 if ( (NULL != (tls = daemon->tls_api)) && 3118 if ( (NULL != (tls = daemon->tls_api)) &&
3090 (! tls->idle_ready (tls->cls, 3119 (! tls->idle_ready (tls->cls,
3091 connection->tls_cs)) ) 3120 connection->tls_cs)) )
3092 break; 3121 break;
3093#endif /* HTTPS_SUPPORT */ 3122#endif /* HTTPS_SUPPORT */
3094#if DEBUG_STATES 3123#if DEBUG_STATES
3095 MHD_DLOG (daemon, 3124 MHD_DLOG (daemon,
3096 MHD_SC_STATE_MACHINE_STATUS_REPORT, 3125 MHD_SC_STATE_MACHINE_STATUS_REPORT,
3097 _("In function %s handling connection at state: %s\n"), 3126 _ ("In function %s handling connection at state: %s\n"),
3098 __FUNCTION__, 3127 __FUNCTION__,
3099 MHD_state_to_string (request->state)); 3128 MHD_state_to_string (request->state));
3100#endif 3129#endif
3101 switch (request->state) 3130 switch (request->state)
3131 {
3132 case MHD_REQUEST_INIT:
3133 line = get_next_header_line (request,
3134 &line_len);
3135 /* Check for empty string, as we might want
3136 to tolerate 'spurious' empty lines; also
3137 NULL means we didn't get a full line yet;
3138 line is not 0-terminated here. */
3139 if ( (NULL == line) ||
3140 (0 == line[0]) )
3141 {
3142 if (MHD_REQUEST_INIT != request->state)
3143 continue;
3144 if (connection->read_closed)
3102 { 3145 {
3103 case MHD_REQUEST_INIT: 3146 CONNECTION_CLOSE_ERROR (connection,
3104 line = get_next_header_line (request, 3147 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
3105 &line_len); 3148 NULL);
3106 /* Check for empty string, as we might want
3107 to tolerate 'spurious' empty lines; also
3108 NULL means we didn't get a full line yet;
3109 line is not 0-terminated here. */
3110 if ( (NULL == line) ||
3111 (0 == line[0]) )
3112 {
3113 if (MHD_REQUEST_INIT != request->state)
3114 continue;
3115 if (connection->read_closed)
3116 {
3117 CONNECTION_CLOSE_ERROR (connection,
3118 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
3119 NULL);
3120 continue;
3121 }
3122 break;
3123 }
3124 if (MHD_NO ==
3125 parse_initial_message_line (request,
3126 line,
3127 line_len))
3128 CONNECTION_CLOSE_ERROR (connection,
3129 MHD_SC_CONNECTION_CLOSED,
3130 NULL);
3131 else
3132 request->state = MHD_REQUEST_URL_RECEIVED;
3133 continue; 3149 continue;
3134 case MHD_REQUEST_URL_RECEIVED: 3150 }
3135 line = get_next_header_line (request, 3151 break;
3136 NULL); 3152 }
3137 if (NULL == line) 3153 if (MHD_NO ==
3138 { 3154 parse_initial_message_line (request,
3139 if (MHD_REQUEST_URL_RECEIVED != request->state) 3155 line,
3140 continue; 3156 line_len))
3141 if (connection->read_closed) 3157 CONNECTION_CLOSE_ERROR (connection,
3142 { 3158 MHD_SC_CONNECTION_CLOSED,
3143 CONNECTION_CLOSE_ERROR (connection, 3159 NULL);
3144 MHD_SC_CONNECTION_READ_FAIL_CLOSED, 3160 else
3145 NULL); 3161 request->state = MHD_REQUEST_URL_RECEIVED;
3146 continue; 3162 continue;
3147 } 3163 case MHD_REQUEST_URL_RECEIVED:
3148 break; 3164 line = get_next_header_line (request,
3149 } 3165 NULL);
3150 if (0 == line[0]) 3166 if (NULL == line)
3151 { 3167 {
3152 request->state = MHD_REQUEST_HEADERS_RECEIVED; 3168 if (MHD_REQUEST_URL_RECEIVED != request->state)
3153 request->header_size = (size_t) (line - request->read_buffer);
3154 continue;
3155 }
3156 if (! process_header_line (request,
3157 line))
3158 {
3159 transmit_error_response (request,
3160 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
3161 MHD_HTTP_BAD_REQUEST,
3162 REQUEST_MALFORMED);
3163 break;
3164 }
3165 request->state = MHD_REQUEST_HEADER_PART_RECEIVED;
3166 continue; 3169 continue;
3167 case MHD_REQUEST_HEADER_PART_RECEIVED: 3170 if (connection->read_closed)
3168 line = get_next_header_line (request, 3171 {
3169 NULL); 3172 CONNECTION_CLOSE_ERROR (connection,
3170 if (NULL == line) 3173 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
3171 { 3174 NULL);
3172 if (request->state != MHD_REQUEST_HEADER_PART_RECEIVED)
3173 continue;
3174 if (connection->read_closed)
3175 {
3176 CONNECTION_CLOSE_ERROR (connection,
3177 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
3178 NULL);
3179 continue;
3180 }
3181 break;
3182 }
3183 if (MHD_NO ==
3184 process_broken_line (request,
3185 line,
3186 MHD_HEADER_KIND))
3187 continue;
3188 if (0 == line[0])
3189 {
3190 request->state = MHD_REQUEST_HEADERS_RECEIVED;
3191 request->header_size = (size_t) (line - request->read_buffer);
3192 continue;
3193 }
3194 continue; 3175 continue;
3195 case MHD_REQUEST_HEADERS_RECEIVED: 3176 }
3196 parse_request_headers (request); 3177 break;
3197 if (MHD_REQUEST_CLOSED == request->state) 3178 }
3198 continue; 3179 if (0 == line[0])
3199 request->state = MHD_REQUEST_HEADERS_PROCESSED; 3180 {
3200 if (connection->suspended) 3181 request->state = MHD_REQUEST_HEADERS_RECEIVED;
3201 break; 3182 request->header_size = (size_t) (line - request->read_buffer);
3183 continue;
3184 }
3185 if (! process_header_line (request,
3186 line))
3187 {
3188 transmit_error_response (request,
3189 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
3190 MHD_HTTP_BAD_REQUEST,
3191 REQUEST_MALFORMED);
3192 break;
3193 }
3194 request->state = MHD_REQUEST_HEADER_PART_RECEIVED;
3195 continue;
3196 case MHD_REQUEST_HEADER_PART_RECEIVED:
3197 line = get_next_header_line (request,
3198 NULL);
3199 if (NULL == line)
3200 {
3201 if (request->state != MHD_REQUEST_HEADER_PART_RECEIVED)
3202 continue; 3202 continue;
3203 case MHD_REQUEST_HEADERS_PROCESSED: 3203 if (connection->read_closed)
3204 call_request_handler (request); /* first call */ 3204 {
3205 if (MHD_REQUEST_CLOSED == request->state) 3205 CONNECTION_CLOSE_ERROR (connection,
3206 continue; 3206 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
3207 if (need_100_continue (request)) 3207 NULL);
3208 {
3209 request->state = MHD_REQUEST_CONTINUE_SENDING;
3210 if (socket_flush_possible (connection))
3211 socket_start_extra_buffering (connection);
3212 else
3213 socket_start_no_buffering (connection);
3214 break;
3215 }
3216 if ( (NULL != request->response) &&
3217 ( (MHD_METHOD_POST == request->method) ||
3218 (MHD_METHOD_PUT == request->method) ) )
3219 {
3220 /* we refused (no upload allowed!) */
3221 request->remaining_upload_size = 0;
3222 /* force close, in case client still tries to upload... */
3223 connection->read_closed = true;
3224 }
3225 request->state = (0 == request->remaining_upload_size)
3226 ? MHD_REQUEST_FOOTERS_RECEIVED
3227 : MHD_REQUEST_CONTINUE_SENT;
3228 if (connection->suspended)
3229 break;
3230 continue; 3208 continue;
3231 case MHD_REQUEST_CONTINUE_SENDING: 3209 }
3232 if (request->continue_message_write_offset == 3210 break;
3233 MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE)) 3211 }
3234 { 3212 if (MHD_NO ==
3235 request->state = MHD_REQUEST_CONTINUE_SENT; 3213 process_broken_line (request,
3236 if (! socket_flush_possible (connection)) 3214 line,
3237 socket_start_no_buffering_flush (connection); 3215 MHD_HEADER_KIND))
3238 else 3216 continue;
3239 socket_start_normal_buffering (connection); 3217 if (0 == line[0])
3240 continue; 3218 {
3241 } 3219 request->state = MHD_REQUEST_HEADERS_RECEIVED;
3242 break; 3220 request->header_size = (size_t) (line - request->read_buffer);
3243 case MHD_REQUEST_CONTINUE_SENT: 3221 continue;
3244 if (0 != request->read_buffer_offset) 3222 }
3245 { 3223 continue;
3246 process_request_body (request); /* loop call */ 3224 case MHD_REQUEST_HEADERS_RECEIVED:
3247 if (MHD_REQUEST_CLOSED == request->state) 3225 parse_request_headers (request);
3248 continue; 3226 if (MHD_REQUEST_CLOSED == request->state)
3249 } 3227 continue;
3250 if ( (0 == request->remaining_upload_size) || 3228 request->state = MHD_REQUEST_HEADERS_PROCESSED;
3251 ( (MHD_SIZE_UNKNOWN == request->remaining_upload_size) && 3229 if (connection->suspended)
3252 (0 == request->read_buffer_offset) && 3230 break;
3253 (connection->read_closed) ) ) 3231 continue;
3254 { 3232 case MHD_REQUEST_HEADERS_PROCESSED:
3255 if ( (request->have_chunked_upload) && 3233 call_request_handler (request); /* first call */
3256 (! connection->read_closed) ) 3234 if (MHD_REQUEST_CLOSED == request->state)
3257 request->state = MHD_REQUEST_BODY_RECEIVED; 3235 continue;
3258 else 3236 if (need_100_continue (request))
3259 request->state = MHD_REQUEST_FOOTERS_RECEIVED; 3237 {
3260 if (connection->suspended) 3238 request->state = MHD_REQUEST_CONTINUE_SENDING;
3261 break; 3239 if (socket_flush_possible (connection))
3262 continue; 3240 socket_start_extra_buffering (connection);
3263 } 3241 else
3242 socket_start_no_buffering (connection);
3243 break;
3244 }
3245 if ( (NULL != request->response) &&
3246 ( (MHD_METHOD_POST == request->method) ||
3247 (MHD_METHOD_PUT == request->method) ) )
3248 {
3249 /* we refused (no upload allowed!) */
3250 request->remaining_upload_size = 0;
3251 /* force close, in case client still tries to upload... */
3252 connection->read_closed = true;
3253 }
3254 request->state = (0 == request->remaining_upload_size)
3255 ? MHD_REQUEST_FOOTERS_RECEIVED
3256 : MHD_REQUEST_CONTINUE_SENT;
3257 if (connection->suspended)
3258 break;
3259 continue;
3260 case MHD_REQUEST_CONTINUE_SENDING:
3261 if (request->continue_message_write_offset ==
3262 MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE))
3263 {
3264 request->state = MHD_REQUEST_CONTINUE_SENT;
3265 if (! socket_flush_possible (connection))
3266 socket_start_no_buffering_flush (connection);
3267 else
3268 socket_start_normal_buffering (connection);
3269 continue;
3270 }
3271 break;
3272 case MHD_REQUEST_CONTINUE_SENT:
3273 if (0 != request->read_buffer_offset)
3274 {
3275 process_request_body (request); /* loop call */
3276 if (MHD_REQUEST_CLOSED == request->state)
3277 continue;
3278 }
3279 if ( (0 == request->remaining_upload_size) ||
3280 ( (MHD_SIZE_UNKNOWN == request->remaining_upload_size) &&
3281 (0 == request->read_buffer_offset) &&
3282 (connection->read_closed) ) )
3283 {
3284 if ( (request->have_chunked_upload) &&
3285 (! connection->read_closed) )
3286 request->state = MHD_REQUEST_BODY_RECEIVED;
3287 else
3288 request->state = MHD_REQUEST_FOOTERS_RECEIVED;
3289 if (connection->suspended)
3264 break; 3290 break;
3265 case MHD_REQUEST_BODY_RECEIVED: 3291 continue;
3266 line = get_next_header_line (request, 3292 }
3267 NULL); 3293 break;
3268 if (NULL == line) 3294 case MHD_REQUEST_BODY_RECEIVED:
3269 { 3295 line = get_next_header_line (request,
3270 if (request->state != MHD_REQUEST_BODY_RECEIVED) 3296 NULL);
3271 continue; 3297 if (NULL == line)
3272 if (connection->read_closed) 3298 {
3273 { 3299 if (request->state != MHD_REQUEST_BODY_RECEIVED)
3274 CONNECTION_CLOSE_ERROR (connection,
3275 MHD_SC_CONNECTION_CLOSED,
3276 NULL);
3277 continue;
3278 }
3279 break;
3280 }
3281 if (0 == line[0])
3282 {
3283 request->state = MHD_REQUEST_FOOTERS_RECEIVED;
3284 if (connection->suspended)
3285 break;
3286 continue;
3287 }
3288 if (MHD_NO == process_header_line (request,
3289 line))
3290 {
3291 transmit_error_response (request,
3292 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
3293 MHD_HTTP_BAD_REQUEST,
3294 REQUEST_MALFORMED);
3295 break;
3296 }
3297 request->state = MHD_REQUEST_FOOTER_PART_RECEIVED;
3298 continue; 3300 continue;
3299 case MHD_REQUEST_FOOTER_PART_RECEIVED: 3301 if (connection->read_closed)
3300 line = get_next_header_line (request, 3302 {
3301 NULL); 3303 CONNECTION_CLOSE_ERROR (connection,
3302 if (NULL == line) 3304 MHD_SC_CONNECTION_CLOSED,
3303 { 3305 NULL);
3304 if (request->state != MHD_REQUEST_FOOTER_PART_RECEIVED)
3305 continue;
3306 if (connection->read_closed)
3307 {
3308 CONNECTION_CLOSE_ERROR (connection,
3309 MHD_SC_CONNECTION_CLOSED,
3310 NULL);
3311 continue;
3312 }
3313 break;
3314 }
3315 if (MHD_NO ==
3316 process_broken_line (request,
3317 line,
3318 MHD_FOOTER_KIND))
3319 continue;
3320 if (0 == line[0])
3321 {
3322 request->state = MHD_REQUEST_FOOTERS_RECEIVED;
3323 if (connection->suspended)
3324 break;
3325 continue;
3326 }
3327 continue; 3306 continue;
3328 case MHD_REQUEST_FOOTERS_RECEIVED: 3307 }
3329 call_request_handler (request); /* "final" call */ 3308 break;
3330 if (request->state == MHD_REQUEST_CLOSED) 3309 }
3331 continue; 3310 if (0 == line[0])
3332 if (NULL == request->response) 3311 {
3333 break; /* try again next time */ 3312 request->state = MHD_REQUEST_FOOTERS_RECEIVED;
3334 if (! build_header_response (request)) 3313 if (connection->suspended)
3335 {
3336 /* oops - close! */
3337 CONNECTION_CLOSE_ERROR (connection,
3338 MHD_SC_FAILED_RESPONSE_HEADER_GENERATION,
3339 _("Closing connection (failed to create response header)\n"));
3340 continue;
3341 }
3342 request->state = MHD_REQUEST_HEADERS_SENDING;
3343 if (MHD_NO != socket_flush_possible (connection))
3344 socket_start_extra_buffering (connection);
3345 else
3346 socket_start_no_buffering (connection);
3347
3348 break; 3314 break;
3349 case MHD_REQUEST_HEADERS_SENDING: 3315 continue;
3350 /* no default action */ 3316 }
3317 if (MHD_NO == process_header_line (request,
3318 line))
3319 {
3320 transmit_error_response (request,
3321 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
3322 MHD_HTTP_BAD_REQUEST,
3323 REQUEST_MALFORMED);
3324 break;
3325 }
3326 request->state = MHD_REQUEST_FOOTER_PART_RECEIVED;
3327 continue;
3328 case MHD_REQUEST_FOOTER_PART_RECEIVED:
3329 line = get_next_header_line (request,
3330 NULL);
3331 if (NULL == line)
3332 {
3333 if (request->state != MHD_REQUEST_FOOTER_PART_RECEIVED)
3334 continue;
3335 if (connection->read_closed)
3336 {
3337 CONNECTION_CLOSE_ERROR (connection,
3338 MHD_SC_CONNECTION_CLOSED,
3339 NULL);
3340 continue;
3341 }
3342 break;
3343 }
3344 if (MHD_NO ==
3345 process_broken_line (request,
3346 line,
3347 MHD_FOOTER_KIND))
3348 continue;
3349 if (0 == line[0])
3350 {
3351 request->state = MHD_REQUEST_FOOTERS_RECEIVED;
3352 if (connection->suspended)
3351 break; 3353 break;
3352 case MHD_REQUEST_HEADERS_SENT: 3354 continue;
3353 /* Some clients may take some actions right after header receive */ 3355 }
3354 if (MHD_NO != socket_flush_possible (connection)) 3356 continue;
3355 socket_start_no_buffering_flush (connection); 3357 case MHD_REQUEST_FOOTERS_RECEIVED:
3358 call_request_handler (request); /* "final" call */
3359 if (request->state == MHD_REQUEST_CLOSED)
3360 continue;
3361 if (NULL == request->response)
3362 break; /* try again next time */
3363 if (! build_header_response (request))
3364 {
3365 /* oops - close! */
3366 CONNECTION_CLOSE_ERROR (connection,
3367 MHD_SC_FAILED_RESPONSE_HEADER_GENERATION,
3368 _ (
3369 "Closing connection (failed to create response header)\n"));
3370 continue;
3371 }
3372 request->state = MHD_REQUEST_HEADERS_SENDING;
3373 if (MHD_NO != socket_flush_possible (connection))
3374 socket_start_extra_buffering (connection);
3375 else
3376 socket_start_no_buffering (connection);
3377
3378 break;
3379 case MHD_REQUEST_HEADERS_SENDING:
3380 /* no default action */
3381 break;
3382 case MHD_REQUEST_HEADERS_SENT:
3383 /* Some clients may take some actions right after header receive */
3384 if (MHD_NO != socket_flush_possible (connection))
3385 socket_start_no_buffering_flush (connection);
3356 3386
3357#ifdef UPGRADE_SUPPORT 3387#ifdef UPGRADE_SUPPORT
3358 if (NULL != request->response->upgrade_handler) 3388 if (NULL != request->response->upgrade_handler)
3359 { 3389 {
3360 socket_start_normal_buffering (connection); 3390 socket_start_normal_buffering (connection);
3361 request->state = MHD_REQUEST_UPGRADE; 3391 request->state = MHD_REQUEST_UPGRADE;
3362#if FIXME_LEGACY_STYLE 3392#if FIXME_LEGACY_STYLE
3363 /* This request is "upgraded". Pass socket to application. */ 3393 /* This request is "upgraded". Pass socket to application. */
3364 if (! MHD_response_execute_upgrade_ (request->response, 3394 if (! MHD_response_execute_upgrade_ (request->response,
3365 request)) 3395 request))
3366 { 3396 {
3367 /* upgrade failed, fail hard */ 3397 /* upgrade failed, fail hard */
3368 CONNECTION_CLOSE_ERROR (connection, 3398 CONNECTION_CLOSE_ERROR (connection,
3369 MHD_SC_CONNECTION_CLOSED, 3399 MHD_SC_CONNECTION_CLOSED,
3370 NULL); 3400 NULL);
3371 continue; 3401 continue;
3372 } 3402 }
3373#endif 3403#endif
3374 /* Response is not required anymore for this request. */ 3404 /* Response is not required anymore for this request. */
3375 { 3405 {
3376 struct MHD_Response * const resp = request->response; 3406 struct MHD_Response *const resp = request->response;
3377 3407
3378 request->response = NULL; 3408 request->response = NULL;
3379 MHD_response_queue_for_destroy (resp); 3409 MHD_response_queue_for_destroy (resp);
3380 } 3410 }
3381 continue; 3411 continue;
3382 } 3412 }
3383#endif /* UPGRADE_SUPPORT */ 3413#endif /* UPGRADE_SUPPORT */
3384 if (MHD_NO != socket_flush_possible (connection)) 3414 if (MHD_NO != socket_flush_possible (connection))
3385 socket_start_extra_buffering (connection); 3415 socket_start_extra_buffering (connection);
3386 else 3416 else
3387 socket_start_normal_buffering (connection); 3417 socket_start_normal_buffering (connection);
3388 3418
3389 if (request->have_chunked_upload) 3419 if (request->have_chunked_upload)
3390 request->state = MHD_REQUEST_CHUNKED_BODY_UNREADY; 3420 request->state = MHD_REQUEST_CHUNKED_BODY_UNREADY;
3391 else 3421 else
3392 request->state = MHD_REQUEST_NORMAL_BODY_UNREADY; 3422 request->state = MHD_REQUEST_NORMAL_BODY_UNREADY;
3393 continue; 3423 continue;
3394 case MHD_REQUEST_NORMAL_BODY_READY: 3424 case MHD_REQUEST_NORMAL_BODY_READY:
3395 /* nothing to do here */ 3425 /* nothing to do here */
3396 break; 3426 break;
3397 case MHD_REQUEST_NORMAL_BODY_UNREADY: 3427 case MHD_REQUEST_NORMAL_BODY_UNREADY:
3398 if (NULL != request->response->crc) 3428 if (NULL != request->response->crc)
3399 MHD_mutex_lock_chk_ (&request->response->mutex); 3429 MHD_mutex_lock_chk_ (&request->response->mutex);
3400 if (0 == request->response->total_size) 3430 if (0 == request->response->total_size)
3401 { 3431 {
3402 if (NULL != request->response->crc) 3432 if (NULL != request->response->crc)
3403 MHD_mutex_unlock_chk_ (&request->response->mutex); 3433 MHD_mutex_unlock_chk_ (&request->response->mutex);
3404 request->state = MHD_REQUEST_BODY_SENT; 3434 request->state = MHD_REQUEST_BODY_SENT;
3405 continue; 3435 continue;
3406 } 3436 }
3407 if (try_ready_normal_body (request)) 3437 if (try_ready_normal_body (request))
3408 { 3438 {
3409 if (NULL != request->response->crc) 3439 if (NULL != request->response->crc)
3410 MHD_mutex_unlock_chk_ (&request->response->mutex); 3440 MHD_mutex_unlock_chk_ (&request->response->mutex);
3411 request->state = MHD_REQUEST_NORMAL_BODY_READY; 3441 request->state = MHD_REQUEST_NORMAL_BODY_READY;
3412 /* Buffering for flushable socket was already enabled*/ 3442 /* Buffering for flushable socket was already enabled*/
3413 if (MHD_NO == socket_flush_possible (connection)) 3443 if (MHD_NO == socket_flush_possible (connection))
3414 socket_start_no_buffering (connection); 3444 socket_start_no_buffering (connection);
3415 break; 3445 break;
3416 } 3446 }
3417 /* mutex was already unlocked by "try_ready_normal_body */ 3447 /* mutex was already unlocked by "try_ready_normal_body */
3418 /* not ready, no socket action */ 3448 /* not ready, no socket action */
3419 break; 3449 break;
3420 case MHD_REQUEST_CHUNKED_BODY_READY: 3450 case MHD_REQUEST_CHUNKED_BODY_READY:
3421 /* nothing to do here */ 3451 /* nothing to do here */
3422 break; 3452 break;
3423 case MHD_REQUEST_CHUNKED_BODY_UNREADY: 3453 case MHD_REQUEST_CHUNKED_BODY_UNREADY:
3424 if (NULL != request->response->crc) 3454 if (NULL != request->response->crc)
3425 MHD_mutex_lock_chk_ (&request->response->mutex); 3455 MHD_mutex_lock_chk_ (&request->response->mutex);
3426 if ( (0 == request->response->total_size) || 3456 if ( (0 == request->response->total_size) ||
3427 (request->response_write_position == 3457 (request->response_write_position ==
3428 request->response->total_size) ) 3458 request->response->total_size) )
3429 { 3459 {
3430 if (NULL != request->response->crc) 3460 if (NULL != request->response->crc)
3431 MHD_mutex_unlock_chk_ (&request->response->mutex); 3461 MHD_mutex_unlock_chk_ (&request->response->mutex);
3432 request->state = MHD_REQUEST_BODY_SENT; 3462 request->state = MHD_REQUEST_BODY_SENT;
3433 continue; 3463 continue;
3434 } 3464 }
3435 if (try_ready_chunked_body (request)) 3465 if (try_ready_chunked_body (request))
3436 { 3466 {
3437 if (NULL != request->response->crc) 3467 if (NULL != request->response->crc)
3438 MHD_mutex_unlock_chk_ (&request->response->mutex); 3468 MHD_mutex_unlock_chk_ (&request->response->mutex);
3439 request->state = MHD_REQUEST_CHUNKED_BODY_READY; 3469 request->state = MHD_REQUEST_CHUNKED_BODY_READY;
3440 /* Buffering for flushable socket was already enabled */ 3470 /* Buffering for flushable socket was already enabled */
3441 if (MHD_NO == socket_flush_possible (connection)) 3471 if (MHD_NO == socket_flush_possible (connection))
3442 socket_start_no_buffering (connection); 3472 socket_start_no_buffering (connection);
3443 continue; 3473 continue;
3444 } 3474 }
3445 /* mutex was already unlocked by try_ready_chunked_body */ 3475 /* mutex was already unlocked by try_ready_chunked_body */
3446 break; 3476 break;
3447 case MHD_REQUEST_BODY_SENT: 3477 case MHD_REQUEST_BODY_SENT:
3448 if (! build_header_response (request)) 3478 if (! build_header_response (request))
3449 { 3479 {
3450 /* oops - close! */ 3480 /* oops - close! */
3451 CONNECTION_CLOSE_ERROR (connection, 3481 CONNECTION_CLOSE_ERROR (connection,
3452 MHD_SC_FAILED_RESPONSE_HEADER_GENERATION, 3482 MHD_SC_FAILED_RESPONSE_HEADER_GENERATION,
3453 _("Closing connection (failed to create response header)\n")); 3483 _ (
3454 continue; 3484 "Closing connection (failed to create response header)\n"));
3455 } 3485 continue;
3456 if ( (! request->have_chunked_upload) || 3486 }
3457 (request->write_buffer_send_offset == 3487 if ( (! request->have_chunked_upload) ||
3458 request->write_buffer_append_offset) ) 3488 (request->write_buffer_send_offset ==
3459 request->state = MHD_REQUEST_FOOTERS_SENT; 3489 request->write_buffer_append_offset) )
3460 else 3490 request->state = MHD_REQUEST_FOOTERS_SENT;
3461 request->state = MHD_REQUEST_FOOTERS_SENDING; 3491 else
3462 continue; 3492 request->state = MHD_REQUEST_FOOTERS_SENDING;
3463 case MHD_REQUEST_FOOTERS_SENDING: 3493 continue;
3464 /* no default action */ 3494 case MHD_REQUEST_FOOTERS_SENDING:
3465 break; 3495 /* no default action */
3466 case MHD_REQUEST_FOOTERS_SENT: 3496 break;
3467 { 3497 case MHD_REQUEST_FOOTERS_SENT:
3468 struct MHD_Response *response = request->response; 3498 {
3469 3499 struct MHD_Response *response = request->response;
3470 if (MHD_HTTP_PROCESSING == response->status_code) 3500
3471 { 3501 if (MHD_HTTP_PROCESSING == response->status_code)
3472 /* After this type of response, we allow sending another! */ 3502 {
3473 request->state = MHD_REQUEST_HEADERS_PROCESSED; 3503 /* After this type of response, we allow sending another! */
3474 MHD_response_queue_for_destroy (response); 3504 request->state = MHD_REQUEST_HEADERS_PROCESSED;
3475 request->response = NULL; 3505 MHD_response_queue_for_destroy (response);
3476 /* FIXME: maybe partially reset memory pool? */ 3506 request->response = NULL;
3477 continue; 3507 /* FIXME: maybe partially reset memory pool? */
3478 }
3479 if (socket_flush_possible (connection))
3480 socket_start_no_buffering_flush (connection);
3481 else
3482 socket_start_normal_buffering (connection);
3483
3484 if (NULL != response->termination_cb)
3485 {
3486 response->termination_cb (response->termination_cb_cls,
3487 MHD_REQUEST_TERMINATED_COMPLETED_OK,
3488 request->client_context);
3489 }
3490 MHD_response_queue_for_destroy (response);
3491 request->response = NULL;
3492 }
3493 if ( (MHD_CONN_USE_KEEPALIVE != request->keepalive) ||
3494 (connection->read_closed) )
3495 {
3496 /* have to close for some reason */
3497 MHD_connection_close_ (connection,
3498 MHD_REQUEST_TERMINATED_COMPLETED_OK);
3499 MHD_pool_destroy (connection->pool);
3500 connection->pool = NULL;
3501 request->read_buffer = NULL;
3502 request->read_buffer_size = 0;
3503 request->read_buffer_offset = 0;
3504 }
3505 else
3506 {
3507 /* can try to keep-alive */
3508 if (socket_flush_possible (connection))
3509 socket_start_normal_buffering (connection);
3510 request->version_s = NULL;
3511 request->state = MHD_REQUEST_INIT;
3512 request->last = NULL;
3513 request->colon = NULL;
3514 request->header_size = 0;
3515 request->keepalive = MHD_CONN_KEEPALIVE_UNKOWN;
3516 /* Reset the read buffer to the starting size,
3517 preserving the bytes we have already read. */
3518 request->read_buffer
3519 = MHD_pool_reset (connection->pool,
3520 request->read_buffer,
3521 request->read_buffer_offset,
3522 daemon->connection_memory_limit_b / 2);
3523 request->read_buffer_size
3524 = daemon->connection_memory_limit_b / 2;
3525 }
3526 // FIXME: this is too much, NULLs out some of the things
3527 // initialized above...
3528 memset (request,
3529 0,
3530 sizeof (struct MHD_Request));
3531 request->daemon = daemon;
3532 request->connection = connection;
3533 continue; 3508 continue;
3534 case MHD_REQUEST_CLOSED: 3509 }
3535 cleanup_connection (connection); 3510 if (socket_flush_possible (connection))
3536 request->in_idle = false; 3511 socket_start_no_buffering_flush (connection);
3537 return false; 3512 else
3513 socket_start_normal_buffering (connection);
3514
3515 if (NULL != response->termination_cb)
3516 {
3517 response->termination_cb (response->termination_cb_cls,
3518 MHD_REQUEST_TERMINATED_COMPLETED_OK,
3519 request->client_context);
3520 }
3521 MHD_response_queue_for_destroy (response);
3522 request->response = NULL;
3523 }
3524 if ( (MHD_CONN_USE_KEEPALIVE != request->keepalive) ||
3525 (connection->read_closed) )
3526 {
3527 /* have to close for some reason */
3528 MHD_connection_close_ (connection,
3529 MHD_REQUEST_TERMINATED_COMPLETED_OK);
3530 MHD_pool_destroy (connection->pool);
3531 connection->pool = NULL;
3532 request->read_buffer = NULL;
3533 request->read_buffer_size = 0;
3534 request->read_buffer_offset = 0;
3535 }
3536 else
3537 {
3538 /* can try to keep-alive */
3539 if (socket_flush_possible (connection))
3540 socket_start_normal_buffering (connection);
3541 request->version_s = NULL;
3542 request->state = MHD_REQUEST_INIT;
3543 request->last = NULL;
3544 request->colon = NULL;
3545 request->header_size = 0;
3546 request->keepalive = MHD_CONN_KEEPALIVE_UNKOWN;
3547 /* Reset the read buffer to the starting size,
3548 preserving the bytes we have already read. */
3549 request->read_buffer
3550 = MHD_pool_reset (connection->pool,
3551 request->read_buffer,
3552 request->read_buffer_offset,
3553 daemon->connection_memory_limit_b / 2);
3554 request->read_buffer_size
3555 = daemon->connection_memory_limit_b / 2;
3556 }
3557 // FIXME: this is too much, NULLs out some of the things
3558 // initialized above...
3559 memset (request,
3560 0,
3561 sizeof (struct MHD_Request));
3562 request->daemon = daemon;
3563 request->connection = connection;
3564 continue;
3565 case MHD_REQUEST_CLOSED:
3566 cleanup_connection (connection);
3567 request->in_idle = false;
3568 return false;
3538#ifdef UPGRADE_SUPPORT 3569#ifdef UPGRADE_SUPPORT
3539 case MHD_REQUEST_UPGRADE: 3570 case MHD_REQUEST_UPGRADE:
3540 request->in_idle = false; 3571 request->in_idle = false;
3541 return true; /* keep open */ 3572 return true; /* keep open */
3542#endif /* UPGRADE_SUPPORT */ 3573#endif /* UPGRADE_SUPPORT */
3543 default: 3574 default:
3544 mhd_assert (0); 3575 mhd_assert (0);
3545 break;
3546 }
3547 break; 3576 break;
3548 } 3577 }
3578 break;
3579 }
3549 if (! connection->suspended) 3580 if (! connection->suspended)
3581 {
3582 time_t timeout;
3583 timeout = connection->connection_timeout;
3584 if ( (0 != timeout) &&
3585 (timeout < (MHD_monotonic_sec_counter ()
3586 - connection->last_activity)) )
3550 { 3587 {
3551 time_t timeout; 3588 MHD_connection_close_ (connection,
3552 timeout = connection->connection_timeout; 3589 MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
3553 if ( (0 != timeout) && 3590 request->in_idle = false;
3554 (timeout < (MHD_monotonic_sec_counter() - connection->last_activity)) ) 3591 return true;
3555 {
3556 MHD_connection_close_ (connection,
3557 MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
3558 request->in_idle = false;
3559 return true;
3560 }
3561 } 3592 }
3593 }
3562 connection_update_event_loop_info (connection); 3594 connection_update_event_loop_info (connection);
3563 ret = true; 3595 ret = true;
3564#ifdef EPOLL_SUPPORT 3596#ifdef EPOLL_SUPPORT
3565 if ( (! connection->suspended) && 3597 if ( (! connection->suspended) &&
3566 (MHD_ELS_EPOLL == daemon->event_loop_syscall) ) 3598 (MHD_ELS_EPOLL == daemon->event_loop_syscall) )
3567 { 3599 {
3568 ret = connection_epoll_update_ (connection); 3600 ret = connection_epoll_update_ (connection);
3569 } 3601 }
3570#endif /* EPOLL_SUPPORT */ 3602#endif /* EPOLL_SUPPORT */
3571 request->in_idle = false; 3603 request->in_idle = false;
3572 return ret; 3604 return ret;
@@ -3589,9 +3621,9 @@ MHD_request_handle_idle_ (struct MHD_Request *request)
3589// FIXME: rename connection->request? 3621// FIXME: rename connection->request?
3590int 3622int
3591MHD_connection_call_handlers_ (struct MHD_Connection *con, 3623MHD_connection_call_handlers_ (struct MHD_Connection *con,
3592 bool read_ready, 3624 bool read_ready,
3593 bool write_ready, 3625 bool write_ready,
3594 bool force_close) 3626 bool force_close)
3595{ 3627{
3596 struct MHD_Daemon *daemon = con->daemon; 3628 struct MHD_Daemon *daemon = con->daemon;
3597 int ret; 3629 int ret;
@@ -3604,38 +3636,38 @@ MHD_connection_call_handlers_ (struct MHD_Connection *con,
3604 read_ready = true; 3636 read_ready = true;
3605#endif /* HTTPS_SUPPORT */ 3637#endif /* HTTPS_SUPPORT */
3606 if (! force_close) 3638 if (! force_close)
3639 {
3640 if ( (MHD_EVENT_LOOP_INFO_READ ==
3641 con->request.event_loop_info) &&
3642 read_ready)
3607 { 3643 {
3608 if ( (MHD_EVENT_LOOP_INFO_READ == 3644 MHD_request_handle_read_ (&con->request);
3609 con->request.event_loop_info) && 3645 ret = MHD_request_handle_idle_ (&con->request);
3610 read_ready) 3646 states_info_processed = true;
3611 {
3612 MHD_request_handle_read_ (&con->request);
3613 ret = MHD_request_handle_idle_ (&con->request);
3614 states_info_processed = true;
3615 }
3616 /* No need to check value of 'ret' here as closed connection
3617 * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */
3618 if ( (MHD_EVENT_LOOP_INFO_WRITE ==
3619 con->request.event_loop_info) &&
3620 write_ready)
3621 {
3622 MHD_request_handle_write_ (&con->request);
3623 ret = MHD_request_handle_idle_ (&con->request);
3624 states_info_processed = true;
3625 }
3626 } 3647 }
3627 else 3648 /* No need to check value of 'ret' here as closed connection
3649 * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */
3650 if ( (MHD_EVENT_LOOP_INFO_WRITE ==
3651 con->request.event_loop_info) &&
3652 write_ready)
3628 { 3653 {
3629 MHD_connection_close_ (con, 3654 MHD_request_handle_write_ (&con->request);
3630 MHD_REQUEST_TERMINATED_WITH_ERROR); 3655 ret = MHD_request_handle_idle_ (&con->request);
3631 return MHD_request_handle_idle_ (&con->request); 3656 states_info_processed = true;
3632 } 3657 }
3658 }
3659 else
3660 {
3661 MHD_connection_close_ (con,
3662 MHD_REQUEST_TERMINATED_WITH_ERROR);
3663 return MHD_request_handle_idle_ (&con->request);
3664 }
3633 3665
3634 if (! states_info_processed) 3666 if (! states_info_processed)
3635 { /* Connection is not read or write ready, but external conditions 3667 { /* Connection is not read or write ready, but external conditions
3636 * may be changed and need to be processed. */ 3668 * may be changed and need to be processed. */
3637 ret = MHD_request_handle_idle_ (&con->request); 3669 ret = MHD_request_handle_idle_ (&con->request);
3638 } 3670 }
3639 /* Fast track for fast connections. */ 3671 /* Fast track for fast connections. */
3640 /* If full request was read by single read_handler() invocation 3672 /* If full request was read by single read_handler() invocation
3641 and headers were completely prepared by single MHD_request_handle_idle_() 3673 and headers were completely prepared by single MHD_request_handle_idle_()
@@ -3647,24 +3679,24 @@ MHD_connection_call_handlers_ (struct MHD_Connection *con,
3647 /* No need to check 'ret' as connection is always in 3679 /* No need to check 'ret' as connection is always in
3648 * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */ 3680 * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */
3649 else if (on_fasttrack && 3681 else if (on_fasttrack &&
3650 con->sk_nonblck) 3682 con->sk_nonblck)
3683 {
3684 if (MHD_REQUEST_HEADERS_SENDING == con->request.state)
3651 { 3685 {
3652 if (MHD_REQUEST_HEADERS_SENDING == con->request.state) 3686 MHD_request_handle_write_ (&con->request);
3653 { 3687 /* Always call 'MHD_request_handle_idle_()' after each read/write. */
3654 MHD_request_handle_write_ (&con->request); 3688 ret = MHD_request_handle_idle_ (&con->request);
3655 /* Always call 'MHD_request_handle_idle_()' after each read/write. */ 3689 }
3656 ret = MHD_request_handle_idle_ (&con->request); 3690 /* If all headers were sent by single write_handler() and
3657 } 3691 * response body is prepared by single MHD_request_handle_idle_()
3658 /* If all headers were sent by single write_handler() and 3692 * call - continue. */
3659 * response body is prepared by single MHD_request_handle_idle_() 3693 if ((MHD_REQUEST_NORMAL_BODY_READY == con->request.state) ||
3660 * call - continue. */ 3694 (MHD_REQUEST_CHUNKED_BODY_READY == con->request.state))
3661 if ((MHD_REQUEST_NORMAL_BODY_READY == con->request.state) || 3695 {
3662 (MHD_REQUEST_CHUNKED_BODY_READY == con->request.state)) 3696 MHD_request_handle_write_ (&con->request);
3663 { 3697 ret = MHD_request_handle_idle_ (&con->request);
3664 MHD_request_handle_write_ (&con->request);
3665 ret = MHD_request_handle_idle_ (&con->request);
3666 }
3667 } 3698 }
3699 }
3668 3700
3669 /* All connection's data and states are processed for this turn. 3701 /* All connection's data and states are processed for this turn.
3670 * If connection already has more data to be processed - use 3702 * If connection already has more data to be processed - use
@@ -3676,17 +3708,17 @@ MHD_connection_call_handlers_ (struct MHD_Connection *con,
3676 * without space in read buffer will be market as 'info block'. */ 3708 * without space in read buffer will be market as 'info block'. */
3677 if ( (! daemon->data_already_pending) && 3709 if ( (! daemon->data_already_pending) &&
3678 (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) ) 3710 (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) )
3679 { 3711 {
3680 if (MHD_EVENT_LOOP_INFO_BLOCK == 3712 if (MHD_EVENT_LOOP_INFO_BLOCK ==
3681 con->request.event_loop_info) 3713 con->request.event_loop_info)
3682 daemon->data_already_pending = true; 3714 daemon->data_already_pending = true;
3683#ifdef HTTPS_SUPPORT 3715#ifdef HTTPS_SUPPORT
3684 else if ( (con->tls_read_ready) && 3716 else if ( (con->tls_read_ready) &&
3685 (MHD_EVENT_LOOP_INFO_READ == 3717 (MHD_EVENT_LOOP_INFO_READ ==
3686 con->request.event_loop_info) ) 3718 con->request.event_loop_info) )
3687 daemon->data_already_pending = true; 3719 daemon->data_already_pending = true;
3688#endif /* HTTPS_SUPPORT */ 3720#endif /* HTTPS_SUPPORT */
3689 } 3721 }
3690 return ret; 3722 return ret;
3691} 3723}
3692 3724
diff --git a/src/lib/connection_call_handlers.h b/src/lib/connection_call_handlers.h
index 980e8064..6297bb9e 100644
--- a/src/lib/connection_call_handlers.h
+++ b/src/lib/connection_call_handlers.h
@@ -40,10 +40,10 @@
40 */ 40 */
41int 41int
42MHD_connection_call_handlers_ (struct MHD_Connection *con, 42MHD_connection_call_handlers_ (struct MHD_Connection *con,
43 bool read_ready, 43 bool read_ready,
44 bool write_ready, 44 bool write_ready,
45 bool force_close) 45 bool force_close)
46 MHD_NONNULL (1); 46MHD_NONNULL (1);
47 47
48 48
49/** 49/**
@@ -58,7 +58,7 @@ MHD_connection_call_handlers_ (struct MHD_Connection *con,
58 */ 58 */
59bool 59bool
60MHD_request_handle_idle_ (struct MHD_Request *request) 60MHD_request_handle_idle_ (struct MHD_Request *request)
61 MHD_NONNULL (1); 61MHD_NONNULL (1);
62
62 63
63
64#endif 64#endif
diff --git a/src/lib/connection_cleanup.c b/src/lib/connection_cleanup.c
index 8883213b..4f2cfb0f 100644
--- a/src/lib/connection_cleanup.c
+++ b/src/lib/connection_cleanup.c
@@ -49,7 +49,7 @@ connection_cleanup_upgraded (struct MHD_Connection *connection)
49 49
50 if (NULL != (tls = connection->daemon->tls_api)) 50 if (NULL != (tls = connection->daemon->tls_api))
51 (void) tls->shutdown_connection (tls->cls, 51 (void) tls->shutdown_connection (tls->cls,
52 connection->tls_cs); 52 connection->tls_cs);
53 } 53 }
54 if (MHD_INVALID_SOCKET != urh->mhd.socket) 54 if (MHD_INVALID_SOCKET != urh->mhd.socket)
55 MHD_socket_close_chk_ (urh->mhd.socket); 55 MHD_socket_close_chk_ (urh->mhd.socket);
@@ -65,7 +65,7 @@ connection_cleanup_upgraded (struct MHD_Connection *connection)
65/** 65/**
66 * Free resources associated with all closed connections. (destroy 66 * Free resources associated with all closed connections. (destroy
67 * responses, free buffers, etc.). All closed connections are kept in 67 * responses, free buffers, etc.). All closed connections are kept in
68 * the "cleanup" doubly-linked list. 68 * the "cleanup" doubly-linked list.
69 * 69 *
70 * @remark To be called only from thread that process daemon's 70 * @remark To be called only from thread that process daemon's
71 * select()/poll()/etc. 71 * select()/poll()/etc.
@@ -79,79 +79,79 @@ MHD_connection_cleanup_ (struct MHD_Daemon *daemon)
79 79
80 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 80 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
81 while (NULL != (pos = daemon->cleanup_tail)) 81 while (NULL != (pos = daemon->cleanup_tail))
82 { 82 {
83 DLL_remove (daemon->cleanup_head, 83 DLL_remove (daemon->cleanup_head,
84 daemon->cleanup_tail, 84 daemon->cleanup_tail,
85 pos); 85 pos);
86 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 86 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
87 87
88 if ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) && 88 if ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) &&
89 (! pos->thread_joined) && 89 (! pos->thread_joined) &&
90 (! MHD_join_thread_ (pos->pid.handle)) ) 90 (! MHD_join_thread_ (pos->pid.handle)) )
91 MHD_PANIC (_("Failed to join a thread\n")); 91 MHD_PANIC (_ ("Failed to join a thread\n"));
92#ifdef UPGRADE_SUPPORT 92#ifdef UPGRADE_SUPPORT
93 connection_cleanup_upgraded (pos); 93 connection_cleanup_upgraded (pos);
94#endif /* UPGRADE_SUPPORT */ 94#endif /* UPGRADE_SUPPORT */
95 MHD_pool_destroy (pos->pool); 95 MHD_pool_destroy (pos->pool);
96#ifdef HTTPS_SUPPORT 96#ifdef HTTPS_SUPPORT
97 { 97 {
98 struct MHD_TLS_Plugin *tls; 98 struct MHD_TLS_Plugin *tls;
99 99
100 if (NULL != (tls = daemon->tls_api)) 100 if (NULL != (tls = daemon->tls_api))
101 tls->teardown_connection (tls->cls, 101 tls->teardown_connection (tls->cls,
102 pos->tls_cs); 102 pos->tls_cs);
103 } 103 }
104#endif /* HTTPS_SUPPORT */ 104#endif /* HTTPS_SUPPORT */
105 105
106 /* clean up the connection */ 106 /* clean up the connection */
107 if (NULL != daemon->notify_connection_cb) 107 if (NULL != daemon->notify_connection_cb)
108 daemon->notify_connection_cb (daemon->notify_connection_cb_cls, 108 daemon->notify_connection_cb (daemon->notify_connection_cb_cls,
109 pos, 109 pos,
110 MHD_CONNECTION_NOTIFY_CLOSED); 110 MHD_CONNECTION_NOTIFY_CLOSED);
111 MHD_ip_limit_del (daemon, 111 MHD_ip_limit_del (daemon,
112 (const struct sockaddr *) &pos->addr, 112 (const struct sockaddr *) &pos->addr,
113 pos->addr_len); 113 pos->addr_len);
114#ifdef EPOLL_SUPPORT 114#ifdef EPOLL_SUPPORT
115 if (MHD_ELS_EPOLL == daemon->event_loop_syscall) 115 if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
116 { 116 {
117 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 117 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
118 { 118 {
119 EDLL_remove (daemon->eready_head, 119 EDLL_remove (daemon->eready_head,
120 daemon->eready_tail, 120 daemon->eready_tail,
121 pos); 121 pos);
122 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; 122 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
123 } 123 }
124 if ( (-1 != daemon->epoll_fd) && 124 if ( (-1 != daemon->epoll_fd) &&
125 (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) ) 125 (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
126 { 126 {
127 /* epoll documentation suggests that closing a FD 127 /* epoll documentation suggests that closing a FD
128 automatically removes it from the epoll set; however, 128 automatically removes it from the epoll set; however,
129 this is not true as if we fail to do manually remove it, 129 this is not true as if we fail to do manually remove it,
130 we are still seeing an event for this fd in epoll, 130 we are still seeing an event for this fd in epoll,
131 causing grief (use-after-free...) --- at least on my 131 causing grief (use-after-free...) --- at least on my
132 system. */ 132 system. */
133 if (0 != epoll_ctl (daemon->epoll_fd, 133 if (0 != epoll_ctl (daemon->epoll_fd,
134 EPOLL_CTL_DEL, 134 EPOLL_CTL_DEL,
135 pos->socket_fd, 135 pos->socket_fd,
136 NULL)) 136 NULL))
137 MHD_PANIC (_("Failed to remove FD from epoll set\n")); 137 MHD_PANIC (_ ("Failed to remove FD from epoll set\n"));
138 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; 138 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
139 } 139 }
140 } 140 }
141#endif 141#endif
142 if (NULL != pos->request.response) 142 if (NULL != pos->request.response)
143 { 143 {
144 MHD_response_queue_for_destroy (pos->request.response); 144 MHD_response_queue_for_destroy (pos->request.response);
145 pos->request.response = NULL; 145 pos->request.response = NULL;
146 }
147 if (MHD_INVALID_SOCKET != pos->socket_fd)
148 MHD_socket_close_chk_ (pos->socket_fd);
149 free (pos);
150
151 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
152 daemon->connections--;
153 daemon->at_limit = false;
154 } 146 }
147 if (MHD_INVALID_SOCKET != pos->socket_fd)
148 MHD_socket_close_chk_ (pos->socket_fd);
149 free (pos);
150
151 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
152 daemon->connections--;
153 daemon->at_limit = false;
154 }
155 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 155 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
156} 156}
157 157
diff --git a/src/lib/connection_cleanup.h b/src/lib/connection_cleanup.h
index 26fbebaf..c6beeeee 100644
--- a/src/lib/connection_cleanup.h
+++ b/src/lib/connection_cleanup.h
@@ -18,7 +18,7 @@
18*/ 18*/
19/** 19/**
20 * @file lib/connection_cleanup.h 20 * @file lib/connection_cleanup.h
21 * @brief functions to cleanup completed connection 21 * @brief functions to cleanup completed connection
22 * @author Christian Grothoff 22 * @author Christian Grothoff
23 */ 23 */
24#ifndef CONNECTION_CLEANUP_H 24#ifndef CONNECTION_CLEANUP_H
@@ -28,7 +28,7 @@
28/** 28/**
29 * Free resources associated with all closed connections. (destroy 29 * Free resources associated with all closed connections. (destroy
30 * responses, free buffers, etc.). All closed connections are kept in 30 * responses, free buffers, etc.). All closed connections are kept in
31 * the "cleanup" doubly-linked list. 31 * the "cleanup" doubly-linked list.
32 * 32 *
33 * @remark To be called only from thread that process daemon's 33 * @remark To be called only from thread that process daemon's
34 * select()/poll()/etc. 34 * select()/poll()/etc.
@@ -37,6 +37,6 @@
37 */ 37 */
38void 38void
39MHD_connection_cleanup_ (struct MHD_Daemon *daemon) 39MHD_connection_cleanup_ (struct MHD_Daemon *daemon)
40 MHD_NONNULL (1); 40MHD_NONNULL (1);
41 41
42#endif 42#endif
diff --git a/src/lib/connection_close.c b/src/lib/connection_close.c
index 945997db..3c872b0b 100644
--- a/src/lib/connection_close.c
+++ b/src/lib/connection_close.c
@@ -40,33 +40,33 @@ MHD_connection_mark_closed_ (struct MHD_Connection *connection)
40 connection->request.state = MHD_REQUEST_CLOSED; 40 connection->request.state = MHD_REQUEST_CLOSED;
41 connection->request.event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP; 41 connection->request.event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
42 if (! daemon->enable_turbo) 42 if (! daemon->enable_turbo)
43 { 43 {
44#ifdef HTTPS_SUPPORT 44#ifdef HTTPS_SUPPORT
45 struct MHD_TLS_Plugin *tls; 45 struct MHD_TLS_Plugin *tls;
46 46
47 /* For TLS connection use shutdown of TLS layer 47 /* For TLS connection use shutdown of TLS layer
48 * and do not shutdown TCP socket. This give more 48 * and do not shutdown TCP socket. This give more
49 * chances to send TLS closure data to remote side. 49 * chances to send TLS closure data to remote side.
50 * Closure of TLS layer will be interpreted by 50 * Closure of TLS layer will be interpreted by
51 * remote side as end of transmission. */ 51 * remote side as end of transmission. */
52 if (NULL != (tls = daemon->tls_api)) 52 if (NULL != (tls = daemon->tls_api))
53 { 53 {
54 if (MHD_YES != 54 if (MHD_YES !=
55 tls->shutdown_connection (tls->cls, 55 tls->shutdown_connection (tls->cls,
56 connection->tls_cs)) 56 connection->tls_cs))
57 { 57 {
58 (void) shutdown (connection->socket_fd, 58 (void) shutdown (connection->socket_fd,
59 SHUT_WR); 59 SHUT_WR);
60 /* FIXME: log errors */ 60 /* FIXME: log errors */
61 } 61 }
62 } 62 }
63 else /* Combined with next 'shutdown()'. */ 63 else /* Combined with next 'shutdown()'. */
64#endif /* HTTPS_SUPPORT */ 64#endif /* HTTPS_SUPPORT */
65 { 65 {
66 (void) shutdown (connection->socket_fd, 66 (void) shutdown (connection->socket_fd,
67 SHUT_WR); /* FIXME: log errors */ 67 SHUT_WR); /* FIXME: log errors */
68 }
69 } 68 }
69 }
70} 70}
71 71
72 72
@@ -90,14 +90,14 @@ MHD_connection_close_ (struct MHD_Connection *connection,
90 (void) rtc; // FIXME 90 (void) rtc; // FIXME
91 MHD_connection_mark_closed_ (connection); 91 MHD_connection_mark_closed_ (connection);
92 if (NULL != resp) 92 if (NULL != resp)
93 { 93 {
94 connection->request.response = NULL; 94 connection->request.response = NULL;
95 MHD_response_queue_for_destroy (resp); 95 MHD_response_queue_for_destroy (resp);
96 } 96 }
97 if (NULL != daemon->notify_connection_cb) 97 if (NULL != daemon->notify_connection_cb)
98 daemon->notify_connection_cb (daemon->notify_connection_cb_cls, 98 daemon->notify_connection_cb (daemon->notify_connection_cb_cls,
99 connection, 99 connection,
100 MHD_CONNECTION_NOTIFY_CLOSED); 100 MHD_CONNECTION_NOTIFY_CLOSED);
101} 101}
102 102
103/* end of connection_close.c */ 103/* end of connection_close.c */
diff --git a/src/lib/connection_close.h b/src/lib/connection_close.h
index 41f141d2..c8e159ee 100644
--- a/src/lib/connection_close.h
+++ b/src/lib/connection_close.h
@@ -35,7 +35,7 @@
35 */ 35 */
36void 36void
37MHD_connection_mark_closed_ (struct MHD_Connection *connection) 37MHD_connection_mark_closed_ (struct MHD_Connection *connection)
38 MHD_NONNULL (1); 38MHD_NONNULL (1);
39 39
40 40
41/** 41/**
@@ -51,6 +51,6 @@ MHD_connection_mark_closed_ (struct MHD_Connection *connection)
51void 51void
52MHD_connection_close_ (struct MHD_Connection *connection, 52MHD_connection_close_ (struct MHD_Connection *connection,
53 enum MHD_RequestTerminationCode rtc) 53 enum MHD_RequestTerminationCode rtc)
54 MHD_NONNULL (1); 54MHD_NONNULL (1);
55 55
56#endif 56#endif
diff --git a/src/lib/connection_finish_forward.c b/src/lib/connection_finish_forward.c
index 335a03bf..1ea9aa31 100644
--- a/src/lib/connection_finish_forward.c
+++ b/src/lib/connection_finish_forward.c
@@ -55,34 +55,34 @@ MHD_connection_finish_forward_ (struct MHD_Connection *connection)
55 EPOLL_CTL_DEL, 55 EPOLL_CTL_DEL,
56 connection->socket_fd, 56 connection->socket_fd,
57 NULL)) ) 57 NULL)) )
58 { 58 {
59 MHD_PANIC (_("Failed to remove FD from epoll set\n")); 59 MHD_PANIC (_ ("Failed to remove FD from epoll set\n"));
60 } 60 }
61 if (urh->in_eready_list) 61 if (urh->in_eready_list)
62 { 62 {
63 EDLL_remove (daemon->eready_urh_head, 63 EDLL_remove (daemon->eready_urh_head,
64 daemon->eready_urh_tail, 64 daemon->eready_urh_tail,
65 urh); 65 urh);
66 urh->in_eready_list = false; 66 urh->in_eready_list = false;
67 } 67 }
68#endif /* EPOLL_SUPPORT */ 68#endif /* EPOLL_SUPPORT */
69 if (MHD_INVALID_SOCKET != urh->mhd.socket) 69 if (MHD_INVALID_SOCKET != urh->mhd.socket)
70 { 70 {
71#if EPOLL_SUPPORT 71#if EPOLL_SUPPORT
72 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && 72 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
73 (0 != epoll_ctl (daemon->epoll_upgrade_fd, 73 (0 != epoll_ctl (daemon->epoll_upgrade_fd,
74 EPOLL_CTL_DEL, 74 EPOLL_CTL_DEL,
75 urh->mhd.socket, 75 urh->mhd.socket,
76 NULL)) ) 76 NULL)) )
77 { 77 {
78 MHD_PANIC (_("Failed to remove FD from epoll set\n")); 78 MHD_PANIC (_ ("Failed to remove FD from epoll set\n"));
79 }
80#endif /* EPOLL_SUPPORT */
81 /* Reflect remote disconnect to application by breaking
82 * socketpair connection. */
83 shutdown (urh->mhd.socket,
84 SHUT_RDWR);
85 } 79 }
80#endif /* EPOLL_SUPPORT */
81 /* Reflect remote disconnect to application by breaking
82 * socketpair connection. */
83 shutdown (urh->mhd.socket,
84 SHUT_RDWR);
85 }
86 /* Socketpair sockets will remain open as they will be 86 /* Socketpair sockets will remain open as they will be
87 * used with MHD_UPGRADE_ACTION_CLOSE. They will be 87 * used with MHD_UPGRADE_ACTION_CLOSE. They will be
88 * closed by MHD_cleanup_upgraded_connection_() during 88 * closed by MHD_cleanup_upgraded_connection_() during
diff --git a/src/lib/connection_finish_forward.h b/src/lib/connection_finish_forward.h
index c6c04f42..ebb77d12 100644
--- a/src/lib/connection_finish_forward.h
+++ b/src/lib/connection_finish_forward.h
@@ -39,6 +39,6 @@
39 */ 39 */
40void 40void
41MHD_connection_finish_forward_ (struct MHD_Connection *connection) 41MHD_connection_finish_forward_ (struct MHD_Connection *connection)
42 MHD_NONNULL (1); 42MHD_NONNULL (1);
43 43
44#endif 44#endif
diff --git a/src/lib/connection_info.c b/src/lib/connection_info.c
index 88055fa4..d83b34c5 100644
--- a/src/lib/connection_info.c
+++ b/src/lib/connection_info.c
@@ -42,13 +42,13 @@
42 */ 42 */
43enum MHD_Bool 43enum MHD_Bool
44MHD_connection_get_information_sz (struct MHD_Connection *connection, 44MHD_connection_get_information_sz (struct MHD_Connection *connection,
45 enum MHD_ConnectionInformationType info_type, 45 enum MHD_ConnectionInformationType info_type,
46 union MHD_ConnectionInformation *return_value, 46 union MHD_ConnectionInformation *return_value,
47 size_t return_value_size) 47 size_t return_value_size)
48{ 48{
49#define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \ 49#define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \
50 return MHD_NO 50 return MHD_NO
51 51
52 switch (info_type) 52 switch (info_type)
53 { 53 {
54#ifdef HTTPS_SUPPORT 54#ifdef HTTPS_SUPPORT
@@ -63,7 +63,7 @@ MHD_connection_get_information_sz (struct MHD_Connection *connection,
63 CHECK_SIZE (int); 63 CHECK_SIZE (int);
64 if (NULL == connection->tls_cs) 64 if (NULL == connection->tls_cs)
65 return MHD_NO; 65 return MHD_NO;
66 //return_value->protocol 66 // return_value->protocol
67 // = gnutls_protocol_get_version (connection->tls_session); 67 // = gnutls_protocol_get_version (connection->tls_session);
68 return MHD_NO; // FIXME: to be implemented 68 return MHD_NO; // FIXME: to be implemented
69 case MHD_CONNECTION_INFORMATION_GNUTLS_SESSION: 69 case MHD_CONNECTION_INFORMATION_GNUTLS_SESSION:
@@ -103,7 +103,7 @@ MHD_connection_get_information_sz (struct MHD_Connection *connection,
103 default: 103 default:
104 return MHD_NO; 104 return MHD_NO;
105 } 105 }
106 106
107#undef CHECK_SIZE 107#undef CHECK_SIZE
108} 108}
109 109
diff --git a/src/lib/connection_options.c b/src/lib/connection_options.c
index 00652161..ce31b315 100644
--- a/src/lib/connection_options.c
+++ b/src/lib/connection_options.c
@@ -35,44 +35,44 @@
35 */ 35 */
36void 36void
37MHD_connection_set_timeout (struct MHD_Connection *connection, 37MHD_connection_set_timeout (struct MHD_Connection *connection,
38 unsigned int timeout_s) 38 unsigned int timeout_s)
39{ 39{
40 struct MHD_Daemon *daemon = connection->daemon; 40 struct MHD_Daemon *daemon = connection->daemon;
41 41
42 connection->last_activity = MHD_monotonic_sec_counter(); 42 connection->last_activity = MHD_monotonic_sec_counter ();
43 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) 43 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
44 { 44 {
45 /* Simple case, no need to lock to update DLLs */ 45 /* Simple case, no need to lock to update DLLs */
46 connection->connection_timeout = (time_t) timeout_s; 46 connection->connection_timeout = (time_t) timeout_s;
47 return; 47 return;
48 } 48 }
49 49
50 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 50 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
51 if (! connection->suspended) 51 if (! connection->suspended)
52 { 52 {
53 if (connection->connection_timeout == 53 if (connection->connection_timeout ==
54 daemon->connection_default_timeout) 54 daemon->connection_default_timeout)
55 XDLL_remove (daemon->normal_timeout_head, 55 XDLL_remove (daemon->normal_timeout_head,
56 daemon->normal_timeout_tail, 56 daemon->normal_timeout_tail,
57 connection); 57 connection);
58 else 58 else
59 XDLL_remove (daemon->manual_timeout_head, 59 XDLL_remove (daemon->manual_timeout_head,
60 daemon->manual_timeout_tail, 60 daemon->manual_timeout_tail,
61 connection); 61 connection);
62 } 62 }
63 connection->connection_timeout = (time_t) timeout_s; 63 connection->connection_timeout = (time_t) timeout_s;
64 if (! connection->suspended) 64 if (! connection->suspended)
65 { 65 {
66 if (connection->connection_timeout == 66 if (connection->connection_timeout ==
67 daemon->connection_default_timeout) 67 daemon->connection_default_timeout)
68 XDLL_insert (daemon->normal_timeout_head, 68 XDLL_insert (daemon->normal_timeout_head,
69 daemon->normal_timeout_tail, 69 daemon->normal_timeout_tail,
70 connection); 70 connection);
71 else 71 else
72 XDLL_insert (daemon->manual_timeout_head, 72 XDLL_insert (daemon->manual_timeout_head,
73 daemon->manual_timeout_tail, 73 daemon->manual_timeout_tail,
74 connection); 74 connection);
75 } 75 }
76 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 76 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
77} 77}
78 78
@@ -95,7 +95,7 @@ MHD_update_last_activity_ (struct MHD_Connection *connection)
95 if (connection->suspended) 95 if (connection->suspended)
96 return; /* no activity on suspended connections */ 96 return; /* no activity on suspended connections */
97 97
98 connection->last_activity = MHD_monotonic_sec_counter(); 98 connection->last_activity = MHD_monotonic_sec_counter ();
99 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) 99 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
100 return; /* each connection has personal timeout */ 100 return; /* each connection has personal timeout */
101 101
@@ -106,11 +106,11 @@ MHD_update_last_activity_ (struct MHD_Connection *connection)
106 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 106 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
107 /* move connection to head of timeout list (by remove + add operation) */ 107 /* move connection to head of timeout list (by remove + add operation) */
108 XDLL_remove (daemon->normal_timeout_head, 108 XDLL_remove (daemon->normal_timeout_head,
109 daemon->normal_timeout_tail, 109 daemon->normal_timeout_tail,
110 connection); 110 connection);
111 XDLL_insert (daemon->normal_timeout_head, 111 XDLL_insert (daemon->normal_timeout_head,
112 daemon->normal_timeout_tail, 112 daemon->normal_timeout_tail,
113 connection); 113 connection);
114 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 114 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
115} 115}
116 116
diff --git a/src/lib/connection_update_last_activity.c b/src/lib/connection_update_last_activity.c
index 7253dc83..741da681 100644
--- a/src/lib/connection_update_last_activity.c
+++ b/src/lib/connection_update_last_activity.c
@@ -43,7 +43,7 @@ MHD_connection_update_last_activity_ (struct MHD_Connection *connection)
43 if (connection->suspended) 43 if (connection->suspended)
44 return; /* no activity on suspended connections */ 44 return; /* no activity on suspended connections */
45 45
46 connection->last_activity = MHD_monotonic_sec_counter(); 46 connection->last_activity = MHD_monotonic_sec_counter ();
47 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) 47 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
48 return; /* each connection has personal timeout */ 48 return; /* each connection has personal timeout */
49 49
@@ -53,13 +53,12 @@ MHD_connection_update_last_activity_ (struct MHD_Connection *connection)
53 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 53 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
54 /* move connection to head of timeout list (by remove + add operation) */ 54 /* move connection to head of timeout list (by remove + add operation) */
55 XDLL_remove (daemon->normal_timeout_head, 55 XDLL_remove (daemon->normal_timeout_head,
56 daemon->normal_timeout_tail, 56 daemon->normal_timeout_tail,
57 connection); 57 connection);
58 XDLL_insert (daemon->normal_timeout_head, 58 XDLL_insert (daemon->normal_timeout_head,
59 daemon->normal_timeout_tail, 59 daemon->normal_timeout_tail,
60 connection); 60 connection);
61 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 61 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
62} 62}
63 63
64/* end of connection_update_last_activity.c */ 64/* end of connection_update_last_activity.c */
65
diff --git a/src/lib/connection_update_last_activity.h b/src/lib/connection_update_last_activity.h
index 8383b6be..ee9f9975 100644
--- a/src/lib/connection_update_last_activity.h
+++ b/src/lib/connection_update_last_activity.h
@@ -35,6 +35,6 @@
35 */ 35 */
36void 36void
37MHD_connection_update_last_activity_ (struct MHD_Connection *connection) 37MHD_connection_update_last_activity_ (struct MHD_Connection *connection)
38 MHD_NONNULL (1); 38MHD_NONNULL (1);
39 39
40#endif 40#endif
diff --git a/src/lib/daemon_close_all_connections.c b/src/lib/daemon_close_all_connections.c
index d4b825da..1a777494 100644
--- a/src/lib/daemon_close_all_connections.c
+++ b/src/lib/daemon_close_all_connections.c
@@ -45,10 +45,10 @@ close_connection (struct MHD_Connection *pos)
45 struct MHD_Daemon *daemon = pos->daemon; 45 struct MHD_Daemon *daemon = pos->daemon;
46 46
47 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) 47 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
48 { 48 {
49 MHD_connection_mark_closed_ (pos); 49 MHD_connection_mark_closed_ (pos);
50 return; /* must let thread to do the rest */ 50 return; /* must let thread to do the rest */
51 } 51 }
52 MHD_connection_close_ (pos, 52 MHD_connection_close_ (pos,
53 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); 53 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN);
54 54
@@ -59,18 +59,18 @@ close_connection (struct MHD_Connection *pos)
59 if (pos->connection_timeout == 59 if (pos->connection_timeout ==
60 pos->daemon->connection_default_timeout) 60 pos->daemon->connection_default_timeout)
61 XDLL_remove (daemon->normal_timeout_head, 61 XDLL_remove (daemon->normal_timeout_head,
62 daemon->normal_timeout_tail, 62 daemon->normal_timeout_tail,
63 pos); 63 pos);
64 else 64 else
65 XDLL_remove (daemon->manual_timeout_head, 65 XDLL_remove (daemon->manual_timeout_head,
66 daemon->manual_timeout_tail, 66 daemon->manual_timeout_tail,
67 pos); 67 pos);
68 DLL_remove (daemon->connections_head, 68 DLL_remove (daemon->connections_head,
69 daemon->connections_tail, 69 daemon->connections_tail,
70 pos); 70 pos);
71 DLL_insert (daemon->cleanup_head, 71 DLL_insert (daemon->cleanup_head,
72 daemon->cleanup_tail, 72 daemon->cleanup_tail,
73 pos); 73 pos);
74 74
75 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 75 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
76} 76}
@@ -89,7 +89,8 @@ void
89MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) 89MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon)
90{ 90{
91 struct MHD_Connection *pos; 91 struct MHD_Connection *pos;
92 const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode); 92 const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION ==
93 daemon->threading_mode);
93#ifdef UPGRADE_SUPPORT 94#ifdef UPGRADE_SUPPORT
94 const bool upg_allowed = (! daemon->disallow_upgrade); 95 const bool upg_allowed = (! daemon->disallow_upgrade);
95#endif /* UPGRADE_SUPPORT */ 96#endif /* UPGRADE_SUPPORT */
@@ -103,16 +104,16 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon)
103 /* give upgraded HTTPS connections a chance to finish */ 104 /* give upgraded HTTPS connections a chance to finish */
104 /* 'daemon->urh_head' is not used in thread-per-connection mode. */ 105 /* 'daemon->urh_head' is not used in thread-per-connection mode. */
105 for (urh = daemon->urh_tail; NULL != urh; urh = urhn) 106 for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
106 { 107 {
107 urhn = urh->prev; 108 urhn = urh->prev;
108 /* call generic forwarding function for passing data 109 /* call generic forwarding function for passing data
109 with chance to detect that application is done. */ 110 with chance to detect that application is done. */
110 MHD_upgrade_response_handle_process_ (urh); 111 MHD_upgrade_response_handle_process_ (urh);
111 MHD_connection_finish_forward_ (urh->connection); 112 MHD_connection_finish_forward_ (urh->connection);
112 urh->clean_ready = true; 113 urh->clean_ready = true;
113 /* Resuming will move connection to cleanup list. */ 114 /* Resuming will move connection to cleanup list. */
114 MHD_request_resume (&urh->connection->request); 115 MHD_request_resume (&urh->connection->request);
115 } 116 }
116#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 117#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
117 118
118 /* Give suspended connections a chance to resume to avoid 119 /* Give suspended connections a chance to resume to avoid
@@ -120,89 +121,93 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon)
120 connections left in case of a tight race with a recently 121 connections left in case of a tight race with a recently
121 resumed connection. */ 122 resumed connection. */
122 if (! daemon->disallow_suspend_resume) 123 if (! daemon->disallow_suspend_resume)
123 { 124 {
124 daemon->resuming = true; /* Force check for pending resume. */ 125 daemon->resuming = true; /* Force check for pending resume. */
125 MHD_resume_suspended_connections_ (daemon); 126 MHD_resume_suspended_connections_ (daemon);
126 } 127 }
127 /* first, make sure all threads are aware of shutdown; need to 128 /* first, make sure all threads are aware of shutdown; need to
128 traverse DLLs in peace... */ 129 traverse DLLs in peace... */
129 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 130 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
130#ifdef UPGRADE_SUPPORT 131#ifdef UPGRADE_SUPPORT
131 if (upg_allowed) 132 if (upg_allowed)
132 { 133 {
133 struct MHD_Connection * susp; 134 struct MHD_Connection *susp;
134 135
135 susp = daemon->suspended_connections_tail; 136 susp = daemon->suspended_connections_tail;
136 while (NULL != susp) 137 while (NULL != susp)
137 { 138 {
138 if (NULL == susp->request.urh) /* "Upgraded" connection? */ 139 if (NULL == susp->request.urh) /* "Upgraded" connection? */
139 MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n")); 140 MHD_PANIC (_ (
141 "MHD_stop_daemon() called while we have suspended connections.\n"));
140#ifdef HTTPS_SUPPORT 142#ifdef HTTPS_SUPPORT
141 else if (used_tls && 143 else if (used_tls &&
142 used_thr_p_c && 144 used_thr_p_c &&
143 (! susp->request.urh->clean_ready) ) 145 (! susp->request.urh->clean_ready) )
144 shutdown (susp->request.urh->app.socket, 146 shutdown (susp->request.urh->app.socket,
145 SHUT_RDWR); /* Wake thread by shutdown of app socket. */ 147 SHUT_RDWR); /* Wake thread by shutdown of app socket. */
146#endif /* HTTPS_SUPPORT */ 148#endif /* HTTPS_SUPPORT */
147 else 149 else
148 { 150 {
149#ifdef HAVE_MESSAGES 151#ifdef HAVE_MESSAGES
150 if (! susp->request.urh->was_closed) 152 if (! susp->request.urh->was_closed)
151 MHD_DLOG (daemon, 153 MHD_DLOG (daemon,
152 MHD_SC_SHUTDOWN_WITH_OPEN_UPGRADED_CONNECTION, 154 MHD_SC_SHUTDOWN_WITH_OPEN_UPGRADED_CONNECTION,
153 _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); 155 _ (
156 "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
154#endif 157#endif
155 susp->request.urh->was_closed = true; 158 susp->request.urh->was_closed = true;
156 /* If thread-per-connection is used, connection's thread 159 /* If thread-per-connection is used, connection's thread
157 * may still processing "upgrade" (exiting). */ 160 * may still processing "upgrade" (exiting). */
158 if (! used_thr_p_c) 161 if (! used_thr_p_c)
159 MHD_connection_finish_forward_ (susp); 162 MHD_connection_finish_forward_ (susp);
160 /* Do not use MHD_resume_connection() as mutex is 163 /* Do not use MHD_resume_connection() as mutex is
161 * already locked. */ 164 * already locked. */
162 susp->resuming = true; 165 susp->resuming = true;
163 daemon->resuming = true; 166 daemon->resuming = true;
164 } 167 }
165 susp = susp->prev; 168 susp = susp->prev;
166 }
167 } 169 }
170 }
168 else /* This 'else' is combined with next 'if' */ 171 else /* This 'else' is combined with next 'if' */
169#endif /* UPGRADE_SUPPORT */ 172#endif /* UPGRADE_SUPPORT */
170 if (NULL != daemon->suspended_connections_head) 173 if (NULL != daemon->suspended_connections_head)
171 MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n")); 174 MHD_PANIC (_ (
175 "MHD_stop_daemon() called while we have suspended connections.\n"));
172 for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) 176 for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
173 { 177 {
174 shutdown (pos->socket_fd, 178 shutdown (pos->socket_fd,
175 SHUT_RDWR); 179 SHUT_RDWR);
176#if MHD_WINSOCK_SOCKETS 180#if MHD_WINSOCK_SOCKETS
177 if ( (used_thr_p_c) && 181 if ( (used_thr_p_c) &&
178 (MHD_ITC_IS_VALID_(daemon->itc)) && 182 (MHD_ITC_IS_VALID_ (daemon->itc)) &&
179 (! MHD_itc_activate_ (daemon->itc, 183 (! MHD_itc_activate_ (daemon->itc,
180 "e")) ) 184 "e")) )
181 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel")); 185 MHD_PANIC (_ (
186 "Failed to signal shutdown via inter-thread communication channel"));
182#endif 187#endif
183 } 188 }
184 189
185 /* now, collect per-connection threads */ 190 /* now, collect per-connection threads */
186 if (used_thr_p_c) 191 if (used_thr_p_c)
192 {
193 pos = daemon->connections_tail;
194 while (NULL != pos)
187 { 195 {
188 pos = daemon->connections_tail; 196 if (! pos->thread_joined)
189 while (NULL != pos)
190 { 197 {
191 if (! pos->thread_joined) 198 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
192 { 199 if (! MHD_join_thread_ (pos->pid.handle))
193 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 200 MHD_PANIC (_ ("Failed to join a thread\n"));
194 if (! MHD_join_thread_ (pos->pid.handle)) 201 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
195 MHD_PANIC (_("Failed to join a thread\n")); 202 pos->thread_joined = true;
196 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 203 /* The thread may have concurrently modified the DLL,
197 pos->thread_joined = true; 204 need to restart from the beginning */
198 /* The thread may have concurrently modified the DLL, 205 pos = daemon->connections_tail;
199 need to restart from the beginning */ 206 continue;
200 pos = daemon->connections_tail;
201 continue;
202 }
203 pos = pos->prev;
204 } 207 }
208 pos = pos->prev;
205 } 209 }
210 }
206 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 211 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
207 212
208#ifdef UPGRADE_SUPPORT 213#ifdef UPGRADE_SUPPORT
@@ -211,10 +216,10 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon)
211 /* "Upgraded" connections that were not closed explicitly by 216 /* "Upgraded" connections that were not closed explicitly by
212 * application should be moved to cleanup list too. */ 217 * application should be moved to cleanup list too. */
213 if (upg_allowed) 218 if (upg_allowed)
214 { 219 {
215 daemon->resuming = true; /* Force check for pending resume. */ 220 daemon->resuming = true; /* Force check for pending resume. */
216 MHD_resume_suspended_connections_ (daemon); 221 MHD_resume_suspended_connections_ (daemon);
217 } 222 }
218#endif /* UPGRADE_SUPPORT */ 223#endif /* UPGRADE_SUPPORT */
219 224
220 /* now that we're alone, move everyone to cleanup */ 225 /* now that we're alone, move everyone to cleanup */
@@ -222,7 +227,7 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon)
222 { 227 {
223 if ( (used_thr_p_c) && 228 if ( (used_thr_p_c) &&
224 (! pos->thread_joined) ) 229 (! pos->thread_joined) )
225 MHD_PANIC (_("Failed to join a thread\n")); 230 MHD_PANIC (_ ("Failed to join a thread\n"));
226 close_connection (pos); 231 close_connection (pos);
227 } 232 }
228 MHD_connection_cleanup_ (daemon); 233 MHD_connection_cleanup_ (daemon);
diff --git a/src/lib/daemon_close_all_connections.h b/src/lib/daemon_close_all_connections.h
index 340b0d47..2716f9ba 100644
--- a/src/lib/daemon_close_all_connections.h
+++ b/src/lib/daemon_close_all_connections.h
@@ -37,6 +37,6 @@
37 */ 37 */
38void 38void
39MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) 39MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon)
40 MHD_NONNULL (1); 40MHD_NONNULL (1);
41 41
42#endif 42#endif
diff --git a/src/lib/daemon_create.c b/src/lib/daemon_create.c
index a2173d88..cd3d0ec4 100644
--- a/src/lib/daemon_create.c
+++ b/src/lib/daemon_create.c
@@ -38,16 +38,16 @@
38 */ 38 */
39static void 39static void
40file_logger (void *cls, 40file_logger (void *cls,
41 enum MHD_StatusCode sc, 41 enum MHD_StatusCode sc,
42 const char *fm, 42 const char *fm,
43 va_list ap) 43 va_list ap)
44{ 44{
45 FILE *f = cls; 45 FILE *f = cls;
46 46
47 (void) sc; 47 (void) sc;
48 (void) vfprintf (f, 48 (void) vfprintf (f,
49 fm, 49 fm,
50 ap); 50 ap);
51} 51}
52 52
53 53
@@ -84,16 +84,16 @@ unescape_wrapper (void *cls,
84 */ 84 */
85struct MHD_Daemon * 85struct MHD_Daemon *
86MHD_daemon_create (MHD_RequestCallback cb, 86MHD_daemon_create (MHD_RequestCallback cb,
87 void *cb_cls) 87 void *cb_cls)
88{ 88{
89 struct MHD_Daemon *daemon; 89 struct MHD_Daemon *daemon;
90 90
91 MHD_check_global_init_(); 91 MHD_check_global_init_ ();
92 if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon)))) 92 if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon))))
93 return NULL; 93 return NULL;
94 memset (daemon, 94 memset (daemon,
95 0, 95 0,
96 sizeof (struct MHD_Daemon)); 96 sizeof (struct MHD_Daemon));
97#ifdef EPOLL_SUPPORT 97#ifdef EPOLL_SUPPORT
98 daemon->epoll_itc_marker = "itc_marker"; 98 daemon->epoll_itc_marker = "itc_marker";
99#endif 99#endif
@@ -107,29 +107,29 @@ MHD_daemon_create (MHD_RequestCallback cb,
107#if ENABLE_DAUTH 107#if ENABLE_DAUTH
108 daemon->digest_nc_length = DIGEST_NC_LENGTH_DEFAULT; 108 daemon->digest_nc_length = DIGEST_NC_LENGTH_DEFAULT;
109#endif 109#endif
110 daemon->listen_backlog = LISTEN_BACKLOG_DEFAULT; 110 daemon->listen_backlog = LISTEN_BACKLOG_DEFAULT;
111 daemon->fo_queue_length = FO_QUEUE_LENGTH_DEFAULT; 111 daemon->fo_queue_length = FO_QUEUE_LENGTH_DEFAULT;
112 daemon->listen_socket = MHD_INVALID_SOCKET; 112 daemon->listen_socket = MHD_INVALID_SOCKET;
113 113
114 if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex)) 114 if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
115 { 115 {
116 free (daemon); 116 free (daemon);
117 return NULL; 117 return NULL;
118 } 118 }
119 if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex)) 119 if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex))
120 { 120 {
121 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex); 121 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
122 free (daemon); 122 free (daemon);
123 return NULL; 123 return NULL;
124 } 124 }
125#ifdef DAUTH_SUPPORT 125#ifdef DAUTH_SUPPORT
126 if (! MHD_mutex_init_ (&daemon->nnc_lock)) 126 if (! MHD_mutex_init_ (&daemon->nnc_lock))
127 { 127 {
128 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex); 128 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
129 (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex); 129 (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
130 free (daemon); 130 free (daemon);
131 return NULL; 131 return NULL;
132 } 132 }
133#endif 133#endif
134 return daemon; 134 return daemon;
135} 135}
diff --git a/src/lib/daemon_destroy.c b/src/lib/daemon_destroy.c
index b4f34d16..a76c2d6b 100644
--- a/src/lib/daemon_destroy.c
+++ b/src/lib/daemon_destroy.c
@@ -46,35 +46,36 @@ stop_workers (struct MHD_Daemon *daemon)
46 fd = daemon->listen_socket; 46 fd = daemon->listen_socket;
47 /* Let workers shutdown in parallel. */ 47 /* Let workers shutdown in parallel. */
48 for (i = 0; i < daemon->worker_pool_size; i++) 48 for (i = 0; i < daemon->worker_pool_size; i++)
49 {
50 daemon->worker_pool[i].shutdown = true;
51 if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc))
49 { 52 {
50 daemon->worker_pool[i].shutdown = true; 53 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc,
51 if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc)) 54 "e"))
52 { 55 MHD_PANIC (_ (
53 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, 56 "Failed to signal shutdown via inter-thread communication channel."));
54 "e"))
55 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel."));
56 }
57 else
58 {
59 /* Better hope shutdown() works... */
60 mhd_assert (MHD_INVALID_SOCKET != fd);
61 }
62 } 57 }
63#ifdef HAVE_LISTEN_SHUTDOWN 58 else
64 if (MHD_INVALID_SOCKET != fd)
65 { 59 {
66 (void) shutdown (fd, 60 /* Better hope shutdown() works... */
67 SHUT_RDWR); 61 mhd_assert (MHD_INVALID_SOCKET != fd);
68 } 62 }
63 }
64#ifdef HAVE_LISTEN_SHUTDOWN
65 if (MHD_INVALID_SOCKET != fd)
66 {
67 (void) shutdown (fd,
68 SHUT_RDWR);
69 }
69#endif /* HAVE_LISTEN_SHUTDOWN */ 70#endif /* HAVE_LISTEN_SHUTDOWN */
70 for (i = 0; i < daemon->worker_pool_size; ++i) 71 for (i = 0; i < daemon->worker_pool_size; ++i)
71 { 72 {
72 MHD_daemon_destroy (&daemon->worker_pool[i]); 73 MHD_daemon_destroy (&daemon->worker_pool[i]);
73 } 74 }
74 free (daemon->worker_pool); 75 free (daemon->worker_pool);
75 daemon->worker_pool = NULL; 76 daemon->worker_pool = NULL;
76 /* FIXME: does this still hold? */ 77 /* FIXME: does this still hold? */
77 mhd_assert (MHD_ITC_IS_INVALID_(daemon->itc)); 78 mhd_assert (MHD_ITC_IS_INVALID_ (daemon->itc));
78#ifdef EPOLL_SUPPORT 79#ifdef EPOLL_SUPPORT
79 mhd_assert (-1 == daemon->epoll_fd); 80 mhd_assert (-1 == daemon->epoll_fd);
80#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 81#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
@@ -104,65 +105,66 @@ MHD_daemon_destroy (struct MHD_Daemon *daemon)
104 /* FIXME: convert from here to microhttpd2-style API! */ 105 /* FIXME: convert from here to microhttpd2-style API! */
105 106
106 if (NULL != daemon->worker_pool) 107 if (NULL != daemon->worker_pool)
107 { /* Master daemon with worker pool. */ 108 { /* Master daemon with worker pool. */
108 stop_workers (daemon); 109 stop_workers (daemon);
109 } 110 }
110 else 111 else
112 {
113 mhd_assert (0 == daemon->worker_pool_size);
114 /* Worker daemon or single-thread daemon. */
115 if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode)
111 { 116 {
112 mhd_assert (0 == daemon->worker_pool_size); 117 /* Worker daemon or single daemon with internal thread(s). */
113 /* Worker daemon or single-thread daemon. */ 118 /* Separate thread(s) is used for polling sockets. */
114 if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) 119 if (MHD_ITC_IS_VALID_ (daemon->itc))
115 { 120 {
116 /* Worker daemon or single daemon with internal thread(s). */ 121 if (! MHD_itc_activate_ (daemon->itc,
117 /* Separate thread(s) is used for polling sockets. */ 122 "e"))
118 if (MHD_ITC_IS_VALID_(daemon->itc)) 123 MHD_PANIC (_ (
119 { 124 "Failed to signal shutdown via inter-thread communication channel"));
120 if (! MHD_itc_activate_ (daemon->itc, 125 }
121 "e"))
122 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
123 }
124 else
125 {
126#ifdef HAVE_LISTEN_SHUTDOWN
127 if (MHD_INVALID_SOCKET != fd)
128 {
129 if (NULL == daemon->master)
130 (void) shutdown (fd,
131 SHUT_RDWR);
132 }
133 else
134#endif /* HAVE_LISTEN_SHUTDOWN */
135 mhd_assert (false); /* Should never happen */
136 }
137
138 if (! MHD_join_thread_ (daemon->pid.handle))
139 {
140 MHD_PANIC (_("Failed to join a thread\n"));
141 }
142 /* close_all_connections() was called in daemon thread. */
143 }
144 else 126 else
127 {
128#ifdef HAVE_LISTEN_SHUTDOWN
129 if (MHD_INVALID_SOCKET != fd)
145 { 130 {
146 /* No internal threads are used for polling sockets 131 if (NULL == daemon->master)
147 (external event loop) */ 132 (void) shutdown (fd,
148 MHD_daemon_close_all_connections_ (daemon); 133 SHUT_RDWR);
149 } 134 }
150 if (MHD_ITC_IS_VALID_ (daemon->itc)) 135 else
151 MHD_itc_destroy_chk_ (daemon->itc); 136#endif /* HAVE_LISTEN_SHUTDOWN */
137 mhd_assert (false); /* Should never happen */
138 }
139
140 if (! MHD_join_thread_ (daemon->pid.handle))
141 {
142 MHD_PANIC (_ ("Failed to join a thread\n"));
143 }
144 /* close_all_connections() was called in daemon thread. */
145 }
146 else
147 {
148 /* No internal threads are used for polling sockets
149 (external event loop) */
150 MHD_daemon_close_all_connections_ (daemon);
151 }
152 if (MHD_ITC_IS_VALID_ (daemon->itc))
153 MHD_itc_destroy_chk_ (daemon->itc);
152 154
153#ifdef EPOLL_SUPPORT 155#ifdef EPOLL_SUPPORT
154 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && 156 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
155 (-1 != daemon->epoll_fd) ) 157 (-1 != daemon->epoll_fd) )
156 MHD_socket_close_chk_ (daemon->epoll_fd); 158 MHD_socket_close_chk_ (daemon->epoll_fd);
157#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 159#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
158 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && 160 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
159 (-1 != daemon->epoll_upgrade_fd) ) 161 (-1 != daemon->epoll_upgrade_fd) )
160 MHD_socket_close_chk_ (daemon->epoll_upgrade_fd); 162 MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
161#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 163#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
162#endif /* EPOLL_SUPPORT */ 164#endif /* EPOLL_SUPPORT */
163 165
164 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 166 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
165 } 167 }
166 168
167 if (NULL != daemon->master) 169 if (NULL != daemon->master)
168 return; 170 return;
@@ -175,18 +177,18 @@ MHD_daemon_destroy (struct MHD_Daemon *daemon)
175 /* TLS clean up */ 177 /* TLS clean up */
176#ifdef HTTPS_SUPPORT 178#ifdef HTTPS_SUPPORT
177 if (NULL != daemon->tls_api) 179 if (NULL != daemon->tls_api)
178 { 180 {
179#if FIXME_TLS_API 181#if FIXME_TLS_API
180 if (daemon->have_dhparams) 182 if (daemon->have_dhparams)
181 { 183 {
182 gnutls_dh_params_deinit (daemon->https_mem_dhparams); 184 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
183 daemon->have_dhparams = false; 185 daemon->have_dhparams = false;
184 }
185 gnutls_priority_deinit (daemon->priority_cache);
186 if (daemon->x509_cred)
187 gnutls_certificate_free_credentials (daemon->x509_cred);
188#endif
189 } 186 }
187 gnutls_priority_deinit (daemon->priority_cache);
188 if (daemon->x509_cred)
189 gnutls_certificate_free_credentials (daemon->x509_cred);
190#endif
191 }
190#endif /* HTTPS_SUPPORT */ 192#endif /* HTTPS_SUPPORT */
191 193
192#ifdef DAUTH_SUPPORT 194#ifdef DAUTH_SUPPORT
diff --git a/src/lib/daemon_epoll.c b/src/lib/daemon_epoll.c
index 4bed148f..b25ba9a7 100644
--- a/src/lib/daemon_epoll.c
+++ b/src/lib/daemon_epoll.c
@@ -53,9 +53,9 @@
53 * 'false' otherwise 53 * 'false' otherwise
54 */ 54 */
55static bool 55static bool
56is_urh_ready (struct MHD_UpgradeResponseHandle * const urh) 56is_urh_ready (struct MHD_UpgradeResponseHandle *const urh)
57{ 57{
58 const struct MHD_Connection * const connection = urh->connection; 58 const struct MHD_Connection *const connection = urh->connection;
59 59
60 if ( (0 == urh->in_buffer_size) && 60 if ( (0 == urh->in_buffer_size) &&
61 (0 == urh->out_buffer_size) && 61 (0 == urh->out_buffer_size) &&
@@ -80,7 +80,7 @@ is_urh_ready (struct MHD_UpgradeResponseHandle * const urh)
80 return true; 80 return true;
81 81
82 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && 82 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
83 (urh->in_buffer_used > 0) ) 83 (urh->in_buffer_used > 0) )
84 return true; 84 return true;
85 85
86 return false; 86 return false;
@@ -103,99 +103,99 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
103{ 103{
104 struct epoll_event events[MAX_EVENTS]; 104 struct epoll_event events[MAX_EVENTS];
105 int num_events; 105 int num_events;
106 struct MHD_UpgradeResponseHandle * pos; 106 struct MHD_UpgradeResponseHandle *pos;
107 struct MHD_UpgradeResponseHandle * prev; 107 struct MHD_UpgradeResponseHandle *prev;
108 108
109 num_events = MAX_EVENTS; 109 num_events = MAX_EVENTS;
110 while (MAX_EVENTS == num_events) 110 while (MAX_EVENTS == num_events)
111 {
112 unsigned int i;
113
114 /* update event masks */
115 num_events = epoll_wait (daemon->epoll_upgrade_fd,
116 events,
117 MAX_EVENTS,
118 0);
119 if (-1 == num_events)
111 { 120 {
112 unsigned int i; 121 const int err = MHD_socket_get_error_ ();
113 122 if (MHD_SCKT_ERR_IS_EINTR_ (err))
114 /* update event masks */ 123 return MHD_SC_OK;
115 num_events = epoll_wait (daemon->epoll_upgrade_fd,
116 events,
117 MAX_EVENTS,
118 0);
119 if (-1 == num_events)
120 {
121 const int err = MHD_socket_get_error_ ();
122 if (MHD_SCKT_ERR_IS_EINTR_ (err))
123 return MHD_SC_OK;
124#ifdef HAVE_MESSAGES 124#ifdef HAVE_MESSAGES
125 MHD_DLOG (daemon, 125 MHD_DLOG (daemon,
126 MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR, 126 MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR,
127 _("Call to epoll_wait failed: %s\n"), 127 _ ("Call to epoll_wait failed: %s\n"),
128 MHD_socket_strerr_ (err)); 128 MHD_socket_strerr_ (err));
129#endif 129#endif
130 return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR; 130 return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR;
131 } 131 }
132 for (i = 0; i < (unsigned int) num_events; i++) 132 for (i = 0; i < (unsigned int) num_events; i++)
133 { 133 {
134 struct UpgradeEpollHandle * const ueh = events[i].data.ptr; 134 struct UpgradeEpollHandle *const ueh = events[i].data.ptr;
135 struct MHD_UpgradeResponseHandle * const urh = ueh->urh; 135 struct MHD_UpgradeResponseHandle *const urh = ueh->urh;
136 bool new_err_state = false; 136 bool new_err_state = false;
137 137
138 if (urh->clean_ready) 138 if (urh->clean_ready)
139 continue; 139 continue;
140 140
141 /* Update ueh state based on what is ready according to epoll() */ 141 /* Update ueh state based on what is ready according to epoll() */
142 if (0 != (events[i].events & EPOLLIN)) 142 if (0 != (events[i].events & EPOLLIN))
143 ueh->celi |= MHD_EPOLL_STATE_READ_READY; 143 ueh->celi |= MHD_EPOLL_STATE_READ_READY;
144 if (0 != (events[i].events & EPOLLOUT)) 144 if (0 != (events[i].events & EPOLLOUT))
145 ueh->celi |= MHD_EPOLL_STATE_WRITE_READY; 145 ueh->celi |= MHD_EPOLL_STATE_WRITE_READY;
146 if (0 != (events[i].events & EPOLLHUP)) 146 if (0 != (events[i].events & EPOLLHUP))
147 ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; 147 ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
148 148
149 if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) && 149 if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) &&
150 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) ) 150 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
151 { 151 {
152 /* Process new error state only one time 152 /* Process new error state only one time
153 * and avoid continuously marking this connection 153 * and avoid continuously marking this connection
154 * as 'ready'. */ 154 * as 'ready'. */
155 ueh->celi |= MHD_EPOLL_STATE_ERROR; 155 ueh->celi |= MHD_EPOLL_STATE_ERROR;
156 new_err_state = true; 156 new_err_state = true;
157 } 157 }
158 158
159 if (! urh->in_eready_list) 159 if (! urh->in_eready_list)
160 { 160 {
161 if (new_err_state || 161 if (new_err_state ||
162 is_urh_ready(urh)) 162 is_urh_ready (urh))
163 { 163 {
164 EDLL_insert (daemon->eready_urh_head, 164 EDLL_insert (daemon->eready_urh_head,
165 daemon->eready_urh_tail, 165 daemon->eready_urh_tail,
166 urh); 166 urh);
167 urh->in_eready_list = true; 167 urh->in_eready_list = true;
168 }
169 }
170 } 168 }
169 }
171 } 170 }
171 }
172 prev = daemon->eready_urh_tail; 172 prev = daemon->eready_urh_tail;
173 while (NULL != (pos = prev)) 173 while (NULL != (pos = prev))
174 {
175 prev = pos->prevE;
176 MHD_upgrade_response_handle_process_ (pos);
177 if (! is_urh_ready (pos))
174 { 178 {
175 prev = pos->prevE; 179 EDLL_remove (daemon->eready_urh_head,
176 MHD_upgrade_response_handle_process_ (pos); 180 daemon->eready_urh_tail,
177 if (! is_urh_ready(pos)) 181 pos);
178 { 182 pos->in_eready_list = false;
179 EDLL_remove (daemon->eready_urh_head, 183 }
180 daemon->eready_urh_tail, 184 /* Finished forwarding? */
181 pos); 185 if ( (0 == pos->in_buffer_size) &&
182 pos->in_eready_list = false; 186 (0 == pos->out_buffer_size) &&
183 } 187 (0 == pos->in_buffer_used) &&
184 /* Finished forwarding? */ 188 (0 == pos->out_buffer_used) )
185 if ( (0 == pos->in_buffer_size) && 189 {
186 (0 == pos->out_buffer_size) && 190 MHD_connection_finish_forward_ (pos->connection);
187 (0 == pos->in_buffer_used) && 191 pos->clean_ready = true;
188 (0 == pos->out_buffer_used) ) 192 /* If 'pos->was_closed' already was set to true, connection
189 { 193 * will be moved immediately to cleanup list. Otherwise
190 MHD_connection_finish_forward_ (pos->connection); 194 * connection will stay in suspended list until 'pos' will
191 pos->clean_ready = true; 195 * be marked with 'was_closed' by application. */
192 /* If 'pos->was_closed' already was set to true, connection 196 MHD_request_resume (&pos->connection->request);
193 * will be moved immediately to cleanup list. Otherwise
194 * connection will stay in suspended list until 'pos' will
195 * be marked with 'was_closed' by application. */
196 MHD_request_resume (&pos->connection->request);
197 }
198 } 197 }
198 }
199 199
200 return MHD_SC_OK; 200 return MHD_SC_OK;
201} 201}
@@ -212,10 +212,10 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
212 */ 212 */
213enum MHD_StatusCode 213enum MHD_StatusCode
214MHD_daemon_epoll_ (struct MHD_Daemon *daemon, 214MHD_daemon_epoll_ (struct MHD_Daemon *daemon,
215 bool may_block) 215 bool may_block)
216{ 216{
217#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 217#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
218 static const char * const upgrade_marker = "upgrade_ptr"; 218 static const char *const upgrade_marker = "upgrade_ptr";
219#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 219#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
220 struct MHD_Connection *pos; 220 struct MHD_Connection *pos;
221 struct MHD_Connection *prev; 221 struct MHD_Connection *prev;
@@ -239,24 +239,24 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon,
239 (daemon->connections < daemon->global_connection_limit) && 239 (daemon->connections < daemon->global_connection_limit) &&
240 (! daemon->listen_socket_in_epoll) && 240 (! daemon->listen_socket_in_epoll) &&
241 (! daemon->at_limit) ) 241 (! daemon->at_limit) )
242 {
243 event.events = EPOLLIN;
244 event.data.ptr = daemon;
245 if (0 != epoll_ctl (daemon->epoll_fd,
246 EPOLL_CTL_ADD,
247 ls,
248 &event))
242 { 249 {
243 event.events = EPOLLIN;
244 event.data.ptr = daemon;
245 if (0 != epoll_ctl (daemon->epoll_fd,
246 EPOLL_CTL_ADD,
247 ls,
248 &event))
249 {
250#ifdef HAVE_MESSAGES 250#ifdef HAVE_MESSAGES
251 MHD_DLOG (daemon, 251 MHD_DLOG (daemon,
252 MHD_SC_EPOLL_CTL_ADD_FAILED, 252 MHD_SC_EPOLL_CTL_ADD_FAILED,
253 _("Call to epoll_ctl failed: %s\n"), 253 _ ("Call to epoll_ctl failed: %s\n"),
254 MHD_socket_last_strerr_ ()); 254 MHD_socket_last_strerr_ ());
255#endif 255#endif
256 return MHD_SC_EPOLL_CTL_ADD_FAILED; 256 return MHD_SC_EPOLL_CTL_ADD_FAILED;
257 }
258 daemon->listen_socket_in_epoll = true;
259 } 257 }
258 daemon->listen_socket_in_epoll = true;
259 }
260 if ( (daemon->was_quiesced) && 260 if ( (daemon->was_quiesced) &&
261 (daemon->listen_socket_in_epoll) ) 261 (daemon->listen_socket_in_epoll) )
262 { 262 {
@@ -271,58 +271,58 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon,
271#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 271#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
272 if ( (! daemon->upgrade_fd_in_epoll) && 272 if ( (! daemon->upgrade_fd_in_epoll) &&
273 (-1 != daemon->epoll_upgrade_fd) ) 273 (-1 != daemon->epoll_upgrade_fd) )
274 {
275 event.events = EPOLLIN | EPOLLOUT;
276 event.data.ptr = (void *) upgrade_marker;
277 if (0 != epoll_ctl (daemon->epoll_fd,
278 EPOLL_CTL_ADD,
279 daemon->epoll_upgrade_fd,
280 &event))
274 { 281 {
275 event.events = EPOLLIN | EPOLLOUT;
276 event.data.ptr = (void *) upgrade_marker;
277 if (0 != epoll_ctl (daemon->epoll_fd,
278 EPOLL_CTL_ADD,
279 daemon->epoll_upgrade_fd,
280 &event))
281 {
282#ifdef HAVE_MESSAGES 282#ifdef HAVE_MESSAGES
283 MHD_DLOG (daemon, 283 MHD_DLOG (daemon,
284 MHD_SC_EPOLL_CTL_ADD_FAILED, 284 MHD_SC_EPOLL_CTL_ADD_FAILED,
285 _("Call to epoll_ctl failed: %s\n"), 285 _ ("Call to epoll_ctl failed: %s\n"),
286 MHD_socket_last_strerr_ ()); 286 MHD_socket_last_strerr_ ());
287#endif 287#endif
288 return MHD_SC_EPOLL_CTL_ADD_FAILED; 288 return MHD_SC_EPOLL_CTL_ADD_FAILED;
289 }
290 daemon->upgrade_fd_in_epoll = true;
291 } 289 }
290 daemon->upgrade_fd_in_epoll = true;
291 }
292#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 292#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
293 if ( (daemon->listen_socket_in_epoll) && 293 if ( (daemon->listen_socket_in_epoll) &&
294 ( (daemon->connections == daemon->global_connection_limit) || 294 ( (daemon->connections == daemon->global_connection_limit) ||
295 (daemon->at_limit) || 295 (daemon->at_limit) ||
296 (daemon->was_quiesced) ) ) 296 (daemon->was_quiesced) ) )
297 { 297 {
298 /* we're at the connection limit, disable listen socket 298 /* we're at the connection limit, disable listen socket
299 for event loop for now */ 299 for event loop for now */
300 if (0 != epoll_ctl (daemon->epoll_fd, 300 if (0 != epoll_ctl (daemon->epoll_fd,
301 EPOLL_CTL_DEL, 301 EPOLL_CTL_DEL,
302 ls, 302 ls,
303 NULL)) 303 NULL))
304 MHD_PANIC (_("Failed to remove listen FD from epoll set\n")); 304 MHD_PANIC (_ ("Failed to remove listen FD from epoll set\n"));
305 daemon->listen_socket_in_epoll = false; 305 daemon->listen_socket_in_epoll = false;
306 } 306 }
307 307
308 if ( (! daemon->disallow_suspend_resume) && 308 if ( (! daemon->disallow_suspend_resume) &&
309 (MHD_resume_suspended_connections_ (daemon)) ) 309 (MHD_resume_suspended_connections_ (daemon)) )
310 may_block = false; 310 may_block = false;
311 311
312 if (may_block) 312 if (may_block)
313 {
314 if (MHD_SC_OK == /* FIXME: distinguish between NO_TIMEOUT and errors */
315 MHD_daemon_get_timeout (daemon,
316 &timeout_ll))
313 { 317 {
314 if (MHD_SC_OK == /* FIXME: distinguish between NO_TIMEOUT and errors */ 318 if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
315 MHD_daemon_get_timeout (daemon, 319 timeout_ms = INT_MAX;
316 &timeout_ll))
317 {
318 if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
319 timeout_ms = INT_MAX;
320 else
321 timeout_ms = (int) timeout_ll;
322 }
323 else 320 else
324 timeout_ms = -1; 321 timeout_ms = (int) timeout_ll;
325 } 322 }
323 else
324 timeout_ms = -1;
325 }
326 else 326 else
327 timeout_ms = 0; 327 timeout_ms = 0;
328 328
@@ -337,113 +337,114 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon,
337 than unfair behavior... */ 337 than unfair behavior... */
338 num_events = MAX_EVENTS; 338 num_events = MAX_EVENTS;
339 while (MAX_EVENTS == num_events) 339 while (MAX_EVENTS == num_events)
340 {
341 /* update event masks */
342 num_events = epoll_wait (daemon->epoll_fd,
343 events,
344 MAX_EVENTS,
345 timeout_ms);
346 if (-1 == num_events)
340 { 347 {
341 /* update event masks */ 348 const int err = MHD_socket_get_error_ ();
342 num_events = epoll_wait (daemon->epoll_fd, 349 if (MHD_SCKT_ERR_IS_EINTR_ (err))
343 events, 350 return MHD_SC_OK;
344 MAX_EVENTS,
345 timeout_ms);
346 if (-1 == num_events)
347 {
348 const int err = MHD_socket_get_error_ ();
349 if (MHD_SCKT_ERR_IS_EINTR_ (err))
350 return MHD_SC_OK;
351#ifdef HAVE_MESSAGES 351#ifdef HAVE_MESSAGES
352 MHD_DLOG (daemon, 352 MHD_DLOG (daemon,
353 MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR, 353 MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR,
354 _("Call to epoll_wait failed: %s\n"), 354 _ ("Call to epoll_wait failed: %s\n"),
355 MHD_socket_strerr_ (err)); 355 MHD_socket_strerr_ (err));
356#endif 356#endif
357 return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR; 357 return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR;
358 } 358 }
359 for (i=0;i<(unsigned int) num_events;i++) 359 for (i = 0; i<(unsigned int) num_events; i++)
360 { 360 {
361 /* First, check for the values of `ptr` that would indicate 361 /* First, check for the values of `ptr` that would indicate
362 that this event is not about a normal connection. */ 362 that this event is not about a normal connection. */
363 if (NULL == events[i].data.ptr) 363 if (NULL == events[i].data.ptr)
364 continue; /* shutdown signal! */ 364 continue; /* shutdown signal! */
365#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 365#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
366 if (upgrade_marker == events[i].data.ptr) 366 if (upgrade_marker == events[i].data.ptr)
367 { 367 {
368 /* activity on an upgraded connection, we process 368 /* activity on an upgraded connection, we process
369 those in a separate epoll() */ 369 those in a separate epoll() */
370 run_upgraded = true; 370 run_upgraded = true;
371 continue; 371 continue;
372 } 372 }
373#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 373#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
374 if (daemon->epoll_itc_marker == events[i].data.ptr) 374 if (daemon->epoll_itc_marker == events[i].data.ptr)
375 { 375 {
376 /* It's OK to clear ITC here as all external 376 /* It's OK to clear ITC here as all external
377 conditions will be processed later. */ 377 conditions will be processed later. */
378 MHD_itc_clear_ (daemon->itc); 378 MHD_itc_clear_ (daemon->itc);
379 continue; 379 continue;
380 } 380 }
381 if (daemon == events[i].data.ptr) 381 if (daemon == events[i].data.ptr)
382 { 382 {
383 /* Check for error conditions on listen socket. */ 383 /* Check for error conditions on listen socket. */
384 /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */ 384 /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */
385 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP))) 385 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
386 { 386 {
387 unsigned int series_length = 0; 387 unsigned int series_length = 0;
388 /* Run 'accept' until it fails or daemon at limit of connections. 388 /* Run 'accept' until it fails or daemon at limit of connections.
389 * Do not accept more then 10 connections at once. The rest will 389 * Do not accept more then 10 connections at once. The rest will
390 * be accepted on next turn (level trigger is used for listen 390 * be accepted on next turn (level trigger is used for listen
391 * socket). */ 391 * socket). */
392 while ( (MHD_SC_OK == 392 while ( (MHD_SC_OK ==
393 MHD_accept_connection_ (daemon)) && 393 MHD_accept_connection_ (daemon)) &&
394 (series_length < 10) && 394 (series_length < 10) &&
395 (daemon->connections < daemon->global_connection_limit) && 395 (daemon->connections < daemon->global_connection_limit) &&
396 (! daemon->at_limit) ) 396 (! daemon->at_limit) )
397 series_length++; 397 series_length++;
398 } 398 }
399 continue; 399 continue;
400 } 400 }
401 /* this is an event relating to a 'normal' connection, 401 /* this is an event relating to a 'normal' connection,
402 remember the event and if appropriate mark the 402 remember the event and if appropriate mark the
403 connection as 'eready'. */ 403 connection as 'eready'. */
404 pos = events[i].data.ptr; 404 pos = events[i].data.ptr;
405 /* normal processing: update read/write data */ 405 /* normal processing: update read/write data */
406 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))) 406 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
407 { 407 {
408 pos->epoll_state |= MHD_EPOLL_STATE_ERROR; 408 pos->epoll_state |= MHD_EPOLL_STATE_ERROR;
409 if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 409 if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
410 { 410 {
411 EDLL_insert (daemon->eready_head, 411 EDLL_insert (daemon->eready_head,
412 daemon->eready_tail, 412 daemon->eready_tail,
413 pos); 413 pos);
414 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; 414 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
415 } 415 }
416 } 416 }
417 else 417 else
418 { 418 {
419 if (0 != (events[i].events & EPOLLIN)) 419 if (0 != (events[i].events & EPOLLIN))
420 { 420 {
421 pos->epoll_state |= MHD_EPOLL_STATE_READ_READY; 421 pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
422 if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info) || 422 if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info) ||
423 (pos->request.read_buffer_size > pos->request.read_buffer_offset) ) && 423 (pos->request.read_buffer_size >
424 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) 424 pos->request.read_buffer_offset) ) &&
425 { 425 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
426 EDLL_insert (daemon->eready_head, 426 {
427 daemon->eready_tail, 427 EDLL_insert (daemon->eready_head,
428 pos); 428 daemon->eready_tail,
429 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; 429 pos);
430 } 430 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
431 } 431 }
432 if (0 != (events[i].events & EPOLLOUT)) 432 }
433 { 433 if (0 != (events[i].events & EPOLLOUT))
434 pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY; 434 {
435 if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info) && 435 pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
436 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) 436 if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info) &&
437 { 437 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
438 EDLL_insert (daemon->eready_head, 438 {
439 daemon->eready_tail, 439 EDLL_insert (daemon->eready_head,
440 pos); 440 daemon->eready_tail,
441 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; 441 pos);
442 } 442 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
443 } 443 }
444 }
445 } 444 }
445 }
446 } 446 }
447 }
447 448
448#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 449#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
449 if (run_upgraded) 450 if (run_upgraded)
@@ -453,28 +454,32 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon,
453 /* process events for connections */ 454 /* process events for connections */
454 prev = daemon->eready_tail; 455 prev = daemon->eready_tail;
455 while (NULL != (pos = prev)) 456 while (NULL != (pos = prev))
457 {
458 prev = pos->prevE;
459 MHD_connection_call_handlers_ (pos,
460 0 != (pos->epoll_state
461 & MHD_EPOLL_STATE_READ_READY),
462 0 != (pos->epoll_state
463 & MHD_EPOLL_STATE_WRITE_READY),
464 0 != (pos->epoll_state
465 & MHD_EPOLL_STATE_ERROR));
466 if (MHD_EPOLL_STATE_IN_EREADY_EDLL ==
467 (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED
468 | MHD_EPOLL_STATE_IN_EREADY_EDLL)))
456 { 469 {
457 prev = pos->prevE; 470 if ( ((MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info) &&
458 MHD_connection_call_handlers_ (pos, 471 (0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ||
459 0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY), 472 ((MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info) &&
460 0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY), 473 (0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ) ||
461 0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR)); 474 (MHD_EVENT_LOOP_INFO_CLEANUP == pos->request.event_loop_info) )
462 if (MHD_EPOLL_STATE_IN_EREADY_EDLL == 475 {
463 (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED | MHD_EPOLL_STATE_IN_EREADY_EDLL))) 476 EDLL_remove (daemon->eready_head,
464 { 477 daemon->eready_tail,
465 if ( (MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info && 478 pos);
466 0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY) ) || 479 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
467 (MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info && 480 }
468 0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY) ) ||
469 MHD_EVENT_LOOP_INFO_CLEANUP == pos->request.event_loop_info)
470 {
471 EDLL_remove (daemon->eready_head,
472 daemon->eready_tail,
473 pos);
474 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
475 }
476 }
477 } 481 }
482 }
478 483
479 /* Finally, handle timed-out connections; we need to do this here 484 /* Finally, handle timed-out connections; we need to do this here
480 as the epoll mechanism won't call the 'MHD_request_handle_idle_()' on everything, 485 as the epoll mechanism won't call the 'MHD_request_handle_idle_()' on everything,
@@ -486,22 +491,22 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon,
486 do not bother to sort that (presumably very short) list. */ 491 do not bother to sort that (presumably very short) list. */
487 prev = daemon->manual_timeout_tail; 492 prev = daemon->manual_timeout_tail;
488 while (NULL != (pos = prev)) 493 while (NULL != (pos = prev))
489 { 494 {
490 prev = pos->prevX; 495 prev = pos->prevX;
491 MHD_request_handle_idle_ (&pos->request); 496 MHD_request_handle_idle_ (&pos->request);
492 } 497 }
493 /* Connections with the default timeout are sorted by prepending 498 /* Connections with the default timeout are sorted by prepending
494 them to the head of the list whenever we touch the connection; 499 them to the head of the list whenever we touch the connection;
495 thus it suffices to iterate from the tail until the first 500 thus it suffices to iterate from the tail until the first
496 connection is NOT timed out */ 501 connection is NOT timed out */
497 prev = daemon->normal_timeout_tail; 502 prev = daemon->normal_timeout_tail;
498 while (NULL != (pos = prev)) 503 while (NULL != (pos = prev))
499 { 504 {
500 prev = pos->prevX; 505 prev = pos->prevX;
501 MHD_request_handle_idle_ (&pos->request); 506 MHD_request_handle_idle_ (&pos->request);
502 if (MHD_REQUEST_CLOSED != pos->request.state) 507 if (MHD_REQUEST_CLOSED != pos->request.state)
503 break; /* sorted by timeout, no need to visit the rest! */ 508 break; /* sorted by timeout, no need to visit the rest! */
504 } 509 }
505 return MHD_SC_OK; 510 return MHD_SC_OK;
506} 511}
507#endif 512#endif
diff --git a/src/lib/daemon_epoll.h b/src/lib/daemon_epoll.h
index 50452d8d..37d0e423 100644
--- a/src/lib/daemon_epoll.h
+++ b/src/lib/daemon_epoll.h
@@ -38,8 +38,8 @@
38 */ 38 */
39enum MHD_StatusCode 39enum MHD_StatusCode
40MHD_daemon_epoll_ (struct MHD_Daemon *daemon, 40MHD_daemon_epoll_ (struct MHD_Daemon *daemon,
41 bool may_block) 41 bool may_block)
42 MHD_NONNULL (1); 42MHD_NONNULL (1);
43 43
44#endif 44#endif
45 45
diff --git a/src/lib/daemon_get_timeout.c b/src/lib/daemon_get_timeout.c
index fcf3ecbc..604c52e2 100644
--- a/src/lib/daemon_get_timeout.c
+++ b/src/lib/daemon_get_timeout.c
@@ -46,7 +46,7 @@
46 */ 46 */
47enum MHD_StatusCode 47enum MHD_StatusCode
48MHD_daemon_get_timeout (struct MHD_Daemon *daemon, 48MHD_daemon_get_timeout (struct MHD_Daemon *daemon,
49 MHD_UNSIGNED_LONG_LONG *timeout) 49 MHD_UNSIGNED_LONG_LONG *timeout)
50{ 50{
51 time_t earliest_deadline; 51 time_t earliest_deadline;
52 time_t now; 52 time_t now;
@@ -54,71 +54,71 @@ MHD_daemon_get_timeout (struct MHD_Daemon *daemon,
54 bool have_timeout; 54 bool have_timeout;
55 55
56 if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) 56 if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode)
57 { 57 {
58#ifdef HAVE_MESSAGES 58#ifdef HAVE_MESSAGES
59 MHD_DLOG (daemon, 59 MHD_DLOG (daemon,
60 MHD_SC_CONFIGURATION_MISMATCH_FOR_GET_TIMEOUT, 60 MHD_SC_CONFIGURATION_MISMATCH_FOR_GET_TIMEOUT,
61 _("Illegal call to MHD_get_timeout\n")); 61 _ ("Illegal call to MHD_get_timeout\n"));
62#endif 62#endif
63 return MHD_SC_CONFIGURATION_MISSMATCH_FOR_GET_TIMEOUT; 63 return MHD_SC_CONFIGURATION_MISSMATCH_FOR_GET_TIMEOUT;
64 } 64 }
65 65
66 if (daemon->data_already_pending) 66 if (daemon->data_already_pending)
67 { 67 {
68 /* Some data already waiting to be processed. */ 68 /* Some data already waiting to be processed. */
69 *timeout = 0; 69 *timeout = 0;
70 return MHD_SC_OK; 70 return MHD_SC_OK;
71 } 71 }
72 72
73#ifdef EPOLL_SUPPORT 73#ifdef EPOLL_SUPPORT
74 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && 74 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
75 ((NULL != daemon->eready_head) 75 ((NULL != daemon->eready_head)
76#if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) 76#if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
77 || (NULL != daemon->eready_urh_head) 77 || (NULL != daemon->eready_urh_head)
78#endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */ 78#endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */
79 ) ) 79 ) )
80 { 80 {
81 /* Some connection(s) already have some data pending. */ 81 /* Some connection(s) already have some data pending. */
82 *timeout = 0; 82 *timeout = 0;
83 return MHD_SC_OK; 83 return MHD_SC_OK;
84 } 84 }
85#endif /* EPOLL_SUPPORT */ 85#endif /* EPOLL_SUPPORT */
86 86
87 have_timeout = false; 87 have_timeout = false;
88 earliest_deadline = 0; /* avoid compiler warnings */ 88 earliest_deadline = 0; /* avoid compiler warnings */
89 for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX) 89 for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX)
90 {
91 if (0 != pos->connection_timeout)
90 { 92 {
91 if (0 != pos->connection_timeout) 93 if ( (! have_timeout) ||
92 { 94 (earliest_deadline - pos->last_activity > pos->connection_timeout) )
93 if ( (! have_timeout) || 95 earliest_deadline = pos->last_activity + pos->connection_timeout;
94 (earliest_deadline - pos->last_activity > pos->connection_timeout) ) 96 have_timeout = true;
95 earliest_deadline = pos->last_activity + pos->connection_timeout;
96 have_timeout = true;
97 }
98 } 97 }
98 }
99 /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */ 99 /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */
100 pos = daemon->normal_timeout_tail; 100 pos = daemon->normal_timeout_tail;
101 if ( (NULL != pos) && 101 if ( (NULL != pos) &&
102 (0 != pos->connection_timeout) ) 102 (0 != pos->connection_timeout) )
103 { 103 {
104 if ( (! have_timeout) || 104 if ( (! have_timeout) ||
105 (earliest_deadline - pos->connection_timeout > pos->last_activity) ) 105 (earliest_deadline - pos->connection_timeout > pos->last_activity) )
106 earliest_deadline = pos->last_activity + pos->connection_timeout; 106 earliest_deadline = pos->last_activity + pos->connection_timeout;
107 have_timeout = true; 107 have_timeout = true;
108 } 108 }
109 109
110 if (! have_timeout) 110 if (! have_timeout)
111 return MHD_SC_NO_TIMEOUT; 111 return MHD_SC_NO_TIMEOUT;
112 now = MHD_monotonic_sec_counter(); 112 now = MHD_monotonic_sec_counter ();
113 if (earliest_deadline < now) 113 if (earliest_deadline < now)
114 *timeout = 0; 114 *timeout = 0;
115 else 115 else
116 { 116 {
117 const time_t second_left = earliest_deadline - now; 117 const time_t second_left = earliest_deadline - now;
118 if (second_left > ULLONG_MAX / 1000) /* Ignore compiler warning: 'second_left' is always positive. */ 118 if (second_left > ULLONG_MAX / 1000) /* Ignore compiler warning: 'second_left' is always positive. */
119 *timeout = ULLONG_MAX; 119 *timeout = ULLONG_MAX;
120 else 120 else
121 *timeout = 1000LL * second_left; 121 *timeout = 1000LL * second_left;
122 } 122 }
123 return MHD_SC_OK; 123 return MHD_SC_OK;
124} 124}
diff --git a/src/lib/daemon_info.c b/src/lib/daemon_info.c
index b0c5ec14..d32f244b 100644
--- a/src/lib/daemon_info.c
+++ b/src/lib/daemon_info.c
@@ -43,62 +43,62 @@
43 */ 43 */
44enum MHD_Bool 44enum MHD_Bool
45MHD_daemon_get_information_sz (struct MHD_Daemon *daemon, 45MHD_daemon_get_information_sz (struct MHD_Daemon *daemon,
46 enum MHD_DaemonInformationType info_type, 46 enum MHD_DaemonInformationType info_type,
47 union MHD_DaemonInformation *return_value, 47 union MHD_DaemonInformation *return_value,
48 size_t return_value_size) 48 size_t return_value_size)
49{ 49{
50#define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \ 50#define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \
51 return MHD_NO 51 return MHD_NO
52 52
53 switch (info_type) 53 switch (info_type)
54 { 54 {
55 case MHD_DAEMON_INFORMATION_LISTEN_SOCKET: 55 case MHD_DAEMON_INFORMATION_LISTEN_SOCKET:
56 CHECK_SIZE (MHD_socket); 56 CHECK_SIZE (MHD_socket);
57 return_value->listen_socket 57 return_value->listen_socket
58 = daemon->listen_socket; 58 = daemon->listen_socket;
59 return MHD_YES; 59 return MHD_YES;
60#ifdef EPOLL_SUPPORT 60#ifdef EPOLL_SUPPORT
61 case MHD_DAEMON_INFORMATION_EPOLL_FD: 61 case MHD_DAEMON_INFORMATION_EPOLL_FD:
62 CHECK_SIZE (int); 62 CHECK_SIZE (int);
63 // FIXME: maybe return MHD_NO if we are not using EPOLL? 63 // FIXME: maybe return MHD_NO if we are not using EPOLL?
64 return_value->epoll_fd = daemon->epoll_fd; 64 return_value->epoll_fd = daemon->epoll_fd;
65 return MHD_YES; 65 return MHD_YES;
66#endif 66#endif
67 case MHD_DAEMON_INFORMATION_CURRENT_CONNECTIONS: 67 case MHD_DAEMON_INFORMATION_CURRENT_CONNECTIONS:
68 CHECK_SIZE (unsigned int); 68 CHECK_SIZE (unsigned int);
69 if (MHD_TM_EXTERNAL_EVENT_LOOP == daemon->threading_mode) 69 if (MHD_TM_EXTERNAL_EVENT_LOOP == daemon->threading_mode)
70 { 70 {
71 /* Assumes that MHD_run() in not called in other thread 71 /* Assumes that MHD_run() in not called in other thread
72 (of the application) at the same time. */ 72 (of the application) at the same time. */
73 MHD_connection_cleanup_ (daemon); 73 MHD_connection_cleanup_ (daemon);
74 return_value->num_connections 74 return_value->num_connections
75 = daemon->connections; 75 = daemon->connections;
76 }
77 else if (daemon->worker_pool)
78 {
79 unsigned int i;
80 /* Collect the connection information stored in the workers. */
81 return_value->num_connections = 0;
82 for (i = 0; i < daemon->worker_pool_size; i++)
83 {
84 /* FIXME: next line is thread-safe only if read is atomic. */
85 return_value->num_connections
86 += daemon->worker_pool[i].connections;
87 }
88 }
89 else
90 return_value->num_connections
91 = daemon->connections;
92 return MHD_YES;
93 case MHD_DAEMON_INFORMATION_BIND_PORT:
94 CHECK_SIZE (uint16_t);
95 // FIXME: return MHD_NO if port is not known/UNIX?
96 return_value->port = daemon->listen_port;
97 return MHD_YES;
98 default:
99 return MHD_NO;
100 } 76 }
101 77 else if (daemon->worker_pool)
78 {
79 unsigned int i;
80 /* Collect the connection information stored in the workers. */
81 return_value->num_connections = 0;
82 for (i = 0; i < daemon->worker_pool_size; i++)
83 {
84 /* FIXME: next line is thread-safe only if read is atomic. */
85 return_value->num_connections
86 += daemon->worker_pool[i].connections;
87 }
88 }
89 else
90 return_value->num_connections
91 = daemon->connections;
92 return MHD_YES;
93 case MHD_DAEMON_INFORMATION_BIND_PORT:
94 CHECK_SIZE (uint16_t);
95 // FIXME: return MHD_NO if port is not known/UNIX?
96 return_value->port = daemon->listen_port;
97 return MHD_YES;
98 default:
99 return MHD_NO;
100 }
101
102#undef CHECK_SIZE 102#undef CHECK_SIZE
103} 103}
104 104
diff --git a/src/lib/daemon_ip_limit.c b/src/lib/daemon_ip_limit.c
index 4a131c92..21550265 100644
--- a/src/lib/daemon_ip_limit.c
+++ b/src/lib/daemon_ip_limit.c
@@ -89,7 +89,7 @@ get_master (struct MHD_Daemon *daemon)
89static void 89static void
90MHD_ip_count_lock (struct MHD_Daemon *daemon) 90MHD_ip_count_lock (struct MHD_Daemon *daemon)
91{ 91{
92 MHD_mutex_lock_chk_(&daemon->per_ip_connection_mutex); 92 MHD_mutex_lock_chk_ (&daemon->per_ip_connection_mutex);
93} 93}
94 94
95 95
@@ -101,7 +101,7 @@ MHD_ip_count_lock (struct MHD_Daemon *daemon)
101static void 101static void
102MHD_ip_count_unlock (struct MHD_Daemon *daemon) 102MHD_ip_count_unlock (struct MHD_Daemon *daemon)
103{ 103{
104 MHD_mutex_unlock_chk_(&daemon->per_ip_connection_mutex); 104 MHD_mutex_unlock_chk_ (&daemon->per_ip_connection_mutex);
105} 105}
106 106
107 107
@@ -135,37 +135,37 @@ MHD_ip_addr_compare (const void *a1,
135 */ 135 */
136static int 136static int
137MHD_ip_addr_to_key (const struct sockaddr *addr, 137MHD_ip_addr_to_key (const struct sockaddr *addr,
138 socklen_t addrlen, 138 socklen_t addrlen,
139 struct MHD_IPCount *key) 139 struct MHD_IPCount *key)
140{ 140{
141 memset(key, 141 memset (key,
142 0, 142 0,
143 sizeof(*key)); 143 sizeof(*key));
144 144
145 /* IPv4 addresses */ 145 /* IPv4 addresses */
146 if (sizeof (struct sockaddr_in) == addrlen) 146 if (sizeof (struct sockaddr_in) == addrlen)
147 { 147 {
148 const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr; 148 const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr;
149 149
150 key->family = AF_INET; 150 key->family = AF_INET;
151 memcpy (&key->addr.ipv4, 151 memcpy (&key->addr.ipv4,
152 &addr4->sin_addr, 152 &addr4->sin_addr,
153 sizeof(addr4->sin_addr)); 153 sizeof(addr4->sin_addr));
154 return MHD_YES; 154 return MHD_YES;
155 } 155 }
156 156
157#if HAVE_INET6 157#if HAVE_INET6
158 /* IPv6 addresses */ 158 /* IPv6 addresses */
159 if (sizeof (struct sockaddr_in6) == addrlen) 159 if (sizeof (struct sockaddr_in6) == addrlen)
160 { 160 {
161 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr; 161 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr;
162 162
163 key->family = AF_INET6; 163 key->family = AF_INET6;
164 memcpy (&key->addr.ipv6, 164 memcpy (&key->addr.ipv6,
165 &addr6->sin6_addr, 165 &addr6->sin6_addr,
166 sizeof(addr6->sin6_addr)); 166 sizeof(addr6->sin6_addr));
167 return MHD_YES; 167 return MHD_YES;
168 } 168 }
169#endif 169#endif
170 170
171 /* Some other address */ 171 /* Some other address */
@@ -186,8 +186,8 @@ MHD_ip_addr_to_key (const struct sockaddr *addr,
186 */ 186 */
187int 187int
188MHD_ip_limit_add (struct MHD_Daemon *daemon, 188MHD_ip_limit_add (struct MHD_Daemon *daemon,
189 const struct sockaddr *addr, 189 const struct sockaddr *addr,
190 socklen_t addrlen) 190 socklen_t addrlen)
191{ 191{
192 struct MHD_IPCount *key; 192 struct MHD_IPCount *key;
193 void **nodep; 193 void **nodep;
@@ -206,31 +206,31 @@ MHD_ip_limit_add (struct MHD_Daemon *daemon,
206 if (MHD_NO == MHD_ip_addr_to_key (addr, 206 if (MHD_NO == MHD_ip_addr_to_key (addr,
207 addrlen, 207 addrlen,
208 key)) 208 key))
209 { 209 {
210 /* Allow unhandled address types through */ 210 /* Allow unhandled address types through */
211 free (key); 211 free (key);
212 return MHD_YES; 212 return MHD_YES;
213 } 213 }
214 MHD_ip_count_lock (daemon); 214 MHD_ip_count_lock (daemon);
215 215
216 /* Search for the IP address */ 216 /* Search for the IP address */
217 if (NULL == (nodep = tsearch (key, 217 if (NULL == (nodep = tsearch (key,
218 &daemon->per_ip_connection_count, 218 &daemon->per_ip_connection_count,
219 &MHD_ip_addr_compare))) 219 &MHD_ip_addr_compare)))
220 { 220 {
221#ifdef HAVE_MESSAGES 221#ifdef HAVE_MESSAGES
222 MHD_DLOG (daemon, 222 MHD_DLOG (daemon,
223 MHD_SC_IP_COUNTER_FAILURE, 223 MHD_SC_IP_COUNTER_FAILURE,
224 _("Failed to add IP connection count node\n")); 224 _ ("Failed to add IP connection count node\n"));
225#endif 225#endif
226 MHD_ip_count_unlock (daemon); 226 MHD_ip_count_unlock (daemon);
227 free (key); 227 free (key);
228 return MHD_NO; 228 return MHD_NO;
229 } 229 }
230 node = *nodep; 230 node = *nodep;
231 /* If we got an existing node back, free the one we created */ 231 /* If we got an existing node back, free the one we created */
232 if (node != key) 232 if (node != key)
233 free(key); 233 free (key);
234 key = (struct MHD_IPCount *) node; 234 key = (struct MHD_IPCount *) node;
235 /* Test if there is room for another connection; if so, 235 /* Test if there is room for another connection; if so,
236 * increment count */ 236 * increment count */
@@ -253,8 +253,8 @@ MHD_ip_limit_add (struct MHD_Daemon *daemon,
253 */ 253 */
254void 254void
255MHD_ip_limit_del (struct MHD_Daemon *daemon, 255MHD_ip_limit_del (struct MHD_Daemon *daemon,
256 const struct sockaddr *addr, 256 const struct sockaddr *addr,
257 socklen_t addrlen) 257 socklen_t addrlen)
258{ 258{
259 struct MHD_IPCount search_key; 259 struct MHD_IPCount search_key;
260 struct MHD_IPCount *found_key; 260 struct MHD_IPCount *found_key;
@@ -274,27 +274,27 @@ MHD_ip_limit_del (struct MHD_Daemon *daemon,
274 274
275 /* Search for the IP address */ 275 /* Search for the IP address */
276 if (NULL == (nodep = tfind (&search_key, 276 if (NULL == (nodep = tfind (&search_key,
277 &daemon->per_ip_connection_count, 277 &daemon->per_ip_connection_count,
278 &MHD_ip_addr_compare))) 278 &MHD_ip_addr_compare)))
279 { 279 {
280 /* Something's wrong if we couldn't find an IP address 280 /* Something's wrong if we couldn't find an IP address
281 * that was previously added */ 281 * that was previously added */
282 MHD_PANIC (_("Failed to find previously-added IP address\n")); 282 MHD_PANIC (_ ("Failed to find previously-added IP address\n"));
283 } 283 }
284 found_key = (struct MHD_IPCount *) *nodep; 284 found_key = (struct MHD_IPCount *) *nodep;
285 /* Validate existing count for IP address */ 285 /* Validate existing count for IP address */
286 if (0 == found_key->count) 286 if (0 == found_key->count)
287 { 287 {
288 MHD_PANIC (_("Previously-added IP address had counter of zero\n")); 288 MHD_PANIC (_ ("Previously-added IP address had counter of zero\n"));
289 } 289 }
290 /* Remove the node entirely if count reduces to 0 */ 290 /* Remove the node entirely if count reduces to 0 */
291 if (0 == --found_key->count) 291 if (0 == --found_key->count)
292 { 292 {
293 tdelete (found_key, 293 tdelete (found_key,
294 &daemon->per_ip_connection_count, 294 &daemon->per_ip_connection_count,
295 &MHD_ip_addr_compare); 295 &MHD_ip_addr_compare);
296 free (found_key); 296 free (found_key);
297 } 297 }
298 298
299 MHD_ip_count_unlock (daemon); 299 MHD_ip_count_unlock (daemon);
300} 300}
diff --git a/src/lib/daemon_ip_limit.h b/src/lib/daemon_ip_limit.h
index 5f22db05..9c587825 100644
--- a/src/lib/daemon_ip_limit.h
+++ b/src/lib/daemon_ip_limit.h
@@ -38,9 +38,9 @@
38 */ 38 */
39int 39int
40MHD_ip_limit_add (struct MHD_Daemon *daemon, 40MHD_ip_limit_add (struct MHD_Daemon *daemon,
41 const struct sockaddr *addr, 41 const struct sockaddr *addr,
42 socklen_t addrlen) 42 socklen_t addrlen)
43 MHD_NONNULL (1,2); 43MHD_NONNULL (1,2);
44 44
45 45
46/** 46/**
@@ -53,8 +53,8 @@ MHD_ip_limit_add (struct MHD_Daemon *daemon,
53 */ 53 */
54void 54void
55MHD_ip_limit_del (struct MHD_Daemon *daemon, 55MHD_ip_limit_del (struct MHD_Daemon *daemon,
56 const struct sockaddr *addr, 56 const struct sockaddr *addr,
57 socklen_t addrlen) 57 socklen_t addrlen)
58 MHD_NONNULL (1,2); 58MHD_NONNULL (1,2);
59 59
60#endif 60#endif
diff --git a/src/lib/daemon_options.c b/src/lib/daemon_options.c
index 4d7bbdf1..04c9cb2f 100644
--- a/src/lib/daemon_options.c
+++ b/src/lib/daemon_options.c
@@ -38,8 +38,8 @@
38 */ 38 */
39void 39void
40MHD_daemon_set_logger (struct MHD_Daemon *daemon, 40MHD_daemon_set_logger (struct MHD_Daemon *daemon,
41 MHD_LoggingCallback logger, 41 MHD_LoggingCallback logger,
42 void *logger_cls) 42 void *logger_cls)
43{ 43{
44 daemon->logger = logger; 44 daemon->logger = logger;
45 daemon->logger_cls = logger_cls; 45 daemon->logger_cls = logger_cls;
@@ -148,8 +148,8 @@ MHD_daemon_disallow_upgrade (struct MHD_Daemon *daemon)
148 */ 148 */
149enum MHD_Bool 149enum MHD_Bool
150MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon, 150MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon,
151 enum MHD_FastOpenMethod fom, 151 enum MHD_FastOpenMethod fom,
152 unsigned int queue_length) 152 unsigned int queue_length)
153{ 153{
154 daemon->fast_open_method = fom; 154 daemon->fast_open_method = fom;
155 daemon->fo_queue_length = queue_length; 155 daemon->fo_queue_length = queue_length;
@@ -185,8 +185,8 @@ MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon,
185 */ 185 */
186void 186void
187MHD_daemon_bind_port (struct MHD_Daemon *daemon, 187MHD_daemon_bind_port (struct MHD_Daemon *daemon,
188 enum MHD_AddressFamily af, 188 enum MHD_AddressFamily af,
189 uint16_t port) 189 uint16_t port)
190{ 190{
191 daemon->listen_af = af; 191 daemon->listen_af = af;
192 daemon->listen_port = port; 192 daemon->listen_port = port;
@@ -204,12 +204,12 @@ MHD_daemon_bind_port (struct MHD_Daemon *daemon,
204 */ 204 */
205void 205void
206MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon, 206MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon,
207 const struct sockaddr *sa, 207 const struct sockaddr *sa,
208 size_t sa_len) 208 size_t sa_len)
209{ 209{
210 memcpy (&daemon->listen_sa, 210 memcpy (&daemon->listen_sa,
211 sa, 211 sa,
212 sa_len); 212 sa_len);
213 daemon->listen_sa_len = sa_len; 213 daemon->listen_sa_len = sa_len;
214} 214}
215 215
@@ -223,7 +223,7 @@ MHD_daemon_bind_socket_address (struct MHD_Daemon *daemon,
223 */ 223 */
224void 224void
225MHD_daemon_listen_backlog (struct MHD_Daemon *daemon, 225MHD_daemon_listen_backlog (struct MHD_Daemon *daemon,
226 int listen_backlog) 226 int listen_backlog)
227{ 227{
228 daemon->listen_backlog = listen_backlog; 228 daemon->listen_backlog = listen_backlog;
229} 229}
@@ -275,7 +275,7 @@ MHD_daemon_enable_shoutcast (struct MHD_Daemon *daemon)
275 */ 275 */
276void 276void
277MHD_daemon_listen_socket (struct MHD_Daemon *daemon, 277MHD_daemon_listen_socket (struct MHD_Daemon *daemon,
278 MHD_socket listen_socket) 278 MHD_socket listen_socket)
279{ 279{
280 daemon->listen_socket = listen_socket; 280 daemon->listen_socket = listen_socket;
281} 281}
@@ -290,7 +290,7 @@ MHD_daemon_listen_socket (struct MHD_Daemon *daemon,
290 */ 290 */
291enum MHD_Bool 291enum MHD_Bool
292MHD_daemon_event_loop (struct MHD_Daemon *daemon, 292MHD_daemon_event_loop (struct MHD_Daemon *daemon,
293 enum MHD_EventLoopSyscall els) 293 enum MHD_EventLoopSyscall els)
294{ 294{
295 switch (els) 295 switch (els)
296 { 296 {
@@ -326,7 +326,7 @@ MHD_daemon_event_loop (struct MHD_Daemon *daemon,
326 */ 326 */
327void 327void
328MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon, 328MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon,
329 enum MHD_ProtocolStrictLevel sl) 329 enum MHD_ProtocolStrictLevel sl)
330{ 330{
331 daemon->protocol_strict_level = sl; 331 daemon->protocol_strict_level = sl;
332} 332}
@@ -349,8 +349,8 @@ MHD_daemon_protocol_strict_level (struct MHD_Daemon *daemon,
349 */ 349 */
350enum MHD_StatusCode 350enum MHD_StatusCode
351MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon, 351MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon,
352 const char *tls_backend, 352 const char *tls_backend,
353 const char *ciphers) 353 const char *ciphers)
354{ 354{
355#if ! (defined(HTTPS_SUPPORT) && defined (HAVE_DLFCN_H)) 355#if ! (defined(HTTPS_SUPPORT) && defined (HAVE_DLFCN_H))
356 return MHD_SC_TLS_DISABLED; 356 return MHD_SC_TLS_DISABLED;
@@ -361,18 +361,18 @@ MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon,
361 361
362 /* todo: .dll on W32? */ 362 /* todo: .dll on W32? */
363 res = MHD_snprintf_ (filename, 363 res = MHD_snprintf_ (filename,
364 sizeof (filename), 364 sizeof (filename),
365 "%s/libmicrohttpd_tls_%s.so", 365 "%s/libmicrohttpd_tls_%s.so",
366 MHD_PLUGIN_INSTALL_PREFIX, 366 MHD_PLUGIN_INSTALL_PREFIX,
367 tls_backend); 367 tls_backend);
368 if (0 >= res) 368 if (0 >= res)
369 return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* string too long? */ 369 return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* string too long? */
370 if (NULL == 370 if (NULL ==
371 (daemon->tls_backend_lib = dlopen (filename, 371 (daemon->tls_backend_lib = dlopen (filename,
372 RTLD_NOW | RTLD_LOCAL))) 372 RTLD_NOW | RTLD_LOCAL)))
373 return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* plugin not found */ 373 return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* plugin not found */
374 if (NULL == (init = dlsym (daemon->tls_backend_lib, 374 if (NULL == (init = dlsym (daemon->tls_backend_lib,
375 "MHD_TLS_init_" MHD_TLS_ABI_VERSION_STR))) 375 "MHD_TLS_init_" MHD_TLS_ABI_VERSION_STR)))
376 376
377 { 377 {
378 dlclose (daemon->tls_backend_lib); 378 dlclose (daemon->tls_backend_lib);
@@ -405,9 +405,9 @@ MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon,
405 */ 405 */
406enum MHD_StatusCode 406enum MHD_StatusCode
407MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon, 407MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon,
408 const char *mem_key, 408 const char *mem_key,
409 const char *mem_cert, 409 const char *mem_cert,
410 const char *pass) 410 const char *pass)
411{ 411{
412#ifndef HTTPS_SUPPORT 412#ifndef HTTPS_SUPPORT
413 return MHD_SC_TLS_DISABLED; 413 return MHD_SC_TLS_DISABLED;
@@ -417,9 +417,9 @@ MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon,
417 if (NULL == (plugin = daemon->tls_api)) 417 if (NULL == (plugin = daemon->tls_api))
418 return MHD_SC_TLS_BACKEND_UNINITIALIZED; 418 return MHD_SC_TLS_BACKEND_UNINITIALIZED;
419 return plugin->init_kcp (plugin->cls, 419 return plugin->init_kcp (plugin->cls,
420 mem_key, 420 mem_key,
421 mem_cert, 421 mem_cert,
422 pass); 422 pass);
423#endif 423#endif
424} 424}
425 425
@@ -435,7 +435,7 @@ MHD_daemon_tls_key_and_cert_from_memory (struct MHD_Daemon *daemon,
435 */ 435 */
436enum MHD_StatusCode 436enum MHD_StatusCode
437MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon, 437MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
438 const char *dh) 438 const char *dh)
439{ 439{
440#ifndef HTTPS_SUPPORT 440#ifndef HTTPS_SUPPORT
441 return MHD_SC_TLS_DISABLED; 441 return MHD_SC_TLS_DISABLED;
@@ -445,7 +445,7 @@ MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
445 if (NULL == (plugin = daemon->tls_api)) 445 if (NULL == (plugin = daemon->tls_api))
446 return MHD_SC_TLS_BACKEND_UNINITIALIZED; 446 return MHD_SC_TLS_BACKEND_UNINITIALIZED;
447 return plugin->init_dhparams (plugin->cls, 447 return plugin->init_dhparams (plugin->cls,
448 dh); 448 dh);
449#endif 449#endif
450} 450}
451 451
@@ -461,7 +461,7 @@ MHD_daemon_tls_mem_dhparams (struct MHD_Daemon *daemon,
461 */ 461 */
462enum MHD_StatusCode 462enum MHD_StatusCode
463MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon, 463MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon,
464 const char *mem_trust) 464 const char *mem_trust)
465{ 465{
466#ifndef HTTPS_SUPPORT 466#ifndef HTTPS_SUPPORT
467 return MHD_SC_TLS_DISABLED; 467 return MHD_SC_TLS_DISABLED;
@@ -471,7 +471,7 @@ MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon,
471 if (NULL == (plugin = daemon->tls_api)) 471 if (NULL == (plugin = daemon->tls_api))
472 return MHD_SC_TLS_BACKEND_UNINITIALIZED; 472 return MHD_SC_TLS_BACKEND_UNINITIALIZED;
473 return plugin->init_mem_trust (plugin->cls, 473 return plugin->init_mem_trust (plugin->cls,
474 mem_trust); 474 mem_trust);
475#endif 475#endif
476} 476}
477 477
@@ -485,7 +485,7 @@ MHD_daemon_tls_mem_trust (struct MHD_Daemon *daemon,
485 */ 485 */
486enum MHD_StatusCode 486enum MHD_StatusCode
487MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon, 487MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon,
488 int gnutls_credentials) 488 int gnutls_credentials)
489{ 489{
490#ifndef HTTPS_SUPPORT 490#ifndef HTTPS_SUPPORT
491 return MHD_SC_TLS_DISABLED; 491 return MHD_SC_TLS_DISABLED;
@@ -518,7 +518,7 @@ MHD_daemon_gnutls_credentials (struct MHD_Daemon *daemon,
518 */ 518 */
519enum MHD_StatusCode 519enum MHD_StatusCode
520MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon, 520MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon,
521 void *cb) 521 void *cb)
522{ 522{
523#ifndef HTTPS_SUPPORT 523#ifndef HTTPS_SUPPORT
524 return MHD_SC_TLS_DISABLED; 524 return MHD_SC_TLS_DISABLED;
@@ -541,7 +541,7 @@ MHD_daemon_gnutls_key_and_cert_from_callback (struct MHD_Daemon *daemon,
541 */ 541 */
542void 542void
543MHD_daemon_threading_mode (struct MHD_Daemon *daemon, 543MHD_daemon_threading_mode (struct MHD_Daemon *daemon,
544 enum MHD_ThreadingMode tm) 544 enum MHD_ThreadingMode tm)
545{ 545{
546 daemon->threading_mode = tm; 546 daemon->threading_mode = tm;
547} 547}
@@ -558,8 +558,8 @@ MHD_daemon_threading_mode (struct MHD_Daemon *daemon,
558 */ 558 */
559void 559void
560MHD_daemon_accept_policy (struct MHD_Daemon *daemon, 560MHD_daemon_accept_policy (struct MHD_Daemon *daemon,
561 MHD_AcceptPolicyCallback apc, 561 MHD_AcceptPolicyCallback apc,
562 void *apc_cls) 562 void *apc_cls)
563{ 563{
564 daemon->accept_policy_cb = apc; 564 daemon->accept_policy_cb = apc;
565 daemon->accept_policy_cb_cls = apc_cls; 565 daemon->accept_policy_cb_cls = apc_cls;
@@ -577,8 +577,8 @@ MHD_daemon_accept_policy (struct MHD_Daemon *daemon,
577 */ 577 */
578void 578void
579MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon, 579MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon,
580 MHD_EarlyUriLogCallback cb, 580 MHD_EarlyUriLogCallback cb,
581 void *cb_cls) 581 void *cb_cls)
582{ 582{
583 daemon->early_uri_logger_cb = cb; 583 daemon->early_uri_logger_cb = cb;
584 daemon->early_uri_logger_cb_cls = cb_cls; 584 daemon->early_uri_logger_cb_cls = cb_cls;
@@ -595,8 +595,8 @@ MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon,
595 */ 595 */
596void 596void
597MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon, 597MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon,
598 MHD_NotifyConnectionCallback ncc, 598 MHD_NotifyConnectionCallback ncc,
599 void *ncc_cls) 599 void *ncc_cls)
600{ 600{
601 daemon->notify_connection_cb = ncc; 601 daemon->notify_connection_cb = ncc;
602 daemon->notify_connection_cb_cls = ncc_cls; 602 daemon->notify_connection_cb_cls = ncc_cls;
@@ -616,8 +616,8 @@ MHD_daemon_set_notify_connection (struct MHD_Daemon *daemon,
616 */ 616 */
617void 617void
618MHD_daemon_connection_memory_limit (struct MHD_Daemon *daemon, 618MHD_daemon_connection_memory_limit (struct MHD_Daemon *daemon,
619 size_t memory_limit_b, 619 size_t memory_limit_b,
620 size_t memory_increment_b) 620 size_t memory_increment_b)
621{ 621{
622 if (memory_increment_b >= memory_limit_b) 622 if (memory_increment_b >= memory_limit_b)
623 MHD_PANIC ("sane memory increment must be below memory limit"); 623 MHD_PANIC ("sane memory increment must be below memory limit");
@@ -636,7 +636,7 @@ MHD_daemon_connection_memory_limit (struct MHD_Daemon *daemon,
636 */ 636 */
637void 637void
638MHD_daemon_thread_stack_size (struct MHD_Daemon *daemon, 638MHD_daemon_thread_stack_size (struct MHD_Daemon *daemon,
639 size_t stack_limit_b) 639 size_t stack_limit_b)
640{ 640{
641 daemon->thread_stack_limit_b = stack_limit_b; 641 daemon->thread_stack_limit_b = stack_limit_b;
642} 642}
@@ -659,8 +659,8 @@ MHD_daemon_thread_stack_size (struct MHD_Daemon *daemon,
659 */ 659 */
660void 660void
661MHD_daemon_connection_limits (struct MHD_Daemon *daemon, 661MHD_daemon_connection_limits (struct MHD_Daemon *daemon,
662 unsigned int global_connection_limit, 662 unsigned int global_connection_limit,
663 unsigned int ip_connection_limit) 663 unsigned int ip_connection_limit)
664{ 664{
665 daemon->global_connection_limit = global_connection_limit; 665 daemon->global_connection_limit = global_connection_limit;
666 daemon->ip_connection_limit = ip_connection_limit; 666 daemon->ip_connection_limit = ip_connection_limit;
@@ -677,7 +677,7 @@ MHD_daemon_connection_limits (struct MHD_Daemon *daemon,
677 */ 677 */
678void 678void
679MHD_daemon_connection_default_timeout (struct MHD_Daemon *daemon, 679MHD_daemon_connection_default_timeout (struct MHD_Daemon *daemon,
680 unsigned int timeout_s) 680 unsigned int timeout_s)
681{ 681{
682 daemon->connection_default_timeout = (time_t) timeout_s; 682 daemon->connection_default_timeout = (time_t) timeout_s;
683} 683}
@@ -696,8 +696,8 @@ MHD_daemon_connection_default_timeout (struct MHD_Daemon *daemon,
696 */ 696 */
697void 697void
698MHD_daemon_unescape_cb (struct MHD_Daemon *daemon, 698MHD_daemon_unescape_cb (struct MHD_Daemon *daemon,
699 MHD_UnescapeCallback unescape_cb, 699 MHD_UnescapeCallback unescape_cb,
700 void *unescape_cb_cls) 700 void *unescape_cb_cls)
701{ 701{
702 daemon->unescape_cb = unescape_cb; 702 daemon->unescape_cb = unescape_cb;
703 daemon->unescape_cb_cls = unescape_cb_cls; 703 daemon->unescape_cb_cls = unescape_cb_cls;
@@ -715,8 +715,8 @@ MHD_daemon_unescape_cb (struct MHD_Daemon *daemon,
715 */ 715 */
716void 716void
717MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon, 717MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon,
718 size_t buf_size, 718 size_t buf_size,
719 const void *buf) 719 const void *buf)
720{ 720{
721#if ENABLE_DAUTH 721#if ENABLE_DAUTH
722 daemon->digest_auth_random_buf = buf; 722 daemon->digest_auth_random_buf = buf;
@@ -739,34 +739,34 @@ MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon,
739 */ 739 */
740enum MHD_StatusCode 740enum MHD_StatusCode
741MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon, 741MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon,
742 size_t nc_length) 742 size_t nc_length)
743{ 743{
744#if ENABLE_DAUTH 744#if ENABLE_DAUTH
745 if ( ( (size_t) (nc_length * sizeof (struct MHD_NonceNc))) / 745 if ( ( (size_t) (nc_length * sizeof (struct MHD_NonceNc)))
746 sizeof (struct MHD_NonceNc) != nc_length) 746 / sizeof (struct MHD_NonceNc) != nc_length)
747 { 747 {
748#ifdef HAVE_MESSAGES 748#ifdef HAVE_MESSAGES
749 MHD_DLOG (daemon, 749 MHD_DLOG (daemon,
750 _("Specified value for NC_SIZE too large\n")); 750 _ ("Specified value for NC_SIZE too large\n"));
751#endif 751#endif
752 return MHD_SC_DIGEST_AUTH_NC_LENGTH_TOO_BIG; 752 return MHD_SC_DIGEST_AUTH_NC_LENGTH_TOO_BIG;
753 } 753 }
754 if (0 < nc_length) 754 if (0 < nc_length)
755 {
756 if (NULL != daemon->nnc)
757 free (daemon->nnc);
758 daemon->nnc = malloc (daemon->nonce_nc_size
759 * sizeof (struct MHD_NonceNc));
760 if (NULL == daemon->nnc)
755 { 761 {
756 if (NULL != daemon->nnc)
757 free (daemon->nnc);
758 daemon->nnc = malloc (daemon->nonce_nc_size *
759 sizeof (struct MHD_NonceNc));
760 if (NULL == daemon->nnc)
761 {
762#ifdef HAVE_MESSAGES 762#ifdef HAVE_MESSAGES
763 MHD_DLOG (daemon, 763 MHD_DLOG (daemon,
764 _("Failed to allocate memory for nonce-nc map: %s\n"), 764 _ ("Failed to allocate memory for nonce-nc map: %s\n"),
765 MHD_strerror_ (errno)); 765 MHD_strerror_ (errno));
766#endif 766#endif
767 return MHD_SC_DIGEST_AUTH_NC_ALLOCATION_FAILURE; 767 return MHD_SC_DIGEST_AUTH_NC_ALLOCATION_FAILURE;
768 }
769 } 768 }
769 }
770 daemon->digest_nc_length = nc_length; 770 daemon->digest_nc_length = nc_length;
771 return MHD_SC_OK; 771 return MHD_SC_OK;
772#else 772#else
diff --git a/src/lib/daemon_poll.c b/src/lib/daemon_poll.c
index 80599e93..1fea9fd6 100644
--- a/src/lib/daemon_poll.c
+++ b/src/lib/daemon_poll.c
@@ -45,7 +45,7 @@
45 */ 45 */
46static void 46static void
47urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh, 47urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh,
48 struct pollfd p[2]) 48 struct pollfd p[2])
49{ 49{
50 p[0].events = 0; 50 p[0].events = 0;
51 p[1].events = 0; 51 p[1].events = 0;
@@ -86,12 +86,12 @@ urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh,
86 */ 86 */
87static void 87static void
88urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh, 88urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh,
89 struct pollfd p[2]) 89 struct pollfd p[2])
90{ 90{
91 p[0].fd = urh->connection->socket_fd; 91 p[0].fd = urh->connection->socket_fd;
92 p[1].fd = urh->mhd.socket; 92 p[1].fd = urh->mhd.socket;
93 urh_update_pollfd (urh, 93 urh_update_pollfd (urh,
94 p); 94 p);
95} 95}
96 96
97 97
@@ -102,7 +102,7 @@ urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh,
102 */ 102 */
103static void 103static void
104urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh, 104urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh,
105 struct pollfd p[2]) 105 struct pollfd p[2])
106{ 106{
107 /* Reset read/write ready, preserve error state. */ 107 /* Reset read/write ready, preserve error state. */
108 urh->app.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); 108 urh->app.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY);
@@ -138,7 +138,7 @@ urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh,
138 */ 138 */
139enum MHD_StatusCode 139enum MHD_StatusCode
140MHD_daemon_poll_all_ (struct MHD_Daemon *daemon, 140MHD_daemon_poll_all_ (struct MHD_Daemon *daemon,
141 bool may_block) 141 bool may_block)
142{ 142{
143 unsigned int num_connections; 143 unsigned int num_connections;
144 struct MHD_Connection *pos; 144 struct MHD_Connection *pos;
@@ -171,103 +171,103 @@ MHD_daemon_poll_all_ (struct MHD_Daemon *daemon,
171 MHD_socket ls; 171 MHD_socket ls;
172 172
173 p = MHD_calloc_ ((2 + num_connections), 173 p = MHD_calloc_ ((2 + num_connections),
174 sizeof (struct pollfd)); 174 sizeof (struct pollfd));
175 if (NULL == p) 175 if (NULL == p)
176 { 176 {
177#ifdef HAVE_MESSAGES 177#ifdef HAVE_MESSAGES
178 MHD_DLOG (daemon, 178 MHD_DLOG (daemon,
179 MHD_SC_POLL_MALLOC_FAILURE, 179 MHD_SC_POLL_MALLOC_FAILURE,
180 _("Error allocating memory: %s\n"), 180 _ ("Error allocating memory: %s\n"),
181 MHD_strerror_(errno)); 181 MHD_strerror_ (errno));
182#endif 182#endif
183 return MHD_SC_POLL_MALLOC_FAILURE; 183 return MHD_SC_POLL_MALLOC_FAILURE;
184 } 184 }
185 poll_server = 0; 185 poll_server = 0;
186 poll_listen = -1; 186 poll_listen = -1;
187 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && 187 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
188 (! daemon->was_quiesced) && 188 (! daemon->was_quiesced) &&
189 (daemon->connections < daemon->global_connection_limit) && 189 (daemon->connections < daemon->global_connection_limit) &&
190 (! daemon->at_limit) ) 190 (! daemon->at_limit) )
191 { 191 {
192 /* only listen if we are not at the connection limit */ 192 /* only listen if we are not at the connection limit */
193 p[poll_server].fd = ls; 193 p[poll_server].fd = ls;
194 p[poll_server].events = POLLIN; 194 p[poll_server].events = POLLIN;
195 p[poll_server].revents = 0; 195 p[poll_server].revents = 0;
196 poll_listen = (int) poll_server; 196 poll_listen = (int) poll_server;
197 poll_server++; 197 poll_server++;
198 } 198 }
199 poll_itc_idx = -1; 199 poll_itc_idx = -1;
200 if (MHD_ITC_IS_VALID_(daemon->itc)) 200 if (MHD_ITC_IS_VALID_ (daemon->itc))
201 { 201 {
202 p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc); 202 p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc);
203 p[poll_server].events = POLLIN; 203 p[poll_server].events = POLLIN;
204 p[poll_server].revents = 0; 204 p[poll_server].revents = 0;
205 poll_itc_idx = (int) poll_server; 205 poll_itc_idx = (int) poll_server;
206 poll_server++; 206 poll_server++;
207 } 207 }
208 if (! may_block) 208 if (! may_block)
209 timeout = 0; 209 timeout = 0;
210 else if ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) || 210 else if ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) ||
211 (MHD_SC_OK != /* FIXME: distinguish between NO_TIMEOUT and errors! */ 211 (MHD_SC_OK != /* FIXME: distinguish between NO_TIMEOUT and errors! */
212 MHD_daemon_get_timeout (daemon, 212 MHD_daemon_get_timeout (daemon,
213 &ltimeout)) ) 213 &ltimeout)) )
214 timeout = -1; 214 timeout = -1;
215 else 215 else
216 timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout; 216 timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
217 217
218 i = 0; 218 i = 0;
219 for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) 219 for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
220 {
221 p[poll_server + i].fd = pos->socket_fd;
222 switch (pos->request.event_loop_info)
220 { 223 {
221 p[poll_server+i].fd = pos->socket_fd; 224 case MHD_EVENT_LOOP_INFO_READ:
222 switch (pos->request.event_loop_info) 225 p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
223 { 226 break;
224 case MHD_EVENT_LOOP_INFO_READ: 227 case MHD_EVENT_LOOP_INFO_WRITE:
225 p[poll_server+i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; 228 p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
226 break; 229 break;
227 case MHD_EVENT_LOOP_INFO_WRITE: 230 case MHD_EVENT_LOOP_INFO_BLOCK:
228 p[poll_server+i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; 231 p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC;
229 break; 232 break;
230 case MHD_EVENT_LOOP_INFO_BLOCK: 233 case MHD_EVENT_LOOP_INFO_CLEANUP:
231 p[poll_server+i].events |= MHD_POLL_EVENTS_ERR_DISC; 234 timeout = 0; /* clean up "pos" immediately */
232 break; 235 break;
233 case MHD_EVENT_LOOP_INFO_CLEANUP:
234 timeout = 0; /* clean up "pos" immediately */
235 break;
236 }
237 i++;
238 } 236 }
237 i++;
238 }
239#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 239#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
240 for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) 240 for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
241 { 241 {
242 urh_to_pollfd (urh, 242 urh_to_pollfd (urh,
243 &(p[poll_server+i])); 243 &(p[poll_server + i]));
244 i += 2; 244 i += 2;
245 } 245 }
246#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 246#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
247 if (0 == poll_server + num_connections) 247 if (0 == poll_server + num_connections)
248 {
249 free (p);
250 return MHD_SC_OK;
251 }
252 if (MHD_sys_poll_ (p,
253 poll_server + num_connections,
254 timeout) < 0)
255 {
256 const int err = MHD_socket_get_error_ ();
257 if (MHD_SCKT_ERR_IS_EINTR_ (err))
248 { 258 {
249 free (p); 259 free (p);
250 return MHD_SC_OK; 260 return MHD_SC_OK;
251 } 261 }
252 if (MHD_sys_poll_(p,
253 poll_server + num_connections,
254 timeout) < 0)
255 {
256 const int err = MHD_socket_get_error_ ();
257 if (MHD_SCKT_ERR_IS_EINTR_ (err))
258 {
259 free(p);
260 return MHD_SC_OK;
261 }
262#ifdef HAVE_MESSAGES 262#ifdef HAVE_MESSAGES
263 MHD_DLOG (daemon, 263 MHD_DLOG (daemon,
264 MHD_SC_UNEXPECTED_POLL_ERROR, 264 MHD_SC_UNEXPECTED_POLL_ERROR,
265 _("poll failed: %s\n"), 265 _ ("poll failed: %s\n"),
266 MHD_socket_strerr_ (err)); 266 MHD_socket_strerr_ (err));
267#endif 267#endif
268 free(p); 268 free (p);
269 return MHD_SC_UNEXPECTED_POLL_ERROR; 269 return MHD_SC_UNEXPECTED_POLL_ERROR;
270 } 270 }
271 271
272 /* Reset. New value will be set when connections are processed. */ 272 /* Reset. New value will be set when connections are processed. */
273 daemon->data_already_pending = false; 273 daemon->data_already_pending = false;
@@ -281,67 +281,69 @@ MHD_daemon_poll_all_ (struct MHD_Daemon *daemon,
281 281
282 /* handle shutdown */ 282 /* handle shutdown */
283 if (daemon->shutdown) 283 if (daemon->shutdown)
284 { 284 {
285 free(p); 285 free (p);
286 return MHD_SC_DAEMON_ALREADY_SHUTDOWN; 286 return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
287 } 287 }
288 i = 0; 288 i = 0;
289 prev = daemon->connections_tail; 289 prev = daemon->connections_tail;
290 while (NULL != (pos = prev)) 290 while (NULL != (pos = prev))
291 { 291 {
292 prev = pos->prev; 292 prev = pos->prev;
293 /* first, sanity checks */ 293 /* first, sanity checks */
294 if (i >= num_connections) 294 if (i >= num_connections)
295 break; /* connection list changed somehow, retry later ... */ 295 break; /* connection list changed somehow, retry later ... */
296 if (p[poll_server+i].fd != pos->socket_fd) 296 if (p[poll_server + i].fd != pos->socket_fd)
297 continue; /* fd mismatch, something else happened, retry later ... */ 297 continue; /* fd mismatch, something else happened, retry later ... */
298 MHD_connection_call_handlers_ (pos, 298 MHD_connection_call_handlers_ (pos,
299 0 != (p[poll_server+i].revents & POLLIN), 299 0 != (p[poll_server + i].revents & POLLIN),
300 0 != (p[poll_server+i].revents & POLLOUT), 300 0 != (p[poll_server + i].revents
301 0 != (p[poll_server+i].revents & MHD_POLL_REVENTS_ERR_DISC)); 301 & POLLOUT),
302 i++; 302 0 != (p[poll_server + i].revents
303 } 303 & MHD_POLL_REVENTS_ERR_DISC));
304 i++;
305 }
304#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 306#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
305 for (urh = daemon->urh_tail; NULL != urh; urh = urhn) 307 for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
308 {
309 if (i >= num_connections)
310 break; /* connection list changed somehow, retry later ... */
311
312 /* Get next connection here as connection can be removed
313 * from 'daemon->urh_head' list. */
314 urhn = urh->prev;
315 /* Check for fd mismatch. FIXME: required for safety? */
316 if ((p[poll_server + i].fd != urh->connection->socket_fd) ||
317 (p[poll_server + i + 1].fd != urh->mhd.socket))
318 break;
319 urh_from_pollfd (urh,
320 &p[poll_server + i]);
321 i += 2;
322 MHD_upgrade_response_handle_process_ (urh);
323 /* Finished forwarding? */
324 if ( (0 == urh->in_buffer_size) &&
325 (0 == urh->out_buffer_size) &&
326 (0 == urh->in_buffer_used) &&
327 (0 == urh->out_buffer_used) )
306 { 328 {
307 if (i >= num_connections) 329 /* MHD_connection_finish_forward_() will remove connection from
308 break; /* connection list changed somehow, retry later ... */ 330 * 'daemon->urh_head' list. */
309 331 MHD_connection_finish_forward_ (urh->connection);
310 /* Get next connection here as connection can be removed 332 urh->clean_ready = true;
311 * from 'daemon->urh_head' list. */ 333 /* If 'urh->was_closed' already was set to true, connection will be
312 urhn = urh->prev; 334 * moved immediately to cleanup list. Otherwise connection
313 /* Check for fd mismatch. FIXME: required for safety? */ 335 * will stay in suspended list until 'urh' will be marked
314 if ((p[poll_server+i].fd != urh->connection->socket_fd) || 336 * with 'was_closed' by application. */
315 (p[poll_server+i+1].fd != urh->mhd.socket)) 337 MHD_request_resume (&urh->connection->request);
316 break;
317 urh_from_pollfd (urh,
318 &p[poll_server+i]);
319 i += 2;
320 MHD_upgrade_response_handle_process_ (urh);
321 /* Finished forwarding? */
322 if ( (0 == urh->in_buffer_size) &&
323 (0 == urh->out_buffer_size) &&
324 (0 == urh->in_buffer_used) &&
325 (0 == urh->out_buffer_used) )
326 {
327 /* MHD_connection_finish_forward_() will remove connection from
328 * 'daemon->urh_head' list. */
329 MHD_connection_finish_forward_ (urh->connection);
330 urh->clean_ready = true;
331 /* If 'urh->was_closed' already was set to true, connection will be
332 * moved immediately to cleanup list. Otherwise connection
333 * will stay in suspended list until 'urh' will be marked
334 * with 'was_closed' by application. */
335 MHD_request_resume (&urh->connection->request);
336 }
337 } 338 }
339 }
338#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 340#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
339 /* handle 'listen' FD */ 341 /* handle 'listen' FD */
340 if ( (-1 != poll_listen) && 342 if ( (-1 != poll_listen) &&
341 (0 != (p[poll_listen].revents & POLLIN)) ) 343 (0 != (p[poll_listen].revents & POLLIN)) )
342 (void) MHD_accept_connection_ (daemon); 344 (void) MHD_accept_connection_ (daemon);
343 345
344 free(p); 346 free (p);
345 } 347 }
346 return MHD_SC_OK; 348 return MHD_SC_OK;
347} 349}
@@ -356,7 +358,7 @@ MHD_daemon_poll_all_ (struct MHD_Daemon *daemon,
356 */ 358 */
357enum MHD_StatusCode 359enum MHD_StatusCode
358MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon, 360MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon,
359 bool may_block) 361 bool may_block)
360{ 362{
361 struct pollfd p[2]; 363 struct pollfd p[2];
362 int timeout; 364 int timeout;
@@ -374,21 +376,21 @@ MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon,
374 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && 376 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
375 (! daemon->was_quiesced) ) 377 (! daemon->was_quiesced) )
376 378
377 { 379 {
378 p[poll_count].fd = ls; 380 p[poll_count].fd = ls;
379 p[poll_count].events = POLLIN; 381 p[poll_count].events = POLLIN;
380 p[poll_count].revents = 0; 382 p[poll_count].revents = 0;
381 poll_listen = poll_count; 383 poll_listen = poll_count;
382 poll_count++; 384 poll_count++;
383 } 385 }
384 if (MHD_ITC_IS_VALID_(daemon->itc)) 386 if (MHD_ITC_IS_VALID_ (daemon->itc))
385 { 387 {
386 p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc); 388 p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc);
387 p[poll_count].events = POLLIN; 389 p[poll_count].events = POLLIN;
388 p[poll_count].revents = 0; 390 p[poll_count].revents = 0;
389 poll_itc_idx = poll_count; 391 poll_itc_idx = poll_count;
390 poll_count++; 392 poll_count++;
391 } 393 }
392 394
393 if (! daemon->disallow_suspend_resume) 395 if (! daemon->disallow_suspend_resume)
394 (void) MHD_resume_suspended_connections_ (daemon); 396 (void) MHD_resume_suspended_connections_ (daemon);
@@ -399,22 +401,22 @@ MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon,
399 timeout = -1; 401 timeout = -1;
400 if (0 == poll_count) 402 if (0 == poll_count)
401 return MHD_SC_OK; 403 return MHD_SC_OK;
402 if (MHD_sys_poll_(p, 404 if (MHD_sys_poll_ (p,
403 poll_count, 405 poll_count,
404 timeout) < 0) 406 timeout) < 0)
405 { 407 {
406 const int err = MHD_socket_get_error_ (); 408 const int err = MHD_socket_get_error_ ();
407 409
408 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 410 if (MHD_SCKT_ERR_IS_EINTR_ (err))
409 return MHD_SC_OK; 411 return MHD_SC_OK;
410#ifdef HAVE_MESSAGES 412#ifdef HAVE_MESSAGES
411 MHD_DLOG (daemon, 413 MHD_DLOG (daemon,
412 MHD_SC_UNEXPECTED_POLL_ERROR, 414 MHD_SC_UNEXPECTED_POLL_ERROR,
413 _("poll failed: %s\n"), 415 _ ("poll failed: %s\n"),
414 MHD_socket_strerr_ (err)); 416 MHD_socket_strerr_ (err));
415#endif 417#endif
416 return MHD_SC_UNEXPECTED_POLL_ERROR; 418 return MHD_SC_UNEXPECTED_POLL_ERROR;
417 } 419 }
418 if ( (-1 != poll_itc_idx) && 420 if ( (-1 != poll_itc_idx) &&
419 (0 != (p[poll_itc_idx].revents & POLLIN)) ) 421 (0 != (p[poll_itc_idx].revents & POLLIN)) )
420 MHD_itc_clear_ (daemon->itc); 422 MHD_itc_clear_ (daemon->itc);
@@ -439,16 +441,16 @@ MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon,
439 */ 441 */
440enum MHD_StatusCode 442enum MHD_StatusCode
441MHD_daemon_poll_ (struct MHD_Daemon *daemon, 443MHD_daemon_poll_ (struct MHD_Daemon *daemon,
442 bool may_block) 444 bool may_block)
443{ 445{
444#ifdef HAVE_POLL 446#ifdef HAVE_POLL
445 if (daemon->shutdown) 447 if (daemon->shutdown)
446 return MHD_SC_DAEMON_ALREADY_SHUTDOWN; 448 return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
447 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) 449 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
448 return MHD_daemon_poll_all_ (daemon, 450 return MHD_daemon_poll_all_ (daemon,
449 may_block); 451 may_block);
450 return MHD_daemon_poll_listen_socket_ (daemon, 452 return MHD_daemon_poll_listen_socket_ (daemon,
451 may_block); 453 may_block);
452#else 454#else
453 /* This code should be dead, as we should have checked 455 /* This code should be dead, as we should have checked
454 this earlier... */ 456 this earlier... */
@@ -472,47 +474,47 @@ MHD_daemon_upgrade_connection_with_poll_ (struct MHD_Connection *con)
472 struct pollfd p[2]; 474 struct pollfd p[2];
473 475
474 memset (p, 476 memset (p,
475 0, 477 0,
476 sizeof (p)); 478 sizeof (p));
477 p[0].fd = urh->connection->socket_fd; 479 p[0].fd = urh->connection->socket_fd;
478 p[1].fd = urh->mhd.socket; 480 p[1].fd = urh->mhd.socket;
479 481
480 while ( (0 != urh->in_buffer_size) || 482 while ( (0 != urh->in_buffer_size) ||
481 (0 != urh->out_buffer_size) || 483 (0 != urh->out_buffer_size) ||
482 (0 != urh->in_buffer_used) || 484 (0 != urh->in_buffer_used) ||
483 (0 != urh->out_buffer_used) ) 485 (0 != urh->out_buffer_used) )
484 { 486 {
485 int timeout; 487 int timeout;
486 488
487 urh_update_pollfd (urh, 489 urh_update_pollfd (urh,
488 p); 490 p);
489 491
490 if ( (con->tls_read_ready) && 492 if ( (con->tls_read_ready) &&
491 (urh->in_buffer_used < urh->in_buffer_size)) 493 (urh->in_buffer_used < urh->in_buffer_size))
492 timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */ 494 timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */
493 else 495 else
494 timeout = -1; 496 timeout = -1;
495 497
496 if (MHD_sys_poll_ (p, 498 if (MHD_sys_poll_ (p,
497 2, 499 2,
498 timeout) < 0) 500 timeout) < 0)
499 { 501 {
500 const int err = MHD_socket_get_error_ (); 502 const int err = MHD_socket_get_error_ ();
501 503
502 if (MHD_SCKT_ERR_IS_EINTR_ (err)) 504 if (MHD_SCKT_ERR_IS_EINTR_ (err))
503 continue; 505 continue;
504#ifdef HAVE_MESSAGES 506#ifdef HAVE_MESSAGES
505 MHD_DLOG (con->daemon, 507 MHD_DLOG (con->daemon,
506 MHD_SC_UNEXPECTED_POLL_ERROR, 508 MHD_SC_UNEXPECTED_POLL_ERROR,
507 _("Error during poll: `%s'\n"), 509 _ ("Error during poll: `%s'\n"),
508 MHD_socket_strerr_ (err)); 510 MHD_socket_strerr_ (err));
509#endif 511#endif
510 break; 512 break;
511 }
512 urh_from_pollfd (urh,
513 p);
514 MHD_upgrade_response_handle_process_ (urh);
515 } 513 }
514 urh_from_pollfd (urh,
515 p);
516 MHD_upgrade_response_handle_process_ (urh);
517 }
516} 518}
517#endif 519#endif
518#endif 520#endif
diff --git a/src/lib/daemon_poll.h b/src/lib/daemon_poll.h
index fc5663b0..3c408620 100644
--- a/src/lib/daemon_poll.h
+++ b/src/lib/daemon_poll.h
@@ -37,8 +37,8 @@
37 */ 37 */
38enum MHD_StatusCode 38enum MHD_StatusCode
39MHD_daemon_poll_all_ (struct MHD_Daemon *daemon, 39MHD_daemon_poll_all_ (struct MHD_Daemon *daemon,
40 bool may_block) 40 bool may_block)
41 MHD_NONNULL(1); 41MHD_NONNULL (1);
42 42
43 43
44/** 44/**
@@ -50,8 +50,8 @@ MHD_daemon_poll_all_ (struct MHD_Daemon *daemon,
50 */ 50 */
51enum MHD_StatusCode 51enum MHD_StatusCode
52MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon, 52MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon,
53 bool may_block) 53 bool may_block)
54 MHD_NONNULL (1); 54MHD_NONNULL (1);
55 55
56 56
57/** 57/**
@@ -63,8 +63,8 @@ MHD_daemon_poll_listen_socket_ (struct MHD_Daemon *daemon,
63 */ 63 */
64enum MHD_StatusCode 64enum MHD_StatusCode
65MHD_daemon_poll_ (struct MHD_Daemon *daemon, 65MHD_daemon_poll_ (struct MHD_Daemon *daemon,
66 bool may_block) 66 bool may_block)
67 MHD_NONNULL (1); 67MHD_NONNULL (1);
68#endif 68#endif
69 69
70 70
@@ -78,7 +78,7 @@ MHD_daemon_poll_ (struct MHD_Daemon *daemon,
78 */ 78 */
79void 79void
80MHD_daemon_upgrade_connection_with_poll_ (struct MHD_Connection *con) 80MHD_daemon_upgrade_connection_with_poll_ (struct MHD_Connection *con)
81 MHD_NONNULL(1); 81MHD_NONNULL (1);
82#endif 82#endif
83#endif 83#endif
84 84
diff --git a/src/lib/daemon_quiesce.c b/src/lib/daemon_quiesce.c
index 0d920608..c7275099 100644
--- a/src/lib/daemon_quiesce.c
+++ b/src/lib/daemon_quiesce.c
@@ -54,75 +54,76 @@ MHD_daemon_quiesce (struct MHD_Daemon *daemon)
54 return MHD_INVALID_SOCKET; 54 return MHD_INVALID_SOCKET;
55 if ( (daemon->disable_itc) && 55 if ( (daemon->disable_itc) &&
56 (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) ) 56 (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) )
57 { 57 {
58#ifdef HAVE_MESSAGES 58#ifdef HAVE_MESSAGES
59 MHD_DLOG (daemon, 59 MHD_DLOG (daemon,
60 MHD_SC_SYSCALL_QUIESCE_REQUIRES_ITC, 60 MHD_SC_SYSCALL_QUIESCE_REQUIRES_ITC,
61 "Using MHD_quiesce_daemon in this mode requires ITC\n"); 61 "Using MHD_quiesce_daemon in this mode requires ITC\n");
62#endif 62#endif
63 return MHD_INVALID_SOCKET; 63 return MHD_INVALID_SOCKET;
64 } 64 }
65 65
66 if (NULL != daemon->worker_pool) 66 if (NULL != daemon->worker_pool)
67 {
68 unsigned int i;
69
70 for (i = 0; i < daemon->worker_pool_size; i++)
67 { 71 {
68 unsigned int i; 72 struct MHD_Daemon *worker = &daemon->worker_pool[i];
69 73
70 for (i = 0; i < daemon->worker_pool_size; i++) 74 worker->was_quiesced = true;
71 {
72 struct MHD_Daemon *worker = &daemon->worker_pool[i];
73
74 worker->was_quiesced = true;
75#ifdef EPOLL_SUPPORT
76 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
77 (-1 != worker->epoll_fd) &&
78 (worker->listen_socket_in_epoll) )
79 {
80 if (0 != epoll_ctl (worker->epoll_fd,
81 EPOLL_CTL_DEL,
82 listen_socket,
83 NULL))
84 MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
85 worker->listen_socket_in_epoll = false;
86 }
87 else
88#endif
89 if (MHD_ITC_IS_VALID_(worker->itc))
90 {
91 if (! MHD_itc_activate_ (worker->itc,
92 "q"))
93 MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel"));
94 }
95 }
96 daemon->was_quiesced = true;
97#ifdef EPOLL_SUPPORT 75#ifdef EPOLL_SUPPORT
98 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && 76 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
99 (-1 != daemon->epoll_fd) && 77 (-1 != worker->epoll_fd) &&
100 (daemon->listen_socket_in_epoll) ) 78 (worker->listen_socket_in_epoll) )
101 { 79 {
102 if (0 != epoll_ctl (daemon->epoll_fd, 80 if (0 != epoll_ctl (worker->epoll_fd,
103 EPOLL_CTL_DEL, 81 EPOLL_CTL_DEL,
104 listen_socket, 82 listen_socket,
105 NULL)) 83 NULL))
106 MHD_PANIC ("Failed to remove listen FD from epoll set\n"); 84 MHD_PANIC (_ ("Failed to remove listen FD from epoll set\n"));
107 daemon->listen_socket_in_epoll = false; 85 worker->listen_socket_in_epoll = false;
108 } 86 }
87 else
109#endif 88#endif
89 if (MHD_ITC_IS_VALID_ (worker->itc))
90 {
91 if (! MHD_itc_activate_ (worker->itc,
92 "q"))
93 MHD_PANIC (_ (
94 "Failed to signal quiesce via inter-thread communication channel"));
95 }
110 } 96 }
111 97 daemon->was_quiesced = true;
112 if ( (MHD_ITC_IS_VALID_(daemon->itc)) && 98#ifdef EPOLL_SUPPORT
99 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
100 (-1 != daemon->epoll_fd) &&
101 (daemon->listen_socket_in_epoll) )
102 {
103 if (0 != epoll_ctl (daemon->epoll_fd,
104 EPOLL_CTL_DEL,
105 listen_socket,
106 NULL))
107 MHD_PANIC ("Failed to remove listen FD from epoll set\n");
108 daemon->listen_socket_in_epoll = false;
109 }
110#endif
111 }
112
113 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
113 (! MHD_itc_activate_ (daemon->itc, 114 (! MHD_itc_activate_ (daemon->itc,
114 "q")) ) 115 "q")) )
115 MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel")); 116 MHD_PANIC (_ (
117 "Failed to signal quiesce via inter-thread communication channel"));
116 118
117 /* FIXME: we might want some bi-directional communication here 119 /* FIXME: we might want some bi-directional communication here
118 (in both the thread-pool and single-thread case!) 120 (in both the thread-pool and single-thread case!)
119 to be sure that the threads have stopped using the listen 121 to be sure that the threads have stopped using the listen
120 socket, otherwise there is still the possibility of a race 122 socket, otherwise there is still the possibility of a race
121 between a thread accept()ing and the caller closing and 123 between a thread accept()ing and the caller closing and
122 re-binding the socket. */ 124 re-binding the socket. */
123 125
124 return listen_socket; 126 return listen_socket;
125} 127}
126 128
127/* end of daemon_quiesce.c */ 129/* end of daemon_quiesce.c */
128
diff --git a/src/lib/daemon_run.c b/src/lib/daemon_run.c
index 129f7efb..cae500da 100644
--- a/src/lib/daemon_run.c
+++ b/src/lib/daemon_run.c
@@ -57,26 +57,26 @@ MHD_daemon_run (struct MHD_Daemon *daemon)
57 if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) 57 if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode)
58 return MHD_SC_CONFIGURATION_MISMATCH_FOR_RUN_EXTERNAL; 58 return MHD_SC_CONFIGURATION_MISMATCH_FOR_RUN_EXTERNAL;
59 switch (daemon->event_loop_syscall) 59 switch (daemon->event_loop_syscall)
60 { 60 {
61 case MHD_ELS_POLL: 61 case MHD_ELS_POLL:
62 sc = MHD_daemon_poll_ (daemon, 62 sc = MHD_daemon_poll_ (daemon,
63 MHD_NO); 63 MHD_NO);
64 MHD_connection_cleanup_ (daemon); 64 MHD_connection_cleanup_ (daemon);
65 return sc; 65 return sc;
66#ifdef EPOLL_SUPPORT 66#ifdef EPOLL_SUPPORT
67 case MHD_ELS_EPOLL: 67 case MHD_ELS_EPOLL:
68 sc = MHD_daemon_epoll_ (daemon, 68 sc = MHD_daemon_epoll_ (daemon,
69 MHD_NO); 69 MHD_NO);
70 MHD_connection_cleanup_ (daemon); 70 MHD_connection_cleanup_ (daemon);
71 return sc; 71 return sc;
72#endif 72#endif
73 case MHD_ELS_SELECT: 73 case MHD_ELS_SELECT:
74 return MHD_daemon_select_ (daemon, 74 return MHD_daemon_select_ (daemon,
75 MHD_NO); 75 MHD_NO);
76 /* MHD_select does MHD_connection_cleanup_ already */ 76 /* MHD_select does MHD_connection_cleanup_ already */
77 default: 77 default:
78 return MHD_SC_CONFIGURATION_UNEXPECTED_ELS; 78 return MHD_SC_CONFIGURATION_UNEXPECTED_ELS;
79 } 79 }
80} 80}
81 81
82/* end of daemon_run.c */ 82/* end of daemon_run.c */
diff --git a/src/lib/daemon_select.c b/src/lib/daemon_select.c
index 08281d8c..69913a9a 100644
--- a/src/lib/daemon_select.c
+++ b/src/lib/daemon_select.c
@@ -66,17 +66,17 @@
66 */ 66 */
67enum MHD_StatusCode 67enum MHD_StatusCode
68MHD_daemon_get_fdset (struct MHD_Daemon *daemon, 68MHD_daemon_get_fdset (struct MHD_Daemon *daemon,
69 fd_set *read_fd_set, 69 fd_set *read_fd_set,
70 fd_set *write_fd_set, 70 fd_set *write_fd_set,
71 fd_set *except_fd_set, 71 fd_set *except_fd_set,
72 MHD_socket *max_fd) 72 MHD_socket *max_fd)
73{ 73{
74 return MHD_daemon_get_fdset2 (daemon, 74 return MHD_daemon_get_fdset2 (daemon,
75 read_fd_set, 75 read_fd_set,
76 write_fd_set, 76 write_fd_set,
77 except_fd_set, 77 except_fd_set,
78 max_fd, 78 max_fd,
79 _MHD_SYS_DEFAULT_FD_SETSIZE); 79 _MHD_SYS_DEFAULT_FD_SETSIZE);
80} 80}
81 81
82 82
@@ -108,55 +108,55 @@ urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
108 /* Do not add to 'es' only if socket is closed 108 /* Do not add to 'es' only if socket is closed
109 * or not used anymore. */ 109 * or not used anymore. */
110 if (MHD_INVALID_SOCKET != conn_sckt) 110 if (MHD_INVALID_SOCKET != conn_sckt)
111 { 111 {
112 if ( (urh->in_buffer_used < urh->in_buffer_size) && 112 if ( (urh->in_buffer_used < urh->in_buffer_size) &&
113 (! MHD_add_to_fd_set_ (conn_sckt, 113 (! MHD_add_to_fd_set_ (conn_sckt,
114 rs, 114 rs,
115 max_fd, 115 max_fd,
116 fd_setsize)) ) 116 fd_setsize)) )
117 res = false; 117 res = false;
118 if ( (0 != urh->out_buffer_used) && 118 if ( (0 != urh->out_buffer_used) &&
119 (! MHD_add_to_fd_set_ (conn_sckt, 119 (! MHD_add_to_fd_set_ (conn_sckt,
120 ws, 120 ws,
121 max_fd, 121 max_fd,
122 fd_setsize)) ) 122 fd_setsize)) )
123 res = false; 123 res = false;
124 /* Do not monitor again for errors if error was detected before as 124 /* Do not monitor again for errors if error was detected before as
125 * error state is remembered. */ 125 * error state is remembered. */
126 if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) && 126 if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
127 ((0 != urh->in_buffer_size) || 127 ((0 != urh->in_buffer_size) ||
128 (0 != urh->out_buffer_size) || 128 (0 != urh->out_buffer_size) ||
129 (0 != urh->out_buffer_used))) 129 (0 != urh->out_buffer_used)))
130 MHD_add_to_fd_set_ (conn_sckt, 130 MHD_add_to_fd_set_ (conn_sckt,
131 es, 131 es,
132 max_fd, 132 max_fd,
133 fd_setsize); 133 fd_setsize);
134 } 134 }
135 if (MHD_INVALID_SOCKET != mhd_sckt) 135 if (MHD_INVALID_SOCKET != mhd_sckt)
136 { 136 {
137 if ( (urh->out_buffer_used < urh->out_buffer_size) && 137 if ( (urh->out_buffer_used < urh->out_buffer_size) &&
138 (! MHD_add_to_fd_set_ (mhd_sckt, 138 (! MHD_add_to_fd_set_ (mhd_sckt,
139 rs, 139 rs,
140 max_fd, 140 max_fd,
141 fd_setsize)) ) 141 fd_setsize)) )
142 res = false; 142 res = false;
143 if ( (0 != urh->in_buffer_used) && 143 if ( (0 != urh->in_buffer_used) &&
144 (! MHD_add_to_fd_set_ (mhd_sckt, 144 (! MHD_add_to_fd_set_ (mhd_sckt,
145 ws, 145 ws,
146 max_fd, 146 max_fd,
147 fd_setsize)) ) 147 fd_setsize)) )
148 res = false; 148 res = false;
149 /* Do not monitor again for errors if error was detected before as 149 /* Do not monitor again for errors if error was detected before as
150 * error state is remembered. */ 150 * error state is remembered. */
151 if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) && 151 if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
152 ((0 != urh->out_buffer_size) || 152 ((0 != urh->out_buffer_size) ||
153 (0 != urh->in_buffer_size) || 153 (0 != urh->in_buffer_size) ||
154 (0 != urh->in_buffer_used))) 154 (0 != urh->in_buffer_used)))
155 MHD_add_to_fd_set_ (mhd_sckt, 155 MHD_add_to_fd_set_ (mhd_sckt,
156 es, 156 es,
157 max_fd, 157 max_fd,
158 fd_setsize); 158 fd_setsize);
159 } 159 }
160 160
161 return res; 161 return res;
162} 162}
@@ -207,77 +207,77 @@ internal_get_fdset2 (struct MHD_Daemon *daemon,
207 * or INFO_WRITE sockets will not fit 'except_fd_set'. */ 207 * or INFO_WRITE sockets will not fit 'except_fd_set'. */
208 /* Start from oldest connections. Make sense for W32 FDSETs. */ 208 /* Start from oldest connections. Make sense for W32 FDSETs. */
209 for (pos = daemon->connections_tail; NULL != pos; pos = posn) 209 for (pos = daemon->connections_tail; NULL != pos; pos = posn)
210 {
211 posn = pos->prev;
212
213 switch (pos->request.event_loop_info)
210 { 214 {
211 posn = pos->prev; 215 case MHD_EVENT_LOOP_INFO_READ:
212 216 if (! MHD_add_to_fd_set_ (pos->socket_fd,
213 switch (pos->request.event_loop_info) 217 read_fd_set,
214 { 218 max_fd,
215 case MHD_EVENT_LOOP_INFO_READ: 219 fd_setsize))
216 if (! MHD_add_to_fd_set_ (pos->socket_fd, 220 result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
217 read_fd_set,
218 max_fd,
219 fd_setsize))
220 result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
221#ifdef MHD_POSIX_SOCKETS 221#ifdef MHD_POSIX_SOCKETS
222 MHD_add_to_fd_set_ (pos->socket_fd, 222 MHD_add_to_fd_set_ (pos->socket_fd,
223 except_fd_set, 223 except_fd_set,
224 max_fd, 224 max_fd,
225 fd_setsize); 225 fd_setsize);
226#endif /* MHD_POSIX_SOCKETS */ 226#endif /* MHD_POSIX_SOCKETS */
227 break; 227 break;
228 case MHD_EVENT_LOOP_INFO_WRITE: 228 case MHD_EVENT_LOOP_INFO_WRITE:
229 if (! MHD_add_to_fd_set_ (pos->socket_fd, 229 if (! MHD_add_to_fd_set_ (pos->socket_fd,
230 write_fd_set, 230 write_fd_set,
231 max_fd, 231 max_fd,
232 fd_setsize)) 232 fd_setsize))
233 result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; 233 result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
234#ifdef MHD_POSIX_SOCKETS 234#ifdef MHD_POSIX_SOCKETS
235 MHD_add_to_fd_set_ (pos->socket_fd, 235 MHD_add_to_fd_set_ (pos->socket_fd,
236 except_fd_set, 236 except_fd_set,
237 max_fd, 237 max_fd,
238 fd_setsize); 238 fd_setsize);
239#endif /* MHD_POSIX_SOCKETS */ 239#endif /* MHD_POSIX_SOCKETS */
240 break; 240 break;
241 case MHD_EVENT_LOOP_INFO_BLOCK: 241 case MHD_EVENT_LOOP_INFO_BLOCK:
242 if ( (NULL == except_fd_set) || 242 if ( (NULL == except_fd_set) ||
243 ! MHD_add_to_fd_set_ (pos->socket_fd, 243 ! MHD_add_to_fd_set_ (pos->socket_fd,
244 except_fd_set, 244 except_fd_set,
245 max_fd, 245 max_fd,
246 fd_setsize)) 246 fd_setsize))
247 result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; 247 result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
248 break; 248 break;
249 case MHD_EVENT_LOOP_INFO_CLEANUP: 249 case MHD_EVENT_LOOP_INFO_CLEANUP:
250 /* this should never happen */ 250 /* this should never happen */
251 break; 251 break;
252 }
253 } 252 }
253 }
254#ifdef MHD_WINSOCK_SOCKETS 254#ifdef MHD_WINSOCK_SOCKETS
255 /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets 255 /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
256 * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will 256 * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
257 * not be pushed out. */ 257 * not be pushed out. */
258 for (pos = daemon->connections_tail; NULL != pos; pos = posn) 258 for (pos = daemon->connections_tail; NULL != pos; pos = posn)
259 { 259 {
260 posn = pos->prev; 260 posn = pos->prev;
261 MHD_add_to_fd_set_ (pos->socket_fd, 261 MHD_add_to_fd_set_ (pos->socket_fd,
262 except_fd_set, 262 except_fd_set,
263 max_fd, 263 max_fd,
264 fd_setsize); 264 fd_setsize);
265 } 265 }
266#endif /* MHD_WINSOCK_SOCKETS */ 266#endif /* MHD_WINSOCK_SOCKETS */
267#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 267#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
268 { 268 {
269 struct MHD_UpgradeResponseHandle *urh; 269 struct MHD_UpgradeResponseHandle *urh;
270 270
271 for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) 271 for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
272 { 272 {
273 if (! urh_to_fdset (urh, 273 if (! urh_to_fdset (urh,
274 read_fd_set, 274 read_fd_set,
275 write_fd_set, 275 write_fd_set,
276 except_fd_set, 276 except_fd_set,
277 max_fd, 277 max_fd,
278 fd_setsize)) 278 fd_setsize))
279 result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; 279 result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
280 } 280 }
281 } 281 }
282#endif 282#endif
283 return result; 283 return result;
@@ -313,11 +313,11 @@ internal_get_fdset2 (struct MHD_Daemon *daemon,
313 */ 313 */
314enum MHD_StatusCode 314enum MHD_StatusCode
315MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon, 315MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon,
316 fd_set *read_fd_set, 316 fd_set *read_fd_set,
317 fd_set *write_fd_set, 317 fd_set *write_fd_set,
318 fd_set *except_fd_set, 318 fd_set *except_fd_set,
319 MHD_socket *max_fd, 319 MHD_socket *max_fd,
320 unsigned int fd_setsize) 320 unsigned int fd_setsize)
321{ 321{
322 if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) || 322 if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) ||
323 (MHD_ELS_POLL == daemon->event_loop_syscall) ) 323 (MHD_ELS_POLL == daemon->event_loop_syscall) )
@@ -325,28 +325,28 @@ MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon,
325 325
326#ifdef EPOLL_SUPPORT 326#ifdef EPOLL_SUPPORT
327 if (MHD_ELS_EPOLL == daemon->event_loop_syscall) 327 if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
328 { 328 {
329 if (daemon->shutdown) 329 if (daemon->shutdown)
330 return MHD_SC_DAEMON_ALREADY_SHUTDOWN; 330 return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
331 331
332 /* we're in epoll mode, use the epoll FD as a stand-in for 332 /* we're in epoll mode, use the epoll FD as a stand-in for
333 the entire event set */ 333 the entire event set */
334 334
335 return MHD_add_to_fd_set_ (daemon->epoll_fd, 335 return MHD_add_to_fd_set_ (daemon->epoll_fd,
336 read_fd_set, 336 read_fd_set,
337 max_fd, 337 max_fd,
338 fd_setsize) 338 fd_setsize)
339 ? MHD_SC_OK 339 ? MHD_SC_OK
340 : MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; 340 : MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
341 } 341 }
342#endif 342#endif
343 343
344 return internal_get_fdset2 (daemon, 344 return internal_get_fdset2 (daemon,
345 read_fd_set, 345 read_fd_set,
346 write_fd_set, 346 write_fd_set,
347 except_fd_set, 347 except_fd_set,
348 max_fd, 348 max_fd,
349 fd_setsize); 349 fd_setsize);
350} 350}
351 351
352 352
@@ -374,23 +374,23 @@ urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
374 urh->mhd.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); 374 urh->mhd.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY);
375 375
376 if (MHD_INVALID_SOCKET != conn_sckt) 376 if (MHD_INVALID_SOCKET != conn_sckt)
377 { 377 {
378 if (FD_ISSET (conn_sckt, rs)) 378 if (FD_ISSET (conn_sckt, rs))
379 urh->app.celi |= MHD_EPOLL_STATE_READ_READY; 379 urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
380 if (FD_ISSET (conn_sckt, ws)) 380 if (FD_ISSET (conn_sckt, ws))
381 urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; 381 urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
382 if (FD_ISSET (conn_sckt, es)) 382 if (FD_ISSET (conn_sckt, es))
383 urh->app.celi |= MHD_EPOLL_STATE_ERROR; 383 urh->app.celi |= MHD_EPOLL_STATE_ERROR;
384 } 384 }
385 if ((MHD_INVALID_SOCKET != mhd_sckt)) 385 if ((MHD_INVALID_SOCKET != mhd_sckt))
386 { 386 {
387 if (FD_ISSET (mhd_sckt, rs)) 387 if (FD_ISSET (mhd_sckt, rs))
388 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; 388 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
389 if (FD_ISSET (mhd_sckt, ws)) 389 if (FD_ISSET (mhd_sckt, ws))
390 urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; 390 urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
391 if (FD_ISSET (mhd_sckt, es)) 391 if (FD_ISSET (mhd_sckt, es))
392 urh->mhd.celi |= MHD_EPOLL_STATE_ERROR; 392 urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
393 } 393 }
394} 394}
395#endif 395#endif
396 396
@@ -425,7 +425,7 @@ internal_run_from_select (struct MHD_Daemon *daemon,
425 /* Clear ITC to avoid spinning select */ 425 /* Clear ITC to avoid spinning select */
426 /* Do it before any other processing so new signals 426 /* Do it before any other processing so new signals
427 will trigger select again and will be processed */ 427 will trigger select again and will be processed */
428 if ( (MHD_ITC_IS_VALID_(daemon->itc)) && 428 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
429 (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), 429 (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
430 read_fd_set)) ) 430 read_fd_set)) )
431 MHD_itc_clear_ (daemon->itc); 431 MHD_itc_clear_ (daemon->itc);
@@ -438,49 +438,49 @@ internal_run_from_select (struct MHD_Daemon *daemon,
438 (void) MHD_accept_connection_ (daemon); 438 (void) MHD_accept_connection_ (daemon);
439 439
440 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) 440 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
441 {
442 /* do not have a thread per connection, process all connections now */
443 prev = daemon->connections_tail;
444 while (NULL != (pos = prev))
441 { 445 {
442 /* do not have a thread per connection, process all connections now */ 446 prev = pos->prev;
443 prev = daemon->connections_tail; 447 ds = pos->socket_fd;
444 while (NULL != (pos = prev)) 448 if (MHD_INVALID_SOCKET == ds)
445 { 449 continue;
446 prev = pos->prev; 450 MHD_connection_call_handlers_ (pos,
447 ds = pos->socket_fd; 451 FD_ISSET (ds,
448 if (MHD_INVALID_SOCKET == ds) 452 read_fd_set),
449 continue; 453 FD_ISSET (ds,
450 MHD_connection_call_handlers_ (pos, 454 write_fd_set),
451 FD_ISSET (ds, 455 FD_ISSET (ds,
452 read_fd_set), 456 except_fd_set));
453 FD_ISSET (ds,
454 write_fd_set),
455 FD_ISSET (ds,
456 except_fd_set));
457 }
458 } 457 }
458 }
459 459
460#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 460#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
461 /* handle upgraded HTTPS connections */ 461 /* handle upgraded HTTPS connections */
462 for (urh = daemon->urh_tail; NULL != urh; urh = urhn) 462 for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
463 {
464 urhn = urh->prev;
465 /* update urh state based on select() output */
466 urh_from_fdset (urh,
467 read_fd_set,
468 write_fd_set,
469 except_fd_set);
470 /* call generic forwarding function for passing data */
471 MHD_upgrade_response_handle_process_ (urh);
472 /* Finished forwarding? */
473 if ( (0 == urh->in_buffer_size) &&
474 (0 == urh->out_buffer_size) &&
475 (0 == urh->in_buffer_used) &&
476 (0 == urh->out_buffer_used) )
463 { 477 {
464 urhn = urh->prev; 478 MHD_connection_finish_forward_ (urh->connection);
465 /* update urh state based on select() output */ 479 urh->clean_ready = true;
466 urh_from_fdset (urh, 480 /* Resuming will move connection to cleanup list. */
467 read_fd_set, 481 MHD_request_resume (&urh->connection->request);
468 write_fd_set,
469 except_fd_set);
470 /* call generic forwarding function for passing data */
471 MHD_upgrade_response_handle_process_ (urh);
472 /* Finished forwarding? */
473 if ( (0 == urh->in_buffer_size) &&
474 (0 == urh->out_buffer_size) &&
475 (0 == urh->in_buffer_used) &&
476 (0 == urh->out_buffer_used) )
477 {
478 MHD_connection_finish_forward_ (urh->connection);
479 urh->clean_ready = true;
480 /* Resuming will move connection to cleanup list. */
481 MHD_request_resume (&urh->connection->request);
482 }
483 } 482 }
483 }
484#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 484#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
485 MHD_connection_cleanup_ (daemon); 485 MHD_connection_cleanup_ (daemon);
486 return MHD_SC_OK; 486 return MHD_SC_OK;
@@ -500,80 +500,80 @@ MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con)
500 struct MHD_UpgradeResponseHandle *urh = con->request.urh; 500 struct MHD_UpgradeResponseHandle *urh = con->request.urh;
501 501
502 while ( (0 != urh->in_buffer_size) || 502 while ( (0 != urh->in_buffer_size) ||
503 (0 != urh->out_buffer_size) || 503 (0 != urh->out_buffer_size) ||
504 (0 != urh->in_buffer_used) || 504 (0 != urh->in_buffer_used) ||
505 (0 != urh->out_buffer_used) ) 505 (0 != urh->out_buffer_used) )
506 {
507 /* use select */
508 fd_set rs;
509 fd_set ws;
510 fd_set es;
511 MHD_socket max_fd;
512 int num_ready;
513 bool result;
514
515 FD_ZERO (&rs);
516 FD_ZERO (&ws);
517 FD_ZERO (&es);
518 max_fd = MHD_INVALID_SOCKET;
519 result = urh_to_fdset (urh,
520 &rs,
521 &ws,
522 &es,
523 &max_fd,
524 FD_SETSIZE);
525 if (! result)
506 { 526 {
507 /* use select */
508 fd_set rs;
509 fd_set ws;
510 fd_set es;
511 MHD_socket max_fd;
512 int num_ready;
513 bool result;
514
515 FD_ZERO (&rs);
516 FD_ZERO (&ws);
517 FD_ZERO (&es);
518 max_fd = MHD_INVALID_SOCKET;
519 result = urh_to_fdset (urh,
520 &rs,
521 &ws,
522 &es,
523 &max_fd,
524 FD_SETSIZE);
525 if (! result)
526 {
527#ifdef HAVE_MESSAGES 527#ifdef HAVE_MESSAGES
528 MHD_DLOG (con->daemon, 528 MHD_DLOG (con->daemon,
529 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, 529 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
530 _("Error preparing select\n")); 530 _ ("Error preparing select\n"));
531#endif 531#endif
532 break; 532 break;
533 } 533 }
534 /* FIXME: does this check really needed? */ 534 /* FIXME: does this check really needed? */
535 if (MHD_INVALID_SOCKET != max_fd) 535 if (MHD_INVALID_SOCKET != max_fd)
536 { 536 {
537 struct timeval* tvp; 537 struct timeval*tvp;
538 struct timeval tv; 538 struct timeval tv;
539 if ( (con->tls_read_ready) && 539 if ( (con->tls_read_ready) &&
540 (urh->in_buffer_used < urh->in_buffer_size)) 540 (urh->in_buffer_used < urh->in_buffer_size))
541 { /* No need to wait if incoming data is already pending in TLS buffers. */ 541 { /* No need to wait if incoming data is already pending in TLS buffers. */
542 tv.tv_sec = 0; 542 tv.tv_sec = 0;
543 tv.tv_usec = 0; 543 tv.tv_usec = 0;
544 tvp = &tv; 544 tvp = &tv;
545 } 545 }
546 else
547 tvp = NULL;
548 num_ready = MHD_SYS_select_ (max_fd + 1,
549 &rs,
550 &ws,
551 &es,
552 tvp);
553 }
554 else 546 else
555 num_ready = 0; 547 tvp = NULL;
556 if (num_ready < 0) 548 num_ready = MHD_SYS_select_ (max_fd + 1,
557 { 549 &rs,
558 const int err = MHD_socket_get_error_(); 550 &ws,
551 &es,
552 tvp);
553 }
554 else
555 num_ready = 0;
556 if (num_ready < 0)
557 {
558 const int err = MHD_socket_get_error_ ();
559 559
560 if (MHD_SCKT_ERR_IS_EINTR_(err)) 560 if (MHD_SCKT_ERR_IS_EINTR_ (err))
561 continue; 561 continue;
562#ifdef HAVE_MESSAGES 562#ifdef HAVE_MESSAGES
563 MHD_DLOG (con->daemon, 563 MHD_DLOG (con->daemon,
564 MHD_SC_UNEXPECTED_SELECT_ERROR, 564 MHD_SC_UNEXPECTED_SELECT_ERROR,
565 _("Error during select (%d): `%s'\n"), 565 _ ("Error during select (%d): `%s'\n"),
566 err, 566 err,
567 MHD_socket_strerr_ (err)); 567 MHD_socket_strerr_ (err));
568#endif 568#endif
569 break; 569 break;
570 }
571 urh_from_fdset (urh,
572 &rs,
573 &ws,
574 &es);
575 MHD_upgrade_response_handle_process_ (urh);
576 } 570 }
571 urh_from_fdset (urh,
572 &rs,
573 &ws,
574 &es);
575 MHD_upgrade_response_handle_process_ (urh);
576 }
577} 577}
578#endif 578#endif
579 579
@@ -602,37 +602,37 @@ MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con)
602 */ 602 */
603enum MHD_StatusCode 603enum MHD_StatusCode
604MHD_daemon_run_from_select (struct MHD_Daemon *daemon, 604MHD_daemon_run_from_select (struct MHD_Daemon *daemon,
605 const fd_set *read_fd_set, 605 const fd_set *read_fd_set,
606 606
607 607
608 const fd_set *write_fd_set, 608 const fd_set *write_fd_set,
609 const fd_set *except_fd_set) 609 const fd_set *except_fd_set)
610{ 610{
611 if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) || 611 if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) ||
612 (MHD_ELS_POLL == daemon->event_loop_syscall) ) 612 (MHD_ELS_POLL == daemon->event_loop_syscall) )
613 return MHD_SC_CONFIGURATION_MISSMATCH_FOR_RUN_SELECT; 613 return MHD_SC_CONFIGURATION_MISSMATCH_FOR_RUN_SELECT;
614 if (MHD_ELS_EPOLL == daemon->event_loop_syscall) 614 if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
615 { 615 {
616#ifdef EPOLL_SUPPORT 616#ifdef EPOLL_SUPPORT
617 enum MHD_StatusCode sc; 617 enum MHD_StatusCode sc;
618 618
619 sc = MHD_daemon_epoll_ (daemon, 619 sc = MHD_daemon_epoll_ (daemon,
620 MHD_NO); 620 MHD_NO);
621 MHD_connection_cleanup_ (daemon); 621 MHD_connection_cleanup_ (daemon);
622 return sc; 622 return sc;
623#else /* ! EPOLL_SUPPORT */ 623#else /* ! EPOLL_SUPPORT */
624 return MHD_NO; 624 return MHD_NO;
625#endif /* ! EPOLL_SUPPORT */ 625#endif /* ! EPOLL_SUPPORT */
626 } 626 }
627 627
628 /* Resuming external connections when using an extern mainloop */ 628 /* Resuming external connections when using an extern mainloop */
629 if (! daemon->disallow_suspend_resume) 629 if (! daemon->disallow_suspend_resume)
630 (void) MHD_resume_suspended_connections_ (daemon); 630 (void) MHD_resume_suspended_connections_ (daemon);
631 631
632 return internal_run_from_select (daemon, 632 return internal_run_from_select (daemon,
633 read_fd_set, 633 read_fd_set,
634 write_fd_set, 634 write_fd_set,
635 except_fd_set); 635 except_fd_set);
636} 636}
637 637
638 638
@@ -646,7 +646,7 @@ MHD_daemon_run_from_select (struct MHD_Daemon *daemon,
646 */ 646 */
647enum MHD_StatusCode 647enum MHD_StatusCode
648MHD_daemon_select_ (struct MHD_Daemon *daemon, 648MHD_daemon_select_ (struct MHD_Daemon *daemon,
649 int may_block) 649 int may_block)
650{ 650{
651 int num_ready; 651 int num_ready;
652 fd_set rs; 652 fd_set rs;
@@ -675,74 +675,75 @@ MHD_daemon_select_ (struct MHD_Daemon *daemon,
675 may_block = MHD_NO; 675 may_block = MHD_NO;
676 676
677 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) 677 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
678 { 678 {
679 679
680 /* single-threaded, go over everything */ 680 /* single-threaded, go over everything */
681 if (MHD_SC_OK != 681 if (MHD_SC_OK !=
682 (sc = internal_get_fdset2 (daemon, 682 (sc = internal_get_fdset2 (daemon,
683 &rs, 683 &rs,
684 &ws, 684 &ws,
685 &es, 685 &es,
686 &maxsock, 686 &maxsock,
687 FD_SETSIZE))) 687 FD_SETSIZE)))
688 { 688 {
689#ifdef HAVE_MESSAGES 689#ifdef HAVE_MESSAGES
690 MHD_DLOG (daemon, 690 MHD_DLOG (daemon,
691 sc, 691 sc,
692 _("Could not obtain daemon fdsets")); 692 _ ("Could not obtain daemon fdsets"));
693#endif 693#endif
694 }
695 } 694 }
695 }
696 else 696 else
697 {
698 /* accept only, have one thread per connection */
699 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
700 (! daemon->was_quiesced) &&
701 (! MHD_add_to_fd_set_ (ls,
702 &rs,
703 &maxsock,
704 FD_SETSIZE)) )
697 { 705 {
698 /* accept only, have one thread per connection */
699 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
700 (! daemon->was_quiesced) &&
701 (! MHD_add_to_fd_set_ (ls,
702 &rs,
703 &maxsock,
704 FD_SETSIZE)) )
705 {
706#ifdef HAVE_MESSAGES 706#ifdef HAVE_MESSAGES
707 MHD_DLOG (daemon, 707 MHD_DLOG (daemon,
708 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE, 708 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
709 _("Could not add listen socket to fdset")); 709 _ ("Could not add listen socket to fdset"));
710#endif 710#endif
711 return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; 711 return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
712 }
713 } 712 }
714 if ( (MHD_ITC_IS_VALID_(daemon->itc)) && 713 }
714 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
715 (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), 715 (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
716 &rs, 716 &rs,
717 &maxsock, 717 &maxsock,
718 FD_SETSIZE)) ) 718 FD_SETSIZE)) )
719 { 719 {
720#if defined(MHD_WINSOCK_SOCKETS) 720#if defined(MHD_WINSOCK_SOCKETS)
721 /* fdset limit reached, new connections 721 /* fdset limit reached, new connections
722 cannot be handled. Remove listen socket FD 722 cannot be handled. Remove listen socket FD
723 from fdset and retry to add ITC FD. */ 723 from fdset and retry to add ITC FD. */
724 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && 724 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
725 (! daemon->was_quiesced) ) 725 (! daemon->was_quiesced) )
726 { 726 {
727 FD_CLR (ls, 727 FD_CLR (ls,
728 &rs); 728 &rs);
729 if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_(daemon->itc), 729 if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
730 &rs, 730 &rs,
731 &maxsock, 731 &maxsock,
732 FD_SETSIZE)) 732 FD_SETSIZE))
733 { 733 {
734#endif /* MHD_WINSOCK_SOCKETS */ 734#endif /* MHD_WINSOCK_SOCKETS */
735 sc = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE; 735 sc = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
736#ifdef HAVE_MESSAGES 736#ifdef HAVE_MESSAGES
737 MHD_DLOG (daemon, 737 MHD_DLOG (daemon,
738 sc, 738 sc,
739 _("Could not add control inter-thread communication channel FD to fdset")); 739 _ (
740 "Could not add control inter-thread communication channel FD to fdset"));
740#endif 741#endif
741#if defined(MHD_WINSOCK_SOCKETS) 742#if defined(MHD_WINSOCK_SOCKETS)
742 } 743 }
743 } 744}
744#endif /* MHD_WINSOCK_SOCKETS */ 745#endif /* MHD_WINSOCK_SOCKETS */
745 } 746 }
746 /* Stop listening if we are at the configured connection limit */ 747 /* Stop listening if we are at the configured connection limit */
747 /* If we're at the connection limit, no point in really 748 /* If we're at the connection limit, no point in really
748 accepting new connections; however, make sure we do not miss 749 accepting new connections; however, make sure we do not miss
@@ -750,35 +751,35 @@ MHD_daemon_select_ (struct MHD_Daemon *daemon,
750 only do this optimization if we have a signaling ITC in 751 only do this optimization if we have a signaling ITC in
751 place. */ 752 place. */
752 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) && 753 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
753 (MHD_ITC_IS_VALID_(daemon->itc)) && 754 (MHD_ITC_IS_VALID_ (daemon->itc)) &&
754 ( (daemon->connections == daemon->global_connection_limit) || 755 ( (daemon->connections == daemon->global_connection_limit) ||
755 (daemon->at_limit) ) ) 756 (daemon->at_limit) ) )
756 { 757 {
757 FD_CLR (ls, 758 FD_CLR (ls,
758 &rs); 759 &rs);
759 } 760 }
760 tv = NULL; 761 tv = NULL;
761 if (MHD_SC_OK != sc) 762 if (MHD_SC_OK != sc)
762 may_block = MHD_NO; 763 may_block = MHD_NO;
763 if (MHD_NO == may_block) 764 if (MHD_NO == may_block)
764 { 765 {
765 timeout.tv_usec = 0; 766 timeout.tv_usec = 0;
766 timeout.tv_sec = 0; 767 timeout.tv_sec = 0;
767 tv = &timeout; 768 tv = &timeout;
768 } 769 }
769 else if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) && 770 else if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) &&
770 (MHD_SC_OK == 771 (MHD_SC_OK ==
771 MHD_daemon_get_timeout (daemon, 772 MHD_daemon_get_timeout (daemon,
772 &ltimeout)) ) 773 &ltimeout)) )
773 { 774 {
774 /* ltimeout is in ms */ 775 /* ltimeout is in ms */
775 timeout.tv_usec = (ltimeout % 1000) * 1000; 776 timeout.tv_usec = (ltimeout % 1000) * 1000;
776 if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX) 777 if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX)
777 timeout.tv_sec = TIMEVAL_TV_SEC_MAX; 778 timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
778 else 779 else
779 timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE)(ltimeout / 1000); 780 timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (ltimeout / 1000);
780 tv = &timeout; 781 tv = &timeout;
781 } 782 }
782 num_ready = MHD_SYS_select_ (maxsock + 1, 783 num_ready = MHD_SYS_select_ (maxsock + 1,
783 &rs, 784 &rs,
784 &ws, 785 &ws,
@@ -787,24 +788,24 @@ MHD_daemon_select_ (struct MHD_Daemon *daemon,
787 if (daemon->shutdown) 788 if (daemon->shutdown)
788 return MHD_SC_DAEMON_ALREADY_SHUTDOWN; 789 return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
789 if (num_ready < 0) 790 if (num_ready < 0)
790 { 791 {
791 const int err = MHD_socket_get_error_ (); 792 const int err = MHD_socket_get_error_ ();
792 793
793 if (MHD_SCKT_ERR_IS_EINTR_(err)) 794 if (MHD_SCKT_ERR_IS_EINTR_ (err))
794 return sc; 795 return sc;
795#ifdef HAVE_MESSAGES 796#ifdef HAVE_MESSAGES
796 MHD_DLOG (daemon, 797 MHD_DLOG (daemon,
797 MHD_SC_UNEXPECTED_SELECT_ERROR, 798 MHD_SC_UNEXPECTED_SELECT_ERROR,
798 _("select failed: %s\n"), 799 _ ("select failed: %s\n"),
799 MHD_socket_strerr_ (err)); 800 MHD_socket_strerr_ (err));
800#endif 801#endif
801 return MHD_SC_UNEXPECTED_SELECT_ERROR; 802 return MHD_SC_UNEXPECTED_SELECT_ERROR;
802 } 803 }
803 if (MHD_SC_OK != 804 if (MHD_SC_OK !=
804 (sc2 = internal_run_from_select (daemon, 805 (sc2 = internal_run_from_select (daemon,
805 &rs, 806 &rs,
806 &ws, 807 &ws,
807 &es))) 808 &es)))
808 return sc2; 809 return sc2;
809 return sc; 810 return sc;
810} 811}
diff --git a/src/lib/daemon_select.h b/src/lib/daemon_select.h
index d6e9e106..7dac8a80 100644
--- a/src/lib/daemon_select.h
+++ b/src/lib/daemon_select.h
@@ -36,8 +36,8 @@
36 */ 36 */
37enum MHD_StatusCode 37enum MHD_StatusCode
38MHD_daemon_select_ (struct MHD_Daemon *daemon, 38MHD_daemon_select_ (struct MHD_Daemon *daemon,
39 int may_block) 39 int may_block)
40 MHD_NONNULL(1); 40MHD_NONNULL (1);
41 41
42 42
43#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 43#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
@@ -49,7 +49,7 @@ MHD_daemon_select_ (struct MHD_Daemon *daemon,
49 */ 49 */
50void 50void
51MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con) 51MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con)
52 MHD_NONNULL(1); 52MHD_NONNULL (1);
53#endif 53#endif
54 54
55#endif 55#endif
diff --git a/src/lib/daemon_start.c b/src/lib/daemon_start.c
index 52124c77..c8c498be 100644
--- a/src/lib/daemon_start.c
+++ b/src/lib/daemon_start.c
@@ -46,63 +46,64 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
46 /* Apply the socket options according to 46 /* Apply the socket options according to
47 listening_address_reuse. */ 47 listening_address_reuse. */
48 if (daemon->allow_address_reuse) 48 if (daemon->allow_address_reuse)
49 { 49 {
50 /* User requested to allow reusing listening address:port. */ 50 /* User requested to allow reusing listening address:port. */
51#ifndef MHD_WINSOCK_SOCKETS 51#ifndef MHD_WINSOCK_SOCKETS
52 /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if 52 /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
53 * it doesn't work. */ 53 * it doesn't work. */
54 if (0 > setsockopt (daemon->listen_socket, 54 if (0 > setsockopt (daemon->listen_socket,
55 SOL_SOCKET, 55 SOL_SOCKET,
56 SO_REUSEADDR, 56 SO_REUSEADDR,
57 (void *) &on, 57 (void *) &on,
58 sizeof (on))) 58 sizeof (on)))
59 { 59 {
60#ifdef HAVE_MESSAGES 60#ifdef HAVE_MESSAGES
61 MHD_DLOG (daemon, 61 MHD_DLOG (daemon,
62 MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED, 62 MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED,
63 _("setsockopt failed: %s\n"), 63 _ ("setsockopt failed: %s\n"),
64 MHD_socket_last_strerr_ ()); 64 MHD_socket_last_strerr_ ());
65#endif 65#endif
66 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED; 66 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED;
67 } 67 }
68 return MHD_SC_OK; 68 return MHD_SC_OK;
69#endif /* ! MHD_WINSOCK_SOCKETS */ 69#endif /* ! MHD_WINSOCK_SOCKETS */
70 /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms. 70 /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
71 * Fail if SO_REUSEPORT is not defined or setsockopt fails. 71 * Fail if SO_REUSEPORT is not defined or setsockopt fails.
72 */ 72 */
73 /* SO_REUSEADDR on W32 has the same semantics 73 /* SO_REUSEADDR on W32 has the same semantics
74 as SO_REUSEPORT on BSD/Linux */ 74 as SO_REUSEPORT on BSD/Linux */
75#if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) 75#if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
76 if (0 > setsockopt (daemon->listen_socket, 76 if (0 > setsockopt (daemon->listen_socket,
77 SOL_SOCKET, 77 SOL_SOCKET,
78#ifndef MHD_WINSOCK_SOCKETS 78#ifndef MHD_WINSOCK_SOCKETS
79 SO_REUSEPORT, 79 SO_REUSEPORT,
80#else /* MHD_WINSOCK_SOCKETS */ 80#else /* MHD_WINSOCK_SOCKETS */
81 SO_REUSEADDR, 81 SO_REUSEADDR,
82#endif /* MHD_WINSOCK_SOCKETS */ 82#endif /* MHD_WINSOCK_SOCKETS */
83 (void *) &on, 83 (void *) &on,
84 sizeof (on))) 84 sizeof (on)))
85 { 85 {
86#ifdef HAVE_MESSAGES 86#ifdef HAVE_MESSAGES
87 MHD_DLOG (daemon, 87 MHD_DLOG (daemon,
88 MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED, 88 MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED,
89 _("setsockopt failed: %s\n"), 89 _ ("setsockopt failed: %s\n"),
90 MHD_socket_last_strerr_ ()); 90 MHD_socket_last_strerr_ ());
91#endif 91#endif
92 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED; 92 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED;
93 } 93 }
94 return MHD_SC_OK; 94 return MHD_SC_OK;
95#else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ 95#else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
96 /* we're supposed to allow address:port re-use, but 96 /* we're supposed to allow address:port re-use, but
97 on this platform we cannot; fail hard */ 97 on this platform we cannot; fail hard */
98#ifdef HAVE_MESSAGES 98#ifdef HAVE_MESSAGES
99 MHD_DLOG (daemon, 99 MHD_DLOG (daemon,
100 MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED, 100 MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED,
101 _("Cannot allow listening address reuse: SO_REUSEPORT not defined\n")); 101 _ (
102 "Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
102#endif 103#endif
103 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED; 104 return MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED;
104#endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ 105#endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
105 } 106 }
106 107
107 /* if (! daemon->allow_address_reuse) */ 108 /* if (! daemon->allow_address_reuse) */
108 /* User requested to disallow reusing listening address:port. 109 /* User requested to disallow reusing listening address:port.
@@ -111,32 +112,33 @@ configure_listen_reuse (struct MHD_Daemon *daemon)
111 * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE 112 * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE
112 * or setsockopt fails. 113 * or setsockopt fails.
113 */ 114 */
114#if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ 115#if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
115 (defined(__sun) && defined(SO_EXCLBIND)) 116 (defined(__sun) && defined(SO_EXCLBIND))
116 if (0 > setsockopt (daemon->listen_socket, 117 if (0 > setsockopt (daemon->listen_socket,
117 SOL_SOCKET, 118 SOL_SOCKET,
118#ifdef SO_EXCLUSIVEADDRUSE 119#ifdef SO_EXCLUSIVEADDRUSE
119 SO_EXCLUSIVEADDRUSE, 120 SO_EXCLUSIVEADDRUSE,
120#else /* SO_EXCLBIND */ 121#else /* SO_EXCLBIND */
121 SO_EXCLBIND, 122 SO_EXCLBIND,
122#endif /* SO_EXCLBIND */ 123#endif /* SO_EXCLBIND */
123 (void *) &on, 124 (void *) &on,
124 sizeof (on))) 125 sizeof (on)))
125 { 126 {
126#ifdef HAVE_MESSAGES 127#ifdef HAVE_MESSAGES
127 MHD_DLOG (daemon, 128 MHD_DLOG (daemon,
128 MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED, 129 MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED,
129 _("setsockopt failed: %s\n"), 130 _ ("setsockopt failed: %s\n"),
130 MHD_socket_last_strerr_ ()); 131 MHD_socket_last_strerr_ ());
131#endif 132#endif
132 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED; 133 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_FAILED;
133 } 134 }
134 return MHD_SC_OK; 135 return MHD_SC_OK;
135#elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */ 136#elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
136#ifdef HAVE_MESSAGES 137#ifdef HAVE_MESSAGES
137 MHD_DLOG (daemon, 138 MHD_DLOG (daemon,
138 MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED, 139 MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED,
139 _("Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n")); 140 _ (
141 "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
140#endif 142#endif
141 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED; 143 return MHD_SC_LISTEN_ADDRESS_REUSE_DISABLE_NOT_SUPPORTED;
142#endif /* MHD_WINSOCK_SOCKETS */ 144#endif /* MHD_WINSOCK_SOCKETS */
@@ -166,86 +168,86 @@ open_listen_socket (struct MHD_Daemon *daemon)
166 pf = -1; 168 pf = -1;
167 /* Determine address family */ 169 /* Determine address family */
168 switch (daemon->listen_af) 170 switch (daemon->listen_af)
171 {
172 case MHD_AF_NONE:
173 if (0 == daemon->listen_sa_len)
169 { 174 {
170 case MHD_AF_NONE: 175 /* no listening desired, that's OK */
171 if (0 == daemon->listen_sa_len) 176 return MHD_SC_OK;
172 { 177 }
173 /* no listening desired, that's OK */ 178 /* we have a listen address, get AF from there! */
174 return MHD_SC_OK; 179 switch (daemon->listen_sa.ss_family)
175 } 180 {
176 /* we have a listen address, get AF from there! */ 181 case AF_INET:
177 switch (daemon->listen_sa.ss_family) 182 pf = PF_INET;
178 { 183 use_v6 = false;
179 case AF_INET: 184 break;
180 pf = PF_INET;
181 use_v6 = false;
182 break;
183#ifdef AF_INET6 185#ifdef AF_INET6
184 case AF_INET6: 186 case AF_INET6:
185 pf = PF_INET6;
186 use_v6 = true;
187 break;
188#endif
189#ifdef AF_UNIX
190 case AF_UNIX:
191 pf = PF_UNIX;
192 use_v6 = false;
193 break;
194#endif
195 default:
196 return MHD_SC_AF_NOT_SUPPORTED_BY_BUILD;
197 } /* switch on ss_family */
198 break; /* MHD_AF_NONE */
199 case MHD_AF_AUTO:
200#if HAVE_INET6
201 pf = PF_INET6; 187 pf = PF_INET6;
202 use_v6 = true; 188 use_v6 = true;
203#else
204 pf = PF_INET;
205 use_v6 = false;
206#endif
207 break; 189 break;
208 case MHD_AF_INET4: 190#endif
191#ifdef AF_UNIX
192 case AF_UNIX:
193 pf = PF_UNIX;
209 use_v6 = false; 194 use_v6 = false;
210 pf = PF_INET;
211 break; 195 break;
212 case MHD_AF_INET6: 196#endif
213 case MHD_AF_DUAL: 197 default:
198 return MHD_SC_AF_NOT_SUPPORTED_BY_BUILD;
199 } /* switch on ss_family */
200 break; /* MHD_AF_NONE */
201 case MHD_AF_AUTO:
214#if HAVE_INET6 202#if HAVE_INET6
215 pf = PF_INET6; 203 pf = PF_INET6;
216 use_v6 = true; 204 use_v6 = true;
217 break; 205#else
206 pf = PF_INET;
207 use_v6 = false;
208#endif
209 break;
210 case MHD_AF_INET4:
211 use_v6 = false;
212 pf = PF_INET;
213 break;
214 case MHD_AF_INET6:
215 case MHD_AF_DUAL:
216#if HAVE_INET6
217 pf = PF_INET6;
218 use_v6 = true;
219 break;
218#else 220#else
219#ifdef HAVE_MESSAGES 221#ifdef HAVE_MESSAGES
220 MHD_DLOG (daemon, 222 MHD_DLOG (daemon,
221 MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD, 223 MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD,
222 _("IPv6 not supported by this build\n")); 224 _ ("IPv6 not supported by this build\n"));
223#endif 225#endif
224 return MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD; 226 return MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD;
225#endif 227#endif
226 } 228 }
227 mhd_assert (-1 != pf); 229 mhd_assert (-1 != pf);
228 /* try to open listen socket */ 230 /* try to open listen socket */
229 try_open_listen_socket: 231try_open_listen_socket:
230 daemon->listen_socket = MHD_socket_create_listen_(pf); 232 daemon->listen_socket = MHD_socket_create_listen_ (pf);
231 if ( (MHD_INVALID_SOCKET == daemon->listen_socket) && 233 if ( (MHD_INVALID_SOCKET == daemon->listen_socket) &&
232 (MHD_AF_AUTO == daemon->listen_af) && 234 (MHD_AF_AUTO == daemon->listen_af) &&
233 (use_v6) ) 235 (use_v6) )
234 { 236 {
235 use_v6 = false; 237 use_v6 = false;
236 pf = PF_INET; 238 pf = PF_INET;
237 goto try_open_listen_socket; 239 goto try_open_listen_socket;
238 } 240 }
239 if (MHD_INVALID_SOCKET == daemon->listen_socket) 241 if (MHD_INVALID_SOCKET == daemon->listen_socket)
240 { 242 {
241#ifdef HAVE_MESSAGES 243#ifdef HAVE_MESSAGES
242 MHD_DLOG (daemon, 244 MHD_DLOG (daemon,
243 MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET, 245 MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET,
244 _("Failed to create socket for listening: %s\n"), 246 _ ("Failed to create socket for listening: %s\n"),
245 MHD_socket_last_strerr_ ()); 247 MHD_socket_last_strerr_ ());
246#endif 248#endif
247 return MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET; 249 return MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET;
248 } 250 }
249 251
250 if (MHD_SC_OK != 252 if (MHD_SC_OK !=
251 (sc = configure_listen_reuse (daemon))) 253 (sc = configure_listen_reuse (daemon)))
@@ -253,156 +255,157 @@ open_listen_socket (struct MHD_Daemon *daemon)
253 255
254 /* configure for dual stack (or not) */ 256 /* configure for dual stack (or not) */
255 if (use_v6) 257 if (use_v6)
256 { 258 {
257#if defined IPPROTO_IPV6 && defined IPV6_V6ONLY 259#if defined IPPROTO_IPV6 && defined IPV6_V6ONLY
258 /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options" 260 /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
259 (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx); 261 (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
260 and may also be missing on older POSIX systems; good luck if you have any of those, 262 and may also be missing on older POSIX systems; good luck if you have any of those,
261 your IPv6 socket may then also bind against IPv4 anyway... */ 263 your IPv6 socket may then also bind against IPv4 anyway... */
262 const MHD_SCKT_OPT_BOOL_ v6_only = 264 const MHD_SCKT_OPT_BOOL_ v6_only =
263 (MHD_AF_INET6 == daemon->listen_af); 265 (MHD_AF_INET6 == daemon->listen_af);
264 if (0 > setsockopt (daemon->listen_socket, 266 if (0 > setsockopt (daemon->listen_socket,
265 IPPROTO_IPV6, 267 IPPROTO_IPV6,
266 IPV6_V6ONLY, 268 IPV6_V6ONLY,
267 (const void *) &v6_only, 269 (const void *) &v6_only,
268 sizeof (v6_only))) 270 sizeof (v6_only)))
269 { 271 {
270#ifdef HAVE_MESSAGES 272#ifdef HAVE_MESSAGES
271 MHD_DLOG (daemon, 273 MHD_DLOG (daemon,
272 MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_FAILED, 274 MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_FAILED,
273 _("setsockopt failed: %s\n"), 275 _ ("setsockopt failed: %s\n"),
274 MHD_socket_last_strerr_ ()); 276 MHD_socket_last_strerr_ ());
275#endif 277#endif
276 } 278 }
277#else 279#else
278#ifdef HAVE_MESSAGES 280#ifdef HAVE_MESSAGES
279 MHD_DLOG (daemon, 281 MHD_DLOG (daemon,
280 MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_NOT_SUPPORTED, 282 MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_NOT_SUPPORTED,
281 _("Cannot explicitly setup dual stack behavior on this platform\n")); 283 _ (
284 "Cannot explicitly setup dual stack behavior on this platform\n"));
282#endif 285#endif
283#endif 286#endif
284 } 287 }
285 288
286 /* Determine address to bind to */ 289 /* Determine address to bind to */
287 if (0 != daemon->listen_sa_len) 290 if (0 != daemon->listen_sa_len)
288 { 291 {
289 /* Bind address explicitly given */ 292 /* Bind address explicitly given */
290 sa = (const struct sockaddr *) &daemon->listen_sa; 293 sa = (const struct sockaddr *) &daemon->listen_sa;
291 addrlen = daemon->listen_sa_len; 294 addrlen = daemon->listen_sa_len;
292 } 295 }
293 else 296 else
294 { 297 {
295 /* Compute bind address based on port and AF */ 298 /* Compute bind address based on port and AF */
296#if HAVE_INET6 299#if HAVE_INET6
297 if (use_v6) 300 if (use_v6)
298 { 301 {
299#ifdef IN6ADDR_ANY_INIT 302#ifdef IN6ADDR_ANY_INIT
300 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT; 303 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
301#endif 304#endif
302 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &ss; 305 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &ss;
303 306
304 addrlen = sizeof (struct sockaddr_in6); 307 addrlen = sizeof (struct sockaddr_in6);
305 memset (sin6, 308 memset (sin6,
306 0, 309 0,
307 sizeof (struct sockaddr_in6)); 310 sizeof (struct sockaddr_in6));
308 sin6->sin6_family = AF_INET6; 311 sin6->sin6_family = AF_INET6;
309 sin6->sin6_port = htons (daemon->listen_port); 312 sin6->sin6_port = htons (daemon->listen_port);
310#ifdef IN6ADDR_ANY_INIT 313#ifdef IN6ADDR_ANY_INIT
311 sin6->sin6_addr = static_in6any; 314 sin6->sin6_addr = static_in6any;
312#endif 315#endif
313#if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 316#if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
314 sin6->sin6_len = sizeof (struct sockaddr_in6); 317 sin6->sin6_len = sizeof (struct sockaddr_in6);
315#endif 318#endif
316 } 319 }
317 else 320 else
318#endif 321#endif
319 { 322 {
320 struct sockaddr_in *sin4 = (struct sockaddr_in *) &ss; 323 struct sockaddr_in *sin4 = (struct sockaddr_in *) &ss;
321 324
322 addrlen = sizeof (struct sockaddr_in); 325 addrlen = sizeof (struct sockaddr_in);
323 memset (sin4, 326 memset (sin4,
324 0, 327 0,
325 sizeof (struct sockaddr_in)); 328 sizeof (struct sockaddr_in));
326 sin4->sin_family = AF_INET; 329 sin4->sin_family = AF_INET;
327 sin4->sin_port = htons (daemon->listen_port); 330 sin4->sin_port = htons (daemon->listen_port);
328 if (0 != INADDR_ANY) 331 if (0 != INADDR_ANY)
329 sin4->sin_addr.s_addr = htonl (INADDR_ANY); 332 sin4->sin_addr.s_addr = htonl (INADDR_ANY);
330#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 333#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
331 sin4->sin_len = sizeof (struct sockaddr_in); 334 sin4->sin_len = sizeof (struct sockaddr_in);
332#endif 335#endif
333 }
334 sa = (const struct sockaddr *) &ss;
335 } 336 }
337 sa = (const struct sockaddr *) &ss;
338 }
336 339
337 /* actually do the bind() */ 340 /* actually do the bind() */
338 if (-1 == bind (daemon->listen_socket, 341 if (-1 == bind (daemon->listen_socket,
339 sa, 342 sa,
340 addrlen)) 343 addrlen))
341 { 344 {
342#ifdef HAVE_MESSAGES 345#ifdef HAVE_MESSAGES
343 unsigned int port = 0; 346 unsigned int port = 0;
344 347
345 switch (sa->sa_family) 348 switch (sa->sa_family)
346 { 349 {
347 case AF_INET: 350 case AF_INET:
348 if (addrlen == sizeof (struct sockaddr_in)) 351 if (addrlen == sizeof (struct sockaddr_in))
349 port = ntohs (((const struct sockaddr_in *) sa)->sin_port); 352 port = ntohs (((const struct sockaddr_in *) sa)->sin_port);
350 else 353 else
351 port = UINT16_MAX + 1; /* indicate size error */ 354 port = UINT16_MAX + 1; /* indicate size error */
352 break; 355 break;
353 case AF_INET6: 356 case AF_INET6:
354 if (addrlen == sizeof (struct sockaddr_in6)) 357 if (addrlen == sizeof (struct sockaddr_in6))
355 port = ntohs (((const struct sockaddr_in6 *) sa)->sin6_port); 358 port = ntohs (((const struct sockaddr_in6 *) sa)->sin6_port);
356 else 359 else
357 port = UINT16_MAX + 1; /* indicate size error */ 360 port = UINT16_MAX + 1; /* indicate size error */
358 break; 361 break;
359 default: 362 default:
360 port = UINT_MAX; /* AF_UNIX? */ 363 port = UINT_MAX; /* AF_UNIX? */
361 break; 364 break;
362 }
363 MHD_DLOG (daemon,
364 MHD_SC_LISTEN_SOCKET_BIND_FAILED,
365 _("Failed to bind to port %u: %s\n"),
366 port,
367 MHD_socket_last_strerr_ ());
368#endif
369 return MHD_SC_LISTEN_SOCKET_BIND_FAILED;
370 } 365 }
366 MHD_DLOG (daemon,
367 MHD_SC_LISTEN_SOCKET_BIND_FAILED,
368 _ ("Failed to bind to port %u: %s\n"),
369 port,
370 MHD_socket_last_strerr_ ());
371#endif
372 return MHD_SC_LISTEN_SOCKET_BIND_FAILED;
373 }
371 374
372 /* setup TCP_FASTOPEN */ 375 /* setup TCP_FASTOPEN */
373#ifdef TCP_FASTOPEN 376#ifdef TCP_FASTOPEN
374 if (MHD_FOM_DISABLE != daemon->fast_open_method) 377 if (MHD_FOM_DISABLE != daemon->fast_open_method)
378 {
379 if (0 != setsockopt (daemon->listen_socket,
380 IPPROTO_TCP,
381 TCP_FASTOPEN,
382 &daemon->fo_queue_length,
383 sizeof (daemon->fo_queue_length)))
375 { 384 {
376 if (0 != setsockopt (daemon->listen_socket,
377 IPPROTO_TCP,
378 TCP_FASTOPEN,
379 &daemon->fo_queue_length,
380 sizeof (daemon->fo_queue_length)))
381 {
382#ifdef HAVE_MESSAGES 385#ifdef HAVE_MESSAGES
383 MHD_DLOG (daemon, 386 MHD_DLOG (daemon,
384 MHD_SC_FAST_OPEN_FAILURE, 387 MHD_SC_FAST_OPEN_FAILURE,
385 _("setsockopt failed: %s\n"), 388 _ ("setsockopt failed: %s\n"),
386 MHD_socket_last_strerr_ ()); 389 MHD_socket_last_strerr_ ());
387#endif 390#endif
388 if (MHD_FOM_REQUIRE == daemon->fast_open_method) 391 if (MHD_FOM_REQUIRE == daemon->fast_open_method)
389 return MHD_SC_FAST_OPEN_FAILURE; 392 return MHD_SC_FAST_OPEN_FAILURE;
390 } 393 }
391 } 394 }
392#endif 395#endif
393 396
394 /* setup listening */ 397 /* setup listening */
395 if (0 > listen (daemon->listen_socket, 398 if (0 > listen (daemon->listen_socket,
396 daemon->listen_backlog)) 399 daemon->listen_backlog))
397 { 400 {
398#ifdef HAVE_MESSAGES 401#ifdef HAVE_MESSAGES
399 MHD_DLOG (daemon, 402 MHD_DLOG (daemon,
400 MHD_SC_LISTEN_FAILURE, 403 MHD_SC_LISTEN_FAILURE,
401 _("Failed to listen for connections: %s\n"), 404 _ ("Failed to listen for connections: %s\n"),
402 MHD_socket_last_strerr_ ()); 405 MHD_socket_last_strerr_ ());
403#endif 406#endif
404 return MHD_SC_LISTEN_FAILURE; 407 return MHD_SC_LISTEN_FAILURE;
405 } 408 }
406 return MHD_SC_OK; 409 return MHD_SC_OK;
407} 410}
408 411
@@ -426,65 +429,66 @@ get_listen_port_number (struct MHD_Daemon *daemon)
426 return; /* nothing to be done */ 429 return; /* nothing to be done */
427 430
428 memset (&servaddr, 431 memset (&servaddr,
429 0, 432 0,
430 sizeof (struct sockaddr_storage)); 433 sizeof (struct sockaddr_storage));
431 addrlen = sizeof (servaddr); 434 addrlen = sizeof (servaddr);
432 if (0 != getsockname (daemon->listen_socket, 435 if (0 != getsockname (daemon->listen_socket,
433 (struct sockaddr *) &servaddr, 436 (struct sockaddr *) &servaddr,
434 &addrlen)) 437 &addrlen))
435 { 438 {
436#ifdef HAVE_MESSAGES 439#ifdef HAVE_MESSAGES
437 MHD_DLOG (daemon, 440 MHD_DLOG (daemon,
438 MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE, 441 MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE,
439 _("Failed to get listen port number: %s\n"), 442 _ ("Failed to get listen port number: %s\n"),
440 MHD_socket_last_strerr_ ()); 443 MHD_socket_last_strerr_ ());
441#endif /* HAVE_MESSAGES */ 444#endif /* HAVE_MESSAGES */
442 return; 445 return;
443 } 446 }
444#ifdef MHD_POSIX_SOCKETS 447#ifdef MHD_POSIX_SOCKETS
445 if (sizeof (servaddr) < addrlen) 448 if (sizeof (servaddr) < addrlen)
446 { 449 {
447 /* should be impossible with `struct sockaddr_storage` */ 450 /* should be impossible with `struct sockaddr_storage` */
448#ifdef HAVE_MESSAGES 451#ifdef HAVE_MESSAGES
449 MHD_DLOG (daemon, 452 MHD_DLOG (daemon,
450 MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE, 453 MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE,
451 _("Failed to get listen port number (`struct sockaddr_storage` too small!?)\n")); 454 _ (
455 "Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
452#endif /* HAVE_MESSAGES */ 456#endif /* HAVE_MESSAGES */
453 return; 457 return;
454 } 458 }
455#endif /* MHD_POSIX_SOCKETS */ 459#endif /* MHD_POSIX_SOCKETS */
456 switch (servaddr.ss_family) 460 switch (servaddr.ss_family)
461 {
462 case AF_INET:
457 { 463 {
458 case AF_INET: 464 struct sockaddr_in *s4 = (struct sockaddr_in *) &servaddr;
459 {
460 struct sockaddr_in *s4 = (struct sockaddr_in *) &servaddr;
461 465
462 daemon->listen_port = ntohs (s4->sin_port); 466 daemon->listen_port = ntohs (s4->sin_port);
463 break; 467 break;
464 } 468 }
465#ifdef HAVE_INET6 469#ifdef HAVE_INET6
466 case AF_INET6: 470 case AF_INET6:
467 { 471 {
468 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &servaddr; 472 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &servaddr;
469 473
470 daemon->listen_port = ntohs(s6->sin6_port); 474 daemon->listen_port = ntohs (s6->sin6_port);
471 break; 475 break;
472 } 476 }
473#endif /* HAVE_INET6 */ 477#endif /* HAVE_INET6 */
474#ifdef AF_UNIX 478#ifdef AF_UNIX
475 case AF_UNIX: 479 case AF_UNIX:
476 daemon->listen_port = 0; /* special value for UNIX domain sockets */ 480 daemon->listen_port = 0; /* special value for UNIX domain sockets */
477 break; 481 break;
478#endif 482#endif
479 default: 483 default:
480#ifdef HAVE_MESSAGES 484#ifdef HAVE_MESSAGES
481 MHD_DLOG (daemon, 485 MHD_DLOG (daemon,
482 MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF, 486 MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF,
483 _("Unknown address family!\n")); 487 _ ("Unknown address family!\n"));
484#endif 488#endif
485 daemon->listen_port = 0; /* ugh */ 489 daemon->listen_port = 0; /* ugh */
486 break; 490 break;
487 } 491 }
488} 492}
489 493
490 494
@@ -501,7 +505,7 @@ setup_epoll_fd (struct MHD_Daemon *daemon)
501 int fd; 505 int fd;
502 506
503#ifndef HAVE_MESSAGES 507#ifndef HAVE_MESSAGES
504 (void)daemon; /* Mute compiler warning. */ 508 (void) daemon; /* Mute compiler warning. */
505#endif /* ! HAVE_MESSAGES */ 509#endif /* ! HAVE_MESSAGES */
506 510
507#ifdef USE_EPOLL_CREATE1 511#ifdef USE_EPOLL_CREATE1
@@ -510,24 +514,24 @@ setup_epoll_fd (struct MHD_Daemon *daemon)
510 fd = epoll_create (MAX_EVENTS); 514 fd = epoll_create (MAX_EVENTS);
511#endif /* ! USE_EPOLL_CREATE1 */ 515#endif /* ! USE_EPOLL_CREATE1 */
512 if (MHD_INVALID_SOCKET == fd) 516 if (MHD_INVALID_SOCKET == fd)
513 { 517 {
514#ifdef HAVE_MESSAGES 518#ifdef HAVE_MESSAGES
515 MHD_DLOG (daemon, 519 MHD_DLOG (daemon,
516 MHD_SC_EPOLL_CTL_CREATE_FAILED, 520 MHD_SC_EPOLL_CTL_CREATE_FAILED,
517 _("Call to epoll_create1 failed: %s\n"), 521 _ ("Call to epoll_create1 failed: %s\n"),
518 MHD_socket_last_strerr_ ()); 522 MHD_socket_last_strerr_ ());
519#endif 523#endif
520 return MHD_INVALID_SOCKET; 524 return MHD_INVALID_SOCKET;
521 } 525 }
522#if !defined(USE_EPOLL_CREATE1) 526#if ! defined(USE_EPOLL_CREATE1)
523 if (! MHD_socket_noninheritable_ (fd)) 527 if (! MHD_socket_noninheritable_ (fd))
524 { 528 {
525#ifdef HAVE_MESSAGES 529#ifdef HAVE_MESSAGES
526 MHD_DLOG (daemon, 530 MHD_DLOG (daemon,
527 MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED, 531 MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED,
528 _("Failed to set noninheritable mode on epoll FD.\n")); 532 _ ("Failed to set noninheritable mode on epoll FD.\n"));
529#endif 533#endif
530 } 534 }
531#endif /* ! USE_EPOLL_CREATE1 */ 535#endif /* ! USE_EPOLL_CREATE1 */
532 return fd; 536 return fd;
533} 537}
@@ -554,11 +558,11 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
554 return MHD_SC_EPOLL_CTL_CREATE_FAILED; 558 return MHD_SC_EPOLL_CTL_CREATE_FAILED;
555#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 559#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
556 if (! daemon->disallow_upgrade) 560 if (! daemon->disallow_upgrade)
557 { 561 {
558 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon); 562 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
559 if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd) 563 if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
560 return MHD_SC_EPOLL_CTL_CREATE_FAILED; 564 return MHD_SC_EPOLL_CTL_CREATE_FAILED;
561 } 565 }
562#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 566#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
563 if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_socket)) || 567 if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_socket)) ||
564 (daemon->was_quiesced) ) 568 (daemon->was_quiesced) )
@@ -566,37 +570,37 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
566 event.events = EPOLLIN; 570 event.events = EPOLLIN;
567 event.data.ptr = daemon; 571 event.data.ptr = daemon;
568 if (0 != epoll_ctl (daemon->epoll_fd, 572 if (0 != epoll_ctl (daemon->epoll_fd,
569 EPOLL_CTL_ADD, 573 EPOLL_CTL_ADD,
570 ls, 574 ls,
571 &event)) 575 &event))
572 { 576 {
573#ifdef HAVE_MESSAGES 577#ifdef HAVE_MESSAGES
574 MHD_DLOG (daemon, 578 MHD_DLOG (daemon,
575 MHD_SC_EPOLL_CTL_ADD_FAILED, 579 MHD_SC_EPOLL_CTL_ADD_FAILED,
576 _("Call to epoll_ctl failed: %s\n"), 580 _ ("Call to epoll_ctl failed: %s\n"),
577 MHD_socket_last_strerr_ ()); 581 MHD_socket_last_strerr_ ());
578#endif 582#endif
579 return MHD_SC_EPOLL_CTL_ADD_FAILED; 583 return MHD_SC_EPOLL_CTL_ADD_FAILED;
580 } 584 }
581 daemon->listen_socket_in_epoll = true; 585 daemon->listen_socket_in_epoll = true;
582 if (MHD_ITC_IS_VALID_(daemon->itc)) 586 if (MHD_ITC_IS_VALID_ (daemon->itc))
587 {
588 event.events = EPOLLIN;
589 event.data.ptr = (void *) daemon->epoll_itc_marker;
590 if (0 != epoll_ctl (daemon->epoll_fd,
591 EPOLL_CTL_ADD,
592 MHD_itc_r_fd_ (daemon->itc),
593 &event))
583 { 594 {
584 event.events = EPOLLIN;
585 event.data.ptr = (void *) daemon->epoll_itc_marker;
586 if (0 != epoll_ctl (daemon->epoll_fd,
587 EPOLL_CTL_ADD,
588 MHD_itc_r_fd_ (daemon->itc),
589 &event))
590 {
591#ifdef HAVE_MESSAGES 595#ifdef HAVE_MESSAGES
592 MHD_DLOG (daemon, 596 MHD_DLOG (daemon,
593 MHD_SC_EPOLL_CTL_ADD_FAILED, 597 MHD_SC_EPOLL_CTL_ADD_FAILED,
594 _("Call to epoll_ctl failed: %s\n"), 598 _ ("Call to epoll_ctl failed: %s\n"),
595 MHD_socket_last_strerr_ ()); 599 MHD_socket_last_strerr_ ());
596#endif 600#endif
597 return MHD_SC_EPOLL_CTL_ADD_FAILED; 601 return MHD_SC_EPOLL_CTL_ADD_FAILED;
598 }
599 } 602 }
603 }
600 return MHD_SC_OK; 604 return MHD_SC_OK;
601} 605}
602#endif 606#endif
@@ -616,35 +620,35 @@ MHD_polling_thread (void *cls)
616 620
617 MHD_thread_init_ (&daemon->pid); 621 MHD_thread_init_ (&daemon->pid);
618 while (! daemon->shutdown) 622 while (! daemon->shutdown)
623 {
624 switch (daemon->event_loop_syscall)
619 { 625 {
620 switch (daemon->event_loop_syscall) 626 case MHD_ELS_AUTO:
621 { 627 MHD_PANIC ("MHD_ELS_AUTO should have been mapped to preferred style");
622 case MHD_ELS_AUTO: 628 break;
623 MHD_PANIC ("MHD_ELS_AUTO should have been mapped to preferred style"); 629 case MHD_ELS_SELECT:
624 break; 630 MHD_daemon_select_ (daemon,
625 case MHD_ELS_SELECT: 631 MHD_YES);
626 MHD_daemon_select_ (daemon, 632 break;
627 MHD_YES); 633 case MHD_ELS_POLL:
628 break;
629 case MHD_ELS_POLL:
630#if HAVE_POLL 634#if HAVE_POLL
631 MHD_daemon_poll_ (daemon, 635 MHD_daemon_poll_ (daemon,
632 MHD_YES); 636 MHD_YES);
633#else 637#else
634 MHD_PANIC ("MHD_ELS_POLL not supported, should have failed earlier"); 638 MHD_PANIC ("MHD_ELS_POLL not supported, should have failed earlier");
635#endif 639#endif
636 break; 640 break;
637 case MHD_ELS_EPOLL: 641 case MHD_ELS_EPOLL:
638#ifdef EPOLL_SUPPORT 642#ifdef EPOLL_SUPPORT
639 MHD_daemon_epoll_ (daemon, 643 MHD_daemon_epoll_ (daemon,
640 MHD_YES); 644 MHD_YES);
641#else 645#else
642 MHD_PANIC ("MHD_ELS_EPOLL not supported, should have failed earlier"); 646 MHD_PANIC ("MHD_ELS_EPOLL not supported, should have failed earlier");
643#endif 647#endif
644 break; 648 break;
645 }
646 MHD_connection_cleanup_ (daemon);
647 } 649 }
650 MHD_connection_cleanup_ (daemon);
651 }
648 /* Resume any pending for resume connections, join 652 /* Resume any pending for resume connections, join
649 * all connection's threads (if any) and finally cleanup 653 * all connection's threads (if any) and finally cleanup
650 * everything. */ 654 * everything. */
@@ -652,7 +656,7 @@ MHD_polling_thread (void *cls)
652 MHD_resume_suspended_connections_ (daemon); 656 MHD_resume_suspended_connections_ (daemon);
653 MHD_daemon_close_all_connections_ (daemon); 657 MHD_daemon_close_all_connections_ (daemon);
654 658
655 return (MHD_THRD_RTRN_TYPE_)0; 659 return (MHD_THRD_RTRN_TYPE_) 0;
656} 660}
657 661
658 662
@@ -669,114 +673,116 @@ setup_thread_pool (struct MHD_Daemon *daemon)
669 * due to integer division). Also keep track of how many 673 * due to integer division). Also keep track of how many
670 * connections are leftover after an equal split. */ 674 * connections are leftover after an equal split. */
671 unsigned int conns_per_thread = daemon->global_connection_limit 675 unsigned int conns_per_thread = daemon->global_connection_limit
672 / daemon->threading_mode; 676 / daemon->threading_mode;
673 unsigned int leftover_conns = daemon->global_connection_limit 677 unsigned int leftover_conns = daemon->global_connection_limit
674 % daemon->threading_mode; 678 % daemon->threading_mode;
675 int i; 679 int i;
676 enum MHD_StatusCode sc; 680 enum MHD_StatusCode sc;
677 681
678 /* Allocate memory for pooled objects */ 682 /* Allocate memory for pooled objects */
679 daemon->worker_pool = MHD_calloc_ (daemon->threading_mode, 683 daemon->worker_pool = MHD_calloc_ (daemon->threading_mode,
680 sizeof (struct MHD_Daemon)); 684 sizeof (struct MHD_Daemon));
681 if (NULL == daemon->worker_pool) 685 if (NULL == daemon->worker_pool)
682 return MHD_SC_THREAD_POOL_MALLOC_FAILURE; 686 return MHD_SC_THREAD_POOL_MALLOC_FAILURE;
683 687
684 /* Start the workers in the pool */ 688 /* Start the workers in the pool */
685 for (i = 0; i < daemon->threading_mode; i++) 689 for (i = 0; i < daemon->threading_mode; i++)
690 {
691 /* Create copy of the Daemon object for each worker */
692 struct MHD_Daemon *d = &daemon->worker_pool[i];
693
694 memcpy (d,
695 daemon,
696 sizeof (struct MHD_Daemon));
697 /* Adjust pooling params for worker daemons; note that memcpy()
698 has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into
699 the worker threads. */
700 d->master = daemon;
701 d->worker_pool_size = 0;
702 d->worker_pool = NULL;
703 /* Divide available connections evenly amongst the threads.
704 * Thread indexes in [0, leftover_conns) each get one of the
705 * leftover connections. */
706 d->global_connection_limit = conns_per_thread;
707 if (((unsigned int) i) < leftover_conns)
708 ++d->global_connection_limit;
709
710 if (! daemon->disable_itc)
686 { 711 {
687 /* Create copy of the Daemon object for each worker */ 712 if (! MHD_itc_init_ (d->itc))
688 struct MHD_Daemon *d = &daemon->worker_pool[i]; 713 {
689
690 memcpy (d,
691 daemon,
692 sizeof (struct MHD_Daemon));
693 /* Adjust pooling params for worker daemons; note that memcpy()
694 has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into
695 the worker threads. */
696 d->master = daemon;
697 d->worker_pool_size = 0;
698 d->worker_pool = NULL;
699 /* Divide available connections evenly amongst the threads.
700 * Thread indexes in [0, leftover_conns) each get one of the
701 * leftover connections. */
702 d->global_connection_limit = conns_per_thread;
703 if (((unsigned int) i) < leftover_conns)
704 ++d->global_connection_limit;
705
706 if (! daemon->disable_itc)
707 {
708 if (! MHD_itc_init_ (d->itc))
709 {
710#ifdef HAVE_MESSAGES 714#ifdef HAVE_MESSAGES
711 MHD_DLOG (daemon, 715 MHD_DLOG (daemon,
712 MHD_SC_ITC_INITIALIZATION_FAILED, 716 MHD_SC_ITC_INITIALIZATION_FAILED,
713 _("Failed to create worker inter-thread communication channel: %s\n"), 717 _ (
714 MHD_itc_last_strerror_() ); 718 "Failed to create worker inter-thread communication channel: %s\n"),
715#endif 719 MHD_itc_last_strerror_ () );
716 sc = MHD_SC_ITC_INITIALIZATION_FAILED; 720#endif
717 goto thread_failed; 721 sc = MHD_SC_ITC_INITIALIZATION_FAILED;
718 } 722 goto thread_failed;
719 if ( (MHD_ELS_SELECT == daemon->event_loop_syscall) && 723 }
720 (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (d->itc), 724 if ( (MHD_ELS_SELECT == daemon->event_loop_syscall) &&
721 NULL)) ) 725 (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (d->itc),
722 { 726 NULL)) )
727 {
723#ifdef HAVE_MESSAGES 728#ifdef HAVE_MESSAGES
724 MHD_DLOG (daemon, 729 MHD_DLOG (daemon,
725 MHD_SC_ITC_DESCRIPTOR_TOO_LARGE, 730 MHD_SC_ITC_DESCRIPTOR_TOO_LARGE,
726 _("File descriptor for inter-thread communication channel exceeds maximum value\n")); 731 _ (
727#endif 732 "File descriptor for inter-thread communication channel exceeds maximum value\n"));
728 MHD_itc_destroy_chk_ (d->itc); 733#endif
729 sc = MHD_SC_ITC_DESCRIPTOR_TOO_LARGE; 734 MHD_itc_destroy_chk_ (d->itc);
730 goto thread_failed; 735 sc = MHD_SC_ITC_DESCRIPTOR_TOO_LARGE;
731 } 736 goto thread_failed;
732 } 737 }
733 else 738 }
734 { 739 else
735 MHD_itc_set_invalid_ (d->itc); 740 {
736 } 741 MHD_itc_set_invalid_ (d->itc);
742 }
737 743
738#ifdef EPOLL_SUPPORT 744#ifdef EPOLL_SUPPORT
739 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && 745 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
740 (MHD_SC_OK != (sc = setup_epoll_to_listen (d))) ) 746 (MHD_SC_OK != (sc = setup_epoll_to_listen (d))) )
741 goto thread_failed; 747 goto thread_failed;
742#endif 748#endif
743 749
744 /* Must init cleanup connection mutex for each worker */ 750 /* Must init cleanup connection mutex for each worker */
745 if (! MHD_mutex_init_ (&d->cleanup_connection_mutex)) 751 if (! MHD_mutex_init_ (&d->cleanup_connection_mutex))
746 { 752 {
747#ifdef HAVE_MESSAGES 753#ifdef HAVE_MESSAGES
748 MHD_DLOG (daemon, 754 MHD_DLOG (daemon,
749 MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE, 755 MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE,
750 _("MHD failed to initialize cleanup connection mutex\n")); 756 _ ("MHD failed to initialize cleanup connection mutex\n"));
751#endif 757#endif
752 if (! daemon->disable_itc) 758 if (! daemon->disable_itc)
753 MHD_itc_destroy_chk_ (d->itc); 759 MHD_itc_destroy_chk_ (d->itc);
754 sc = MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE; 760 sc = MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE;
755 goto thread_failed; 761 goto thread_failed;
756 } 762 }
757 763
758 /* Spawn the worker thread */ 764 /* Spawn the worker thread */
759 if (! MHD_create_named_thread_ (&d->pid, 765 if (! MHD_create_named_thread_ (&d->pid,
760 "MHD-worker", 766 "MHD-worker",
761 daemon->thread_stack_limit_b, 767 daemon->thread_stack_limit_b,
762 &MHD_polling_thread, 768 &MHD_polling_thread,
763 d)) 769 d))
764 { 770 {
765#ifdef HAVE_MESSAGES 771#ifdef HAVE_MESSAGES
766 MHD_DLOG (daemon, 772 MHD_DLOG (daemon,
767 MHD_SC_THREAD_POOL_LAUNCH_FAILURE, 773 MHD_SC_THREAD_POOL_LAUNCH_FAILURE,
768 _("Failed to create pool thread: %s\n"), 774 _ ("Failed to create pool thread: %s\n"),
769 MHD_strerror_ (errno)); 775 MHD_strerror_ (errno));
770#endif 776#endif
771 /* Free memory for this worker; cleanup below handles 777 /* Free memory for this worker; cleanup below handles
772 * all previously-created workers. */ 778 * all previously-created workers. */
773 if (! daemon->disable_itc) 779 if (! daemon->disable_itc)
774 MHD_itc_destroy_chk_ (d->itc); 780 MHD_itc_destroy_chk_ (d->itc);
775 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); 781 MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
776 sc = MHD_SC_THREAD_POOL_LAUNCH_FAILURE; 782 sc = MHD_SC_THREAD_POOL_LAUNCH_FAILURE;
777 goto thread_failed; 783 goto thread_failed;
778 } 784 }
779 } /* end for() */ 785 } /* end for() */
780 return MHD_SC_OK; 786 return MHD_SC_OK;
781 787
782thread_failed: 788thread_failed:
@@ -785,14 +791,14 @@ thread_failed:
785 assumes a 0-sized thread pool means we had been in the default 791 assumes a 0-sized thread pool means we had been in the default
786 MHD_USE_INTERNAL_POLLING_THREAD mode. */ 792 MHD_USE_INTERNAL_POLLING_THREAD mode. */
787 if (0 == i) 793 if (0 == i)
794 {
795 if (NULL != daemon->worker_pool)
788 { 796 {
789 if (NULL != daemon->worker_pool) 797 free (daemon->worker_pool);
790 { 798 daemon->worker_pool = NULL;
791 free (daemon->worker_pool);
792 daemon->worker_pool = NULL;
793 }
794 return MHD_SC_THREAD_LAUNCH_FAILURE;
795 } 799 }
800 return MHD_SC_THREAD_LAUNCH_FAILURE;
801 }
796 /* Shutdown worker threads we've already created. Pretend 802 /* Shutdown worker threads we've already created. Pretend
797 as though we had fully initialized our daemon, but 803 as though we had fully initialized our daemon, but
798 with a smaller number of threads than had been 804 with a smaller number of threads than had been
@@ -817,63 +823,65 @@ MHD_daemon_start (struct MHD_Daemon *daemon)
817 enum MHD_StatusCode sc; 823 enum MHD_StatusCode sc;
818 824
819 if (MHD_ELS_AUTO == daemon->event_loop_syscall) 825 if (MHD_ELS_AUTO == daemon->event_loop_syscall)
820 { 826 {
821#if EPOLL_SUPPORT 827#if EPOLL_SUPPORT
822 /* We do not support thread-per-connection in combination 828 /* We do not support thread-per-connection in combination
823 with epoll, so use poll in this case, otherwise prefer 829 with epoll, so use poll in this case, otherwise prefer
824 epoll. */ 830 epoll. */
825 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) 831 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
826 daemon->event_loop_syscall = MHD_ELS_POLL;
827 else
828 daemon->event_loop_syscall = MHD_ELS_EPOLL;
829#elif HAVE_POLL
830 daemon->event_loop_syscall = MHD_ELS_POLL; 832 daemon->event_loop_syscall = MHD_ELS_POLL;
833 else
834 daemon->event_loop_syscall = MHD_ELS_EPOLL;
835#elif HAVE_POLL
836 daemon->event_loop_syscall = MHD_ELS_POLL;
831#else 837#else
832 daemon->event_loop_syscall = MHD_ELS_SELECT; 838 daemon->event_loop_syscall = MHD_ELS_SELECT;
833#endif 839#endif
834 } 840 }
835 841
836#ifdef EPOLL_SUPPORT 842#ifdef EPOLL_SUPPORT
837 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && 843 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
838 (0 == daemon->worker_pool_size) && 844 (0 == daemon->worker_pool_size) &&
839 (MHD_INVALID_SOCKET != daemon->listen_socket) && 845 (MHD_INVALID_SOCKET != daemon->listen_socket) &&
840 (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) ) 846 (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) )
841 { 847 {
842#ifdef HAVE_MESSAGES 848#ifdef HAVE_MESSAGES
843 MHD_DLOG (daemon, 849 MHD_DLOG (daemon,
844 MHD_SC_SYSCALL_THREAD_COMBINATION_INVALID, 850 MHD_SC_SYSCALL_THREAD_COMBINATION_INVALID,
845 _("Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n")); 851 _ (
852 "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
846#endif 853#endif
847 return MHD_SC_SYSCALL_THREAD_COMBINATION_INVALID; 854 return MHD_SC_SYSCALL_THREAD_COMBINATION_INVALID;
848 } 855 }
849#endif 856#endif
850 857
851 /* Setup ITC */ 858 /* Setup ITC */
852 if ( (! daemon->disable_itc) && 859 if ( (! daemon->disable_itc) &&
853 (0 == daemon->worker_pool_size) ) 860 (0 == daemon->worker_pool_size) )
861 {
862 if (! MHD_itc_init_ (daemon->itc))
854 { 863 {
855 if (! MHD_itc_init_ (daemon->itc))
856 {
857#ifdef HAVE_MESSAGES 864#ifdef HAVE_MESSAGES
858 MHD_DLOG (daemon, 865 MHD_DLOG (daemon,
859 MHD_SC_ITC_INITIALIZATION_FAILED, 866 MHD_SC_ITC_INITIALIZATION_FAILED,
860 _("Failed to create inter-thread communication channel: %s\n"), 867 _ ("Failed to create inter-thread communication channel: %s\n"),
861 MHD_itc_last_strerror_ ()); 868 MHD_itc_last_strerror_ ());
862#endif 869#endif
863 return MHD_SC_ITC_INITIALIZATION_FAILED; 870 return MHD_SC_ITC_INITIALIZATION_FAILED;
864 } 871 }
865 if ( (MHD_ELS_SELECT == daemon->event_loop_syscall) && 872 if ( (MHD_ELS_SELECT == daemon->event_loop_syscall) &&
866 (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (daemon->itc), 873 (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (daemon->itc),
867 NULL)) ) 874 NULL)) )
868 { 875 {
869#ifdef HAVE_MESSAGES 876#ifdef HAVE_MESSAGES
870 MHD_DLOG (daemon, 877 MHD_DLOG (daemon,
871 MHD_SC_ITC_DESCRIPTOR_TOO_LARGE, 878 MHD_SC_ITC_DESCRIPTOR_TOO_LARGE,
872 _("File descriptor for inter-thread communication channel exceeds maximum value\n")); 879 _ (
880 "File descriptor for inter-thread communication channel exceeds maximum value\n"));
873#endif 881#endif
874 return MHD_SC_ITC_DESCRIPTOR_TOO_LARGE; 882 return MHD_SC_ITC_DESCRIPTOR_TOO_LARGE;
875 }
876 } 883 }
884 }
877 885
878 if (MHD_SC_OK != (sc = open_listen_socket (daemon))) 886 if (MHD_SC_OK != (sc = open_listen_socket (daemon)))
879 return sc; 887 return sc;
@@ -881,39 +889,39 @@ MHD_daemon_start (struct MHD_Daemon *daemon)
881 /* Check listen socket is in range (if we are limited) */ 889 /* Check listen socket is in range (if we are limited) */
882 if ( (MHD_INVALID_SOCKET != daemon->listen_socket) && 890 if ( (MHD_INVALID_SOCKET != daemon->listen_socket) &&
883 (MHD_ELS_SELECT == daemon->event_loop_syscall) && 891 (MHD_ELS_SELECT == daemon->event_loop_syscall) &&
884 (! MHD_SCKT_FD_FITS_FDSET_(daemon->listen_socket, 892 (! MHD_SCKT_FD_FITS_FDSET_ (daemon->listen_socket,
885 NULL)) ) 893 NULL)) )
886 { 894 {
887#ifdef HAVE_MESSAGES 895#ifdef HAVE_MESSAGES
888 MHD_DLOG (daemon, 896 MHD_DLOG (daemon,
889 MHD_SC_LISTEN_SOCKET_TOO_LARGE, 897 MHD_SC_LISTEN_SOCKET_TOO_LARGE,
890 _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), 898 _ ("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
891 daemon->listen_socket, 899 daemon->listen_socket,
892 FD_SETSIZE); 900 FD_SETSIZE);
893#endif 901#endif
894 return MHD_SC_LISTEN_SOCKET_TOO_LARGE; 902 return MHD_SC_LISTEN_SOCKET_TOO_LARGE;
895 } 903 }
896 904
897 /* set listen socket to non-blocking */ 905 /* set listen socket to non-blocking */
898 if ( (MHD_INVALID_SOCKET != daemon->listen_socket) && 906 if ( (MHD_INVALID_SOCKET != daemon->listen_socket) &&
899 (! MHD_socket_nonblocking_ (daemon->listen_socket)) ) 907 (! MHD_socket_nonblocking_ (daemon->listen_socket)) )
900 { 908 {
901#ifdef HAVE_MESSAGES 909#ifdef HAVE_MESSAGES
902 MHD_DLOG (daemon, 910 MHD_DLOG (daemon,
903 MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE, 911 MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE,
904 _("Failed to set nonblocking mode on listening socket: %s\n"), 912 _ ("Failed to set nonblocking mode on listening socket: %s\n"),
905 MHD_socket_last_strerr_()); 913 MHD_socket_last_strerr_ ());
906#endif 914#endif
907 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) || 915 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) ||
908 (daemon->worker_pool_size > 0) ) 916 (daemon->worker_pool_size > 0) )
909 { 917 {
910 /* Accept must be non-blocking. Multiple children may wake 918 /* Accept must be non-blocking. Multiple children may wake
911 * up to handle a new connection, but only one will win the 919 * up to handle a new connection, but only one will win the
912 * race. The others must immediately return. As this is 920 * race. The others must immediately return. As this is
913 * not possible, we must fail hard here. */ 921 * not possible, we must fail hard here. */
914 return MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE; 922 return MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE;
915 }
916 } 923 }
924 }
917 925
918#ifdef EPOLL_SUPPORT 926#ifdef EPOLL_SUPPORT
919 /* Setup epoll */ 927 /* Setup epoll */
@@ -928,30 +936,31 @@ MHD_daemon_start (struct MHD_Daemon *daemon)
928 external event loop and do have a listen socket) */ 936 external event loop and do have a listen socket) */
929 /* FIXME: why no worker thread if we have no listen socket? */ 937 /* FIXME: why no worker thread if we have no listen socket? */
930 if ( ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) || 938 if ( ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) ||
931 (1 == daemon->threading_mode) ) && 939 (1 == daemon->threading_mode) ) &&
932 (MHD_INVALID_SOCKET != daemon->listen_socket) && 940 (MHD_INVALID_SOCKET != daemon->listen_socket) &&
933 (! MHD_create_named_thread_ (&daemon->pid, 941 (! MHD_create_named_thread_ (&daemon->pid,
934 (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) 942 (MHD_TM_THREAD_PER_CONNECTION ==
935 ? "MHD-listen" 943 daemon->threading_mode)
936 : "MHD-single", 944 ? "MHD-listen"
937 daemon->thread_stack_limit_b, 945 : "MHD-single",
938 &MHD_polling_thread, 946 daemon->thread_stack_limit_b,
939 daemon) ) ) 947 &MHD_polling_thread,
940 { 948 daemon) ) )
949 {
941#ifdef HAVE_MESSAGES 950#ifdef HAVE_MESSAGES
942 MHD_DLOG (daemon, 951 MHD_DLOG (daemon,
943 MHD_SC_THREAD_MAIN_LAUNCH_FAILURE, 952 MHD_SC_THREAD_MAIN_LAUNCH_FAILURE,
944 _("Failed to create listen thread: %s\n"), 953 _ ("Failed to create listen thread: %s\n"),
945 MHD_strerror_ (errno)); 954 MHD_strerror_ (errno));
946#endif 955#endif
947 return MHD_SC_THREAD_MAIN_LAUNCH_FAILURE; 956 return MHD_SC_THREAD_MAIN_LAUNCH_FAILURE;
948 } 957 }
949 958
950 /* Setup worker threads */ 959 /* Setup worker threads */
951 /* FIXME: why no thread pool if we have no listen socket? */ 960 /* FIXME: why no thread pool if we have no listen socket? */
952 if ( (1 < daemon->threading_mode) && 961 if ( (1 < daemon->threading_mode) &&
953 (MHD_INVALID_SOCKET != daemon->listen_socket) && 962 (MHD_INVALID_SOCKET != daemon->listen_socket) &&
954 (MHD_SC_OK != (sc = setup_thread_pool (daemon))) ) 963 (MHD_SC_OK != (sc = setup_thread_pool (daemon))) )
955 return sc; 964 return sc;
956 965
957 /* make sure we know our listen port (if any) */ 966 /* make sure we know our listen port (if any) */
diff --git a/src/lib/init.c b/src/lib/init.c
index b23bdadf..5dcb02c4 100644
--- a/src/lib/init.c
+++ b/src/lib/init.c
@@ -36,7 +36,7 @@ volatile unsigned int global_init_count = 0;
36/** 36/**
37 * Global initialisation mutex 37 * Global initialisation mutex
38 */ 38 */
39MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_); 39MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_);
40#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ 40#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
41 41
42#endif 42#endif
@@ -59,21 +59,21 @@ static int mhd_winsock_inited_ = 0;
59 */ 59 */
60static void 60static void
61mhd_panic_std (void *cls, 61mhd_panic_std (void *cls,
62 const char *file, 62 const char *file,
63 unsigned int line, 63 unsigned int line,
64 const char *reason) 64 const char *reason)
65{ 65{
66 (void)cls; /* Mute compiler warning. */ 66 (void) cls; /* Mute compiler warning. */
67#ifdef HAVE_MESSAGES 67#ifdef HAVE_MESSAGES
68 fprintf (stderr, 68 fprintf (stderr,
69 _("Fatal error in GNU libmicrohttpd %s:%u: %s\n"), 69 _ ("Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
70 file, 70 file,
71 line, 71 line,
72 reason); 72 reason);
73#else /* ! HAVE_MESSAGES */ 73#else /* ! HAVE_MESSAGES */
74 (void)file; /* Mute compiler warning. */ 74 (void) file; /* Mute compiler warning. */
75 (void)line; /* Mute compiler warning. */ 75 (void) line; /* Mute compiler warning. */
76 (void)reason; /* Mute compiler warning. */ 76 (void) reason; /* Mute compiler warning. */
77#endif 77#endif
78 abort (); 78 abort ();
79} 79}
@@ -93,13 +93,13 @@ MHD_init (void)
93 mhd_panic = &mhd_panic_std; 93 mhd_panic = &mhd_panic_std;
94 94
95#if defined(_WIN32) && ! defined(__CYGWIN__) 95#if defined(_WIN32) && ! defined(__CYGWIN__)
96 if (0 != WSAStartup (MAKEWORD(2, 2), 96 if (0 != WSAStartup (MAKEWORD (2, 2),
97 &wsd)) 97 &wsd))
98 MHD_PANIC (_("Failed to initialize winsock\n")); 98 MHD_PANIC (_ ("Failed to initialize winsock\n"));
99 mhd_winsock_inited_ = 1; 99 mhd_winsock_inited_ = 1;
100 if ( (2 != LOBYTE(wsd.wVersion)) && 100 if ( (2 != LOBYTE (wsd.wVersion)) &&
101 (2 != HIBYTE(wsd.wVersion)) ) 101 (2 != HIBYTE (wsd.wVersion)) )
102 MHD_PANIC (_("Winsock version 2.2 is not available\n")); 102 MHD_PANIC (_ ("Winsock version 2.2 is not available\n"));
103#endif 103#endif
104 MHD_monotonic_sec_counter_init (); 104 MHD_monotonic_sec_counter_init ();
105#ifdef HAVE_FREEBSD_SENDFILE 105#ifdef HAVE_FREEBSD_SENDFILE
@@ -116,14 +116,14 @@ MHD_fini (void)
116{ 116{
117#if defined(_WIN32) && ! defined(__CYGWIN__) 117#if defined(_WIN32) && ! defined(__CYGWIN__)
118 if (mhd_winsock_inited_) 118 if (mhd_winsock_inited_)
119 WSACleanup(); 119 WSACleanup ();
120#endif 120#endif
121 MHD_monotonic_sec_counter_finish (); 121 MHD_monotonic_sec_counter_finish ();
122} 122}
123 123
124#ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED 124#ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
125 125
126_SET_INIT_AND_DEINIT_FUNCS(MHD_init, MHD_fini); 126_SET_INIT_AND_DEINIT_FUNCS (MHD_init, MHD_fini);
127 127
128#else 128#else
129 129
@@ -135,12 +135,12 @@ void
135MHD_check_global_init_ (void) 135MHD_check_global_init_ (void)
136{ 136{
137#ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 137#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
138 MHD_mutex_lock_chk_(&global_init_mutex_); 138 MHD_mutex_lock_chk_ (&global_init_mutex_);
139#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ 139#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
140 if (0 == global_init_count++) 140 if (0 == global_init_count++)
141 MHD_init (); 141 MHD_init ();
142#ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 142#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
143 MHD_mutex_unlock_chk_(&global_init_mutex_); 143 MHD_mutex_unlock_chk_ (&global_init_mutex_);
144#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ 144#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
145} 145}
146#endif 146#endif
diff --git a/src/lib/init.h b/src/lib/init.h
index fae96159..2d9a9389 100644
--- a/src/lib/init.h
+++ b/src/lib/init.h
@@ -31,7 +31,7 @@
31 * Do nothing - global initialisation is 31 * Do nothing - global initialisation is
32 * performed by library constructor. 32 * performed by library constructor.
33 */ 33 */
34#define MHD_check_global_init_() (void)0 34#define MHD_check_global_init_() (void) 0
35#else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */ 35#else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
36/** 36/**
37 * Check whether global initialisation was performed 37 * Check whether global initialisation was performed
diff --git a/src/lib/internal.c b/src/lib/internal.c
index 75eae8a4..04d83624 100644
--- a/src/lib/internal.c
+++ b/src/lib/internal.c
@@ -35,50 +35,50 @@ const char *
35MHD_state_to_string (enum MHD_CONNECTION_STATE state) 35MHD_state_to_string (enum MHD_CONNECTION_STATE state)
36{ 36{
37 switch (state) 37 switch (state)
38 { 38 {
39 case MHD_CONNECTION_INIT: 39 case MHD_CONNECTION_INIT:
40 return "connection init"; 40 return "connection init";
41 case MHD_CONNECTION_URL_RECEIVED: 41 case MHD_CONNECTION_URL_RECEIVED:
42 return "connection url received"; 42 return "connection url received";
43 case MHD_CONNECTION_HEADER_PART_RECEIVED: 43 case MHD_CONNECTION_HEADER_PART_RECEIVED:
44 return "header partially received"; 44 return "header partially received";
45 case MHD_CONNECTION_HEADERS_RECEIVED: 45 case MHD_CONNECTION_HEADERS_RECEIVED:
46 return "headers received"; 46 return "headers received";
47 case MHD_CONNECTION_HEADERS_PROCESSED: 47 case MHD_CONNECTION_HEADERS_PROCESSED:
48 return "headers processed"; 48 return "headers processed";
49 case MHD_CONNECTION_CONTINUE_SENDING: 49 case MHD_CONNECTION_CONTINUE_SENDING:
50 return "continue sending"; 50 return "continue sending";
51 case MHD_CONNECTION_CONTINUE_SENT: 51 case MHD_CONNECTION_CONTINUE_SENT:
52 return "continue sent"; 52 return "continue sent";
53 case MHD_CONNECTION_BODY_RECEIVED: 53 case MHD_CONNECTION_BODY_RECEIVED:
54 return "body received"; 54 return "body received";
55 case MHD_CONNECTION_FOOTER_PART_RECEIVED: 55 case MHD_CONNECTION_FOOTER_PART_RECEIVED:
56 return "footer partially received"; 56 return "footer partially received";
57 case MHD_CONNECTION_FOOTERS_RECEIVED: 57 case MHD_CONNECTION_FOOTERS_RECEIVED:
58 return "footers received"; 58 return "footers received";
59 case MHD_CONNECTION_HEADERS_SENDING: 59 case MHD_CONNECTION_HEADERS_SENDING:
60 return "headers sending"; 60 return "headers sending";
61 case MHD_CONNECTION_HEADERS_SENT: 61 case MHD_CONNECTION_HEADERS_SENT:
62 return "headers sent"; 62 return "headers sent";
63 case MHD_CONNECTION_NORMAL_BODY_READY: 63 case MHD_CONNECTION_NORMAL_BODY_READY:
64 return "normal body ready"; 64 return "normal body ready";
65 case MHD_CONNECTION_NORMAL_BODY_UNREADY: 65 case MHD_CONNECTION_NORMAL_BODY_UNREADY:
66 return "normal body unready"; 66 return "normal body unready";
67 case MHD_CONNECTION_CHUNKED_BODY_READY: 67 case MHD_CONNECTION_CHUNKED_BODY_READY:
68 return "chunked body ready"; 68 return "chunked body ready";
69 case MHD_CONNECTION_CHUNKED_BODY_UNREADY: 69 case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
70 return "chunked body unready"; 70 return "chunked body unready";
71 case MHD_CONNECTION_BODY_SENT: 71 case MHD_CONNECTION_BODY_SENT:
72 return "body sent"; 72 return "body sent";
73 case MHD_CONNECTION_FOOTERS_SENDING: 73 case MHD_CONNECTION_FOOTERS_SENDING:
74 return "footers sending"; 74 return "footers sending";
75 case MHD_CONNECTION_FOOTERS_SENT: 75 case MHD_CONNECTION_FOOTERS_SENT:
76 return "footers sent"; 76 return "footers sent";
77 case MHD_CONNECTION_CLOSED: 77 case MHD_CONNECTION_CLOSED:
78 return "closed"; 78 return "closed";
79 default: 79 default:
80 return "unrecognized connection state"; 80 return "unrecognized connection state";
81 } 81 }
82} 82}
83#endif 83#endif
84#endif 84#endif
@@ -91,7 +91,7 @@ MHD_state_to_string (enum MHD_CONNECTION_STATE state)
91 */ 91 */
92void 92void
93MHD_DLOG (const struct MHD_Daemon *daemon, 93MHD_DLOG (const struct MHD_Daemon *daemon,
94 enum MHD_StatusCode sc, 94 enum MHD_StatusCode sc,
95 const char *format, 95 const char *format,
96 ...) 96 ...)
97{ 97{
@@ -100,11 +100,11 @@ MHD_DLOG (const struct MHD_Daemon *daemon,
100 if (NULL == daemon->logger) 100 if (NULL == daemon->logger)
101 return; 101 return;
102 va_start (va, 102 va_start (va,
103 format); 103 format);
104 daemon->logger (daemon->logger_cls, 104 daemon->logger (daemon->logger_cls,
105 sc, 105 sc,
106 format, 106 format,
107 va); 107 va);
108 va_end (va); 108 va_end (va);
109} 109}
110#endif 110#endif
@@ -120,7 +120,7 @@ MHD_unescape_plus (char *arg)
120{ 120{
121 char *p; 121 char *p;
122 122
123 for (p=strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+')) 123 for (p = strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+'))
124 *p = ' '; 124 *p = ' ';
125} 125}
126 126
@@ -141,28 +141,28 @@ MHD_http_unescape (char *val)
141 char *wpos = val; 141 char *wpos = val;
142 142
143 while ('\0' != *rpos) 143 while ('\0' != *rpos)
144 {
145 uint32_t num;
146 switch (*rpos)
144 { 147 {
145 uint32_t num; 148 case '%':
146 switch (*rpos) 149 if (2 == MHD_strx_to_uint32_n_ (rpos + 1,
147 { 150 2,
148 case '%': 151 &num))
149 if (2 == MHD_strx_to_uint32_n_ (rpos + 1, 152 {
150 2, 153 *wpos = (char) ((unsigned char) num);
151 &num)) 154 wpos++;
152 { 155 rpos += 3;
153 *wpos = (char)((unsigned char) num); 156 break;
154 wpos++; 157 }
155 rpos += 3; 158 /* TODO: add bad sequence handling */
156 break; 159 /* intentional fall through! */
157 } 160 default:
158 /* TODO: add bad sequence handling */ 161 *wpos = *rpos;
159 /* intentional fall through! */ 162 wpos++;
160 default: 163 rpos++;
161 *wpos = *rpos;
162 wpos++;
163 rpos++;
164 }
165 } 164 }
165 }
166 *wpos = '\0'; /* add 0-terminator */ 166 *wpos = '\0'; /* add 0-terminator */
167 return wpos - val; /* = strlen(val) */ 167 return wpos - val; /* = strlen(val) */
168} 168}
@@ -184,10 +184,10 @@ MHD_http_unescape (char *val)
184 */ 184 */
185bool 185bool
186MHD_parse_arguments_ (struct MHD_Request *request, 186MHD_parse_arguments_ (struct MHD_Request *request,
187 enum MHD_ValueKind kind, 187 enum MHD_ValueKind kind,
188 char *args, 188 char *args,
189 MHD_ArgumentIterator_ cb, 189 MHD_ArgumentIterator_ cb,
190 unsigned int *num_headers) 190 unsigned int *num_headers)
191{ 191{
192 struct MHD_Daemon *daemon = request->daemon; 192 struct MHD_Daemon *daemon = request->daemon;
193 char *equals; 193 char *equals;
@@ -195,88 +195,88 @@ MHD_parse_arguments_ (struct MHD_Request *request,
195 195
196 *num_headers = 0; 196 *num_headers = 0;
197 while ( (NULL != args) && 197 while ( (NULL != args) &&
198 ('\0' != args[0]) ) 198 ('\0' != args[0]) )
199 {
200 equals = strchr (args, '=');
201 amper = strchr (args, '&');
202 if (NULL == amper)
199 { 203 {
200 equals = strchr (args, '='); 204 /* last argument */
201 amper = strchr (args, '&'); 205 if (NULL == equals)
202 if (NULL == amper) 206 {
203 { 207 /* last argument, without '=' */
204 /* last argument */ 208 MHD_unescape_plus (args);
205 if (NULL == equals) 209 daemon->unescape_cb (daemon->unescape_cb_cls,
206 { 210 request,
207 /* last argument, without '=' */ 211 args);
208 MHD_unescape_plus (args); 212 if (! cb (request,
209 daemon->unescape_cb (daemon->unescape_cb_cls, 213 args,
210 request, 214 NULL,
211 args); 215 kind))
212 if (! cb (request, 216 return false;
213 args, 217 (*num_headers)++;
214 NULL, 218 break;
215 kind)) 219 }
216 return false; 220 /* got 'foo=bar' */
217 (*num_headers)++;
218 break;
219 }
220 /* got 'foo=bar' */
221 equals[0] = '\0';
222 equals++;
223 MHD_unescape_plus (args);
224 daemon->unescape_cb (daemon->unescape_cb_cls,
225 request,
226 args);
227 MHD_unescape_plus (equals);
228 daemon->unescape_cb (daemon->unescape_cb_cls,
229 request,
230 equals);
231 if (! cb (request,
232 args,
233 equals,
234 kind))
235 return false;
236 (*num_headers)++;
237 break;
238 }
239 /* amper is non-NULL here */
240 amper[0] = '\0';
241 amper++;
242 if ( (NULL == equals) ||
243 (equals >= amper) )
244 {
245 /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
246 MHD_unescape_plus (args);
247 daemon->unescape_cb (daemon->unescape_cb_cls,
248 request,
249 args);
250 if (! cb (request,
251 args,
252 NULL,
253 kind))
254 return false;
255 /* continue with 'bar' */
256 (*num_headers)++;
257 args = amper;
258 continue;
259 }
260 /* equals and amper are non-NULL here, and equals < amper,
261 so we got regular 'foo=value&bar...'-kind of argument */
262 equals[0] = '\0'; 221 equals[0] = '\0';
263 equals++; 222 equals++;
264 MHD_unescape_plus (args); 223 MHD_unescape_plus (args);
265 daemon->unescape_cb (daemon->unescape_cb_cls, 224 daemon->unescape_cb (daemon->unescape_cb_cls,
266 request, 225 request,
267 args); 226 args);
268 MHD_unescape_plus (equals); 227 MHD_unescape_plus (equals);
269 daemon->unescape_cb (daemon->unescape_cb_cls, 228 daemon->unescape_cb (daemon->unescape_cb_cls,
270 request, 229 request,
271 equals); 230 equals);
231 if (! cb (request,
232 args,
233 equals,
234 kind))
235 return false;
236 (*num_headers)++;
237 break;
238 }
239 /* amper is non-NULL here */
240 amper[0] = '\0';
241 amper++;
242 if ( (NULL == equals) ||
243 (equals >= amper) )
244 {
245 /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
246 MHD_unescape_plus (args);
247 daemon->unescape_cb (daemon->unescape_cb_cls,
248 request,
249 args);
272 if (! cb (request, 250 if (! cb (request,
273 args, 251 args,
274 equals, 252 NULL,
275 kind)) 253 kind))
276 return false; 254 return false;
255 /* continue with 'bar' */
277 (*num_headers)++; 256 (*num_headers)++;
278 args = amper; 257 args = amper;
258 continue;
279 } 259 }
260 /* equals and amper are non-NULL here, and equals < amper,
261 so we got regular 'foo=value&bar...'-kind of argument */
262 equals[0] = '\0';
263 equals++;
264 MHD_unescape_plus (args);
265 daemon->unescape_cb (daemon->unescape_cb_cls,
266 request,
267 args);
268 MHD_unescape_plus (equals);
269 daemon->unescape_cb (daemon->unescape_cb_cls,
270 request,
271 equals);
272 if (! cb (request,
273 args,
274 equals,
275 kind))
276 return false;
277 (*num_headers)++;
278 args = amper;
279 }
280 return true; 280 return true;
281} 281}
282 282
diff --git a/src/lib/internal.h b/src/lib/internal.h
index bd3bd1c6..b5ec3039 100644
--- a/src/lib/internal.h
+++ b/src/lib/internal.h
@@ -58,14 +58,16 @@
58 * 58 *
59 * @param msg error message (const char *) 59 * @param msg error message (const char *)
60 */ 60 */
61#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, msg); BUILTIN_NOT_REACHED; } while (0) 61#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, msg); \
62 BUILTIN_NOT_REACHED; } while (0)
62#else 63#else
63/** 64/**
64 * Trigger 'panic' action based on fatal errors. 65 * Trigger 'panic' action based on fatal errors.
65 * 66 *
66 * @param msg error message (const char *) 67 * @param msg error message (const char *)
67 */ 68 */
68#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); BUILTIN_NOT_REACHED; } while (0) 69#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); \
70 BUILTIN_NOT_REACHED; } while (0)
69#endif 71#endif
70 72
71#include "mhd_threads.h" 73#include "mhd_threads.h"
@@ -82,8 +84,8 @@
82 */ 84 */
83void 85void
84MHD_DLOG (const struct MHD_Daemon *daemon, 86MHD_DLOG (const struct MHD_Daemon *daemon,
85 enum MHD_StatusCode sc, 87 enum MHD_StatusCode sc,
86 const char *format, 88 const char *format,
87 ...); 89 ...);
88#endif 90#endif
89 91
@@ -93,9 +95,9 @@ MHD_DLOG (const struct MHD_Daemon *daemon,
93 * @param fd the FD to close 95 * @param fd the FD to close
94 */ 96 */
95#define MHD_fd_close_chk_(fd) do { \ 97#define MHD_fd_close_chk_(fd) do { \
96 if ( (0 != close ((fd)) && (EBADF == errno)) ) \ 98 if ( (0 != close ((fd)) && (EBADF == errno)) ) \
97 MHD_PANIC(_("Failed to close FD.\n")); \ 99 MHD_PANIC (_ ("Failed to close FD.\n")); \
98 } while(0) 100} while (0)
99 101
100/** 102/**
101 * Should we perform additional sanity checks at runtime (on our internal 103 * Should we perform additional sanity checks at runtime (on our internal
@@ -128,10 +130,11 @@ extern MHD_PanicCallback mhd_panic;
128extern void *mhd_panic_cls; 130extern void *mhd_panic_cls;
129 131
130/* If we have Clang or gcc >= 4.5, use __buildin_unreachable() */ 132/* If we have Clang or gcc >= 4.5, use __buildin_unreachable() */
131#if defined(__clang__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) 133#if defined(__clang__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= \
132#define BUILTIN_NOT_REACHED __builtin_unreachable() 134 5)
135#define BUILTIN_NOT_REACHED __builtin_unreachable ()
133#elif defined(_MSC_FULL_VER) 136#elif defined(_MSC_FULL_VER)
134#define BUILTIN_NOT_REACHED __assume(0) 137#define BUILTIN_NOT_REACHED __assume (0)
135#else 138#else
136#define BUILTIN_NOT_REACHED 139#define BUILTIN_NOT_REACHED
137#endif 140#endif
@@ -140,7 +143,7 @@ extern void *mhd_panic_cls;
140/** 143/**
141 * Determine length of static string / macro strings at compile time. 144 * Determine length of static string / macro strings at compile time.
142 */ 145 */
143#define MHD_STATICSTR_LEN_(macro) (sizeof(macro)/sizeof(char) - 1) 146#define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1)
144#endif /* ! MHD_STATICSTR_LEN_ */ 147#endif /* ! MHD_STATICSTR_LEN_ */
145 148
146 149
@@ -1534,8 +1537,8 @@ struct MHD_Daemon
1534 * @return #MHD_SC_OK on success, otherwise an error code 1537 * @return #MHD_SC_OK on success, otherwise an error code
1535 */ 1538 */
1536typedef enum MHD_StatusCode 1539typedef enum MHD_StatusCode
1537(*ActionCallback) (void *cls, 1540(*ActionCallback)(void *cls,
1538 struct MHD_Request *request); 1541 struct MHD_Request *request);
1539 1542
1540 1543
1541/** 1544/**
@@ -1703,9 +1706,9 @@ struct MHD_Response
1703 */ 1706 */
1704typedef bool 1707typedef bool
1705(*MHD_ArgumentIterator_)(struct MHD_Request *request, 1708(*MHD_ArgumentIterator_)(struct MHD_Request *request,
1706 const char *key, 1709 const char *key,
1707 const char *value, 1710 const char *value,
1708 enum MHD_ValueKind kind); 1711 enum MHD_ValueKind kind);
1709 1712
1710 1713
1711/** 1714/**
@@ -1724,10 +1727,10 @@ typedef bool
1724 */ 1727 */
1725bool 1728bool
1726MHD_parse_arguments_ (struct MHD_Request *request, 1729MHD_parse_arguments_ (struct MHD_Request *request,
1727 enum MHD_ValueKind kind, 1730 enum MHD_ValueKind kind,
1728 char *args, 1731 char *args,
1729 MHD_ArgumentIterator_ cb, 1732 MHD_ArgumentIterator_ cb,
1730 unsigned int *num_headers); 1733 unsigned int *num_headers);
1731 1734
1732 1735
1733 1736
@@ -1740,15 +1743,15 @@ MHD_parse_arguments_ (struct MHD_Request *request,
1740 * @param element element to insert 1743 * @param element element to insert
1741 */ 1744 */
1742#define DLL_insert(head,tail,element) do { \ 1745#define DLL_insert(head,tail,element) do { \
1743 mhd_assert (NULL == (element)->next); \ 1746 mhd_assert (NULL == (element)->next); \
1744 mhd_assert (NULL == (element)->prev); \ 1747 mhd_assert (NULL == (element)->prev); \
1745 (element)->next = (head); \ 1748 (element)->next = (head); \
1746 (element)->prev = NULL; \ 1749 (element)->prev = NULL; \
1747 if ((tail) == NULL) \ 1750 if ((tail) == NULL) \
1748 (tail) = element; \ 1751 (tail) = element; \
1749 else \ 1752 else \
1750 (head)->prev = element; \ 1753 (head)->prev = element; \
1751 (head) = (element); } while (0) 1754 (head) = (element); } while (0)
1752 1755
1753 1756
1754/** 1757/**
@@ -1760,18 +1763,18 @@ MHD_parse_arguments_ (struct MHD_Request *request,
1760 * @param element element to remove 1763 * @param element element to remove
1761 */ 1764 */
1762#define DLL_remove(head,tail,element) do { \ 1765#define DLL_remove(head,tail,element) do { \
1763 mhd_assert ( (NULL != (element)->next) || ((element) == (tail))); \ 1766 mhd_assert ( (NULL != (element)->next) || ((element) == (tail))); \
1764 mhd_assert ( (NULL != (element)->prev) || ((element) == (head))); \ 1767 mhd_assert ( (NULL != (element)->prev) || ((element) == (head))); \
1765 if ((element)->prev == NULL) \ 1768 if ((element)->prev == NULL) \
1766 (head) = (element)->next; \ 1769 (head) = (element)->next; \
1767 else \ 1770 else \
1768 (element)->prev->next = (element)->next; \ 1771 (element)->prev->next = (element)->next; \
1769 if ((element)->next == NULL) \ 1772 if ((element)->next == NULL) \
1770 (tail) = (element)->prev; \ 1773 (tail) = (element)->prev; \
1771 else \ 1774 else \
1772 (element)->next->prev = (element)->prev; \ 1775 (element)->next->prev = (element)->prev; \
1773 (element)->next = NULL; \ 1776 (element)->next = NULL; \
1774 (element)->prev = NULL; } while (0) 1777 (element)->prev = NULL; } while (0)
1775 1778
1776 1779
1777 1780
@@ -1784,15 +1787,15 @@ MHD_parse_arguments_ (struct MHD_Request *request,
1784 * @param element element to insert 1787 * @param element element to insert
1785 */ 1788 */
1786#define XDLL_insert(head,tail,element) do { \ 1789#define XDLL_insert(head,tail,element) do { \
1787 mhd_assert (NULL == (element)->nextX); \ 1790 mhd_assert (NULL == (element)->nextX); \
1788 mhd_assert (NULL == (element)->prevX); \ 1791 mhd_assert (NULL == (element)->prevX); \
1789 (element)->nextX = (head); \ 1792 (element)->nextX = (head); \
1790 (element)->prevX = NULL; \ 1793 (element)->prevX = NULL; \
1791 if (NULL == (tail)) \ 1794 if (NULL == (tail)) \
1792 (tail) = element; \ 1795 (tail) = element; \
1793 else \ 1796 else \
1794 (head)->prevX = element; \ 1797 (head)->prevX = element; \
1795 (head) = (element); } while (0) 1798 (head) = (element); } while (0)
1796 1799
1797 1800
1798/** 1801/**
@@ -1804,18 +1807,18 @@ MHD_parse_arguments_ (struct MHD_Request *request,
1804 * @param element element to remove 1807 * @param element element to remove
1805 */ 1808 */
1806#define XDLL_remove(head,tail,element) do { \ 1809#define XDLL_remove(head,tail,element) do { \
1807 mhd_assert ( (NULL != (element)->nextX) || ((element) == (tail))); \ 1810 mhd_assert ( (NULL != (element)->nextX) || ((element) == (tail))); \
1808 mhd_assert ( (NULL != (element)->prevX) || ((element) == (head))); \ 1811 mhd_assert ( (NULL != (element)->prevX) || ((element) == (head))); \
1809 if (NULL == (element)->prevX) \ 1812 if (NULL == (element)->prevX) \
1810 (head) = (element)->nextX; \ 1813 (head) = (element)->nextX; \
1811 else \ 1814 else \
1812 (element)->prevX->nextX = (element)->nextX; \ 1815 (element)->prevX->nextX = (element)->nextX; \
1813 if (NULL == (element)->nextX) \ 1816 if (NULL == (element)->nextX) \
1814 (tail) = (element)->prevX; \ 1817 (tail) = (element)->prevX; \
1815 else \ 1818 else \
1816 (element)->nextX->prevX = (element)->prevX; \ 1819 (element)->nextX->prevX = (element)->prevX; \
1817 (element)->nextX = NULL; \ 1820 (element)->nextX = NULL; \
1818 (element)->prevX = NULL; } while (0) 1821 (element)->prevX = NULL; } while (0)
1819 1822
1820 1823
1821/** 1824/**
@@ -1827,13 +1830,13 @@ MHD_parse_arguments_ (struct MHD_Request *request,
1827 * @param element element to insert 1830 * @param element element to insert
1828 */ 1831 */
1829#define EDLL_insert(head,tail,element) do { \ 1832#define EDLL_insert(head,tail,element) do { \
1830 (element)->nextE = (head); \ 1833 (element)->nextE = (head); \
1831 (element)->prevE = NULL; \ 1834 (element)->prevE = NULL; \
1832 if ((tail) == NULL) \ 1835 if ((tail) == NULL) \
1833 (tail) = element; \ 1836 (tail) = element; \
1834 else \ 1837 else \
1835 (head)->prevE = element; \ 1838 (head)->prevE = element; \
1836 (head) = (element); } while (0) 1839 (head) = (element); } while (0)
1837 1840
1838 1841
1839/** 1842/**
@@ -1845,16 +1848,16 @@ MHD_parse_arguments_ (struct MHD_Request *request,
1845 * @param element element to remove 1848 * @param element element to remove
1846 */ 1849 */
1847#define EDLL_remove(head,tail,element) do { \ 1850#define EDLL_remove(head,tail,element) do { \
1848 if ((element)->prevE == NULL) \ 1851 if ((element)->prevE == NULL) \
1849 (head) = (element)->nextE; \ 1852 (head) = (element)->nextE; \
1850 else \ 1853 else \
1851 (element)->prevE->nextE = (element)->nextE; \ 1854 (element)->prevE->nextE = (element)->nextE; \
1852 if ((element)->nextE == NULL) \ 1855 if ((element)->nextE == NULL) \
1853 (tail) = (element)->prevE; \ 1856 (tail) = (element)->prevE; \
1854 else \ 1857 else \
1855 (element)->nextE->prevE = (element)->prevE; \ 1858 (element)->nextE->prevE = (element)->prevE; \
1856 (element)->nextE = NULL; \ 1859 (element)->nextE = NULL; \
1857 (element)->prevE = NULL; } while (0) 1860 (element)->prevE = NULL; } while (0)
1858 1861
1859 1862
1860 1863
diff --git a/src/lib/md5.c b/src/lib/md5.c
index a7eb35fe..3d0f7493 100644
--- a/src/lib/md5.c
+++ b/src/lib/md5.c
@@ -20,21 +20,21 @@
20#include "md5.h" 20#include "md5.h"
21#include "mhd_byteorder.h" 21#include "mhd_byteorder.h"
22 22
23#define PUT_64BIT_LE(cp, value) do { \ 23#define PUT_64BIT_LE(cp, value) do { \
24 (cp)[7] = (uint8_t)((value) >> 56); \ 24 (cp)[7] = (uint8_t) ((value) >> 56); \
25 (cp)[6] = (uint8_t)((value) >> 48); \ 25 (cp)[6] = (uint8_t) ((value) >> 48); \
26 (cp)[5] = (uint8_t)((value) >> 40); \ 26 (cp)[5] = (uint8_t) ((value) >> 40); \
27 (cp)[4] = (uint8_t)((value) >> 32); \ 27 (cp)[4] = (uint8_t) ((value) >> 32); \
28 (cp)[3] = (uint8_t)((value) >> 24); \ 28 (cp)[3] = (uint8_t) ((value) >> 24); \
29 (cp)[2] = (uint8_t)((value) >> 16); \ 29 (cp)[2] = (uint8_t) ((value) >> 16); \
30 (cp)[1] = (uint8_t)((value) >> 8); \ 30 (cp)[1] = (uint8_t) ((value) >> 8); \
31 (cp)[0] = (uint8_t)((value)); } while (0) 31 (cp)[0] = (uint8_t) ((value)); } while (0)
32 32
33#define PUT_32BIT_LE(cp, value) do { \ 33#define PUT_32BIT_LE(cp, value) do { \
34 (cp)[3] = (uint8_t)((value) >> 24); \ 34 (cp)[3] = (uint8_t) ((value) >> 24); \
35 (cp)[2] = (uint8_t)((value) >> 16); \ 35 (cp)[2] = (uint8_t) ((value) >> 16); \
36 (cp)[1] = (uint8_t)((value) >> 8); \ 36 (cp)[1] = (uint8_t) ((value) >> 8); \
37 (cp)[0] = (uint8_t)((value)); } while (0) 37 (cp)[0] = (uint8_t) ((value)); } while (0)
38 38
39static uint8_t PADDING[MD5_BLOCK_SIZE] = { 39static uint8_t PADDING[MD5_BLOCK_SIZE] = {
40 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -47,9 +47,9 @@ static uint8_t PADDING[MD5_BLOCK_SIZE] = {
47 * initialization constants. 47 * initialization constants.
48 */ 48 */
49void 49void
50MHD_MD5Init(struct MD5Context *ctx) 50MHD_MD5Init (struct MD5Context *ctx)
51{ 51{
52 if (!ctx) 52 if (! ctx)
53 return; 53 return;
54 54
55 ctx->count = 0; 55 ctx->count = 0;
@@ -64,26 +64,26 @@ MHD_MD5Init(struct MD5Context *ctx)
64 * of bytes. 64 * of bytes.
65 */ 65 */
66void 66void
67MHD_MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len) 67MHD_MD5Update (struct MD5Context *ctx, const unsigned char *input, size_t len)
68{ 68{
69 size_t have, need; 69 size_t have, need;
70 70
71 if (!ctx || !input) 71 if (! ctx || ! input)
72 return; 72 return;
73 73
74 /* Check how many bytes we already have and how many more we need. */ 74 /* Check how many bytes we already have and how many more we need. */
75 have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1)); 75 have = (size_t) ((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1));
76 need = MD5_BLOCK_SIZE - have; 76 need = MD5_BLOCK_SIZE - have;
77 77
78 /* Update bitcount */ 78 /* Update bitcount */
79 ctx->count += (uint64_t)len << 3; 79 ctx->count += (uint64_t) len << 3;
80 80
81 if (len >= need) 81 if (len >= need)
82 { 82 {
83 if (have != 0) 83 if (have != 0)
84 { 84 {
85 memcpy(ctx->buffer + have, input, need); 85 memcpy (ctx->buffer + have, input, need);
86 MD5Transform(ctx->state, ctx->buffer); 86 MD5Transform (ctx->state, ctx->buffer);
87 input += need; 87 input += need;
88 len -= need; 88 len -= need;
89 have = 0; 89 have = 0;
@@ -92,7 +92,7 @@ MHD_MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len)
92 /* Process data in MD5_BLOCK_SIZE-byte chunks. */ 92 /* Process data in MD5_BLOCK_SIZE-byte chunks. */
93 while (len >= MD5_BLOCK_SIZE) 93 while (len >= MD5_BLOCK_SIZE)
94 { 94 {
95 MD5Transform(ctx->state, input); 95 MD5Transform (ctx->state, input);
96 input += MD5_BLOCK_SIZE; 96 input += MD5_BLOCK_SIZE;
97 len -= MD5_BLOCK_SIZE; 97 len -= MD5_BLOCK_SIZE;
98 } 98 }
@@ -100,7 +100,7 @@ MHD_MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len)
100 100
101 /* Handle any remaining bytes of data. */ 101 /* Handle any remaining bytes of data. */
102 if (len != 0) 102 if (len != 0)
103 memcpy(ctx->buffer + have, input, len); 103 memcpy (ctx->buffer + have, input, len);
104} 104}
105 105
106/* 106/*
@@ -108,42 +108,42 @@ MHD_MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len)
108 * 1 0* (64-bit count of bits processed, MSB-first) 108 * 1 0* (64-bit count of bits processed, MSB-first)
109 */ 109 */
110void 110void
111MD5Pad(struct MD5Context *ctx) 111MD5Pad (struct MD5Context *ctx)
112{ 112{
113 uint8_t count[8]; 113 uint8_t count[8];
114 size_t padlen; 114 size_t padlen;
115 115
116 if (!ctx) 116 if (! ctx)
117 return; 117 return;
118 118
119 /* Convert count to 8 bytes in little endian order. */ 119 /* Convert count to 8 bytes in little endian order. */
120 PUT_64BIT_LE(count, ctx->count); 120 PUT_64BIT_LE (count, ctx->count);
121 121
122 /* Pad out to 56 mod 64. */ 122 /* Pad out to 56 mod 64. */
123 padlen = MD5_BLOCK_SIZE - 123 padlen = MD5_BLOCK_SIZE
124 ((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1)); 124 - ((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1));
125 if (padlen < 1 + 8) 125 if (padlen < 1 + 8)
126 padlen += MD5_BLOCK_SIZE; 126 padlen += MD5_BLOCK_SIZE;
127 MHD_MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ 127 MHD_MD5Update (ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */
128 MHD_MD5Update(ctx, count, 8); 128 MHD_MD5Update (ctx, count, 8);
129} 129}
130 130
131/* 131/*
132 * Final wrapup--call MD5Pad, fill in digest and zero out ctx. 132 * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
133 */ 133 */
134void 134void
135MHD_MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx) 135MHD_MD5Final (unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx)
136{ 136{
137 int i; 137 int i;
138 138
139 if (!ctx || !digest) 139 if (! ctx || ! digest)
140 return; 140 return;
141 141
142 MD5Pad(ctx); 142 MD5Pad (ctx);
143 for (i = 0; i < 4; i++) 143 for (i = 0; i < 4; i++)
144 PUT_32BIT_LE(digest + i * 4, ctx->state[i]); 144 PUT_32BIT_LE (digest + i * 4, ctx->state[i]);
145 145
146 memset(ctx, 0, sizeof(*ctx)); 146 memset (ctx, 0, sizeof(*ctx));
147} 147}
148 148
149 149
@@ -151,13 +151,13 @@ MHD_MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx)
151 151
152/* #define F1(x, y, z) (x & y | ~x & z) */ 152/* #define F1(x, y, z) (x & y | ~x & z) */
153#define F1(x, y, z) (z ^ (x & (y ^ z))) 153#define F1(x, y, z) (z ^ (x & (y ^ z)))
154#define F2(x, y, z) F1(z, x, y) 154#define F2(x, y, z) F1 (z, x, y)
155#define F3(x, y, z) (x ^ y ^ z) 155#define F3(x, y, z) (x ^ y ^ z)
156#define F4(x, y, z) (y ^ (x | ~z)) 156#define F4(x, y, z) (y ^ (x | ~z))
157 157
158/* This is the central step in the MD5 algorithm. */ 158/* This is the central step in the MD5 algorithm. */
159#define MD5STEP(f, w, x, y, z, data, s) \ 159#define MD5STEP(f, w, x, y, z, data, s) \
160 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) 160 (w += f (x, y, z) + data, w = w << s | w >> (32 - s), w += x)
161 161
162/* 162/*
163 * The core of the MD5 algorithm, this alters an existing MD5 hash to 163 * The core of the MD5 algorithm, this alters an existing MD5 hash to
@@ -165,20 +165,20 @@ MHD_MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx)
165 * the data and converts bytes into longwords for this routine. 165 * the data and converts bytes into longwords for this routine.
166 */ 166 */
167void 167void
168MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE]) 168MD5Transform (uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE])
169{ 169{
170 uint32_t a, b, c, d, in[MD5_BLOCK_SIZE / 4]; 170 uint32_t a, b, c, d, in[MD5_BLOCK_SIZE / 4];
171 171
172#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN 172#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
173 memcpy(in, block, sizeof(in)); 173 memcpy (in, block, sizeof(in));
174#else 174#else
175 for (a = 0; a < MD5_BLOCK_SIZE / 4; a++) 175 for (a = 0; a < MD5_BLOCK_SIZE / 4; a++)
176 { 176 {
177 in[a] = (uint32_t)( 177 in[a] = (uint32_t) (
178 (uint32_t)(block[a * 4 + 0]) | 178 (uint32_t) (block[a * 4 + 0])
179 (uint32_t)(block[a * 4 + 1]) << 8 | 179 | (uint32_t) (block[a * 4 + 1]) << 8
180 (uint32_t)(block[a * 4 + 2]) << 16 | 180 | (uint32_t) (block[a * 4 + 2]) << 16
181 (uint32_t)(block[a * 4 + 3]) << 24); 181 | (uint32_t) (block[a * 4 + 3]) << 24);
182 } 182 }
183#endif 183#endif
184 184
@@ -187,73 +187,73 @@ MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE])
187 c = state[2]; 187 c = state[2];
188 d = state[3]; 188 d = state[3];
189 189
190 MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 190 MD5STEP (F1, a, b, c, d, in[0] + 0xd76aa478, 7);
191 MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 191 MD5STEP (F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
192 MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 192 MD5STEP (F1, c, d, a, b, in[2] + 0x242070db, 17);
193 MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 193 MD5STEP (F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
194 MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 194 MD5STEP (F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
195 MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 195 MD5STEP (F1, d, a, b, c, in[5] + 0x4787c62a, 12);
196 MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 196 MD5STEP (F1, c, d, a, b, in[6] + 0xa8304613, 17);
197 MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 197 MD5STEP (F1, b, c, d, a, in[7] + 0xfd469501, 22);
198 MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 198 MD5STEP (F1, a, b, c, d, in[8] + 0x698098d8, 7);
199 MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 199 MD5STEP (F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
200 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 200 MD5STEP (F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
201 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 201 MD5STEP (F1, b, c, d, a, in[11] + 0x895cd7be, 22);
202 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 202 MD5STEP (F1, a, b, c, d, in[12] + 0x6b901122, 7);
203 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 203 MD5STEP (F1, d, a, b, c, in[13] + 0xfd987193, 12);
204 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 204 MD5STEP (F1, c, d, a, b, in[14] + 0xa679438e, 17);
205 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 205 MD5STEP (F1, b, c, d, a, in[15] + 0x49b40821, 22);
206 206
207 MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 207 MD5STEP (F2, a, b, c, d, in[1] + 0xf61e2562, 5);
208 MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 208 MD5STEP (F2, d, a, b, c, in[6] + 0xc040b340, 9);
209 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 209 MD5STEP (F2, c, d, a, b, in[11] + 0x265e5a51, 14);
210 MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 210 MD5STEP (F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
211 MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 211 MD5STEP (F2, a, b, c, d, in[5] + 0xd62f105d, 5);
212 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 212 MD5STEP (F2, d, a, b, c, in[10] + 0x02441453, 9);
213 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 213 MD5STEP (F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
214 MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 214 MD5STEP (F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
215 MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 215 MD5STEP (F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
216 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 216 MD5STEP (F2, d, a, b, c, in[14] + 0xc33707d6, 9);
217 MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 217 MD5STEP (F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
218 MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 218 MD5STEP (F2, b, c, d, a, in[8] + 0x455a14ed, 20);
219 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 219 MD5STEP (F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
220 MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 220 MD5STEP (F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
221 MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 221 MD5STEP (F2, c, d, a, b, in[7] + 0x676f02d9, 14);
222 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 222 MD5STEP (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
223 223
224 MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 224 MD5STEP (F3, a, b, c, d, in[5] + 0xfffa3942, 4);
225 MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 225 MD5STEP (F3, d, a, b, c, in[8] + 0x8771f681, 11);
226 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 226 MD5STEP (F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
227 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 227 MD5STEP (F3, b, c, d, a, in[14] + 0xfde5380c, 23);
228 MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 228 MD5STEP (F3, a, b, c, d, in[1] + 0xa4beea44, 4);
229 MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 229 MD5STEP (F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
230 MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 230 MD5STEP (F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
231 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 231 MD5STEP (F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
232 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 232 MD5STEP (F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
233 MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 233 MD5STEP (F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
234 MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 234 MD5STEP (F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
235 MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 235 MD5STEP (F3, b, c, d, a, in[6] + 0x04881d05, 23);
236 MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 236 MD5STEP (F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
237 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 237 MD5STEP (F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
238 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 238 MD5STEP (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
239 MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 239 MD5STEP (F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
240 240
241 MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 241 MD5STEP (F4, a, b, c, d, in[0] + 0xf4292244, 6);
242 MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 242 MD5STEP (F4, d, a, b, c, in[7] + 0x432aff97, 10);
243 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 243 MD5STEP (F4, c, d, a, b, in[14] + 0xab9423a7, 15);
244 MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 244 MD5STEP (F4, b, c, d, a, in[5] + 0xfc93a039, 21);
245 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 245 MD5STEP (F4, a, b, c, d, in[12] + 0x655b59c3, 6);
246 MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 246 MD5STEP (F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
247 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 247 MD5STEP (F4, c, d, a, b, in[10] + 0xffeff47d, 15);
248 MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 248 MD5STEP (F4, b, c, d, a, in[1] + 0x85845dd1, 21);
249 MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 249 MD5STEP (F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
250 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 250 MD5STEP (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
251 MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 251 MD5STEP (F4, c, d, a, b, in[6] + 0xa3014314, 15);
252 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 252 MD5STEP (F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
253 MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 253 MD5STEP (F4, a, b, c, d, in[4] + 0xf7537e82, 6);
254 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 254 MD5STEP (F4, d, a, b, c, in[11] + 0xbd3af235, 10);
255 MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 255 MD5STEP (F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
256 MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 256 MD5STEP (F4, b, c, d, a, in[9] + 0xeb86d391, 21);
257 257
258 state[0] += a; 258 state[0] += a;
259 state[1] += b; 259 state[1] += b;
diff --git a/src/lib/md5.h b/src/lib/md5.h
index 7a6f84e6..8e95b29b 100644
--- a/src/lib/md5.h
+++ b/src/lib/md5.h
@@ -20,45 +20,47 @@
20 20
21#include "platform.h" 21#include "platform.h"
22 22
23#define MD5_BLOCK_SIZE 64 23#define MD5_BLOCK_SIZE 64
24#define MD5_DIGEST_SIZE 16 24#define MD5_DIGEST_SIZE 16
25#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_SIZE * 2 + 1) 25#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_SIZE * 2 + 1)
26 26
27struct MD5Context 27struct MD5Context
28{ 28{
29 uint32_t state[4]; /* state */ 29 uint32_t state[4]; /* state */
30 uint64_t count; /* number of bits, mod 2^64 */ 30 uint64_t count; /* number of bits, mod 2^64 */
31 uint8_t buffer[MD5_BLOCK_SIZE]; /* input buffer */ 31 uint8_t buffer[MD5_BLOCK_SIZE]; /* input buffer */
32}; 32};
33 33
34/* 34/*
35 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 35 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
36 * initialization constants. 36 * initialization constants.
37 */ 37 */
38void MHD_MD5Init(struct MD5Context *ctx); 38void MHD_MD5Init (struct MD5Context *ctx);
39 39
40/* 40/*
41 * Update context to reflect the concatenation of another buffer full 41 * Update context to reflect the concatenation of another buffer full
42 * of bytes. 42 * of bytes.
43 */ 43 */
44void MHD_MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len); 44void MHD_MD5Update (struct MD5Context *ctx, const unsigned char *input, size_t
45 len);
45 46
46/* 47/*
47 * Pad pad to 64-byte boundary with the bit pattern 48 * Pad pad to 64-byte boundary with the bit pattern
48 * 1 0* (64-bit count of bits processed, MSB-first) 49 * 1 0* (64-bit count of bits processed, MSB-first)
49 */ 50 */
50void MD5Pad(struct MD5Context *ctx); 51void MD5Pad (struct MD5Context *ctx);
51 52
52/* 53/*
53 * Final wrapup--call MD5Pad, fill in digest and zero out ctx. 54 * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
54 */ 55 */
55void MHD_MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx); 56void MHD_MD5Final (unsigned char digest[MD5_DIGEST_SIZE], struct
57 MD5Context *ctx);
56 58
57/* 59/*
58 * The core of the MD5 algorithm, this alters an existing MD5 hash to 60 * The core of the MD5 algorithm, this alters an existing MD5 hash to
59 * reflect the addition of 16 longwords of new data. MHD_MD5Update blocks 61 * reflect the addition of 16 longwords of new data. MHD_MD5Update blocks
60 * the data and converts bytes into longwords for this routine. 62 * the data and converts bytes into longwords for this routine.
61 */ 63 */
62void MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE]); 64void MD5Transform (uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE]);
63 65
64#endif /* !MHD_MD5_H */ 66#endif /* !MHD_MD5_H */
diff --git a/src/lib/memorypool.c b/src/lib/memorypool.c
index 8ef1e2d1..9f7472e1 100644
--- a/src/lib/memorypool.c
+++ b/src/lib/memorypool.c
@@ -25,11 +25,11 @@
25#include "memorypool.h" 25#include "memorypool.h"
26 26
27/* define MAP_ANONYMOUS for Mac OS X */ 27/* define MAP_ANONYMOUS for Mac OS X */
28#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) 28#if defined(MAP_ANON) && ! defined(MAP_ANONYMOUS)
29#define MAP_ANONYMOUS MAP_ANON 29#define MAP_ANONYMOUS MAP_ANON
30#endif 30#endif
31#ifndef MAP_FAILED 31#ifndef MAP_FAILED
32#define MAP_FAILED ((void*)-1) 32#define MAP_FAILED ((void*) -1)
33#endif 33#endif
34 34
35/** 35/**
@@ -40,7 +40,7 @@
40/** 40/**
41 * Round up 'n' to a multiple of ALIGN_SIZE. 41 * Round up 'n' to a multiple of ALIGN_SIZE.
42 */ 42 */
43#define ROUND_TO_ALIGN(n) ((n+(ALIGN_SIZE-1)) & (~(ALIGN_SIZE-1))) 43#define ROUND_TO_ALIGN(n) ((n + (ALIGN_SIZE - 1)) & (~(ALIGN_SIZE - 1)))
44 44
45 45
46/** 46/**
@@ -110,11 +110,11 @@ MHD_pool_create (size_t max)
110 if (max <= 32 * 1024) 110 if (max <= 32 * 1024)
111 pool->memory = MAP_FAILED; 111 pool->memory = MAP_FAILED;
112 else 112 else
113#if defined(MAP_ANONYMOUS) && !defined(_WIN32) 113#if defined(MAP_ANONYMOUS) && ! defined(_WIN32)
114 pool->memory = mmap (NULL, 114 pool->memory = mmap (NULL,
115 max, 115 max,
116 PROT_READ | PROT_WRITE, 116 PROT_READ | PROT_WRITE,
117 MAP_PRIVATE | MAP_ANONYMOUS, 117 MAP_PRIVATE | MAP_ANONYMOUS,
118 -1, 118 -1,
119 0); 119 0);
120#elif defined(_WIN32) 120#elif defined(_WIN32)
@@ -128,19 +128,19 @@ MHD_pool_create (size_t max)
128#endif 128#endif
129 if ( (MAP_FAILED == pool->memory) || 129 if ( (MAP_FAILED == pool->memory) ||
130 (NULL == pool->memory)) 130 (NULL == pool->memory))
131 {
132 pool->memory = malloc (max);
133 if (NULL == pool->memory)
131 { 134 {
132 pool->memory = malloc (max); 135 free (pool);
133 if (NULL == pool->memory) 136 return NULL;
134 {
135 free (pool);
136 return NULL;
137 }
138 pool->is_mmap = false;
139 } 137 }
138 pool->is_mmap = false;
139 }
140 else 140 else
141 { 141 {
142 pool->is_mmap = true; 142 pool->is_mmap = true;
143 } 143 }
144 pool->pos = 0; 144 pool->pos = 0;
145 pool->end = max; 145 pool->end = max;
146 pool->size = max; 146 pool->size = max;
@@ -161,7 +161,7 @@ MHD_pool_destroy (struct MemoryPool *pool)
161 if (! pool->is_mmap) 161 if (! pool->is_mmap)
162 free (pool->memory); 162 free (pool->memory);
163 else 163 else
164#if defined(MAP_ANONYMOUS) && !defined(_WIN32) 164#if defined(MAP_ANONYMOUS) && ! defined(_WIN32)
165 munmap (pool->memory, 165 munmap (pool->memory,
166 pool->size); 166 pool->size);
167#elif defined(_WIN32) 167#elif defined(_WIN32)
@@ -201,7 +201,7 @@ MHD_pool_get_free (struct MemoryPool *pool)
201 */ 201 */
202void * 202void *
203MHD_pool_allocate (struct MemoryPool *pool, 203MHD_pool_allocate (struct MemoryPool *pool,
204 size_t size, 204 size_t size,
205 int from_end) 205 int from_end)
206{ 206{
207 void *ret; 207 void *ret;
@@ -214,15 +214,15 @@ MHD_pool_allocate (struct MemoryPool *pool,
214 (pool->pos + asize < pool->pos)) 214 (pool->pos + asize < pool->pos))
215 return NULL; 215 return NULL;
216 if (from_end == MHD_YES) 216 if (from_end == MHD_YES)
217 { 217 {
218 ret = &pool->memory[pool->end - asize]; 218 ret = &pool->memory[pool->end - asize];
219 pool->end -= asize; 219 pool->end -= asize;
220 } 220 }
221 else 221 else
222 { 222 {
223 ret = &pool->memory[pool->pos]; 223 ret = &pool->memory[pool->pos];
224 pool->pos += asize; 224 pool->pos += asize;
225 } 225 }
226 return ret; 226 return ret;
227} 227}
228 228
@@ -247,8 +247,8 @@ MHD_pool_allocate (struct MemoryPool *pool,
247void * 247void *
248MHD_pool_reallocate (struct MemoryPool *pool, 248MHD_pool_reallocate (struct MemoryPool *pool,
249 void *old, 249 void *old,
250 size_t old_size, 250 size_t old_size,
251 size_t new_size) 251 size_t new_size)
252{ 252{
253 void *ret; 253 void *ret;
254 size_t asize; 254 size_t asize;
@@ -263,35 +263,35 @@ MHD_pool_reallocate (struct MemoryPool *pool,
263 263
264 if ( (pool->pos >= old_size) && 264 if ( (pool->pos >= old_size) &&
265 (&pool->memory[pool->pos - old_size] == old) ) 265 (&pool->memory[pool->pos - old_size] == old) )
266 {
267 /* was the previous allocation - optimize! */
268 if (pool->pos + asize - old_size <= pool->end)
266 { 269 {
267 /* was the previous allocation - optimize! */ 270 /* fits */
268 if (pool->pos + asize - old_size <= pool->end) 271 pool->pos += asize - old_size;
269 { 272 if (asize < old_size) /* shrinking - zero again! */
270 /* fits */ 273 memset (&pool->memory[pool->pos],
271 pool->pos += asize - old_size; 274 0,
272 if (asize < old_size) /* shrinking - zero again! */ 275 old_size - asize);
273 memset (&pool->memory[pool->pos], 276 return old;
274 0,
275 old_size - asize);
276 return old;
277 }
278 /* does not fit */
279 return NULL;
280 } 277 }
278 /* does not fit */
279 return NULL;
280 }
281 if (asize <= old_size) 281 if (asize <= old_size)
282 return old; /* cannot shrink, no need to move */ 282 return old; /* cannot shrink, no need to move */
283 if ((pool->pos + asize >= pool->pos) && 283 if ((pool->pos + asize >= pool->pos) &&
284 (pool->pos + asize <= pool->end)) 284 (pool->pos + asize <= pool->end))
285 { 285 {
286 /* fits */ 286 /* fits */
287 ret = &pool->memory[pool->pos]; 287 ret = &pool->memory[pool->pos];
288 if (0 != old_size) 288 if (0 != old_size)
289 memmove (ret, 289 memmove (ret,
290 old, 290 old,
291 old_size); 291 old_size);
292 pool->pos += asize; 292 pool->pos += asize;
293 return ret; 293 return ret;
294 } 294 }
295 /* does not fit */ 295 /* does not fit */
296 return NULL; 296 return NULL;
297} 297}
@@ -312,19 +312,19 @@ MHD_pool_reallocate (struct MemoryPool *pool,
312 */ 312 */
313void * 313void *
314MHD_pool_reset (struct MemoryPool *pool, 314MHD_pool_reset (struct MemoryPool *pool,
315 void *keep, 315 void *keep,
316 size_t copy_bytes, 316 size_t copy_bytes,
317 size_t new_size) 317 size_t new_size)
318{ 318{
319 if ( (NULL != keep) && 319 if ( (NULL != keep) &&
320 (keep != pool->memory) ) 320 (keep != pool->memory) )
321 { 321 {
322 if (0 != copy_bytes) 322 if (0 != copy_bytes)
323 memmove (pool->memory, 323 memmove (pool->memory,
324 keep, 324 keep,
325 copy_bytes); 325 copy_bytes);
326 keep = pool->memory; 326 keep = pool->memory;
327 } 327 }
328 pool->end = pool->size; 328 pool->end = pool->size;
329 /* technically not needed, but safer to zero out */ 329 /* technically not needed, but safer to zero out */
330 if (pool->size > copy_bytes) 330 if (pool->size > copy_bytes)
diff --git a/src/lib/memorypool.h b/src/lib/memorypool.h
index 36136af8..774b05ba 100644
--- a/src/lib/memorypool.h
+++ b/src/lib/memorypool.h
@@ -70,7 +70,7 @@ MHD_pool_destroy (struct MemoryPool *pool);
70 */ 70 */
71void * 71void *
72MHD_pool_allocate (struct MemoryPool *pool, 72MHD_pool_allocate (struct MemoryPool *pool,
73 size_t size, 73 size_t size,
74 int from_end); 74 int from_end);
75 75
76 76
@@ -93,9 +93,9 @@ MHD_pool_allocate (struct MemoryPool *pool,
93 */ 93 */
94void * 94void *
95MHD_pool_reallocate (struct MemoryPool *pool, 95MHD_pool_reallocate (struct MemoryPool *pool,
96 void *old, 96 void *old,
97 size_t old_size, 97 size_t old_size,
98 size_t new_size); 98 size_t new_size);
99 99
100 100
101/** 101/**
@@ -123,8 +123,8 @@ MHD_pool_get_free (struct MemoryPool *pool);
123 */ 123 */
124void * 124void *
125MHD_pool_reset (struct MemoryPool *pool, 125MHD_pool_reset (struct MemoryPool *pool,
126 void *keep, 126 void *keep,
127 size_t copy_bytes, 127 size_t copy_bytes,
128 size_t new_size); 128 size_t new_size);
129 129
130#endif 130#endif
diff --git a/src/lib/mhd_assert.h b/src/lib/mhd_assert.h
index c720ce5c..e99632d0 100644
--- a/src/lib/mhd_assert.h
+++ b/src/lib/mhd_assert.h
@@ -28,21 +28,21 @@
28 28
29#include "mhd_options.h" 29#include "mhd_options.h"
30#ifdef NDEBUG 30#ifdef NDEBUG
31# define mhd_assert(ignore) ((void)0) 31# define mhd_assert(ignore) ((void) 0)
32#else /* _DEBUG */ 32#else /* _DEBUG */
33# ifdef HAVE_ASSERT 33# ifdef HAVE_ASSERT
34# include <assert.h> 34# include <assert.h>
35# define mhd_assert(CHK) assert(CHK) 35# define mhd_assert(CHK) assert (CHK)
36# else /* ! HAVE_ASSERT */ 36# else /* ! HAVE_ASSERT */
37# include <stdio.h> 37# include <stdio.h>
38# include <stdlib.h> 38# include <stdlib.h>
39# define mhd_assert(CHK) \ 39# define mhd_assert(CHK) \
40 do { \ 40 do { \
41 if (!(CHK)) { \ 41 if (! (CHK)) { \
42 fprintf(stderr, "%s:%u Assertion failed: %s\nProgram aborted.\n", \ 42 fprintf (stderr, "%s:%u Assertion failed: %s\nProgram aborted.\n", \
43 __FILE__, (unsigned)__LINE__, #CHK); \ 43 __FILE__, (unsigned) __LINE__, #CHK); \
44 fflush(stderr); abort(); } \ 44 fflush (stderr); abort (); } \
45 } while(0) 45 } while (0)
46# endif /* ! HAVE_ASSERT */ 46# endif /* ! HAVE_ASSERT */
47#endif /* _DEBUG */ 47#endif /* _DEBUG */
48 48
diff --git a/src/lib/mhd_byteorder.h b/src/lib/mhd_byteorder.h
index 66689804..230ae803 100644
--- a/src/lib/mhd_byteorder.h
+++ b/src/lib/mhd_byteorder.h
@@ -71,7 +71,8 @@
71#if defined(__BYTE_ORDER__) 71#if defined(__BYTE_ORDER__)
72#if defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 72#if defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
73#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN 73#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
74#elif defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 74#elif defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == \
75 __ORDER_LITTLE_ENDIAN__
75#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN 76#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
76#elif defined(__ORDER_PDP_ENDIAN__) && __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__ 77#elif defined(__ORDER_PDP_ENDIAN__) && __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
77#define _MHD_BYTE_ORDER _MHD_PDP_ENDIAN 78#define _MHD_BYTE_ORDER _MHD_PDP_ENDIAN
@@ -106,36 +107,40 @@
106/* Byte order specification didn't detected in system headers */ 107/* Byte order specification didn't detected in system headers */
107/* Try some guessing */ 108/* Try some guessing */
108 109
109#if (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \ 110#if (defined(__BIG_ENDIAN__) && ! defined(__LITTLE_ENDIAN__)) || \
110 (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) 111 (defined(_BIG_ENDIAN) && ! defined(_LITTLE_ENDIAN))
111/* Seems that we are on big endian platform */ 112/* Seems that we are on big endian platform */
112#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN 113#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
113#elif (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ 114#elif (defined(__LITTLE_ENDIAN__) && ! defined(__BIG_ENDIAN__)) || \
114 (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) 115 (defined(_LITTLE_ENDIAN) && ! defined(_BIG_ENDIAN))
115/* Seems that we are on little endian platform */ 116/* Seems that we are on little endian platform */
116#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN 117#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
117#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || \ 118#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || \
118 defined(_M_X64) || defined(_M_AMD64) || defined(i386) || defined(__i386) || \ 119 defined(__x86_64) || \
119 defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || \ 120 defined(_M_X64) || defined(_M_AMD64) || defined(i386) || defined(__i386) || \
120 defined(_M_IX86) || defined(_X86_) || defined (__THW_INTEL__) 121 defined(__i386__) || defined(__i486__) || defined(__i586__) || \
122 defined(__i686__) || \
123 defined(_M_IX86) || defined(_X86_) || defined (__THW_INTEL__)
121/* x86 family is little endian */ 124/* x86 family is little endian */
122#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN 125#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
123#elif defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \ 126#elif defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
124 defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__) 127 defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__)
125/* Looks like we are on ARM/MIPS in big endian mode */ 128/* Looks like we are on ARM/MIPS in big endian mode */
126#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN 129#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
127#elif defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \ 130#elif defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \
128 defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) 131 defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__)
129/* Looks like we are on ARM/MIPS in little endian mode */ 132/* Looks like we are on ARM/MIPS in little endian mode */
130#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN 133#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
131#elif defined(__m68k__) || defined(M68000) || defined(__hppa__) || defined(__hppa) || \ 134#elif defined(__m68k__) || defined(M68000) || defined(__hppa__) || \
132 defined(__HPPA__) || defined(__370__) || defined(__THW_370__) || \ 135 defined(__hppa) || \
133 defined(__s390__) || defined(__s390x__) || defined(__SYSC_ZARCH__) 136 defined(__HPPA__) || defined(__370__) || defined(__THW_370__) || \
137 defined(__s390__) || defined(__s390x__) || defined(__SYSC_ZARCH__)
134/* Looks like we are on big endian platform */ 138/* Looks like we are on big endian platform */
135#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN 139#define _MHD_BYTE_ORDER _MHD_BIG_ENDIAN
136#elif defined(__ia64__) || defined(_IA64) || defined(__IA64__) || defined(__ia64) || \ 140#elif defined(__ia64__) || defined(_IA64) || defined(__IA64__) || \
137 defined(_M_IA64) || defined(__itanium__) || defined(__bfin__) || \ 141 defined(__ia64) || \
138 defined(__BFIN__) || defined(bfin) || defined(BFIN) 142 defined(_M_IA64) || defined(__itanium__) || defined(__bfin__) || \
143 defined(__BFIN__) || defined(bfin) || defined(BFIN)
139/* Looks like we are on little endian platform */ 144/* Looks like we are on little endian platform */
140#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN 145#define _MHD_BYTE_ORDER _MHD_LITTLE_ENDIAN
141#elif defined(_WIN32) 146#elif defined(_WIN32)
@@ -151,9 +156,11 @@
151#ifdef _MHD_BYTE_ORDER 156#ifdef _MHD_BYTE_ORDER
152/* Some safety checks */ 157/* Some safety checks */
153#if defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN 158#if defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN
154#error Configure detected big endian byte order but headers specify different byte order 159#error \
155#elif !defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN 160 Configure detected big endian byte order but headers specify different byte order
156#error Configure did not detect big endian byte order but headers specify big endian byte order 161#elif ! defined(WORDS_BIGENDIAN) && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
162#error \
163 Configure did not detect big endian byte order but headers specify big endian byte order
157#endif /* !WORDS_BIGENDIAN && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN */ 164#endif /* !WORDS_BIGENDIAN && _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN */
158#endif /* _MHD_BYTE_ORDER */ 165#endif /* _MHD_BYTE_ORDER */
159 166
diff --git a/src/lib/mhd_compat.c b/src/lib/mhd_compat.c
index 3abdc367..6f6c6f9c 100644
--- a/src/lib/mhd_compat.c
+++ b/src/lib/mhd_compat.c
@@ -25,7 +25,7 @@
25 */ 25 */
26 26
27#include "mhd_compat.h" 27#include "mhd_compat.h"
28#if defined(_WIN32) && !defined(__CYGWIN__) 28#if defined(_WIN32) && ! defined(__CYGWIN__)
29#include <stdint.h> 29#include <stdint.h>
30#include <time.h> 30#include <time.h>
31#ifndef HAVE_SNPRINTF 31#ifndef HAVE_SNPRINTF
@@ -38,7 +38,7 @@
38#include <string.h> /* for memset() */ 38#include <string.h> /* for memset() */
39#endif /* ! HAVE_CALLOC */ 39#endif /* ! HAVE_CALLOC */
40 40
41#if defined(_WIN32) && !defined(__CYGWIN__) 41#if defined(_WIN32) && ! defined(__CYGWIN__)
42 42
43#ifndef HAVE_SNPRINTF 43#ifndef HAVE_SNPRINTF
44/* Emulate snprintf function on W32 */ 44/* Emulate snprintf function on W32 */
@@ -61,16 +61,16 @@ W32_snprintf (char *__restrict s,
61 format, 61 format,
62 args); 62 args);
63 va_end (args); 63 va_end (args);
64 if ((int)n == ret) 64 if ((int) n == ret)
65 s[n - 1] = 0; 65 s[n - 1] = 0;
66 if (ret >= 0) 66 if (ret >= 0)
67 return ret; 67 return ret;
68 } 68 }
69 va_start(args, 69 va_start (args,
70 format); 70 format);
71 ret = _vscprintf (format, 71 ret = _vscprintf (format,
72 args); 72 args);
73 va_end(args); 73 va_end (args);
74 if ( (0 <= ret) && 74 if ( (0 <= ret) &&
75 (0 != n) && 75 (0 != n) &&
76 (NULL == s) ) 76 (NULL == s) )
@@ -85,30 +85,30 @@ W32_snprintf (char *__restrict s,
85#ifndef HAVE_CALLOC 85#ifndef HAVE_CALLOC
86 86
87#ifdef __has_builtin 87#ifdef __has_builtin
88# if __has_builtin(__builtin_mul_overflow) 88# if __has_builtin (__builtin_mul_overflow)
89# define MHD_HAVE_NUL_OVERFLOW 1 89# define MHD_HAVE_NUL_OVERFLOW 1
90# endif 90# endif
91#elif __GNUC__+0 >= 5 91#elif __GNUC__ + 0 >= 5
92# define MHD_HAVE_NUL_OVERFLOW 1 92# define MHD_HAVE_NUL_OVERFLOW 1
93#endif /* __GNUC__ >= 5 */ 93#endif /* __GNUC__ >= 5 */
94 94
95 95
96void *MHD_calloc_(size_t nelem, size_t elsize) 96void *MHD_calloc_ (size_t nelem, size_t elsize)
97{ 97{
98 size_t alloc_size; 98 size_t alloc_size;
99 void *ptr; 99 void *ptr;
100#ifdef MHD_HAVE_NUL_OVERFLOW 100#ifdef MHD_HAVE_NUL_OVERFLOW
101 if (__builtin_mul_overflow(nelem, elsize, &alloc_size) || 0 == alloc_size) 101 if (__builtin_mul_overflow (nelem, elsize, &alloc_size) ||(0 == alloc_size))
102 return NULL; 102 return NULL;
103#else /* ! MHD_HAVE_NUL_OVERFLOW */ 103#else /* ! MHD_HAVE_NUL_OVERFLOW */
104 alloc_size = nelem * elsize; 104 alloc_size = nelem * elsize;
105 if (0 == alloc_size || elsize != alloc_size / nelem) 105 if ((0 == alloc_size)||(elsize != alloc_size / nelem))
106 return NULL; 106 return NULL;
107#endif /* ! MHD_HAVE_NUL_OVERFLOW */ 107#endif /* ! MHD_HAVE_NUL_OVERFLOW */
108 ptr = malloc (alloc_size); 108 ptr = malloc (alloc_size);
109 if (NULL == ptr) 109 if (NULL == ptr)
110 return NULL; 110 return NULL;
111 memset(ptr, 0, alloc_size); 111 memset (ptr, 0, alloc_size);
112 return ptr; 112 return ptr;
113} 113}
114#endif /* ! HAVE_CALLOC */ 114#endif /* ! HAVE_CALLOC */
diff --git a/src/lib/mhd_compat.h b/src/lib/mhd_compat.h
index b4e2c66c..6b38a03e 100644
--- a/src/lib/mhd_compat.h
+++ b/src/lib/mhd_compat.h
@@ -40,8 +40,8 @@
40#include <string.h> 40#include <string.h>
41#endif /* HAVE_STRING_H */ 41#endif /* HAVE_STRING_H */
42 42
43 /* MHD_strerror_ is strerror */ 43/* MHD_strerror_ is strerror */
44#define MHD_strerror_(errnum) strerror((errnum)) 44#define MHD_strerror_(errnum) strerror ((errnum))
45 45
46/* Platform-independent snprintf name */ 46/* Platform-independent snprintf name */
47#if defined(HAVE_SNPRINTF) 47#if defined(HAVE_SNPRINTF)
@@ -49,10 +49,12 @@
49#else /* ! HAVE_SNPRINTF */ 49#else /* ! HAVE_SNPRINTF */
50#if defined(_WIN32) && ! defined(__CYGWIN__) 50#if defined(_WIN32) && ! defined(__CYGWIN__)
51/* Emulate snprintf function on W32 */ 51/* Emulate snprintf function on W32 */
52int W32_snprintf(char *__restrict s, size_t n, const char *__restrict format, ...); 52int W32_snprintf (char *__restrict s, size_t n, const char *__restrict format,
53 ...);
53#define MHD_snprintf_ W32_snprintf 54#define MHD_snprintf_ W32_snprintf
54#else /* ! _WIN32 || __CYGWIN__ */ 55#else /* ! _WIN32 || __CYGWIN__ */
55#error Your platform does not support snprintf() and MHD does not know how to emulate it on your platform. 56#error \
57 Your platform does not support snprintf() and MHD does not know how to emulate it on your platform.
56#endif /* ! _WIN32 || __CYGWIN__ */ 58#endif /* ! _WIN32 || __CYGWIN__ */
57#endif /* ! HAVE_SNPRINTF */ 59#endif /* ! HAVE_SNPRINTF */
58 60
@@ -61,14 +63,14 @@ int W32_snprintf(char *__restrict s, size_t n, const char *__restrict format, ..
61 * Generate pseudo random number at least 30-bit wide. 63 * Generate pseudo random number at least 30-bit wide.
62 * @return pseudo random number at least 30-bit wide. 64 * @return pseudo random number at least 30-bit wide.
63 */ 65 */
64#define MHD_random_() random() 66#define MHD_random_() random ()
65#else /* HAVE_RANDOM */ 67#else /* HAVE_RANDOM */
66#ifdef HAVE_RAND 68#ifdef HAVE_RAND
67/** 69/**
68 * Generate pseudo random number at least 30-bit wide. 70 * Generate pseudo random number at least 30-bit wide.
69 * @return pseudo random number at least 30-bit wide. 71 * @return pseudo random number at least 30-bit wide.
70 */ 72 */
71#define MHD_random_() ( (((long)rand()) << 15) + (long)rand() ) 73#define MHD_random_() ( (((long) rand ()) << 15) + (long) rand () )
72#endif /* HAVE_RAND */ 74#endif /* HAVE_RAND */
73#endif /* HAVE_RANDOM */ 75#endif /* HAVE_RANDOM */
74 76
@@ -76,12 +78,12 @@ int W32_snprintf(char *__restrict s, size_t n, const char *__restrict format, ..
76/** 78/**
77 * MHD_calloc_ is platform-independent calloc() 79 * MHD_calloc_ is platform-independent calloc()
78 */ 80 */
79#define MHD_calloc_(n,s) calloc((n),(s)) 81#define MHD_calloc_(n,s) calloc ((n),(s))
80#else /* ! HAVE_CALLOC */ 82#else /* ! HAVE_CALLOC */
81/** 83/**
82 * MHD_calloc_ is platform-independent calloc() 84 * MHD_calloc_ is platform-independent calloc()
83 */ 85 */
84void *MHD_calloc_(size_t nelem, size_t elsize); 86void *MHD_calloc_ (size_t nelem, size_t elsize);
85#endif /* ! HAVE_CALLOC */ 87#endif /* ! HAVE_CALLOC */
86 88
87#endif /* MHD_COMPAT_H */ 89#endif /* MHD_COMPAT_H */
diff --git a/src/lib/mhd_itc.c b/src/lib/mhd_itc.c
index 8aeee576..6c81ef62 100644
--- a/src/lib/mhd_itc.c
+++ b/src/lib/mhd_itc.c
@@ -34,7 +34,7 @@
34 34
35 35
36#if defined(_MHD_ITC_PIPE) 36#if defined(_MHD_ITC_PIPE)
37#if !defined(_WIN32) || defined(__CYGWIN__) 37#if ! defined(_WIN32) || defined(__CYGWIN__)
38 38
39#ifndef HAVE_PIPE2_FUNC 39#ifndef HAVE_PIPE2_FUNC
40/** 40/**
@@ -48,7 +48,7 @@ MHD_itc_nonblocking_ (struct MHD_itc_ itc)
48{ 48{
49 unsigned int i; 49 unsigned int i;
50 50
51 for (i=0;i<2;i++) 51 for (i = 0; i<2; i++)
52 { 52 {
53 int flags; 53 int flags;
54 54
@@ -63,7 +63,7 @@ MHD_itc_nonblocking_ (struct MHD_itc_ itc)
63 flags | O_NONBLOCK)) ) 63 flags | O_NONBLOCK)) )
64 return 0; 64 return 0;
65 } 65 }
66 return !0; 66 return ! 0;
67} 67}
68#endif /* ! HAVE_PIPE2_FUNC */ 68#endif /* ! HAVE_PIPE2_FUNC */
69#endif /* !_WIN32 || __CYGWIN__ */ 69#endif /* !_WIN32 || __CYGWIN__ */
diff --git a/src/lib/mhd_itc.h b/src/lib/mhd_itc.h
index 01331f13..8e303ef9 100644
--- a/src/lib/mhd_itc.h
+++ b/src/lib/mhd_itc.h
@@ -41,8 +41,9 @@
41# include <stdlib.h> 41# include <stdlib.h>
42/* Simple implementation of MHD_PANIC, to be used outside lib */ 42/* Simple implementation of MHD_PANIC, to be used outside lib */
43# define MHD_PANIC(msg) do { fprintf (stderr, \ 43# define MHD_PANIC(msg) do { fprintf (stderr, \
44 "Abnormal termination at %d line in file %s: %s\n", \ 44 "Abnormal termination at %d line in file %s: %s\n", \
45 (int)__LINE__, __FILE__, msg); abort();} while(0) 45 (int) __LINE__, __FILE__, msg); abort (); \
46} while (0)
46#endif /* ! MHD_PANIC */ 47#endif /* ! MHD_PANIC */
47 48
48#if defined(_MHD_ITC_EVENTFD) 49#if defined(_MHD_ITC_EVENTFD)
@@ -63,12 +64,13 @@
63 * @param itc the itc to initialise 64 * @param itc the itc to initialise
64 * @return non-zero if succeeded, zero otherwise 65 * @return non-zero if succeeded, zero otherwise
65 */ 66 */
66#define MHD_itc_init_(itc) (-1 != ((itc).fd = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK))) 67#define MHD_itc_init_(itc) (-1 != ((itc).fd = eventfd (0, EFD_CLOEXEC \
68 | EFD_NONBLOCK)))
67 69
68/** 70/**
69 * Get description string of last errno for itc operations. 71 * Get description string of last errno for itc operations.
70 */ 72 */
71#define MHD_itc_last_strerror_() strerror(errno) 73#define MHD_itc_last_strerror_() strerror (errno)
72 74
73/** 75/**
74 * Internal static const helper for MHD_itc_activate_() 76 * Internal static const helper for MHD_itc_activate_()
@@ -82,7 +84,8 @@ static const uint64_t _MHD_itc_wr_data = 1;
82 * @return non-zero if succeeded, zero otherwise 84 * @return non-zero if succeeded, zero otherwise
83 */ 85 */
84#define MHD_itc_activate_(itc, str) \ 86#define MHD_itc_activate_(itc, str) \
85 ((write((itc).fd, (const void*)&_MHD_itc_wr_data, 8) > 0) || (EAGAIN == errno)) 87 ((write ((itc).fd, (const void*) &_MHD_itc_wr_data, 8) > 0) || (EAGAIN == \
88 errno))
86 89
87/** 90/**
88 * Return read FD of @a itc which can be used for poll(), select() etc. 91 * Return read FD of @a itc which can be used for poll(), select() etc.
@@ -104,8 +107,8 @@ static const uint64_t _MHD_itc_wr_data = 1;
104 */ 107 */
105#define MHD_itc_clear_(itc) \ 108#define MHD_itc_clear_(itc) \
106 do { uint64_t __b; int __r; \ 109 do { uint64_t __b; int __r; \
107 __r = read((itc).fd, &__b, sizeof(__b)); \ 110 __r = read ((itc).fd, &__b, sizeof(__b)); \
108 (void)__r; } while(0) 111 (void) __r; } while (0)
109 112
110/** 113/**
111 * Destroy previously initialised ITC. Note that close() 114 * Destroy previously initialised ITC. Note that close()
@@ -155,20 +158,20 @@ static const uint64_t _MHD_itc_wr_data = 1;
155 * @return non-zero if succeeded, zero otherwise 158 * @return non-zero if succeeded, zero otherwise
156 */ 159 */
157#ifdef HAVE_PIPE2_FUNC 160#ifdef HAVE_PIPE2_FUNC
158# define MHD_itc_init_(itc) (!pipe2((itc).fd, O_CLOEXEC | O_NONBLOCK)) 161# define MHD_itc_init_(itc) (! pipe2 ((itc).fd, O_CLOEXEC | O_NONBLOCK))
159#else /* ! HAVE_PIPE2_FUNC */ 162#else /* ! HAVE_PIPE2_FUNC */
160# define MHD_itc_init_(itc) \ 163# define MHD_itc_init_(itc) \
161 ( (!pipe((itc).fd)) ? \ 164 ( (! pipe ((itc).fd)) ? \
162 (MHD_itc_nonblocking_((itc)) ? \ 165 (MHD_itc_nonblocking_ ((itc)) ? \
163 (!0) : \ 166 (! 0) : \
164 (MHD_itc_destroy_((itc)), 0) ) \ 167 (MHD_itc_destroy_ ((itc)), 0) ) \
165 : (0) ) 168 : (0) )
166#endif /* ! HAVE_PIPE2_FUNC */ 169#endif /* ! HAVE_PIPE2_FUNC */
167 170
168/** 171/**
169 * Get description string of last errno for itc operations. 172 * Get description string of last errno for itc operations.
170 */ 173 */
171#define MHD_itc_last_strerror_() strerror(errno) 174#define MHD_itc_last_strerror_() strerror (errno)
172 175
173/** 176/**
174 * Activate signal on @a itc 177 * Activate signal on @a itc
@@ -177,7 +180,7 @@ static const uint64_t _MHD_itc_wr_data = 1;
177 * @return non-zero if succeeded, zero otherwise 180 * @return non-zero if succeeded, zero otherwise
178 */ 181 */
179#define MHD_itc_activate_(itc, str) \ 182#define MHD_itc_activate_(itc, str) \
180 ((write((itc).fd[1], (const void*)(str), 1) > 0) || (EAGAIN == errno)) 183 ((write ((itc).fd[1], (const void*) (str), 1) > 0) || (EAGAIN == errno))
181 184
182 185
183/** 186/**
@@ -200,8 +203,8 @@ static const uint64_t _MHD_itc_wr_data = 1;
200 */ 203 */
201#define MHD_itc_clear_(itc) do \ 204#define MHD_itc_clear_(itc) do \
202 { long __b; \ 205 { long __b; \
203 while(0 < read((itc).fd[0], &__b, sizeof(__b))) \ 206 while (0 < read ((itc).fd[0], &__b, sizeof(__b))) \
204 {} } while(0) 207 {} } while (0)
205 208
206/** 209/**
207 * Destroy previously initialised ITC 210 * Destroy previously initialised ITC
@@ -210,8 +213,8 @@ static const uint64_t _MHD_itc_wr_data = 1;
210 */ 213 */
211#define MHD_itc_destroy_(itc) \ 214#define MHD_itc_destroy_(itc) \
212 ( (0 == close ((itc).fd[0])) ? \ 215 ( (0 == close ((itc).fd[0])) ? \
213 (0 == close ((itc).fd[1])) : \ 216 (0 == close ((itc).fd[1])) : \
214 ((close ((itc).fd[1])), 0) ) 217 ((close ((itc).fd[1])), 0) )
215 218
216/** 219/**
217 * Check whether ITC has valid value. 220 * Check whether ITC has valid value.
@@ -231,14 +234,14 @@ static const uint64_t _MHD_itc_wr_data = 1;
231#define MHD_itc_set_invalid_(itc) ((itc).fd[0] = (itc).fd[1] = -1) 234#define MHD_itc_set_invalid_(itc) ((itc).fd[0] = (itc).fd[1] = -1)
232 235
233#ifndef HAVE_PIPE2_FUNC 236#ifndef HAVE_PIPE2_FUNC
234 /** 237/**
235 * Change itc FD options to be non-blocking. 238 * Change itc FD options to be non-blocking.
236 * 239 *
237 * @param fd the FD to manipulate 240 * @param fd the FD to manipulate
238 * @return non-zero if succeeded, zero otherwise 241 * @return non-zero if succeeded, zero otherwise
239 */ 242 */
240 int 243int
241 MHD_itc_nonblocking_ (struct MHD_itc_ itc); 244MHD_itc_nonblocking_ (struct MHD_itc_ itc);
242#endif /* ! HAVE_PIPE2_FUNC */ 245#endif /* ! HAVE_PIPE2_FUNC */
243 246
244 247
@@ -255,20 +258,20 @@ static const uint64_t _MHD_itc_wr_data = 1;
255 * @return non-zero if succeeded, zero otherwise 258 * @return non-zero if succeeded, zero otherwise
256 */ 259 */
257#ifdef MHD_socket_pair_nblk_ 260#ifdef MHD_socket_pair_nblk_
258# define MHD_itc_init_(itc) MHD_socket_pair_nblk_((itc).sk) 261# define MHD_itc_init_(itc) MHD_socket_pair_nblk_ ((itc).sk)
259#else /* ! MHD_socket_pair_nblk_ */ 262#else /* ! MHD_socket_pair_nblk_ */
260# define MHD_itc_init_(itc) \ 263# define MHD_itc_init_(itc) \
261 (MHD_socket_pair_((itc).sk) ? \ 264 (MHD_socket_pair_ ((itc).sk) ? \
262 (MHD_itc_nonblocking_((itc)) ? \ 265 (MHD_itc_nonblocking_ ((itc)) ? \
263 (!0) : \ 266 (! 0) : \
264 (MHD_itc_destroy_((itc)), 0) ) \ 267 (MHD_itc_destroy_ ((itc)), 0) ) \
265 : (0)) 268 : (0))
266#endif /* ! MHD_socket_pair_nblk_ */ 269#endif /* ! MHD_socket_pair_nblk_ */
267 270
268/** 271/**
269 * Get description string of last error for itc operations. 272 * Get description string of last error for itc operations.
270 */ 273 */
271#define MHD_itc_last_strerror_() MHD_socket_last_strerr_() 274#define MHD_itc_last_strerror_() MHD_socket_last_strerr_ ()
272 275
273/** 276/**
274 * Activate signal on @a itc 277 * Activate signal on @a itc
@@ -277,8 +280,8 @@ static const uint64_t _MHD_itc_wr_data = 1;
277 * @return non-zero if succeeded, zero otherwise 280 * @return non-zero if succeeded, zero otherwise
278 */ 281 */
279#define MHD_itc_activate_(itc, str) \ 282#define MHD_itc_activate_(itc, str) \
280 ((MHD_send_((itc).sk[1], (str), 1) > 0) || \ 283 ((MHD_send_ ((itc).sk[1], (str), 1) > 0) || \
281 (MHD_SCKT_ERR_IS_EAGAIN_(MHD_socket_get_error_()))) 284 (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ())))
282 285
283/** 286/**
284 * Return read FD of @a itc which can be used for poll(), select() etc. 287 * Return read FD of @a itc which can be used for poll(), select() etc.
@@ -300,10 +303,10 @@ static const uint64_t _MHD_itc_wr_data = 1;
300 */ 303 */
301#define MHD_itc_clear_(itc) do \ 304#define MHD_itc_clear_(itc) do \
302 { long __b; \ 305 { long __b; \
303 while(0 < recv((itc).sk[0], \ 306 while (0 < recv ((itc).sk[0], \
304 (char*)&__b, \ 307 (char*) &__b, \
305 sizeof(__b), 0)) \ 308 sizeof(__b), 0)) \
306 {} } while(0) 309 {} } while (0)
307 310
308/** 311/**
309 * Destroy previously initialised ITC 312 * Destroy previously initialised ITC
@@ -311,9 +314,9 @@ static const uint64_t _MHD_itc_wr_data = 1;
311 * @return non-zero if succeeded, zero otherwise 314 * @return non-zero if succeeded, zero otherwise
312 */ 315 */
313#define MHD_itc_destroy_(itc) \ 316#define MHD_itc_destroy_(itc) \
314 ( MHD_socket_close_((itc).sk[0]) ? \ 317 (MHD_socket_close_ ((itc).sk[0]) ? \
315 MHD_socket_close_((itc).sk[1]) : \ 318 MHD_socket_close_ ((itc).sk[1]) : \
316 ((void)MHD_socket_close_((itc).sk[1]), 0) ) 319 ((void) MHD_socket_close_ ((itc).sk[1]), 0) )
317 320
318 321
319/** 322/**
@@ -331,10 +334,12 @@ static const uint64_t _MHD_itc_wr_data = 1;
331 * Set @a itc to invalid value. 334 * Set @a itc to invalid value.
332 * @param itc the itc to set 335 * @param itc the itc to set
333 */ 336 */
334#define MHD_itc_set_invalid_(itc) ((itc).sk[0] = (itc).sk[1] = MHD_INVALID_SOCKET) 337#define MHD_itc_set_invalid_(itc) ((itc).sk[0] = (itc).sk[1] = \
338 MHD_INVALID_SOCKET)
335 339
336#ifndef MHD_socket_pair_nblk_ 340#ifndef MHD_socket_pair_nblk_
337# define MHD_itc_nonblocking_(pip) (MHD_socket_nonblocking_((pip).sk[0]) && MHD_socket_nonblocking_((pip).sk[1])) 341# define MHD_itc_nonblocking_(pip) (MHD_socket_nonblocking_ ((pip).sk[0]) && \
342 MHD_socket_nonblocking_ ((pip).sk[1]))
338#endif /* ! MHD_socket_pair_nblk_ */ 343#endif /* ! MHD_socket_pair_nblk_ */
339 344
340#endif /* _MHD_ITC_SOCKETPAIR */ 345#endif /* _MHD_ITC_SOCKETPAIR */
@@ -345,9 +350,9 @@ static const uint64_t _MHD_itc_wr_data = 1;
345 * @param itc the itc to destroy 350 * @param itc the itc to destroy
346 */ 351 */
347#define MHD_itc_destroy_chk_(itc) do { \ 352#define MHD_itc_destroy_chk_(itc) do { \
348 if (!MHD_itc_destroy_(itc)) \ 353 if (! MHD_itc_destroy_ (itc)) \
349 MHD_PANIC(_("Failed to destroy ITC.\n")); \ 354 MHD_PANIC (_ ("Failed to destroy ITC.\n")); \
350 } while(0) 355} while (0)
351 356
352/** 357/**
353 * Check whether ITC has invalid value. 358 * Check whether ITC has invalid value.
@@ -358,6 +363,6 @@ static const uint64_t _MHD_itc_wr_data = 1;
358 * @return boolean true if @a itc has invalid value, 363 * @return boolean true if @a itc has invalid value,
359 * boolean false otherwise. 364 * boolean false otherwise.
360 */ 365 */
361#define MHD_ITC_IS_INVALID_(itc) (! MHD_ITC_IS_VALID_(itc)) 366#define MHD_ITC_IS_INVALID_(itc) (! MHD_ITC_IS_VALID_ (itc))
362 367
363#endif /* MHD_ITC_H */ 368#endif /* MHD_ITC_H */
diff --git a/src/lib/mhd_itc_types.h b/src/lib/mhd_itc_types.h
index 04966d36..36d4218b 100644
--- a/src/lib/mhd_itc_types.h
+++ b/src/lib/mhd_itc_types.h
@@ -32,7 +32,7 @@
32#include "mhd_options.h" 32#include "mhd_options.h"
33 33
34/* Force socketpair on native W32 */ 34/* Force socketpair on native W32 */
35#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(_MHD_ITC_SOCKETPAIR) 35#if defined(_WIN32) && ! defined(__CYGWIN__) && ! defined(_MHD_ITC_SOCKETPAIR)
36#error _MHD_ITC_SOCKETPAIR is not defined on naitive W32 platform 36#error _MHD_ITC_SOCKETPAIR is not defined on naitive W32 platform
37#endif /* _WIN32 && !__CYGWIN__ && !_MHD_ITC_SOCKETPAIR */ 37#endif /* _WIN32 && !__CYGWIN__ && !_MHD_ITC_SOCKETPAIR */
38 38
diff --git a/src/lib/mhd_limits.h b/src/lib/mhd_limits.h
index 41d33a8f..87b41447 100644
--- a/src/lib/mhd_limits.h
+++ b/src/lib/mhd_limits.h
@@ -32,17 +32,17 @@
32#include <limits.h> 32#include <limits.h>
33#endif /* HAVE_LIMITS_H */ 33#endif /* HAVE_LIMITS_H */
34 34
35#define MHD_UNSIGNED_TYPE_MAX_(type) ((type)-1) 35#define MHD_UNSIGNED_TYPE_MAX_(type) ((type) - 1)
36/* Assume 8 bits per byte, no padding bits. */ 36/* Assume 8 bits per byte, no padding bits. */
37#define MHD_SIGNED_TYPE_MAX_(type) \ 37#define MHD_SIGNED_TYPE_MAX_(type) \
38 ( (type)((( ((type)1) << (sizeof(type)*8 - 2)) - 1)*2 + 1) ) 38 ( (type) ((( ((type) 1) << (sizeof(type) * 8 - 2)) - 1) * 2 + 1) )
39#define MHD_TYPE_IS_SIGNED_(type) (((type)0)>((type)-1)) 39#define MHD_TYPE_IS_SIGNED_(type) (((type) 0)>((type) - 1))
40 40
41#ifndef UINT_MAX 41#ifndef UINT_MAX
42#ifdef __UINT_MAX__ 42#ifdef __UINT_MAX__
43#define UINT_MAX __UINT_MAX__ 43#define UINT_MAX __UINT_MAX__
44#else /* ! __UINT_MAX__ */ 44#else /* ! __UINT_MAX__ */
45#define UINT_MAX MHD_UNSIGNED_TYPE_MAX_(unsigned int) 45#define UINT_MAX MHD_UNSIGNED_TYPE_MAX_ (unsigned int)
46#endif /* ! __UINT_MAX__ */ 46#endif /* ! __UINT_MAX__ */
47#endif /* !UINT_MAX */ 47#endif /* !UINT_MAX */
48 48
@@ -50,19 +50,19 @@
50#ifdef __LONG_MAX__ 50#ifdef __LONG_MAX__
51#define LONG_MAX __LONG_MAX__ 51#define LONG_MAX __LONG_MAX__
52#else /* ! __LONG_MAX__ */ 52#else /* ! __LONG_MAX__ */
53#define LONG_MAX MHD_SIGNED_TYPE_MAX(long) 53#define LONG_MAX MHD_SIGNED_TYPE_MAX (long)
54#endif /* ! __LONG_MAX__ */ 54#endif /* ! __LONG_MAX__ */
55#endif /* !OFF_T_MAX */ 55#endif /* !OFF_T_MAX */
56 56
57#ifndef ULLONG_MAX 57#ifndef ULLONG_MAX
58#define ULLONG_MAX MHD_UNSIGNED_TYPE_MAX_(MHD_UNSIGNED_LONG_LONG) 58#define ULLONG_MAX MHD_UNSIGNED_TYPE_MAX_ (MHD_UNSIGNED_LONG_LONG)
59#endif /* !ULLONG_MAX */ 59#endif /* !ULLONG_MAX */
60 60
61#ifndef INT32_MAX 61#ifndef INT32_MAX
62#ifdef __INT32_MAX__ 62#ifdef __INT32_MAX__
63#define INT32_MAX __INT32_MAX__ 63#define INT32_MAX __INT32_MAX__
64#else /* ! __INT32_MAX__ */ 64#else /* ! __INT32_MAX__ */
65#define INT32_MAX ((int32_t)0x7FFFFFFF) 65#define INT32_MAX ((int32_t) 0x7FFFFFFF)
66#endif /* ! __INT32_MAX__ */ 66#endif /* ! __INT32_MAX__ */
67#endif /* !INT32_MAX */ 67#endif /* !INT32_MAX */
68 68
@@ -70,7 +70,7 @@
70#ifdef __UINT32_MAX__ 70#ifdef __UINT32_MAX__
71#define UINT32_MAX __UINT32_MAX__ 71#define UINT32_MAX __UINT32_MAX__
72#else /* ! __UINT32_MAX__ */ 72#else /* ! __UINT32_MAX__ */
73#define UINT32_MAX ((int32_t)0xFFFFFFFF) 73#define UINT32_MAX ((int32_t) 0xFFFFFFFF)
74#endif /* ! __UINT32_MAX__ */ 74#endif /* ! __UINT32_MAX__ */
75#endif /* !UINT32_MAX */ 75#endif /* !UINT32_MAX */
76 76
@@ -78,7 +78,7 @@
78#ifdef __UINT64_MAX__ 78#ifdef __UINT64_MAX__
79#define UINT64_MAX __UINT64_MAX__ 79#define UINT64_MAX __UINT64_MAX__
80#else /* ! __UINT64_MAX__ */ 80#else /* ! __UINT64_MAX__ */
81#define UINT64_MAX ((uint64_t)0xFFFFFFFFFFFFFFFF) 81#define UINT64_MAX ((uint64_t) 0xFFFFFFFFFFFFFFFF)
82#endif /* ! __UINT64_MAX__ */ 82#endif /* ! __UINT64_MAX__ */
83#endif /* !UINT64_MAX */ 83#endif /* !UINT64_MAX */
84 84
@@ -86,7 +86,7 @@
86#ifdef __INT64_MAX__ 86#ifdef __INT64_MAX__
87#define INT64_MAX __INT64_MAX__ 87#define INT64_MAX __INT64_MAX__
88#else /* ! __INT64_MAX__ */ 88#else /* ! __INT64_MAX__ */
89#define INT64_MAX ((int64_t)0x7FFFFFFFFFFFFFFF) 89#define INT64_MAX ((int64_t) 0x7FFFFFFFFFFFFFFF)
90#endif /* ! __UINT64_MAX__ */ 90#endif /* ! __UINT64_MAX__ */
91#endif /* !INT64_MAX */ 91#endif /* !INT64_MAX */
92 92
@@ -96,8 +96,8 @@
96#elif defined(UINTPTR_MAX) 96#elif defined(UINTPTR_MAX)
97#define SIZE_MAX UINTPTR_MAX 97#define SIZE_MAX UINTPTR_MAX
98#else /* ! __SIZE_MAX__ */ 98#else /* ! __SIZE_MAX__ */
99#define SIZE_MAX MHD_UNSIGNED_TYPE_MAX_(size_t) 99#define SIZE_MAX MHD_UNSIGNED_TYPE_MAX_ (size_t)
100#endif /* ! __SIZE_MAX__ */ 100#endif /* ! __SIZE_MAX__ */
101#endif /* !SIZE_MAX */ 101#endif /* !SIZE_MAX */
102 102
103#ifndef SSIZE_MAX 103#ifndef SSIZE_MAX
@@ -108,7 +108,7 @@
108#elif defined(INTPTR_MAX) 108#elif defined(INTPTR_MAX)
109#define SSIZE_MAX INTPTR_MAX 109#define SSIZE_MAX INTPTR_MAX
110#else 110#else
111#define SSIZE_MAN MHD_SIGNED_TYPE_MAX_(ssize_t) 111#define SSIZE_MAN MHD_SIGNED_TYPE_MAX_ (ssize_t)
112#endif 112#endif
113#endif /* ! SSIZE_MAX */ 113#endif /* ! SSIZE_MAX */
114 114
@@ -120,19 +120,19 @@
120#elif defined(__APPLE__) && defined(__MACH__) 120#elif defined(__APPLE__) && defined(__MACH__)
121#define OFF_T_MAX INT64_MAX 121#define OFF_T_MAX INT64_MAX
122#else 122#else
123#define OFF_T_MAX MHD_SIGNED_TYPE_MAX_(off_t) 123#define OFF_T_MAX MHD_SIGNED_TYPE_MAX_ (off_t)
124#endif 124#endif
125#endif /* !OFF_T_MAX */ 125#endif /* !OFF_T_MAX */
126 126
127#if defined(_LARGEFILE64_SOURCE) && !defined(OFF64_T_MAX) 127#if defined(_LARGEFILE64_SOURCE) && ! defined(OFF64_T_MAX)
128#define OFF64_T_MAX MHD_SIGNED_TYPE_MAX_(uint64_t) 128#define OFF64_T_MAX MHD_SIGNED_TYPE_MAX_ (uint64_t)
129#endif /* _LARGEFILE64_SOURCE && !OFF64_T_MAX */ 129#endif /* _LARGEFILE64_SOURCE && !OFF64_T_MAX */
130 130
131#ifndef TIME_T_MAX 131#ifndef TIME_T_MAX
132#define TIME_T_MAX ((time_t) \ 132#define TIME_T_MAX ((time_t) \
133 ( MHD_TYPE_IS_SIGNED_(time_t) ? \ 133 (MHD_TYPE_IS_SIGNED_ (time_t) ? \
134 MHD_SIGNED_TYPE_MAX_(time_t) : \ 134 MHD_SIGNED_TYPE_MAX_ (time_t) : \
135 MHD_UNSIGNED_TYPE_MAX_(time_t))) 135 MHD_UNSIGNED_TYPE_MAX_ (time_t)))
136#endif /* !TIME_T_MAX */ 136#endif /* !TIME_T_MAX */
137 137
138#ifndef TIMEVAL_TV_SEC_MAX 138#ifndef TIMEVAL_TV_SEC_MAX
diff --git a/src/lib/mhd_locks.h b/src/lib/mhd_locks.h
index 21db56c4..8c9b0844 100644
--- a/src/lib/mhd_locks.h
+++ b/src/lib/mhd_locks.h
@@ -59,14 +59,15 @@
59# include <stdlib.h> 59# include <stdlib.h>
60/* Simple implementation of MHD_PANIC, to be used outside lib */ 60/* Simple implementation of MHD_PANIC, to be used outside lib */
61# define MHD_PANIC(msg) do { fprintf (stderr, \ 61# define MHD_PANIC(msg) do { fprintf (stderr, \
62 "Abnormal termination at %d line in file %s: %s\n", \ 62 "Abnormal termination at %d line in file %s: %s\n", \
63 (int)__LINE__, __FILE__, msg); abort();} while(0) 63 (int) __LINE__, __FILE__, msg); abort (); \
64} while (0)
64#endif /* ! MHD_PANIC */ 65#endif /* ! MHD_PANIC */
65 66
66#if defined(MHD_PTHREAD_MUTEX_) 67#if defined(MHD_PTHREAD_MUTEX_)
67 typedef pthread_mutex_t MHD_mutex_; 68typedef pthread_mutex_t MHD_mutex_;
68#elif defined(MHD_W32_MUTEX_) 69#elif defined(MHD_W32_MUTEX_)
69 typedef CRITICAL_SECTION MHD_mutex_; 70typedef CRITICAL_SECTION MHD_mutex_;
70#endif 71#endif
71 72
72#if defined(MHD_PTHREAD_MUTEX_) 73#if defined(MHD_PTHREAD_MUTEX_)
@@ -75,14 +76,15 @@
75 * @param pmutex pointer to the mutex 76 * @param pmutex pointer to the mutex
76 * @return nonzero on success, zero otherwise 77 * @return nonzero on success, zero otherwise
77 */ 78 */
78#define MHD_mutex_init_(pmutex) (!(pthread_mutex_init((pmutex), NULL))) 79#define MHD_mutex_init_(pmutex) (! (pthread_mutex_init ((pmutex), NULL)))
79#elif defined(MHD_W32_MUTEX_) 80#elif defined(MHD_W32_MUTEX_)
80/** 81/**
81 * Initialise new mutex. 82 * Initialise new mutex.
82 * @param pmutex pointer to mutex 83 * @param pmutex pointer to mutex
83 * @return nonzero on success, zero otherwise 84 * @return nonzero on success, zero otherwise
84 */ 85 */
85#define MHD_mutex_init_(pmutex) (InitializeCriticalSectionAndSpinCount((pmutex),16)) 86#define MHD_mutex_init_(pmutex) (InitializeCriticalSectionAndSpinCount ( \
87 (pmutex),16))
86#endif 88#endif
87 89
88#if defined(MHD_PTHREAD_MUTEX_) 90#if defined(MHD_PTHREAD_MUTEX_)
@@ -90,7 +92,8 @@
90/** 92/**
91 * Define static mutex and statically initialise it. 93 * Define static mutex and statically initialise it.
92 */ 94 */
93# define MHD_MUTEX_STATIC_DEFN_INIT_(m) static MHD_mutex_ m = PTHREAD_MUTEX_INITIALIZER 95# define MHD_MUTEX_STATIC_DEFN_INIT_(m) static MHD_mutex_ m = \
96 PTHREAD_MUTEX_INITIALIZER
94# endif /* PTHREAD_MUTEX_INITIALIZER */ 97# endif /* PTHREAD_MUTEX_INITIALIZER */
95#endif 98#endif
96 99
@@ -100,14 +103,14 @@
100 * @param pmutex pointer to mutex 103 * @param pmutex pointer to mutex
101 * @return nonzero on success, zero otherwise 104 * @return nonzero on success, zero otherwise
102 */ 105 */
103#define MHD_mutex_destroy_(pmutex) (!(pthread_mutex_destroy((pmutex)))) 106#define MHD_mutex_destroy_(pmutex) (! (pthread_mutex_destroy ((pmutex))))
104#elif defined(MHD_W32_MUTEX_) 107#elif defined(MHD_W32_MUTEX_)
105/** 108/**
106 * Destroy previously initialised mutex. 109 * Destroy previously initialised mutex.
107 * @param pmutex pointer to mutex 110 * @param pmutex pointer to mutex
108 * @return Always nonzero 111 * @return Always nonzero
109 */ 112 */
110#define MHD_mutex_destroy_(pmutex) (DeleteCriticalSection((pmutex)), !0) 113#define MHD_mutex_destroy_(pmutex) (DeleteCriticalSection ((pmutex)), ! 0)
111#endif 114#endif
112 115
113/** 116/**
@@ -116,9 +119,9 @@
116 * @param pmutex pointer to mutex 119 * @param pmutex pointer to mutex
117 */ 120 */
118#define MHD_mutex_destroy_chk_(pmutex) do { \ 121#define MHD_mutex_destroy_chk_(pmutex) do { \
119 if (!MHD_mutex_destroy_(pmutex)) \ 122 if (! MHD_mutex_destroy_ (pmutex)) \
120 MHD_PANIC(_("Failed to destroy mutex.\n")); \ 123 MHD_PANIC (_ ("Failed to destroy mutex.\n")); \
121 } while(0) 124} while (0)
122 125
123 126
124#if defined(MHD_PTHREAD_MUTEX_) 127#if defined(MHD_PTHREAD_MUTEX_)
@@ -129,7 +132,7 @@
129 * @param pmutex pointer to mutex 132 * @param pmutex pointer to mutex
130 * @return nonzero on success, zero otherwise 133 * @return nonzero on success, zero otherwise
131 */ 134 */
132#define MHD_mutex_lock_(pmutex) (!(pthread_mutex_lock((pmutex)))) 135#define MHD_mutex_lock_(pmutex) (! (pthread_mutex_lock ((pmutex))))
133#elif defined(MHD_W32_MUTEX_) 136#elif defined(MHD_W32_MUTEX_)
134/** 137/**
135 * Acquire lock on previously initialised mutex. 138 * Acquire lock on previously initialised mutex.
@@ -138,7 +141,7 @@
138 * @param pmutex pointer to mutex 141 * @param pmutex pointer to mutex
139 * @return Always nonzero 142 * @return Always nonzero
140 */ 143 */
141#define MHD_mutex_lock_(pmutex) (EnterCriticalSection((pmutex)), !0) 144#define MHD_mutex_lock_(pmutex) (EnterCriticalSection ((pmutex)), ! 0)
142#endif 145#endif
143 146
144/** 147/**
@@ -149,9 +152,9 @@
149 * @param pmutex pointer to mutex 152 * @param pmutex pointer to mutex
150 */ 153 */
151#define MHD_mutex_lock_chk_(pmutex) do { \ 154#define MHD_mutex_lock_chk_(pmutex) do { \
152 if (!MHD_mutex_lock_(pmutex)) \ 155 if (! MHD_mutex_lock_ (pmutex)) \
153 MHD_PANIC(_("Failed to lock mutex.\n")); \ 156 MHD_PANIC (_ ("Failed to lock mutex.\n")); \
154 } while(0) 157} while (0)
155 158
156#if defined(MHD_PTHREAD_MUTEX_) 159#if defined(MHD_PTHREAD_MUTEX_)
157/** 160/**
@@ -159,14 +162,14 @@
159 * @param pmutex pointer to mutex 162 * @param pmutex pointer to mutex
160 * @return nonzero on success, zero otherwise 163 * @return nonzero on success, zero otherwise
161 */ 164 */
162#define MHD_mutex_unlock_(pmutex) (!(pthread_mutex_unlock((pmutex)))) 165#define MHD_mutex_unlock_(pmutex) (! (pthread_mutex_unlock ((pmutex))))
163#elif defined(MHD_W32_MUTEX_) 166#elif defined(MHD_W32_MUTEX_)
164/** 167/**
165 * Unlock previously initialised and locked mutex. 168 * Unlock previously initialised and locked mutex.
166 * @param pmutex pointer to mutex 169 * @param pmutex pointer to mutex
167 * @return Always nonzero 170 * @return Always nonzero
168 */ 171 */
169#define MHD_mutex_unlock_(pmutex) (LeaveCriticalSection((pmutex)), !0) 172#define MHD_mutex_unlock_(pmutex) (LeaveCriticalSection ((pmutex)), ! 0)
170#endif 173#endif
171 174
172/** 175/**
@@ -175,9 +178,9 @@
175 * @param pmutex pointer to mutex 178 * @param pmutex pointer to mutex
176 */ 179 */
177#define MHD_mutex_unlock_chk_(pmutex) do { \ 180#define MHD_mutex_unlock_chk_(pmutex) do { \
178 if (!MHD_mutex_unlock_(pmutex)) \ 181 if (! MHD_mutex_unlock_ (pmutex)) \
179 MHD_PANIC(_("Failed to unlock mutex.\n")); \ 182 MHD_PANIC (_ ("Failed to unlock mutex.\n")); \
180 } while(0) 183} while (0)
181 184
182 185
183#endif /* ! MHD_LOCKS_H */ 186#endif /* ! MHD_LOCKS_H */
diff --git a/src/lib/mhd_mono_clock.c b/src/lib/mhd_mono_clock.c
index 97dbfb9f..eee911fb 100644
--- a/src/lib/mhd_mono_clock.c
+++ b/src/lib/mhd_mono_clock.c
@@ -76,7 +76,8 @@ static clockid_t mono_clock_id = _MHD_UNWANTED_CLOCK;
76#endif /* HAVE_CLOCK_GETTIME */ 76#endif /* HAVE_CLOCK_GETTIME */
77 77
78/* sync clocks; reduce chance of value wrap */ 78/* sync clocks; reduce chance of value wrap */
79#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_GET_TIME) || defined(HAVE_GETHRTIME) 79#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_GET_TIME) || \
80 defined(HAVE_GETHRTIME)
80static time_t mono_clock_start; 81static time_t mono_clock_start;
81#endif /* HAVE_CLOCK_GETTIME || HAVE_CLOCK_GET_TIME || HAVE_GETHRTIME */ 82#endif /* HAVE_CLOCK_GETTIME || HAVE_CLOCK_GET_TIME || HAVE_GETHRTIME */
82static time_t sys_clock_start; 83static time_t sys_clock_start;
@@ -124,9 +125,9 @@ enum _MHD_mono_clock_source
124 */ 125 */
125 _MHD_CLOCK_GETTICKCOUNT64, 126 _MHD_CLOCK_GETTICKCOUNT64,
126 127
127 /** 128 /**
128 * QueryPerformanceCounter() / QueryPerformanceFrequency() 129 * QueryPerformanceCounter() / QueryPerformanceFrequency()
129 */ 130 */
130 _MHD_CLOCK_PERFCOUNTER 131 _MHD_CLOCK_PERFCOUNTER
131}; 132};
132 133
@@ -153,8 +154,8 @@ MHD_monotonic_sec_counter_init (void)
153 /* just a little syntactic trick to get the 154 /* just a little syntactic trick to get the
154 various following ifdef's to work out nicely */ 155 various following ifdef's to work out nicely */
155 if (0) 156 if (0)
156 { 157 {
157 } 158 }
158 else 159 else
159#ifdef HAVE_CLOCK_GETTIME 160#ifdef HAVE_CLOCK_GETTIME
160#ifdef CLOCK_MONOTONIC_COARSE 161#ifdef CLOCK_MONOTONIC_COARSE
@@ -163,11 +164,11 @@ MHD_monotonic_sec_counter_init (void)
163 /* but preferred since it's fast */ 164 /* but preferred since it's fast */
164 if (0 == clock_gettime (CLOCK_MONOTONIC_COARSE, 165 if (0 == clock_gettime (CLOCK_MONOTONIC_COARSE,
165 &ts)) 166 &ts))
166 { 167 {
167 mono_clock_id = CLOCK_MONOTONIC_COARSE; 168 mono_clock_id = CLOCK_MONOTONIC_COARSE;
168 mono_clock_start = ts.tv_sec; 169 mono_clock_start = ts.tv_sec;
169 mono_clock_source = _MHD_CLOCK_GETTIME; 170 mono_clock_source = _MHD_CLOCK_GETTIME;
170 } 171 }
171 else 172 else
172#endif /* CLOCK_MONOTONIC_COARSE */ 173#endif /* CLOCK_MONOTONIC_COARSE */
173#ifdef CLOCK_MONOTONIC_FAST 174#ifdef CLOCK_MONOTONIC_FAST
@@ -175,11 +176,11 @@ MHD_monotonic_sec_counter_init (void)
175 /* Can be affected by frequency adjustment, but preferred since it's fast */ 176 /* Can be affected by frequency adjustment, but preferred since it's fast */
176 if (0 == clock_gettime (CLOCK_MONOTONIC_FAST, 177 if (0 == clock_gettime (CLOCK_MONOTONIC_FAST,
177 &ts)) 178 &ts))
178 { 179 {
179 mono_clock_id = CLOCK_MONOTONIC_FAST; 180 mono_clock_id = CLOCK_MONOTONIC_FAST;
180 mono_clock_start = ts.tv_sec; 181 mono_clock_start = ts.tv_sec;
181 mono_clock_source = _MHD_CLOCK_GETTIME; 182 mono_clock_source = _MHD_CLOCK_GETTIME;
182 } 183 }
183 else 184 else
184#endif /* CLOCK_MONOTONIC_COARSE */ 185#endif /* CLOCK_MONOTONIC_COARSE */
185#ifdef CLOCK_MONOTONIC_RAW 186#ifdef CLOCK_MONOTONIC_RAW
@@ -187,11 +188,11 @@ MHD_monotonic_sec_counter_init (void)
187 /* Not affected by frequency adjustment, but don't count time in suspend */ 188 /* Not affected by frequency adjustment, but don't count time in suspend */
188 if (0 == clock_gettime (CLOCK_MONOTONIC_RAW, 189 if (0 == clock_gettime (CLOCK_MONOTONIC_RAW,
189 &ts)) 190 &ts))
190 { 191 {
191 mono_clock_id = CLOCK_MONOTONIC_RAW; 192 mono_clock_id = CLOCK_MONOTONIC_RAW;
192 mono_clock_start = ts.tv_sec; 193 mono_clock_start = ts.tv_sec;
193 mono_clock_source = _MHD_CLOCK_GETTIME; 194 mono_clock_source = _MHD_CLOCK_GETTIME;
194 } 195 }
195 else 196 else
196#endif /* CLOCK_MONOTONIC_RAW */ 197#endif /* CLOCK_MONOTONIC_RAW */
197#ifdef CLOCK_BOOTTIME 198#ifdef CLOCK_BOOTTIME
@@ -200,11 +201,11 @@ MHD_monotonic_sec_counter_init (void)
200 /* but can be slower value-getting than other clocks */ 201 /* but can be slower value-getting than other clocks */
201 if (0 == clock_gettime (CLOCK_BOOTTIME, 202 if (0 == clock_gettime (CLOCK_BOOTTIME,
202 &ts)) 203 &ts))
203 { 204 {
204 mono_clock_id = CLOCK_BOOTTIME; 205 mono_clock_id = CLOCK_BOOTTIME;
205 mono_clock_start = ts.tv_sec; 206 mono_clock_start = ts.tv_sec;
206 mono_clock_source = _MHD_CLOCK_GETTIME; 207 mono_clock_source = _MHD_CLOCK_GETTIME;
207 } 208 }
208 else 209 else
209#endif /* CLOCK_BOOTTIME */ 210#endif /* CLOCK_BOOTTIME */
210#ifdef CLOCK_MONOTONIC 211#ifdef CLOCK_MONOTONIC
@@ -213,11 +214,11 @@ MHD_monotonic_sec_counter_init (void)
213 /* On Linux it's not truly monotonic as it doesn't count time in suspend */ 214 /* On Linux it's not truly monotonic as it doesn't count time in suspend */
214 if (0 == clock_gettime (CLOCK_MONOTONIC, 215 if (0 == clock_gettime (CLOCK_MONOTONIC,
215 &ts)) 216 &ts))
216 { 217 {
217 mono_clock_id = CLOCK_MONOTONIC; 218 mono_clock_id = CLOCK_MONOTONIC;
218 mono_clock_start = ts.tv_sec; 219 mono_clock_start = ts.tv_sec;
219 mono_clock_source = _MHD_CLOCK_GETTIME; 220 mono_clock_source = _MHD_CLOCK_GETTIME;
220 } 221 }
221 else 222 else
222#endif /* CLOCK_BOOTTIME */ 223#endif /* CLOCK_BOOTTIME */
223#endif /* HAVE_CLOCK_GETTIME */ 224#endif /* HAVE_CLOCK_GETTIME */
@@ -225,15 +226,15 @@ MHD_monotonic_sec_counter_init (void)
225 /* Darwin-specific monotonic clock */ 226 /* Darwin-specific monotonic clock */
226 /* Should be monotonic as clock_set_time function always unconditionally */ 227 /* Should be monotonic as clock_set_time function always unconditionally */
227 /* failed on latest kernels */ 228 /* failed on latest kernels */
228 if ( (KERN_SUCCESS == host_get_clock_service (mach_host_self(), 229 if ( (KERN_SUCCESS == host_get_clock_service (mach_host_self (),
229 SYSTEM_CLOCK, 230 SYSTEM_CLOCK,
230 &mono_clock_service)) && 231 &mono_clock_service)) &&
231 (KERN_SUCCESS == clock_get_time (mono_clock_service, 232 (KERN_SUCCESS == clock_get_time (mono_clock_service,
232 &cur_time)) ) 233 &cur_time)) )
233 { 234 {
234 mono_clock_start = cur_time.tv_sec; 235 mono_clock_start = cur_time.tv_sec;
235 mono_clock_source = _MHD_CLOCK_GET_TIME; 236 mono_clock_source = _MHD_CLOCK_GET_TIME;
236 } 237 }
237 else 238 else
238#endif /* HAVE_CLOCK_GET_TIME */ 239#endif /* HAVE_CLOCK_GET_TIME */
239#ifdef _WIN32 240#ifdef _WIN32
@@ -241,25 +242,25 @@ MHD_monotonic_sec_counter_init (void)
241 /* W32 Vista or later specific monotonic clock */ 242 /* W32 Vista or later specific monotonic clock */
242 /* Available since Vista, ~15ms accuracy */ 243 /* Available since Vista, ~15ms accuracy */
243 if (1) 244 if (1)
244 { 245 {
245 tick_start = GetTickCount64 (); 246 tick_start = GetTickCount64 ();
246 mono_clock_source = _MHD_CLOCK_GETTICKCOUNT64; 247 mono_clock_source = _MHD_CLOCK_GETTICKCOUNT64;
247 } 248 }
248 else 249 else
249#else /* _WIN32_WINNT < 0x0600 */ 250#else /* _WIN32_WINNT < 0x0600 */
250 /* W32 specific monotonic clock */ 251 /* W32 specific monotonic clock */
251 /* Available on Windows 2000 and later */ 252 /* Available on Windows 2000 and later */
252 if (1) 253 if (1)
253 { 254 {
254 LARGE_INTEGER freq; 255 LARGE_INTEGER freq;
255 LARGE_INTEGER perf_counter; 256 LARGE_INTEGER perf_counter;
256 257
257 QueryPerformanceFrequency (&freq); /* never fail on XP and later */ 258 QueryPerformanceFrequency (&freq); /* never fail on XP and later */
258 QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */ 259 QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */
259 perf_freq = freq.QuadPart; 260 perf_freq = freq.QuadPart;
260 perf_start = perf_counter.QuadPart; 261 perf_start = perf_counter.QuadPart;
261 mono_clock_source = _MHD_CLOCK_PERFCOUNTER; 262 mono_clock_source = _MHD_CLOCK_PERFCOUNTER;
262 } 263 }
263 else 264 else
264#endif /* _WIN32_WINNT < 0x0600 */ 265#endif /* _WIN32_WINNT < 0x0600 */
265#endif /* _WIN32 */ 266#endif /* _WIN32 */
@@ -269,11 +270,11 @@ MHD_monotonic_sec_counter_init (void)
269 /* Not preferred due to be potentially resource-hungry */ 270 /* Not preferred due to be potentially resource-hungry */
270 if (0 == clock_gettime (CLOCK_HIGHRES, 271 if (0 == clock_gettime (CLOCK_HIGHRES,
271 &ts)) 272 &ts))
272 { 273 {
273 mono_clock_id = CLOCK_HIGHRES; 274 mono_clock_id = CLOCK_HIGHRES;
274 mono_clock_start = ts.tv_sec; 275 mono_clock_start = ts.tv_sec;
275 mono_clock_source = _MHD_CLOCK_GETTIME; 276 mono_clock_source = _MHD_CLOCK_GETTIME;
276 } 277 }
277 else 278 else
278#endif /* CLOCK_HIGHRES */ 279#endif /* CLOCK_HIGHRES */
279#endif /* HAVE_CLOCK_GETTIME */ 280#endif /* HAVE_CLOCK_GETTIME */
@@ -281,26 +282,26 @@ MHD_monotonic_sec_counter_init (void)
281 /* HP-UX and Solaris monotonic clock */ 282 /* HP-UX and Solaris monotonic clock */
282 /* Not preferred due to be potentially resource-hungry */ 283 /* Not preferred due to be potentially resource-hungry */
283 if (1) 284 if (1)
284 { 285 {
285 hrtime_start = gethrtime (); 286 hrtime_start = gethrtime ();
286 mono_clock_source = _MHD_CLOCK_GETHRTIME; 287 mono_clock_source = _MHD_CLOCK_GETHRTIME;
287 } 288 }
288 else 289 else
289#endif /* HAVE_GETHRTIME */ 290#endif /* HAVE_GETHRTIME */
290 { 291 {
291 /* no suitable clock source was found */ 292 /* no suitable clock source was found */
292 mono_clock_source = _MHD_CLOCK_NO_SOURCE; 293 mono_clock_source = _MHD_CLOCK_NO_SOURCE;
293 } 294 }
294 295
295#ifdef HAVE_CLOCK_GET_TIME 296#ifdef HAVE_CLOCK_GET_TIME
296 if ( (_MHD_CLOCK_GET_TIME != mono_clock_source) && 297 if ( (_MHD_CLOCK_GET_TIME != mono_clock_source) &&
297 (_MHD_INVALID_CLOCK_SERV != mono_clock_service) ) 298 (_MHD_INVALID_CLOCK_SERV != mono_clock_service) )
298 { 299 {
299 /* clock service was initialised but clock_get_time failed */ 300 /* clock service was initialised but clock_get_time failed */
300 mach_port_deallocate (mach_task_self(), 301 mach_port_deallocate (mach_task_self (),
301 mono_clock_service); 302 mono_clock_service);
302 mono_clock_service = _MHD_INVALID_CLOCK_SERV; 303 mono_clock_service = _MHD_INVALID_CLOCK_SERV;
303 } 304 }
304#else 305#else
305 (void) mono_clock_source; /* avoid compiler warning */ 306 (void) mono_clock_source; /* avoid compiler warning */
306#endif /* HAVE_CLOCK_GET_TIME */ 307#endif /* HAVE_CLOCK_GET_TIME */
@@ -317,11 +318,11 @@ MHD_monotonic_sec_counter_finish (void)
317{ 318{
318#ifdef HAVE_CLOCK_GET_TIME 319#ifdef HAVE_CLOCK_GET_TIME
319 if (_MHD_INVALID_CLOCK_SERV != mono_clock_service) 320 if (_MHD_INVALID_CLOCK_SERV != mono_clock_service)
320 { 321 {
321 mach_port_deallocate (mach_task_self(), 322 mach_port_deallocate (mach_task_self (),
322 mono_clock_service); 323 mono_clock_service);
323 mono_clock_service = _MHD_INVALID_CLOCK_SERV; 324 mono_clock_service = _MHD_INVALID_CLOCK_SERV;
324 } 325 }
325#endif /* HAVE_CLOCK_GET_TIME */ 326#endif /* HAVE_CLOCK_GET_TIME */
326} 327}
327 328
@@ -340,37 +341,38 @@ MHD_monotonic_sec_counter (void)
340 struct timespec ts; 341 struct timespec ts;
341 342
342 if ( (_MHD_UNWANTED_CLOCK != mono_clock_id) && 343 if ( (_MHD_UNWANTED_CLOCK != mono_clock_id) &&
343 (0 == clock_gettime (mono_clock_id , 344 (0 == clock_gettime (mono_clock_id,
344 &ts)) ) 345 &ts)) )
345 return ts.tv_sec - mono_clock_start; 346 return ts.tv_sec - mono_clock_start;
346#endif /* HAVE_CLOCK_GETTIME */ 347#endif /* HAVE_CLOCK_GETTIME */
347#ifdef HAVE_CLOCK_GET_TIME 348#ifdef HAVE_CLOCK_GET_TIME
348 if (_MHD_INVALID_CLOCK_SERV != mono_clock_service) 349 if (_MHD_INVALID_CLOCK_SERV != mono_clock_service)
349 { 350 {
350 mach_timespec_t cur_time; 351 mach_timespec_t cur_time;
351 352
352 if (KERN_SUCCESS == clock_get_time(mono_clock_service, 353 if (KERN_SUCCESS == clock_get_time (mono_clock_service,
353 &cur_time)) 354 &cur_time))
354 return cur_time.tv_sec - mono_clock_start; 355 return cur_time.tv_sec - mono_clock_start;
355 } 356 }
356#endif /* HAVE_CLOCK_GET_TIME */ 357#endif /* HAVE_CLOCK_GET_TIME */
357#if defined(_WIN32) 358#if defined(_WIN32)
358#if _WIN32_WINNT >= 0x0600 359#if _WIN32_WINNT >= 0x0600
359 if (1) 360 if (1)
360 return (time_t)(((uint64_t)(GetTickCount64() - tick_start)) / 1000); 361 return (time_t) (((uint64_t) (GetTickCount64 () - tick_start)) / 1000);
361#else /* _WIN32_WINNT < 0x0600 */ 362#else /* _WIN32_WINNT < 0x0600 */
362 if (0 != perf_freq) 363 if (0 != perf_freq)
363 { 364 {
364 LARGE_INTEGER perf_counter; 365 LARGE_INTEGER perf_counter;
365 366
366 QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */ 367 QueryPerformanceCounter (&perf_counter); /* never fail on XP and later */
367 return (time_t)(((uint64_t)(perf_counter.QuadPart - perf_start)) / perf_freq); 368 return (time_t) (((uint64_t) (perf_counter.QuadPart - perf_start))
368 } 369 / perf_freq);
370 }
369#endif /* _WIN32_WINNT < 0x0600 */ 371#endif /* _WIN32_WINNT < 0x0600 */
370#endif /* _WIN32 */ 372#endif /* _WIN32 */
371#ifdef HAVE_GETHRTIME 373#ifdef HAVE_GETHRTIME
372 if (1) 374 if (1)
373 return (time_t)(((uint64_t) (gethrtime () - hrtime_start)) / 1000000000); 375 return (time_t) (((uint64_t) (gethrtime () - hrtime_start)) / 1000000000);
374#endif /* HAVE_GETHRTIME */ 376#endif /* HAVE_GETHRTIME */
375 377
376 return time (NULL) - sys_clock_start; 378 return time (NULL) - sys_clock_start;
diff --git a/src/lib/mhd_mono_clock.h b/src/lib/mhd_mono_clock.h
index f4722af2..92485e00 100644
--- a/src/lib/mhd_mono_clock.h
+++ b/src/lib/mhd_mono_clock.h
@@ -37,14 +37,14 @@
37 * Initialise monotonic seconds counter. 37 * Initialise monotonic seconds counter.
38 */ 38 */
39void 39void
40MHD_monotonic_sec_counter_init(void); 40MHD_monotonic_sec_counter_init (void);
41 41
42 42
43/** 43/**
44 * Deinitialise monotonic seconds counter by freeing any allocated resources 44 * Deinitialise monotonic seconds counter by freeing any allocated resources
45 */ 45 */
46void 46void
47MHD_monotonic_sec_counter_finish(void); 47MHD_monotonic_sec_counter_finish (void);
48 48
49 49
50/** 50/**
@@ -55,6 +55,6 @@ MHD_monotonic_sec_counter_finish(void);
55 * @return number of seconds from some fixed moment 55 * @return number of seconds from some fixed moment
56 */ 56 */
57time_t 57time_t
58MHD_monotonic_sec_counter(void); 58MHD_monotonic_sec_counter (void);
59 59
60#endif /* MHD_MONO_CLOCK_H */ 60#endif /* MHD_MONO_CLOCK_H */
diff --git a/src/lib/mhd_sockets.c b/src/lib/mhd_sockets.c
index 356d288f..248b9a68 100644
--- a/src/lib/mhd_sockets.c
+++ b/src/lib/mhd_sockets.c
@@ -37,10 +37,10 @@
37 * @param err the WinSock error code. 37 * @param err the WinSock error code.
38 * @return pointer to string description of specified WinSock error. 38 * @return pointer to string description of specified WinSock error.
39 */ 39 */
40const char* MHD_W32_strerror_winsock_(int err) 40const char*MHD_W32_strerror_winsock_ (int err)
41{ 41{
42 switch (err) 42 switch (err)
43 { 43 {
44 case 0: 44 case 0:
45 return "No error"; 45 return "No error";
46 case WSA_INVALID_HANDLE: 46 case WSA_INVALID_HANDLE:
@@ -233,7 +233,7 @@ const char* MHD_W32_strerror_winsock_(int err)
233 return "Invalid QoS shaping rate object"; 233 return "Invalid QoS shaping rate object";
234 case WSA_QOS_RESERVED_PETYPE: 234 case WSA_QOS_RESERVED_PETYPE:
235 return "Reserved policy QoS element type"; 235 return "Reserved policy QoS element type";
236 } 236 }
237 return "Unknown winsock error"; 237 return "Unknown winsock error";
238} 238}
239 239
@@ -246,113 +246,114 @@ const char* MHD_W32_strerror_winsock_(int err)
246 * @return non-zero if succeeded, zero otherwise 246 * @return non-zero if succeeded, zero otherwise
247 */ 247 */
248int 248int
249MHD_W32_socket_pair_(SOCKET sockets_pair[2], int non_blk) 249MHD_W32_socket_pair_ (SOCKET sockets_pair[2], int non_blk)
250{ 250{
251 int i; 251 int i;
252 252
253 if (! sockets_pair) 253 if (! sockets_pair)
254 { 254 {
255 WSASetLastError (WSAEFAULT); 255 WSASetLastError (WSAEFAULT);
256 return 0; 256 return 0;
257 } 257 }
258 258
259#define PAIRMAXTRYIES 800 259#define PAIRMAXTRYIES 800
260 for (i = 0; i < PAIRMAXTRYIES; i++) 260 for (i = 0; i < PAIRMAXTRYIES; i++)
261 {
262 struct sockaddr_in listen_addr;
263 SOCKET listen_s;
264 static const int c_addinlen = sizeof(struct sockaddr_in); /* help compiler to optimize */
265 int addr_len = c_addinlen;
266 unsigned long on_val = 1;
267 unsigned long off_val = 0;
268
269 listen_s = socket (AF_INET,
270 SOCK_STREAM,
271 IPPROTO_TCP);
272 if (INVALID_SOCKET == listen_s)
273 break; /* can't create even single socket */
274
275 listen_addr.sin_family = AF_INET;
276 listen_addr.sin_port = 0; /* same as htons(0) */
277 listen_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
278 if ( ((0 == bind (listen_s,
279 (struct sockaddr*) &listen_addr,
280 c_addinlen)) &&
281 (0 == listen (listen_s,
282 1) ) &&
283 (0 == getsockname (listen_s,
284 (struct sockaddr*) &listen_addr,
285 &addr_len))) )
261 { 286 {
262 struct sockaddr_in listen_addr; 287 SOCKET client_s = socket (AF_INET,
263 SOCKET listen_s; 288 SOCK_STREAM,
264 static const int c_addinlen = sizeof(struct sockaddr_in); /* help compiler to optimize */ 289 IPPROTO_TCP);
265 int addr_len = c_addinlen; 290 struct sockaddr_in accepted_from_addr;
266 unsigned long on_val = 1; 291 struct sockaddr_in client_addr;
267 unsigned long off_val = 0; 292 SOCKET server_s;
268 293
269 listen_s = socket (AF_INET, 294 if (INVALID_SOCKET == client_s)
270 SOCK_STREAM, 295 {
271 IPPROTO_TCP); 296 /* try again */
272 if (INVALID_SOCKET == listen_s) 297 closesocket (listen_s);
273 break; /* can't create even single socket */ 298 continue;
274 299 }
275 listen_addr.sin_family = AF_INET; 300
276 listen_addr.sin_port = 0; /* same as htons(0) */ 301 if ( (0 != ioctlsocket (client_s,
277 listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 302 FIONBIO,
278 if ( (0 == bind (listen_s, 303 &on_val)) ||
279 (struct sockaddr*) &listen_addr, 304 ( (0 != connect (client_s,
280 c_addinlen) && 305 (struct sockaddr*) &listen_addr,
281 (0 == listen (listen_s, 306 c_addinlen)) &&
282 1) ) && 307 (WSAGetLastError () != WSAEWOULDBLOCK)) )
283 (0 == getsockname (listen_s, 308 {
284 (struct sockaddr*) &listen_addr, 309 /* try again */
285 &addr_len))) ) 310 closesocket (listen_s);
286 { 311 closesocket (client_s);
287 SOCKET client_s = socket(AF_INET, 312 continue;
288 SOCK_STREAM, 313 }
289 IPPROTO_TCP); 314
290 struct sockaddr_in accepted_from_addr; 315 addr_len = c_addinlen;
291 struct sockaddr_in client_addr; 316 server_s = accept (listen_s,
292 SOCKET server_s; 317 (struct sockaddr*) &accepted_from_addr,
293 318 &addr_len);
294 if (INVALID_SOCKET == client_s) 319 if (INVALID_SOCKET == server_s)
295 { 320 {
296 /* try again */ 321 /* try again */
297 closesocket (listen_s); 322 closesocket (listen_s);
298 continue; 323 closesocket (client_s);
299 } 324 continue;
300 325 }
301 if ( (0 != ioctlsocket (client_s, 326
302 FIONBIO, 327 addr_len = c_addinlen;
303 &on_val)) || 328 if ( (0 == getsockname (client_s,
304 ( (0 != connect (client_s, 329 (struct sockaddr*) &client_addr,
305 (struct sockaddr*) &listen_addr, 330 &addr_len)) &&
306 c_addinlen)) && 331 (accepted_from_addr.sin_family == client_addr.sin_family) &&
307 (WSAGetLastError() != WSAEWOULDBLOCK)) ) 332 (accepted_from_addr.sin_port == client_addr.sin_port) &&
308 { 333 (accepted_from_addr.sin_addr.s_addr ==
309 /* try again */ 334 client_addr.sin_addr.s_addr) &&
310 closesocket (listen_s); 335 ( (0 != non_blk) ?
311 closesocket (client_s); 336 (0 == ioctlsocket (server_s,
312 continue; 337 FIONBIO,
313 } 338 &on_val)) :
314 339 (0 == ioctlsocket (client_s,
315 addr_len = c_addinlen; 340 FIONBIO,
316 server_s = accept (listen_s, 341 &off_val)) ) )
317 (struct sockaddr*) &accepted_from_addr, 342 {
318 &addr_len); 343 closesocket (listen_s);
319 if (INVALID_SOCKET == server_s) 344 sockets_pair[0] = server_s;
320 { 345 sockets_pair[1] = client_s;
321 /* try again */ 346 return ! 0;
322 closesocket (listen_s); 347 }
323 closesocket (client_s); 348 closesocket (server_s);
324 continue; 349 closesocket (client_s);
325 }
326
327 addr_len = c_addinlen;
328 if ( (0 == getsockname (client_s,
329 (struct sockaddr*) &client_addr,
330 &addr_len)) &&
331 (accepted_from_addr.sin_family == client_addr.sin_family) &&
332 (accepted_from_addr.sin_port == client_addr.sin_port) &&
333 (accepted_from_addr.sin_addr.s_addr == client_addr.sin_addr.s_addr) &&
334 ( (0 != non_blk) ?
335 (0 == ioctlsocket(server_s,
336 FIONBIO,
337 &on_val)) :
338 (0 == ioctlsocket(client_s,
339 FIONBIO,
340 &off_val)) ) )
341 {
342 closesocket (listen_s);
343 sockets_pair[0] = server_s;
344 sockets_pair[1] = client_s;
345 return !0;
346 }
347 closesocket (server_s);
348 closesocket (client_s);
349 }
350 closesocket(listen_s);
351 } 350 }
351 closesocket (listen_s);
352 }
352 353
353 sockets_pair[0] = INVALID_SOCKET; 354 sockets_pair[0] = INVALID_SOCKET;
354 sockets_pair[1] = INVALID_SOCKET; 355 sockets_pair[1] = INVALID_SOCKET;
355 WSASetLastError(WSAECONNREFUSED); 356 WSASetLastError (WSAECONNREFUSED);
356 357
357 return 0; 358 return 0;
358} 359}
@@ -383,9 +384,9 @@ MHD_add_to_fd_set_ (MHD_socket fd,
383 set, 384 set,
384 fd_setsize)) 385 fd_setsize))
385 return 0; 386 return 0;
386 MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd, 387 MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_ (fd,
387 set, 388 set,
388 fd_setsize); 389 fd_setsize);
389 if ( (NULL != max_fd) && 390 if ( (NULL != max_fd) &&
390 ( (fd > *max_fd) || 391 ( (fd > *max_fd) ||
391 (MHD_INVALID_SOCKET == *max_fd) ) ) 392 (MHD_INVALID_SOCKET == *max_fd) ) )
@@ -424,7 +425,7 @@ MHD_socket_nonblocking_ (MHD_socket sock)
424 &flags)) 425 &flags))
425 return 0; 426 return 0;
426#endif /* MHD_WINSOCK_SOCKETS */ 427#endif /* MHD_WINSOCK_SOCKETS */
427 return !0; 428 return ! 0;
428} 429}
429 430
430 431
@@ -452,12 +453,12 @@ MHD_socket_noninheritable_ (MHD_socket sock)
452 flags | FD_CLOEXEC)) ) 453 flags | FD_CLOEXEC)) )
453 return 0; 454 return 0;
454#elif defined(MHD_WINSOCK_SOCKETS) 455#elif defined(MHD_WINSOCK_SOCKETS)
455 if (! SetHandleInformation ((HANDLE)sock, 456 if (! SetHandleInformation ((HANDLE) sock,
456 HANDLE_FLAG_INHERIT, 457 HANDLE_FLAG_INHERIT,
457 0)) 458 0))
458 return 0; 459 return 0;
459#endif /* MHD_WINSOCK_SOCKETS */ 460#endif /* MHD_WINSOCK_SOCKETS */
460 return !0; 461 return ! 0;
461} 462}
462 463
463 464
@@ -477,7 +478,7 @@ MHD_socket_create_listen_ (int pf)
477 fd = socket (pf, 478 fd = socket (pf,
478 SOCK_STREAM | SOCK_CLOEXEC, 479 SOCK_STREAM | SOCK_CLOEXEC,
479 0); 480 0);
480 cloexec_set = !0; 481 cloexec_set = ! 0;
481#elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT) 482#elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT)
482 fd = WSASocketW (pf, 483 fd = WSASocketW (pf,
483 SOCK_STREAM, 484 SOCK_STREAM,
@@ -485,27 +486,27 @@ MHD_socket_create_listen_ (int pf)
485 NULL, 486 NULL,
486 0, 487 0,
487 WSA_FLAG_NO_HANDLE_INHERIT); 488 WSA_FLAG_NO_HANDLE_INHERIT);
488 cloexec_set = !0; 489 cloexec_set = ! 0;
489#else /* !SOCK_CLOEXEC */ 490#else /* !SOCK_CLOEXEC */
490 fd = MHD_INVALID_SOCKET; 491 fd = MHD_INVALID_SOCKET;
491#endif /* !SOCK_CLOEXEC */ 492#endif /* !SOCK_CLOEXEC */
492 if (MHD_INVALID_SOCKET == fd) 493 if (MHD_INVALID_SOCKET == fd)
493 { 494 {
494 fd = socket (pf, 495 fd = socket (pf,
495 SOCK_STREAM, 496 SOCK_STREAM,
496 0); 497 0);
497 cloexec_set = 0; 498 cloexec_set = 0;
498 } 499 }
499 if (MHD_INVALID_SOCKET == fd) 500 if (MHD_INVALID_SOCKET == fd)
500 return MHD_INVALID_SOCKET; 501 return MHD_INVALID_SOCKET;
501#ifdef MHD_socket_nosignal_ 502#ifdef MHD_socket_nosignal_
502 if(! MHD_socket_nosignal_(fd)) 503 if (! MHD_socket_nosignal_ (fd))
503 { 504 {
504 const int err = MHD_socket_get_error_ (); 505 const int err = MHD_socket_get_error_ ();
505 (void) MHD_socket_close_ (fd); 506 (void) MHD_socket_close_ (fd);
506 MHD_socket_fset_error_ (err); 507 MHD_socket_fset_error_ (err);
507 return MHD_INVALID_SOCKET; 508 return MHD_INVALID_SOCKET;
508 } 509 }
509#endif /* MHD_socket_nosignal_ */ 510#endif /* MHD_socket_nosignal_ */
510 if (! cloexec_set) 511 if (! cloexec_set)
511 (void) MHD_socket_noninheritable_ (fd); 512 (void) MHD_socket_noninheritable_ (fd);
diff --git a/src/lib/mhd_sockets.h b/src/lib/mhd_sockets.h
index 9be34144..ebe40275 100644
--- a/src/lib/mhd_sockets.h
+++ b/src/lib/mhd_sockets.h
@@ -36,8 +36,8 @@
36 36
37#include <errno.h> 37#include <errno.h>
38 38
39#if !defined(MHD_POSIX_SOCKETS) && !defined(MHD_WINSOCK_SOCKETS) 39#if ! defined(MHD_POSIX_SOCKETS) && ! defined(MHD_WINSOCK_SOCKETS)
40# if !defined(_WIN32) || defined(__CYGWIN__) 40# if ! defined(_WIN32) || defined(__CYGWIN__)
41# define MHD_POSIX_SOCKETS 1 41# define MHD_POSIX_SOCKETS 1
42# else /* defined(_WIN32) && !defined(__CYGWIN__) */ 42# else /* defined(_WIN32) && !defined(__CYGWIN__) */
43# define MHD_WINSOCK_SOCKETS 1 43# define MHD_WINSOCK_SOCKETS 1
@@ -92,7 +92,7 @@
92# include <sys/epoll.h> 92# include <sys/epoll.h>
93# endif 93# endif
94# ifdef HAVE_NETINET_TCP_H 94# ifdef HAVE_NETINET_TCP_H
95 /* for TCP_FASTOPEN and TCP_CORK */ 95/* for TCP_FASTOPEN and TCP_CORK */
96# include <netinet/tcp.h> 96# include <netinet/tcp.h>
97# endif 97# endif
98# ifdef HAVE_STRING_H 98# ifdef HAVE_STRING_H
@@ -111,10 +111,10 @@
111#endif 111#endif
112 112
113#include <stddef.h> 113#include <stddef.h>
114#if defined(_MSC_FULL_VER) && !defined (_SSIZE_T_DEFINED) 114#if defined(_MSC_FULL_VER) && ! defined (_SSIZE_T_DEFINED)
115# include <stdint.h> 115# include <stdint.h>
116# define _SSIZE_T_DEFINED 116# define _SSIZE_T_DEFINED
117 typedef intptr_t ssize_t; 117typedef intptr_t ssize_t;
118#endif /* !_SSIZE_T_DEFINED */ 118#endif /* !_SSIZE_T_DEFINED */
119 119
120#include "mhd_limits.h" 120#include "mhd_limits.h"
@@ -123,7 +123,7 @@
123# define _MHD_SYS_DEFAULT_FD_SETSIZE FD_SETSIZE 123# define _MHD_SYS_DEFAULT_FD_SETSIZE FD_SETSIZE
124#else /* ! _MHD_FD_SETSIZE_IS_DEFAULT */ 124#else /* ! _MHD_FD_SETSIZE_IS_DEFAULT */
125# include "sysfdsetsize.h" 125# include "sysfdsetsize.h"
126# define _MHD_SYS_DEFAULT_FD_SETSIZE get_system_fdsetsize_value() 126# define _MHD_SYS_DEFAULT_FD_SETSIZE get_system_fdsetsize_value ()
127#endif /* ! _MHD_FD_SETSIZE_IS_DEFAULT */ 127#endif /* ! _MHD_FD_SETSIZE_IS_DEFAULT */
128 128
129#ifndef MHD_PANIC 129#ifndef MHD_PANIC
@@ -131,8 +131,9 @@
131# include <stdlib.h> 131# include <stdlib.h>
132/* Simple implementation of MHD_PANIC, to be used outside lib */ 132/* Simple implementation of MHD_PANIC, to be used outside lib */
133# define MHD_PANIC(msg) do { fprintf (stderr, \ 133# define MHD_PANIC(msg) do { fprintf (stderr, \
134 "Abnormal termination at %d line in file %s: %s\n", \ 134 "Abnormal termination at %d line in file %s: %s\n", \
135 (int)__LINE__, __FILE__, msg); abort();} while(0) 135 (int) __LINE__, __FILE__, msg); abort (); \
136} while (0)
136#endif /* ! MHD_PANIC */ 137#endif /* ! MHD_PANIC */
137 138
138#ifndef MHD_SOCKET_DEFINED 139#ifndef MHD_SOCKET_DEFINED
@@ -140,10 +141,10 @@
140 * MHD_socket is type for socket FDs 141 * MHD_socket is type for socket FDs
141 */ 142 */
142# if defined(MHD_POSIX_SOCKETS) 143# if defined(MHD_POSIX_SOCKETS)
143 typedef int MHD_socket; 144typedef int MHD_socket;
144# define MHD_INVALID_SOCKET (-1) 145# define MHD_INVALID_SOCKET (-1)
145# elif defined(MHD_WINSOCK_SOCKETS) 146# elif defined(MHD_WINSOCK_SOCKETS)
146 typedef SOCKET MHD_socket; 147typedef SOCKET MHD_socket;
147# define MHD_INVALID_SOCKET (INVALID_SOCKET) 148# define MHD_INVALID_SOCKET (INVALID_SOCKET)
148# endif /* MHD_WINSOCK_SOCKETS */ 149# endif /* MHD_WINSOCK_SOCKETS */
149 150
@@ -168,17 +169,18 @@
168# define MAYBE_MSG_NOSIGNAL 0 169# define MAYBE_MSG_NOSIGNAL 0
169#endif /* ! MSG_NOSIGNAL */ 170#endif /* ! MSG_NOSIGNAL */
170 171
171#if !defined(SHUT_WR) && defined(SD_SEND) 172#if ! defined(SHUT_WR) && defined(SD_SEND)
172# define SHUT_WR SD_SEND 173# define SHUT_WR SD_SEND
173#endif 174#endif
174#if !defined(SHUT_RD) && defined(SD_RECEIVE) 175#if ! defined(SHUT_RD) && defined(SD_RECEIVE)
175# define SHUT_RD SD_RECEIVE 176# define SHUT_RD SD_RECEIVE
176#endif 177#endif
177#if !defined(SHUT_RDWR) && defined(SD_BOTH) 178#if ! defined(SHUT_RDWR) && defined(SD_BOTH)
178# define SHUT_RDWR SD_BOTH 179# define SHUT_RDWR SD_BOTH
179#endif 180#endif
180 181
181#if HAVE_ACCEPT4+0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || defined(SOCK_CLOEXEC)) 182#if HAVE_ACCEPT4 + 0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || \
183 defined(SOCK_CLOEXEC))
182# define USE_ACCEPT4 1 184# define USE_ACCEPT4 1
183#endif 185#endif
184 186
@@ -198,25 +200,25 @@
198 * MHD_SCKT_OPT_BOOL_ is type for bool parameters for setsockopt()/getsockopt() 200 * MHD_SCKT_OPT_BOOL_ is type for bool parameters for setsockopt()/getsockopt()
199 */ 201 */
200#ifdef MHD_POSIX_SOCKETS 202#ifdef MHD_POSIX_SOCKETS
201 typedef int MHD_SCKT_OPT_BOOL_; 203typedef int MHD_SCKT_OPT_BOOL_;
202#else /* MHD_WINSOCK_SOCKETS */ 204#else /* MHD_WINSOCK_SOCKETS */
203 typedef BOOL MHD_SCKT_OPT_BOOL_; 205typedef BOOL MHD_SCKT_OPT_BOOL_;
204#endif /* MHD_WINSOCK_SOCKETS */ 206#endif /* MHD_WINSOCK_SOCKETS */
205 207
206/** 208/**
207 * MHD_SCKT_SEND_SIZE_ is type used to specify size for send and recv 209 * MHD_SCKT_SEND_SIZE_ is type used to specify size for send and recv
208 * functions 210 * functions
209 */ 211 */
210#if !defined(MHD_WINSOCK_SOCKETS) 212#if ! defined(MHD_WINSOCK_SOCKETS)
211 typedef size_t MHD_SCKT_SEND_SIZE_; 213typedef size_t MHD_SCKT_SEND_SIZE_;
212#else 214#else
213 typedef int MHD_SCKT_SEND_SIZE_; 215typedef int MHD_SCKT_SEND_SIZE_;
214#endif 216#endif
215 217
216/** 218/**
217 * MHD_SCKT_SEND_MAX_SIZE_ is maximum send()/recv() size value. 219 * MHD_SCKT_SEND_MAX_SIZE_ is maximum send()/recv() size value.
218 */ 220 */
219#if !defined(MHD_WINSOCK_SOCKETS) 221#if ! defined(MHD_WINSOCK_SOCKETS)
220# define MHD_SCKT_SEND_MAX_SIZE_ SSIZE_MAX 222# define MHD_SCKT_SEND_MAX_SIZE_ SSIZE_MAX
221#else 223#else
222# define MHD_SCKT_SEND_MAX_SIZE_ INT_MAX 224# define MHD_SCKT_SEND_MAX_SIZE_ INT_MAX
@@ -232,10 +234,10 @@
232 * counted as success, only EBADF counts as an error!), 234 * counted as success, only EBADF counts as an error!),
233 * boolean false otherwise. 235 * boolean false otherwise.
234 */ 236 */
235#if !defined(MHD_WINSOCK_SOCKETS) 237#if ! defined(MHD_WINSOCK_SOCKETS)
236# define MHD_socket_close_(fd) ((0 == close((fd))) || (EBADF != errno)) 238# define MHD_socket_close_(fd) ((0 == close ((fd))) || (EBADF != errno))
237#else 239#else
238# define MHD_socket_close_(fd) (0 == closesocket((fd))) 240# define MHD_socket_close_(fd) (0 == closesocket ((fd)))
239#endif 241#endif
240 242
241/** 243/**
@@ -244,9 +246,9 @@
244 * @param fd socket to close 246 * @param fd socket to close
245 */ 247 */
246#define MHD_socket_close_chk_(fd) do { \ 248#define MHD_socket_close_chk_(fd) do { \
247 if (!MHD_socket_close_(fd)) \ 249 if (! MHD_socket_close_ (fd)) \
248 MHD_PANIC(_("Close socket failed.\n")); \ 250 MHD_PANIC (_ ("Close socket failed.\n")); \
249 } while(0) 251} while (0)
250 252
251 253
252/** 254/**
@@ -257,7 +259,8 @@
257 * @return ssize_t type value 259 * @return ssize_t type value
258 */ 260 */
259#define MHD_send_(s,b,l) \ 261#define MHD_send_(s,b,l) \
260 ((ssize_t)send((s),(const void*)(b),((MHD_SCKT_SEND_SIZE_)l), MAYBE_MSG_NOSIGNAL)) 262 ((ssize_t) send ((s),(const void*) (b),((MHD_SCKT_SEND_SIZE_) l), \
263 MAYBE_MSG_NOSIGNAL))
261 264
262 265
263/** 266/**
@@ -268,7 +271,7 @@
268 * @return ssize_t type value 271 * @return ssize_t type value
269 */ 272 */
270#define MHD_recv_(s,b,l) \ 273#define MHD_recv_(s,b,l) \
271 ((ssize_t)recv((s),(void*)(b),((MHD_SCKT_SEND_SIZE_)l), 0)) 274 ((ssize_t) recv ((s),(void*) (b),((MHD_SCKT_SEND_SIZE_) l), 0))
272 275
273 276
274/** 277/**
@@ -281,11 +284,18 @@
281 * boolean false otherwise. 284 * boolean false otherwise.
282 */ 285 */
283#if defined(MHD_POSIX_SOCKETS) 286#if defined(MHD_POSIX_SOCKETS)
284# define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ((fd) < ((MHD_socket)setsize)) 287# define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ((fd) < \
288 ((MHD_socket) \
289 setsize))
285#elif defined(MHD_WINSOCK_SOCKETS) 290#elif defined(MHD_WINSOCK_SOCKETS)
286# define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ( ((void*)(pset)==(void*)0) || \ 291# define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ( ((void*) (pset)== \
287 (((fd_set*)(pset))->fd_count < ((unsigned)setsize)) || \ 292 (void*) 0) || \
288 (FD_ISSET((fd),(pset))) ) 293 (((fd_set*) (pset)) \
294 ->fd_count < \
295 ((unsigned) \
296 setsize)) || \
297 (FD_ISSET ((fd), \
298 (pset))) )
289#endif 299#endif
290 300
291/** 301/**
@@ -296,7 +306,9 @@
296 * @return boolean true if FD can be added to fd_set, 306 * @return boolean true if FD can be added to fd_set,
297 * boolean false otherwise. 307 * boolean false otherwise.
298 */ 308 */
299#define MHD_SCKT_FD_FITS_FDSET_(fd,pset) MHD_SCKT_FD_FITS_FDSET_SETSIZE_((fd),(pset),FD_SETSIZE) 309#define MHD_SCKT_FD_FITS_FDSET_(fd,pset) MHD_SCKT_FD_FITS_FDSET_SETSIZE_ ((fd), \
310 (pset), \
311 FD_SETSIZE)
300 312
301/** 313/**
302 * Add FD to fd_set with specified FD_SETSIZE. 314 * Add FD to fd_set with specified FD_SETSIZE.
@@ -307,34 +319,35 @@
307 * system definition of FD_SET() is not used. 319 * system definition of FD_SET() is not used.
308 */ 320 */
309#if defined(MHD_POSIX_SOCKETS) 321#if defined(MHD_POSIX_SOCKETS)
310# define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) FD_SET((fd),(pset)) 322# define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) FD_SET ((fd), \
323 (pset))
311#elif defined(MHD_WINSOCK_SOCKETS) 324#elif defined(MHD_WINSOCK_SOCKETS)
312# define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) \ 325# define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) \
313 do { \ 326 do { \
314 u_int _i_ = 0; \ 327 u_int _i_ = 0; \
315 fd_set* const _s_ = (fd_set*)(pset); \ 328 fd_set*const _s_ = (fd_set*) (pset); \
316 while((_i_ < _s_->fd_count) && ((fd) != _s_->fd_array[_i_])) {++_i_;} \ 329 while ((_i_ < _s_->fd_count) && ((fd) != _s_->fd_array [_i_])) {++_i_;} \
317 if ((_i_ == _s_->fd_count)) {_s_->fd_array[_s_->fd_count++] = (fd);} \ 330 if ((_i_ == _s_->fd_count)) {_s_->fd_array [_s_->fd_count ++] = (fd);} \
318 } while(0) 331 } while (0)
319#endif 332#endif
320 333
321 /* MHD_SYS_select_ is wrapper macro for system select() function */ 334/* MHD_SYS_select_ is wrapper macro for system select() function */
322#if !defined(MHD_WINSOCK_SOCKETS) 335#if ! defined(MHD_WINSOCK_SOCKETS)
323# define MHD_SYS_select_(n,r,w,e,t) select((n),(r),(w),(e),(t)) 336# define MHD_SYS_select_(n,r,w,e,t) select ((n),(r),(w),(e),(t))
324#else 337#else
325# define MHD_SYS_select_(n,r,w,e,t) \ 338# define MHD_SYS_select_(n,r,w,e,t) \
326( ( (((void*)(r) == (void*)0) || ((fd_set*)(r))->fd_count == 0) && \ 339 ( ( (((void*) (r) == (void*) 0) || ((fd_set*) (r))->fd_count == 0) && \
327 (((void*)(w) == (void*)0) || ((fd_set*)(w))->fd_count == 0) && \ 340 (((void*) (w) == (void*) 0) || ((fd_set*) (w))->fd_count == 0) && \
328 (((void*)(e) == (void*)0) || ((fd_set*)(e))->fd_count == 0) ) ? \ 341 (((void*) (e) == (void*) 0) || ((fd_set*) (e))->fd_count == 0) ) ? \
329 ( ((void*)(t) == (void*)0) ? 0 : \ 342 ( ((void*) (t) == (void*) 0) ? 0 : \
330 (Sleep(((struct timeval*)(t))->tv_sec * 1000 + \ 343 (Sleep (((struct timeval*) (t))->tv_sec * 1000 \
331 ((struct timeval*)(t))->tv_usec / 1000), 0) ) : \ 344 + ((struct timeval*) (t))->tv_usec / 1000), 0) ) : \
332 (select((int)0,(r),(w),(e),(t))) ) 345 (select ((int) 0,(r),(w),(e),(t))) )
333#endif 346#endif
334 347
335#if defined(HAVE_POLL) 348#if defined(HAVE_POLL)
336/* MHD_sys_poll_ is wrapper macro for system poll() function */ 349/* MHD_sys_poll_ is wrapper macro for system poll() function */
337# if !defined(MHD_WINSOCK_SOCKETS) 350# if ! defined(MHD_WINSOCK_SOCKETS)
338# define MHD_sys_poll_ poll 351# define MHD_sys_poll_ poll
339# else /* MHD_WINSOCK_SOCKETS */ 352# else /* MHD_WINSOCK_SOCKETS */
340# define MHD_sys_poll_ WSAPoll 353# define MHD_sys_poll_ WSAPoll
@@ -363,16 +376,19 @@
363# elif defined(__linux__) 376# elif defined(__linux__)
364# define MHD_POLL_EVENTS_ERR_DISC POLLPRI 377# define MHD_POLL_EVENTS_ERR_DISC POLLPRI
365# else /* ! __linux__ */ 378# else /* ! __linux__ */
366# define MHD_POLL_EVENTS_ERR_DISC (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO) 379# define MHD_POLL_EVENTS_ERR_DISC (MHD_POLLPRI_OR_ZERO \
380 | MHD_POLLRDBAND_OR_ZERO)
367# endif /* ! __linux__ */ 381# endif /* ! __linux__ */
368/* MHD_POLL_REVENTS_ERR_DISC is 'revents' mask for errors and disconnect. 382/* MHD_POLL_REVENTS_ERR_DISC is 'revents' mask for errors and disconnect.
369 * Note: Out-of-band data is treated as error. */ 383 * Note: Out-of-band data is treated as error. */
370# define MHD_POLL_REVENTS_ERR_DISC \ 384# define MHD_POLL_REVENTS_ERR_DISC \
371 (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO | POLLERR | POLLHUP) 385 (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO \
386 | POLLERR | POLLHUP)
372/* MHD_POLL_REVENTS_ERRROR is 'revents' mask for errors. 387/* MHD_POLL_REVENTS_ERRROR is 'revents' mask for errors.
373 * Note: Out-of-band data is treated as error. */ 388 * Note: Out-of-band data is treated as error. */
374# define MHD_POLL_REVENTS_ERRROR \ 389# define MHD_POLL_REVENTS_ERRROR \
375 (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO | POLLERR) 390 (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO \
391 | POLLERR)
376#endif /* HAVE_POLL */ 392#endif /* HAVE_POLL */
377 393
378#define MHD_SCKT_MISSING_ERR_CODE_ 31450 394#define MHD_SCKT_MISSING_ERR_CODE_ 31450
@@ -506,30 +522,30 @@
506#if defined(MHD_POSIX_SOCKETS) 522#if defined(MHD_POSIX_SOCKETS)
507# define MHD_socket_get_error_() (errno) 523# define MHD_socket_get_error_() (errno)
508#elif defined(MHD_WINSOCK_SOCKETS) 524#elif defined(MHD_WINSOCK_SOCKETS)
509# define MHD_socket_get_error_() WSAGetLastError() 525# define MHD_socket_get_error_() WSAGetLastError ()
510#endif 526#endif
511 527
512#ifdef MHD_WINSOCK_SOCKETS 528#ifdef MHD_WINSOCK_SOCKETS
513 /* POSIX-W32 sockets compatibility functions */ 529/* POSIX-W32 sockets compatibility functions */
514 530
515/** 531/**
516 * Return pointer to string description of specified WinSock error 532 * Return pointer to string description of specified WinSock error
517 * @param err the WinSock error code. 533 * @param err the WinSock error code.
518 * @return pointer to string description of specified WinSock error. 534 * @return pointer to string description of specified WinSock error.
519 */ 535 */
520 const char* MHD_W32_strerror_winsock_(int err); 536const char*MHD_W32_strerror_winsock_ (int err);
521#endif /* MHD_WINSOCK_SOCKETS */ 537#endif /* MHD_WINSOCK_SOCKETS */
522 538
523/* MHD_socket_last_strerr_ is description string of specified socket error code */ 539/* MHD_socket_last_strerr_ is description string of specified socket error code */
524#if defined(MHD_POSIX_SOCKETS) 540#if defined(MHD_POSIX_SOCKETS)
525# define MHD_socket_strerr_(err) strerror((err)) 541# define MHD_socket_strerr_(err) strerror ((err))
526#elif defined(MHD_WINSOCK_SOCKETS) 542#elif defined(MHD_WINSOCK_SOCKETS)
527# define MHD_socket_strerr_(err) MHD_W32_strerror_winsock_((err)) 543# define MHD_socket_strerr_(err) MHD_W32_strerror_winsock_ ((err))
528#endif 544#endif
529 545
530/* MHD_socket_last_strerr_ is description string of last errno (non-W32) / 546/* MHD_socket_last_strerr_ is description string of last errno (non-W32) /
531 * description string of last socket error (W32) */ 547 * description string of last socket error (W32) */
532#define MHD_socket_last_strerr_() MHD_socket_strerr_(MHD_socket_get_error_()) 548#define MHD_socket_last_strerr_() MHD_socket_strerr_ (MHD_socket_get_error_ ())
533 549
534/** 550/**
535 * MHD_socket_fset_error_() set socket system native error code. 551 * MHD_socket_fset_error_() set socket system native error code.
@@ -537,7 +553,7 @@
537#if defined(MHD_POSIX_SOCKETS) 553#if defined(MHD_POSIX_SOCKETS)
538# define MHD_socket_fset_error_(err) (errno = (err)) 554# define MHD_socket_fset_error_(err) (errno = (err))
539#elif defined(MHD_WINSOCK_SOCKETS) 555#elif defined(MHD_WINSOCK_SOCKETS)
540# define MHD_socket_fset_error_(err) (WSASetLastError((err))) 556# define MHD_socket_fset_error_(err) (WSASetLastError ((err)))
541#endif 557#endif
542 558
543/** 559/**
@@ -549,7 +565,8 @@
549 * and error was not set. 565 * and error was not set.
550 */ 566 */
551#define MHD_socket_try_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ != (err)) ? \ 567#define MHD_socket_try_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ != (err)) ? \
552 (MHD_socket_fset_error_((err)), !0) : 0 ) 568 (MHD_socket_fset_error_ ((err)), ! 0) : \
569 0)
553 570
554/** 571/**
555 * MHD_socket_set_error_() set socket system native error code to 572 * MHD_socket_set_error_() set socket system native error code to
@@ -562,7 +579,8 @@
562 (errno = ENOSYS) : (errno = (err)) ) 579 (errno = ENOSYS) : (errno = (err)) )
563# elif defined(EOPNOTSUPP) 580# elif defined(EOPNOTSUPP)
564# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ 581# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
565 (errno = EOPNOTSUPP) : (errno = (err)) ) 582 (errno = EOPNOTSUPP) : (errno = \
583 (err)) )
566# elif defined (EFAULT) 584# elif defined (EFAULT)
567# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ 585# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
568 (errno = EFAULT) : (errno = (err)) ) 586 (errno = EFAULT) : (errno = (err)) )
@@ -570,13 +588,14 @@
570# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ 588# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
571 (errno = EINVAL) : (errno = (err)) ) 589 (errno = EINVAL) : (errno = (err)) )
572# else /* !EOPNOTSUPP && !EFAULT && !EINVAL */ 590# else /* !EOPNOTSUPP && !EFAULT && !EINVAL */
573# warning No suitable replacement for missing socket error code is found. Edit this file and add replacement code which is defined on system. 591# warning \
592 No suitable replacement for missing socket error code is found. Edit this file and add replacement code which is defined on system.
574# define MHD_socket_set_error_(err) (errno = (err)) 593# define MHD_socket_set_error_(err) (errno = (err))
575# endif /* !EOPNOTSUPP && !EFAULT && !EINVAL*/ 594# endif /* !EOPNOTSUPP && !EFAULT && !EINVAL*/
576#elif defined(MHD_WINSOCK_SOCKETS) 595#elif defined(MHD_WINSOCK_SOCKETS)
577# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ 596# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
578 (WSASetLastError((WSAEOPNOTSUPP))) : \ 597 (WSASetLastError ((WSAEOPNOTSUPP))) : \
579 (WSASetLastError((err))) ) 598 (WSASetLastError ((err))) )
580#endif 599#endif
581 600
582/** 601/**
@@ -600,7 +619,8 @@
600 * last socket error equals to MHD_SCKT_E*_ @a code; 619 * last socket error equals to MHD_SCKT_E*_ @a code;
601 * boolean false otherwise 620 * boolean false otherwise
602 */ 621 */
603#define MHD_SCKT_LAST_ERR_IS_(code) MHD_SCKT_ERR_IS_(MHD_socket_get_error_() ,(code)) 622#define MHD_SCKT_LAST_ERR_IS_(code) MHD_SCKT_ERR_IS_ (MHD_socket_get_error_ (), \
623 (code))
604 624
605/* Specific error code checks */ 625/* Specific error code checks */
606 626
@@ -610,7 +630,7 @@
610 * @return boolean true if @a err is equal to sockets' EINTR code; 630 * @return boolean true if @a err is equal to sockets' EINTR code;
611 * boolean false otherwise. 631 * boolean false otherwise.
612 */ 632 */
613#define MHD_SCKT_ERR_IS_EINTR_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_EINTR_) 633#define MHD_SCKT_ERR_IS_EINTR_(err) MHD_SCKT_ERR_IS_ ((err),MHD_SCKT_EINTR_)
614 634
615/** 635/**
616 * Check whether given socket error is equal to system's 636 * Check whether given socket error is equal to system's
@@ -619,10 +639,12 @@
619 * boolean false otherwise. 639 * boolean false otherwise.
620 */ 640 */
621#if MHD_SCKT_EAGAIN_ == MHD_SCKT_EWOULDBLOCK_ 641#if MHD_SCKT_EAGAIN_ == MHD_SCKT_EWOULDBLOCK_
622# define MHD_SCKT_ERR_IS_EAGAIN_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_EAGAIN_) 642# define MHD_SCKT_ERR_IS_EAGAIN_(err) MHD_SCKT_ERR_IS_ ((err),MHD_SCKT_EAGAIN_)
623#else /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */ 643#else /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */
624# define MHD_SCKT_ERR_IS_EAGAIN_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_EAGAIN_) || \ 644# define MHD_SCKT_ERR_IS_EAGAIN_(err) (MHD_SCKT_ERR_IS_ ((err), \
625 MHD_SCKT_ERR_IS_((err),MHD_SCKT_EWOULDBLOCK_) ) 645 MHD_SCKT_EAGAIN_) || \
646 MHD_SCKT_ERR_IS_ ((err), \
647 MHD_SCKT_EWOULDBLOCK_) )
626#endif /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */ 648#endif /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */
627 649
628/** 650/**
@@ -630,10 +652,17 @@
630 * @return boolean true if @a err is any kind of "low resource" error, 652 * @return boolean true if @a err is any kind of "low resource" error,
631 * boolean false otherwise. 653 * boolean false otherwise.
632 */ 654 */
633#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_EMFILE_) || \ 655#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err) (MHD_SCKT_ERR_IS_ ((err), \
634 MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENFILE_) || \ 656 MHD_SCKT_EMFILE_) \
635 MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENOMEM_) || \ 657 || \
636 MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENOBUFS_) ) 658 MHD_SCKT_ERR_IS_ ((err), \
659 MHD_SCKT_ENFILE_) \
660 || \
661 MHD_SCKT_ERR_IS_ ((err), \
662 MHD_SCKT_ENOMEM_) \
663 || \
664 MHD_SCKT_ERR_IS_ ((err), \
665 MHD_SCKT_ENOBUFS_) )
637 666
638/** 667/**
639 * Check whether is given socket error is type of "incoming connection 668 * Check whether is given socket error is type of "incoming connection
@@ -642,9 +671,11 @@
642 * boolean false otherwise. 671 * boolean false otherwise.
643 */ 672 */
644#if defined(MHD_POSIX_SOCKETS) 673#if defined(MHD_POSIX_SOCKETS)
645# define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNABORTED_) 674# define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_ ((err), \
675 MHD_SCKT_ECONNABORTED_)
646#elif defined(MHD_WINSOCK_SOCKETS) 676#elif defined(MHD_WINSOCK_SOCKETS)
647# define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNRESET_) 677# define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_ ((err), \
678 MHD_SCKT_ECONNRESET_)
648#endif 679#endif
649 680
650/** 681/**
@@ -653,8 +684,11 @@
653 * @return boolean true is @a err match described socket error code, 684 * @return boolean true is @a err match described socket error code,
654 * boolean false otherwise. 685 * boolean false otherwise.
655 */ 686 */
656#define MHD_SCKT_ERR_IS_REMOTE_DISCNN_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNRESET_) || \ 687#define MHD_SCKT_ERR_IS_REMOTE_DISCNN_(err) (MHD_SCKT_ERR_IS_ ((err), \
657 MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNABORTED_)) 688 MHD_SCKT_ECONNRESET_) \
689 || \
690 MHD_SCKT_ERR_IS_ ((err), \
691 MHD_SCKT_ECONNABORTED_))
658 692
659/* Specific error code set */ 693/* Specific error code set */
660 694
@@ -663,12 +697,16 @@
663 * available on platform. 697 * available on platform.
664 */ 698 */
665#if MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOMEM_ 699#if MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOMEM_
666# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOMEM_) 700# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_ ( \
701 MHD_SCKT_ENOMEM_)
667#elif MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOBUFS_ 702#elif MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOBUFS_
668# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOBUFS_) 703# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_ ( \
704 MHD_SCKT_ENOBUFS_)
669#else 705#else
670# warning No suitable replacement for ENOMEM error codes is found. Edit this file and add replacement code which is defined on system. 706# warning \
671# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOMEM_) 707 No suitable replacement for ENOMEM error codes is found. Edit this file and add replacement code which is defined on system.
708# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_ ( \
709 MHD_SCKT_ENOMEM_)
672#endif 710#endif
673 711
674/* Socket functions */ 712/* Socket functions */
@@ -680,22 +718,26 @@
680#endif /* AF_UNIX */ 718#endif /* AF_UNIX */
681 719
682#if defined(MHD_POSIX_SOCKETS) && defined(MHD_SCKT_LOCAL) 720#if defined(MHD_POSIX_SOCKETS) && defined(MHD_SCKT_LOCAL)
683# define MHD_socket_pair_(fdarr) (!socketpair(MHD_SCKT_LOCAL, SOCK_STREAM, 0, (fdarr))) 721# define MHD_socket_pair_(fdarr) (! socketpair (MHD_SCKT_LOCAL, SOCK_STREAM, 0, \
722 (fdarr)))
684# if defined(HAVE_SOCK_NONBLOCK) 723# if defined(HAVE_SOCK_NONBLOCK)
685# define MHD_socket_pair_nblk_(fdarr) (!socketpair(MHD_SCKT_LOCAL, SOCK_STREAM | SOCK_NONBLOCK, 0, (fdarr))) 724# define MHD_socket_pair_nblk_(fdarr) (! socketpair (MHD_SCKT_LOCAL, \
725 SOCK_STREAM \
726 | SOCK_NONBLOCK, 0, \
727 (fdarr)))
686# endif /* HAVE_SOCK_NONBLOCK*/ 728# endif /* HAVE_SOCK_NONBLOCK*/
687#elif defined(MHD_WINSOCK_SOCKETS) 729#elif defined(MHD_WINSOCK_SOCKETS)
688 /** 730/**
689 * Create pair of mutually connected TCP/IP sockets on loopback address 731 * Create pair of mutually connected TCP/IP sockets on loopback address
690 * @param sockets_pair array to receive resulted sockets 732 * @param sockets_pair array to receive resulted sockets
691 * @param non_blk if set to non-zero value, sockets created in non-blocking mode 733 * @param non_blk if set to non-zero value, sockets created in non-blocking mode
692 * otherwise sockets will be in blocking mode 734 * otherwise sockets will be in blocking mode
693 * @return non-zero if succeeded, zero otherwise 735 * @return non-zero if succeeded, zero otherwise
694 */ 736 */
695 int MHD_W32_socket_pair_(SOCKET sockets_pair[2], int non_blk); 737int MHD_W32_socket_pair_ (SOCKET sockets_pair[2], int non_blk);
696 738
697# define MHD_socket_pair_(fdarr) MHD_W32_socket_pair_((fdarr), 0) 739# define MHD_socket_pair_(fdarr) MHD_W32_socket_pair_ ((fdarr), 0)
698# define MHD_socket_pair_nblk_(fdarr) MHD_W32_socket_pair_((fdarr), 1) 740# define MHD_socket_pair_nblk_(fdarr) MHD_W32_socket_pair_ ((fdarr), 1)
699#endif 741#endif
700 742
701/** 743/**
@@ -737,7 +779,7 @@ MHD_socket_noninheritable_ (MHD_socket sock);
737 779
738 780
739#if defined(SOL_SOCKET) && defined(SO_NOSIGPIPE) 781#if defined(SOL_SOCKET) && defined(SO_NOSIGPIPE)
740 static const int _MHD_socket_int_one = 1; 782static const int _MHD_socket_int_one = 1;
741/** 783/**
742 * Change socket options to no signal on remote disconnect. 784 * Change socket options to no signal on remote disconnect.
743 * 785 *
@@ -745,7 +787,8 @@ MHD_socket_noninheritable_ (MHD_socket sock);
745 * @return non-zero if succeeded, zero otherwise 787 * @return non-zero if succeeded, zero otherwise
746 */ 788 */
747# define MHD_socket_nosignal_(sock) \ 789# define MHD_socket_nosignal_(sock) \
748 (!setsockopt((sock),SOL_SOCKET,SO_NOSIGPIPE,&_MHD_socket_int_one,sizeof(_MHD_socket_int_one))) 790 (! setsockopt ((sock),SOL_SOCKET,SO_NOSIGPIPE,&_MHD_socket_int_one, \
791 sizeof(_MHD_socket_int_one)))
749#endif /* SOL_SOCKET && SO_NOSIGPIPE */ 792#endif /* SOL_SOCKET && SO_NOSIGPIPE */
750 793
751/** 794/**
diff --git a/src/lib/mhd_str.c b/src/lib/mhd_str.c
index d0b03ead..6f2d7b98 100644
--- a/src/lib/mhd_str.c
+++ b/src/lib/mhd_str.c
@@ -117,8 +117,8 @@ _MHD_static_inline bool
117isasciixdigit (char c) 117isasciixdigit (char c)
118{ 118{
119 return isasciidigit (c) || 119 return isasciidigit (c) ||
120 ( (c >= 'A') && (c <= 'F') ) || 120 ( (c >= 'A') && (c <= 'F') ) ||
121 ( (c >= 'a') && (c <= 'f') ); 121 ( (c >= 'a') && (c <= 'f') );
122} 122}
123 123
124 124
@@ -181,7 +181,7 @@ _MHD_static_inline int
181todigitvalue (char c) 181todigitvalue (char c)
182{ 182{
183 if (isasciidigit (c)) 183 if (isasciidigit (c))
184 return (unsigned char)(c - '0'); 184 return (unsigned char) (c - '0');
185 185
186 return -1; 186 return -1;
187} 187}
@@ -198,11 +198,11 @@ _MHD_static_inline int
198toxdigitvalue (char c) 198toxdigitvalue (char c)
199{ 199{
200 if (isasciidigit (c)) 200 if (isasciidigit (c))
201 return (unsigned char)(c - '0'); 201 return (unsigned char) (c - '0');
202 if ( (c >= 'A') && (c <= 'F') ) 202 if ( (c >= 'A') && (c <= 'F') )
203 return (unsigned char)(c - 'A' + 10); 203 return (unsigned char) (c - 'A' + 10);
204 if ( (c >= 'a') && (c <= 'f') ) 204 if ( (c >= 'a') && (c <= 'f') )
205 return (unsigned char)(c - 'a' + 10); 205 return (unsigned char) (c - 'a' + 10);
206 206
207 return -1; 207 return -1;
208} 208}
@@ -216,7 +216,7 @@ toxdigitvalue (char c)
216 * @return boolean true if character is lower case letter, 216 * @return boolean true if character is lower case letter,
217 * boolean false otherwise 217 * boolean false otherwise
218 */ 218 */
219#define isasciilower(c) (((char)(c)) >= 'a' && ((char)(c)) <= 'z') 219#define isasciilower(c) (((char) (c)) >= 'a' && ((char) (c)) <= 'z')
220 220
221 221
222/** 222/**
@@ -226,7 +226,7 @@ toxdigitvalue (char c)
226 * @return boolean true if character is upper case letter, 226 * @return boolean true if character is upper case letter,
227 * boolean false otherwise 227 * boolean false otherwise
228 */ 228 */
229#define isasciiupper(c) (((char)(c)) >= 'A' && ((char)(c)) <= 'Z') 229#define isasciiupper(c) (((char) (c)) >= 'A' && ((char) (c)) <= 'Z')
230 230
231 231
232/** 232/**
@@ -236,7 +236,7 @@ toxdigitvalue (char c)
236 * @return boolean true if character is letter, boolean false 236 * @return boolean true if character is letter, boolean false
237 * otherwise 237 * otherwise
238 */ 238 */
239#define isasciialpha(c) (isasciilower(c) || isasciiupper(c)) 239#define isasciialpha(c) (isasciilower (c) || isasciiupper (c))
240 240
241 241
242/** 242/**
@@ -246,7 +246,7 @@ toxdigitvalue (char c)
246 * @return boolean true if character is decimal digit, boolean false 246 * @return boolean true if character is decimal digit, boolean false
247 * otherwise 247 * otherwise
248 */ 248 */
249#define isasciidigit(c) (((char)(c)) >= '0' && ((char)(c)) <= '9') 249#define isasciidigit(c) (((char) (c)) >= '0' && ((char) (c)) <= '9')
250 250
251 251
252/** 252/**
@@ -256,9 +256,9 @@ toxdigitvalue (char c)
256 * @return boolean true if character is hexadecimal digit, 256 * @return boolean true if character is hexadecimal digit,
257 * boolean false otherwise 257 * boolean false otherwise
258 */ 258 */
259#define isasciixdigit(c) (isasciidigit((c)) || \ 259#define isasciixdigit(c) (isasciidigit ((c)) || \
260 (((char)(c)) >= 'A' && ((char)(c)) <= 'F') || \ 260 (((char) (c)) >= 'A' && ((char) (c)) <= 'F') || \
261 (((char)(c)) >= 'a' && ((char)(c)) <= 'f') ) 261 (((char) (c)) >= 'a' && ((char) (c)) <= 'f') )
262 262
263 263
264/** 264/**
@@ -268,7 +268,7 @@ toxdigitvalue (char c)
268 * @return boolean true if character is decimal digit or letter, 268 * @return boolean true if character is decimal digit or letter,
269 * boolean false otherwise 269 * boolean false otherwise
270 */ 270 */
271#define isasciialnum(c) (isasciialpha(c) || isasciidigit(c)) 271#define isasciialnum(c) (isasciialpha (c) || isasciidigit (c))
272 272
273 273
274/** 274/**
@@ -280,7 +280,8 @@ toxdigitvalue (char c)
280 * @param c character to convert 280 * @param c character to convert
281 * @return converted to lower case character 281 * @return converted to lower case character
282 */ 282 */
283#define toasciilower(c) ((isasciiupper(c)) ? (((char)(c)) - 'A' + 'a') : ((char)(c))) 283#define toasciilower(c) ((isasciiupper (c)) ? (((char) (c)) - 'A' + 'a') : \
284 ((char) (c)))
284 285
285 286
286/** 287/**
@@ -292,7 +293,8 @@ toxdigitvalue (char c)
292 * @param c character to convert 293 * @param c character to convert
293 * @return converted to upper case character 294 * @return converted to upper case character
294 */ 295 */
295#define toasciiupper(c) ((isasciilower(c)) ? (((char)(c)) - 'a' + 'A') : ((char)(c))) 296#define toasciiupper(c) ((isasciilower (c)) ? (((char) (c)) - 'a' + 'A') : \
297 ((char) (c)))
296 298
297 299
298/** 300/**
@@ -301,7 +303,8 @@ toxdigitvalue (char c)
301 * @param c character to convert 303 * @param c character to convert
302 * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit 304 * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit
303 */ 305 */
304#define todigitvalue(c) (isasciidigit(c) ? (int)(((char)(c)) - '0') : (int)(-1)) 306#define todigitvalue(c) (isasciidigit (c) ? (int) (((char) (c)) - '0') : \
307 (int) (-1))
305 308
306 309
307/** 310/**
@@ -309,11 +312,12 @@ toxdigitvalue (char c)
309 * @param c character to convert 312 * @param c character to convert
310 * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit 313 * @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit
311 */ 314 */
312#define toxdigitvalue(c) ( isasciidigit(c) ? (int)(((char)(c)) - '0') : \ 315#define toxdigitvalue(c) (isasciidigit (c) ? (int) (((char) (c)) - '0') : \
313 ( (((char)(c)) >= 'A' && ((char)(c)) <= 'F') ? \ 316 ( (((char) (c)) >= 'A' && ((char) (c)) <= 'F') ? \
314 (int)(((unsigned char)(c)) - 'A' + 10) : \ 317 (int) (((unsigned char) (c)) - 'A' + 10) : \
315 ( (((char)(c)) >= 'a' && ((char)(c)) <= 'f') ? \ 318 ( (((char) (c)) >= 'a' && ((char) (c)) <= 'f') ? \
316 (int)(((unsigned char)(c)) - 'a' + 10) : (int)(-1) ))) 319 (int) (((unsigned char) (c)) - 'a' + 10) : \
320 (int) (-1) )))
317#endif /* !INLINE_FUNC */ 321#endif /* !INLINE_FUNC */
318 322
319 323
@@ -326,19 +330,19 @@ toxdigitvalue (char c)
326 * @return non-zero if two strings are equal, zero otherwise. 330 * @return non-zero if two strings are equal, zero otherwise.
327 */ 331 */
328int 332int
329MHD_str_equal_caseless_ (const char * str1, 333MHD_str_equal_caseless_ (const char *str1,
330 const char * str2) 334 const char *str2)
331{ 335{
332 while (0 != (*str1)) 336 while (0 != (*str1))
333 { 337 {
334 const char c1 = *str1; 338 const char c1 = *str1;
335 const char c2 = *str2; 339 const char c2 = *str2;
336 if ( (c1 != c2) && 340 if ( (c1 != c2) &&
337 (toasciilower (c1) != toasciilower (c2)) ) 341 (toasciilower (c1) != toasciilower (c2)) )
338 return 0; 342 return 0;
339 str1++; 343 str1++;
340 str2++; 344 str2++;
341 } 345 }
342 return 0 == (*str2); 346 return 0 == (*str2);
343} 347}
344#endif /* ! MHD_FAVOR_SMALL_CODE */ 348#endif /* ! MHD_FAVOR_SMALL_CODE */
@@ -356,23 +360,23 @@ MHD_str_equal_caseless_ (const char * str1,
356 * @return non-zero if two strings are equal, zero otherwise. 360 * @return non-zero if two strings are equal, zero otherwise.
357 */ 361 */
358int 362int
359MHD_str_equal_caseless_n_ (const char * const str1, 363MHD_str_equal_caseless_n_ (const char *const str1,
360 const char * const str2, 364 const char *const str2,
361 size_t maxlen) 365 size_t maxlen)
362{ 366{
363 size_t i; 367 size_t i;
364 368
365 for (i = 0; i < maxlen; ++i) 369 for (i = 0; i < maxlen; ++i)
366 { 370 {
367 const char c1 = str1[i]; 371 const char c1 = str1[i];
368 const char c2 = str2[i]; 372 const char c2 = str2[i];
369 if (0 == c2) 373 if (0 == c2)
370 return 0 == c1; 374 return 0 == c1;
371 if ( (c1 != c2) && 375 if ( (c1 != c2) &&
372 (toasciilower (c1) != toasciilower (c2)) ) 376 (toasciilower (c1) != toasciilower (c2)) )
373 return 0; 377 return 0;
374 } 378 }
375 return !0; 379 return ! 0;
376} 380}
377 381
378 382
@@ -390,46 +394,49 @@ MHD_str_equal_caseless_n_ (const char * const str1,
390 * @return non-zero if two strings are equal, zero otherwise. 394 * @return non-zero if two strings are equal, zero otherwise.
391 */ 395 */
392bool 396bool
393MHD_str_has_token_caseless_ (const char * str, 397MHD_str_has_token_caseless_ (const char *str,
394 const char * const token, 398 const char *const token,
395 size_t token_len) 399 size_t token_len)
396{ 400{
397 if (0 == token_len) 401 if (0 == token_len)
398 return false; 402 return false;
399 403
400 while (0 != *str) 404 while (0 != *str)
405 {
406 size_t i;
407 /* Skip all whitespaces and empty tokens. */
408 while (' ' == *str || '\t' == *str || ',' == *str)
409 str++;
410
411 /* Check for token match. */
412 i = 0;
413 while (1)
401 { 414 {
402 size_t i; 415 const char sc = *(str++);
403 /* Skip all whitespaces and empty tokens. */ 416 const char tc = token[i++];
404 while (' ' == *str || '\t' == *str || ',' == *str) str++; 417
405 418 if (0 == sc)
406 /* Check for token match. */ 419 return false;
407 i = 0; 420 if ( (sc != tc) &&
408 while (1) 421 (toasciilower (sc) != toasciilower (tc)) )
409 { 422 break;
410 const char sc = *(str++); 423 if (i >= token_len)
411 const char tc = token[i++]; 424 {
412 425 /* Check whether substring match token fully or
413 if (0 == sc) 426 * has additional unmatched chars at tail. */
414 return false; 427 while (' ' == *str || '\t' == *str)
415 if ( (sc != tc) && 428 str++;
416 (toasciilower (sc) != toasciilower (tc)) ) 429 /* End of (sub)string? */
417 break; 430 if ((0 == *str) ||(',' == *str) )
418 if (i >= token_len) 431 return true;
419 { 432 /* Unmatched chars at end of substring. */
420 /* Check whether substring match token fully or 433 break;
421 * has additional unmatched chars at tail. */ 434 }
422 while (' ' == *str || '\t' == *str) str++;
423 /* End of (sub)string? */
424 if (0 == *str || ',' == *str)
425 return true;
426 /* Unmatched chars at end of substring. */
427 break;
428 }
429 }
430 /* Find next substring. */
431 while (0 != *str && ',' != *str) str++;
432 } 435 }
436 /* Find next substring. */
437 while (0 != *str && ',' != *str)
438 str++;
439 }
433 return false; 440 return false;
434} 441}
435 442
@@ -450,25 +457,25 @@ size_t
450MHD_str_to_uint64_ (const char *str, 457MHD_str_to_uint64_ (const char *str,
451 uint64_t *out_val) 458 uint64_t *out_val)
452{ 459{
453 const char * const start = str; 460 const char *const start = str;
454 uint64_t res; 461 uint64_t res;
455 462
456 if (!str || !out_val || !isasciidigit(str[0])) 463 if (! str || ! out_val || ! isasciidigit (str[0]))
457 return 0; 464 return 0;
458 465
459 res = 0; 466 res = 0;
460 do 467 do
461 { 468 {
462 const int digit = (unsigned char)(*str) - '0'; 469 const int digit = (unsigned char) (*str) - '0';
463 if ( (res > (UINT64_MAX / 10)) || 470 if ( (res > (UINT64_MAX / 10)) ||
464 ( (res == (UINT64_MAX / 10)) && 471 ( (res == (UINT64_MAX / 10)) &&
465 ((uint64_t)digit > (UINT64_MAX % 10)) ) ) 472 ((uint64_t) digit > (UINT64_MAX % 10)) ) )
466 return 0; 473 return 0;
467 474
468 res *= 10; 475 res *= 10;
469 res += digit; 476 res += digit;
470 str++; 477 str++;
471 } while (isasciidigit (*str)); 478 } while (isasciidigit (*str));
472 479
473 *out_val = res; 480 *out_val = res;
474 return str - start; 481 return str - start;
@@ -489,34 +496,34 @@ MHD_str_to_uint64_ (const char *str,
489 * then possible to store in uint64_t or @a out_val is NULL 496 * then possible to store in uint64_t or @a out_val is NULL
490 */ 497 */
491size_t 498size_t
492MHD_str_to_uint64_n_ (const char * str, 499MHD_str_to_uint64_n_ (const char *str,
493 size_t maxlen, 500 size_t maxlen,
494 uint64_t *out_val) 501 uint64_t *out_val)
495{ 502{
496 uint64_t res; 503 uint64_t res;
497 size_t i; 504 size_t i;
498 505
499 if (!str || !maxlen || !out_val || !isasciidigit (str[0])) 506 if (! str || ! maxlen || ! out_val || ! isasciidigit (str[0]))
500 return 0; 507 return 0;
501 508
502 res = 0; 509 res = 0;
503 i = 0; 510 i = 0;
504 do 511 do
505 { 512 {
506 const int digit = (unsigned char)str[i] - '0'; 513 const int digit = (unsigned char) str[i] - '0';
507 514
508 if ( (res > (UINT64_MAX / 10)) || 515 if ( (res > (UINT64_MAX / 10)) ||
509 ( (res == (UINT64_MAX / 10)) && 516 ( (res == (UINT64_MAX / 10)) &&
510 ((uint64_t)digit > (UINT64_MAX % 10)) ) ) 517 ((uint64_t) digit > (UINT64_MAX % 10)) ) )
511 return 0; 518 return 0;
512 519
513 res *= 10; 520 res *= 10;
514 res += digit; 521 res += digit;
515 i++; 522 i++;
516 } while ( (i < maxlen) && 523 } while ( (i < maxlen) &&
517 isasciidigit (str[i]) ); 524 isasciidigit (str[i]) );
518 525
519 *out_val= res; 526 *out_val = res;
520 return i; 527 return i;
521} 528}
522 529
@@ -532,31 +539,32 @@ MHD_str_to_uint64_n_ (const char * str,
532 * then possible to store in uint32_t or @a out_val is NULL 539 * then possible to store in uint32_t or @a out_val is NULL
533 */ 540 */
534size_t 541size_t
535MHD_strx_to_uint32_ (const char * str, 542MHD_strx_to_uint32_ (const char *str,
536 uint32_t *out_val) 543 uint32_t *out_val)
537{ 544{
538 const char * const start = str; 545 const char *const start = str;
539 uint32_t res; 546 uint32_t res;
540 int digit; 547 int digit;
541 548
542 if (!str || !out_val) 549 if (! str || ! out_val)
543 return 0; 550 return 0;
544 551
545 res = 0; 552 res = 0;
546 digit = toxdigitvalue (*str); 553 digit = toxdigitvalue (*str);
547 while (digit >= 0) 554 while (digit >= 0)
555 {
556 if ( (res < (UINT32_MAX / 16)) ||
557 ((res == (UINT32_MAX / 16)) &&( (uint32_t) digit <= (UINT32_MAX
558 % 16)) ) )
548 { 559 {
549 if ( (res < (UINT32_MAX / 16)) || 560 res *= 16;
550 (res == (UINT32_MAX / 16) && (uint32_t)digit <= (UINT32_MAX % 16)) ) 561 res += digit;
551 {
552 res *= 16;
553 res += digit;
554 }
555 else
556 return 0;
557 str++;
558 digit = toxdigitvalue (*str);
559 } 562 }
563 else
564 return 0;
565 str++;
566 digit = toxdigitvalue (*str);
567 }
560 568
561 if (str - start > 0) 569 if (str - start > 0)
562 *out_val = res; 570 *out_val = res;
@@ -585,21 +593,22 @@ MHD_strx_to_uint32_n_ (const char *str,
585 size_t i; 593 size_t i;
586 uint32_t res; 594 uint32_t res;
587 int digit; 595 int digit;
588 if (!str || !out_val) 596 if (! str || ! out_val)
589 return 0; 597 return 0;
590 598
591 res = 0; 599 res = 0;
592 i = 0; 600 i = 0;
593 while (i < maxlen && (digit = toxdigitvalue (str[i])) >= 0) 601 while (i < maxlen && (digit = toxdigitvalue (str[i])) >= 0)
594 { 602 {
595 if ( (res > (UINT32_MAX / 16)) || 603 if ( (res > (UINT32_MAX / 16)) ||
596 (res == (UINT32_MAX / 16) && (uint32_t)digit > (UINT32_MAX % 16)) ) 604 ((res == (UINT32_MAX / 16)) &&( (uint32_t) digit > (UINT32_MAX
597 return 0; 605 % 16)) ) )
606 return 0;
598 607
599 res *= 16; 608 res *= 16;
600 res += digit; 609 res += digit;
601 i++; 610 i++;
602 } 611 }
603 612
604 if (i) 613 if (i)
605 *out_val = res; 614 *out_val = res;
@@ -621,27 +630,28 @@ size_t
621MHD_strx_to_uint64_ (const char *str, 630MHD_strx_to_uint64_ (const char *str,
622 uint64_t *out_val) 631 uint64_t *out_val)
623{ 632{
624 const char * const start = str; 633 const char *const start = str;
625 uint64_t res; 634 uint64_t res;
626 int digit; 635 int digit;
627 if (!str || !out_val) 636 if (! str || ! out_val)
628 return 0; 637 return 0;
629 638
630 res = 0; 639 res = 0;
631 digit = toxdigitvalue (*str); 640 digit = toxdigitvalue (*str);
632 while (digit >= 0) 641 while (digit >= 0)
642 {
643 if ( (res < (UINT64_MAX / 16)) ||
644 ((res == (UINT64_MAX / 16)) &&( (uint64_t) digit <= (UINT64_MAX
645 % 16)) ) )
633 { 646 {
634 if ( (res < (UINT64_MAX / 16)) || 647 res *= 16;
635 (res == (UINT64_MAX / 16) && (uint64_t)digit <= (UINT64_MAX % 16)) ) 648 res += digit;
636 {
637 res *= 16;
638 res += digit;
639 }
640 else
641 return 0;
642 str++;
643 digit = toxdigitvalue (*str);
644 } 649 }
650 else
651 return 0;
652 str++;
653 digit = toxdigitvalue (*str);
654 }
645 655
646 if (str - start > 0) 656 if (str - start > 0)
647 *out_val = res; 657 *out_val = res;
@@ -663,28 +673,29 @@ MHD_strx_to_uint64_ (const char *str,
663 * then possible to store in uint64_t or @a out_val is NULL 673 * then possible to store in uint64_t or @a out_val is NULL
664 */ 674 */
665size_t 675size_t
666MHD_strx_to_uint64_n_ (const char * str, 676MHD_strx_to_uint64_n_ (const char *str,
667 size_t maxlen, 677 size_t maxlen,
668 uint64_t *out_val) 678 uint64_t *out_val)
669{ 679{
670 size_t i; 680 size_t i;
671 uint64_t res; 681 uint64_t res;
672 int digit; 682 int digit;
673 if (!str || !out_val) 683 if (! str || ! out_val)
674 return 0; 684 return 0;
675 685
676 res = 0; 686 res = 0;
677 i = 0; 687 i = 0;
678 while (i < maxlen && (digit = toxdigitvalue (str[i])) >= 0) 688 while (i < maxlen && (digit = toxdigitvalue (str[i])) >= 0)
679 { 689 {
680 if ( (res > (UINT64_MAX / 16)) || 690 if ( (res > (UINT64_MAX / 16)) ||
681 (res == (UINT64_MAX / 16) && (uint64_t)digit > (UINT64_MAX % 16)) ) 691 ((res == (UINT64_MAX / 16)) &&( (uint64_t) digit > (UINT64_MAX
682 return 0; 692 % 16)) ) )
693 return 0;
683 694
684 res *= 16; 695 res *= 16;
685 res += digit; 696 res += digit;
686 i++; 697 i++;
687 } 698 }
688 699
689 if (i) 700 if (i)
690 *out_val = res; 701 *out_val = res;
@@ -713,7 +724,7 @@ MHD_strx_to_uint64_n_ (const char * str,
713size_t 724size_t
714MHD_str_to_uvalue_n_ (const char *str, 725MHD_str_to_uvalue_n_ (const char *str,
715 size_t maxlen, 726 size_t maxlen,
716 void * out_val, 727 void *out_val,
717 size_t val_size, 728 size_t val_size,
718 uint64_t max_val, 729 uint64_t max_val,
719 int base) 730 int base)
@@ -725,34 +736,34 @@ MHD_str_to_uvalue_n_ (const char *str,
725 const uint64_t max_v_mod_b = max_val % base; 736 const uint64_t max_v_mod_b = max_val % base;
726 /* 'digit->value' must be function, not macro */ 737 /* 'digit->value' must be function, not macro */
727 int (*const dfunc)(char) = (base == 16) ? 738 int (*const dfunc)(char) = (base == 16) ?
728 toxdigitvalue : todigitvalue; 739 toxdigitvalue : todigitvalue;
729 740
730 if ( !str || !out_val || 741 if ( ! str || ! out_val ||
731 (base != 16 && base != 10) ) 742 ((base != 16)&&(base != 10)) )
732 return 0; 743 return 0;
733 744
734 res = 0; 745 res = 0;
735 i = 0; 746 i = 0;
736 while (maxlen > i && 0 <= (digit = dfunc (str[i]))) 747 while (maxlen > i && 0 <= (digit = dfunc (str[i])))
737 { 748 {
738 if ( ((max_v_div_b) < res) || 749 if ( ((max_v_div_b) < res) ||
739 ((max_v_div_b) == res && (max_v_mod_b) < (uint64_t)digit) ) 750 (( (max_v_div_b) == res) &&( (max_v_mod_b) < (uint64_t) digit) ) )
740 return 0; 751 return 0;
741 752
742 res *= base; 753 res *= base;
743 res += digit; 754 res += digit;
744 i++; 755 i++;
745 } 756 }
746 757
747 if (i) 758 if (i)
748 { 759 {
749 if (8 == val_size) 760 if (8 == val_size)
750 *(uint64_t*)out_val = res; 761 *(uint64_t*) out_val = res;
751 else if (4 == val_size) 762 else if (4 == val_size)
752 *(uint32_t*)out_val = (uint32_t)res; 763 *(uint32_t*) out_val = (uint32_t) res;
753 else 764 else
754 return 0; 765 return 0;
755 } 766 }
756 return i; 767 return i;
757} 768}
758#endif /* MHD_FAVOR_SMALL_CODE */ 769#endif /* MHD_FAVOR_SMALL_CODE */
diff --git a/src/lib/mhd_str.h b/src/lib/mhd_str.h
index 410cc36e..f0f6511d 100644
--- a/src/lib/mhd_str.h
+++ b/src/lib/mhd_str.h
@@ -42,7 +42,7 @@
42/** 42/**
43 * Determine length of static string / macro strings at compile time. 43 * Determine length of static string / macro strings at compile time.
44 */ 44 */
45#define MHD_STATICSTR_LEN_(macro) (sizeof(macro)/sizeof(char) - 1) 45#define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1)
46#endif /* ! MHD_STATICSTR_LEN_ */ 46#endif /* ! MHD_STATICSTR_LEN_ */
47 47
48/* 48/*
@@ -58,11 +58,12 @@
58 * @return non-zero if two strings are equal, zero otherwise. 58 * @return non-zero if two strings are equal, zero otherwise.
59 */ 59 */
60int 60int
61MHD_str_equal_caseless_ (const char * str1, 61MHD_str_equal_caseless_ (const char *str1,
62 const char * str2); 62 const char *str2);
63#else /* MHD_FAVOR_SMALL_CODE */ 63#else /* MHD_FAVOR_SMALL_CODE */
64/* Reuse MHD_str_equal_caseless_n_() to reduce size */ 64/* Reuse MHD_str_equal_caseless_n_() to reduce size */
65#define MHD_str_equal_caseless_(s1,s2) MHD_str_equal_caseless_n_((s1),(s2), SIZE_MAX) 65#define MHD_str_equal_caseless_(s1,s2) MHD_str_equal_caseless_n_ ((s1),(s2), \
66 SIZE_MAX)
66#endif /* MHD_FAVOR_SMALL_CODE */ 67#endif /* MHD_FAVOR_SMALL_CODE */
67 68
68 69
@@ -77,9 +78,9 @@ MHD_str_equal_caseless_ (const char * str1,
77 * @return non-zero if two strings are equal, zero otherwise. 78 * @return non-zero if two strings are equal, zero otherwise.
78 */ 79 */
79int 80int
80MHD_str_equal_caseless_n_ (const char * const str1, 81MHD_str_equal_caseless_n_ (const char *const str1,
81 const char * const str2, 82 const char *const str2,
82 size_t maxlen); 83 size_t maxlen);
83 84
84 85
85/** 86/**
@@ -96,8 +97,8 @@ MHD_str_equal_caseless_n_ (const char * const str1,
96 * @return non-zero if two strings are equal, zero otherwise. 97 * @return non-zero if two strings are equal, zero otherwise.
97 */ 98 */
98bool 99bool
99MHD_str_has_token_caseless_ (const char * str, 100MHD_str_has_token_caseless_ (const char *str,
100 const char * const token, 101 const char *const token,
101 size_t token_len); 102 size_t token_len);
102 103
103/** 104/**
@@ -111,7 +112,7 @@ MHD_str_has_token_caseless_ (const char * str,
111 * @return non-zero if two strings are equal, zero otherwise. 112 * @return non-zero if two strings are equal, zero otherwise.
112 */ 113 */
113#define MHD_str_has_s_token_caseless_(str,tkn) \ 114#define MHD_str_has_s_token_caseless_(str,tkn) \
114 MHD_str_has_token_caseless_((str),(tkn),MHD_STATICSTR_LEN_(tkn)) 115 MHD_str_has_token_caseless_ ((str),(tkn),MHD_STATICSTR_LEN_ (tkn))
115 116
116#ifndef MHD_FAVOR_SMALL_CODE 117#ifndef MHD_FAVOR_SMALL_CODE
117/* Use individual function for each case to improve speed */ 118/* Use individual function for each case to improve speed */
@@ -126,13 +127,13 @@ MHD_str_has_token_caseless_ (const char * str,
126 * then possible to store in uint64_t or @a out_val is NULL 127 * then possible to store in uint64_t or @a out_val is NULL
127 */ 128 */
128size_t 129size_t
129MHD_str_to_uint64_ (const char * str, 130MHD_str_to_uint64_ (const char *str,
130 uint64_t * out_val); 131 uint64_t *out_val);
131 132
132/** 133/**
133 * Convert not more then @a maxlen decimal US-ASCII digits in string to 134 * Convert not more then @a maxlen decimal US-ASCII digits in string to
134 * number in uint64_t. 135 * number in uint64_t.
135 * Conversion stopped at first non-digit character or after @a maxlen 136 * Conversion stopped at first non-digit character or after @a maxlen
136 * digits. 137 * digits.
137 * @param str string to convert 138 * @param str string to convert
138 * @param maxlen maximum number of characters to process 139 * @param maxlen maximum number of characters to process
@@ -142,9 +143,9 @@ MHD_str_to_uint64_ (const char * str,
142 * then possible to store in uint64_t or @a out_val is NULL 143 * then possible to store in uint64_t or @a out_val is NULL
143 */ 144 */
144size_t 145size_t
145MHD_str_to_uint64_n_ (const char * str, 146MHD_str_to_uint64_n_ (const char *str,
146 size_t maxlen, 147 size_t maxlen,
147 uint64_t * out_val); 148 uint64_t *out_val);
148 149
149 150
150/** 151/**
@@ -152,19 +153,19 @@ MHD_str_to_uint64_n_ (const char * str,
152 * Conversion stopped at first non-digit character. 153 * Conversion stopped at first non-digit character.
153 * @param str string to convert 154 * @param str string to convert
154 * @param out_val pointer to uint32_t to store result of conversion 155 * @param out_val pointer to uint32_t to store result of conversion
155 * @return non-zero number of characters processed on succeed, 156 * @return non-zero number of characters processed on succeed,
156 * zero if no digit is found, resulting value is larger 157 * zero if no digit is found, resulting value is larger
157 * then possible to store in uint32_t or @a out_val is NULL 158 * then possible to store in uint32_t or @a out_val is NULL
158 */ 159 */
159size_t 160size_t
160MHD_strx_to_uint32_ (const char * str, 161MHD_strx_to_uint32_ (const char *str,
161 uint32_t * out_val); 162 uint32_t *out_val);
162 163
163 164
164/** 165/**
165 * Convert not more then @a maxlen hexadecimal US-ASCII digits in string 166 * Convert not more then @a maxlen hexadecimal US-ASCII digits in string
166 * to number in uint32_t. 167 * to number in uint32_t.
167 * Conversion stopped at first non-digit character or after @a maxlen 168 * Conversion stopped at first non-digit character or after @a maxlen
168 * digits. 169 * digits.
169 * @param str string to convert 170 * @param str string to convert
170 * @param maxlen maximum number of characters to process 171 * @param maxlen maximum number of characters to process
@@ -174,9 +175,9 @@ MHD_strx_to_uint32_ (const char * str,
174 * then possible to store in uint32_t or @a out_val is NULL 175 * then possible to store in uint32_t or @a out_val is NULL
175 */ 176 */
176size_t 177size_t
177MHD_strx_to_uint32_n_ (const char * str, 178MHD_strx_to_uint32_n_ (const char *str,
178 size_t maxlen, 179 size_t maxlen,
179 uint32_t * out_val); 180 uint32_t *out_val);
180 181
181 182
182/** 183/**
@@ -184,19 +185,19 @@ MHD_strx_to_uint32_n_ (const char * str,
184 * Conversion stopped at first non-digit character. 185 * Conversion stopped at first non-digit character.
185 * @param str string to convert 186 * @param str string to convert
186 * @param out_val pointer to uint64_t to store result of conversion 187 * @param out_val pointer to uint64_t to store result of conversion
187 * @return non-zero number of characters processed on succeed, 188 * @return non-zero number of characters processed on succeed,
188 * zero if no digit is found, resulting value is larger 189 * zero if no digit is found, resulting value is larger
189 * then possible to store in uint64_t or @a out_val is NULL 190 * then possible to store in uint64_t or @a out_val is NULL
190 */ 191 */
191size_t 192size_t
192MHD_strx_to_uint64_ (const char * str, 193MHD_strx_to_uint64_ (const char *str,
193 uint64_t * out_val); 194 uint64_t *out_val);
194 195
195 196
196/** 197/**
197 * Convert not more then @a maxlen hexadecimal US-ASCII digits in string 198 * Convert not more then @a maxlen hexadecimal US-ASCII digits in string
198 * to number in uint64_t. 199 * to number in uint64_t.
199 * Conversion stopped at first non-digit character or after @a maxlen 200 * Conversion stopped at first non-digit character or after @a maxlen
200 * digits. 201 * digits.
201 * @param str string to convert 202 * @param str string to convert
202 * @param maxlen maximum number of characters to process 203 * @param maxlen maximum number of characters to process
@@ -206,9 +207,9 @@ MHD_strx_to_uint64_ (const char * str,
206 * then possible to store in uint64_t or @a out_val is NULL 207 * then possible to store in uint64_t or @a out_val is NULL
207 */ 208 */
208size_t 209size_t
209MHD_strx_to_uint64_n_ (const char * str, 210MHD_strx_to_uint64_n_ (const char *str,
210 size_t maxlen, 211 size_t maxlen,
211 uint64_t * out_val); 212 uint64_t *out_val);
212 213
213#else /* MHD_FAVOR_SMALL_CODE */ 214#else /* MHD_FAVOR_SMALL_CODE */
214/* Use one universal function and macros to reduce size */ 215/* Use one universal function and macros to reduce size */
@@ -216,7 +217,7 @@ MHD_strx_to_uint64_n_ (const char * str,
216/** 217/**
217 * Generic function for converting not more then @a maxlen 218 * Generic function for converting not more then @a maxlen
218 * hexadecimal or decimal US-ASCII digits in string to number. 219 * hexadecimal or decimal US-ASCII digits in string to number.
219 * Conversion stopped at first non-digit character or after @a maxlen 220 * Conversion stopped at first non-digit character or after @a maxlen
220 * digits. 221 * digits.
221 * To be used only within macro. 222 * To be used only within macro.
222 * @param str the string to convert 223 * @param str the string to convert
@@ -230,36 +231,44 @@ MHD_strx_to_uint64_n_ (const char * str,
230 * then @ max_val or @a out_val is NULL 231 * then @ max_val or @a out_val is NULL
231 */ 232 */
232size_t 233size_t
233MHD_str_to_uvalue_n_ (const char * str, 234MHD_str_to_uvalue_n_ (const char *str,
234 size_t maxlen, 235 size_t maxlen,
235 void * out_val, 236 void *out_val,
236 size_t val_size, 237 size_t val_size,
237 uint64_t max_val, 238 uint64_t max_val,
238 int base); 239 int base);
239 240
240#define MHD_str_to_uint64_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\ 241#define MHD_str_to_uint64_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
241 sizeof(uint64_t),UINT64_MAX,10) 242 sizeof(uint64_t), \
243 UINT64_MAX,10)
242 244
243#define MHD_str_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\ 245#define MHD_str_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
244 sizeof(uint64_t),UINT64_MAX,10) 246 sizeof(uint64_t), \
247 UINT64_MAX,10)
245 248
246#define MHD_strx_to_sizet_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\ 249#define MHD_strx_to_sizet_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
247 sizeof(size_t),SIZE_MAX,16) 250 sizeof(size_t),SIZE_MAX, \
251 16)
248 252
249#define MHD_strx_to_sizet_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\ 253#define MHD_strx_to_sizet_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
250 sizeof(size_t),SIZE_MAX,16) 254 sizeof(size_t), \
255 SIZE_MAX,16)
251 256
252#define MHD_strx_to_uint32_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\ 257#define MHD_strx_to_uint32_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
253 sizeof(uint32_t),UINT32_MAX,16) 258 sizeof(uint32_t), \
259 UINT32_MAX,16)
254 260
255#define MHD_strx_to_uint32_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\ 261#define MHD_strx_to_uint32_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
256 sizeof(uint32_t),UINT32_MAX,16) 262 sizeof(uint32_t), \
263 UINT32_MAX,16)
257 264
258#define MHD_strx_to_uint64_(s,ov) MHD_str_to_uvalue_n_((s),SIZE_MAX,(ov),\ 265#define MHD_strx_to_uint64_(s,ov) MHD_str_to_uvalue_n_ ((s),SIZE_MAX,(ov), \
259 sizeof(uint64_t),UINT64_MAX,16) 266 sizeof(uint64_t), \
267 UINT64_MAX,16)
260 268
261#define MHD_strx_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_((s),(ml),(ov),\ 269#define MHD_strx_to_uint64_n_(s,ml,ov) MHD_str_to_uvalue_n_ ((s),(ml),(ov), \
262 sizeof(uint64_t),UINT64_MAX,16) 270 sizeof(uint64_t), \
271 UINT64_MAX,16)
263 272
264#endif /* MHD_FAVOR_SMALL_CODE */ 273#endif /* MHD_FAVOR_SMALL_CODE */
265 274
diff --git a/src/lib/mhd_threads.c b/src/lib/mhd_threads.c
index 6578e4b1..a90090f4 100644
--- a/src/lib/mhd_threads.c
+++ b/src/lib/mhd_threads.c
@@ -46,12 +46,14 @@
46#else /* MHD_USE_THREAD_NAME_ */ 46#else /* MHD_USE_THREAD_NAME_ */
47 47
48#if defined(MHD_USE_POSIX_THREADS) 48#if defined(MHD_USE_POSIX_THREADS)
49#if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI) 49#if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || \
50 defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
50# define MHD_USE_THREAD_ATTR_SETNAME 1 51# define MHD_USE_THREAD_ATTR_SETNAME 1
51#endif /* HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD || HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI */ 52#endif /* HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD || HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI */
52 53
53#if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) \ 54#if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || \
54 || defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) 55 defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) \
56 || defined(HAVE_PTHREAD_SETNAME_NP_NETBSD)
55 57
56/** 58/**
57 * Set thread name 59 * Set thread name
@@ -61,25 +63,25 @@
61 * @return non-zero on success, zero otherwise 63 * @return non-zero on success, zero otherwise
62 */ 64 */
63static int 65static int
64MHD_set_thread_name_(const MHD_thread_ID_ thread_id, 66MHD_set_thread_name_ (const MHD_thread_ID_ thread_id,
65 const char *thread_name) 67 const char *thread_name)
66{ 68{
67 if (NULL == thread_name) 69 if (NULL == thread_name)
68 return 0; 70 return 0;
69 71
70#if defined(HAVE_PTHREAD_SETNAME_NP_GNU) 72#if defined(HAVE_PTHREAD_SETNAME_NP_GNU)
71 return !pthread_setname_np (thread_id, thread_name); 73 return ! pthread_setname_np (thread_id, thread_name);
72#elif defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) 74#elif defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD)
73 /* FreeBSD and OpenBSD use different name and void return type */ 75 /* FreeBSD and OpenBSD use different name and void return type */
74 pthread_set_name_np (thread_id, thread_name); 76 pthread_set_name_np (thread_id, thread_name);
75 return !0; 77 return ! 0;
76#elif defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) 78#elif defined(HAVE_PTHREAD_SETNAME_NP_NETBSD)
77 /* NetBSD use 3 arguments: second argument is string in printf-like format, 79 /* NetBSD use 3 arguments: second argument is string in printf-like format,
78 * third argument is single argument for printf; 80 * third argument is single argument for printf;
79 * OSF1 use 3 arguments too, but last one always must be zero (NULL). 81 * OSF1 use 3 arguments too, but last one always must be zero (NULL).
80 * MHD doesn't use '%' in thread names, so both form are used in same way. 82 * MHD doesn't use '%' in thread names, so both form are used in same way.
81 */ 83 */
82 return !pthread_setname_np (thread_id, thread_name, 0); 84 return ! pthread_setname_np (thread_id, thread_name, 0);
83#endif /* HAVE_PTHREAD_SETNAME_NP_NETBSD */ 85#endif /* HAVE_PTHREAD_SETNAME_NP_NETBSD */
84} 86}
85 87
@@ -90,10 +92,10 @@ MHD_set_thread_name_(const MHD_thread_ID_ thread_id,
90 * @param n name to set 92 * @param n name to set
91 * @return non-zero on success, zero otherwise 93 * @return non-zero on success, zero otherwise
92 */ 94 */
93#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_(pthread_self(),(n)) 95#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_ (pthread_self (),(n))
94#else /* __QNXNTO__ */ 96#else /* __QNXNTO__ */
95/* Special case for QNX Neutrino - using zero for thread ID sets name faster. */ 97/* Special case for QNX Neutrino - using zero for thread ID sets name faster. */
96#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_(0,(n)) 98#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_ (0,(n))
97#endif /* __QNXNTO__ */ 99#endif /* __QNXNTO__ */
98#elif defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) 100#elif defined(HAVE_PTHREAD_SETNAME_NP_DARWIN)
99 101
@@ -102,7 +104,7 @@ MHD_set_thread_name_(const MHD_thread_ID_ thread_id,
102 * @param n name to set 104 * @param n name to set
103 * @return non-zero on success, zero otherwise 105 * @return non-zero on success, zero otherwise
104 */ 106 */
105#define MHD_set_cur_thread_name_(n) (!(pthread_setname_np((n)))) 107#define MHD_set_cur_thread_name_(n) (! (pthread_setname_np ((n))))
106#endif /* HAVE_PTHREAD_SETNAME_NP_DARWIN */ 108#endif /* HAVE_PTHREAD_SETNAME_NP_DARWIN */
107 109
108#elif defined(MHD_USE_W32_THREADS) 110#elif defined(MHD_USE_W32_THREADS)
@@ -117,8 +119,8 @@ MHD_set_thread_name_(const MHD_thread_ID_ thread_id,
117 * @return non-zero on success, zero otherwise 119 * @return non-zero on success, zero otherwise
118 */ 120 */
119static int 121static int
120MHD_set_thread_name_(const MHD_thread_ID_ thread_id, 122MHD_set_thread_name_ (const MHD_thread_ID_ thread_id,
121 const char *thread_name) 123 const char *thread_name)
122{ 124{
123 static const DWORD VC_SETNAME_EXC = 0x406D1388; 125 static const DWORD VC_SETNAME_EXC = 0x406D1388;
124#pragma pack(push,8) 126#pragma pack(push,8)
@@ -149,7 +151,7 @@ MHD_set_thread_name_(const MHD_thread_ID_ thread_id,
149 __except (EXCEPTION_EXECUTE_HANDLER) 151 __except (EXCEPTION_EXECUTE_HANDLER)
150 {} 152 {}
151 153
152 return !0; 154 return ! 0;
153} 155}
154 156
155 157
@@ -158,7 +160,7 @@ MHD_set_thread_name_(const MHD_thread_ID_ thread_id,
158 * @param n name to set 160 * @param n name to set
159 * @return non-zero on success, zero otherwise 161 * @return non-zero on success, zero otherwise
160 */ 162 */
161#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_(-1,(n)) 163#define MHD_set_cur_thread_name_(n) MHD_set_thread_name_ (-1,(n))
162#endif /* _MSC_FULL_VER */ 164#endif /* _MSC_FULL_VER */
163#endif /* MHD_USE_W32_THREADS */ 165#endif /* MHD_USE_W32_THREADS */
164 166
@@ -184,21 +186,21 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
184 int res; 186 int res;
185 187
186 if (0 != stack_size) 188 if (0 != stack_size)
189 {
190 pthread_attr_t attr;
191 res = pthread_attr_init (&attr);
192 if (0 == res)
187 { 193 {
188 pthread_attr_t attr; 194 res = pthread_attr_setstacksize (&attr,
189 res = pthread_attr_init (&attr); 195 stack_size);
190 if (0 == res) 196 if (0 == res)
191 { 197 res = pthread_create (&(thread->handle),
192 res = pthread_attr_setstacksize (&attr, 198 &attr,
193 stack_size); 199 start_routine,
194 if (0 == res) 200 arg);
195 res = pthread_create (&(thread->handle), 201 pthread_attr_destroy (&attr);
196 &attr,
197 start_routine,
198 arg);
199 pthread_attr_destroy (&attr);
200 }
201 } 202 }
203 }
202 else 204 else
203 res = pthread_create (&(thread->handle), 205 res = pthread_create (&(thread->handle),
204 NULL, 206 NULL,
@@ -208,28 +210,28 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
208 if (0 != res) 210 if (0 != res)
209 errno = res; 211 errno = res;
210 212
211 return !res; 213 return ! res;
212#elif defined(MHD_USE_W32_THREADS) 214#elif defined(MHD_USE_W32_THREADS)
213#if SIZE_MAX != UINT_MAX 215#if SIZE_MAX != UINT_MAX
214 if (stack_size > UINT_MAX) 216 if (stack_size > UINT_MAX)
215 { 217 {
216 errno = EINVAL; 218 errno = EINVAL;
217 return 0; 219 return 0;
218 } 220 }
219#endif /* SIZE_MAX != UINT_MAX */ 221#endif /* SIZE_MAX != UINT_MAX */
220 222
221 thread->handle = (MHD_thread_handle_) 223 thread->handle = (MHD_thread_handle_)
222 _beginthreadex (NULL, 224 _beginthreadex (NULL,
223 (unsigned int) stack_size, 225 (unsigned int) stack_size,
224 start_routine, 226 start_routine,
225 arg, 227 arg,
226 0, 228 0,
227 NULL); 229 NULL);
228 230
229 if ((MHD_thread_handle_)-1 == thread->handle) 231 if ((MHD_thread_handle_) - 1 == thread->handle)
230 return 0; 232 return 0;
231 233
232 return !0; 234 return ! 0;
233#endif 235#endif
234} 236}
235 237
@@ -258,21 +260,21 @@ struct MHD_named_helper_param_
258static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ 260static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
259named_thread_starter (void *data) 261named_thread_starter (void *data)
260{ 262{
261 struct MHD_named_helper_param_ * const param = 263 struct MHD_named_helper_param_ *const param =
262 (struct MHD_named_helper_param_ *) data; 264 (struct MHD_named_helper_param_ *) data;
263 void * arg; 265 void *arg;
264 MHD_THREAD_START_ROUTINE_ thr_func; 266 MHD_THREAD_START_ROUTINE_ thr_func;
265 267
266 if (NULL == data) 268 if (NULL == data)
267 return (MHD_THRD_RTRN_TYPE_)0; 269 return (MHD_THRD_RTRN_TYPE_) 0;
268 270
269 MHD_set_cur_thread_name_ (param->name); 271 MHD_set_cur_thread_name_ (param->name);
270 272
271 arg = param->arg; 273 arg = param->arg;
272 thr_func = param->start_routine; 274 thr_func = param->start_routine;
273 free(data); 275 free (data);
274 276
275 return thr_func(arg); 277 return thr_func (arg);
276} 278}
277#endif /* ! MHD_USE_THREAD_ATTR_SETNAME */ 279#endif /* ! MHD_USE_THREAD_ATTR_SETNAME */
278 280
@@ -289,7 +291,7 @@ named_thread_starter (void *data)
289 */ 291 */
290int 292int
291MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread, 293MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
292 const char* thread_name, 294 const char*thread_name,
293 size_t stack_size, 295 size_t stack_size,
294 MHD_THREAD_START_ROUTINE_ start_routine, 296 MHD_THREAD_START_ROUTINE_ start_routine,
295 void *arg) 297 void *arg)
@@ -300,41 +302,41 @@ MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
300 302
301 res = pthread_attr_init (&attr); 303 res = pthread_attr_init (&attr);
302 if (0 == res) 304 if (0 == res)
303 { 305 {
304#if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) 306#if defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD)
305 /* NetBSD use 3 arguments: second argument is string in printf-like format, 307 /* NetBSD use 3 arguments: second argument is string in printf-like format,
306 * third argument is single argument for printf; 308 * third argument is single argument for printf;
307 * OSF1 use 3 arguments too, but last one always must be zero (NULL). 309 * OSF1 use 3 arguments too, but last one always must be zero (NULL).
308 * MHD doesn't use '%' in thread names, so both form are used in same way. 310 * MHD doesn't use '%' in thread names, so both form are used in same way.
309 */ 311 */
310 res = pthread_attr_setname_np (&attr, thread_name, 0); 312 res = pthread_attr_setname_np (&attr, thread_name, 0);
311#elif defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI) 313#elif defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
312 res = pthread_attr_setname_np (&attr, thread_name); 314 res = pthread_attr_setname_np (&attr, thread_name);
313#else 315#else
314#error No pthread_attr_setname_np() function. 316#error No pthread_attr_setname_np() function.
315#endif 317#endif
316 if (res == 0 && 0 != stack_size) 318 if ((res == 0) &&(0 != stack_size) )
317 res = pthread_attr_setstacksize (&attr, 319 res = pthread_attr_setstacksize (&attr,
318 stack_size); 320 stack_size);
319 if (0 == res) 321 if (0 == res)
320 res = pthread_create (&(thread->handle), 322 res = pthread_create (&(thread->handle),
321 &attr, 323 &attr,
322 start_routine, 324 start_routine,
323 arg); 325 arg);
324 pthread_attr_destroy (&attr); 326 pthread_attr_destroy (&attr);
325 } 327 }
326 if (0 != res) 328 if (0 != res)
327 errno = res; 329 errno = res;
328 330
329 return !res; 331 return ! res;
330#else /* ! MHD_USE_THREAD_ATTR_SETNAME */ 332#else /* ! MHD_USE_THREAD_ATTR_SETNAME */
331 struct MHD_named_helper_param_ *param; 333 struct MHD_named_helper_param_ *param;
332 334
333 if (NULL == thread_name) 335 if (NULL == thread_name)
334 { 336 {
335 errno = EINVAL; 337 errno = EINVAL;
336 return 0; 338 return 0;
337 } 339 }
338 340
339 param = malloc (sizeof (struct MHD_named_helper_param_)); 341 param = malloc (sizeof (struct MHD_named_helper_param_));
340 if (NULL == param) 342 if (NULL == param)
@@ -347,16 +349,16 @@ MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
347 /* Set thread name in thread itself to avoid problems with 349 /* Set thread name in thread itself to avoid problems with
348 * threads which terminated before name is set in other thread. 350 * threads which terminated before name is set in other thread.
349 */ 351 */
350 if (! MHD_create_thread_(thread, 352 if (! MHD_create_thread_ (thread,
351 stack_size, 353 stack_size,
352 &named_thread_starter, 354 &named_thread_starter,
353 (void*)param)) 355 (void*) param))
354 { 356 {
355 free (param); 357 free (param);
356 return 0; 358 return 0;
357 } 359 }
358 360
359 return !0; 361 return ! 0;
360#endif /* ! MHD_USE_THREAD_ATTR_SETNAME */ 362#endif /* ! MHD_USE_THREAD_ATTR_SETNAME */
361} 363}
362 364
diff --git a/src/lib/mhd_threads.h b/src/lib/mhd_threads.h
index 6d69b9ed..79520d53 100644
--- a/src/lib/mhd_threads.h
+++ b/src/lib/mhd_threads.h
@@ -58,23 +58,26 @@
58 58
59#ifndef MHD_NO_THREAD_NAMES 59#ifndef MHD_NO_THREAD_NAMES
60# if defined(MHD_USE_POSIX_THREADS) 60# if defined(MHD_USE_POSIX_THREADS)
61# if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) || \ 61# if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || \
62 defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) || defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) || \ 62 defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) || \
63 defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI) 63 defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) || \
64 defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) || \
65 defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || \
66 defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
64# define MHD_USE_THREAD_NAME_ 67# define MHD_USE_THREAD_NAME_
65# endif /* HAVE_PTHREAD_SETNAME_NP */ 68# endif /* HAVE_PTHREAD_SETNAME_NP */
66# elif defined(MHD_USE_W32_THREADS) 69# elif defined(MHD_USE_W32_THREADS)
67# ifdef _MSC_FULL_VER 70# ifdef _MSC_FULL_VER
68 /* Thread names only available with VC compiler */ 71/* Thread names only available with VC compiler */
69# define MHD_USE_THREAD_NAME_ 72# define MHD_USE_THREAD_NAME_
70# endif /* _MSC_FULL_VER */ 73# endif /* _MSC_FULL_VER */
71# endif 74# endif
72#endif 75#endif
73 76
74#if defined(MHD_USE_POSIX_THREADS) 77#if defined(MHD_USE_POSIX_THREADS)
75 typedef pthread_t MHD_thread_handle_; 78typedef pthread_t MHD_thread_handle_;
76#elif defined(MHD_USE_W32_THREADS) 79#elif defined(MHD_USE_W32_THREADS)
77 typedef HANDLE MHD_thread_handle_; 80typedef HANDLE MHD_thread_handle_;
78#endif 81#endif
79 82
80#if defined(MHD_USE_POSIX_THREADS) 83#if defined(MHD_USE_POSIX_THREADS)
@@ -86,9 +89,9 @@
86#endif 89#endif
87 90
88#if defined(MHD_USE_POSIX_THREADS) 91#if defined(MHD_USE_POSIX_THREADS)
89 typedef pthread_t MHD_thread_ID_; 92typedef pthread_t MHD_thread_ID_;
90#elif defined(MHD_USE_W32_THREADS) 93#elif defined(MHD_USE_W32_THREADS)
91 typedef DWORD MHD_thread_ID_; 94typedef DWORD MHD_thread_ID_;
92#endif 95#endif
93 96
94/* Depending on implementation, pthread_create() MAY set thread ID into 97/* Depending on implementation, pthread_create() MAY set thread ID into
@@ -100,27 +103,27 @@
100 * to save some resources. */ 103 * to save some resources. */
101#if defined(MHD_USE_POSIX_THREADS) 104#if defined(MHD_USE_POSIX_THREADS)
102# ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD 105# ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
103 union _MHD_thread_handle_ID_ 106union _MHD_thread_handle_ID_
104 { 107{
105 MHD_thread_handle_ handle; /**< To be used in other threads */ 108 MHD_thread_handle_ handle; /**< To be used in other threads */
106 MHD_thread_ID_ ID; /**< To be used in thread itself */ 109 MHD_thread_ID_ ID; /**< To be used in thread itself */
107 }; 110};
108 typedef union _MHD_thread_handle_ID_ MHD_thread_handle_ID_; 111typedef union _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
109# else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ 112# else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
110 struct _MHD_thread_handle_ID_ 113struct _MHD_thread_handle_ID_
111 { 114{
112 MHD_thread_handle_ handle; /**< To be used in other threads */ 115 MHD_thread_handle_ handle; /**< To be used in other threads */
113 MHD_thread_ID_ ID; /**< To be used in thread itself */ 116 MHD_thread_ID_ ID; /**< To be used in thread itself */
114 }; 117};
115 typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_; 118typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
116# endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ 119# endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
117#elif defined(MHD_USE_W32_THREADS) 120#elif defined(MHD_USE_W32_THREADS)
118 struct _MHD_thread_handle_ID_ 121struct _MHD_thread_handle_ID_
119 { 122{
120 MHD_thread_handle_ handle; /**< To be used in other threads */ 123 MHD_thread_handle_ handle; /**< To be used in other threads */
121 MHD_thread_ID_ ID; /**< To be used in thread itself */ 124 MHD_thread_ID_ ID; /**< To be used in thread itself */
122 }; 125};
123 typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_; 126typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
124#endif 127#endif
125 128
126#if defined(MHD_USE_POSIX_THREADS) 129#if defined(MHD_USE_POSIX_THREADS)
@@ -129,14 +132,17 @@
129 * @param thread handle to watch 132 * @param thread handle to watch
130 * @return nonzero on success, zero otherwise 133 * @return nonzero on success, zero otherwise
131 */ 134 */
132#define MHD_join_thread_(thread) (!pthread_join((thread), NULL)) 135#define MHD_join_thread_(thread) (! pthread_join ((thread), NULL))
133#elif defined(MHD_USE_W32_THREADS) 136#elif defined(MHD_USE_W32_THREADS)
134/** 137/**
135 * Wait until specified thread is ended and free thread handle on success. 138 * Wait until specified thread is ended and free thread handle on success.
136 * @param thread handle to watch 139 * @param thread handle to watch
137 * @return nonzero on success, zero otherwise 140 * @return nonzero on success, zero otherwise
138 */ 141 */
139#define MHD_join_thread_(thread) (WAIT_OBJECT_0 == WaitForSingleObject((thread), INFINITE) ? (CloseHandle((thread)), !0) : 0) 142#define MHD_join_thread_(thread) (WAIT_OBJECT_0 == WaitForSingleObject ( \
143 (thread), INFINITE) ? (CloseHandle ( \
144 (thread)), ! 0) : \
145 0)
140#endif 146#endif
141 147
142#if defined(MHD_USE_POSIX_THREADS) 148#if defined(MHD_USE_POSIX_THREADS)
@@ -145,14 +151,14 @@
145 * @param ID thread ID to match 151 * @param ID thread ID to match
146 * @return nonzero on match, zero otherwise 152 * @return nonzero on match, zero otherwise
147 */ 153 */
148#define MHD_thread_ID_match_current_(ID) (pthread_equal((ID), pthread_self())) 154#define MHD_thread_ID_match_current_(ID) (pthread_equal ((ID), pthread_self ()))
149#elif defined(MHD_USE_W32_THREADS) 155#elif defined(MHD_USE_W32_THREADS)
150/** 156/**
151 * Check whether provided thread ID match current thread. 157 * Check whether provided thread ID match current thread.
152 * @param ID thread ID to match 158 * @param ID thread ID to match
153 * @return nonzero on match, zero otherwise 159 * @return nonzero on match, zero otherwise
154 */ 160 */
155#define MHD_thread_ID_match_current_(ID) (GetCurrentThreadId() == (ID)) 161#define MHD_thread_ID_match_current_(ID) (GetCurrentThreadId () == (ID))
156#endif 162#endif
157 163
158#if defined(MHD_USE_POSIX_THREADS) 164#if defined(MHD_USE_POSIX_THREADS)
@@ -161,20 +167,22 @@
161 * Initialise thread ID. 167 * Initialise thread ID.
162 * @param thread_handle_ID_ptr pointer to thread handle-ID 168 * @param thread_handle_ID_ptr pointer to thread handle-ID
163 */ 169 */
164#define MHD_thread_init_(thread_handle_ID_ptr) (void)0 170#define MHD_thread_init_(thread_handle_ID_ptr) (void) 0
165# else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ 171# else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
166/** 172/**
167 * Initialise thread ID. 173 * Initialise thread ID.
168 * @param thread_handle_ID_ptr pointer to thread handle-ID 174 * @param thread_handle_ID_ptr pointer to thread handle-ID
169 */ 175 */
170#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID=pthread_self()) 176#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID = \
177 pthread_self ())
171# endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */ 178# endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
172#elif defined(MHD_USE_W32_THREADS) 179#elif defined(MHD_USE_W32_THREADS)
173/** 180/**
174 * Initialise thread ID. 181 * Initialise thread ID.
175 * @param thread_handle_ID_ptr pointer to thread handle-ID 182 * @param thread_handle_ID_ptr pointer to thread handle-ID
176 */ 183 */
177#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID=GetCurrentThreadId()) 184#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID = \
185 GetCurrentThreadId ())
178#endif 186#endif
179 187
180/** 188/**
@@ -205,7 +213,7 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
205 void *arg); 213 void *arg);
206 214
207#ifndef MHD_USE_THREAD_NAME_ 215#ifndef MHD_USE_THREAD_NAME_
208#define MHD_create_named_thread_(t,n,s,r,a) MHD_create_thread_((t),(s),(r),(a)) 216#define MHD_create_named_thread_(t,n,s,r,a) MHD_create_thread_ ((t),(s),(r),(a))
209#else /* MHD_USE_THREAD_NAME_ */ 217#else /* MHD_USE_THREAD_NAME_ */
210/** 218/**
211 * Create a named thread and set the attributes according to our options. 219 * Create a named thread and set the attributes according to our options.
@@ -219,7 +227,7 @@ MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
219 */ 227 */
220int 228int
221MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread, 229MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
222 const char* thread_name, 230 const char*thread_name,
223 size_t stack_size, 231 size_t stack_size,
224 MHD_THREAD_START_ROUTINE_ start_routine, 232 MHD_THREAD_START_ROUTINE_ start_routine,
225 void *arg); 233 void *arg);
diff --git a/src/lib/reason_phrase.c b/src/lib/reason_phrase.c
index 97ace0a3..e3692837 100644
--- a/src/lib/reason_phrase.c
+++ b/src/lib/reason_phrase.c
@@ -27,7 +27,7 @@
27#include "internal.h" 27#include "internal.h"
28 28
29#ifndef NULL 29#ifndef NULL
30#define NULL ((void*)0) 30#define NULL ((void*) 0)
31#endif 31#endif
32 32
33static const char *const invalid_hundred[] = { 33static const char *const invalid_hundred[] = {
diff --git a/src/lib/request.c b/src/lib/request.c
index 02cce55c..5b932bfa 100644
--- a/src/lib/request.c
+++ b/src/lib/request.c
@@ -40,9 +40,9 @@
40 */ 40 */
41unsigned int 41unsigned int
42MHD_request_get_values (struct MHD_Request *request, 42MHD_request_get_values (struct MHD_Request *request,
43 enum MHD_ValueKind kind, 43 enum MHD_ValueKind kind,
44 MHD_KeyValueIterator iterator, 44 MHD_KeyValueIterator iterator,
45 void *iterator_cls) 45 void *iterator_cls)
46{ 46{
47 int ret; 47 int ret;
48 struct MHD_HTTP_Header *pos; 48 struct MHD_HTTP_Header *pos;
@@ -51,18 +51,18 @@ MHD_request_get_values (struct MHD_Request *request,
51 for (pos = request->headers_received; 51 for (pos = request->headers_received;
52 NULL != pos; 52 NULL != pos;
53 pos = pos->next) 53 pos = pos->next)
54 {
55 if (0 != (pos->kind & kind))
54 { 56 {
55 if (0 != (pos->kind & kind)) 57 ret++;
56 { 58 if ( (NULL != iterator) &&
57 ret++; 59 (MHD_YES != iterator (iterator_cls,
58 if ( (NULL != iterator) && 60 pos->kind,
59 (MHD_YES != iterator (iterator_cls, 61 pos->header,
60 pos->kind, 62 pos->value)) )
61 pos->header, 63 return ret;
62 pos->value)) )
63 return ret;
64 }
65 } 64 }
65 }
66 return ret; 66 return ret;
67} 67}
68 68
@@ -94,9 +94,9 @@ MHD_request_get_values (struct MHD_Request *request,
94 */ 94 */
95enum MHD_Bool 95enum MHD_Bool
96MHD_request_set_value (struct MHD_Request *request, 96MHD_request_set_value (struct MHD_Request *request,
97 enum MHD_ValueKind kind, 97 enum MHD_ValueKind kind,
98 const char *key, 98 const char *key,
99 const char *value) 99 const char *value)
100{ 100{
101 struct MHD_HTTP_Header *pos; 101 struct MHD_HTTP_Header *pos;
102 102
@@ -111,15 +111,15 @@ MHD_request_set_value (struct MHD_Request *request,
111 pos->next = NULL; 111 pos->next = NULL;
112 /* append 'pos' to the linked list of headers */ 112 /* append 'pos' to the linked list of headers */
113 if (NULL == request->headers_received_tail) 113 if (NULL == request->headers_received_tail)
114 { 114 {
115 request->headers_received = pos; 115 request->headers_received = pos;
116 request->headers_received_tail = pos; 116 request->headers_received_tail = pos;
117 } 117 }
118 else 118 else
119 { 119 {
120 request->headers_received_tail->next = pos; 120 request->headers_received_tail->next = pos;
121 request->headers_received_tail = pos; 121 request->headers_received_tail = pos;
122 } 122 }
123 return MHD_YES; 123 return MHD_YES;
124} 124}
125 125
@@ -136,27 +136,25 @@ MHD_request_set_value (struct MHD_Request *request,
136 */ 136 */
137const char * 137const char *
138MHD_request_lookup_value (struct MHD_Request *request, 138MHD_request_lookup_value (struct MHD_Request *request,
139 enum MHD_ValueKind kind, 139 enum MHD_ValueKind kind,
140 const char *key) 140 const char *key)
141{ 141{
142 struct MHD_HTTP_Header *pos; 142 struct MHD_HTTP_Header *pos;
143 143
144 for (pos = request->headers_received; 144 for (pos = request->headers_received;
145 NULL != pos; 145 NULL != pos;
146 pos = pos->next) 146 pos = pos->next)
147 { 147 {
148 if ((0 != (pos->kind & kind)) && 148 if ((0 != (pos->kind & kind)) &&
149 ( (key == pos->header) || 149 ( (key == pos->header) ||
150 ( (NULL != pos->header) && 150 ( (NULL != pos->header) &&
151 (NULL != key) && 151 (NULL != key) &&
152 (MHD_str_equal_caseless_(key, 152 (MHD_str_equal_caseless_ (key,
153 pos->header))))) 153 pos->header)))))
154 return pos->value; 154 return pos->value;
155 } 155 }
156 return NULL; 156 return NULL;
157} 157}
158 158
159 159
160/* end of request.c */ 160/* end of request.c */
161
162
diff --git a/src/lib/request_info.c b/src/lib/request_info.c
index 5f481d98..51aae075 100644
--- a/src/lib/request_info.c
+++ b/src/lib/request_info.c
@@ -42,11 +42,11 @@
42 */ 42 */
43enum MHD_Bool 43enum MHD_Bool
44MHD_request_get_information_sz (struct MHD_Request *request, 44MHD_request_get_information_sz (struct MHD_Request *request,
45 enum MHD_RequestInformationType info_type, 45 enum MHD_RequestInformationType info_type,
46 union MHD_RequestInformation *return_value, 46 union MHD_RequestInformation *return_value,
47 size_t return_value_size) 47 size_t return_value_size)
48{ 48{
49#define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \ 49#define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \
50 return MHD_NO 50 return MHD_NO
51 51
52 switch (info_type) 52 switch (info_type)
@@ -70,8 +70,8 @@ MHD_request_get_information_sz (struct MHD_Request *request,
70 case MHD_REQUEST_INFORMATION_HEADER_SIZE: 70 case MHD_REQUEST_INFORMATION_HEADER_SIZE:
71 CHECK_SIZE (size_t); 71 CHECK_SIZE (size_t);
72 if ( (MHD_REQUEST_HEADERS_RECEIVED > request->state) || 72 if ( (MHD_REQUEST_HEADERS_RECEIVED > request->state) ||
73 (MHD_REQUEST_CLOSED == request->state) ) 73 (MHD_REQUEST_CLOSED == request->state) )
74 return MHD_NO; /* invalid, too early! */ 74 return MHD_NO; /* invalid, too early! */
75 return_value->header_size = request->header_size; 75 return_value->header_size = request->header_size;
76 return MHD_YES; 76 return MHD_YES;
77 77
diff --git a/src/lib/request_resume.c b/src/lib/request_resume.c
index a69107b9..be513f53 100644
--- a/src/lib/request_resume.c
+++ b/src/lib/request_resume.c
@@ -45,21 +45,23 @@ MHD_request_resume (struct MHD_Request *request)
45 struct MHD_Daemon *daemon = request->daemon; 45 struct MHD_Daemon *daemon = request->daemon;
46 46
47 if (daemon->disallow_suspend_resume) 47 if (daemon->disallow_suspend_resume)
48 MHD_PANIC (_("Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n")); 48 MHD_PANIC (_ (
49 "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
49 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 50 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
50 request->connection->resuming = true; 51 request->connection->resuming = true;
51 daemon->resuming = true; 52 daemon->resuming = true;
52 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 53 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
53 if ( (MHD_ITC_IS_VALID_(daemon->itc)) && 54 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
54 (! MHD_itc_activate_ (daemon->itc, 55 (! MHD_itc_activate_ (daemon->itc,
55 "r")) ) 56 "r")) )
56 { 57 {
57#ifdef HAVE_MESSAGES 58#ifdef HAVE_MESSAGES
58 MHD_DLOG (daemon, 59 MHD_DLOG (daemon,
59 MHD_SC_ITC_USE_FAILED, 60 MHD_SC_ITC_USE_FAILED,
60 _("Failed to signal resume via inter-thread communication channel.")); 61 _ (
62 "Failed to signal resume via inter-thread communication channel."));
61#endif 63#endif
62 } 64 }
63} 65}
64 66
65 67
@@ -80,115 +82,118 @@ MHD_resume_suspended_connections_ (struct MHD_Daemon *daemon)
80 struct MHD_Connection *pos; 82 struct MHD_Connection *pos;
81 struct MHD_Connection *prev = NULL; 83 struct MHD_Connection *prev = NULL;
82 bool ret; 84 bool ret;
83 const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode); 85 const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION ==
86 daemon->threading_mode);
84 87
85 mhd_assert (NULL == daemon->worker_pool); 88 mhd_assert (NULL == daemon->worker_pool);
86 ret = false; 89 ret = false;
87 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 90 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
88 91
89 if (daemon->resuming) 92 if (daemon->resuming)
90 { 93 {
91 prev = daemon->suspended_connections_tail; 94 prev = daemon->suspended_connections_tail;
92 /* During shutdown check for resuming is forced. */ 95 /* During shutdown check for resuming is forced. */
93 mhd_assert((NULL != prev) || (daemon->shutdown)); 96 mhd_assert ((NULL != prev) || (daemon->shutdown));
94 } 97 }
95 98
96 daemon->resuming = false; 99 daemon->resuming = false;
97 100
98 while (NULL != (pos = prev)) 101 while (NULL != (pos = prev))
99 { 102 {
100#ifdef UPGRADE_SUPPORT 103#ifdef UPGRADE_SUPPORT
101 struct MHD_UpgradeResponseHandle * const urh = pos->request.urh; 104 struct MHD_UpgradeResponseHandle *const urh = pos->request.urh;
102#else /* ! UPGRADE_SUPPORT */ 105#else /* ! UPGRADE_SUPPORT */
103 static const void * const urh = NULL; 106 static const void *const urh = NULL;
104#endif /* ! UPGRADE_SUPPORT */ 107#endif /* ! UPGRADE_SUPPORT */
105 prev = pos->prev; 108 prev = pos->prev;
106 if ( (! pos->resuming) 109 if ( (! pos->resuming)
107#ifdef UPGRADE_SUPPORT 110#ifdef UPGRADE_SUPPORT
108 || ( (NULL != urh) && 111 || ( (NULL != urh) &&
109 ( (! urh->was_closed) || 112 ( (! urh->was_closed) ||
110 (! urh->clean_ready) ) ) 113 (! urh->clean_ready) ) )
111#endif /* UPGRADE_SUPPORT */ 114#endif /* UPGRADE_SUPPORT */
112 ) 115 )
113 continue; 116 continue;
114 ret = true; 117 ret = true;
115 mhd_assert (pos->suspended); 118 mhd_assert (pos->suspended);
116 DLL_remove (daemon->suspended_connections_head, 119 DLL_remove (daemon->suspended_connections_head,
117 daemon->suspended_connections_tail, 120 daemon->suspended_connections_tail,
121 pos);
122 pos->suspended = false;
123 if (NULL == urh)
124 {
125 DLL_insert (daemon->connections_head,
126 daemon->connections_tail,
118 pos); 127 pos);
119 pos->suspended = false; 128 if (! used_thr_p_c)
120 if (NULL == urh) 129 {
121 { 130 /* Reset timeout timer on resume. */
122 DLL_insert (daemon->connections_head, 131 if (0 != pos->connection_timeout)
123 daemon->connections_tail, 132 pos->last_activity = MHD_monotonic_sec_counter ();
124 pos); 133
125 if (! used_thr_p_c) 134 if (pos->connection_timeout == daemon->connection_default_timeout)
126 { 135 XDLL_insert (daemon->normal_timeout_head,
127 /* Reset timeout timer on resume. */ 136 daemon->normal_timeout_tail,
128 if (0 != pos->connection_timeout) 137 pos);
129 pos->last_activity = MHD_monotonic_sec_counter(); 138 else
130 139 XDLL_insert (daemon->manual_timeout_head,
131 if (pos->connection_timeout == daemon->connection_default_timeout) 140 daemon->manual_timeout_tail,
132 XDLL_insert (daemon->normal_timeout_head, 141 pos);
133 daemon->normal_timeout_tail, 142 }
134 pos);
135 else
136 XDLL_insert (daemon->manual_timeout_head,
137 daemon->manual_timeout_tail,
138 pos);
139 }
140#ifdef EPOLL_SUPPORT 143#ifdef EPOLL_SUPPORT
141 if (MHD_ELS_EPOLL == daemon->event_loop_syscall) 144 if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
142 { 145 {
143 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 146 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
144 MHD_PANIC ("Resumed connection was already in EREADY set\n"); 147 MHD_PANIC ("Resumed connection was already in EREADY set\n");
145 /* we always mark resumed connections as ready, as we 148 /* we always mark resumed connections as ready, as we
146 might have missed the edge poll event during suspension */ 149 might have missed the edge poll event during suspension */
147 EDLL_insert (daemon->eready_head, 150 EDLL_insert (daemon->eready_head,
148 daemon->eready_tail, 151 daemon->eready_tail,
149 pos); 152 pos);
150 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL | \ 153 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL \
151 MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; 154 | MHD_EPOLL_STATE_READ_READY
152 pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED; 155 | MHD_EPOLL_STATE_WRITE_READY;
153 } 156 pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
157 }
154#endif 158#endif
155 } 159 }
156#ifdef UPGRADE_SUPPORT 160#ifdef UPGRADE_SUPPORT
157 else 161 else
158 { 162 {
159 struct MHD_Response *response = pos->request.response; 163 struct MHD_Response *response = pos->request.response;
160 164
161 /* Data forwarding was finished (for TLS connections) AND 165 /* Data forwarding was finished (for TLS connections) AND
162 * application was closed upgraded connection. 166 * application was closed upgraded connection.
163 * Insert connection into cleanup list. */ 167 * Insert connection into cleanup list. */
164 if ( (NULL != response) && 168 if ( (NULL != response) &&
165 (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) && 169 (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) &&
166 (NULL != response->termination_cb) ) 170 (NULL != response->termination_cb) )
167 response->termination_cb (response->termination_cb_cls, 171 response->termination_cb (response->termination_cb_cls,
168 MHD_REQUEST_TERMINATED_COMPLETED_OK, 172 MHD_REQUEST_TERMINATED_COMPLETED_OK,
169 &pos->request.client_context); 173 &pos->request.client_context);
170 DLL_insert (daemon->cleanup_head, 174 DLL_insert (daemon->cleanup_head,
171 daemon->cleanup_tail, 175 daemon->cleanup_tail,
172 pos); 176 pos);
173 177
174 }
175#endif /* UPGRADE_SUPPORT */
176 pos->resuming = false;
177 } 178 }
179#endif /* UPGRADE_SUPPORT */
180 pos->resuming = false;
181 }
178 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 182 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
179 if ( (used_thr_p_c) && 183 if ( (used_thr_p_c) &&
180 (ret) ) 184 (ret) )
181 { /* Wake up suspended connections. */ 185 { /* Wake up suspended connections. */
182 if (! MHD_itc_activate_(daemon->itc, 186 if (! MHD_itc_activate_ (daemon->itc,
183 "w")) 187 "w"))
184 { 188 {
185#ifdef HAVE_MESSAGES 189#ifdef HAVE_MESSAGES
186 MHD_DLOG (daemon, 190 MHD_DLOG (daemon,
187 MHD_SC_ITC_USE_FAILED, 191 MHD_SC_ITC_USE_FAILED,
188 _("Failed to signal resume of connection via inter-thread communication channel.")); 192 _ (
193 "Failed to signal resume of connection via inter-thread communication channel."));
189#endif 194#endif
190 }
191 } 195 }
196 }
192 return ret; 197 return ret;
193} 198}
194 199
diff --git a/src/lib/request_resume.h b/src/lib/request_resume.h
index d23ff9e8..dad43467 100644
--- a/src/lib/request_resume.h
+++ b/src/lib/request_resume.h
@@ -38,6 +38,6 @@
38 */ 38 */
39bool 39bool
40MHD_resume_suspended_connections_ (struct MHD_Daemon *daemon) 40MHD_resume_suspended_connections_ (struct MHD_Daemon *daemon)
41 MHD_NONNULL(1); 41MHD_NONNULL (1);
42 42
43#endif 43#endif
diff --git a/src/lib/response.c b/src/lib/response.c
index ff23c7fd..47dd98d6 100644
--- a/src/lib/response.c
+++ b/src/lib/response.c
@@ -38,9 +38,9 @@
38 */ 38 */
39static bool 39static bool
40add_response_entry (struct MHD_Response *response, 40add_response_entry (struct MHD_Response *response,
41 enum MHD_ValueKind kind, 41 enum MHD_ValueKind kind,
42 const char *header, 42 const char *header,
43 const char *content) 43 const char *content)
44{ 44{
45 struct MHD_HTTP_Header *hdr; 45 struct MHD_HTTP_Header *hdr;
46 46
@@ -58,16 +58,16 @@ add_response_entry (struct MHD_Response *response,
58 if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header)))) 58 if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header))))
59 return false; 59 return false;
60 if (NULL == (hdr->header = strdup (header))) 60 if (NULL == (hdr->header = strdup (header)))
61 { 61 {
62 free (hdr); 62 free (hdr);
63 return false; 63 return false;
64 } 64 }
65 if (NULL == (hdr->value = strdup (content))) 65 if (NULL == (hdr->value = strdup (content)))
66 { 66 {
67 free (hdr->header); 67 free (hdr->header);
68 free (hdr); 68 free (hdr);
69 return false; 69 return false;
70 } 70 }
71 hdr->kind = kind; 71 hdr->kind = kind;
72 hdr->next = response->first_header; 72 hdr->next = response->first_header;
73 response->first_header = hdr; 73 response->first_header = hdr;
@@ -91,22 +91,22 @@ MHD_response_queue_for_destroy (struct MHD_Response *response)
91 91
92 MHD_mutex_lock_chk_ (&response->mutex); 92 MHD_mutex_lock_chk_ (&response->mutex);
93 if (0 != --(response->reference_count)) 93 if (0 != --(response->reference_count))
94 { 94 {
95 MHD_mutex_unlock_chk_ (&response->mutex); 95 MHD_mutex_unlock_chk_ (&response->mutex);
96 return; 96 return;
97 } 97 }
98 MHD_mutex_unlock_chk_ (&response->mutex); 98 MHD_mutex_unlock_chk_ (&response->mutex);
99 MHD_mutex_destroy_chk_ (&response->mutex); 99 MHD_mutex_destroy_chk_ (&response->mutex);
100 if (NULL != response->crfc) 100 if (NULL != response->crfc)
101 response->crfc (response->crc_cls); 101 response->crfc (response->crc_cls);
102 while (NULL != response->first_header) 102 while (NULL != response->first_header)
103 { 103 {
104 pos = response->first_header; 104 pos = response->first_header;
105 response->first_header = pos->next; 105 response->first_header = pos->next;
106 free (pos->header); 106 free (pos->header);
107 free (pos->value); 107 free (pos->value);
108 free (pos); 108 free (pos);
109 } 109 }
110 free (response); 110 free (response);
111} 111}
112 112
@@ -124,12 +124,12 @@ MHD_response_queue_for_destroy (struct MHD_Response *response)
124enum MHD_Bool 124enum MHD_Bool
125MHD_response_add_header (struct MHD_Response *response, 125MHD_response_add_header (struct MHD_Response *response,
126 const char *header, 126 const char *header,
127 const char *content) 127 const char *content)
128{ 128{
129 return add_response_entry (response, 129 return add_response_entry (response,
130 MHD_HEADER_KIND, 130 MHD_HEADER_KIND,
131 header, 131 header,
132 content) ? MHD_YES : MHD_NO; 132 content) ? MHD_YES : MHD_NO;
133} 133}
134 134
135 135
@@ -149,9 +149,9 @@ MHD_response_add_trailer (struct MHD_Response *response,
149 const char *content) 149 const char *content)
150{ 150{
151 return add_response_entry (response, 151 return add_response_entry (response,
152 MHD_FOOTER_KIND, 152 MHD_FOOTER_KIND,
153 footer, 153 footer,
154 content) ? MHD_YES : MHD_NO; 154 content) ? MHD_YES : MHD_NO;
155} 155}
156 156
157 157
@@ -167,7 +167,7 @@ MHD_response_add_trailer (struct MHD_Response *response,
167enum MHD_Bool 167enum MHD_Bool
168MHD_response_del_header (struct MHD_Response *response, 168MHD_response_del_header (struct MHD_Response *response,
169 const char *header, 169 const char *header,
170 const char *content) 170 const char *content)
171{ 171{
172 struct MHD_HTTP_Header *pos; 172 struct MHD_HTTP_Header *pos;
173 struct MHD_HTTP_Header *prev; 173 struct MHD_HTTP_Header *prev;
@@ -175,24 +175,24 @@ MHD_response_del_header (struct MHD_Response *response,
175 prev = NULL; 175 prev = NULL;
176 pos = response->first_header; 176 pos = response->first_header;
177 while (NULL != pos) 177 while (NULL != pos)
178 {
179 if ((0 == strcmp (header,
180 pos->header)) &&
181 (0 == strcmp (content,
182 pos->value)))
178 { 183 {
179 if ((0 == strcmp (header, 184 free (pos->header);
180 pos->header)) && 185 free (pos->value);
181 (0 == strcmp (content, 186 if (NULL == prev)
182 pos->value))) 187 response->first_header = pos->next;
183 { 188 else
184 free (pos->header); 189 prev->next = pos->next;
185 free (pos->value); 190 free (pos);
186 if (NULL == prev) 191 return MHD_YES;
187 response->first_header = pos->next;
188 else
189 prev->next = pos->next;
190 free (pos);
191 return MHD_YES;
192 }
193 prev = pos;
194 pos = pos->next;
195 } 192 }
193 prev = pos;
194 pos = pos->next;
195 }
196 return MHD_NO; 196 return MHD_NO;
197} 197}
198 198
@@ -210,7 +210,7 @@ MHD_response_del_header (struct MHD_Response *response,
210unsigned int 210unsigned int
211MHD_response_get_headers (struct MHD_Response *response, 211MHD_response_get_headers (struct MHD_Response *response,
212 MHD_KeyValueIterator iterator, 212 MHD_KeyValueIterator iterator,
213 void *iterator_cls) 213 void *iterator_cls)
214{ 214{
215 unsigned int numHeaders = 0; 215 unsigned int numHeaders = 0;
216 struct MHD_HTTP_Header *pos; 216 struct MHD_HTTP_Header *pos;
@@ -218,15 +218,15 @@ MHD_response_get_headers (struct MHD_Response *response,
218 for (pos = response->first_header; 218 for (pos = response->first_header;
219 NULL != pos; 219 NULL != pos;
220 pos = pos->next) 220 pos = pos->next)
221 { 221 {
222 numHeaders++; 222 numHeaders++;
223 if ( (NULL != iterator) && 223 if ( (NULL != iterator) &&
224 (MHD_YES != iterator (iterator_cls, 224 (MHD_YES != iterator (iterator_cls,
225 pos->kind, 225 pos->kind,
226 pos->header, 226 pos->header,
227 pos->value)) ) 227 pos->value)) )
228 break; 228 break;
229 } 229 }
230 return numHeaders; 230 return numHeaders;
231} 231}
232 232
@@ -241,18 +241,18 @@ MHD_response_get_headers (struct MHD_Response *response,
241 */ 241 */
242const char * 242const char *
243MHD_response_get_header (struct MHD_Response *response, 243MHD_response_get_header (struct MHD_Response *response,
244 const char *key) 244 const char *key)
245{ 245{
246 struct MHD_HTTP_Header *pos; 246 struct MHD_HTTP_Header *pos;
247 247
248 for (pos = response->first_header; 248 for (pos = response->first_header;
249 NULL != pos; 249 NULL != pos;
250 pos = pos->next) 250 pos = pos->next)
251 { 251 {
252 if (MHD_str_equal_caseless_ (pos->header, 252 if (MHD_str_equal_caseless_ (pos->header,
253 key)) 253 key))
254 return pos->value; 254 return pos->value;
255 } 255 }
256 return NULL; 256 return NULL;
257} 257}
258 258
diff --git a/src/lib/response_for_upgrade.c b/src/lib/response_for_upgrade.c
index 0d843b8e..ef66b029 100644
--- a/src/lib/response_for_upgrade.c
+++ b/src/lib/response_for_upgrade.c
@@ -57,21 +57,21 @@
57 */ 57 */
58struct MHD_Response * 58struct MHD_Response *
59MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, 59MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
60 void *upgrade_handler_cls) 60 void *upgrade_handler_cls)
61{ 61{
62#ifdef UPGRADE_SUPPORT 62#ifdef UPGRADE_SUPPORT
63 struct MHD_Response *response; 63 struct MHD_Response *response;
64 64
65 mhd_assert (NULL != upgrade_handler); 65 mhd_assert (NULL != upgrade_handler);
66 response = MHD_calloc_ (1, 66 response = MHD_calloc_ (1,
67 sizeof (struct MHD_Response)); 67 sizeof (struct MHD_Response));
68 if (NULL == response) 68 if (NULL == response)
69 return NULL; 69 return NULL;
70 if (! MHD_mutex_init_ (&response->mutex)) 70 if (! MHD_mutex_init_ (&response->mutex))
71 { 71 {
72 free (response); 72 free (response);
73 return NULL; 73 return NULL;
74 } 74 }
75 response->upgrade_handler = upgrade_handler; 75 response->upgrade_handler = upgrade_handler;
76 response->upgrade_handler_cls = upgrade_handler_cls; 76 response->upgrade_handler_cls = upgrade_handler_cls;
77 response->status_code = MHD_HTTP_SWITCHING_PROTOCOLS; 77 response->status_code = MHD_HTTP_SWITCHING_PROTOCOLS;
@@ -81,10 +81,10 @@ MHD_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
81 MHD_response_add_header (response, 81 MHD_response_add_header (response,
82 MHD_HTTP_HEADER_CONNECTION, 82 MHD_HTTP_HEADER_CONNECTION,
83 "Upgrade")) 83 "Upgrade"))
84 { 84 {
85 MHD_response_queue_for_destroy (response); 85 MHD_response_queue_for_destroy (response);
86 return NULL; 86 return NULL;
87 } 87 }
88 return response; 88 return response;
89#else 89#else
90 return NULL; 90 return NULL;
diff --git a/src/lib/response_from_buffer.c b/src/lib/response_from_buffer.c
index a53537b0..a65a0298 100644
--- a/src/lib/response_from_buffer.c
+++ b/src/lib/response_from_buffer.c
@@ -39,44 +39,44 @@
39 */ 39 */
40struct MHD_Response * 40struct MHD_Response *
41MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc, 41MHD_response_from_buffer (enum MHD_HTTP_StatusCode sc,
42 size_t size, 42 size_t size,
43 void *buffer, 43 void *buffer,
44 enum MHD_ResponseMemoryMode mode) 44 enum MHD_ResponseMemoryMode mode)
45{ 45{
46 struct MHD_Response *response; 46 struct MHD_Response *response;
47 void *tmp; 47 void *tmp;
48 48
49 mhd_assert ( (NULL != buffer) || 49 mhd_assert ( (NULL != buffer) ||
50 (0 == size) ); 50 (0 == size) );
51 if (NULL == 51 if (NULL ==
52 (response = MHD_calloc_ (1, 52 (response = MHD_calloc_ (1,
53 sizeof (struct MHD_Response)))) 53 sizeof (struct MHD_Response))))
54 return NULL; 54 return NULL;
55 response->fd = -1; 55 response->fd = -1;
56 if (! MHD_mutex_init_ (&response->mutex)) 56 if (! MHD_mutex_init_ (&response->mutex))
57 { 57 {
58 free (response); 58 free (response);
59 return NULL; 59 return NULL;
60 } 60 }
61 if ( (MHD_RESPMEM_MUST_COPY == mode) && 61 if ( (MHD_RESPMEM_MUST_COPY == mode) &&
62 (size > 0) ) 62 (size > 0) )
63 {
64 if (NULL == (tmp = malloc (size)))
63 { 65 {
64 if (NULL == (tmp = malloc (size))) 66 MHD_mutex_destroy_chk_ (&response->mutex);
65 { 67 free (response);
66 MHD_mutex_destroy_chk_ (&response->mutex); 68 return NULL;
67 free (response);
68 return NULL;
69 }
70 memcpy (tmp,
71 buffer,
72 size);
73 buffer = tmp;
74 } 69 }
70 memcpy (tmp,
71 buffer,
72 size);
73 buffer = tmp;
74 }
75 if (MHD_RESPMEM_PERSISTENT != mode) 75 if (MHD_RESPMEM_PERSISTENT != mode)
76 { 76 {
77 response->crfc = &free; 77 response->crfc = &free;
78 response->crc_cls = buffer; 78 response->crc_cls = buffer;
79 } 79 }
80 response->status_code = sc; 80 response->status_code = sc;
81 response->reference_count = 1; 81 response->reference_count = 1;
82 response->total_size = size; 82 response->total_size = size;
diff --git a/src/lib/response_from_callback.c b/src/lib/response_from_callback.c
index 1fd65bf0..e00033ce 100644
--- a/src/lib/response_from_callback.c
+++ b/src/lib/response_from_callback.c
@@ -44,11 +44,11 @@
44 */ 44 */
45struct MHD_Response * 45struct MHD_Response *
46MHD_response_from_callback (enum MHD_HTTP_StatusCode sc, 46MHD_response_from_callback (enum MHD_HTTP_StatusCode sc,
47 uint64_t size, 47 uint64_t size,
48 size_t block_size, 48 size_t block_size,
49 MHD_ContentReaderCallback crc, 49 MHD_ContentReaderCallback crc,
50 void *crc_cls, 50 void *crc_cls,
51 MHD_ContentReaderFreeCallback crfc) 51 MHD_ContentReaderFreeCallback crfc)
52{ 52{
53 struct MHD_Response *response; 53 struct MHD_Response *response;
54 54
@@ -56,8 +56,8 @@ MHD_response_from_callback (enum MHD_HTTP_StatusCode sc,
56 mhd_assert (0 != block_size); 56 mhd_assert (0 != block_size);
57 if (NULL == 57 if (NULL ==
58 (response = MHD_calloc_ (1, 58 (response = MHD_calloc_ (1,
59 sizeof (struct MHD_Response) + 59 sizeof (struct MHD_Response)
60 block_size))) 60 + block_size)))
61 return NULL; 61 return NULL;
62 response->fd = -1; 62 response->fd = -1;
63 response->status_code = sc; 63 response->status_code = sc;
diff --git a/src/lib/response_from_fd.c b/src/lib/response_from_fd.c
index ac0a54d1..ffeb2b91 100644
--- a/src/lib/response_from_fd.c
+++ b/src/lib/response_from_fd.c
@@ -57,34 +57,34 @@ file_reader (void *cls,
57 size_t max) 57 size_t max)
58{ 58{
59 struct MHD_Response *response = cls; 59 struct MHD_Response *response = cls;
60#if !defined(_WIN32) || defined(__CYGWIN__) 60#if ! defined(_WIN32) || defined(__CYGWIN__)
61 ssize_t n; 61 ssize_t n;
62#else /* _WIN32 && !__CYGWIN__ */ 62#else /* _WIN32 && !__CYGWIN__ */
63 const HANDLE fh = (HANDLE) _get_osfhandle (response->fd); 63 const HANDLE fh = (HANDLE) _get_osfhandle (response->fd);
64#endif /* _WIN32 && !__CYGWIN__ */ 64#endif /* _WIN32 && !__CYGWIN__ */
65 const int64_t offset64 = (int64_t)(pos + response->fd_off); 65 const int64_t offset64 = (int64_t) (pos + response->fd_off);
66 66
67 if (offset64 < 0) 67 if (offset64 < 0)
68 return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */ 68 return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
69 69
70#if !defined(_WIN32) || defined(__CYGWIN__) 70#if ! defined(_WIN32) || defined(__CYGWIN__)
71 if (max > SSIZE_MAX) 71 if (max > SSIZE_MAX)
72 max = SSIZE_MAX; /* Clamp to maximum return value. */ 72 max = SSIZE_MAX; /* Clamp to maximum return value. */
73 73
74#if defined(HAVE_PREAD64) 74#if defined(HAVE_PREAD64)
75 n = pread64 (response->fd, 75 n = pread64 (response->fd,
76 buf, 76 buf,
77 max, 77 max,
78 offset64); 78 offset64);
79#elif defined(HAVE_PREAD) 79#elif defined(HAVE_PREAD)
80 if ( (sizeof(off_t) < sizeof (uint64_t)) && 80 if ( (sizeof(off_t) < sizeof (uint64_t)) &&
81 (offset64 > (uint64_t)INT32_MAX) ) 81 (offset64 > (uint64_t) INT32_MAX) )
82 return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */ 82 return MHD_CONTENT_READER_END_WITH_ERROR; /* Read at required position is not possible. */
83 83
84 n = pread (response->fd, 84 n = pread (response->fd,
85 buf, 85 buf,
86 max, 86 max,
87 (off_t) offset64); 87 (off_t) offset64);
88#else /* ! HAVE_PREAD */ 88#else /* ! HAVE_PREAD */
89#if defined(HAVE_LSEEK64) 89#if defined(HAVE_LSEEK64)
90 if (lseek64 (response->fd, 90 if (lseek64 (response->fd,
@@ -93,7 +93,7 @@ file_reader (void *cls,
93 return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */ 93 return MHD_CONTENT_READER_END_WITH_ERROR; /* can't seek to required position */
94#else /* ! HAVE_LSEEK64 */ 94#else /* ! HAVE_LSEEK64 */
95 if ( (sizeof(off_t) < sizeof (uint64_t)) && 95 if ( (sizeof(off_t) < sizeof (uint64_t)) &&
96 (offset64 > (uint64_t)INT32_MAX) ) 96 (offset64 > (uint64_t) INT32_MAX) )
97 return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */ 97 return MHD_CONTENT_READER_END_WITH_ERROR; /* seek to required position is not possible */
98 98
99 if (lseek (response->fd, 99 if (lseek (response->fd,
@@ -115,25 +115,25 @@ file_reader (void *cls,
115 if (INVALID_HANDLE_VALUE == fh) 115 if (INVALID_HANDLE_VALUE == fh)
116 return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */ 116 return MHD_CONTENT_READER_END_WITH_ERROR; /* Value of 'response->fd' is not valid. */
117 else 117 else
118 { 118 {
119 OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */ 119 OVERLAPPED f_ol = {0, 0, {{0, 0}}, 0}; /* Initialize to zero. */
120 ULARGE_INTEGER pos_uli; 120 ULARGE_INTEGER pos_uli;
121 DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max; 121 DWORD toRead = (max > INT32_MAX) ? INT32_MAX : (DWORD) max;
122 DWORD resRead; 122 DWORD resRead;
123 123
124 pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */ 124 pos_uli.QuadPart = (uint64_t) offset64; /* Simple transformation 64bit -> 2x32bit. */
125 f_ol.Offset = pos_uli.LowPart; 125 f_ol.Offset = pos_uli.LowPart;
126 f_ol.OffsetHigh = pos_uli.HighPart; 126 f_ol.OffsetHigh = pos_uli.HighPart;
127 if (! ReadFile (fh, 127 if (! ReadFile (fh,
128 (void*)buf, 128 (void*) buf,
129 toRead, 129 toRead,
130 &resRead, 130 &resRead,
131 &f_ol)) 131 &f_ol))
132 return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */ 132 return MHD_CONTENT_READER_END_WITH_ERROR; /* Read error. */
133 if (0 == resRead) 133 if (0 == resRead)
134 return MHD_CONTENT_READER_END_OF_STREAM; 134 return MHD_CONTENT_READER_END_OF_STREAM;
135 return (ssize_t) resRead; 135 return (ssize_t) resRead;
136 } 136 }
137#endif /* _WIN32 && !__CYGWIN__ */ 137#endif /* _WIN32 && !__CYGWIN__ */
138} 138}
139 139
@@ -174,18 +174,18 @@ free_callback (void *cls)
174 */ 174 */
175struct MHD_Response * 175struct MHD_Response *
176MHD_response_from_fd (enum MHD_HTTP_StatusCode sc, 176MHD_response_from_fd (enum MHD_HTTP_StatusCode sc,
177 int fd, 177 int fd,
178 uint64_t offset, 178 uint64_t offset,
179 uint64_t size) 179 uint64_t size)
180{ 180{
181 struct MHD_Response *response; 181 struct MHD_Response *response;
182 182
183 mhd_assert (-1 != fd); 183 mhd_assert (-1 != fd);
184#if !defined(HAVE___LSEEKI64) && !defined(HAVE_LSEEK64) 184#if ! defined(HAVE___LSEEKI64) && ! defined(HAVE_LSEEK64)
185 if ( (sizeof (uint64_t) > sizeof (off_t)) && 185 if ( (sizeof (uint64_t) > sizeof (off_t)) &&
186 ( (size > (uint64_t)INT32_MAX) || 186 ( (size > (uint64_t) INT32_MAX) ||
187 (offset > (uint64_t)INT32_MAX) || 187 (offset > (uint64_t) INT32_MAX) ||
188 ((size + offset) >= (uint64_t)INT32_MAX) ) ) 188 ((size + offset) >= (uint64_t) INT32_MAX) ) )
189 return NULL; 189 return NULL;
190#endif 190#endif
191 if ( ((int64_t) size < 0) || 191 if ( ((int64_t) size < 0) ||
@@ -194,11 +194,11 @@ MHD_response_from_fd (enum MHD_HTTP_StatusCode sc,
194 return NULL; 194 return NULL;
195 195
196 response = MHD_response_from_callback (sc, 196 response = MHD_response_from_callback (sc,
197 size, 197 size,
198 MHD_FILE_READ_BLOCK_SIZE, 198 MHD_FILE_READ_BLOCK_SIZE,
199 &file_reader, 199 &file_reader,
200 NULL, 200 NULL,
201 &free_callback); 201 &free_callback);
202 if (NULL == response) 202 if (NULL == response)
203 return NULL; 203 return NULL;
204 response->fd = fd; 204 response->fd = fd;
@@ -208,4 +208,3 @@ MHD_response_from_fd (enum MHD_HTTP_StatusCode sc,
208} 208}
209 209
210/* end of response_from_fd.c */ 210/* end of response_from_fd.c */
211
diff --git a/src/lib/response_options.c b/src/lib/response_options.c
index 406d1d32..e349627a 100644
--- a/src/lib/response_options.c
+++ b/src/lib/response_options.c
@@ -49,8 +49,9 @@ MHD_response_option_v10_only (struct MHD_Response *response)
49 */ 49 */
50void 50void
51MHD_response_option_termination_callback (struct MHD_Response *response, 51MHD_response_option_termination_callback (struct MHD_Response *response,
52 MHD_RequestTerminationCallback termination_cb, 52 MHD_RequestTerminationCallback
53 void *termination_cb_cls) 53 termination_cb,
54 void *termination_cb_cls)
54{ 55{
55 /* Q: should we assert termination_cb non-NULL? */ 56 /* Q: should we assert termination_cb non-NULL? */
56 response->termination_cb = termination_cb; 57 response->termination_cb = termination_cb;
diff --git a/src/lib/sysfdsetsize.c b/src/lib/sysfdsetsize.c
index fe7fba75..4929b3d2 100644
--- a/src/lib/sysfdsetsize.c
+++ b/src/lib/sysfdsetsize.c
@@ -56,7 +56,7 @@
56#include <sys/socket.h> 56#include <sys/socket.h>
57#endif /* HAVE_SYS_SOCKET_H */ 57#endif /* HAVE_SYS_SOCKET_H */
58 58
59#if defined(_WIN32) && !defined(__CYGWIN__) 59#if defined(_WIN32) && ! defined(__CYGWIN__)
60#ifndef WIN32_LEAN_AND_MEAN 60#ifndef WIN32_LEAN_AND_MEAN
61#define WIN32_LEAN_AND_MEAN 1 61#define WIN32_LEAN_AND_MEAN 1
62#endif /* !WIN32_LEAN_AND_MEAN */ 62#endif /* !WIN32_LEAN_AND_MEAN */
diff --git a/src/lib/tsearch.c b/src/lib/tsearch.c
index fe5fcd5b..e43d758f 100644
--- a/src/lib/tsearch.c
+++ b/src/lib/tsearch.c
@@ -13,7 +13,7 @@
13#include <stdlib.h> 13#include <stdlib.h>
14 14
15 15
16typedef struct node 16typedef struct node
17{ 17{
18 const void *key; 18 const void *key;
19 struct node *llink; 19 struct node *llink;
@@ -24,35 +24,35 @@ typedef struct node
24/* $NetBSD: tsearch.c,v 1.5 2005/11/29 03:12:00 christos Exp $ */ 24/* $NetBSD: tsearch.c,v 1.5 2005/11/29 03:12:00 christos Exp $ */
25/* find or insert datum into search tree */ 25/* find or insert datum into search tree */
26void * 26void *
27tsearch (const void *vkey, /* key to be located */ 27tsearch (const void *vkey, /* key to be located */
28 void **vrootp, /* address of tree root */ 28 void **vrootp, /* address of tree root */
29 int (*compar)(const void *, const void *)) 29 int (*compar)(const void *, const void *))
30{ 30{
31 node_t *q; 31 node_t *q;
32 node_t **rootp = (node_t **)vrootp; 32 node_t **rootp = (node_t **) vrootp;
33 33
34 if (NULL == rootp) 34 if (NULL == rootp)
35 return NULL; 35 return NULL;
36 36
37 while (*rootp != NULL) 37 while (*rootp != NULL)
38 { /* Knuth's T1: */ 38 { /* Knuth's T1: */
39 int r; 39 int r;
40 40
41 if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */ 41 if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */
42 return *rootp; /* we found it! */ 42 return *rootp; /* we found it! */
43 43
44 rootp = (r < 0) ? 44 rootp = (r < 0) ?
45 &(*rootp)->llink : /* T3: follow left branch */ 45 &(*rootp)->llink : /* T3: follow left branch */
46 &(*rootp)->rlink; /* T4: follow right branch */ 46 &(*rootp)->rlink; /* T4: follow right branch */
47 } 47 }
48 48
49 q = malloc (sizeof(node_t)); /* T5: key not found */ 49 q = malloc (sizeof(node_t)); /* T5: key not found */
50 if (q) 50 if (q)
51 { /* make new node */ 51 { /* make new node */
52 *rootp = q; /* link new node to old */ 52 *rootp = q; /* link new node to old */
53 q->key = vkey; /* initialize new node */ 53 q->key = vkey; /* initialize new node */
54 q->llink = q->rlink = NULL; 54 q->llink = q->rlink = NULL;
55 } 55 }
56 return q; 56 return q;
57} 57}
58 58
@@ -61,24 +61,24 @@ tsearch (const void *vkey, /* key to be located */
61/* find a node, or return NULL */ 61/* find a node, or return NULL */
62void * 62void *
63tfind (const void *vkey, /* key to be found */ 63tfind (const void *vkey, /* key to be found */
64 void * const *vrootp, /* address of the tree root */ 64 void *const *vrootp, /* address of the tree root */
65 int (*compar)(const void *, const void *)) 65 int (*compar)(const void *, const void *))
66{ 66{
67 node_t * const *rootp = (node_t * const*)vrootp; 67 node_t *const *rootp = (node_t *const*) vrootp;
68 68
69 if (NULL == rootp) 69 if (NULL == rootp)
70 return NULL; 70 return NULL;
71 71
72 while (*rootp != NULL) 72 while (*rootp != NULL)
73 { /* T1: */ 73 { /* T1: */
74 int r; 74 int r;
75 75
76 if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */ 76 if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */
77 return *rootp; /* key found */ 77 return *rootp; /* key found */
78 rootp = (r < 0) ? 78 rootp = (r < 0) ?
79 &(*rootp)->llink : /* T3: follow left branch */ 79 &(*rootp)->llink : /* T3: follow left branch */
80 &(*rootp)->rlink; /* T4: follow right branch */ 80 &(*rootp)->rlink; /* T4: follow right branch */
81 } 81 }
82 return NULL; 82 return NULL;
83} 83}
84 84
@@ -92,51 +92,51 @@ tfind (const void *vkey, /* key to be found */
92 * compar: function to carry out node comparisons 92 * compar: function to carry out node comparisons
93 */ 93 */
94void * 94void *
95tdelete (const void * __restrict vkey, 95tdelete (const void *__restrict vkey,
96 void ** __restrict vrootp, 96 void **__restrict vrootp,
97 int (*compar)(const void *, const void *)) 97 int (*compar)(const void *, const void *))
98{ 98{
99 node_t **rootp = (node_t **)vrootp; 99 node_t **rootp = (node_t **) vrootp;
100 node_t *p; 100 node_t *p;
101 node_t *q; 101 node_t *q;
102 node_t *r; 102 node_t *r;
103 int cmp; 103 int cmp;
104 104
105 if (rootp == NULL || (p = *rootp) == NULL) 105 if ((rootp == NULL)||((p = *rootp) == NULL))
106 return NULL; 106 return NULL;
107 107
108 while ((cmp = (*compar)(vkey, (*rootp)->key)) != 0) 108 while ((cmp = (*compar)(vkey, (*rootp)->key)) != 0)
109 { 109 {
110 p = *rootp; 110 p = *rootp;
111 rootp = (cmp < 0) ? 111 rootp = (cmp < 0) ?
112 &(*rootp)->llink : /* follow llink branch */ 112 &(*rootp)->llink : /* follow llink branch */
113 &(*rootp)->rlink; /* follow rlink branch */ 113 &(*rootp)->rlink; /* follow rlink branch */
114 if (*rootp == NULL) 114 if (*rootp == NULL)
115 return NULL; /* key not found */ 115 return NULL; /* key not found */
116 } 116 }
117 r = (*rootp)->rlink; /* D1: */ 117 r = (*rootp)->rlink; /* D1: */
118 if ((q = (*rootp)->llink) == NULL) /* Left NULL? */ 118 if ((q = (*rootp)->llink) == NULL) /* Left NULL? */
119 { 119 {
120 q = r;
121 }
122 else if (r != NULL)
123 { /* Right link is NULL? */
124 if (r->llink == NULL)
125 { /* D2: Find successor */
126 r->llink = q;
120 q = r; 127 q = r;
121 } 128 }
122 else if (r != NULL) 129 else
123 { /* Right link is NULL? */ 130 { /* D3: Find NULL link */
124 if (r->llink == NULL) 131 for (q = r->llink; q->llink != NULL; q = r->llink)
125 { /* D2: Find successor */ 132 r = q;
126 r->llink = q; 133 r->llink = q->rlink;
127 q = r; 134 q->llink = (*rootp)->llink;
128 } 135 q->rlink = (*rootp)->rlink;
129 else
130 { /* D3: Find NULL link */
131 for (q = r->llink; q->llink != NULL; q = r->llink)
132 r = q;
133 r->llink = q->rlink;
134 q->llink = (*rootp)->llink;
135 q->rlink = (*rootp)->rlink;
136 }
137 } 136 }
138 free(*rootp); /* D4: Free node */ 137 }
139 *rootp = q; /* link parent to new node */ 138 free (*rootp); /* D4: Free node */
139 *rootp = q; /* link parent to new node */
140 return p; 140 return p;
141} 141}
142 142
diff --git a/src/lib/tsearch.h b/src/lib/tsearch.h
index aa186495..0cfe16a7 100644
--- a/src/lib/tsearch.h
+++ b/src/lib/tsearch.h
@@ -14,22 +14,22 @@ extern "C" {
14#endif /* __cplusplus */ 14#endif /* __cplusplus */
15 15
16 16
17void * 17void *
18tdelete (const void * __restrict, 18 tdelete (const void *__restrict,
19 void ** __restrict, 19 void **__restrict,
20 int (*)(const void *, const void *)); 20 int (*)(const void *, const void *));
21 21
22 22
23void * 23void *
24tfind (const void *, 24 tfind (const void *,
25 void * const *, 25 void *const *,
26 int (*)(const void *, const void *)); 26 int (*)(const void *, const void *));
27 27
28 28
29void * 29void *
30tsearch (const void *, 30 tsearch (const void *,
31 void **, 31 void **,
32 int (*)(const void *, const void *)); 32 int (*)(const void *, const void *));
33 33
34#if defined(__cplusplus) 34#if defined(__cplusplus)
35}; 35};
diff --git a/src/lib/upgrade_process.c b/src/lib/upgrade_process.c
index 75924eee..353f2753 100644
--- a/src/lib/upgrade_process.c
+++ b/src/lib/upgrade_process.c
@@ -41,59 +41,62 @@ MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh)
41 * pointers to 'connection' and 'daemon' are not changed 41 * pointers to 'connection' and 'daemon' are not changed
42 * during this processing, so no need to chain dereference 42 * during this processing, so no need to chain dereference
43 * each time. */ 43 * each time. */
44 struct MHD_Connection * const connection = urh->connection; 44 struct MHD_Connection *const connection = urh->connection;
45 struct MHD_Daemon * const daemon = connection->daemon; 45 struct MHD_Daemon *const daemon = connection->daemon;
46 /* Prevent data races: use same value of 'was_closed' throughout 46 /* Prevent data races: use same value of 'was_closed' throughout
47 * this function. If 'was_closed' changed externally in the middle 47 * this function. If 'was_closed' changed externally in the middle
48 * of processing - it will be processed on next iteration. */ 48 * of processing - it will be processed on next iteration. */
49 bool was_closed; 49 bool was_closed;
50 struct MHD_TLS_Plugin *tls = daemon->tls_api; 50 struct MHD_TLS_Plugin *tls = daemon->tls_api;
51 51
52 if (daemon->shutdown) 52 if (daemon->shutdown)
53 { 53 {
54 /* Daemon shutting down, application will not receive any more data. */ 54 /* Daemon shutting down, application will not receive any more data. */
55#ifdef HAVE_MESSAGES 55#ifdef HAVE_MESSAGES
56 if (! urh->was_closed) 56 if (! urh->was_closed)
57 { 57 {
58 MHD_DLOG (daemon, 58 MHD_DLOG (daemon,
59 MHD_SC_DAEMON_ALREADY_SHUTDOWN, 59 MHD_SC_DAEMON_ALREADY_SHUTDOWN,
60 _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); 60 _ (
61 } 61 "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
62#endif
63 urh->was_closed = true;
64 } 62 }
63#endif
64 urh->was_closed = true;
65 }
65 was_closed = urh->was_closed; 66 was_closed = urh->was_closed;
66 if (was_closed) 67 if (was_closed)
68 {
69 /* Application was closed connections: no more data
70 * can be forwarded to application socket. */
71 if (0 < urh->in_buffer_used)
67 { 72 {
68 /* Application was closed connections: no more data
69 * can be forwarded to application socket. */
70 if (0 < urh->in_buffer_used)
71 {
72#ifdef HAVE_MESSAGES 73#ifdef HAVE_MESSAGES
73 MHD_DLOG (daemon, 74 MHD_DLOG (daemon,
74 MHD_SC_UPGRADE_FORWARD_INCOMPLETE, 75 MHD_SC_UPGRADE_FORWARD_INCOMPLETE,
75 _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \ 76 _ (
76 " bytes of data received from remote side: application shut down socket\n"), 77 "Failed to forward to application "
77 (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used); 78 MHD_UNSIGNED_LONG_LONG_PRINTF \
79 " bytes of data received from remote side: application shut down socket\n"),
80 (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used);
78#endif 81#endif
79 82
80 }
81 /* If application signaled MHD about socket closure then
82 * check for any pending data even if socket is not marked
83 * as 'ready' (signal may arrive after poll()/select()).
84 * Socketpair for forwarding is always in non-blocking mode
85 * so no risk that recv() will block the thread. */
86 if (0 != urh->out_buffer_size)
87 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
88 /* Discard any data received form remote. */
89 urh->in_buffer_used = 0;
90 /* Do not try to push data to application. */
91 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
92 /* Reading from remote client is not required anymore. */
93 urh->in_buffer_size = 0;
94 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
95 connection->tls_read_ready = false;
96 } 83 }
84 /* If application signaled MHD about socket closure then
85 * check for any pending data even if socket is not marked
86 * as 'ready' (signal may arrive after poll()/select()).
87 * Socketpair for forwarding is always in non-blocking mode
88 * so no risk that recv() will block the thread. */
89 if (0 != urh->out_buffer_size)
90 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
91 /* Discard any data received form remote. */
92 urh->in_buffer_used = 0;
93 /* Do not try to push data to application. */
94 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
95 /* Reading from remote client is not required anymore. */
96 urh->in_buffer_size = 0;
97 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
98 connection->tls_read_ready = false;
99 }
97 100
98 /* On some platforms (W32, possibly Darwin) failed send() (send() will always 101 /* On some platforms (W32, possibly Darwin) failed send() (send() will always
99 * fail after remote disconnect was detected) may discard data in system 102 * fail after remote disconnect was detected) may discard data in system
@@ -114,245 +117,249 @@ MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh)
114 if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) || 117 if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
115 (connection->tls_read_ready) ) && 118 (connection->tls_read_ready) ) &&
116 (urh->in_buffer_used < urh->in_buffer_size) ) 119 (urh->in_buffer_used < urh->in_buffer_size) )
117 { 120 {
118 ssize_t res; 121 ssize_t res;
119 size_t buf_size; 122 size_t buf_size;
120 123
121 buf_size = urh->in_buffer_size - urh->in_buffer_used; 124 buf_size = urh->in_buffer_size - urh->in_buffer_used;
122 if (buf_size > SSIZE_MAX) 125 if (buf_size > SSIZE_MAX)
123 buf_size = SSIZE_MAX; 126 buf_size = SSIZE_MAX;
124 127
125 connection->tls_read_ready = false; 128 connection->tls_read_ready = false;
126 res = tls->recv (tls->cls, 129 res = tls->recv (tls->cls,
127 connection->tls_cs, 130 connection->tls_cs,
128 &urh->in_buffer[urh->in_buffer_used], 131 &urh->in_buffer[urh->in_buffer_used],
129 buf_size); 132 buf_size);
130 if (0 >= res) 133 if (0 >= res)
131 { 134 {
132 // FIXME: define GNUTLS-independent error codes! 135 // FIXME: define GNUTLS-independent error codes!
133 if (GNUTLS_E_INTERRUPTED != res) 136 if (GNUTLS_E_INTERRUPTED != res)
134 { 137 {
135 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; 138 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
136 if (GNUTLS_E_AGAIN != res) 139 if (GNUTLS_E_AGAIN != res)
137 {
138 /* Unrecoverable error on socket was detected or
139 * socket was disconnected/shut down. */
140 /* Stop trying to read from this TLS socket. */
141 urh->in_buffer_size = 0;
142 }
143 }
144 }
145 else /* 0 < res */
146 {
147 urh->in_buffer_used += res;
148 if (buf_size > (size_t)res)
149 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
150 else if (0 < tls->check_record_pending (tls->cls,
151 connection->tls_cs))
152 connection->tls_read_ready = true;
153 }
154 if (MHD_EPOLL_STATE_ERROR ==
155 ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi))
156 { 140 {
157 /* Unrecoverable error on socket was detected and all 141 /* Unrecoverable error on socket was detected or
158 * pending data was read from system buffers. */ 142 * socket was disconnected/shut down. */
159 /* Stop trying to read from this TLS socket. */ 143 /* Stop trying to read from this TLS socket. */
160 urh->in_buffer_size = 0; 144 urh->in_buffer_size = 0;
161 } 145 }
146 }
162 } 147 }
148 else /* 0 < res */
149 {
150 urh->in_buffer_used += res;
151 if (buf_size > (size_t) res)
152 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
153 else if (0 < tls->check_record_pending (tls->cls,
154 connection->tls_cs))
155 connection->tls_read_ready = true;
156 }
157 if (MHD_EPOLL_STATE_ERROR ==
158 ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi))
159 {
160 /* Unrecoverable error on socket was detected and all
161 * pending data was read from system buffers. */
162 /* Stop trying to read from this TLS socket. */
163 urh->in_buffer_size = 0;
164 }
165 }
163 166
164 /* 167 /*
165 * handle reading from application 168 * handle reading from application
166 */ 169 */
167 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && 170 if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
168 (urh->out_buffer_used < urh->out_buffer_size) ) 171 (urh->out_buffer_used < urh->out_buffer_size) )
169 { 172 {
170 ssize_t res; 173 ssize_t res;
171 size_t buf_size; 174 size_t buf_size;
172 175
173 buf_size = urh->out_buffer_size - urh->out_buffer_used; 176 buf_size = urh->out_buffer_size - urh->out_buffer_used;
174 if (buf_size > MHD_SCKT_SEND_MAX_SIZE_) 177 if (buf_size > MHD_SCKT_SEND_MAX_SIZE_)
175 buf_size = MHD_SCKT_SEND_MAX_SIZE_; 178 buf_size = MHD_SCKT_SEND_MAX_SIZE_;
176 179
177 res = MHD_recv_ (urh->mhd.socket, 180 res = MHD_recv_ (urh->mhd.socket,
178 &urh->out_buffer[urh->out_buffer_used], 181 &urh->out_buffer[urh->out_buffer_used],
179 buf_size); 182 buf_size);
180 if (0 >= res) 183 if (0 >= res)
181 { 184 {
182 const int err = MHD_socket_get_error_ (); 185 const int err = MHD_socket_get_error_ ();
183 if ((0 == res) || 186 if ((0 == res) ||
184 ((! MHD_SCKT_ERR_IS_EINTR_ (err)) && 187 ((! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
185 (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)))) 188 (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err))))
186 { 189 {
187 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; 190 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
188 if ((0 == res) || 191 if ((0 == res) ||
189 (was_closed) || 192 (was_closed) ||
190 (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || 193 (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
191 (! MHD_SCKT_ERR_IS_EAGAIN_ (err))) 194 (! MHD_SCKT_ERR_IS_EAGAIN_ (err)))
192 {
193 /* Socket disconnect/shutdown was detected;
194 * Application signaled about closure of 'upgraded' socket;
195 * or persistent / unrecoverable error. */
196 /* Do not try to pull more data from application. */
197 urh->out_buffer_size = 0;
198 }
199 }
200 }
201 else /* 0 < res */
202 {
203 urh->out_buffer_used += res;
204 if (buf_size > (size_t)res)
205 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
206 }
207 if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
208 ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
209 (was_closed) ) )
210 { 195 {
211 /* Unrecoverable error on socket was detected and all 196 /* Socket disconnect/shutdown was detected;
212 * pending data was read from system buffers. */ 197 * Application signaled about closure of 'upgraded' socket;
198 * or persistent / unrecoverable error. */
213 /* Do not try to pull more data from application. */ 199 /* Do not try to pull more data from application. */
214 urh->out_buffer_size = 0; 200 urh->out_buffer_size = 0;
215 } 201 }
202 }
203 }
204 else /* 0 < res */
205 {
206 urh->out_buffer_used += res;
207 if (buf_size > (size_t) res)
208 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
216 } 209 }
210 if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
211 ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
212 (was_closed) ) )
213 {
214 /* Unrecoverable error on socket was detected and all
215 * pending data was read from system buffers. */
216 /* Do not try to pull more data from application. */
217 urh->out_buffer_size = 0;
218 }
219 }
217 220
218 /* 221 /*
219 * handle writing to remote HTTPS client 222 * handle writing to remote HTTPS client
220 */ 223 */
221 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && 224 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
222 (urh->out_buffer_used > 0) ) 225 (urh->out_buffer_used > 0) )
223 { 226 {
224 ssize_t res; 227 ssize_t res;
225 size_t data_size; 228 size_t data_size;
226 229
227 data_size = urh->out_buffer_used; 230 data_size = urh->out_buffer_used;
228 if (data_size > SSIZE_MAX) 231 if (data_size > SSIZE_MAX)
229 data_size = SSIZE_MAX; 232 data_size = SSIZE_MAX;
230 233
231 res = tls->send (tls->cls, 234 res = tls->send (tls->cls,
232 connection->tls_cs, 235 connection->tls_cs,
233 urh->out_buffer, 236 urh->out_buffer,
234 data_size); 237 data_size);
235 if (0 >= res) 238 if (0 >= res)
239 {
240 // FIXME: define GNUTLS-independent error codes!
241 if (GNUTLS_E_INTERRUPTED != res)
242 {
243 urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
244 if (GNUTLS_E_INTERRUPTED != res)
236 { 245 {
237 // FIXME: define GNUTLS-independent error codes! 246 /* TLS connection shut down or
238 if (GNUTLS_E_INTERRUPTED != res) 247 * persistent / unrecoverable error. */
239 {
240 urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
241 if (GNUTLS_E_INTERRUPTED != res)
242 {
243 /* TLS connection shut down or
244 * persistent / unrecoverable error. */
245#ifdef HAVE_MESSAGES 248#ifdef HAVE_MESSAGES
246 MHD_DLOG (daemon, 249 MHD_DLOG (daemon,
247 MHD_SC_UPGRADE_FORWARD_INCOMPLETE, 250 MHD_SC_UPGRADE_FORWARD_INCOMPLETE,
248 _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \ 251 _ (
249 " bytes of data received from application: %s\n"), 252 "Failed to forward to remote client "
250 (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used, 253 MHD_UNSIGNED_LONG_LONG_PRINTF \
251 tls->strerror (tls->cls, 254 " bytes of data received from application: %s\n"),
252 res)); 255 (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used,
256 tls->strerror (tls->cls,
257 res));
253#endif 258#endif
254 /* Discard any data unsent to remote. */ 259 /* Discard any data unsent to remote. */
255 urh->out_buffer_used = 0; 260 urh->out_buffer_used = 0;
256 /* Do not try to pull more data from application. */
257 urh->out_buffer_size = 0;
258 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
259 }
260 }
261 }
262 else /* 0 < res */
263 {
264 const size_t next_out_buffer_used = urh->out_buffer_used - res;
265 if (0 != next_out_buffer_used)
266 {
267 memmove (urh->out_buffer,
268 &urh->out_buffer[res],
269 next_out_buffer_used);
270 if (data_size > (size_t)res)
271 urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
272 }
273 urh->out_buffer_used = next_out_buffer_used;
274 }
275 if ( (0 == urh->out_buffer_used) &&
276 (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) )
277 {
278 /* Unrecoverable error on socket was detected and all
279 * pending data was sent to remote. */
280 /* Do not try to send to remote anymore. */
281 urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
282 /* Do not try to pull more data from application. */ 261 /* Do not try to pull more data from application. */
283 urh->out_buffer_size = 0; 262 urh->out_buffer_size = 0;
284 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; 263 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
285 } 264 }
265 }
286 } 266 }
267 else /* 0 < res */
268 {
269 const size_t next_out_buffer_used = urh->out_buffer_used - res;
270 if (0 != next_out_buffer_used)
271 {
272 memmove (urh->out_buffer,
273 &urh->out_buffer[res],
274 next_out_buffer_used);
275 if (data_size > (size_t) res)
276 urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
277 }
278 urh->out_buffer_used = next_out_buffer_used;
279 }
280 if ( (0 == urh->out_buffer_used) &&
281 (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) )
282 {
283 /* Unrecoverable error on socket was detected and all
284 * pending data was sent to remote. */
285 /* Do not try to send to remote anymore. */
286 urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
287 /* Do not try to pull more data from application. */
288 urh->out_buffer_size = 0;
289 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
290 }
291 }
287 292
288 /* 293 /*
289 * handle writing to application 294 * handle writing to application
290 */ 295 */
291 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && 296 if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
292 (urh->in_buffer_used > 0) ) 297 (urh->in_buffer_used > 0) )
293 { 298 {
294 ssize_t res; 299 ssize_t res;
295 size_t data_size; 300 size_t data_size;
296 301
297 data_size = urh->in_buffer_used; 302 data_size = urh->in_buffer_used;
298 if (data_size > MHD_SCKT_SEND_MAX_SIZE_) 303 if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
299 data_size = MHD_SCKT_SEND_MAX_SIZE_; 304 data_size = MHD_SCKT_SEND_MAX_SIZE_;
300 305
301 res = MHD_send_ (urh->mhd.socket, 306 res = MHD_send_ (urh->mhd.socket,
302 urh->in_buffer, 307 urh->in_buffer,
303 data_size); 308 data_size);
304 if (0 >= res) 309 if (0 >= res)
310 {
311 const int err = MHD_socket_get_error_ ();
312 if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
313 (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)) )
314 {
315 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
316 if (! MHD_SCKT_ERR_IS_EAGAIN_ (err))
305 { 317 {
306 const int err = MHD_socket_get_error_ (); 318 /* Socketpair connection shut down or
307 if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) && 319 * persistent / unrecoverable error. */
308 (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)) )
309 {
310 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
311 if (! MHD_SCKT_ERR_IS_EAGAIN_ (err))
312 {
313 /* Socketpair connection shut down or
314 * persistent / unrecoverable error. */
315#ifdef HAVE_MESSAGES 320#ifdef HAVE_MESSAGES
316 MHD_DLOG (daemon, 321 MHD_DLOG (daemon,
317 MHD_SC_UPGRADE_FORWARD_INCOMPLETE, 322 MHD_SC_UPGRADE_FORWARD_INCOMPLETE,
318 _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \ 323 _ (
319 " bytes of data received from remote side: %s\n"), 324 "Failed to forward to application "
320 (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used, 325 MHD_UNSIGNED_LONG_LONG_PRINTF \
321 MHD_socket_strerr_ (err)); 326 " bytes of data received from remote side: %s\n"),
327 (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used,
328 MHD_socket_strerr_ (err));
322#endif 329#endif
323 /* Discard any data received form remote. */ 330 /* Discard any data received form remote. */
324 urh->in_buffer_used = 0; 331 urh->in_buffer_used = 0;
325 /* Reading from remote client is not required anymore. */
326 urh->in_buffer_size = 0;
327 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
328 connection->tls_read_ready = false;
329 }
330 }
331 }
332 else /* 0 < res */
333 {
334 const size_t next_in_buffer_used = urh->in_buffer_used - res;
335 if (0 != next_in_buffer_used)
336 {
337 memmove (urh->in_buffer,
338 &urh->in_buffer[res],
339 next_in_buffer_used);
340 if (data_size > (size_t)res)
341 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
342 }
343 urh->in_buffer_used = next_in_buffer_used;
344 }
345 if ( (0 == urh->in_buffer_used) &&
346 (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) )
347 {
348 /* Do not try to push data to application. */
349 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
350 /* Reading from remote client is not required anymore. */ 332 /* Reading from remote client is not required anymore. */
351 urh->in_buffer_size = 0; 333 urh->in_buffer_size = 0;
352 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; 334 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
353 connection->tls_read_ready = false; 335 connection->tls_read_ready = false;
354 } 336 }
337 }
338 }
339 else /* 0 < res */
340 {
341 const size_t next_in_buffer_used = urh->in_buffer_used - res;
342 if (0 != next_in_buffer_used)
343 {
344 memmove (urh->in_buffer,
345 &urh->in_buffer[res],
346 next_in_buffer_used);
347 if (data_size > (size_t) res)
348 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
349 }
350 urh->in_buffer_used = next_in_buffer_used;
351 }
352 if ( (0 == urh->in_buffer_used) &&
353 (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) )
354 {
355 /* Do not try to push data to application. */
356 urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
357 /* Reading from remote client is not required anymore. */
358 urh->in_buffer_size = 0;
359 urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
360 connection->tls_read_ready = false;
355 } 361 }
362 }
356 363
357 /* Check whether data is present in TLS buffers 364 /* Check whether data is present in TLS buffers
358 * and incoming forward buffer have some space. */ 365 * and incoming forward buffer have some space. */
@@ -364,24 +371,26 @@ MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh)
364 if ( (daemon->shutdown) && 371 if ( (daemon->shutdown) &&
365 ( (0 != urh->out_buffer_size) || 372 ( (0 != urh->out_buffer_size) ||
366 (0 != urh->out_buffer_used) ) ) 373 (0 != urh->out_buffer_used) ) )
367 { 374 {
368 /* Daemon shutting down, discard any remaining forward data. */ 375 /* Daemon shutting down, discard any remaining forward data. */
369#ifdef HAVE_MESSAGES 376#ifdef HAVE_MESSAGES
370 if (0 < urh->out_buffer_used) 377 if (0 < urh->out_buffer_used)
371 MHD_DLOG (daemon, 378 MHD_DLOG (daemon,
372 MHD_SC_UPGRADE_FORWARD_INCOMPLETE, 379 MHD_SC_UPGRADE_FORWARD_INCOMPLETE,
373 _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \ 380 _ (
374 " bytes of data received from application: daemon shut down\n"), 381 "Failed to forward to remote client "
375 (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used); 382 MHD_UNSIGNED_LONG_LONG_PRINTF \
383 " bytes of data received from application: daemon shut down\n"),
384 (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used);
376#endif 385#endif
377 /* Discard any data unsent to remote. */ 386 /* Discard any data unsent to remote. */
378 urh->out_buffer_used = 0; 387 urh->out_buffer_used = 0;
379 /* Do not try to sent to remote anymore. */ 388 /* Do not try to sent to remote anymore. */
380 urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; 389 urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
381 /* Do not try to pull more data from application. */ 390 /* Do not try to pull more data from application. */
382 urh->out_buffer_size = 0; 391 urh->out_buffer_size = 0;
383 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; 392 urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
384 } 393 }
385} 394}
386#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 395#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
387 396
diff --git a/src/lib/upgrade_process.h b/src/lib/upgrade_process.h
index 36a7ddff..8b0d4119 100644
--- a/src/lib/upgrade_process.h
+++ b/src/lib/upgrade_process.h
@@ -36,7 +36,7 @@
36 */ 36 */
37void 37void
38MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh) 38MHD_upgrade_response_handle_process_ (struct MHD_UpgradeResponseHandle *urh)
39 MHD_NONNULL(1); 39MHD_NONNULL (1);
40 40
41 41
42#endif 42#endif
diff --git a/src/lib/version.c b/src/lib/version.c
index 472a8c04..5bf4ab01 100644
--- a/src/lib/version.c
+++ b/src/lib/version.c
@@ -40,13 +40,13 @@ MHD_get_version (void)
40 static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0"; 40 static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0";
41 if (0 == ver[0]) 41 if (0 == ver[0])
42 { 42 {
43 int res = MHD_snprintf_(ver, 43 int res = MHD_snprintf_ (ver,
44 sizeof(ver), 44 sizeof(ver),
45 "%x.%x.%x", 45 "%x.%x.%x",
46 (((int)MHD_VERSION >> 24) & 0xFF), 46 (((int) MHD_VERSION >> 24) & 0xFF),
47 (((int)MHD_VERSION >> 16) & 0xFF), 47 (((int) MHD_VERSION >> 16) & 0xFF),
48 (((int)MHD_VERSION >> 8) & 0xFF)); 48 (((int) MHD_VERSION >> 8) & 0xFF));
49 if (0 >= res || sizeof(ver) <= res) 49 if ((0 >= res)||(sizeof(ver) <= res))
50 return "0.0.0"; /* Can't return real version*/ 50 return "0.0.0"; /* Can't return real version*/
51 } 51 }
52 return ver; 52 return ver;
@@ -66,141 +66,142 @@ MHD_get_version (void)
66 * @ingroup specialized 66 * @ingroup specialized
67 */ 67 */
68_MHD_EXTERN enum MHD_Bool 68_MHD_EXTERN enum MHD_Bool
69MHD_is_feature_supported(enum MHD_Feature feature) 69MHD_is_feature_supported (enum MHD_Feature feature)
70{ 70{
71 switch(feature) 71 switch (feature)
72 { 72 {
73 case MHD_FEATURE_MESSAGES: 73 case MHD_FEATURE_MESSAGES:
74#ifdef HAVE_MESSAGES 74#ifdef HAVE_MESSAGES
75 return MHD_YES; 75 return MHD_YES;
76#else 76#else
77 return MHD_NO; 77 return MHD_NO;
78#endif 78#endif
79 case MHD_FEATURE_TLS: 79 case MHD_FEATURE_TLS:
80#ifdef HTTPS_SUPPORT 80#ifdef HTTPS_SUPPORT
81 return MHD_YES; 81 return MHD_YES;
82#else /* ! HTTPS_SUPPORT */ 82#else /* ! HTTPS_SUPPORT */
83 return MHD_NO; 83 return MHD_NO;
84#endif /* ! HTTPS_SUPPORT */ 84#endif /* ! HTTPS_SUPPORT */
85 case MHD_FEATURE_HTTPS_CERT_CALLBACK: 85 case MHD_FEATURE_HTTPS_CERT_CALLBACK:
86#if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 86#if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
87 return MHD_YES; 87 return MHD_YES;
88#else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ 88#else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
89 return MHD_NO; 89 return MHD_NO;
90#endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ 90#endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
91 case MHD_FEATURE_IPv6: 91 case MHD_FEATURE_IPv6:
92#ifdef HAVE_INET6 92#ifdef HAVE_INET6
93 return MHD_YES; 93 return MHD_YES;
94#else 94#else
95 return MHD_NO; 95 return MHD_NO;
96#endif 96#endif
97 case MHD_FEATURE_IPv6_ONLY: 97 case MHD_FEATURE_IPv6_ONLY:
98#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) 98#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
99 return MHD_YES; 99 return MHD_YES;
100#else 100#else
101 return MHD_NO; 101 return MHD_NO;
102#endif 102#endif
103 case MHD_FEATURE_POLL: 103 case MHD_FEATURE_POLL:
104#ifdef HAVE_POLL 104#ifdef HAVE_POLL
105 return MHD_YES; 105 return MHD_YES;
106#else 106#else
107 return MHD_NO; 107 return MHD_NO;
108#endif 108#endif
109 case MHD_FEATURE_EPOLL: 109 case MHD_FEATURE_EPOLL:
110#ifdef EPOLL_SUPPORT 110#ifdef EPOLL_SUPPORT
111 return MHD_YES; 111 return MHD_YES;
112#else 112#else
113 return MHD_NO; 113 return MHD_NO;
114#endif 114#endif
115 case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET: 115 case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET:
116#ifdef HAVE_LISTEN_SHUTDOWN 116#ifdef HAVE_LISTEN_SHUTDOWN
117 return MHD_YES; 117 return MHD_YES;
118#else 118#else
119 return MHD_NO; 119 return MHD_NO;
120#endif 120#endif
121 case MHD_FEATURE_SOCKETPAIR: 121 case MHD_FEATURE_SOCKETPAIR:
122#ifdef _MHD_ITC_SOCKETPAIR 122#ifdef _MHD_ITC_SOCKETPAIR
123 return MHD_YES; 123 return MHD_YES;
124#else 124#else
125 return MHD_NO; 125 return MHD_NO;
126#endif 126#endif
127 case MHD_FEATURE_TCP_FASTOPEN: 127 case MHD_FEATURE_TCP_FASTOPEN:
128#ifdef TCP_FASTOPEN 128#ifdef TCP_FASTOPEN
129 return MHD_YES; 129 return MHD_YES;
130#else 130#else
131 return MHD_NO; 131 return MHD_NO;
132#endif 132#endif
133 case MHD_FEATURE_BASIC_AUTH: 133 case MHD_FEATURE_BASIC_AUTH:
134#ifdef BAUTH_SUPPORT 134#ifdef BAUTH_SUPPORT
135 return MHD_YES; 135 return MHD_YES;
136#else 136#else
137 return MHD_NO; 137 return MHD_NO;
138#endif 138#endif
139 case MHD_FEATURE_DIGEST_AUTH: 139 case MHD_FEATURE_DIGEST_AUTH:
140#ifdef DAUTH_SUPPORT 140#ifdef DAUTH_SUPPORT
141 return MHD_YES; 141 return MHD_YES;
142#else 142#else
143 return MHD_NO; 143 return MHD_NO;
144#endif 144#endif
145 case MHD_FEATURE_POSTPROCESSOR: 145 case MHD_FEATURE_POSTPROCESSOR:
146#ifdef HAVE_POSTPROCESSOR 146#ifdef HAVE_POSTPROCESSOR
147 return MHD_YES; 147 return MHD_YES;
148#else 148#else
149 return MHD_NO; 149 return MHD_NO;
150#endif 150#endif
151 case MHD_FEATURE_HTTPS_KEY_PASSWORD: 151 case MHD_FEATURE_HTTPS_KEY_PASSWORD:
152#if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 152#if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
153 return MHD_YES; 153 return MHD_YES;
154#else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ 154#else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
155 return MHD_NO; 155 return MHD_NO;
156#endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ 156#endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
157 case MHD_FEATURE_LARGE_FILE: 157 case MHD_FEATURE_LARGE_FILE:
158#if defined(HAVE_PREAD64) || defined(_WIN32) 158#if defined(HAVE_PREAD64) || defined(_WIN32)
159 return MHD_YES; 159 return MHD_YES;
160#elif defined(HAVE_PREAD) 160#elif defined(HAVE_PREAD)
161 return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; 161 return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
162#elif defined(HAVE_LSEEK64) 162#elif defined(HAVE_LSEEK64)
163 return MHD_YES; 163 return MHD_YES;
164#else 164#else
165 return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; 165 return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
166#endif 166#endif
167 case MHD_FEATURE_THREAD_NAMES: 167 case MHD_FEATURE_THREAD_NAMES:
168#if defined(MHD_USE_THREAD_NAME_) 168#if defined(MHD_USE_THREAD_NAME_)
169 return MHD_YES; 169 return MHD_YES;
170#else 170#else
171 return MHD_NO; 171 return MHD_NO;
172#endif 172#endif
173 case MHD_FEATURE_UPGRADE: 173 case MHD_FEATURE_UPGRADE:
174#if defined(UPGRADE_SUPPORT) 174#if defined(UPGRADE_SUPPORT)
175 return MHD_YES; 175 return MHD_YES;
176#else 176#else
177 return MHD_NO; 177 return MHD_NO;
178#endif 178#endif
179 case MHD_FEATURE_RESPONSES_SHARED_FD: 179 case MHD_FEATURE_RESPONSES_SHARED_FD:
180#if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) 180#if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
181 return MHD_YES; 181 return MHD_YES;
182#else 182#else
183 return MHD_NO; 183 return MHD_NO;
184#endif 184#endif
185 case MHD_FEATURE_AUTODETECT_BIND_PORT: 185 case MHD_FEATURE_AUTODETECT_BIND_PORT:
186#ifdef MHD_USE_GETSOCKNAME 186#ifdef MHD_USE_GETSOCKNAME
187 return MHD_YES; 187 return MHD_YES;
188#else 188#else
189 return MHD_NO; 189 return MHD_NO;
190#endif 190#endif
191 case MHD_FEATURE_AUTOSUPPRESS_SIGPIPE: 191 case MHD_FEATURE_AUTOSUPPRESS_SIGPIPE:
192#if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || defined (MSG_NOSIGNAL) 192#if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || \
193 return MHD_YES; 193 defined (MSG_NOSIGNAL)
194 return MHD_YES;
194#else 195#else
195 return MHD_NO; 196 return MHD_NO;
196#endif 197#endif
197 case MHD_FEATURE_SENDFILE: 198 case MHD_FEATURE_SENDFILE:
198#ifdef _MHD_HAVE_SENDFILE 199#ifdef _MHD_HAVE_SENDFILE
199 return MHD_YES; 200 return MHD_YES;
200#else 201#else
201 return MHD_NO; 202 return MHD_NO;
202#endif 203#endif
203 204
204 } 205 }
205 return MHD_NO; 206 return MHD_NO;
206} 207}