aboutsummaryrefslogtreecommitdiff
path: root/src/examples/demo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/examples/demo.c')
-rw-r--r--src/examples/demo.c106
1 files changed, 53 insertions, 53 deletions
diff --git a/src/examples/demo.c b/src/examples/demo.c
index 4e7c5d2a..5ce1a244 100644
--- a/src/examples/demo.c
+++ b/src/examples/demo.c
@@ -21,7 +21,7 @@
21 * @file demo.c 21 * @file demo.c
22 * @brief complex demonstration site: create directory index, offer 22 * @brief complex demonstration site: create directory index, offer
23 * upload via form and HTTP POST, download with mime type detection 23 * upload via form and HTTP POST, download with mime type detection
24 * and error reporting (403, etc.) --- and all of this with 24 * and error reporting (403, etc.) --- and all of this with
25 * high-performance settings (large buffers, thread pool). 25 * high-performance settings (large buffers, thread pool).
26 * If you want to benchmark MHD, this code should be used to 26 * If you want to benchmark MHD, this code should be used to
27 * run tests against. Note that the number of threads may need 27 * run tests against. Note that the number of threads may need
@@ -222,7 +222,7 @@ struct ResponseDataContext
222 * Response data string. 222 * Response data string.
223 */ 223 */
224 char *buf; 224 char *buf;
225 225
226 /** 226 /**
227 * Number of bytes allocated for 'buf'. 227 * Number of bytes allocated for 'buf'.
228 */ 228 */
@@ -253,12 +253,12 @@ list_directory (struct ResponseDataContext *rdc,
253 struct dirent *de; 253 struct dirent *de;
254 254
255 if (NULL == (dir = opendir (dirname))) 255 if (NULL == (dir = opendir (dirname)))
256 return MHD_NO; 256 return MHD_NO;
257 while (NULL != (de = readdir (dir))) 257 while (NULL != (de = readdir (dir)))
258 { 258 {
259 if ('.' == de->d_name[0]) 259 if ('.' == de->d_name[0])
260 continue; 260 continue;
261 if (sizeof (fullname) <= 261 if (sizeof (fullname) <=
262 snprintf (fullname, sizeof (fullname), 262 snprintf (fullname, sizeof (fullname),
263 "%s/%s", 263 "%s/%s",
264 dirname, de->d_name)) 264 dirname, de->d_name))
@@ -278,7 +278,7 @@ list_directory (struct ResponseDataContext *rdc,
278 break; /* out of memory */ 278 break; /* out of memory */
279 rdc->buf = r; 279 rdc->buf = r;
280 } 280 }
281 rdc->off += snprintf (&rdc->buf[rdc->off], 281 rdc->off += snprintf (&rdc->buf[rdc->off],
282 rdc->buf_len - rdc->off, 282 rdc->buf_len - rdc->off,
283 "<li><a href=\"/%s\">%s</a></li>\n", 283 "<li><a href=\"/%s\">%s</a></li>\n",
284 fullname, 284 fullname,
@@ -305,11 +305,11 @@ update_directory ()
305 char dir_name[128]; 305 char dir_name[128];
306 struct stat sbuf; 306 struct stat sbuf;
307 307
308 rdc.buf_len = initial_allocation; 308 rdc.buf_len = initial_allocation;
309 if (NULL == (rdc.buf = malloc (rdc.buf_len))) 309 if (NULL == (rdc.buf = malloc (rdc.buf_len)))
310 { 310 {
311 update_cached_response (NULL); 311 update_cached_response (NULL);
312 return; 312 return;
313 } 313 }
314 rdc.off = snprintf (rdc.buf, rdc.buf_len, 314 rdc.off = snprintf (rdc.buf, rdc.buf_len,
315 "%s", 315 "%s",
@@ -342,7 +342,7 @@ update_directory ()
342 rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off, 342 rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off,
343 "<h3>%s</h3>\n", 343 "<h3>%s</h3>\n",
344 category); 344 category);
345 345
346 if (MHD_NO == list_directory (&rdc, dir_name)) 346 if (MHD_NO == list_directory (&rdc, dir_name))
347 { 347 {
348 free (rdc.buf); 348 free (rdc.buf);
@@ -352,7 +352,7 @@ update_directory ()
352 } 352 }
353 } 353 }
354 /* we ensured always +1k room, filenames are ~256 bytes, 354 /* we ensured always +1k room, filenames are ~256 bytes,
355 so there is always still enough space for the footer 355 so there is always still enough space for the footer
356 without need for a final reallocation check. */ 356 without need for a final reallocation check. */
357 rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off, 357 rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off,
358 "%s", 358 "%s",
@@ -427,7 +427,7 @@ do_append (char **ret,
427{ 427{
428 char *buf; 428 char *buf;
429 size_t old_len; 429 size_t old_len;
430 430
431 if (NULL == *ret) 431 if (NULL == *ret)
432 old_len = 0; 432 old_len = 0;
433 else 433 else
@@ -471,8 +471,8 @@ process_upload_data (void *cls,
471 const char *filename, 471 const char *filename,
472 const char *content_type, 472 const char *content_type,
473 const char *transfer_encoding, 473 const char *transfer_encoding,
474 const char *data, 474 const char *data,
475 uint64_t off, 475 uint64_t off,
476 size_t size) 476 size_t size)
477{ 477{
478 struct UploadContext *uc = cls; 478 struct UploadContext *uc = cls;
@@ -484,10 +484,10 @@ process_upload_data (void *cls,
484 return do_append (&uc->language, data, size); 484 return do_append (&uc->language, data, size);
485 if (0 != strcmp (key, "upload")) 485 if (0 != strcmp (key, "upload"))
486 { 486 {
487 fprintf (stderr, 487 fprintf (stderr,
488 "Ignoring unexpected form value `%s'\n", 488 "Ignoring unexpected form value `%s'\n",
489 key); 489 key);
490 return MHD_YES; /* ignore */ 490 return MHD_YES; /* ignore */
491 } 491 }
492 if (NULL == filename) 492 if (NULL == filename)
493 { 493 {
@@ -497,7 +497,7 @@ process_upload_data (void *cls,
497 if ( (NULL == uc->category) || 497 if ( (NULL == uc->category) ||
498 (NULL == uc->language) ) 498 (NULL == uc->language) )
499 { 499 {
500 fprintf (stderr, 500 fprintf (stderr,
501 "Missing form data for upload `%s'\n", 501 "Missing form data for upload `%s'\n",
502 filename); 502 filename);
503 uc->response = request_refused_response; 503 uc->response = request_refused_response;
@@ -523,8 +523,8 @@ process_upload_data (void *cls,
523 snprintf (fn, sizeof (fn), 523 snprintf (fn, sizeof (fn),
524 "%s/%s", 524 "%s/%s",
525 uc->language, 525 uc->language,
526 uc->category); 526 uc->category);
527#ifdef WINDOWS 527#ifdef WINDOWS
528 (void) mkdir (fn); 528 (void) mkdir (fn);
529#else 529#else
530 (void) mkdir (fn, S_IRWXU); 530 (void) mkdir (fn, S_IRWXU);
@@ -534,12 +534,12 @@ process_upload_data (void *cls,
534 "%s/%s/%s", 534 "%s/%s/%s",
535 uc->language, 535 uc->language,
536 uc->category, 536 uc->category,
537 filename); 537 filename);
538 for (i=strlen (fn)-1;i>=0;i--) 538 for (i=strlen (fn)-1;i>=0;i--)
539 if (! isprint ((int) fn[i])) 539 if (! isprint ((int) fn[i]))
540 fn[i] = '_'; 540 fn[i] = '_';
541 uc->fd = open (fn, 541 uc->fd = open (fn,
542 O_CREAT | O_EXCL 542 O_CREAT | O_EXCL
543#if O_LARGEFILE 543#if O_LARGEFILE
544 | O_LARGEFILE 544 | O_LARGEFILE
545#endif 545#endif
@@ -547,20 +547,20 @@ process_upload_data (void *cls,
547 S_IRUSR | S_IWUSR); 547 S_IRUSR | S_IWUSR);
548 if (-1 == uc->fd) 548 if (-1 == uc->fd)
549 { 549 {
550 fprintf (stderr, 550 fprintf (stderr,
551 "Error opening file `%s' for upload: %s\n", 551 "Error opening file `%s' for upload: %s\n",
552 fn, 552 fn,
553 strerror (errno)); 553 strerror (errno));
554 uc->response = request_refused_response; 554 uc->response = request_refused_response;
555 return MHD_NO; 555 return MHD_NO;
556 } 556 }
557 uc->filename = strdup (fn); 557 uc->filename = strdup (fn);
558 } 558 }
559 if ( (0 != size) && 559 if ( (0 != size) &&
560 (size != write (uc->fd, data, size)) ) 560 (size != write (uc->fd, data, size)) )
561 { 561 {
562 /* write failed; likely: disk full */ 562 /* write failed; likely: disk full */
563 fprintf (stderr, 563 fprintf (stderr,
564 "Error writing to file `%s': %s\n", 564 "Error writing to file `%s': %s\n",
565 uc->filename, 565 uc->filename,
566 strerror (errno)); 566 strerror (errno));
@@ -573,7 +573,7 @@ process_upload_data (void *cls,
573 free (uc->filename); 573 free (uc->filename);
574 uc->filename = NULL; 574 uc->filename = NULL;
575 } 575 }
576 return MHD_NO; 576 return MHD_NO;
577 } 577 }
578 return MHD_YES; 578 return MHD_YES;
579} 579}
@@ -610,13 +610,13 @@ response_completed_callback (void *cls,
610 (void) close (uc->fd); 610 (void) close (uc->fd);
611 if (NULL != uc->filename) 611 if (NULL != uc->filename)
612 { 612 {
613 fprintf (stderr, 613 fprintf (stderr,
614 "Upload of file `%s' failed (incomplete or aborted), removing file.\n", 614 "Upload of file `%s' failed (incomplete or aborted), removing file.\n",
615 uc->filename); 615 uc->filename);
616 (void) unlink (uc->filename); 616 (void) unlink (uc->filename);
617 } 617 }
618 } 618 }
619 if (NULL != uc->filename) 619 if (NULL != uc->filename)
620 free (uc->filename); 620 free (uc->filename);
621 free (uc); 621 free (uc);
622} 622}
@@ -624,7 +624,7 @@ response_completed_callback (void *cls,
624 624
625/** 625/**
626 * Return the current directory listing. 626 * Return the current directory listing.
627 * 627 *
628 * @param connection connection to return the directory for 628 * @param connection connection to return the directory for
629 * @return MHD_YES on success, MHD_NO on error 629 * @return MHD_YES on success, MHD_NO on error
630 */ 630 */
@@ -635,12 +635,12 @@ return_directory_response (struct MHD_Connection *connection)
635 635
636 (void) pthread_mutex_lock (&mutex); 636 (void) pthread_mutex_lock (&mutex);
637 if (NULL == cached_directory_response) 637 if (NULL == cached_directory_response)
638 ret = MHD_queue_response (connection, 638 ret = MHD_queue_response (connection,
639 MHD_HTTP_INTERNAL_SERVER_ERROR, 639 MHD_HTTP_INTERNAL_SERVER_ERROR,
640 internal_error_response); 640 internal_error_response);
641 else 641 else
642 ret = MHD_queue_response (connection, 642 ret = MHD_queue_response (connection,
643 MHD_HTTP_OK, 643 MHD_HTTP_OK,
644 cached_directory_response); 644 cached_directory_response);
645 (void) pthread_mutex_unlock (&mutex); 645 (void) pthread_mutex_unlock (&mutex);
646 return ret; 646 return ret;
@@ -657,7 +657,7 @@ return_directory_response (struct MHD_Connection *connection)
657 * @param version HTTP version 657 * @param version HTTP version
658 * @param upload_data data from upload (PUT/POST) 658 * @param upload_data data from upload (PUT/POST)
659 * @param upload_data_size number of bytes in "upload_data" 659 * @param upload_data_size number of bytes in "upload_data"
660 * @param ptr our context 660 * @param ptr our context
661 * @return MHD_YES on success, MHD_NO to drop connection 661 * @return MHD_YES on success, MHD_NO to drop connection
662 */ 662 */
663static int 663static int
@@ -668,11 +668,11 @@ generate_page (void *cls,
668 const char *version, 668 const char *version,
669 const char *upload_data, 669 const char *upload_data,
670 size_t *upload_data_size, void **ptr) 670 size_t *upload_data_size, void **ptr)
671{ 671{
672 struct MHD_Response *response; 672 struct MHD_Response *response;
673 int ret; 673 int ret;
674 int fd; 674 int fd;
675 struct stat buf; 675 struct stat buf;
676 676
677 if (0 != strcmp (url, "/")) 677 if (0 != strcmp (url, "/"))
678 { 678 {
@@ -685,13 +685,13 @@ generate_page (void *cls,
685 return MHD_NO; /* unexpected method (we're not polite...) */ 685 return MHD_NO; /* unexpected method (we're not polite...) */
686 if ( (0 == stat (&url[1], &buf)) && 686 if ( (0 == stat (&url[1], &buf)) &&
687 (NULL == strstr (&url[1], "..")) && 687 (NULL == strstr (&url[1], "..")) &&
688 ('/' != url[1])) 688 ('/' != url[1]))
689 fd = open (&url[1], O_RDONLY); 689 fd = open (&url[1], O_RDONLY);
690 else 690 else
691 fd = -1; 691 fd = -1;
692 if (-1 == fd) 692 if (-1 == fd)
693 return MHD_queue_response (connection, 693 return MHD_queue_response (connection,
694 MHD_HTTP_NOT_FOUND, 694 MHD_HTTP_NOT_FOUND,
695 file_not_found_response); 695 file_not_found_response);
696 /* read beginning of the file to determine mime type */ 696 /* read beginning of the file to determine mime type */
697 got = read (fd, file_data, sizeof (file_data)); 697 got = read (fd, file_data, sizeof (file_data));
@@ -701,12 +701,12 @@ generate_page (void *cls,
701 mime = NULL; 701 mime = NULL;
702 (void) lseek (fd, 0, SEEK_SET); 702 (void) lseek (fd, 0, SEEK_SET);
703 703
704 if (NULL == (response = MHD_create_response_from_fd (buf.st_size, 704 if (NULL == (response = MHD_create_response_from_fd (buf.st_size,
705 fd))) 705 fd)))
706 { 706 {
707 /* internal error (i.e. out of memory) */ 707 /* internal error (i.e. out of memory) */
708 (void) close (fd); 708 (void) close (fd);
709 return MHD_NO; 709 return MHD_NO;
710 } 710 }
711 711
712 /* add mime type if we had one */ 712 /* add mime type if we had one */
@@ -714,8 +714,8 @@ generate_page (void *cls,
714 (void) MHD_add_response_header (response, 714 (void) MHD_add_response_header (response,
715 MHD_HTTP_HEADER_CONTENT_TYPE, 715 MHD_HTTP_HEADER_CONTENT_TYPE,
716 mime); 716 mime);
717 ret = MHD_queue_response (connection, 717 ret = MHD_queue_response (connection,
718 MHD_HTTP_OK, 718 MHD_HTTP_OK,
719 response); 719 response);
720 MHD_destroy_response (response); 720 MHD_destroy_response (response);
721 return ret; 721 return ret;
@@ -744,11 +744,11 @@ generate_page (void *cls,
744 } 744 }
745 *ptr = uc; 745 *ptr = uc;
746 return MHD_YES; 746 return MHD_YES;
747 } 747 }
748 if (0 != *upload_data_size) 748 if (0 != *upload_data_size)
749 { 749 {
750 if (NULL == uc->response) 750 if (NULL == uc->response)
751 (void) MHD_post_process (uc->pp, 751 (void) MHD_post_process (uc->pp,
752 upload_data, 752 upload_data,
753 *upload_data_size); 753 *upload_data_size);
754 *upload_data_size = 0; 754 *upload_data_size = 0;
@@ -764,8 +764,8 @@ generate_page (void *cls,
764 } 764 }
765 if (NULL != uc->response) 765 if (NULL != uc->response)
766 { 766 {
767 return MHD_queue_response (connection, 767 return MHD_queue_response (connection,
768 MHD_HTTP_FORBIDDEN, 768 MHD_HTTP_FORBIDDEN,
769 uc->response); 769 uc->response);
770 } 770 }
771 else 771 else
@@ -778,8 +778,8 @@ generate_page (void *cls,
778 return return_directory_response (connection); 778 return return_directory_response (connection);
779 779
780 /* unexpected request, refuse */ 780 /* unexpected request, refuse */
781 return MHD_queue_response (connection, 781 return MHD_queue_response (connection,
782 MHD_HTTP_FORBIDDEN, 782 MHD_HTTP_FORBIDDEN,
783 request_refused_response); 783 request_refused_response);
784} 784}
785 785
@@ -837,7 +837,7 @@ main (int argc, char *const *argv)
837 837
838 if ( (argc != 2) || 838 if ( (argc != 2) ||
839 (1 != sscanf (argv[1], "%u", &port)) || 839 (1 != sscanf (argv[1], "%u", &port)) ||
840 (UINT16_MAX < port) ) 840 (UINT16_MAX < port) )
841 { 841 {
842 fprintf (stderr, 842 fprintf (stderr,
843 "%s PORT\n", argv[0]); 843 "%s PORT\n", argv[0]);
@@ -864,14 +864,14 @@ main (int argc, char *const *argv)
864 mark_as_html (internal_error_response); 864 mark_as_html (internal_error_response);
865 update_directory (); 865 update_directory ();
866 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG 866 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG
867#if EPOLL_SUPPORT 867#if EPOLL_SUPPORT
868 | MHD_USE_EPOLL_LINUX_ONLY 868 | MHD_USE_EPOLL_LINUX_ONLY
869#endif 869#endif
870 , 870 ,
871 port, 871 port,
872 NULL, NULL, 872 NULL, NULL,
873 &generate_page, NULL, 873 &generate_page, NULL,
874 MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (256 * 1024), 874 MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (256 * 1024),
875#if PRODUCTION 875#if PRODUCTION
876 MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) (64), 876 MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) (64),
877#endif 877#endif