diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2023-05-19 13:07:09 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2023-06-01 10:58:16 +0300 |
commit | feb9ac1f4cd0fe0d83f6f5ef18c25f059674905a (patch) | |
tree | 35db4983e4d7c3820a540ef109d7b1fdf18b03d1 | |
parent | 3002ca583e2770146bdd5d75602b6a36c8b2a777 (diff) | |
download | libmicrohttpd-feb9ac1f4cd0fe0d83f6f5ef18c25f059674905a.tar.gz libmicrohttpd-feb9ac1f4cd0fe0d83f6f5ef18c25f059674905a.zip |
examples/sessions.c: removed non-portable function and improved safety
-rw-r--r-- | doc/examples/sessions.c | 150 |
1 files changed, 69 insertions, 81 deletions
diff --git a/doc/examples/sessions.c b/doc/examples/sessions.c index de864382..3f60c291 100644 --- a/doc/examples/sessions.c +++ b/doc/examples/sessions.c | |||
@@ -6,61 +6,8 @@ | |||
6 | #include <stdio.h> | 6 | #include <stdio.h> |
7 | #include <errno.h> | 7 | #include <errno.h> |
8 | #include <time.h> | 8 | #include <time.h> |
9 | #include <stdarg.h> | ||
10 | #include <microhttpd.h> | 9 | #include <microhttpd.h> |
11 | 10 | ||
12 | /* Emulate 'asprintf()', as it is not portable */ | ||
13 | static int | ||
14 | MHD_asprintf (char **resultp, const char *format, ...) | ||
15 | { | ||
16 | va_list argptr; | ||
17 | va_list argcopy; | ||
18 | int len; | ||
19 | int ret; | ||
20 | |||
21 | ret = -1; | ||
22 | va_start (argptr, format); | ||
23 | |||
24 | va_copy (argcopy, argptr); | ||
25 | #ifndef _WIN32 | ||
26 | len = vsnprintf (NULL, 0, format, argcopy); | ||
27 | #else | ||
28 | len = _vscprintf (format, argcopy); | ||
29 | #endif | ||
30 | va_end (argcopy); | ||
31 | if (0 < len) | ||
32 | { | ||
33 | size_t buf_size; | ||
34 | char *buf; | ||
35 | |||
36 | buf_size = (size_t) len + 1; | ||
37 | buf = (char *) malloc (buf_size * sizeof(char)); | ||
38 | if (NULL != buf) | ||
39 | { | ||
40 | int res; | ||
41 | |||
42 | #ifndef _WIN32 | ||
43 | res = vsnprintf (buf, buf_size, format, argptr); | ||
44 | #else | ||
45 | res = _vsnprintf (buf, buf_size, format, argptr); | ||
46 | #endif | ||
47 | if (len == res) | ||
48 | { | ||
49 | *resultp = buf; | ||
50 | ret = res; | ||
51 | } | ||
52 | else | ||
53 | { | ||
54 | free (buf); | ||
55 | *resultp = NULL; | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | va_end (argptr); | ||
60 | return ret; | ||
61 | } | ||
62 | |||
63 | |||
64 | /** | 11 | /** |
65 | * Invalid method page. | 12 | * Invalid method page. |
66 | */ | 13 | */ |
@@ -79,12 +26,16 @@ MHD_asprintf (char **resultp, const char *format, ...) | |||
79 | #define MAIN_PAGE \ | 26 | #define MAIN_PAGE \ |
80 | "<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>" | 27 | "<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>" |
81 | 28 | ||
29 | #define FORM_V1 MAIN_PAGE | ||
30 | |||
82 | /** | 31 | /** |
83 | * Second page. (/2) | 32 | * Second page. (/2) |
84 | */ | 33 | */ |
85 | #define SECOND_PAGE \ | 34 | #define SECOND_PAGE \ |
86 | "<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>" | 35 | "<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>" |
87 | 36 | ||
37 | #define FORM_V1_V2 SECOND_PAGE | ||
38 | |||
88 | /** | 39 | /** |
89 | * Second page (/S) | 40 | * Second page (/S) |
90 | */ | 41 | */ |
@@ -350,27 +301,45 @@ fill_v1_form (const void *cls, | |||
350 | int reply_len; | 301 | int reply_len; |
351 | (void) cls; /* Unused */ | 302 | (void) cls; /* Unused */ |
352 | 303 | ||
353 | reply_len = MHD_asprintf (&reply, | 304 | /* Emulate 'asprintf' */ |
354 | MAIN_PAGE, | 305 | reply_len = snprintf (NULL, 0, FORM_V1, session->value_1); |
355 | session->value_1); | ||
356 | if (0 > reply_len) | 306 | if (0 > reply_len) |
307 | return MHD_NO; /* Internal error */ | ||
308 | |||
309 | reply = (char *) malloc (reply_len + 1); | ||
310 | if (NULL == reply) | ||
311 | return MHD_NO; /* Out-of-memory error */ | ||
312 | |||
313 | if (reply_len != snprintf (reply, | ||
314 | ((size_t) reply_len) + 1, | ||
315 | FORM_V1, | ||
316 | session->value_1)) | ||
357 | { | 317 | { |
358 | /* oops */ | 318 | free (reply); |
359 | return MHD_NO; | 319 | return MHD_NO; /* printf error */ |
360 | } | 320 | } |
321 | |||
361 | /* return static form */ | 322 | /* return static form */ |
362 | response = | 323 | response = |
363 | MHD_create_response_from_buffer_with_free_callback ((size_t) reply_len, | 324 | MHD_create_response_from_buffer_with_free_callback ((size_t) reply_len, |
364 | (void *) reply, | 325 | (void *) reply, |
365 | &free); | 326 | &free); |
366 | add_session_cookie (session, response); | 327 | if (NULL != response) |
367 | MHD_add_response_header (response, | 328 | { |
368 | MHD_HTTP_HEADER_CONTENT_ENCODING, | 329 | add_session_cookie (session, response); |
369 | mime); | 330 | MHD_add_response_header (response, |
370 | ret = MHD_queue_response (connection, | 331 | MHD_HTTP_HEADER_CONTENT_ENCODING, |
371 | MHD_HTTP_OK, | 332 | mime); |
372 | response); | 333 | ret = MHD_queue_response (connection, |
373 | MHD_destroy_response (response); | 334 | MHD_HTTP_OK, |
335 | response); | ||
336 | MHD_destroy_response (response); | ||
337 | } | ||
338 | else | ||
339 | { | ||
340 | free (reply); | ||
341 | ret = MHD_NO; | ||
342 | } | ||
374 | return ret; | 343 | return ret; |
375 | } | 344 | } |
376 | 345 | ||
@@ -395,28 +364,47 @@ fill_v1_v2_form (const void *cls, | |||
395 | int reply_len; | 364 | int reply_len; |
396 | (void) cls; /* Unused */ | 365 | (void) cls; /* Unused */ |
397 | 366 | ||
398 | reply_len = MHD_asprintf (&reply, | 367 | /* Emulate 'asprintf' */ |
399 | SECOND_PAGE, | 368 | reply_len = snprintf (NULL, 0, FORM_V1_V2, session->value_1, |
400 | session->value_1, | 369 | session->value_2); |
401 | session->value_2); | ||
402 | if (0 > reply_len) | 370 | if (0 > reply_len) |
371 | return MHD_NO; /* Internal error */ | ||
372 | |||
373 | reply = (char *) malloc (reply_len + 1); | ||
374 | if (NULL == reply) | ||
375 | return MHD_NO; /* Out-of-memory error */ | ||
376 | |||
377 | if (reply_len == snprintf (reply, | ||
378 | ((size_t) reply_len) + 1, | ||
379 | FORM_V1_V2, | ||
380 | session->value_1, | ||
381 | session->value_2)) | ||
403 | { | 382 | { |
404 | /* oops */ | 383 | free (reply); |
405 | return MHD_NO; | 384 | return MHD_NO; /* printf error */ |
406 | } | 385 | } |
386 | |||
407 | /* return static form */ | 387 | /* return static form */ |
408 | response = | 388 | response = |
409 | MHD_create_response_from_buffer_with_free_callback ((size_t) reply_len, | 389 | MHD_create_response_from_buffer_with_free_callback ((size_t) reply_len, |
410 | (void *) reply, | 390 | (void *) reply, |
411 | &free); | 391 | &free); |
412 | add_session_cookie (session, response); | 392 | if (NULL != response) |
413 | MHD_add_response_header (response, | 393 | { |
414 | MHD_HTTP_HEADER_CONTENT_ENCODING, | 394 | add_session_cookie (session, response); |
415 | mime); | 395 | MHD_add_response_header (response, |
416 | ret = MHD_queue_response (connection, | 396 | MHD_HTTP_HEADER_CONTENT_ENCODING, |
417 | MHD_HTTP_OK, | 397 | mime); |
418 | response); | 398 | ret = MHD_queue_response (connection, |
419 | MHD_destroy_response (response); | 399 | MHD_HTTP_OK, |
400 | response); | ||
401 | MHD_destroy_response (response); | ||
402 | } | ||
403 | else | ||
404 | { | ||
405 | free (reply); | ||
406 | ret = MHD_NO; | ||
407 | } | ||
420 | return ret; | 408 | return ret; |
421 | } | 409 | } |
422 | 410 | ||
@@ -457,7 +445,7 @@ not_found_page (const void *cls, | |||
457 | /** | 445 | /** |
458 | * List of all pages served by this HTTP server. | 446 | * List of all pages served by this HTTP server. |
459 | */ | 447 | */ |
460 | static struct Page pages[] = { | 448 | static const struct Page pages[] = { |
461 | { "/", "text/html", &fill_v1_form, NULL }, | 449 | { "/", "text/html", &fill_v1_form, NULL }, |
462 | { "/2", "text/html", &fill_v1_v2_form, NULL }, | 450 | { "/2", "text/html", &fill_v1_v2_form, NULL }, |
463 | { "/S", "text/html", &serve_simple_form, SUBMIT_PAGE }, | 451 | { "/S", "text/html", &serve_simple_form, SUBMIT_PAGE }, |