diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-03-11 12:06:52 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-03-11 12:07:38 +0100 |
commit | 740a46dd3619f113b262a03c07e593be30d6b63d (patch) | |
tree | 6c4c72269bca6d3f030cea06e2da824b9abae58f /doc | |
parent | 15a2570f7cc3702c81ca783b4ff394fcbfe462ec (diff) | |
download | libmicrohttpd-740a46dd3619f113b262a03c07e593be30d6b63d.tar.gz libmicrohttpd-740a46dd3619f113b262a03c07e593be30d6b63d.zip |
fix largepost example, must only queue replies either before upload happens or after upload is done, not while upload is ongoing
Diffstat (limited to 'doc')
-rw-r--r-- | doc/examples/largepost.c | 113 |
1 files changed, 75 insertions, 38 deletions
diff --git a/doc/examples/largepost.c b/doc/examples/largepost.c index edaebd0d..6846a536 100644 --- a/doc/examples/largepost.c +++ b/doc/examples/largepost.c | |||
@@ -36,15 +36,36 @@ enum ConnectionType | |||
36 | 36 | ||
37 | static unsigned int nr_of_uploading_clients = 0; | 37 | static unsigned int nr_of_uploading_clients = 0; |
38 | 38 | ||
39 | |||
40 | /** | ||
41 | * Information we keep per connection. | ||
42 | */ | ||
39 | struct connection_info_struct | 43 | struct connection_info_struct |
40 | { | 44 | { |
41 | enum ConnectionType connectiontype; | 45 | enum ConnectionType connectiontype; |
46 | |||
47 | /** | ||
48 | * Handle to the POST processing state. | ||
49 | */ | ||
42 | struct MHD_PostProcessor *postprocessor; | 50 | struct MHD_PostProcessor *postprocessor; |
51 | |||
52 | /** | ||
53 | * File handle where we write uploaded data. | ||
54 | */ | ||
43 | FILE *fp; | 55 | FILE *fp; |
56 | |||
57 | /** | ||
58 | * HTTP response body we will return, NULL if not yet known. | ||
59 | */ | ||
44 | const char *answerstring; | 60 | const char *answerstring; |
45 | int answercode; | 61 | |
62 | /** | ||
63 | * HTTP status code we will return, 0 for undecided. | ||
64 | */ | ||
65 | unsigned int answercode; | ||
46 | }; | 66 | }; |
47 | 67 | ||
68 | |||
48 | const char *askpage = "<html><body>\n\ | 69 | const char *askpage = "<html><body>\n\ |
49 | Upload a file, please!<br>\n\ | 70 | Upload a file, please!<br>\n\ |
50 | There are %u clients uploading at the moment.<br>\n\ | 71 | There are %u clients uploading at the moment.<br>\n\ |
@@ -52,19 +73,18 @@ const char *askpage = "<html><body>\n\ | |||
52 | <input name=\"file\" type=\"file\">\n\ | 73 | <input name=\"file\" type=\"file\">\n\ |
53 | <input type=\"submit\" value=\" Send \"></form>\n\ | 74 | <input type=\"submit\" value=\" Send \"></form>\n\ |
54 | </body></html>"; | 75 | </body></html>"; |
55 | |||
56 | const char *busypage = | 76 | const char *busypage = |
57 | "<html><body>This server is busy, please try again later.</body></html>"; | 77 | "<html><body>This server is busy, please try again later.</body></html>"; |
58 | |||
59 | const char *completepage = | 78 | const char *completepage = |
60 | "<html><body>The upload has been completed.</body></html>"; | 79 | "<html><body>The upload has been completed.</body></html>"; |
61 | |||
62 | const char *errorpage = | 80 | const char *errorpage = |
63 | "<html><body>This doesn't seem to be right.</body></html>"; | 81 | "<html><body>This doesn't seem to be right.</body></html>"; |
64 | const char *servererrorpage = | 82 | const char *servererrorpage = |
65 | "<html><body>An internal server error has occured.</body></html>"; | 83 | "<html><body>Invalid request.</body></html>"; |
66 | const char *fileexistspage = | 84 | const char *fileexistspage = |
67 | "<html><body>This file already exists.</body></html>"; | 85 | "<html><body>This file already exists.</body></html>"; |
86 | const char *fileioerror = | ||
87 | "<html><body>IO error writing to disk.</body></html>"; | ||
68 | const char* const postprocerror = | 88 | const char* const postprocerror = |
69 | "<html><head><title>Error</title></head><body>Error processing POST data</body></html>"; | 89 | "<html><head><title>Error</title></head><body>Error processing POST data</body></html>"; |
70 | 90 | ||
@@ -109,11 +129,12 @@ iterate_post (void *coninfo_cls, | |||
109 | struct connection_info_struct *con_info = coninfo_cls; | 129 | struct connection_info_struct *con_info = coninfo_cls; |
110 | FILE *fp; | 130 | FILE *fp; |
111 | 131 | ||
112 | con_info->answerstring = servererrorpage; | ||
113 | con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
114 | |||
115 | if (0 != strcmp (key, "file")) | 132 | if (0 != strcmp (key, "file")) |
116 | return MHD_NO; | 133 | { |
134 | con_info->answerstring = servererrorpage; | ||
135 | con_info->answercode = MHD_HTTP_BAD_REQUEST; | ||
136 | return MHD_YES; | ||
137 | } | ||
117 | 138 | ||
118 | if (! con_info->fp) | 139 | if (! con_info->fp) |
119 | { | 140 | { |
@@ -122,23 +143,28 @@ iterate_post (void *coninfo_cls, | |||
122 | fclose (fp); | 143 | fclose (fp); |
123 | con_info->answerstring = fileexistspage; | 144 | con_info->answerstring = fileexistspage; |
124 | con_info->answercode = MHD_HTTP_FORBIDDEN; | 145 | con_info->answercode = MHD_HTTP_FORBIDDEN; |
125 | return MHD_NO; | 146 | return MHD_YES; |
126 | } | 147 | } |
127 | 148 | ||
128 | con_info->fp = fopen (filename, "ab"); | 149 | con_info->fp = fopen (filename, "ab"); |
129 | if (!con_info->fp) | 150 | if (!con_info->fp) |
130 | return MHD_NO; | 151 | { |
152 | con_info->answerstring = fileioerror; | ||
153 | con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
154 | return MHD_YES; | ||
155 | } | ||
131 | } | 156 | } |
132 | 157 | ||
133 | if (size > 0) | 158 | if (size > 0) |
134 | { | 159 | { |
135 | if (! fwrite (data, sizeof (char), size, con_info->fp)) | 160 | if (! fwrite (data, sizeof (char), size, con_info->fp)) |
136 | return MHD_NO; | 161 | { |
162 | con_info->answerstring = fileioerror; | ||
163 | con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
164 | return MHD_NO; | ||
165 | } | ||
137 | } | 166 | } |
138 | 167 | ||
139 | con_info->answerstring = completepage; | ||
140 | con_info->answercode = MHD_HTTP_OK; | ||
141 | |||
142 | return MHD_YES; | 168 | return MHD_YES; |
143 | } | 169 | } |
144 | 170 | ||
@@ -183,6 +209,7 @@ answer_to_connection (void *cls, | |||
183 | { | 209 | { |
184 | if (NULL == *con_cls) | 210 | if (NULL == *con_cls) |
185 | { | 211 | { |
212 | /* First call, setup data structures */ | ||
186 | struct connection_info_struct *con_info; | 213 | struct connection_info_struct *con_info; |
187 | 214 | ||
188 | if (nr_of_uploading_clients >= MAXCLIENTS) | 215 | if (nr_of_uploading_clients >= MAXCLIENTS) |
@@ -193,7 +220,7 @@ answer_to_connection (void *cls, | |||
193 | con_info = malloc (sizeof (struct connection_info_struct)); | 220 | con_info = malloc (sizeof (struct connection_info_struct)); |
194 | if (NULL == con_info) | 221 | if (NULL == con_info) |
195 | return MHD_NO; | 222 | return MHD_NO; |
196 | 223 | con_info->answercode = 0; /* none yet */ | |
197 | con_info->fp = NULL; | 224 | con_info->fp = NULL; |
198 | 225 | ||
199 | if (0 == strcasecmp (method, MHD_HTTP_METHOD_POST)) | 226 | if (0 == strcasecmp (method, MHD_HTTP_METHOD_POST)) |
@@ -213,11 +240,11 @@ answer_to_connection (void *cls, | |||
213 | nr_of_uploading_clients++; | 240 | nr_of_uploading_clients++; |
214 | 241 | ||
215 | con_info->connectiontype = POST; | 242 | con_info->connectiontype = POST; |
216 | con_info->answercode = MHD_HTTP_OK; | ||
217 | con_info->answerstring = completepage; | ||
218 | } | 243 | } |
219 | else | 244 | else |
220 | con_info->connectiontype = GET; | 245 | { |
246 | con_info->connectiontype = GET; | ||
247 | } | ||
221 | 248 | ||
222 | *con_cls = (void *) con_info; | 249 | *con_cls = (void *) con_info; |
223 | 250 | ||
@@ -226,6 +253,7 @@ answer_to_connection (void *cls, | |||
226 | 253 | ||
227 | if (0 == strcasecmp (method, MHD_HTTP_METHOD_GET)) | 254 | if (0 == strcasecmp (method, MHD_HTTP_METHOD_GET)) |
228 | { | 255 | { |
256 | /* We just return the standard form for uploads on all GET requests */ | ||
229 | char buffer[1024]; | 257 | char buffer[1024]; |
230 | 258 | ||
231 | snprintf (buffer, | 259 | snprintf (buffer, |
@@ -243,34 +271,43 @@ answer_to_connection (void *cls, | |||
243 | 271 | ||
244 | if (0 != *upload_data_size) | 272 | if (0 != *upload_data_size) |
245 | { | 273 | { |
246 | if (MHD_post_process (con_info->postprocessor, | 274 | /* Upload not yet done */ |
275 | if (0 != con_info->answercode) | ||
276 | { | ||
277 | /* we already know the answer, skip rest of upload */ | ||
278 | *upload_data_size = 0; | ||
279 | return MHD_YES; | ||
280 | } | ||
281 | if (MHD_YES != | ||
282 | MHD_post_process (con_info->postprocessor, | ||
247 | upload_data, | 283 | upload_data, |
248 | *upload_data_size) != MHD_YES) | 284 | *upload_data_size)) |
249 | { | 285 | { |
250 | return send_page (connection, | 286 | con_info->answerstring = postprocerror; |
251 | postprocerror, | 287 | con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR; |
252 | MHD_HTTP_BAD_REQUEST); | ||
253 | } | 288 | } |
254 | *upload_data_size = 0; | 289 | *upload_data_size = 0; |
255 | 290 | ||
256 | return MHD_YES; | 291 | return MHD_YES; |
257 | } | 292 | } |
258 | else | 293 | /* Upload finished */ |
259 | { | 294 | if (NULL != con_info->fp) |
260 | if (NULL != con_info->fp) | 295 | { |
261 | { | 296 | fclose (con_info->fp); |
262 | fclose (con_info->fp); | 297 | con_info->fp = NULL; |
263 | con_info->fp = NULL; | 298 | } |
264 | } | 299 | if (0 == con_info->answercode) |
265 | /* Now it is safe to open and inspect the file before | 300 | { |
266 | calling send_page with a response */ | 301 | /* No errors encountered, declare success */ |
267 | return send_page (connection, | 302 | con_info->answerstring = completepage; |
268 | con_info->answerstring, | 303 | con_info->answercode = MHD_HTTP_OK; |
269 | con_info->answercode); | 304 | } |
270 | } | 305 | return send_page (connection, |
271 | 306 | con_info->answerstring, | |
307 | con_info->answercode); | ||
272 | } | 308 | } |
273 | 309 | ||
310 | /* Note a GET or a POST, generate error */ | ||
274 | return send_page (connection, | 311 | return send_page (connection, |
275 | errorpage, | 312 | errorpage, |
276 | MHD_HTTP_BAD_REQUEST); | 313 | MHD_HTTP_BAD_REQUEST); |