libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 938b9b8dae70739c6e629bf144b57b5d6212e6b1
parent 7f9b98e25631731afd8b853b9f0163dc793a0a57
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Mon, 28 Nov 2016 13:36:11 +0300

fileserver_example: used MHD built-in function for sending files, added comments

Diffstat:
Msrc/examples/fileserver_example.c | 63+++++++++++++++++++++++++--------------------------------------
1 file changed, 25 insertions(+), 38 deletions(-)

diff --git a/src/examples/fileserver_example.c b/src/examples/fileserver_example.c @@ -24,31 +24,21 @@ #include "platform.h" #include <microhttpd.h> +#ifdef HAVE_UNISTD_H #include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif /* HAVE_SYS_STAT_H */ +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif /* HAVE_FCNTL_H */ #define PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>" - -static ssize_t -file_reader (void *cls, - uint64_t pos, - char *buf, - size_t max) -{ - FILE *file = cls; - - (void) fseek (file, pos, SEEK_SET); - return fread (buf, 1, max, file); -} - - -static void -free_callback (void *cls) -{ - FILE *file = cls; - fclose (file); -} - +#ifndef S_ISREG +#define S_ISREG(x) (S_IFREG == (x & S_IFREG)) +#endif /* S_ISREG */ static int ahc_echo (void *cls, @@ -62,7 +52,6 @@ ahc_echo (void *cls, static int aptr; struct MHD_Response *response; int ret; - FILE *file; int fd; struct stat buf; @@ -76,24 +65,25 @@ ahc_echo (void *cls, return MHD_YES; } *ptr = NULL; /* reset when done */ - file = fopen (&url[1], "rb"); - if (NULL != file) + /* WARNING: direct usage of url as filename is for example only! + * NEVER pass received data directly as parameter to file manipulation + * functions. Always check validity of data before using. + */ + if (NULL != strstr(url, "../")) /* Very simplified check! */ + fd = -1; /* Do not allow usage of parent directories. */ + else + fd = open (url + 1, O_RDONLY); + if (-1 != fd) { - fd = fileno (file); - if (-1 == fd) - { - (void) fclose (file); - return MHD_NO; /* internal error */ - } if ( (0 != fstat (fd, &buf)) || (! S_ISREG (buf.st_mode)) ) { /* not a regular file, refuse to serve */ - fclose (file); - file = NULL; + close (fd); + fd = -1; } } - if (NULL == file) + if (-1 == fd) { response = MHD_create_response_from_buffer (strlen (PAGE), (void *) PAGE, @@ -103,13 +93,10 @@ ahc_echo (void *cls, } else { - response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k page size */ - &file_reader, - file, - &free_callback); + response = MHD_create_response_from_fd64(buf.st_size, fd); if (NULL == response) { - fclose (file); + close (fd); return MHD_NO; } ret = MHD_queue_response (connection, MHD_HTTP_OK, response);