aboutsummaryrefslogtreecommitdiff
path: root/src/examples/post_example.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/examples/post_example.c')
-rw-r--r--src/examples/post_example.c509
1 files changed, 258 insertions, 251 deletions
diff --git a/src/examples/post_example.c b/src/examples/post_example.c
index 6c9a3f4b..311bf6c2 100644
--- a/src/examples/post_example.c
+++ b/src/examples/post_example.c
@@ -32,32 +32,38 @@
32/** 32/**
33 * Invalid method page. 33 * Invalid method page.
34 */ 34 */
35#define METHOD_ERROR "<html><head><title>Illegal request</title></head><body>Go away.</body></html>" 35#define METHOD_ERROR \
36 "<html><head><title>Illegal request</title></head><body>Go away.</body></html>"
36 37
37/** 38/**
38 * Invalid URL page. 39 * Invalid URL page.
39 */ 40 */
40#define NOT_FOUND_ERROR "<html><head><title>Not found</title></head><body>Go away.</body></html>" 41#define NOT_FOUND_ERROR \
42 "<html><head><title>Not found</title></head><body>Go away.</body></html>"
41 43
42/** 44/**
43 * Front page. (/) 45 * Front page. (/)
44 */ 46 */
45#define MAIN_PAGE "<html><head><title>Welcome</title></head><body><form action=\"/2\" method=\"post\">What is your name? <input type=\"text\" name=\"v1\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>" 47#define MAIN_PAGE \
48 "<html><head><title>Welcome</title></head><body><form action=\"/2\" method=\"post\">What is your name? <input type=\"text\" name=\"v1\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>"
46 49
47/** 50/**
48 * Second page. (/2) 51 * Second page. (/2)
49 */ 52 */
50#define SECOND_PAGE "<html><head><title>Tell me more</title></head><body><a href=\"/\">previous</a> <form action=\"/S\" method=\"post\">%s, what is your job? <input type=\"text\" name=\"v2\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>" 53#define SECOND_PAGE \
54 "<html><head><title>Tell me more</title></head><body><a href=\"/\">previous</a> <form action=\"/S\" method=\"post\">%s, what is your job? <input type=\"text\" name=\"v2\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>"
51 55
52/** 56/**
53 * Second page (/S) 57 * Second page (/S)
54 */ 58 */
55#define SUBMIT_PAGE "<html><head><title>Ready to submit?</title></head><body><form action=\"/F\" method=\"post\"><a href=\"/2\">previous </a> <input type=\"hidden\" name=\"DONE\" value=\"yes\" /><input type=\"submit\" value=\"Submit\" /></body></html>" 59#define SUBMIT_PAGE \
60 "<html><head><title>Ready to submit?</title></head><body><form action=\"/F\" method=\"post\"><a href=\"/2\">previous </a> <input type=\"hidden\" name=\"DONE\" value=\"yes\" /><input type=\"submit\" value=\"Submit\" /></body></html>"
56 61
57/** 62/**
58 * Last page. 63 * Last page.
59 */ 64 */
60#define LAST_PAGE "<html><head><title>Thank you</title></head><body>Thank you.</body></html>" 65#define LAST_PAGE \
66 "<html><head><title>Thank you</title></head><body>Thank you.</body></html>"
61 67
62/** 68/**
63 * Name of our cookie. 69 * Name of our cookie.
@@ -150,40 +156,40 @@ get_session (struct MHD_Connection *connection)
150 const char *cookie; 156 const char *cookie;
151 157
152 cookie = MHD_lookup_connection_value (connection, 158 cookie = MHD_lookup_connection_value (connection,
153 MHD_COOKIE_KIND, 159 MHD_COOKIE_KIND,
154 COOKIE_NAME); 160 COOKIE_NAME);
155 if (cookie != NULL) 161 if (cookie != NULL)
162 {
163 /* find existing session */
164 ret = sessions;
165 while (NULL != ret)
166 {
167 if (0 == strcmp (cookie, ret->sid))
168 break;
169 ret = ret->next;
170 }
171 if (NULL != ret)
156 { 172 {
157 /* find existing session */ 173 ret->rc++;
158 ret = sessions; 174 return ret;
159 while (NULL != ret)
160 {
161 if (0 == strcmp (cookie, ret->sid))
162 break;
163 ret = ret->next;
164 }
165 if (NULL != ret)
166 {
167 ret->rc++;
168 return ret;
169 }
170 } 175 }
176 }
171 /* create fresh session */ 177 /* create fresh session */
172 ret = calloc (1, sizeof (struct Session)); 178 ret = calloc (1, sizeof (struct Session));
173 if (NULL == ret) 179 if (NULL == ret)
174 { 180 {
175 fprintf (stderr, "calloc error: %s\n", strerror (errno)); 181 fprintf (stderr, "calloc error: %s\n", strerror (errno));
176 return NULL; 182 return NULL;
177 } 183 }
178 /* not a super-secure way to generate a random session ID, 184 /* not a super-secure way to generate a random session ID,
179 but should do for a simple example... */ 185 but should do for a simple example... */
180 snprintf (ret->sid, 186 snprintf (ret->sid,
181 sizeof (ret->sid), 187 sizeof (ret->sid),
182 "%X%X%X%X", 188 "%X%X%X%X",
183 (unsigned int) rand (), 189 (unsigned int) rand (),
184 (unsigned int) rand (), 190 (unsigned int) rand (),
185 (unsigned int) rand (), 191 (unsigned int) rand (),
186 (unsigned int) rand ()); 192 (unsigned int) rand ());
187 ret->rc++; 193 ret->rc++;
188 ret->start = time (NULL); 194 ret->start = time (NULL);
189 ret->next = sessions; 195 ret->next = sessions;
@@ -202,9 +208,9 @@ get_session (struct MHD_Connection *connection)
202 * @param MHD_YES on success, MHD_NO on failure 208 * @param MHD_YES on success, MHD_NO on failure
203 */ 209 */
204typedef int (*PageHandler)(const void *cls, 210typedef int (*PageHandler)(const void *cls,
205 const char *mime, 211 const char *mime,
206 struct Session *session, 212 struct Session *session,
207 struct MHD_Connection *connection); 213 struct MHD_Connection *connection);
208 214
209 215
210/** 216/**
@@ -242,22 +248,22 @@ struct Page
242 */ 248 */
243static void 249static void
244add_session_cookie (struct Session *session, 250add_session_cookie (struct Session *session,
245 struct MHD_Response *response) 251 struct MHD_Response *response)
246{ 252{
247 char cstr[256]; 253 char cstr[256];
248 snprintf (cstr, 254 snprintf (cstr,
249 sizeof (cstr), 255 sizeof (cstr),
250 "%s=%s", 256 "%s=%s",
251 COOKIE_NAME, 257 COOKIE_NAME,
252 session->sid); 258 session->sid);
253 if (MHD_NO == 259 if (MHD_NO ==
254 MHD_add_response_header (response, 260 MHD_add_response_header (response,
255 MHD_HTTP_HEADER_SET_COOKIE, 261 MHD_HTTP_HEADER_SET_COOKIE,
256 cstr)) 262 cstr))
257 { 263 {
258 fprintf (stderr, 264 fprintf (stderr,
259 "Failed to set session cookie header!\n"); 265 "Failed to set session cookie header!\n");
260 } 266 }
261} 267}
262 268
263 269
@@ -272,9 +278,9 @@ add_session_cookie (struct Session *session,
272 */ 278 */
273static int 279static int
274serve_simple_form (const void *cls, 280serve_simple_form (const void *cls,
275 const char *mime, 281 const char *mime,
276 struct Session *session, 282 struct Session *session,
277 struct MHD_Connection *connection) 283 struct MHD_Connection *connection)
278{ 284{
279 int ret; 285 int ret;
280 const char *form = cls; 286 const char *form = cls;
@@ -282,17 +288,17 @@ serve_simple_form (const void *cls,
282 288
283 /* return static form */ 289 /* return static form */
284 response = MHD_create_response_from_buffer (strlen (form), 290 response = MHD_create_response_from_buffer (strlen (form),
285 (void *) form, 291 (void *) form,
286 MHD_RESPMEM_PERSISTENT); 292 MHD_RESPMEM_PERSISTENT);
287 if (NULL == response) 293 if (NULL == response)
288 return MHD_NO; 294 return MHD_NO;
289 add_session_cookie (session, response); 295 add_session_cookie (session, response);
290 MHD_add_response_header (response, 296 MHD_add_response_header (response,
291 MHD_HTTP_HEADER_CONTENT_ENCODING, 297 MHD_HTTP_HEADER_CONTENT_ENCODING,
292 mime); 298 mime);
293 ret = MHD_queue_response (connection, 299 ret = MHD_queue_response (connection,
294 MHD_HTTP_OK, 300 MHD_HTTP_OK,
295 response); 301 response);
296 MHD_destroy_response (response); 302 MHD_destroy_response (response);
297 return ret; 303 return ret;
298} 304}
@@ -308,28 +314,28 @@ serve_simple_form (const void *cls,
308 */ 314 */
309static int 315static int
310fill_v1_form (const void *cls, 316fill_v1_form (const void *cls,
311 const char *mime, 317 const char *mime,
312 struct Session *session, 318 struct Session *session,
313 struct MHD_Connection *connection) 319 struct MHD_Connection *connection)
314{ 320{
315 int ret; 321 int ret;
316 size_t slen; 322 size_t slen;
317 char *reply; 323 char *reply;
318 struct MHD_Response *response; 324 struct MHD_Response *response;
319 (void)cls; /* Unused. Silent compiler warning. */ 325 (void) cls; /* Unused. Silent compiler warning. */
320 326
321 slen = strlen (MAIN_PAGE) + strlen (session->value_1); 327 slen = strlen (MAIN_PAGE) + strlen (session->value_1);
322 reply = malloc (slen + 1); 328 reply = malloc (slen + 1);
323 if (NULL == reply) 329 if (NULL == reply)
324 return MHD_NO; 330 return MHD_NO;
325 snprintf (reply, 331 snprintf (reply,
326 slen + 1, 332 slen + 1,
327 MAIN_PAGE, 333 MAIN_PAGE,
328 session->value_1); 334 session->value_1);
329 /* return static form */ 335 /* return static form */
330 response = MHD_create_response_from_buffer (slen, 336 response = MHD_create_response_from_buffer (slen,
331 (void *) reply, 337 (void *) reply,
332 MHD_RESPMEM_MUST_FREE); 338 MHD_RESPMEM_MUST_FREE);
333 if (NULL == response) 339 if (NULL == response)
334 { 340 {
335 free (reply); 341 free (reply);
@@ -337,11 +343,11 @@ fill_v1_form (const void *cls,
337 } 343 }
338 add_session_cookie (session, response); 344 add_session_cookie (session, response);
339 MHD_add_response_header (response, 345 MHD_add_response_header (response,
340 MHD_HTTP_HEADER_CONTENT_ENCODING, 346 MHD_HTTP_HEADER_CONTENT_ENCODING,
341 mime); 347 mime);
342 ret = MHD_queue_response (connection, 348 ret = MHD_queue_response (connection,
343 MHD_HTTP_OK, 349 MHD_HTTP_OK,
344 response); 350 response);
345 MHD_destroy_response (response); 351 MHD_destroy_response (response);
346 return ret; 352 return ret;
347} 353}
@@ -357,29 +363,30 @@ fill_v1_form (const void *cls,
357 */ 363 */
358static int 364static int
359fill_v1_v2_form (const void *cls, 365fill_v1_v2_form (const void *cls,
360 const char *mime, 366 const char *mime,
361 struct Session *session, 367 struct Session *session,
362 struct MHD_Connection *connection) 368 struct MHD_Connection *connection)
363{ 369{
364 int ret; 370 int ret;
365 char *reply; 371 char *reply;
366 struct MHD_Response *response; 372 struct MHD_Response *response;
367 size_t slen; 373 size_t slen;
368 (void)cls; /* Unused. Silent compiler warning. */ 374 (void) cls; /* Unused. Silent compiler warning. */
369 375
370 slen = strlen (SECOND_PAGE) + strlen (session->value_1) + strlen (session->value_2); 376 slen = strlen (SECOND_PAGE) + strlen (session->value_1) + strlen (
377 session->value_2);
371 reply = malloc (slen + 1); 378 reply = malloc (slen + 1);
372 if (NULL == reply) 379 if (NULL == reply)
373 return MHD_NO; 380 return MHD_NO;
374 snprintf (reply, 381 snprintf (reply,
375 slen + 1, 382 slen + 1,
376 SECOND_PAGE, 383 SECOND_PAGE,
377 session->value_1, 384 session->value_1,
378 session->value_2); 385 session->value_2);
379 /* return static form */ 386 /* return static form */
380 response = MHD_create_response_from_buffer (slen, 387 response = MHD_create_response_from_buffer (slen,
381 (void *) reply, 388 (void *) reply,
382 MHD_RESPMEM_MUST_FREE); 389 MHD_RESPMEM_MUST_FREE);
383 if (NULL == response) 390 if (NULL == response)
384 { 391 {
385 free (reply); 392 free (reply);
@@ -387,11 +394,11 @@ fill_v1_v2_form (const void *cls,
387 } 394 }
388 add_session_cookie (session, response); 395 add_session_cookie (session, response);
389 MHD_add_response_header (response, 396 MHD_add_response_header (response,
390 MHD_HTTP_HEADER_CONTENT_ENCODING, 397 MHD_HTTP_HEADER_CONTENT_ENCODING,
391 mime); 398 mime);
392 ret = MHD_queue_response (connection, 399 ret = MHD_queue_response (connection,
393 MHD_HTTP_OK, 400 MHD_HTTP_OK,
394 response); 401 response);
395 MHD_destroy_response (response); 402 MHD_destroy_response (response);
396 return ret; 403 return ret;
397} 404}
@@ -407,27 +414,27 @@ fill_v1_v2_form (const void *cls,
407 */ 414 */
408static int 415static int
409not_found_page (const void *cls, 416not_found_page (const void *cls,
410 const char *mime, 417 const char *mime,
411 struct Session *session, 418 struct Session *session,
412 struct MHD_Connection *connection) 419 struct MHD_Connection *connection)
413{ 420{
414 int ret; 421 int ret;
415 struct MHD_Response *response; 422 struct MHD_Response *response;
416 (void)cls; /* Unused. Silent compiler warning. */ 423 (void) cls; /* Unused. Silent compiler warning. */
417 (void)session; /* Unused. Silent compiler warning. */ 424 (void) session; /* Unused. Silent compiler warning. */
418 425
419 /* unsupported HTTP method */ 426 /* unsupported HTTP method */
420 response = MHD_create_response_from_buffer (strlen (NOT_FOUND_ERROR), 427 response = MHD_create_response_from_buffer (strlen (NOT_FOUND_ERROR),
421 (void *) NOT_FOUND_ERROR, 428 (void *) NOT_FOUND_ERROR,
422 MHD_RESPMEM_PERSISTENT); 429 MHD_RESPMEM_PERSISTENT);
423 if (NULL == response) 430 if (NULL == response)
424 return MHD_NO; 431 return MHD_NO;
425 ret = MHD_queue_response (connection, 432 ret = MHD_queue_response (connection,
426 MHD_HTTP_NOT_FOUND, 433 MHD_HTTP_NOT_FOUND,
427 response); 434 response);
428 MHD_add_response_header (response, 435 MHD_add_response_header (response,
429 MHD_HTTP_HEADER_CONTENT_ENCODING, 436 MHD_HTTP_HEADER_CONTENT_ENCODING,
430 mime); 437 mime);
431 MHD_destroy_response (response); 438 MHD_destroy_response (response);
432 return ret; 439 return ret;
433} 440}
@@ -436,14 +443,13 @@ not_found_page (const void *cls,
436/** 443/**
437 * List of all pages served by this HTTP server. 444 * List of all pages served by this HTTP server.
438 */ 445 */
439static struct Page pages[] = 446static struct Page pages[] = {
440 { 447 { "/", "text/html", &fill_v1_form, NULL },
441 { "/", "text/html", &fill_v1_form, NULL }, 448 { "/2", "text/html", &fill_v1_v2_form, NULL },
442 { "/2", "text/html", &fill_v1_v2_form, NULL }, 449 { "/S", "text/html", &serve_simple_form, SUBMIT_PAGE },
443 { "/S", "text/html", &serve_simple_form, SUBMIT_PAGE }, 450 { "/F", "text/html", &serve_simple_form, LAST_PAGE },
444 { "/F", "text/html", &serve_simple_form, LAST_PAGE }, 451 { NULL, NULL, &not_found_page, NULL } /* 404 */
445 { NULL, NULL, &not_found_page, NULL } /* 404 */ 452};
446 };
447 453
448 454
449 455
@@ -468,49 +474,49 @@ static struct Page pages[] =
468 */ 474 */
469static int 475static int
470post_iterator (void *cls, 476post_iterator (void *cls,
471 enum MHD_ValueKind kind, 477 enum MHD_ValueKind kind,
472 const char *key, 478 const char *key,
473 const char *filename, 479 const char *filename,
474 const char *content_type, 480 const char *content_type,
475 const char *transfer_encoding, 481 const char *transfer_encoding,
476 const char *data, uint64_t off, size_t size) 482 const char *data, uint64_t off, size_t size)
477{ 483{
478 struct Request *request = cls; 484 struct Request *request = cls;
479 struct Session *session = request->session; 485 struct Session *session = request->session;
480 (void)kind; /* Unused. Silent compiler warning. */ 486 (void) kind; /* Unused. Silent compiler warning. */
481 (void)filename; /* Unused. Silent compiler warning. */ 487 (void) filename; /* Unused. Silent compiler warning. */
482 (void)content_type; /* Unused. Silent compiler warning. */ 488 (void) content_type; /* Unused. Silent compiler warning. */
483 (void)transfer_encoding; /* Unused. Silent compiler warning. */ 489 (void) transfer_encoding; /* Unused. Silent compiler warning. */
484 490
485 if (0 == strcmp ("DONE", key)) 491 if (0 == strcmp ("DONE", key))
486 { 492 {
487 fprintf (stdout, 493 fprintf (stdout,
488 "Session `%s' submitted `%s', `%s'\n", 494 "Session `%s' submitted `%s', `%s'\n",
489 session->sid, 495 session->sid,
490 session->value_1, 496 session->value_1,
491 session->value_2); 497 session->value_2);
492 return MHD_YES; 498 return MHD_YES;
493 } 499 }
494 if (0 == strcmp ("v1", key)) 500 if (0 == strcmp ("v1", key))
495 { 501 {
496 if (size + off >= sizeof(session->value_1)) 502 if (size + off >= sizeof(session->value_1))
497 size = sizeof (session->value_1) - off - 1; 503 size = sizeof (session->value_1) - off - 1;
498 memcpy (&session->value_1[off], 504 memcpy (&session->value_1[off],
499 data, 505 data,
500 size); 506 size);
501 session->value_1[size+off] = '\0'; 507 session->value_1[size + off] = '\0';
502 return MHD_YES; 508 return MHD_YES;
503 } 509 }
504 if (0 == strcmp ("v2", key)) 510 if (0 == strcmp ("v2", key))
505 { 511 {
506 if (size + off >= sizeof(session->value_2)) 512 if (size + off >= sizeof(session->value_2))
507 size = sizeof (session->value_2) - off - 1; 513 size = sizeof (session->value_2) - off - 1;
508 memcpy (&session->value_2[off], 514 memcpy (&session->value_2[off],
509 data, 515 data,
510 size); 516 size);
511 session->value_2[size+off] = '\0'; 517 session->value_2[size + off] = '\0';
512 return MHD_YES; 518 return MHD_YES;
513 } 519 }
514 fprintf (stderr, 520 fprintf (stderr,
515 "Unsupported form value `%s'\n", 521 "Unsupported form value `%s'\n",
516 key); 522 key);
@@ -553,99 +559,99 @@ post_iterator (void *cls,
553 */ 559 */
554static int 560static int
555create_response (void *cls, 561create_response (void *cls,
556 struct MHD_Connection *connection, 562 struct MHD_Connection *connection,
557 const char *url, 563 const char *url,
558 const char *method, 564 const char *method,
559 const char *version, 565 const char *version,
560 const char *upload_data, 566 const char *upload_data,
561 size_t *upload_data_size, 567 size_t *upload_data_size,
562 void **ptr) 568 void **ptr)
563{ 569{
564 struct MHD_Response *response; 570 struct MHD_Response *response;
565 struct Request *request; 571 struct Request *request;
566 struct Session *session; 572 struct Session *session;
567 int ret; 573 int ret;
568 unsigned int i; 574 unsigned int i;
569 (void)cls; /* Unused. Silent compiler warning. */ 575 (void) cls; /* Unused. Silent compiler warning. */
570 (void)version; /* Unused. Silent compiler warning. */ 576 (void) version; /* Unused. Silent compiler warning. */
571 577
572 request = *ptr; 578 request = *ptr;
573 if (NULL == request) 579 if (NULL == request)
580 {
581 request = calloc (1, sizeof (struct Request));
582 if (NULL == request)
574 { 583 {
575 request = calloc (1, sizeof (struct Request)); 584 fprintf (stderr, "calloc error: %s\n", strerror (errno));
576 if (NULL == request) 585 return MHD_NO;
577 {
578 fprintf (stderr, "calloc error: %s\n", strerror (errno));
579 return MHD_NO;
580 }
581 *ptr = request;
582 if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
583 {
584 request->pp = MHD_create_post_processor (connection, 1024,
585 &post_iterator, request);
586 if (NULL == request->pp)
587 {
588 fprintf (stderr, "Failed to setup post processor for `%s'\n",
589 url);
590 return MHD_NO; /* internal error */
591 }
592 }
593 return MHD_YES;
594 } 586 }
587 *ptr = request;
588 if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
589 {
590 request->pp = MHD_create_post_processor (connection, 1024,
591 &post_iterator, request);
592 if (NULL == request->pp)
593 {
594 fprintf (stderr, "Failed to setup post processor for `%s'\n",
595 url);
596 return MHD_NO; /* internal error */
597 }
598 }
599 return MHD_YES;
600 }
595 if (NULL == request->session) 601 if (NULL == request->session)
602 {
603 request->session = get_session (connection);
604 if (NULL == request->session)
596 { 605 {
597 request->session = get_session (connection); 606 fprintf (stderr, "Failed to setup session for `%s'\n",
598 if (NULL == request->session) 607 url);
599 { 608 return MHD_NO; /* internal error */
600 fprintf (stderr, "Failed to setup session for `%s'\n",
601 url);
602 return MHD_NO; /* internal error */
603 }
604 } 609 }
610 }
605 session = request->session; 611 session = request->session;
606 session->start = time (NULL); 612 session->start = time (NULL);
607 if (0 == strcmp (method, MHD_HTTP_METHOD_POST)) 613 if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
614 {
615 /* evaluate POST data */
616 MHD_post_process (request->pp,
617 upload_data,
618 *upload_data_size);
619 if (0 != *upload_data_size)
608 { 620 {
609 /* evaluate POST data */ 621 *upload_data_size = 0;
610 MHD_post_process (request->pp, 622 return MHD_YES;
611 upload_data,
612 *upload_data_size);
613 if (0 != *upload_data_size)
614 {
615 *upload_data_size = 0;
616 return MHD_YES;
617 }
618 /* done with POST data, serve response */
619 MHD_destroy_post_processor (request->pp);
620 request->pp = NULL;
621 method = MHD_HTTP_METHOD_GET; /* fake 'GET' */
622 if (NULL != request->post_url)
623 url = request->post_url;
624 } 623 }
624 /* done with POST data, serve response */
625 MHD_destroy_post_processor (request->pp);
626 request->pp = NULL;
627 method = MHD_HTTP_METHOD_GET; /* fake 'GET' */
628 if (NULL != request->post_url)
629 url = request->post_url;
630 }
625 631
626 if ( (0 == strcmp (method, MHD_HTTP_METHOD_GET)) || 632 if ( (0 == strcmp (method, MHD_HTTP_METHOD_GET)) ||
627 (0 == strcmp (method, MHD_HTTP_METHOD_HEAD)) ) 633 (0 == strcmp (method, MHD_HTTP_METHOD_HEAD)) )
628 { 634 {
629 /* find out which page to serve */ 635 /* find out which page to serve */
630 i=0; 636 i = 0;
631 while ( (pages[i].url != NULL) && 637 while ( (pages[i].url != NULL) &&
632 (0 != strcmp (pages[i].url, url)) ) 638 (0 != strcmp (pages[i].url, url)) )
633 i++; 639 i++;
634 ret = pages[i].handler (pages[i].handler_cls, 640 ret = pages[i].handler (pages[i].handler_cls,
635 pages[i].mime, 641 pages[i].mime,
636 session, connection); 642 session, connection);
637 if (ret != MHD_YES) 643 if (ret != MHD_YES)
638 fprintf (stderr, "Failed to create page for `%s'\n", 644 fprintf (stderr, "Failed to create page for `%s'\n",
639 url); 645 url);
640 return ret; 646 return ret;
641 } 647 }
642 /* unsupported HTTP method */ 648 /* unsupported HTTP method */
643 response = MHD_create_response_from_buffer (strlen (METHOD_ERROR), 649 response = MHD_create_response_from_buffer (strlen (METHOD_ERROR),
644 (void *) METHOD_ERROR, 650 (void *) METHOD_ERROR,
645 MHD_RESPMEM_PERSISTENT); 651 MHD_RESPMEM_PERSISTENT);
646 ret = MHD_queue_response (connection, 652 ret = MHD_queue_response (connection,
647 MHD_HTTP_NOT_ACCEPTABLE, 653 MHD_HTTP_NOT_ACCEPTABLE,
648 response); 654 response);
649 MHD_destroy_response (response); 655 MHD_destroy_response (response);
650 return ret; 656 return ret;
651} 657}
@@ -662,14 +668,14 @@ create_response (void *cls,
662 */ 668 */
663static void 669static void
664request_completed_callback (void *cls, 670request_completed_callback (void *cls,
665 struct MHD_Connection *connection, 671 struct MHD_Connection *connection,
666 void **con_cls, 672 void **con_cls,
667 enum MHD_RequestTerminationCode toe) 673 enum MHD_RequestTerminationCode toe)
668{ 674{
669 struct Request *request = *con_cls; 675 struct Request *request = *con_cls;
670 (void)cls; /* Unused. Silent compiler warning. */ 676 (void) cls; /* Unused. Silent compiler warning. */
671 (void)connection; /* Unused. Silent compiler warning. */ 677 (void) connection; /* Unused. Silent compiler warning. */
672 (void)toe; /* Unused. Silent compiler warning. */ 678 (void) toe; /* Unused. Silent compiler warning. */
673 679
674 if (NULL == request) 680 if (NULL == request)
675 return; 681 return;
@@ -697,21 +703,21 @@ expire_sessions ()
697 prev = NULL; 703 prev = NULL;
698 pos = sessions; 704 pos = sessions;
699 while (NULL != pos) 705 while (NULL != pos)
706 {
707 next = pos->next;
708 if (now - pos->start > 60 * 60)
700 { 709 {
701 next = pos->next; 710 /* expire sessions after 1h */
702 if (now - pos->start > 60 * 60) 711 if (NULL == prev)
703 { 712 sessions = pos->next;
704 /* expire sessions after 1h */
705 if (NULL == prev)
706 sessions = pos->next;
707 else
708 prev->next = next;
709 free (pos);
710 }
711 else 713 else
712 prev = pos; 714 prev->next = next;
713 pos = next; 715 free (pos);
714 } 716 }
717 else
718 prev = pos;
719 pos = next;
720 }
715} 721}
716 722
717 723
@@ -732,45 +738,46 @@ main (int argc, char *const *argv)
732 MHD_UNSIGNED_LONG_LONG mhd_timeout; 738 MHD_UNSIGNED_LONG_LONG mhd_timeout;
733 739
734 if (argc != 2) 740 if (argc != 2)
735 { 741 {
736 printf ("%s PORT\n", argv[0]); 742 printf ("%s PORT\n", argv[0]);
737 return 1; 743 return 1;
738 } 744 }
739 /* initialize PRNG */ 745 /* initialize PRNG */
740 srand ((unsigned int) time (NULL)); 746 srand ((unsigned int) time (NULL));
741 d = MHD_start_daemon (MHD_USE_ERROR_LOG, 747 d = MHD_start_daemon (MHD_USE_ERROR_LOG,
742 atoi (argv[1]), 748 atoi (argv[1]),
743 NULL, NULL, 749 NULL, NULL,
744 &create_response, NULL, 750 &create_response, NULL,
745 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 15, 751 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 15,
746 MHD_OPTION_NOTIFY_COMPLETED, &request_completed_callback, NULL, 752 MHD_OPTION_NOTIFY_COMPLETED,
747 MHD_OPTION_END); 753 &request_completed_callback, NULL,
754 MHD_OPTION_END);
748 if (NULL == d) 755 if (NULL == d)
749 return 1; 756 return 1;
750 while (1) 757 while (1)
758 {
759 expire_sessions ();
760 max = 0;
761 FD_ZERO (&rs);
762 FD_ZERO (&ws);
763 FD_ZERO (&es);
764 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
765 break; /* fatal internal error */
766 if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES)
751 { 767 {
752 expire_sessions (); 768 tv.tv_sec = mhd_timeout / 1000;
753 max = 0; 769 tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000;
754 FD_ZERO (&rs); 770 tvp = &tv;
755 FD_ZERO (&ws);
756 FD_ZERO (&es);
757 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
758 break; /* fatal internal error */
759 if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES)
760 {
761 tv.tv_sec = mhd_timeout / 1000;
762 tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000;
763 tvp = &tv;
764 }
765 else
766 tvp = NULL;
767 if (-1 == select (max + 1, &rs, &ws, &es, tvp))
768 {
769 if (EINTR != errno)
770 abort ();
771 }
772 MHD_run (d);
773 } 771 }
772 else
773 tvp = NULL;
774 if (-1 == select (max + 1, &rs, &ws, &es, tvp))
775 {
776 if (EINTR != errno)
777 abort ();
778 }
779 MHD_run (d);
780 }
774 MHD_stop_daemon (d); 781 MHD_stop_daemon (d);
775 return 0; 782 return 0;
776} 783}