diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-01-18 22:14:09 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-01-18 22:14:09 +0000 |
commit | 9363e91e9476c489852c4f6c0a70ea6570ec469c (patch) | |
tree | 9bfb0beb76825f6b292211129d36da9356db1721 /src/examples/fileserver_example_dirs.c | |
parent | a0f69a6671f46af1a436e18dd6bf99ec1f9a6a56 (diff) | |
download | libmicrohttpd-9363e91e9476c489852c4f6c0a70ea6570ec469c.tar.gz libmicrohttpd-9363e91e9476c489852c4f6c0a70ea6570ec469c.zip |
fixing another one of the open/stat clones
Diffstat (limited to 'src/examples/fileserver_example_dirs.c')
-rw-r--r-- | src/examples/fileserver_example_dirs.c | 52 |
1 files changed, 37 insertions, 15 deletions
diff --git a/src/examples/fileserver_example_dirs.c b/src/examples/fileserver_example_dirs.c index 9d4a1935..e0a6362c 100644 --- a/src/examples/fileserver_example_dirs.c +++ b/src/examples/fileserver_example_dirs.c | |||
@@ -18,7 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | /** | 20 | /** |
21 | * @file fileserver_example.c | 21 | * @file fileserver_example_dirs.c |
22 | * @brief example for how to use libmicrohttpd to serve files (with directory support) | 22 | * @brief example for how to use libmicrohttpd to serve files (with directory support) |
23 | * @author Christian Grothoff | 23 | * @author Christian Grothoff |
24 | */ | 24 | */ |
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #define PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>" | 31 | #define PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>" |
32 | 32 | ||
33 | |||
33 | static ssize_t | 34 | static ssize_t |
34 | file_reader (void *cls, uint64_t pos, char *buf, size_t max) | 35 | file_reader (void *cls, uint64_t pos, char *buf, size_t max) |
35 | { | 36 | { |
@@ -39,6 +40,7 @@ file_reader (void *cls, uint64_t pos, char *buf, size_t max) | |||
39 | return fread (buf, 1, max, file); | 40 | return fread (buf, 1, max, file); |
40 | } | 41 | } |
41 | 42 | ||
43 | |||
42 | static void | 44 | static void |
43 | file_free_callback (void *cls) | 45 | file_free_callback (void *cls) |
44 | { | 46 | { |
@@ -46,6 +48,7 @@ file_free_callback (void *cls) | |||
46 | fclose (file); | 48 | fclose (file); |
47 | } | 49 | } |
48 | 50 | ||
51 | |||
49 | static void | 52 | static void |
50 | dir_free_callback (void *cls) | 53 | dir_free_callback (void *cls) |
51 | { | 54 | { |
@@ -54,6 +57,7 @@ dir_free_callback (void *cls) | |||
54 | closedir (dir); | 57 | closedir (dir); |
55 | } | 58 | } |
56 | 59 | ||
60 | |||
57 | static ssize_t | 61 | static ssize_t |
58 | dir_reader (void *cls, uint64_t pos, char *buf, size_t max) | 62 | dir_reader (void *cls, uint64_t pos, char *buf, size_t max) |
59 | { | 63 | { |
@@ -88,6 +92,7 @@ ahc_echo (void *cls, | |||
88 | struct MHD_Response *response; | 92 | struct MHD_Response *response; |
89 | int ret; | 93 | int ret; |
90 | FILE *file; | 94 | FILE *file; |
95 | int fd; | ||
91 | DIR *dir; | 96 | DIR *dir; |
92 | struct stat buf; | 97 | struct stat buf; |
93 | char emsg[1024]; | 98 | char emsg[1024]; |
@@ -101,17 +106,31 @@ ahc_echo (void *cls, | |||
101 | return MHD_YES; | 106 | return MHD_YES; |
102 | } | 107 | } |
103 | *ptr = NULL; /* reset when done */ | 108 | *ptr = NULL; /* reset when done */ |
104 | if ( (0 == stat (&url[1], &buf)) && | 109 | |
105 | (S_ISREG (buf.st_mode)) ) | 110 | file = fopen (&url[1], "rb"); |
106 | file = fopen (&url[1], "rb"); | 111 | if (NULL != file) |
107 | else | 112 | { |
108 | file = NULL; | 113 | fd = fileno (file); |
109 | if (file == NULL) | 114 | if (-1 == fd) |
115 | { | ||
116 | (void) fclose (file); | ||
117 | return MHD_NO; /* internal error */ | ||
118 | } | ||
119 | if ( (0 != fstat (fd, &buf)) || | ||
120 | (! S_ISREG (buf.st_mode)) ) | ||
121 | { | ||
122 | /* not a regular file, refuse to serve */ | ||
123 | fclose (file); | ||
124 | file = NULL; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | if (NULL == file) | ||
110 | { | 129 | { |
111 | dir = opendir ("."); | 130 | dir = opendir ("."); |
112 | if (dir == NULL) | 131 | if (NULL == dir) |
113 | { | 132 | { |
114 | /* most likely cause: more concurrent requests than | 133 | /* most likely cause: more concurrent requests than |
115 | available file descriptors / 2 */ | 134 | available file descriptors / 2 */ |
116 | snprintf (emsg, | 135 | snprintf (emsg, |
117 | sizeof (emsg), | 136 | sizeof (emsg), |
@@ -120,9 +139,11 @@ ahc_echo (void *cls, | |||
120 | response = MHD_create_response_from_buffer (strlen (emsg), | 139 | response = MHD_create_response_from_buffer (strlen (emsg), |
121 | emsg, | 140 | emsg, |
122 | MHD_RESPMEM_MUST_COPY); | 141 | MHD_RESPMEM_MUST_COPY); |
123 | if (response == NULL) | 142 | if (NULL == response) |
124 | return MHD_NO; | 143 | return MHD_NO; |
125 | ret = MHD_queue_response (connection, MHD_HTTP_SERVICE_UNAVAILABLE, response); | 144 | ret = MHD_queue_response (connection, |
145 | MHD_HTTP_SERVICE_UNAVAILABLE, | ||
146 | response); | ||
126 | MHD_destroy_response (response); | 147 | MHD_destroy_response (response); |
127 | } | 148 | } |
128 | else | 149 | else |
@@ -132,7 +153,7 @@ ahc_echo (void *cls, | |||
132 | &dir_reader, | 153 | &dir_reader, |
133 | dir, | 154 | dir, |
134 | &dir_free_callback); | 155 | &dir_free_callback); |
135 | if (response == NULL) | 156 | if (NULL == response) |
136 | { | 157 | { |
137 | closedir (dir); | 158 | closedir (dir); |
138 | return MHD_NO; | 159 | return MHD_NO; |
@@ -147,7 +168,7 @@ ahc_echo (void *cls, | |||
147 | &file_reader, | 168 | &file_reader, |
148 | file, | 169 | file, |
149 | &file_free_callback); | 170 | &file_free_callback); |
150 | if (response == NULL) | 171 | if (NULL == response) |
151 | { | 172 | { |
152 | fclose (file); | 173 | fclose (file); |
153 | return MHD_NO; | 174 | return MHD_NO; |
@@ -158,6 +179,7 @@ ahc_echo (void *cls, | |||
158 | return ret; | 179 | return ret; |
159 | } | 180 | } |
160 | 181 | ||
182 | |||
161 | int | 183 | int |
162 | main (int argc, char *const *argv) | 184 | main (int argc, char *const *argv) |
163 | { | 185 | { |
@@ -171,7 +193,7 @@ main (int argc, char *const *argv) | |||
171 | d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, | 193 | d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, |
172 | atoi (argv[1]), | 194 | atoi (argv[1]), |
173 | NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); | 195 | NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); |
174 | if (d == NULL) | 196 | if (NULL == d) |
175 | return 1; | 197 | return 1; |
176 | (void) getc (stdin); | 198 | (void) getc (stdin); |
177 | MHD_stop_daemon (d); | 199 | MHD_stop_daemon (d); |