diff options
Diffstat (limited to 'src/examples/fileserver_example_dirs.c')
-rw-r--r-- | src/examples/fileserver_example_dirs.c | 162 |
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 | ||
34 | static ssize_t | 35 | static 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) |