diff options
Diffstat (limited to 'src/examples/post_example.c')
-rw-r--r-- | src/examples/post_example.c | 509 |
1 files changed, 258 insertions, 251 deletions
diff --git a/src/examples/post_example.c b/src/examples/post_example.c index 6c9a3f4b..311bf6c2 100644 --- a/src/examples/post_example.c +++ b/src/examples/post_example.c | |||
@@ -32,32 +32,38 @@ | |||
32 | /** | 32 | /** |
33 | * Invalid method page. | 33 | * Invalid method page. |
34 | */ | 34 | */ |
35 | #define METHOD_ERROR "<html><head><title>Illegal request</title></head><body>Go away.</body></html>" | 35 | #define METHOD_ERROR \ |
36 | "<html><head><title>Illegal request</title></head><body>Go away.</body></html>" | ||
36 | 37 | ||
37 | /** | 38 | /** |
38 | * Invalid URL page. | 39 | * Invalid URL page. |
39 | */ | 40 | */ |
40 | #define NOT_FOUND_ERROR "<html><head><title>Not found</title></head><body>Go away.</body></html>" | 41 | #define NOT_FOUND_ERROR \ |
42 | "<html><head><title>Not found</title></head><body>Go away.</body></html>" | ||
41 | 43 | ||
42 | /** | 44 | /** |
43 | * Front page. (/) | 45 | * Front page. (/) |
44 | */ | 46 | */ |
45 | #define MAIN_PAGE "<html><head><title>Welcome</title></head><body><form action=\"/2\" method=\"post\">What is your name? <input type=\"text\" name=\"v1\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>" | 47 | #define MAIN_PAGE \ |
48 | "<html><head><title>Welcome</title></head><body><form action=\"/2\" method=\"post\">What is your name? <input type=\"text\" name=\"v1\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>" | ||
46 | 49 | ||
47 | /** | 50 | /** |
48 | * Second page. (/2) | 51 | * Second page. (/2) |
49 | */ | 52 | */ |
50 | #define SECOND_PAGE "<html><head><title>Tell me more</title></head><body><a href=\"/\">previous</a> <form action=\"/S\" method=\"post\">%s, what is your job? <input type=\"text\" name=\"v2\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>" | 53 | #define SECOND_PAGE \ |
54 | "<html><head><title>Tell me more</title></head><body><a href=\"/\">previous</a> <form action=\"/S\" method=\"post\">%s, what is your job? <input type=\"text\" name=\"v2\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>" | ||
51 | 55 | ||
52 | /** | 56 | /** |
53 | * Second page (/S) | 57 | * Second page (/S) |
54 | */ | 58 | */ |
55 | #define SUBMIT_PAGE "<html><head><title>Ready to submit?</title></head><body><form action=\"/F\" method=\"post\"><a href=\"/2\">previous </a> <input type=\"hidden\" name=\"DONE\" value=\"yes\" /><input type=\"submit\" value=\"Submit\" /></body></html>" | 59 | #define SUBMIT_PAGE \ |
60 | "<html><head><title>Ready to submit?</title></head><body><form action=\"/F\" method=\"post\"><a href=\"/2\">previous </a> <input type=\"hidden\" name=\"DONE\" value=\"yes\" /><input type=\"submit\" value=\"Submit\" /></body></html>" | ||
56 | 61 | ||
57 | /** | 62 | /** |
58 | * Last page. | 63 | * Last page. |
59 | */ | 64 | */ |
60 | #define LAST_PAGE "<html><head><title>Thank you</title></head><body>Thank you.</body></html>" | 65 | #define LAST_PAGE \ |
66 | "<html><head><title>Thank you</title></head><body>Thank you.</body></html>" | ||
61 | 67 | ||
62 | /** | 68 | /** |
63 | * Name of our cookie. | 69 | * Name of our cookie. |
@@ -150,40 +156,40 @@ get_session (struct MHD_Connection *connection) | |||
150 | const char *cookie; | 156 | const char *cookie; |
151 | 157 | ||
152 | cookie = MHD_lookup_connection_value (connection, | 158 | cookie = MHD_lookup_connection_value (connection, |
153 | MHD_COOKIE_KIND, | 159 | MHD_COOKIE_KIND, |
154 | COOKIE_NAME); | 160 | COOKIE_NAME); |
155 | if (cookie != NULL) | 161 | if (cookie != NULL) |
162 | { | ||
163 | /* find existing session */ | ||
164 | ret = sessions; | ||
165 | while (NULL != ret) | ||
166 | { | ||
167 | if (0 == strcmp (cookie, ret->sid)) | ||
168 | break; | ||
169 | ret = ret->next; | ||
170 | } | ||
171 | if (NULL != ret) | ||
156 | { | 172 | { |
157 | /* find existing session */ | 173 | ret->rc++; |
158 | ret = sessions; | 174 | return ret; |
159 | while (NULL != ret) | ||
160 | { | ||
161 | if (0 == strcmp (cookie, ret->sid)) | ||
162 | break; | ||
163 | ret = ret->next; | ||
164 | } | ||
165 | if (NULL != ret) | ||
166 | { | ||
167 | ret->rc++; | ||
168 | return ret; | ||
169 | } | ||
170 | } | 175 | } |
176 | } | ||
171 | /* create fresh session */ | 177 | /* create fresh session */ |
172 | ret = calloc (1, sizeof (struct Session)); | 178 | ret = calloc (1, sizeof (struct Session)); |
173 | if (NULL == ret) | 179 | if (NULL == ret) |
174 | { | 180 | { |
175 | fprintf (stderr, "calloc error: %s\n", strerror (errno)); | 181 | fprintf (stderr, "calloc error: %s\n", strerror (errno)); |
176 | return NULL; | 182 | return NULL; |
177 | } | 183 | } |
178 | /* not a super-secure way to generate a random session ID, | 184 | /* not a super-secure way to generate a random session ID, |
179 | but should do for a simple example... */ | 185 | but should do for a simple example... */ |
180 | snprintf (ret->sid, | 186 | snprintf (ret->sid, |
181 | sizeof (ret->sid), | 187 | sizeof (ret->sid), |
182 | "%X%X%X%X", | 188 | "%X%X%X%X", |
183 | (unsigned int) rand (), | 189 | (unsigned int) rand (), |
184 | (unsigned int) rand (), | 190 | (unsigned int) rand (), |
185 | (unsigned int) rand (), | 191 | (unsigned int) rand (), |
186 | (unsigned int) rand ()); | 192 | (unsigned int) rand ()); |
187 | ret->rc++; | 193 | ret->rc++; |
188 | ret->start = time (NULL); | 194 | ret->start = time (NULL); |
189 | ret->next = sessions; | 195 | ret->next = sessions; |
@@ -202,9 +208,9 @@ get_session (struct MHD_Connection *connection) | |||
202 | * @param MHD_YES on success, MHD_NO on failure | 208 | * @param MHD_YES on success, MHD_NO on failure |
203 | */ | 209 | */ |
204 | typedef int (*PageHandler)(const void *cls, | 210 | typedef int (*PageHandler)(const void *cls, |
205 | const char *mime, | 211 | const char *mime, |
206 | struct Session *session, | 212 | struct Session *session, |
207 | struct MHD_Connection *connection); | 213 | struct MHD_Connection *connection); |
208 | 214 | ||
209 | 215 | ||
210 | /** | 216 | /** |
@@ -242,22 +248,22 @@ struct Page | |||
242 | */ | 248 | */ |
243 | static void | 249 | static void |
244 | add_session_cookie (struct Session *session, | 250 | add_session_cookie (struct Session *session, |
245 | struct MHD_Response *response) | 251 | struct MHD_Response *response) |
246 | { | 252 | { |
247 | char cstr[256]; | 253 | char cstr[256]; |
248 | snprintf (cstr, | 254 | snprintf (cstr, |
249 | sizeof (cstr), | 255 | sizeof (cstr), |
250 | "%s=%s", | 256 | "%s=%s", |
251 | COOKIE_NAME, | 257 | COOKIE_NAME, |
252 | session->sid); | 258 | session->sid); |
253 | if (MHD_NO == | 259 | if (MHD_NO == |
254 | MHD_add_response_header (response, | 260 | MHD_add_response_header (response, |
255 | MHD_HTTP_HEADER_SET_COOKIE, | 261 | MHD_HTTP_HEADER_SET_COOKIE, |
256 | cstr)) | 262 | cstr)) |
257 | { | 263 | { |
258 | fprintf (stderr, | 264 | fprintf (stderr, |
259 | "Failed to set session cookie header!\n"); | 265 | "Failed to set session cookie header!\n"); |
260 | } | 266 | } |
261 | } | 267 | } |
262 | 268 | ||
263 | 269 | ||
@@ -272,9 +278,9 @@ add_session_cookie (struct Session *session, | |||
272 | */ | 278 | */ |
273 | static int | 279 | static int |
274 | serve_simple_form (const void *cls, | 280 | serve_simple_form (const void *cls, |
275 | const char *mime, | 281 | const char *mime, |
276 | struct Session *session, | 282 | struct Session *session, |
277 | struct MHD_Connection *connection) | 283 | struct MHD_Connection *connection) |
278 | { | 284 | { |
279 | int ret; | 285 | int ret; |
280 | const char *form = cls; | 286 | const char *form = cls; |
@@ -282,17 +288,17 @@ serve_simple_form (const void *cls, | |||
282 | 288 | ||
283 | /* return static form */ | 289 | /* return static form */ |
284 | response = MHD_create_response_from_buffer (strlen (form), | 290 | response = MHD_create_response_from_buffer (strlen (form), |
285 | (void *) form, | 291 | (void *) form, |
286 | MHD_RESPMEM_PERSISTENT); | 292 | MHD_RESPMEM_PERSISTENT); |
287 | if (NULL == response) | 293 | if (NULL == response) |
288 | return MHD_NO; | 294 | return MHD_NO; |
289 | add_session_cookie (session, response); | 295 | add_session_cookie (session, response); |
290 | MHD_add_response_header (response, | 296 | MHD_add_response_header (response, |
291 | MHD_HTTP_HEADER_CONTENT_ENCODING, | 297 | MHD_HTTP_HEADER_CONTENT_ENCODING, |
292 | mime); | 298 | mime); |
293 | ret = MHD_queue_response (connection, | 299 | ret = MHD_queue_response (connection, |
294 | MHD_HTTP_OK, | 300 | MHD_HTTP_OK, |
295 | response); | 301 | response); |
296 | MHD_destroy_response (response); | 302 | MHD_destroy_response (response); |
297 | return ret; | 303 | return ret; |
298 | } | 304 | } |
@@ -308,28 +314,28 @@ serve_simple_form (const void *cls, | |||
308 | */ | 314 | */ |
309 | static int | 315 | static int |
310 | fill_v1_form (const void *cls, | 316 | fill_v1_form (const void *cls, |
311 | const char *mime, | 317 | const char *mime, |
312 | struct Session *session, | 318 | struct Session *session, |
313 | struct MHD_Connection *connection) | 319 | struct MHD_Connection *connection) |
314 | { | 320 | { |
315 | int ret; | 321 | int ret; |
316 | size_t slen; | 322 | size_t slen; |
317 | char *reply; | 323 | char *reply; |
318 | struct MHD_Response *response; | 324 | struct MHD_Response *response; |
319 | (void)cls; /* Unused. Silent compiler warning. */ | 325 | (void) cls; /* Unused. Silent compiler warning. */ |
320 | 326 | ||
321 | slen = strlen (MAIN_PAGE) + strlen (session->value_1); | 327 | slen = strlen (MAIN_PAGE) + strlen (session->value_1); |
322 | reply = malloc (slen + 1); | 328 | reply = malloc (slen + 1); |
323 | if (NULL == reply) | 329 | if (NULL == reply) |
324 | return MHD_NO; | 330 | return MHD_NO; |
325 | snprintf (reply, | 331 | snprintf (reply, |
326 | slen + 1, | 332 | slen + 1, |
327 | MAIN_PAGE, | 333 | MAIN_PAGE, |
328 | session->value_1); | 334 | session->value_1); |
329 | /* return static form */ | 335 | /* return static form */ |
330 | response = MHD_create_response_from_buffer (slen, | 336 | response = MHD_create_response_from_buffer (slen, |
331 | (void *) reply, | 337 | (void *) reply, |
332 | MHD_RESPMEM_MUST_FREE); | 338 | MHD_RESPMEM_MUST_FREE); |
333 | if (NULL == response) | 339 | if (NULL == response) |
334 | { | 340 | { |
335 | free (reply); | 341 | free (reply); |
@@ -337,11 +343,11 @@ fill_v1_form (const void *cls, | |||
337 | } | 343 | } |
338 | add_session_cookie (session, response); | 344 | add_session_cookie (session, response); |
339 | MHD_add_response_header (response, | 345 | MHD_add_response_header (response, |
340 | MHD_HTTP_HEADER_CONTENT_ENCODING, | 346 | MHD_HTTP_HEADER_CONTENT_ENCODING, |
341 | mime); | 347 | mime); |
342 | ret = MHD_queue_response (connection, | 348 | ret = MHD_queue_response (connection, |
343 | MHD_HTTP_OK, | 349 | MHD_HTTP_OK, |
344 | response); | 350 | response); |
345 | MHD_destroy_response (response); | 351 | MHD_destroy_response (response); |
346 | return ret; | 352 | return ret; |
347 | } | 353 | } |
@@ -357,29 +363,30 @@ fill_v1_form (const void *cls, | |||
357 | */ | 363 | */ |
358 | static int | 364 | static int |
359 | fill_v1_v2_form (const void *cls, | 365 | fill_v1_v2_form (const void *cls, |
360 | const char *mime, | 366 | const char *mime, |
361 | struct Session *session, | 367 | struct Session *session, |
362 | struct MHD_Connection *connection) | 368 | struct MHD_Connection *connection) |
363 | { | 369 | { |
364 | int ret; | 370 | int ret; |
365 | char *reply; | 371 | char *reply; |
366 | struct MHD_Response *response; | 372 | struct MHD_Response *response; |
367 | size_t slen; | 373 | size_t slen; |
368 | (void)cls; /* Unused. Silent compiler warning. */ | 374 | (void) cls; /* Unused. Silent compiler warning. */ |
369 | 375 | ||
370 | slen = strlen (SECOND_PAGE) + strlen (session->value_1) + strlen (session->value_2); | 376 | slen = strlen (SECOND_PAGE) + strlen (session->value_1) + strlen ( |
377 | session->value_2); | ||
371 | reply = malloc (slen + 1); | 378 | reply = malloc (slen + 1); |
372 | if (NULL == reply) | 379 | if (NULL == reply) |
373 | return MHD_NO; | 380 | return MHD_NO; |
374 | snprintf (reply, | 381 | snprintf (reply, |
375 | slen + 1, | 382 | slen + 1, |
376 | SECOND_PAGE, | 383 | SECOND_PAGE, |
377 | session->value_1, | 384 | session->value_1, |
378 | session->value_2); | 385 | session->value_2); |
379 | /* return static form */ | 386 | /* return static form */ |
380 | response = MHD_create_response_from_buffer (slen, | 387 | response = MHD_create_response_from_buffer (slen, |
381 | (void *) reply, | 388 | (void *) reply, |
382 | MHD_RESPMEM_MUST_FREE); | 389 | MHD_RESPMEM_MUST_FREE); |
383 | if (NULL == response) | 390 | if (NULL == response) |
384 | { | 391 | { |
385 | free (reply); | 392 | free (reply); |
@@ -387,11 +394,11 @@ fill_v1_v2_form (const void *cls, | |||
387 | } | 394 | } |
388 | add_session_cookie (session, response); | 395 | add_session_cookie (session, response); |
389 | MHD_add_response_header (response, | 396 | MHD_add_response_header (response, |
390 | MHD_HTTP_HEADER_CONTENT_ENCODING, | 397 | MHD_HTTP_HEADER_CONTENT_ENCODING, |
391 | mime); | 398 | mime); |
392 | ret = MHD_queue_response (connection, | 399 | ret = MHD_queue_response (connection, |
393 | MHD_HTTP_OK, | 400 | MHD_HTTP_OK, |
394 | response); | 401 | response); |
395 | MHD_destroy_response (response); | 402 | MHD_destroy_response (response); |
396 | return ret; | 403 | return ret; |
397 | } | 404 | } |
@@ -407,27 +414,27 @@ fill_v1_v2_form (const void *cls, | |||
407 | */ | 414 | */ |
408 | static int | 415 | static int |
409 | not_found_page (const void *cls, | 416 | not_found_page (const void *cls, |
410 | const char *mime, | 417 | const char *mime, |
411 | struct Session *session, | 418 | struct Session *session, |
412 | struct MHD_Connection *connection) | 419 | struct MHD_Connection *connection) |
413 | { | 420 | { |
414 | int ret; | 421 | int ret; |
415 | struct MHD_Response *response; | 422 | struct MHD_Response *response; |
416 | (void)cls; /* Unused. Silent compiler warning. */ | 423 | (void) cls; /* Unused. Silent compiler warning. */ |
417 | (void)session; /* Unused. Silent compiler warning. */ | 424 | (void) session; /* Unused. Silent compiler warning. */ |
418 | 425 | ||
419 | /* unsupported HTTP method */ | 426 | /* unsupported HTTP method */ |
420 | response = MHD_create_response_from_buffer (strlen (NOT_FOUND_ERROR), | 427 | response = MHD_create_response_from_buffer (strlen (NOT_FOUND_ERROR), |
421 | (void *) NOT_FOUND_ERROR, | 428 | (void *) NOT_FOUND_ERROR, |
422 | MHD_RESPMEM_PERSISTENT); | 429 | MHD_RESPMEM_PERSISTENT); |
423 | if (NULL == response) | 430 | if (NULL == response) |
424 | return MHD_NO; | 431 | return MHD_NO; |
425 | ret = MHD_queue_response (connection, | 432 | ret = MHD_queue_response (connection, |
426 | MHD_HTTP_NOT_FOUND, | 433 | MHD_HTTP_NOT_FOUND, |
427 | response); | 434 | response); |
428 | MHD_add_response_header (response, | 435 | MHD_add_response_header (response, |
429 | MHD_HTTP_HEADER_CONTENT_ENCODING, | 436 | MHD_HTTP_HEADER_CONTENT_ENCODING, |
430 | mime); | 437 | mime); |
431 | MHD_destroy_response (response); | 438 | MHD_destroy_response (response); |
432 | return ret; | 439 | return ret; |
433 | } | 440 | } |
@@ -436,14 +443,13 @@ not_found_page (const void *cls, | |||
436 | /** | 443 | /** |
437 | * List of all pages served by this HTTP server. | 444 | * List of all pages served by this HTTP server. |
438 | */ | 445 | */ |
439 | static struct Page pages[] = | 446 | static struct Page pages[] = { |
440 | { | 447 | { "/", "text/html", &fill_v1_form, NULL }, |
441 | { "/", "text/html", &fill_v1_form, NULL }, | 448 | { "/2", "text/html", &fill_v1_v2_form, NULL }, |
442 | { "/2", "text/html", &fill_v1_v2_form, NULL }, | 449 | { "/S", "text/html", &serve_simple_form, SUBMIT_PAGE }, |
443 | { "/S", "text/html", &serve_simple_form, SUBMIT_PAGE }, | 450 | { "/F", "text/html", &serve_simple_form, LAST_PAGE }, |
444 | { "/F", "text/html", &serve_simple_form, LAST_PAGE }, | 451 | { NULL, NULL, ¬_found_page, NULL } /* 404 */ |
445 | { NULL, NULL, ¬_found_page, NULL } /* 404 */ | 452 | }; |
446 | }; | ||
447 | 453 | ||
448 | 454 | ||
449 | 455 | ||
@@ -468,49 +474,49 @@ static struct Page pages[] = | |||
468 | */ | 474 | */ |
469 | static int | 475 | static int |
470 | post_iterator (void *cls, | 476 | post_iterator (void *cls, |
471 | enum MHD_ValueKind kind, | 477 | enum MHD_ValueKind kind, |
472 | const char *key, | 478 | const char *key, |
473 | const char *filename, | 479 | const char *filename, |
474 | const char *content_type, | 480 | const char *content_type, |
475 | const char *transfer_encoding, | 481 | const char *transfer_encoding, |
476 | const char *data, uint64_t off, size_t size) | 482 | const char *data, uint64_t off, size_t size) |
477 | { | 483 | { |
478 | struct Request *request = cls; | 484 | struct Request *request = cls; |
479 | struct Session *session = request->session; | 485 | struct Session *session = request->session; |
480 | (void)kind; /* Unused. Silent compiler warning. */ | 486 | (void) kind; /* Unused. Silent compiler warning. */ |
481 | (void)filename; /* Unused. Silent compiler warning. */ | 487 | (void) filename; /* Unused. Silent compiler warning. */ |
482 | (void)content_type; /* Unused. Silent compiler warning. */ | 488 | (void) content_type; /* Unused. Silent compiler warning. */ |
483 | (void)transfer_encoding; /* Unused. Silent compiler warning. */ | 489 | (void) transfer_encoding; /* Unused. Silent compiler warning. */ |
484 | 490 | ||
485 | if (0 == strcmp ("DONE", key)) | 491 | if (0 == strcmp ("DONE", key)) |
486 | { | 492 | { |
487 | fprintf (stdout, | 493 | fprintf (stdout, |
488 | "Session `%s' submitted `%s', `%s'\n", | 494 | "Session `%s' submitted `%s', `%s'\n", |
489 | session->sid, | 495 | session->sid, |
490 | session->value_1, | 496 | session->value_1, |
491 | session->value_2); | 497 | session->value_2); |
492 | return MHD_YES; | 498 | return MHD_YES; |
493 | } | 499 | } |
494 | if (0 == strcmp ("v1", key)) | 500 | if (0 == strcmp ("v1", key)) |
495 | { | 501 | { |
496 | if (size + off >= sizeof(session->value_1)) | 502 | if (size + off >= sizeof(session->value_1)) |
497 | size = sizeof (session->value_1) - off - 1; | 503 | size = sizeof (session->value_1) - off - 1; |
498 | memcpy (&session->value_1[off], | 504 | memcpy (&session->value_1[off], |
499 | data, | 505 | data, |
500 | size); | 506 | size); |
501 | session->value_1[size+off] = '\0'; | 507 | session->value_1[size + off] = '\0'; |
502 | return MHD_YES; | 508 | return MHD_YES; |
503 | } | 509 | } |
504 | if (0 == strcmp ("v2", key)) | 510 | if (0 == strcmp ("v2", key)) |
505 | { | 511 | { |
506 | if (size + off >= sizeof(session->value_2)) | 512 | if (size + off >= sizeof(session->value_2)) |
507 | size = sizeof (session->value_2) - off - 1; | 513 | size = sizeof (session->value_2) - off - 1; |
508 | memcpy (&session->value_2[off], | 514 | memcpy (&session->value_2[off], |
509 | data, | 515 | data, |
510 | size); | 516 | size); |
511 | session->value_2[size+off] = '\0'; | 517 | session->value_2[size + off] = '\0'; |
512 | return MHD_YES; | 518 | return MHD_YES; |
513 | } | 519 | } |
514 | fprintf (stderr, | 520 | fprintf (stderr, |
515 | "Unsupported form value `%s'\n", | 521 | "Unsupported form value `%s'\n", |
516 | key); | 522 | key); |
@@ -553,99 +559,99 @@ post_iterator (void *cls, | |||
553 | */ | 559 | */ |
554 | static int | 560 | static int |
555 | create_response (void *cls, | 561 | create_response (void *cls, |
556 | struct MHD_Connection *connection, | 562 | struct MHD_Connection *connection, |
557 | const char *url, | 563 | const char *url, |
558 | const char *method, | 564 | const char *method, |
559 | const char *version, | 565 | const char *version, |
560 | const char *upload_data, | 566 | const char *upload_data, |
561 | size_t *upload_data_size, | 567 | size_t *upload_data_size, |
562 | void **ptr) | 568 | void **ptr) |
563 | { | 569 | { |
564 | struct MHD_Response *response; | 570 | struct MHD_Response *response; |
565 | struct Request *request; | 571 | struct Request *request; |
566 | struct Session *session; | 572 | struct Session *session; |
567 | int ret; | 573 | int ret; |
568 | unsigned int i; | 574 | unsigned int i; |
569 | (void)cls; /* Unused. Silent compiler warning. */ | 575 | (void) cls; /* Unused. Silent compiler warning. */ |
570 | (void)version; /* Unused. Silent compiler warning. */ | 576 | (void) version; /* Unused. Silent compiler warning. */ |
571 | 577 | ||
572 | request = *ptr; | 578 | request = *ptr; |
573 | if (NULL == request) | 579 | if (NULL == request) |
580 | { | ||
581 | request = calloc (1, sizeof (struct Request)); | ||
582 | if (NULL == request) | ||
574 | { | 583 | { |
575 | request = calloc (1, sizeof (struct Request)); | 584 | fprintf (stderr, "calloc error: %s\n", strerror (errno)); |
576 | if (NULL == request) | 585 | return MHD_NO; |
577 | { | ||
578 | fprintf (stderr, "calloc error: %s\n", strerror (errno)); | ||
579 | return MHD_NO; | ||
580 | } | ||
581 | *ptr = request; | ||
582 | if (0 == strcmp (method, MHD_HTTP_METHOD_POST)) | ||
583 | { | ||
584 | request->pp = MHD_create_post_processor (connection, 1024, | ||
585 | &post_iterator, request); | ||
586 | if (NULL == request->pp) | ||
587 | { | ||
588 | fprintf (stderr, "Failed to setup post processor for `%s'\n", | ||
589 | url); | ||
590 | return MHD_NO; /* internal error */ | ||
591 | } | ||
592 | } | ||
593 | return MHD_YES; | ||
594 | } | 586 | } |
587 | *ptr = request; | ||
588 | if (0 == strcmp (method, MHD_HTTP_METHOD_POST)) | ||
589 | { | ||
590 | request->pp = MHD_create_post_processor (connection, 1024, | ||
591 | &post_iterator, request); | ||
592 | if (NULL == request->pp) | ||
593 | { | ||
594 | fprintf (stderr, "Failed to setup post processor for `%s'\n", | ||
595 | url); | ||
596 | return MHD_NO; /* internal error */ | ||
597 | } | ||
598 | } | ||
599 | return MHD_YES; | ||
600 | } | ||
595 | if (NULL == request->session) | 601 | if (NULL == request->session) |
602 | { | ||
603 | request->session = get_session (connection); | ||
604 | if (NULL == request->session) | ||
596 | { | 605 | { |
597 | request->session = get_session (connection); | 606 | fprintf (stderr, "Failed to setup session for `%s'\n", |
598 | if (NULL == request->session) | 607 | url); |
599 | { | 608 | return MHD_NO; /* internal error */ |
600 | fprintf (stderr, "Failed to setup session for `%s'\n", | ||
601 | url); | ||
602 | return MHD_NO; /* internal error */ | ||
603 | } | ||
604 | } | 609 | } |
610 | } | ||
605 | session = request->session; | 611 | session = request->session; |
606 | session->start = time (NULL); | 612 | session->start = time (NULL); |
607 | if (0 == strcmp (method, MHD_HTTP_METHOD_POST)) | 613 | if (0 == strcmp (method, MHD_HTTP_METHOD_POST)) |
614 | { | ||
615 | /* evaluate POST data */ | ||
616 | MHD_post_process (request->pp, | ||
617 | upload_data, | ||
618 | *upload_data_size); | ||
619 | if (0 != *upload_data_size) | ||
608 | { | 620 | { |
609 | /* evaluate POST data */ | 621 | *upload_data_size = 0; |
610 | MHD_post_process (request->pp, | 622 | return MHD_YES; |
611 | upload_data, | ||
612 | *upload_data_size); | ||
613 | if (0 != *upload_data_size) | ||
614 | { | ||
615 | *upload_data_size = 0; | ||
616 | return MHD_YES; | ||
617 | } | ||
618 | /* done with POST data, serve response */ | ||
619 | MHD_destroy_post_processor (request->pp); | ||
620 | request->pp = NULL; | ||
621 | method = MHD_HTTP_METHOD_GET; /* fake 'GET' */ | ||
622 | if (NULL != request->post_url) | ||
623 | url = request->post_url; | ||
624 | } | 623 | } |
624 | /* done with POST data, serve response */ | ||
625 | MHD_destroy_post_processor (request->pp); | ||
626 | request->pp = NULL; | ||
627 | method = MHD_HTTP_METHOD_GET; /* fake 'GET' */ | ||
628 | if (NULL != request->post_url) | ||
629 | url = request->post_url; | ||
630 | } | ||
625 | 631 | ||
626 | if ( (0 == strcmp (method, MHD_HTTP_METHOD_GET)) || | 632 | if ( (0 == strcmp (method, MHD_HTTP_METHOD_GET)) || |
627 | (0 == strcmp (method, MHD_HTTP_METHOD_HEAD)) ) | 633 | (0 == strcmp (method, MHD_HTTP_METHOD_HEAD)) ) |
628 | { | 634 | { |
629 | /* find out which page to serve */ | 635 | /* find out which page to serve */ |
630 | i=0; | 636 | i = 0; |
631 | while ( (pages[i].url != NULL) && | 637 | while ( (pages[i].url != NULL) && |
632 | (0 != strcmp (pages[i].url, url)) ) | 638 | (0 != strcmp (pages[i].url, url)) ) |
633 | i++; | 639 | i++; |
634 | ret = pages[i].handler (pages[i].handler_cls, | 640 | ret = pages[i].handler (pages[i].handler_cls, |
635 | pages[i].mime, | 641 | pages[i].mime, |
636 | session, connection); | 642 | session, connection); |
637 | if (ret != MHD_YES) | 643 | if (ret != MHD_YES) |
638 | fprintf (stderr, "Failed to create page for `%s'\n", | 644 | fprintf (stderr, "Failed to create page for `%s'\n", |
639 | url); | 645 | url); |
640 | return ret; | 646 | return ret; |
641 | } | 647 | } |
642 | /* unsupported HTTP method */ | 648 | /* unsupported HTTP method */ |
643 | response = MHD_create_response_from_buffer (strlen (METHOD_ERROR), | 649 | response = MHD_create_response_from_buffer (strlen (METHOD_ERROR), |
644 | (void *) METHOD_ERROR, | 650 | (void *) METHOD_ERROR, |
645 | MHD_RESPMEM_PERSISTENT); | 651 | MHD_RESPMEM_PERSISTENT); |
646 | ret = MHD_queue_response (connection, | 652 | ret = MHD_queue_response (connection, |
647 | MHD_HTTP_NOT_ACCEPTABLE, | 653 | MHD_HTTP_NOT_ACCEPTABLE, |
648 | response); | 654 | response); |
649 | MHD_destroy_response (response); | 655 | MHD_destroy_response (response); |
650 | return ret; | 656 | return ret; |
651 | } | 657 | } |
@@ -662,14 +668,14 @@ create_response (void *cls, | |||
662 | */ | 668 | */ |
663 | static void | 669 | static void |
664 | request_completed_callback (void *cls, | 670 | request_completed_callback (void *cls, |
665 | struct MHD_Connection *connection, | 671 | struct MHD_Connection *connection, |
666 | void **con_cls, | 672 | void **con_cls, |
667 | enum MHD_RequestTerminationCode toe) | 673 | enum MHD_RequestTerminationCode toe) |
668 | { | 674 | { |
669 | struct Request *request = *con_cls; | 675 | struct Request *request = *con_cls; |
670 | (void)cls; /* Unused. Silent compiler warning. */ | 676 | (void) cls; /* Unused. Silent compiler warning. */ |
671 | (void)connection; /* Unused. Silent compiler warning. */ | 677 | (void) connection; /* Unused. Silent compiler warning. */ |
672 | (void)toe; /* Unused. Silent compiler warning. */ | 678 | (void) toe; /* Unused. Silent compiler warning. */ |
673 | 679 | ||
674 | if (NULL == request) | 680 | if (NULL == request) |
675 | return; | 681 | return; |
@@ -697,21 +703,21 @@ expire_sessions () | |||
697 | prev = NULL; | 703 | prev = NULL; |
698 | pos = sessions; | 704 | pos = sessions; |
699 | while (NULL != pos) | 705 | while (NULL != pos) |
706 | { | ||
707 | next = pos->next; | ||
708 | if (now - pos->start > 60 * 60) | ||
700 | { | 709 | { |
701 | next = pos->next; | 710 | /* expire sessions after 1h */ |
702 | if (now - pos->start > 60 * 60) | 711 | if (NULL == prev) |
703 | { | 712 | sessions = pos->next; |
704 | /* expire sessions after 1h */ | ||
705 | if (NULL == prev) | ||
706 | sessions = pos->next; | ||
707 | else | ||
708 | prev->next = next; | ||
709 | free (pos); | ||
710 | } | ||
711 | else | 713 | else |
712 | prev = pos; | 714 | prev->next = next; |
713 | pos = next; | 715 | free (pos); |
714 | } | 716 | } |
717 | else | ||
718 | prev = pos; | ||
719 | pos = next; | ||
720 | } | ||
715 | } | 721 | } |
716 | 722 | ||
717 | 723 | ||
@@ -732,45 +738,46 @@ main (int argc, char *const *argv) | |||
732 | MHD_UNSIGNED_LONG_LONG mhd_timeout; | 738 | MHD_UNSIGNED_LONG_LONG mhd_timeout; |
733 | 739 | ||
734 | if (argc != 2) | 740 | if (argc != 2) |
735 | { | 741 | { |
736 | printf ("%s PORT\n", argv[0]); | 742 | printf ("%s PORT\n", argv[0]); |
737 | return 1; | 743 | return 1; |
738 | } | 744 | } |
739 | /* initialize PRNG */ | 745 | /* initialize PRNG */ |
740 | srand ((unsigned int) time (NULL)); | 746 | srand ((unsigned int) time (NULL)); |
741 | d = MHD_start_daemon (MHD_USE_ERROR_LOG, | 747 | d = MHD_start_daemon (MHD_USE_ERROR_LOG, |
742 | atoi (argv[1]), | 748 | atoi (argv[1]), |
743 | NULL, NULL, | 749 | NULL, NULL, |
744 | &create_response, NULL, | 750 | &create_response, NULL, |
745 | MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 15, | 751 | MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 15, |
746 | MHD_OPTION_NOTIFY_COMPLETED, &request_completed_callback, NULL, | 752 | MHD_OPTION_NOTIFY_COMPLETED, |
747 | MHD_OPTION_END); | 753 | &request_completed_callback, NULL, |
754 | MHD_OPTION_END); | ||
748 | if (NULL == d) | 755 | if (NULL == d) |
749 | return 1; | 756 | return 1; |
750 | while (1) | 757 | while (1) |
758 | { | ||
759 | expire_sessions (); | ||
760 | max = 0; | ||
761 | FD_ZERO (&rs); | ||
762 | FD_ZERO (&ws); | ||
763 | FD_ZERO (&es); | ||
764 | if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max)) | ||
765 | break; /* fatal internal error */ | ||
766 | if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES) | ||
751 | { | 767 | { |
752 | expire_sessions (); | 768 | tv.tv_sec = mhd_timeout / 1000; |
753 | max = 0; | 769 | tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000; |
754 | FD_ZERO (&rs); | 770 | tvp = &tv; |
755 | FD_ZERO (&ws); | ||
756 | FD_ZERO (&es); | ||
757 | if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max)) | ||
758 | break; /* fatal internal error */ | ||
759 | if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES) | ||
760 | { | ||
761 | tv.tv_sec = mhd_timeout / 1000; | ||
762 | tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000; | ||
763 | tvp = &tv; | ||
764 | } | ||
765 | else | ||
766 | tvp = NULL; | ||
767 | if (-1 == select (max + 1, &rs, &ws, &es, tvp)) | ||
768 | { | ||
769 | if (EINTR != errno) | ||
770 | abort (); | ||
771 | } | ||
772 | MHD_run (d); | ||
773 | } | 771 | } |
772 | else | ||
773 | tvp = NULL; | ||
774 | if (-1 == select (max + 1, &rs, &ws, &es, tvp)) | ||
775 | { | ||
776 | if (EINTR != errno) | ||
777 | abort (); | ||
778 | } | ||
779 | MHD_run (d); | ||
780 | } | ||
774 | MHD_stop_daemon (d); | 781 | MHD_stop_daemon (d); |
775 | return 0; | 782 | return 0; |
776 | } | 783 | } |