aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-03-11 12:06:52 +0100
committerChristian Grothoff <christian@grothoff.org>2017-03-11 12:07:38 +0100
commit740a46dd3619f113b262a03c07e593be30d6b63d (patch)
tree6c4c72269bca6d3f030cea06e2da824b9abae58f /doc
parent15a2570f7cc3702c81ca783b4ff394fcbfe462ec (diff)
downloadlibmicrohttpd-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.c113
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
37static unsigned int nr_of_uploading_clients = 0; 37static unsigned int nr_of_uploading_clients = 0;
38 38
39
40/**
41 * Information we keep per connection.
42 */
39struct connection_info_struct 43struct 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
48const char *askpage = "<html><body>\n\ 69const 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
56const char *busypage = 76const 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
59const char *completepage = 78const char *completepage =
60 "<html><body>The upload has been completed.</body></html>"; 79 "<html><body>The upload has been completed.</body></html>";
61
62const char *errorpage = 80const 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>";
64const char *servererrorpage = 82const char *servererrorpage =
65 "<html><body>An internal server error has occured.</body></html>"; 83 "<html><body>Invalid request.</body></html>";
66const char *fileexistspage = 84const char *fileexistspage =
67 "<html><body>This file already exists.</body></html>"; 85 "<html><body>This file already exists.</body></html>";
86const char *fileioerror =
87 "<html><body>IO error writing to disk.</body></html>";
68const char* const postprocerror = 88const 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);