aboutsummaryrefslogtreecommitdiff
path: root/src/examples/fileserver_example_dirs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/examples/fileserver_example_dirs.c')
-rw-r--r--src/examples/fileserver_example_dirs.c162
1 files changed, 82 insertions, 80 deletions
diff --git a/src/examples/fileserver_example_dirs.c b/src/examples/fileserver_example_dirs.c
index 8c37f219..2b544b69 100644
--- a/src/examples/fileserver_example_dirs.c
+++ b/src/examples/fileserver_example_dirs.c
@@ -28,7 +28,8 @@
28#include <microhttpd.h> 28#include <microhttpd.h>
29#include <unistd.h> 29#include <unistd.h>
30 30
31#define PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>" 31#define PAGE \
32 "<html><head><title>File not found</title></head><body>File not found</body></html>"
32 33
33 34
34static ssize_t 35static ssize_t
@@ -66,17 +67,17 @@ dir_reader (void *cls, uint64_t pos, char *buf, size_t max)
66 67
67 if (max < 512) 68 if (max < 512)
68 return 0; 69 return 0;
69 (void)pos; /* 'pos' is ignored as function return next one single entry per call. */ 70 (void) pos; /* 'pos' is ignored as function return next one single entry per call. */
70 do 71 do
71 { 72 {
72 e = readdir (dir); 73 e = readdir (dir);
73 if (e == NULL) 74 if (e == NULL)
74 return MHD_CONTENT_READER_END_OF_STREAM; 75 return MHD_CONTENT_READER_END_OF_STREAM;
75 } while (e->d_name[0] == '.'); 76 } while (e->d_name[0] == '.');
76 return snprintf (buf, max, 77 return snprintf (buf, max,
77 "<a href=\"/%s\">%s</a><br>", 78 "<a href=\"/%s\">%s</a><br>",
78 e->d_name, 79 e->d_name,
79 e->d_name); 80 e->d_name);
80} 81}
81 82
82 83
@@ -87,7 +88,7 @@ ahc_echo (void *cls,
87 const char *method, 88 const char *method,
88 const char *version, 89 const char *version,
89 const char *upload_data, 90 const char *upload_data,
90 size_t *upload_data_size, void **ptr) 91 size_t *upload_data_size, void **ptr)
91{ 92{
92 static int aptr; 93 static int aptr;
93 struct MHD_Response *response; 94 struct MHD_Response *response;
@@ -97,90 +98,90 @@ ahc_echo (void *cls,
97 DIR *dir; 98 DIR *dir;
98 struct stat buf; 99 struct stat buf;
99 char emsg[1024]; 100 char emsg[1024];
100 (void)cls; /* Unused. Silent compiler warning. */ 101 (void) cls; /* Unused. Silent compiler warning. */
101 (void)version; /* Unused. Silent compiler warning. */ 102 (void) version; /* Unused. Silent compiler warning. */
102 (void)upload_data; /* Unused. Silent compiler warning. */ 103 (void) upload_data; /* Unused. Silent compiler warning. */
103 (void)upload_data_size; /* Unused. Silent compiler warning. */ 104 (void) upload_data_size; /* Unused. Silent compiler warning. */
104 105
105 if (0 != strcmp (method, MHD_HTTP_METHOD_GET)) 106 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
106 return MHD_NO; /* unexpected method */ 107 return MHD_NO; /* unexpected method */
107 if (&aptr != *ptr) 108 if (&aptr != *ptr)
108 { 109 {
109 /* do never respond on first call */ 110 /* do never respond on first call */
110 *ptr = &aptr; 111 *ptr = &aptr;
111 return MHD_YES; 112 return MHD_YES;
112 } 113 }
113 *ptr = NULL; /* reset when done */ 114 *ptr = NULL; /* reset when done */
114 115
115 file = fopen (&url[1], "rb"); 116 file = fopen (&url[1], "rb");
116 if (NULL != file) 117 if (NULL != file)
118 {
119 fd = fileno (file);
120 if (-1 == fd)
117 { 121 {
118 fd = fileno (file); 122 (void) fclose (file);
119 if (-1 == fd) 123 return MHD_NO; /* internal error */
120 {
121 (void) fclose (file);
122 return MHD_NO; /* internal error */
123 }
124 if ( (0 != fstat (fd, &buf)) ||
125 (! S_ISREG (buf.st_mode)) )
126 {
127 /* not a regular file, refuse to serve */
128 fclose (file);
129 file = NULL;
130 }
131 } 124 }
125 if ( (0 != fstat (fd, &buf)) ||
126 (! S_ISREG (buf.st_mode)) )
127 {
128 /* not a regular file, refuse to serve */
129 fclose (file);
130 file = NULL;
131 }
132 }
132 133
133 if (NULL == file) 134 if (NULL == file)
135 {
136 dir = opendir (".");
137 if (NULL == dir)
134 { 138 {
135 dir = opendir ("."); 139 /* most likely cause: more concurrent requests than
136 if (NULL == dir) 140 available file descriptors / 2 */
137 { 141 snprintf (emsg,
138 /* most likely cause: more concurrent requests than 142 sizeof (emsg),
139 available file descriptors / 2 */ 143 "Failed to open directory `.': %s\n",
140 snprintf (emsg, 144 strerror (errno));
141 sizeof (emsg), 145 response = MHD_create_response_from_buffer (strlen (emsg),
142 "Failed to open directory `.': %s\n", 146 emsg,
143 strerror (errno)); 147 MHD_RESPMEM_MUST_COPY);
144 response = MHD_create_response_from_buffer (strlen (emsg), 148 if (NULL == response)
145 emsg, 149 return MHD_NO;
146 MHD_RESPMEM_MUST_COPY); 150 ret = MHD_queue_response (connection,
147 if (NULL == response) 151 MHD_HTTP_SERVICE_UNAVAILABLE,
148 return MHD_NO; 152 response);
149 ret = MHD_queue_response (connection, 153 MHD_destroy_response (response);
150 MHD_HTTP_SERVICE_UNAVAILABLE,
151 response);
152 MHD_destroy_response (response);
153 }
154 else
155 {
156 response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
157 32 * 1024,
158 &dir_reader,
159 dir,
160 &dir_free_callback);
161 if (NULL == response)
162 {
163 closedir (dir);
164 return MHD_NO;
165 }
166 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
167 MHD_destroy_response (response);
168 }
169 } 154 }
170 else 155 else
171 { 156 {
172 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k page size */ 157 response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
173 &file_reader, 158 32 * 1024,
174 file, 159 &dir_reader,
175 &file_free_callback); 160 dir,
161 &dir_free_callback);
176 if (NULL == response) 162 if (NULL == response)
177 { 163 {
178 fclose (file); 164 closedir (dir);
179 return MHD_NO; 165 return MHD_NO;
180 } 166 }
181 ret = MHD_queue_response (connection, MHD_HTTP_OK, response); 167 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
182 MHD_destroy_response (response); 168 MHD_destroy_response (response);
183 } 169 }
170 }
171 else
172 {
173 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k page size */
174 &file_reader,
175 file,
176 &file_free_callback);
177 if (NULL == response)
178 {
179 fclose (file);
180 return MHD_NO;
181 }
182 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
183 MHD_destroy_response (response);
184 }
184 return ret; 185 return ret;
185} 186}
186 187
@@ -191,11 +192,12 @@ main (int argc, char *const *argv)
191 struct MHD_Daemon *d; 192 struct MHD_Daemon *d;
192 193
193 if (argc != 2) 194 if (argc != 2)
194 { 195 {
195 printf ("%s PORT\n", argv[0]); 196 printf ("%s PORT\n", argv[0]);
196 return 1; 197 return 1;
197 } 198 }
198 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, 199 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
200 | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
199 atoi (argv[1]), 201 atoi (argv[1]),
200 NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); 202 NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END);
201 if (NULL == d) 203 if (NULL == d)