aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2008-05-25 04:35:45 +0000
committerChristian Grothoff <christian@grothoff.org>2008-05-25 04:35:45 +0000
commitdd433c0f8c77fa20626d57a9aece6bf5b9c1e62c (patch)
treeecd123e5a2ae5df637f1134b92a0f99b9109e9ca
parentc51d65ffce7b0542a15afa4d7bb252df6a970b5c (diff)
downloadlibmicrohttpd-dd433c0f8c77fa20626d57a9aece6bf5b9c1e62c.tar.gz
libmicrohttpd-dd433c0f8c77fa20626d57a9aece6bf5b9c1e62c.zip
fixing lv formatting
-rw-r--r--src/daemon/daemon.c1200
-rw-r--r--src/daemon/internal.h210
-rw-r--r--src/daemon/postprocessor.c43
-rw-r--r--src/daemon/postprocessor_large_test.c11
-rw-r--r--src/examples/fileserver_example_external_select.c34
-rw-r--r--src/examples/https_server_example.c6
6 files changed, 761 insertions, 743 deletions
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index ef575dd6..3578823a 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -59,331 +59,340 @@
59 * daemon was not started with the right 59 * daemon was not started with the right
60 * options for this call. 60 * options for this call.
61 */ 61 */
62int MHD_get_fdset(struct MHD_Daemon *daemon, 62int
63 fd_set * read_fd_set, 63MHD_get_fdset (struct MHD_Daemon *daemon,
64 fd_set * write_fd_set, 64 fd_set * read_fd_set,
65 fd_set * except_fd_set, 65 fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd)
66 int *max_fd) 66{
67 { 67 struct MHD_Connection *con_itr;
68 struct MHD_Connection *con_itr; 68 int fd;
69 int fd; 69
70 70 if ((daemon == NULL) || (read_fd_set == NULL) || (write_fd_set == NULL)
71 if ((daemon == NULL) || (read_fd_set == NULL) || (write_fd_set == NULL) 71 || (except_fd_set == NULL) || (max_fd == NULL) || (-1 == (fd = daemon->
72 || (except_fd_set == NULL) || (max_fd == NULL) || (-1 == (fd = daemon-> 72 socket_fd))
73 socket_fd)) || (daemon->shutdown == MHD_YES) || ((daemon->options 73 || (daemon->shutdown == MHD_YES)
74 & MHD_USE_THREAD_PER_CONNECTION) != 0)) 74 || ((daemon->options & MHD_USE_THREAD_PER_CONNECTION) != 0))
75 return MHD_NO; 75 return MHD_NO;
76 76
77 __FD_SET (fd, read_fd_set); 77 __FD_SET (fd, read_fd_set);
78 78
79 /* update max file descriptor */ 79 /* update max file descriptor */
80 if ((*max_fd) < fd) 80 if ((*max_fd) < fd)
81 *max_fd = fd; 81 *max_fd = fd;
82 82
83 con_itr = daemon->connections; 83 con_itr = daemon->connections;
84 while (con_itr != NULL) 84 while (con_itr != NULL)
85 { 85 {
86 if (MHD_YES != MHD_connection_get_fdset (con_itr, 86 if (MHD_YES != MHD_connection_get_fdset (con_itr,
87 read_fd_set, 87 read_fd_set,
88 write_fd_set, 88 write_fd_set,
89 except_fd_set, max_fd)) 89 except_fd_set, max_fd))
90 return MHD_NO; 90 return MHD_NO;
91 con_itr = con_itr->next; 91 con_itr = con_itr->next;
92 } 92 }
93#if DEBUG_CONNECT 93#if DEBUG_CONNECT
94 MHD_DLOG (daemon, "Maximum socket in select set: %d\n", *max_fd); 94 MHD_DLOG (daemon, "Maximum socket in select set: %d\n", *max_fd);
95#endif 95#endif
96 return MHD_YES; 96 return MHD_YES;
97 } 97}
98 98
99/** 99/**
100 * Main function of the thread that handles an individual 100 * Main function of the thread that handles an individual
101 * connection. 101 * connection.
102 */ 102 */
103static void * MHD_handle_connection(void *data) 103static void *
104 { 104MHD_handle_connection (void *data)
105 struct MHD_Connection *con = data; 105{
106 int num_ready; 106 struct MHD_Connection *con = data;
107 fd_set rs; 107 int num_ready;
108 fd_set ws; 108 fd_set rs;
109 fd_set es; 109 fd_set ws;
110 int max; 110 fd_set es;
111 struct timeval tv; 111 int max;
112 unsigned int timeout; 112 struct timeval tv;
113 unsigned int now; 113 unsigned int timeout;
114 114 unsigned int now;
115 if (con == NULL) 115
116 abort(); 116 if (con == NULL)
117 timeout = con->daemon->connection_timeout; 117 abort ();
118 while ((!con->daemon->shutdown) && (con->socket_fd != -1)) 118 timeout = con->daemon->connection_timeout;
119 { 119 while ((!con->daemon->shutdown) && (con->socket_fd != -1))
120 FD_ZERO (&rs); 120 {
121 FD_ZERO (&ws); 121 FD_ZERO (&rs);
122 FD_ZERO (&es); 122 FD_ZERO (&ws);
123 max = 0; 123 FD_ZERO (&es);
124 MHD_connection_get_fdset(con, &rs, &ws, &es, &max); 124 max = 0;
125 now = time(NULL); 125 MHD_connection_get_fdset (con, &rs, &ws, &es, &max);
126 tv.tv_usec = 0; 126 now = time (NULL);
127 if (timeout > (now - con->last_activity)) 127 tv.tv_usec = 0;
128 tv.tv_sec = timeout - (now - con->last_activity); 128 if (timeout > (now - con->last_activity))
129 else 129 tv.tv_sec = timeout - (now - con->last_activity);
130 tv.tv_sec = 0; 130 else
131 num_ready = SELECT (max + 1, 131 tv.tv_sec = 0;
132 &rs, &ws, &es, (timeout != 0) ? &tv : NULL); 132 num_ready = SELECT (max + 1,
133 if (num_ready < 0) 133 &rs, &ws, &es, (timeout != 0) ? &tv : NULL);
134 { 134 if (num_ready < 0)
135 if (errno == EINTR) 135 {
136 continue; 136 if (errno == EINTR)
137 continue;
137#if HAVE_MESSAGES 138#if HAVE_MESSAGES
138 MHD_DLOG(con->daemon, "Error during select (%d): `%s'\n", max, 139 MHD_DLOG (con->daemon, "Error during select (%d): `%s'\n", max,
139 STRERROR (errno)); 140 STRERROR (errno));
140#endif 141#endif
141 break; 142 break;
142 } 143 }
143 if (FD_ISSET (con->socket_fd, &rs)) 144 if (FD_ISSET (con->socket_fd, &rs))
144 MHD_connection_handle_read(con); 145 MHD_connection_handle_read (con);
145 if ((con->socket_fd != -1) && (FD_ISSET (con->socket_fd, &ws))) 146 if ((con->socket_fd != -1) && (FD_ISSET (con->socket_fd, &ws)))
146 MHD_connection_handle_write(con); 147 MHD_connection_handle_write (con);
147 if (con->socket_fd != -1) 148 if (con->socket_fd != -1)
148 MHD_connection_handle_idle(con); 149 MHD_connection_handle_idle (con);
149 } 150 }
150 if (con->socket_fd != -1) 151 if (con->socket_fd != -1)
151 { 152 {
152#if DEBUG_CLOSE 153#if DEBUG_CLOSE
153#if HAVE_MESSAGES 154#if HAVE_MESSAGES
154 MHD_DLOG (con->daemon, 155 MHD_DLOG (con->daemon,
155 "Processing thread terminating, closing connection\n"); 156 "Processing thread terminating, closing connection\n");
156#endif 157#endif
157#endif 158#endif
158 SHUTDOWN (con->socket_fd, SHUT_RDWR); 159 SHUTDOWN (con->socket_fd, SHUT_RDWR);
159 CLOSE (con->socket_fd); 160 CLOSE (con->socket_fd);
160 con->socket_fd = -1; 161 con->socket_fd = -1;
161 } 162 }
162 return NULL; 163 return NULL;
163 } 164}
164 165
165/** 166/**
166 * Handle an individual TLS connection. 167 * Handle an individual TLS connection.
167 */ 168 */
168static void * MHDS_handle_connection(void *data) 169static void *
169 { 170MHDS_handle_connection (void *data)
170 struct MHD_Connection *con = data; 171{
172 struct MHD_Connection *con = data;
171 173
172 if (con == NULL) 174 if (con == NULL)
173 abort(); 175 abort ();
174 176
175 /* forward call to handler */ 177 /* forward call to handler */
176 con->daemon->default_handler(NULL, con, NULL, NULL, NULL, NULL, NULL, 178 con->daemon->default_handler (NULL, con, NULL, NULL, NULL, NULL, NULL,
177 NULL); 179 NULL);
178 180
179 return NULL; 181 return NULL;
180 } 182}
181 183
182/** 184/**
183 * Accept an incoming connection and create the MHD_Connection object for 185 * Accept an incoming connection and create the MHD_Connection object for
184 * it. This function also enforces policy by way of checking with the 186 * it. This function also enforces policy by way of checking with the
185 * accept policy callback. 187 * accept policy callback.
186 */ 188 */
187static int MHD_accept_connection(struct MHD_Daemon *daemon) 189static int
188 { 190MHD_accept_connection (struct MHD_Daemon *daemon)
189 struct MHD_Connection *pos; 191{
190 struct MHD_Connection *connection; 192 struct MHD_Connection *pos;
191 struct sockaddr_in6 addr6; 193 struct MHD_Connection *connection;
192 struct sockaddr *addr = (struct sockaddr *) &addr6; 194 struct sockaddr_in6 addr6;
193 socklen_t addrlen; 195 struct sockaddr *addr = (struct sockaddr *) &addr6;
194 unsigned int have; 196 socklen_t addrlen;
195 int s, res_thread_create; 197 unsigned int have;
198 int s, res_thread_create;
196#if OSX 199#if OSX
197 static int on = 1; 200 static int on = 1;
198#endif 201#endif
199 202
200 if (sizeof(struct sockaddr) > sizeof(struct sockaddr_in6)) 203 if (sizeof (struct sockaddr) > sizeof (struct sockaddr_in6))
201 abort(); /* fatal, serious error */ 204 abort (); /* fatal, serious error */
202 addrlen = sizeof(struct sockaddr_in6); 205 addrlen = sizeof (struct sockaddr_in6);
203 memset(addr, 0, sizeof(struct sockaddr_in6)); 206 memset (addr, 0, sizeof (struct sockaddr_in6));
204 207
205 s = ACCEPT (daemon->socket_fd, addr, &addrlen); 208 s = ACCEPT (daemon->socket_fd, addr, &addrlen);
206 209
207 if ((s < 0) || (addrlen <= 0)) 210 if ((s < 0) || (addrlen <= 0))
208 { 211 {
209#if HAVE_MESSAGES 212#if HAVE_MESSAGES
210 MHD_DLOG(daemon, "Error accepting connection: %s\n", STRERROR (errno)); 213 MHD_DLOG (daemon, "Error accepting connection: %s\n", STRERROR (errno));
211#endif 214#endif
212 if (s != -1) 215 if (s != -1)
213 { 216 {
214 SHUTDOWN (s, SHUT_RDWR); 217 SHUTDOWN (s, SHUT_RDWR);
215 CLOSE (s); 218 CLOSE (s);
216 /* just in case */ 219 /* just in case */
217 } 220 }
218 return MHD_NO; 221 return MHD_NO;
219 } 222 }
220#if DEBUG_CONNECT 223#if DEBUG_CONNECT
221 MHD_DLOG (daemon, "Accepted connection on socket %d\n", s); 224 MHD_DLOG (daemon, "Accepted connection on socket %d\n", s);
222#endif 225#endif
223 have = 0; 226 have = 0;
224 if ((daemon->per_ip_connection_limit != 0) && (daemon->max_connections > 0)) 227 if ((daemon->per_ip_connection_limit != 0) && (daemon->max_connections > 0))
225 { 228 {
226 pos = daemon->connections; 229 pos = daemon->connections;
227 while (pos != NULL) 230 while (pos != NULL)
228 { 231 {
229 if ((pos->addr != NULL) && (pos->addr_len == addrlen)) 232 if ((pos->addr != NULL) && (pos->addr_len == addrlen))
230 { 233 {
231 if (addrlen == sizeof(struct sockaddr_in)) 234 if (addrlen == sizeof (struct sockaddr_in))
232 { 235 {
233 const struct sockaddr_in *a1 = 236 const struct sockaddr_in *a1 =
234 (const struct sockaddr_in *) &addr; 237 (const struct sockaddr_in *) &addr;
235 const struct sockaddr_in *a2 = 238 const struct sockaddr_in *a2 =
236 (const struct sockaddr_in *) pos->addr; 239 (const struct sockaddr_in *) pos->addr;
237 if (0 == memcmp(&a1->sin_addr, &a2->sin_addr, 240 if (0 == memcmp (&a1->sin_addr, &a2->sin_addr,
238 sizeof(struct in_addr))) 241 sizeof (struct in_addr)))
239 have++; 242 have++;
240 } 243 }
241 if (addrlen == sizeof(struct sockaddr_in6)) 244 if (addrlen == sizeof (struct sockaddr_in6))
242 { 245 {
243 const struct sockaddr_in6 *a1 = 246 const struct sockaddr_in6 *a1 =
244 (const struct sockaddr_in6 *) &addr; 247 (const struct sockaddr_in6 *) &addr;
245 const struct sockaddr_in6 *a2 = 248 const struct sockaddr_in6 *a2 =
246 (const struct sockaddr_in6 *) pos->addr; 249 (const struct sockaddr_in6 *) pos->addr;
247 if (0 == memcmp(&a1->sin6_addr, &a2->sin6_addr, 250 if (0 == memcmp (&a1->sin6_addr, &a2->sin6_addr,
248 sizeof(struct in6_addr))) 251 sizeof (struct in6_addr)))
249 have++; 252 have++;
250 } 253 }
251 } 254 }
252 pos = pos->next; 255 pos = pos->next;
253 } 256 }
254 } 257 }
255 258
256 if ((daemon->max_connections == 0) || ((daemon->per_ip_connection_limit 259 if ((daemon->max_connections == 0) || ((daemon->per_ip_connection_limit
257 != 0) && (daemon-> 260 != 0) && (daemon->
258 per_ip_connection_limit <= have))) 261 per_ip_connection_limit <=
259 { 262 have)))
260 /* above connection limit - reject */ 263 {
264 /* above connection limit - reject */
261#if HAVE_MESSAGES 265#if HAVE_MESSAGES
262 MHD_DLOG(daemon, 266 MHD_DLOG (daemon,
263 "Server reached connection limit (closing inbound connection)\n"); 267 "Server reached connection limit (closing inbound connection)\n");
264#endif 268#endif
265 SHUTDOWN (s, SHUT_RDWR); 269 SHUTDOWN (s, SHUT_RDWR);
266 CLOSE (s); 270 CLOSE (s);
267 return MHD_NO; 271 return MHD_NO;
268 } 272 }
269 if ((daemon->apc != NULL) && (MHD_NO == daemon->apc (daemon->apc_cls, addr, addrlen))) 273 if ((daemon->apc != NULL)
270 { 274 && (MHD_NO == daemon->apc (daemon->apc_cls, addr, addrlen)))
275 {
271#if DEBUG_CLOSE 276#if DEBUG_CLOSE
272#if HAVE_MESSAGES 277#if HAVE_MESSAGES
273 MHD_DLOG (daemon, "Connection rejected, closing connection\n"); 278 MHD_DLOG (daemon, "Connection rejected, closing connection\n");
274#endif 279#endif
275#endif 280#endif
276 SHUTDOWN (s, SHUT_RDWR); 281 SHUTDOWN (s, SHUT_RDWR);
277 CLOSE (s); 282 CLOSE (s);
278 return MHD_YES; 283 return MHD_YES;
279 } 284 }
280#if OSX 285#if OSX
281#ifdef SOL_SOCKET 286#ifdef SOL_SOCKET
282#ifdef SO_NOSIGPIPE 287#ifdef SO_NOSIGPIPE
283 setsockopt (s, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof (on)); 288 setsockopt (s, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof (on));
284#endif 289#endif
285#endif 290#endif
286#endif 291#endif
287 connection = malloc(sizeof(struct MHD_Connection)); 292 connection = malloc (sizeof (struct MHD_Connection));
288 if (connection == NULL) 293 if (connection == NULL)
289 { 294 {
290#if HAVE_MESSAGES 295#if HAVE_MESSAGES
291 MHD_DLOG(daemon, "Error allocating memory: %s\n", STRERROR (errno)); 296 MHD_DLOG (daemon, "Error allocating memory: %s\n", STRERROR (errno));
292#endif 297#endif
293 SHUTDOWN (s, SHUT_RDWR); 298 SHUTDOWN (s, SHUT_RDWR);
294 CLOSE (s); 299 CLOSE (s);
295 return MHD_NO; 300 return MHD_NO;
296 } 301 }
297 memset(connection, 0, sizeof(struct MHD_Connection)); 302 memset (connection, 0, sizeof (struct MHD_Connection));
298 connection->pool = NULL; 303 connection->pool = NULL;
299 connection->addr = malloc(addrlen); 304 connection->addr = malloc (addrlen);
300 if (connection->addr == NULL) 305 if (connection->addr == NULL)
301 { 306 {
302#if HAVE_MESSAGES 307#if HAVE_MESSAGES
303 MHD_DLOG(daemon, "Error allocating memory: %s\n", STRERROR (errno)); 308 MHD_DLOG (daemon, "Error allocating memory: %s\n", STRERROR (errno));
304#endif 309#endif
305 SHUTDOWN (s, SHUT_RDWR); 310 SHUTDOWN (s, SHUT_RDWR);
306 CLOSE (s); 311 CLOSE (s);
307 free(connection); 312 free (connection);
308 return MHD_NO; 313 return MHD_NO;
309 } 314 }
310 memcpy(connection->addr, addr, addrlen); 315 memcpy (connection->addr, addr, addrlen);
311 connection->addr_len = addrlen; 316 connection->addr_len = addrlen;
312 connection->socket_fd = s; 317 connection->socket_fd = s;
313 connection->daemon = daemon; 318 connection->daemon = daemon;
314 319
315 /* attempt to create handler thread */ 320 /* attempt to create handler thread */
316 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 321 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
317 { 322 {
318 if (daemon->options & MHD_USE_SSL) 323 if (daemon->options & MHD_USE_SSL)
319 res_thread_create= pthread_create(&connection->pid, NULL, 324 res_thread_create = pthread_create (&connection->pid, NULL,
320 &MHDS_handle_connection, connection); 325 &MHDS_handle_connection,
321 else 326 connection);
322 { 327 else
323 res_thread_create= pthread_create(&connection->pid, NULL, 328 {
324 &MHD_handle_connection, connection); 329 res_thread_create = pthread_create (&connection->pid, NULL,
325 } 330 &MHD_handle_connection,
326 if (res_thread_create != 0) 331 connection);
327 { 332 }
333 if (res_thread_create != 0)
334 {
328#if HAVE_MESSAGES 335#if HAVE_MESSAGES
329 MHD_DLOG(daemon, "Failed to create a thread: %s\n", STRERROR (errno)); 336 MHD_DLOG (daemon, "Failed to create a thread: %s\n",
337 STRERROR (errno));
330#endif 338#endif
331 SHUTDOWN (s, SHUT_RDWR); 339 SHUTDOWN (s, SHUT_RDWR);
332 CLOSE (s); 340 CLOSE (s);
333 free(connection->addr); 341 free (connection->addr);
334 free(connection); 342 free (connection);
335 return MHD_NO; 343 return MHD_NO;
336 } 344 }
337 } 345 }
338 346
339 connection->last_activity = time(NULL); 347 connection->last_activity = time (NULL);
340 connection->next = daemon->connections; 348 connection->next = daemon->connections;
341 daemon->connections = connection; 349 daemon->connections = connection;
342 daemon->max_connections--; 350 daemon->max_connections--;
343 return MHD_YES; 351 return MHD_YES;
344 } 352}
345 353
346/** 354/**
347 * Free resources associated with all closed connections. 355 * Free resources associated with all closed connections.
348 * (destroy responses, free buffers, etc.). A connection 356 * (destroy responses, free buffers, etc.). A connection
349 * is known to be closed if the socket_fd is -1. 357 * is known to be closed if the socket_fd is -1.
350 */ 358 */
351static void MHD_cleanup_connections(struct MHD_Daemon *daemon) 359static void
352 { 360MHD_cleanup_connections (struct MHD_Daemon *daemon)
353 struct MHD_Connection *pos; 361{
354 struct MHD_Connection *prev; 362 struct MHD_Connection *pos;
355 void *unused; 363 struct MHD_Connection *prev;
356 364 void *unused;
357 pos = daemon->connections; 365
358 prev = NULL; 366 pos = daemon->connections;
359 while (pos != NULL) 367 prev = NULL;
360 { 368 while (pos != NULL)
361 if (pos->socket_fd == -1) 369 {
362 { 370 if (pos->socket_fd == -1)
363 if (prev == NULL) 371 {
364 daemon->connections = pos->next; 372 if (prev == NULL)
365 else 373 daemon->connections = pos->next;
366 prev->next = pos->next; 374 else
367 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 375 prev->next = pos->next;
368 { 376 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
369 pthread_kill(pos->pid, SIGALRM); 377 {
370 pthread_join(pos->pid, &unused); 378 pthread_kill (pos->pid, SIGALRM);
371 } 379 pthread_join (pos->pid, &unused);
372 MHD_destroy_response(pos->response); 380 }
373 MHD_pool_destroy(pos->pool); 381 MHD_destroy_response (pos->response);
374 free(pos->addr); 382 MHD_pool_destroy (pos->pool);
375 free(pos); 383 free (pos->addr);
376 daemon->max_connections++; 384 free (pos);
377 if (prev == NULL) 385 daemon->max_connections++;
378 pos = daemon->connections; 386 if (prev == NULL)
379 else 387 pos = daemon->connections;
380 pos = prev->next; 388 else
381 continue; 389 pos = prev->next;
382 } 390 continue;
383 prev = pos; 391 }
384 pos = pos->next; 392 prev = pos;
385 } 393 pos = pos->next;
386 } 394 }
395}
387 396
388/** 397/**
389 * Obtain timeout value for select for this daemon 398 * Obtain timeout value for select for this daemon
@@ -396,34 +405,35 @@ static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
396 * not used (or no connections exist that would 405 * not used (or no connections exist that would
397 * necessiate the use of a timeout right now). 406 * necessiate the use of a timeout right now).
398 */ 407 */
399int MHD_get_timeout(struct MHD_Daemon *daemon, unsigned long long *timeout) 408int
400 { 409MHD_get_timeout (struct MHD_Daemon *daemon, unsigned long long *timeout)
401 time_t earliest_deadline; 410{
402 time_t now; 411 time_t earliest_deadline;
403 struct MHD_Connection *pos; 412 time_t now;
404 unsigned int dto; 413 struct MHD_Connection *pos;
405 414 unsigned int dto;
406 dto = daemon->connection_timeout; 415
407 if (0 == dto) 416 dto = daemon->connection_timeout;
408 return MHD_NO; 417 if (0 == dto)
409 pos = daemon->connections; 418 return MHD_NO;
410 if (pos == NULL) 419 pos = daemon->connections;
411 return MHD_NO; /* no connections */ 420 if (pos == NULL)
412 now = time(NULL); 421 return MHD_NO; /* no connections */
413 /* start with conservative estimate */ 422 now = time (NULL);
414 earliest_deadline = now + dto; 423 /* start with conservative estimate */
415 while (pos != NULL) 424 earliest_deadline = now + dto;
416 { 425 while (pos != NULL)
417 if (earliest_deadline > pos->last_activity + dto) 426 {
418 earliest_deadline = pos->last_activity + dto; 427 if (earliest_deadline > pos->last_activity + dto)
419 pos = pos->next; 428 earliest_deadline = pos->last_activity + dto;
420 } 429 pos = pos->next;
421 if (earliest_deadline < now) 430 }
422 *timeout = 0; 431 if (earliest_deadline < now)
423 else 432 *timeout = 0;
424 *timeout = (earliest_deadline - now); 433 else
425 return MHD_YES; 434 *timeout = (earliest_deadline - now);
426 } 435 return MHD_YES;
436}
427 437
428/** 438/**
429 * Main select call. 439 * Main select call.
@@ -431,102 +441,103 @@ int MHD_get_timeout(struct MHD_Daemon *daemon, unsigned long long *timeout)
431 * @param may_block YES if blocking, NO if non-blocking 441 * @param may_block YES if blocking, NO if non-blocking
432 * @return MHD_NO on serious errors, MHD_YES on success 442 * @return MHD_NO on serious errors, MHD_YES on success
433 */ 443 */
434static int MHD_select(struct MHD_Daemon *daemon, int may_block) 444static int
435 { 445MHD_select (struct MHD_Daemon *daemon, int may_block)
436 struct MHD_Connection *pos; 446{
437 int num_ready; 447 struct MHD_Connection *pos;
438 fd_set rs; 448 int num_ready;
439 fd_set ws; 449 fd_set rs;
440 fd_set es; 450 fd_set ws;
441 int max; 451 fd_set es;
442 struct timeval timeout; 452 int max;
443 unsigned long long ltimeout; 453 struct timeval timeout;
444 int ds; 454 unsigned long long ltimeout;
445 time_t now; 455 int ds;
446 456 time_t now;
447 timeout.tv_sec = 0; 457
448 timeout.tv_usec = 0; 458 timeout.tv_sec = 0;
449 if (daemon == NULL) 459 timeout.tv_usec = 0;
450 abort(); 460 if (daemon == NULL)
451 if (daemon->shutdown == MHD_YES) 461 abort ();
452 return MHD_NO; 462 if (daemon->shutdown == MHD_YES)
453 FD_ZERO (&rs); 463 return MHD_NO;
454 FD_ZERO (&ws); 464 FD_ZERO (&rs);
455 FD_ZERO (&es); 465 FD_ZERO (&ws);
456 max = 0; 466 FD_ZERO (&es);
457 467 max = 0;
458 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 468
459 { 469 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
460 /* single-threaded, go over everything */ 470 {
461 if (MHD_NO == MHD_get_fdset (daemon, &rs, &ws, &es, &max)) 471 /* single-threaded, go over everything */
462 return MHD_NO; 472 if (MHD_NO == MHD_get_fdset (daemon, &rs, &ws, &es, &max))
463 } 473 return MHD_NO;
464 else 474 }
465 { 475 else
466 /* accept only, have one thread per connection */ 476 {
467 max = daemon->socket_fd; 477 /* accept only, have one thread per connection */
468 if (max == -1) 478 max = daemon->socket_fd;
469 return MHD_NO; 479 if (max == -1)
470 FD_SET (max, &rs); 480 return MHD_NO;
471 } 481 FD_SET (max, &rs);
472 482 }
473 if (may_block == MHD_NO) 483
474 { 484 if (may_block == MHD_NO)
475 timeout.tv_usec = 0; 485 {
476 timeout.tv_sec = 0; 486 timeout.tv_usec = 0;
477 } 487 timeout.tv_sec = 0;
478 else 488 }
479 { 489 else
480 /* ltimeout is in ms */ 490 {
481 if (MHD_YES == MHD_get_timeout (daemon, &ltimeout)) 491 /* ltimeout is in ms */
482 { 492 if (MHD_YES == MHD_get_timeout (daemon, &ltimeout))
483 timeout.tv_usec = (ltimeout % 1000) * 1000; 493 {
484 timeout.tv_sec = ltimeout / 1000; 494 timeout.tv_usec = (ltimeout % 1000) * 1000;
485 may_block = MHD_NO; 495 timeout.tv_sec = ltimeout / 1000;
486 } 496 may_block = MHD_NO;
487 } 497 }
488 498 }
489 num_ready = select(max + 1, &rs, &ws, &es, may_block == MHD_NO ? &timeout 499
490 : NULL); 500 num_ready = select (max + 1, &rs, &ws, &es, may_block == MHD_NO ? &timeout
491 501 : NULL);
492 if (daemon->shutdown == MHD_YES) 502
493 return MHD_NO; 503 if (daemon->shutdown == MHD_YES)
494 if (num_ready < 0) 504 return MHD_NO;
495 { 505 if (num_ready < 0)
496 if (errno == EINTR) 506 {
497 return MHD_YES; 507 if (errno == EINTR)
508 return MHD_YES;
498#if HAVE_MESSAGES 509#if HAVE_MESSAGES
499 MHD_DLOG(daemon, "Select failed: %s\n", STRERROR (errno)); 510 MHD_DLOG (daemon, "Select failed: %s\n", STRERROR (errno));
500#endif 511#endif
501 return MHD_NO; 512 return MHD_NO;
502 } 513 }
503 ds = daemon->socket_fd; 514 ds = daemon->socket_fd;
504 if (ds == -1) 515 if (ds == -1)
505 return MHD_YES;
506 if (__FD_ISSET (ds, &rs))
507 MHD_accept_connection(daemon);
508 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
509 {
510 /* do not have a thread per connection, process all connections now */
511 now = time(NULL);
512 pos = daemon->connections;
513 while (pos != NULL)
514 {
515 ds = pos->socket_fd;
516 if (ds != -1)
517 {
518 if (FD_ISSET (ds, &rs))
519 MHD_connection_handle_read(pos);
520 if ((pos->socket_fd != -1) && (FD_ISSET (ds, &ws)))
521 MHD_connection_handle_write(pos);
522 if (pos->socket_fd != -1)
523 MHD_connection_handle_idle(pos);
524 }
525 pos = pos->next;
526 }
527 }
528 return MHD_YES; 516 return MHD_YES;
529 } 517 if (__FD_ISSET (ds, &rs))
518 MHD_accept_connection (daemon);
519 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
520 {
521 /* do not have a thread per connection, process all connections now */
522 now = time (NULL);
523 pos = daemon->connections;
524 while (pos != NULL)
525 {
526 ds = pos->socket_fd;
527 if (ds != -1)
528 {
529 if (FD_ISSET (ds, &rs))
530 MHD_connection_handle_read (pos);
531 if ((pos->socket_fd != -1) && (FD_ISSET (ds, &ws)))
532 MHD_connection_handle_write (pos);
533 if (pos->socket_fd != -1)
534 MHD_connection_handle_idle (pos);
535 }
536 pos = pos->next;
537 }
538 }
539 return MHD_YES;
540}
530 541
531/** 542/**
532 * Run webserver operations (without blocking unless 543 * Run webserver operations (without blocking unless
@@ -538,31 +549,33 @@ static int MHD_select(struct MHD_Daemon *daemon, int may_block)
538 * daemon was not started with the right 549 * daemon was not started with the right
539 * options for this call. 550 * options for this call.
540 */ 551 */
541int MHD_run(struct MHD_Daemon *daemon) 552int
542 { 553MHD_run (struct MHD_Daemon *daemon)
543 if ((daemon->shutdown != MHD_NO) || (0 != (daemon->options 554{
544 & MHD_USE_THREAD_PER_CONNECTION)) || (0 != (daemon->options 555 if ((daemon->shutdown != MHD_NO) || (0 != (daemon->options
545 & MHD_USE_SELECT_INTERNALLY))) 556 & MHD_USE_THREAD_PER_CONNECTION))
546 return MHD_NO; 557 || (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)))
547 MHD_select(daemon, MHD_NO); 558 return MHD_NO;
548 MHD_cleanup_connections(daemon); 559 MHD_select (daemon, MHD_NO);
549 return MHD_YES; 560 MHD_cleanup_connections (daemon);
550 } 561 return MHD_YES;
562}
551 563
552/** 564/**
553 * Thread that runs the select loop until the daemon 565 * Thread that runs the select loop until the daemon
554 * is explicitly shut down. 566 * is explicitly shut down.
555 */ 567 */
556static void * MHD_select_thread(void *cls) 568static void *
557 { 569MHD_select_thread (void *cls)
558 struct MHD_Daemon *daemon = cls; 570{
559 while (daemon->shutdown == MHD_NO) 571 struct MHD_Daemon *daemon = cls;
560 { 572 while (daemon->shutdown == MHD_NO)
561 MHD_select(daemon, MHD_YES); 573 {
562 MHD_cleanup_connections(daemon); 574 MHD_select (daemon, MHD_YES);
563 } 575 MHD_cleanup_connections (daemon);
564 return NULL; 576 }
565 } 577 return NULL;
578}
566 579
567/** 580/**
568 * Start a webserver on the given port. 581 * Start a webserver on the given port.
@@ -575,119 +588,118 @@ static void * MHD_select_thread(void *cls)
575 * @param dh_cls extra argument to dh 588 * @param dh_cls extra argument to dh
576 * @return NULL on error, handle to daemon on success 589 * @return NULL on error, handle to daemon on success
577 */ 590 */
578struct MHD_Daemon * MHD_start_daemon(unsigned int options, 591struct MHD_Daemon *
579 unsigned short port, 592MHD_start_daemon (unsigned int options,
580 MHD_AcceptPolicyCallback apc, 593 unsigned short port,
581 void *apc_cls, 594 MHD_AcceptPolicyCallback apc,
582 MHD_AccessHandlerCallback dh, 595 void *apc_cls,
583 void *dh_cls, 596 MHD_AccessHandlerCallback dh, void *dh_cls, ...)
584 ...) 597{
585 { 598 const int on = 1;
586 const int on = 1; 599 struct MHD_Daemon *retVal;
587 struct MHD_Daemon *retVal; 600
588 601 /* listeningss sockets used by the daemon */
589 /* listeningss sockets used by the daemon */ 602 int socket_fd;
590 int socket_fd; 603
591 604 struct sockaddr_in servaddr4;
592 struct sockaddr_in servaddr4; 605 struct sockaddr_in6 servaddr6;
593 struct sockaddr_in6 servaddr6; 606 const struct sockaddr *servaddr;
594 const struct sockaddr *servaddr; 607 socklen_t addrlen;
595 socklen_t addrlen; 608 va_list ap;
596 va_list ap; 609 enum MHD_OPTION opt;
597 enum MHD_OPTION opt; 610
598 611 if ((port == 0) || (dh == NULL))
599 if ((port == 0) || (dh == NULL)) 612 return NULL;
600 return NULL; 613 if ((options & MHD_USE_IPv6) != 0)
601 if ((options & MHD_USE_IPv6) != 0) 614 socket_fd = SOCKET (PF_INET6, SOCK_STREAM, 0);
602 socket_fd = SOCKET (PF_INET6, SOCK_STREAM, 0); 615 else
603 else 616 socket_fd = SOCKET (PF_INET, SOCK_STREAM, 0);
604 socket_fd = SOCKET (PF_INET, SOCK_STREAM, 0); 617 if (socket_fd < 0)
605 if (socket_fd < 0) 618 {
606 {
607#if HAVE_MESSAGES 619#if HAVE_MESSAGES
608 if ((options & MHD_USE_DEBUG) != 0) 620 if ((options & MHD_USE_DEBUG) != 0)
609 fprintf(stderr, "Call to socket failed: %s\n", STRERROR (errno)); 621 fprintf (stderr, "Call to socket failed: %s\n", STRERROR (errno));
610#endif 622#endif
611 return NULL; 623 return NULL;
612 } 624 }
613 if ((SETSOCKOPT (socket_fd, 625 if ((SETSOCKOPT (socket_fd,
614 SOL_SOCKET, 626 SOL_SOCKET,
615 SO_REUSEADDR, 627 SO_REUSEADDR,
616 &on, sizeof (on)) < 0) && (options & MHD_USE_DEBUG) != 0) 628 &on, sizeof (on)) < 0) && (options & MHD_USE_DEBUG) != 0)
617 { 629 {
618#if HAVE_MESSAGES 630#if HAVE_MESSAGES
619 fprintf(stderr, "setsockopt failed: %s\n", STRERROR (errno)); 631 fprintf (stderr, "setsockopt failed: %s\n", STRERROR (errno));
620#endif 632#endif
621 } 633 }
622 if ((options & MHD_USE_IPv6) != 0) 634 if ((options & MHD_USE_IPv6) != 0)
623 { 635 {
624 memset(&servaddr6, 0, sizeof(struct sockaddr_in6)); 636 memset (&servaddr6, 0, sizeof (struct sockaddr_in6));
625 servaddr6.sin6_family = AF_INET6; 637 servaddr6.sin6_family = AF_INET6;
626 servaddr6.sin6_port = htons(port); 638 servaddr6.sin6_port = htons (port);
627 servaddr = (struct sockaddr *) &servaddr6; 639 servaddr = (struct sockaddr *) &servaddr6;
628 addrlen = sizeof(struct sockaddr_in6); 640 addrlen = sizeof (struct sockaddr_in6);
629 } 641 }
630 else 642 else
631 { 643 {
632 memset(&servaddr4, 0, sizeof(struct sockaddr_in)); 644 memset (&servaddr4, 0, sizeof (struct sockaddr_in));
633 servaddr4.sin_family = AF_INET; 645 servaddr4.sin_family = AF_INET;
634 servaddr4.sin_port = htons(port); 646 servaddr4.sin_port = htons (port);
635 servaddr = (struct sockaddr *) &servaddr4; 647 servaddr = (struct sockaddr *) &servaddr4;
636 addrlen = sizeof(struct sockaddr_in); 648 addrlen = sizeof (struct sockaddr_in);
637 } 649 }
638 if (BIND (socket_fd, servaddr, addrlen) < 0) 650 if (BIND (socket_fd, servaddr, addrlen) < 0)
639 { 651 {
640#if HAVE_MESSAGES 652#if HAVE_MESSAGES
641 if ((options & MHD_USE_DEBUG) != 0) 653 if ((options & MHD_USE_DEBUG) != 0)
642 fprintf(stderr, 654 fprintf (stderr,
643 "Failed to bind to port %u: %s\n", port, STRERROR (errno)); 655 "Failed to bind to port %u: %s\n", port, STRERROR (errno));
644#endif 656#endif
645 CLOSE (socket_fd); 657 CLOSE (socket_fd);
646 return NULL; 658 return NULL;
647 } 659 }
648 if (LISTEN (socket_fd, 20) < 0) 660 if (LISTEN (socket_fd, 20) < 0)
649 { 661 {
650#if HAVE_MESSAGES 662#if HAVE_MESSAGES
651 if ((options & MHD_USE_DEBUG) != 0) 663 if ((options & MHD_USE_DEBUG) != 0)
652 fprintf(stderr, 664 fprintf (stderr,
653 "Failed to listen for connections: %s\n", STRERROR (errno)); 665 "Failed to listen for connections: %s\n", STRERROR (errno));
654#endif 666#endif
655 CLOSE (socket_fd); 667 CLOSE (socket_fd);
656 return NULL; 668 return NULL;
657 } 669 }
658 670
659 /* allocate the mhd daemon */ 671 /* allocate the mhd daemon */
660 672
661 retVal = malloc(sizeof(struct MHD_Daemon)); 673 retVal = malloc (sizeof (struct MHD_Daemon));
662 674
663 if (retVal == NULL) 675 if (retVal == NULL)
664 { 676 {
665 CLOSE (socket_fd); 677 CLOSE (socket_fd);
666 return NULL; 678 return NULL;
667 } 679 }
668 680
669 memset(retVal, 0, sizeof(struct MHD_Daemon)); 681 memset (retVal, 0, sizeof (struct MHD_Daemon));
670 retVal->options = options; 682 retVal->options = options;
671 retVal->port = port; 683 retVal->port = port;
672 retVal->apc = apc; 684 retVal->apc = apc;
673 retVal->apc_cls = apc_cls; 685 retVal->apc_cls = apc_cls;
674 retVal->socket_fd = socket_fd; 686 retVal->socket_fd = socket_fd;
675 retVal->default_handler = dh; 687 retVal->default_handler = dh;
676 retVal->default_handler_cls = dh_cls; 688 retVal->default_handler_cls = dh_cls;
677 retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT; 689 retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT;
678 retVal->pool_size = MHD_POOL_SIZE_DEFAULT; 690 retVal->pool_size = MHD_POOL_SIZE_DEFAULT;
679 retVal->connection_timeout = 0; /* no timeout */ 691 retVal->connection_timeout = 0; /* no timeout */
680 692
681 /* initializes the argument pointer variable */ 693 /* initializes the argument pointer variable */
682 va_start (ap, dh_cls); 694 va_start (ap, dh_cls);
683 695
684 /* 696 /*
685 * loop through daemon options 697 * loop through daemon options
686 */ 698 */
687 while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION))) 699 while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION)))
688 { 700 {
689 switch (opt) 701 switch (opt)
690 { 702 {
691 case MHD_OPTION_CONNECTION_MEMORY_LIMIT: 703 case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
692 retVal->pool_size = va_arg (ap, unsigned int); 704 retVal->pool_size = va_arg (ap, unsigned int);
693 break; 705 break;
@@ -698,7 +710,8 @@ struct MHD_Daemon * MHD_start_daemon(unsigned int options,
698 retVal->connection_timeout = va_arg (ap, unsigned int); 710 retVal->connection_timeout = va_arg (ap, unsigned int);
699 break; 711 break;
700 case MHD_OPTION_NOTIFY_COMPLETED: 712 case MHD_OPTION_NOTIFY_COMPLETED:
701 retVal->notify_completed = va_arg (ap, MHD_RequestCompletedCallback); 713 retVal->notify_completed =
714 va_arg (ap, MHD_RequestCompletedCallback);
702 retVal->notify_completed_cls = va_arg (ap, void *); 715 retVal->notify_completed_cls = va_arg (ap, void *);
703 break; 716 break;
704 case MHD_OPTION_PER_IP_CONNECTION_LIMIT: 717 case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
@@ -706,76 +719,82 @@ struct MHD_Daemon * MHD_start_daemon(unsigned int options,
706 break; 719 break;
707 default: 720 default:
708#if HAVE_MESSAGES 721#if HAVE_MESSAGES
709 fprintf(stderr, 722 fprintf (stderr,
710 "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); 723 "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n");
711#endif 724#endif
712 abort(); 725 abort ();
713 } 726 }
714 } 727 }
715 va_end (ap); 728 va_end (ap);
716 if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || (0 != (options 729 if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || (0 != (options
717 & MHD_USE_SELECT_INTERNALLY))) && (0 != pthread_create(&retVal->pid, 730 &
718 NULL, &MHD_select_thread, retVal))) 731 MHD_USE_SELECT_INTERNALLY)))
719 { 732 && (0 !=
733 pthread_create (&retVal->pid, NULL, &MHD_select_thread, retVal)))
734 {
720#if HAVE_MESSAGES 735#if HAVE_MESSAGES
721 MHD_DLOG(retVal, "Failed to create listen thread: %s\n", 736 MHD_DLOG (retVal, "Failed to create listen thread: %s\n",
722 STRERROR (errno)); 737 STRERROR (errno));
723#endif 738#endif
724 free(retVal); 739 free (retVal);
725 CLOSE (socket_fd); 740 CLOSE (socket_fd);
726 return NULL; 741 return NULL;
727 } 742 }
728 743
729 return retVal; 744 return retVal;
730 } 745}
731 746
732/** 747/**
733 * Shutdown an http daemon. 748 * Shutdown an http daemon.
734 */ 749 */
735void MHD_stop_daemon(struct MHD_Daemon *daemon) 750void
736 { 751MHD_stop_daemon (struct MHD_Daemon *daemon)
737 void *unused; 752{
738 int fd; 753 void *unused;
739 754 int fd;
740 if (daemon == NULL) 755
741 return; 756 if (daemon == NULL)
742 daemon->shutdown = MHD_YES; 757 return;
743 fd = daemon->socket_fd; 758 daemon->shutdown = MHD_YES;
744 daemon->socket_fd = -1; 759 fd = daemon->socket_fd;
760 daemon->socket_fd = -1;
745#if DEBUG_CLOSE 761#if DEBUG_CLOSE
746#if HAVE_MESSAGES 762#if HAVE_MESSAGES
747 MHD_DLOG (daemon, "MHD shutdown, closing listen socket\n"); 763 MHD_DLOG (daemon, "MHD shutdown, closing listen socket\n");
748#endif 764#endif
749#endif 765#endif
750 CLOSE (fd); 766 CLOSE (fd);
751 if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || (0 767 if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || (0
752 != (daemon-> 768 !=
753 options & MHD_USE_SELECT_INTERNALLY))) 769 (daemon->
754 { 770 options &
755 pthread_kill(daemon->pid, SIGALRM); 771 MHD_USE_SELECT_INTERNALLY)))
756 pthread_join(daemon->pid, &unused); 772 {
757 } 773 pthread_kill (daemon->pid, SIGALRM);
758 while (daemon->connections != NULL) 774 pthread_join (daemon->pid, &unused);
759 { 775 }
760 if (-1 != daemon->connections->socket_fd) 776 while (daemon->connections != NULL)
761 { 777 {
778 if (-1 != daemon->connections->socket_fd)
779 {
762#if DEBUG_CLOSE 780#if DEBUG_CLOSE
763#if HAVE_MESSAGES 781#if HAVE_MESSAGES
764 MHD_DLOG (daemon, "MHD shutdown, closing active connections\n"); 782 MHD_DLOG (daemon, "MHD shutdown, closing active connections\n");
765#endif 783#endif
766#endif 784#endif
767 if (daemon->notify_completed != NULL) 785 if (daemon->notify_completed != NULL)
768 daemon->notify_completed(daemon->notify_completed_cls, 786 daemon->notify_completed (daemon->notify_completed_cls,
769 daemon->connections, &daemon->connections->client_context, 787 daemon->connections,
770 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); 788 &daemon->connections->client_context,
771 SHUTDOWN (daemon->connections->socket_fd, SHUT_RDWR); 789 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN);
772 CLOSE (daemon->connections->socket_fd); 790 SHUTDOWN (daemon->connections->socket_fd, SHUT_RDWR);
773 daemon->connections->socket_fd = -1; 791 CLOSE (daemon->connections->socket_fd);
774 } 792 daemon->connections->socket_fd = -1;
775 MHD_cleanup_connections(daemon); 793 }
776 } 794 MHD_cleanup_connections (daemon);
777 free(daemon); 795 }
778 } 796 free (daemon);
797}
779 798
780#ifndef WINDOWS 799#ifndef WINDOWS
781 800
@@ -783,37 +802,38 @@ static struct sigaction sig;
783 802
784static struct sigaction old; 803static struct sigaction old;
785 804
786static void sigalrmHandler(int sig) 805static void
787 { 806sigalrmHandler (int sig)
788 } 807{
808}
789 809
790/** 810/**
791 * Initialize the signal handler for SIGALRM. 811 * Initialize the signal handler for SIGALRM.
792 */ 812 */
793void __attribute__ ((constructor)) MHD_pthread_handlers_ltdl_init() 813void __attribute__ ((constructor)) MHD_pthread_handlers_ltdl_init ()
794 { 814{
795 /* make sure SIGALRM does not kill us */ 815 /* make sure SIGALRM does not kill us */
796 memset(&sig, 0, sizeof(struct sigaction)); 816 memset (&sig, 0, sizeof (struct sigaction));
797 memset(&old, 0, sizeof(struct sigaction)); 817 memset (&old, 0, sizeof (struct sigaction));
798 sig.sa_flags = SA_NODEFER; 818 sig.sa_flags = SA_NODEFER;
799 sig.sa_handler = &sigalrmHandler; 819 sig.sa_handler = &sigalrmHandler;
800 sigaction(SIGALRM, &sig, &old); 820 sigaction (SIGALRM, &sig, &old);
801 } 821}
802 822
803void __attribute__ ((destructor)) MHD_pthread_handlers_ltdl_fini() 823void __attribute__ ((destructor)) MHD_pthread_handlers_ltdl_fini ()
804 { 824{
805 sigaction(SIGALRM, &old, &sig); 825 sigaction (SIGALRM, &old, &sig);
806 } 826}
807#else 827#else
808void __attribute__ ((constructor)) MHD_win_ltdl_init () 828void __attribute__ ((constructor)) MHD_win_ltdl_init ()
809 { 829{
810 plibc_init ("CRISP", "libmicrohttpd"); 830 plibc_init ("CRISP", "libmicrohttpd");
811 } 831}
812 832
813void __attribute__ ((destructor)) MHD_win_ltdl_fini () 833void __attribute__ ((destructor)) MHD_win_ltdl_fini ()
814 { 834{
815 plibc_shutdown (); 835 plibc_shutdown ();
816 } 836}
817#endif 837#endif
818 838
819/* end of daemon.c */ 839/* end of daemon.c */
diff --git a/src/daemon/internal.h b/src/daemon/internal.h
index a06d7ae2..37075bc0 100644
--- a/src/daemon/internal.h
+++ b/src/daemon/internal.h
@@ -63,101 +63,101 @@
63 * fprintf-like helper function for logging debug 63 * fprintf-like helper function for logging debug
64 * messages. 64 * messages.
65 */ 65 */
66void MHD_DLOG(const struct MHD_Daemon *daemon, const char *format, ...); 66void MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...);
67#endif 67#endif
68 68
69/** 69/**
70 * Process escape sequences ('+'=space, %HH). 70 * Process escape sequences ('+'=space, %HH).
71 * Updates val in place. 71 * Updates val in place.
72 */ 72 */
73void MHD_http_unescape(char *val); 73void MHD_http_unescape (char *val);
74 74
75/** 75/**
76 * Header or cookie in HTTP request or response. 76 * Header or cookie in HTTP request or response.
77 */ 77 */
78struct MHD_HTTP_Header 78struct MHD_HTTP_Header
79 { 79{
80 struct MHD_HTTP_Header *next; 80 struct MHD_HTTP_Header *next;
81 81
82 char *header; 82 char *header;
83 83
84 char *value; 84 char *value;
85 85
86 enum MHD_ValueKind kind; 86 enum MHD_ValueKind kind;
87 87
88 }; 88};
89 89
90/** 90/**
91 * Representation of a response. 91 * Representation of a response.
92 */ 92 */
93struct MHD_Response 93struct MHD_Response
94 { 94{
95 95
96 /** 96 /**
97 * Headers to send for the response. Initially 97 * Headers to send for the response. Initially
98 * the linked list is created in inverse order; 98 * the linked list is created in inverse order;
99 * the order should be inverted before sending! 99 * the order should be inverted before sending!
100 */ 100 */
101 struct MHD_HTTP_Header *first_header; 101 struct MHD_HTTP_Header *first_header;
102 102
103 /** 103 /**
104 * Buffer pointing to data that we are supposed 104 * Buffer pointing to data that we are supposed
105 * to send as a response. 105 * to send as a response.
106 */ 106 */
107 char *data; 107 char *data;
108 108
109 /** 109 /**
110 * Closure to give to the content reader 110 * Closure to give to the content reader
111 * free callback. 111 * free callback.
112 */ 112 */
113 void *crc_cls; 113 void *crc_cls;
114 114
115 /** 115 /**
116 * How do we get more data? NULL if we are 116 * How do we get more data? NULL if we are
117 * given all of the data up front. 117 * given all of the data up front.
118 */ 118 */
119 MHD_ContentReaderCallback crc; 119 MHD_ContentReaderCallback crc;
120 120
121 /** 121 /**
122 * NULL if data must not be freed, otherwise 122 * NULL if data must not be freed, otherwise
123 * either user-specified callback or "&free". 123 * either user-specified callback or "&free".
124 */ 124 */
125 MHD_ContentReaderFreeCallback crfc; 125 MHD_ContentReaderFreeCallback crfc;
126 126
127 /** 127 /**
128 * Mutex to synchronize access to data/size and 128 * Mutex to synchronize access to data/size and
129 * reference counts. 129 * reference counts.
130 */ 130 */
131 pthread_mutex_t mutex; 131 pthread_mutex_t mutex;
132 132
133 /** 133 /**
134 * Reference count for this response. Free 134 * Reference count for this response. Free
135 * once the counter hits zero. 135 * once the counter hits zero.
136 */ 136 */
137 unsigned int reference_count; 137 unsigned int reference_count;
138 138
139 /** 139 /**
140 * Set to -1 if size is not known. 140 * Set to -1 if size is not known.
141 */ 141 */
142 size_t total_size; 142 size_t total_size;
143 143
144 /** 144 /**
145 * Size of data. 145 * Size of data.
146 */ 146 */
147 size_t data_size; 147 size_t data_size;
148 148
149 /** 149 /**
150 * Size of the data buffer. 150 * Size of the data buffer.
151 */ 151 */
152 size_t data_buffer_size; 152 size_t data_buffer_size;
153 153
154 /** 154 /**
155 * At what offset in the stream is the 155 * At what offset in the stream is the
156 * beginning of data located? 156 * beginning of data located?
157 */ 157 */
158 size_t data_start; 158 size_t data_start;
159 159
160 }; 160};
161 161
162/** 162/**
163 * States in a state machine for a connection. 163 * States in a state machine for a connection.
@@ -174,151 +174,151 @@ struct MHD_Response
174 * requires the write to be complete. 174 * requires the write to be complete.
175 */ 175 */
176enum MHD_CONNECTION_STATE 176enum MHD_CONNECTION_STATE
177 { 177{
178 /** 178 /**
179 * Connection just started (no headers received). 179 * Connection just started (no headers received).
180 * Waiting for the line with the request type, URL and version. 180 * Waiting for the line with the request type, URL and version.
181 */ 181 */
182 MHD_CONNECTION_INIT = 0, 182 MHD_CONNECTION_INIT = 0,
183 183
184 /** 184 /**
185 * 1: We got the URL (and request type and version). Wait for a header line. 185 * 1: We got the URL (and request type and version). Wait for a header line.
186 */ 186 */
187 MHD_CONNECTION_URL_RECEIVED = MHD_CONNECTION_INIT + 1, 187 MHD_CONNECTION_URL_RECEIVED = MHD_CONNECTION_INIT + 1,
188 188
189 /** 189 /**
190 * 2: We got part of a multi-line request header. Wait for the rest. 190 * 2: We got part of a multi-line request header. Wait for the rest.
191 */ 191 */
192 MHD_CONNECTION_HEADER_PART_RECEIVED = MHD_CONNECTION_URL_RECEIVED + 1, 192 MHD_CONNECTION_HEADER_PART_RECEIVED = MHD_CONNECTION_URL_RECEIVED + 1,
193 193
194 /** 194 /**
195 * 3: We got the request headers. Process them. 195 * 3: We got the request headers. Process them.
196 */ 196 */
197 MHD_CONNECTION_HEADERS_RECEIVED = MHD_CONNECTION_HEADER_PART_RECEIVED + 1, 197 MHD_CONNECTION_HEADERS_RECEIVED = MHD_CONNECTION_HEADER_PART_RECEIVED + 1,
198 198
199 /** 199 /**
200 * 4: We have processed the request headers. Send 100 continue. 200 * 4: We have processed the request headers. Send 100 continue.
201 */ 201 */
202 MHD_CONNECTION_HEADERS_PROCESSED = MHD_CONNECTION_HEADERS_RECEIVED + 1, 202 MHD_CONNECTION_HEADERS_PROCESSED = MHD_CONNECTION_HEADERS_RECEIVED + 1,
203 203
204 /** 204 /**
205 * 5: We have processed the headers and need to send 100 CONTINUE. 205 * 5: We have processed the headers and need to send 100 CONTINUE.
206 */ 206 */
207 MHD_CONNECTION_CONTINUE_SENDING = MHD_CONNECTION_HEADERS_PROCESSED + 1, 207 MHD_CONNECTION_CONTINUE_SENDING = MHD_CONNECTION_HEADERS_PROCESSED + 1,
208 208
209 /** 209 /**
210 * 6: We have sent 100 CONTINUE (or do not need to). Read the message body. 210 * 6: We have sent 100 CONTINUE (or do not need to). Read the message body.
211 */ 211 */
212 MHD_CONNECTION_CONTINUE_SENT = MHD_CONNECTION_CONTINUE_SENDING + 1, 212 MHD_CONNECTION_CONTINUE_SENT = MHD_CONNECTION_CONTINUE_SENDING + 1,
213 213
214 /** 214 /**
215 * 7: We got the request body. Wait for a line of the footer. 215 * 7: We got the request body. Wait for a line of the footer.
216 */ 216 */
217 MHD_CONNECTION_BODY_RECEIVED = MHD_CONNECTION_CONTINUE_SENT + 1, 217 MHD_CONNECTION_BODY_RECEIVED = MHD_CONNECTION_CONTINUE_SENT + 1,
218 218
219 /** 219 /**
220 * 8: We got part of a line of the footer. Wait for the 220 * 8: We got part of a line of the footer. Wait for the
221 * rest. 221 * rest.
222 */ 222 */
223 MHD_CONNECTION_FOOTER_PART_RECEIVED = MHD_CONNECTION_BODY_RECEIVED + 1, 223 MHD_CONNECTION_FOOTER_PART_RECEIVED = MHD_CONNECTION_BODY_RECEIVED + 1,
224 224
225 /** 225 /**
226 * 9: We received the entire footer. Wait for a response to be queued 226 * 9: We received the entire footer. Wait for a response to be queued
227 * and prepare the response headers. 227 * and prepare the response headers.
228 */ 228 */
229 MHD_CONNECTION_FOOTERS_RECEIVED = MHD_CONNECTION_FOOTER_PART_RECEIVED + 1, 229 MHD_CONNECTION_FOOTERS_RECEIVED = MHD_CONNECTION_FOOTER_PART_RECEIVED + 1,
230 230
231 /** 231 /**
232 * 10: We have prepared the response headers in the writ buffer. 232 * 10: We have prepared the response headers in the writ buffer.
233 * Send the response headers. 233 * Send the response headers.
234 */ 234 */
235 MHD_CONNECTION_HEADERS_SENDING = MHD_CONNECTION_FOOTERS_RECEIVED + 1, 235 MHD_CONNECTION_HEADERS_SENDING = MHD_CONNECTION_FOOTERS_RECEIVED + 1,
236 236
237 /** 237 /**
238 * 11: We have sent the response headers. Get ready to send the body. 238 * 11: We have sent the response headers. Get ready to send the body.
239 */ 239 */
240 MHD_CONNECTION_HEADERS_SENT = MHD_CONNECTION_HEADERS_SENDING + 1, 240 MHD_CONNECTION_HEADERS_SENT = MHD_CONNECTION_HEADERS_SENDING + 1,
241 241
242 /** 242 /**
243 * 12: We are ready to send a part of a non-chunked body. Send it. 243 * 12: We are ready to send a part of a non-chunked body. Send it.
244 */ 244 */
245 MHD_CONNECTION_NORMAL_BODY_READY = MHD_CONNECTION_HEADERS_SENT + 1, 245 MHD_CONNECTION_NORMAL_BODY_READY = MHD_CONNECTION_HEADERS_SENT + 1,
246 246
247 /** 247 /**
248 * 13: We are waiting for the client to provide more 248 * 13: We are waiting for the client to provide more
249 * data of a non-chunked body. 249 * data of a non-chunked body.
250 */ 250 */
251 MHD_CONNECTION_NORMAL_BODY_UNREADY = MHD_CONNECTION_NORMAL_BODY_READY + 1, 251 MHD_CONNECTION_NORMAL_BODY_UNREADY = MHD_CONNECTION_NORMAL_BODY_READY + 1,
252 252
253 /** 253 /**
254 * 14: We are ready to send a chunk. 254 * 14: We are ready to send a chunk.
255 */ 255 */
256 MHD_CONNECTION_CHUNKED_BODY_READY = MHD_CONNECTION_NORMAL_BODY_UNREADY + 1, 256 MHD_CONNECTION_CHUNKED_BODY_READY = MHD_CONNECTION_NORMAL_BODY_UNREADY + 1,
257 257
258 /** 258 /**
259 * 15: We are waiting for the client to provide a chunk of the body. 259 * 15: We are waiting for the client to provide a chunk of the body.
260 */ 260 */
261 MHD_CONNECTION_CHUNKED_BODY_UNREADY = MHD_CONNECTION_CHUNKED_BODY_READY + 1, 261 MHD_CONNECTION_CHUNKED_BODY_UNREADY = MHD_CONNECTION_CHUNKED_BODY_READY + 1,
262 262
263 /** 263 /**
264 * 16: We have sent the response body. Prepare the footers. 264 * 16: We have sent the response body. Prepare the footers.
265 */ 265 */
266 MHD_CONNECTION_BODY_SENT = MHD_CONNECTION_CHUNKED_BODY_UNREADY + 1, 266 MHD_CONNECTION_BODY_SENT = MHD_CONNECTION_CHUNKED_BODY_UNREADY + 1,
267 267
268 /** 268 /**
269 * 17: We have prepared the response footer. Send it. 269 * 17: We have prepared the response footer. Send it.
270 */ 270 */
271 MHD_CONNECTION_FOOTERS_SENDING = MHD_CONNECTION_BODY_SENT + 1, 271 MHD_CONNECTION_FOOTERS_SENDING = MHD_CONNECTION_BODY_SENT + 1,
272 272
273 /** 273 /**
274 * 18: We have sent the response footer. Shutdown or restart. 274 * 18: We have sent the response footer. Shutdown or restart.
275 */ 275 */
276 MHD_CONNECTION_FOOTERS_SENT = MHD_CONNECTION_FOOTERS_SENDING + 1, 276 MHD_CONNECTION_FOOTERS_SENT = MHD_CONNECTION_FOOTERS_SENDING + 1,
277 277
278 /** 278 /**
279 * 19: This connection is closed (no more activity 279 * 19: This connection is closed (no more activity
280 * allowed). 280 * allowed).
281 */ 281 */
282 MHD_CONNECTION_CLOSED = MHD_CONNECTION_FOOTERS_SENT + 1, 282 MHD_CONNECTION_CLOSED = MHD_CONNECTION_FOOTERS_SENT + 1,
283 283
284 }; 284};
285 285
286enum MHDS_CONNECTION_STATE 286enum MHDS_CONNECTION_STATE
287 { 287{
288 MHDS_CONNECTION_INIT = 0, 288 MHDS_CONNECTION_INIT = 0,
289 289
290 /** 290 /**
291 * 1: We got the URL (and request type and version). Wait for a header line. 291 * 1: We got the URL (and request type and version). Wait for a header line.
292 */ 292 */
293 MHDS_HANDSHAKE_COMPLETE = MHDS_CONNECTION_INIT + 1, 293 MHDS_HANDSHAKE_COMPLETE = MHDS_CONNECTION_INIT + 1,
294 294
295 MHDS_CONNECTION_CONTINUE_SENDING = MHDS_HANDSHAKE_COMPLETE + 1, 295 MHDS_CONNECTION_CONTINUE_SENDING = MHDS_HANDSHAKE_COMPLETE + 1,
296 296
297 MHDS_CONNECTION_CLOSED = MHDS_CONNECTION_CONTINUE_SENDING + 1 297 MHDS_CONNECTION_CLOSED = MHDS_CONNECTION_CONTINUE_SENDING + 1
298 }; 298};
299 299
300struct MHD_Connection 300struct MHD_Connection
301 { 301{
302 302
303 /** 303 /**
304 * This is a linked list. 304 * This is a linked list.
305 */ 305 */
306 struct MHD_Connection *next; 306 struct MHD_Connection *next;
307 307
308 /** 308 /**
309 * Reference to the MHD_Daemon struct. 309 * Reference to the MHD_Daemon struct.
310 */ 310 */
311 struct MHD_Daemon *daemon; 311 struct MHD_Daemon *daemon;
312 312
313 /** 313 /**
314 * Linked list of parsed headers. 314 * Linked list of parsed headers.
315 */ 315 */
316 struct MHD_HTTP_Header *headers_received; 316 struct MHD_HTTP_Header *headers_received;
317 317
318 /** 318 /**
319 * Response to transmit (initially NULL). 319 * Response to transmit (initially NULL).
320 */ 320 */
321 struct MHD_Response *response; 321 struct MHD_Response *response;
322 322
323 /** 323 /**
324 * The memory pool is created whenever we first read 324 * The memory pool is created whenever we first read
@@ -330,7 +330,7 @@ struct MHD_Connection
330 * connections) and the IP address (which persists 330 * connections) and the IP address (which persists
331 * across individual requests). 331 * across individual requests).
332 */ 332 */
333 struct MemoryPool *pool; 333 struct MemoryPool *pool;
334 334
335 /** 335 /**
336 * We allow the main application to associate some 336 * We allow the main application to associate some
@@ -338,25 +338,25 @@ struct MHD_Connection
338 * store it. (MHD does not know or care what it 338 * store it. (MHD does not know or care what it
339 * is). 339 * is).
340 */ 340 */
341 void *client_context; 341 void *client_context;
342 342
343 /** 343 /**
344 * Request method. Should be GET/POST/etc. Allocated 344 * Request method. Should be GET/POST/etc. Allocated
345 * in pool. 345 * in pool.
346 */ 346 */
347 char *method; 347 char *method;
348 348
349 /** 349 /**
350 * Requested URL (everything after "GET" only). Allocated 350 * Requested URL (everything after "GET" only). Allocated
351 * in pool. 351 * in pool.
352 */ 352 */
353 char *url; 353 char *url;
354 354
355 /** 355 /**
356 * HTTP version string (i.e. http/1.1). Allocated 356 * HTTP version string (i.e. http/1.1). Allocated
357 * in pool. 357 * in pool.
358 */ 358 */
359 char *version; 359 char *version;
360 360
361 /** 361 /**
362 * Buffer for reading requests. Allocated 362 * Buffer for reading requests. Allocated
@@ -364,20 +364,20 @@ struct MHD_Connection
364 * read_buffer_size (if non-NULL) to allow for 364 * read_buffer_size (if non-NULL) to allow for
365 * 0-termination. 365 * 0-termination.
366 */ 366 */
367 char *read_buffer; 367 char *read_buffer;
368 368
369 /** 369 /**
370 * Buffer for writing response (headers only). Allocated 370 * Buffer for writing response (headers only). Allocated
371 * in pool. 371 * in pool.
372 */ 372 */
373 char *write_buffer; 373 char *write_buffer;
374 374
375 /** 375 /**
376 * Last incomplete header line during parsing of headers. 376 * Last incomplete header line during parsing of headers.
377 * Allocated in pool. Only valid if state is 377 * Allocated in pool. Only valid if state is
378 * either HEADER_PART_RECEIVED or FOOTER_PART_RECEIVED. 378 * either HEADER_PART_RECEIVED or FOOTER_PART_RECEIVED.
379 */ 379 */
380 char *last; 380 char *last;
381 381
382 /** 382 /**
383 * Position after the colon on the last incomplete header 383 * Position after the colon on the last incomplete header
@@ -385,19 +385,19 @@ struct MHD_Connection
385 * Allocated in pool. Only valid if state is 385 * Allocated in pool. Only valid if state is
386 * either HEADER_PART_RECEIVED or FOOTER_PART_RECEIVED. 386 * either HEADER_PART_RECEIVED or FOOTER_PART_RECEIVED.
387 */ 387 */
388 char *colon; 388 char *colon;
389 389
390 /** 390 /**
391 * Foreign address (of length addr_len). MALLOCED (not 391 * Foreign address (of length addr_len). MALLOCED (not
392 * in pool!). 392 * in pool!).
393 */ 393 */
394 struct sockaddr_in *addr; 394 struct sockaddr_in *addr;
395 395
396 /** 396 /**
397 * Thread for this connection (if we are using 397 * Thread for this connection (if we are using
398 * one thread per connection). 398 * one thread per connection).
399 */ 399 */
400 pthread_t pid; 400 pthread_t pid;
401 401
402 /** 402 /**
403 * Size of read_buffer (in bytes). This value indicates 403 * Size of read_buffer (in bytes). This value indicates
@@ -405,66 +405,66 @@ struct MHD_Connection
405 * the real buffer is one byte longer to allow for 405 * the real buffer is one byte longer to allow for
406 * adding zero-termination (when needed). 406 * adding zero-termination (when needed).
407 */ 407 */
408 size_t read_buffer_size; 408 size_t read_buffer_size;
409 409
410 /** 410 /**
411 * Position where we currently append data in 411 * Position where we currently append data in
412 * read_buffer (last valid position). 412 * read_buffer (last valid position).
413 */ 413 */
414 size_t read_buffer_offset; 414 size_t read_buffer_offset;
415 415
416 /** 416 /**
417 * Size of write_buffer (in bytes). 417 * Size of write_buffer (in bytes).
418 */ 418 */
419 size_t write_buffer_size; 419 size_t write_buffer_size;
420 420
421 /** 421 /**
422 * Offset where we are with sending from write_buffer. 422 * Offset where we are with sending from write_buffer.
423 */ 423 */
424 size_t write_buffer_send_offset; 424 size_t write_buffer_send_offset;
425 425
426 /** 426 /**
427 * Last valid location in write_buffer (where do we 427 * Last valid location in write_buffer (where do we
428 * append and up to where is it safe to send?) 428 * append and up to where is it safe to send?)
429 */ 429 */
430 size_t write_buffer_append_offset; 430 size_t write_buffer_append_offset;
431 431
432 /** 432 /**
433 * How many more bytes of the body do we expect 433 * How many more bytes of the body do we expect
434 * to read? "-1" for unknown. 434 * to read? "-1" for unknown.
435 */ 435 */
436 size_t remaining_upload_size; 436 size_t remaining_upload_size;
437 437
438 /** 438 /**
439 * Current write position in the actual response 439 * Current write position in the actual response
440 * (excluding headers, content only; should be 0 440 * (excluding headers, content only; should be 0
441 * while sending headers). 441 * while sending headers).
442 */ 442 */
443 size_t response_write_position; 443 size_t response_write_position;
444 444
445 /** 445 /**
446 * Position in the 100 CONTINUE message that 446 * Position in the 100 CONTINUE message that
447 * we need to send when receiving http 1.1 requests. 447 * we need to send when receiving http 1.1 requests.
448 */ 448 */
449 size_t continue_message_write_offset; 449 size_t continue_message_write_offset;
450 450
451 /** 451 /**
452 * Length of the foreign address. 452 * Length of the foreign address.
453 */ 453 */
454 socklen_t addr_len; 454 socklen_t addr_len;
455 455
456 /** 456 /**
457 * Last time this connection had any activity 457 * Last time this connection had any activity
458 * (reading or writing). 458 * (reading or writing).
459 */ 459 */
460 time_t last_activity; 460 time_t last_activity;
461 461
462 /** 462 /**
463 * Socket for this connection. Set to -1 if 463 * Socket for this connection. Set to -1 if
464 * this connection has died (daemon should clean 464 * this connection has died (daemon should clean
465 * up in that case). 465 * up in that case).
466 */ 466 */
467 int socket_fd; 467 int socket_fd;
468 468
469 /** 469 /**
470 * Has this socket been closed for reading (i.e. 470 * Has this socket been closed for reading (i.e.
@@ -473,18 +473,18 @@ struct MHD_Connection
473 * we are done sending our response (and stop 473 * we are done sending our response (and stop
474 * trying to read from this socket). 474 * trying to read from this socket).
475 */ 475 */
476 int read_closed; 476 int read_closed;
477 477
478 /** 478 /**
479 * State in the FSM for this connection. 479 * State in the FSM for this connection.
480 */ 480 */
481 enum MHD_CONNECTION_STATE state; 481 enum MHD_CONNECTION_STATE state;
482 482
483 /** 483 /**
484 * HTTP response code. Only valid if response object 484 * HTTP response code. Only valid if response object
485 * is already set. 485 * is already set.
486 */ 486 */
487 unsigned int responseCode; 487 unsigned int responseCode;
488 488
489 /** 489 /**
490 * Set to MHD_YES if the response's content reader 490 * Set to MHD_YES if the response's content reader
@@ -493,12 +493,12 @@ struct MHD_Connection
493 * write socket should be marked as unready until 493 * write socket should be marked as unready until
494 * the CRC call succeeds. 494 * the CRC call succeeds.
495 */ 495 */
496 int response_unready; 496 int response_unready;
497 497
498 /** 498 /**
499 * Are we sending with chunked encoding? 499 * Are we sending with chunked encoding?
500 */ 500 */
501 int have_chunked_response; 501 int have_chunked_response;
502 502
503 /** 503 /**
504 * Are we receiving with chunked encoding? This will be set to 504 * Are we receiving with chunked encoding? This will be set to
@@ -507,7 +507,7 @@ struct MHD_Connection
507 * processing the footers; once the footers are also done, this will 507 * processing the footers; once the footers are also done, this will
508 * be set to MHD_NO again (before the final call to the handler). 508 * be set to MHD_NO again (before the final call to the handler).
509 */ 509 */
510 int have_chunked_upload; 510 int have_chunked_upload;
511 511
512 /** 512 /**
513 * If we are receiving with chunked encoding, where are we right 513 * If we are receiving with chunked encoding, where are we right
@@ -515,97 +515,97 @@ struct MHD_Connection
515 * otherwise, this is the size of the current chunk. A value of 515 * otherwise, this is the size of the current chunk. A value of
516 * zero is also used when we're at the end of the chunks. 516 * zero is also used when we're at the end of the chunks.
517 */ 517 */
518 unsigned int current_chunk_size; 518 unsigned int current_chunk_size;
519 519
520 /** 520 /**
521 * If we are receiving with chunked encoding, where are we currently 521 * If we are receiving with chunked encoding, where are we currently
522 * with respect to the current chunk (at what offset / position)? 522 * with respect to the current chunk (at what offset / position)?
523 */ 523 */
524 unsigned int current_chunk_offset; 524 unsigned int current_chunk_offset;
525 525
526 }; 526};
527 527
528typedef struct MHD_Connection MHD_Connection_t; 528typedef struct MHD_Connection MHD_Connection_t;
529 529
530struct MHD_Daemon 530struct MHD_Daemon
531 { 531{
532 532
533 /** 533 /**
534 * Callback function for all requests. 534 * Callback function for all requests.
535 */ 535 */
536 MHD_AccessHandlerCallback default_handler; 536 MHD_AccessHandlerCallback default_handler;
537 537
538 /** 538 /**
539 * Closure argument to default_handler. 539 * Closure argument to default_handler.
540 */ 540 */
541 void *default_handler_cls; 541 void *default_handler_cls;
542 542
543 /** 543 /**
544 * Linked list of our current connections. 544 * Linked list of our current connections.
545 */ 545 */
546 struct MHD_Connection *connections; 546 struct MHD_Connection *connections;
547 547
548 /** 548 /**
549 * Linked list of our current connections. 549 * Linked list of our current connections.
550 */ 550 */
551 // TODO switch to a dedicated tls connection struct 551 // TODO switch to a dedicated tls connection struct
552 struct MHD_Connection *tls_connections; 552 struct MHD_Connection *tls_connections;
553 553
554 MHD_AcceptPolicyCallback apc; 554 MHD_AcceptPolicyCallback apc;
555 555
556 void *apc_cls; 556 void *apc_cls;
557 557
558 MHD_RequestCompletedCallback notify_completed; 558 MHD_RequestCompletedCallback notify_completed;
559 559
560 void *notify_completed_cls; 560 void *notify_completed_cls;
561 561
562 /** 562 /**
563 * PID of the select thread (if we have internal select) 563 * PID of the select thread (if we have internal select)
564 */ 564 */
565 pthread_t pid; 565 pthread_t pid;
566 566
567 /** 567 /**
568 * Listen socket. 568 * Listen socket.
569 */ 569 */
570 int socket_fd; 570 int socket_fd;
571 571
572 /** 572 /**
573 * Are we shutting down? 573 * Are we shutting down?
574 */ 574 */
575 int shutdown; 575 int shutdown;
576 576
577 /** 577 /**
578 * Size of the per-connection memory pools. 578 * Size of the per-connection memory pools.
579 */ 579 */
580 unsigned int pool_size; 580 unsigned int pool_size;
581 581
582 /** 582 /**
583 * Limit on the number of parallel connections. 583 * Limit on the number of parallel connections.
584 */ 584 */
585 unsigned int max_connections; 585 unsigned int max_connections;
586 586
587 /** 587 /**
588 * After how many seconds of inactivity should 588 * After how many seconds of inactivity should
589 * connections time out? Zero for no timeout. 589 * connections time out? Zero for no timeout.
590 */ 590 */
591 unsigned int connection_timeout; 591 unsigned int connection_timeout;
592 592
593 /** 593 /**
594 * Maximum number of connections per IP, or 0 for 594 * Maximum number of connections per IP, or 0 for
595 * unlimited. 595 * unlimited.
596 */ 596 */
597 unsigned int per_ip_connection_limit; 597 unsigned int per_ip_connection_limit;
598 598
599 /** 599 /**
600 * Daemon's options. 600 * Daemon's options.
601 */ 601 */
602 enum MHD_OPTION options; 602 enum MHD_OPTION options;
603 603
604 /** 604 /**
605 * Listen port. 605 * Listen port.
606 */ 606 */
607 unsigned short port; 607 unsigned short port;
608 608
609 }; 609};
610 610
611#endif 611#endif
diff --git a/src/daemon/postprocessor.c b/src/daemon/postprocessor.c
index 241bfcdd..5e25747a 100644
--- a/src/daemon/postprocessor.c
+++ b/src/daemon/postprocessor.c
@@ -356,15 +356,15 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
356 /* find last position in input buffer that is part of the value */ 356 /* find last position in input buffer that is part of the value */
357 amper = 0; 357 amper = 0;
358 while ((amper + poff < post_data_len) && 358 while ((amper + poff < post_data_len) &&
359 (amper < XBUF_SIZE) && 359 (amper < XBUF_SIZE) &&
360 (post_data[amper + poff] != '&') && 360 (post_data[amper + poff] != '&') &&
361 (post_data[amper + poff] != '\n') && 361 (post_data[amper + poff] != '\n') &&
362 (post_data[amper + poff] != '\r')) 362 (post_data[amper + poff] != '\r'))
363 amper++; 363 amper++;
364 end_of_value_found = ( (amper + poff < post_data_len) && 364 end_of_value_found = ((amper + poff < post_data_len) &&
365 ( (post_data[amper + poff] == '&') || 365 ((post_data[amper + poff] == '&') ||
366 (post_data[amper + poff] == '\n') || 366 (post_data[amper + poff] == '\n') ||
367 (post_data[amper + poff] == '\r') ) ); 367 (post_data[amper + poff] == '\r')));
368 /* compute delta, the maximum number of bytes that we will be able to 368 /* compute delta, the maximum number of bytes that we will be able to
369 process right now (either amper-limited of xbuf-size limited) */ 369 process right now (either amper-limited of xbuf-size limited) */
370 delta = amper; 370 delta = amper;
@@ -405,29 +405,28 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
405 MHD_http_unescape (xbuf); 405 MHD_http_unescape (xbuf);
406 406
407 /* finally: call application! */ 407 /* finally: call application! */
408 if (MHD_NO == 408 if (MHD_NO == pp->ikvi (pp->cls, MHD_POSTDATA_KIND, (const char *) &pp[1], /* key */
409 pp->ikvi (pp->cls, MHD_POSTDATA_KIND, (const char *) &pp[1], /* key */ 409 NULL, NULL, NULL, xbuf, pp->value_offset,
410 NULL, NULL, NULL, xbuf, pp->value_offset, xoff)) 410 xoff))
411 { 411 {
412 pp->state = PP_Error; 412 pp->state = PP_Error;
413 return MHD_NO; 413 return MHD_NO;
414 } 414 }
415 pp->value_offset += xoff; 415 pp->value_offset += xoff;
416 416
417 /* are we done with the value? */ 417 /* are we done with the value? */
418 if (end_of_value_found) 418 if (end_of_value_found)
419 { 419 {
420 /* we found the end of the value! */ 420 /* we found the end of the value! */
421 if ((post_data[poff] == '\n') || 421 if ((post_data[poff] == '\n') || (post_data[poff] == '\r'))
422 (post_data[poff] == '\r')) 422 {
423 { 423 pp->state = PP_ExpectNewLine;
424 pp->state = PP_ExpectNewLine; 424 }
425 } 425 else
426 else 426 {
427 { 427 poff++; /* skip '&' */
428 poff++; /* skip '&' */ 428 pp->state = PP_Init;
429 pp->state = PP_Init; 429 }
430 }
431 } 430 }
432 break; 431 break;
433 case PP_ExpectNewLine: 432 case PP_ExpectNewLine:
diff --git a/src/daemon/postprocessor_large_test.c b/src/daemon/postprocessor_large_test.c
index 549f606e..f3e1f478 100644
--- a/src/daemon/postprocessor_large_test.c
+++ b/src/daemon/postprocessor_large_test.c
@@ -48,7 +48,7 @@ value_checker (void *cls,
48#if 0 48#if 0
49 fprintf (stderr, 49 fprintf (stderr,
50 "VC: %u %u `%s' `%s' `%s' `%s' `%.*s'\n", 50 "VC: %u %u `%s' `%s' `%s' `%s' `%.*s'\n",
51 off, size, 51 off, size,
52 key, filename, content_type, transfer_encoding, size, data); 52 key, filename, content_type, transfer_encoding, size, data);
53#endif 53#endif
54 if (size == 0) 54 if (size == 0)
@@ -72,17 +72,16 @@ test_simple_large ()
72 unsigned int pos; 72 unsigned int pos;
73 73
74 pos = 0; 74 pos = 0;
75 memset (data, 'A', sizeof(data)); 75 memset (data, 'A', sizeof (data));
76 memcpy (data, "key=", 4); 76 memcpy (data, "key=", 4);
77 data[sizeof(data)-1] = '\0'; 77 data[sizeof (data) - 1] = '\0';
78 memset (&connection, 0, sizeof (struct MHD_Connection)); 78 memset (&connection, 0, sizeof (struct MHD_Connection));
79 memset (&header, 0, sizeof (struct MHD_HTTP_Header)); 79 memset (&header, 0, sizeof (struct MHD_HTTP_Header));
80 connection.headers_received = &header; 80 connection.headers_received = &header;
81 header.header = MHD_HTTP_HEADER_CONTENT_TYPE; 81 header.header = MHD_HTTP_HEADER_CONTENT_TYPE;
82 header.value = MHD_HTTP_POST_ENCODING_FORM_URLENCODED; 82 header.value = MHD_HTTP_POST_ENCODING_FORM_URLENCODED;
83 header.kind = MHD_HEADER_KIND; 83 header.kind = MHD_HEADER_KIND;
84 pp = MHD_create_post_processor (&connection, 84 pp = MHD_create_post_processor (&connection, 1024, &value_checker, &pos);
85 1024, &value_checker, &pos);
86 i = 0; 85 i = 0;
87 size = strlen (data); 86 size = strlen (data);
88 while (i < size) 87 while (i < size)
@@ -92,7 +91,7 @@ test_simple_large ()
92 i += delta; 91 i += delta;
93 } 92 }
94 MHD_destroy_post_processor (pp); 93 MHD_destroy_post_processor (pp);
95 if (pos != sizeof(data) - 5) /* minus 0-termination and 'key=' */ 94 if (pos != sizeof (data) - 5) /* minus 0-termination and 'key=' */
96 return 1; 95 return 1;
97 return 0; 96 return 0;
98} 97}
diff --git a/src/examples/fileserver_example_external_select.c b/src/examples/fileserver_example_external_select.c
index b0956c51..4ec4a0fb 100644
--- a/src/examples/fileserver_example_external_select.c
+++ b/src/examples/fileserver_example_external_select.c
@@ -115,28 +115,28 @@ main (int argc, char *const *argv)
115 NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); 115 NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END);
116 if (d == NULL) 116 if (d == NULL)
117 return 1; 117 return 1;
118 end = time(NULL) + atoi (argv[2]); 118 end = time (NULL) + atoi (argv[2]);
119 while ( (t = time(NULL)) < end) 119 while ((t = time (NULL)) < end)
120 { 120 {
121 tv.tv_sec = end - t; 121 tv.tv_sec = end - t;
122 tv.tv_usec = 0; 122 tv.tv_usec = 0;
123 max = 0; 123 max = 0;
124 FD_ZERO(&rs); 124 FD_ZERO (&rs);
125 FD_ZERO(&ws); 125 FD_ZERO (&ws);
126 FD_ZERO(&es); 126 FD_ZERO (&es);
127 MHD_get_fdset(d, &rs, &ws, &es, &max); 127 MHD_get_fdset (d, &rs, &ws, &es, &max);
128 if (MHD_get_timeout(d, &mhd_timeout) == MHD_YES) 128 if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES)
129 129
130 { 130 {
131 if (tv.tv_sec * 1000 < mhd_timeout) 131 if (tv.tv_sec * 1000 < mhd_timeout)
132 { 132 {
133 tv.tv_sec = mhd_timeout / 1000; 133 tv.tv_sec = mhd_timeout / 1000;
134 tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000; 134 tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000;
135 } 135 }
136 } 136 }
137 select(max+1, &rs, &ws, &es, &tv); 137 select (max + 1, &rs, &ws, &es, &tv);
138 MHD_run(d); 138 MHD_run (d);
139 } 139 }
140 MHD_stop_daemon (d); 140 MHD_stop_daemon (d);
141 return 0; 141 return 0;
142} 142}
diff --git a/src/examples/https_server_example.c b/src/examples/https_server_example.c
index 709f8502..78f7176b 100644
--- a/src/examples/https_server_example.c
+++ b/src/examples/https_server_example.c
@@ -165,9 +165,9 @@ main (int argc, char *const *argv)
165 gnutls_anon_set_server_dh_params (anoncred, dh_params); 165 gnutls_anon_set_server_dh_params (anoncred, dh_params);
166 166
167 TLS_daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION 167 TLS_daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
168 | MHD_USE_DEBUG | MHD_USE_SSL, 168 | MHD_USE_DEBUG | MHD_USE_SSL,
169 atoi (argv[3]), NULL, NULL, &TLS_echo, NULL, 169 atoi (argv[3]), NULL, NULL, &TLS_echo, NULL,
170 MHD_OPTION_END); 170 MHD_OPTION_END);
171 171
172 if (TLS_daemon == NULL) 172 if (TLS_daemon == NULL)
173 return 1; 173 return 1;