diff options
Diffstat (limited to 'src/examples/demo.c')
-rw-r--r-- | src/examples/demo.c | 106 |
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 | */ |
663 | static int | 663 | static 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 |