PageRenderTime 55ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/src/testcurl/test_parse_cookies.c

https://gitlab.com/karlson2k/libmicrohttpd-old
C | 260 lines | 212 code | 18 blank | 30 comment | 62 complexity | 257e368bb92994d02adea06b05cce447 MD5 | raw file
  1. /*
  2. This file is part of libmicrohttpd
  3. Copyright (C) 2007 Christian Grothoff
  4. libmicrohttpd is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. libmicrohttpd is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with libmicrohttpd; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  15. Boston, MA 02110-1301, USA.
  16. */
  17. /**
  18. * @file test_parse_cookies.c
  19. * @brief Testcase for HTTP cookie parsing
  20. * @author Christian Grothoff
  21. */
  22. #include "MHD_config.h"
  23. #include "platform.h"
  24. #include <curl/curl.h>
  25. #include <microhttpd.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <time.h>
  29. #ifndef WINDOWS
  30. #include <unistd.h>
  31. #endif
  32. static int oneone;
  33. struct CBC
  34. {
  35. char *buf;
  36. size_t pos;
  37. size_t size;
  38. };
  39. static size_t
  40. copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
  41. {
  42. struct CBC *cbc = ctx;
  43. if (cbc->pos + size * nmemb > cbc->size)
  44. return 0; /* overflow */
  45. memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
  46. cbc->pos += size * nmemb;
  47. return size * nmemb;
  48. }
  49. static int
  50. ahc_echo (void *cls,
  51. struct MHD_Connection *connection,
  52. const char *url,
  53. const char *method,
  54. const char *version,
  55. const char *upload_data, size_t *upload_data_size,
  56. void **unused)
  57. {
  58. static int ptr;
  59. const char *me = cls;
  60. struct MHD_Response *response;
  61. int ret;
  62. const char *hdr;
  63. if (0 != strcmp (me, method))
  64. return MHD_NO; /* unexpected method */
  65. if (&ptr != *unused)
  66. {
  67. *unused = &ptr;
  68. return MHD_YES;
  69. }
  70. *unused = NULL;
  71. ret = 0;
  72. hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name1");
  73. if ((hdr == NULL) || (0 != strcmp (hdr, "var1")))
  74. abort ();
  75. hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name2");
  76. if ((hdr == NULL) || (0 != strcmp (hdr, "var2")))
  77. abort ();
  78. hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name3");
  79. if ((hdr == NULL) || (0 != strcmp (hdr, "")))
  80. abort ();
  81. hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name4");
  82. if ((hdr == NULL) || (0 != strcmp (hdr, "var4 with spaces")))
  83. abort ();
  84. response = MHD_create_response_from_buffer (strlen (url),
  85. (void *) url,
  86. MHD_RESPMEM_PERSISTENT);
  87. ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
  88. MHD_destroy_response (response);
  89. if (ret == MHD_NO)
  90. abort ();
  91. return ret;
  92. }
  93. static int
  94. testExternalGet ()
  95. {
  96. struct MHD_Daemon *d;
  97. CURL *c;
  98. char buf[2048];
  99. struct CBC cbc;
  100. CURLM *multi;
  101. CURLMcode mret;
  102. fd_set rs;
  103. fd_set ws;
  104. fd_set es;
  105. MHD_socket maxsock;
  106. #ifdef MHD_WINSOCK_SOCKETS
  107. int maxposixs; /* Max socket number unused on W32 */
  108. #else /* MHD_POSIX_SOCKETS */
  109. #define maxposixs maxsock
  110. #endif /* MHD_POSIX_SOCKETS */
  111. int running;
  112. struct CURLMsg *msg;
  113. time_t start;
  114. struct timeval tv;
  115. multi = NULL;
  116. cbc.buf = buf;
  117. cbc.size = 2048;
  118. cbc.pos = 0;
  119. d = MHD_start_daemon (MHD_USE_DEBUG,
  120. 21080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
  121. if (d == NULL)
  122. return 256;
  123. c = curl_easy_init ();
  124. curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:21080/hello_world");
  125. curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  126. curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  127. curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  128. /* note that the string below intentionally uses the
  129. various ways cookies can be specified to exercise the
  130. parser! Do not change! */
  131. curl_easy_setopt (c, CURLOPT_COOKIE,
  132. "name1=var1; name2=var2,name3 ;name4=\"var4 with spaces\";");
  133. if (oneone)
  134. curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  135. else
  136. curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
  137. curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  138. curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
  139. /* NOTE: use of CONNECTTIMEOUT without also
  140. setting NOSIGNAL results in really weird
  141. crashes on my system! */
  142. curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
  143. multi = curl_multi_init ();
  144. if (multi == NULL)
  145. {
  146. curl_easy_cleanup (c);
  147. MHD_stop_daemon (d);
  148. return 512;
  149. }
  150. mret = curl_multi_add_handle (multi, c);
  151. if (mret != CURLM_OK)
  152. {
  153. curl_multi_cleanup (multi);
  154. curl_easy_cleanup (c);
  155. MHD_stop_daemon (d);
  156. return 1024;
  157. }
  158. start = time (NULL);
  159. while ((time (NULL) - start < 5) && (multi != NULL))
  160. {
  161. maxsock = MHD_INVALID_SOCKET;
  162. maxposixs = -1;
  163. FD_ZERO (&rs);
  164. FD_ZERO (&ws);
  165. FD_ZERO (&es);
  166. curl_multi_perform (multi, &running);
  167. mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
  168. if (mret != CURLM_OK)
  169. {
  170. curl_multi_remove_handle (multi, c);
  171. curl_multi_cleanup (multi);
  172. curl_easy_cleanup (c);
  173. MHD_stop_daemon (d);
  174. return 2048;
  175. }
  176. if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
  177. {
  178. curl_multi_remove_handle (multi, c);
  179. curl_multi_cleanup (multi);
  180. curl_easy_cleanup (c);
  181. MHD_stop_daemon (d);
  182. return 4096;
  183. }
  184. tv.tv_sec = 0;
  185. tv.tv_usec = 1000;
  186. if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
  187. {
  188. if (EINTR != errno)
  189. abort ();
  190. }
  191. curl_multi_perform (multi, &running);
  192. if (running == 0)
  193. {
  194. msg = curl_multi_info_read (multi, &running);
  195. if (msg == NULL)
  196. break;
  197. if (msg->msg == CURLMSG_DONE)
  198. {
  199. if (msg->data.result != CURLE_OK)
  200. printf ("%s failed at %s:%d: `%s'\n",
  201. "curl_multi_perform",
  202. __FILE__,
  203. __LINE__, curl_easy_strerror (msg->data.result));
  204. curl_multi_remove_handle (multi, c);
  205. curl_multi_cleanup (multi);
  206. curl_easy_cleanup (c);
  207. c = NULL;
  208. multi = NULL;
  209. }
  210. }
  211. MHD_run (d);
  212. }
  213. if (multi != NULL)
  214. {
  215. curl_multi_remove_handle (multi, c);
  216. curl_easy_cleanup (c);
  217. curl_multi_cleanup (multi);
  218. }
  219. MHD_stop_daemon (d);
  220. if (cbc.pos != strlen ("/hello_world"))
  221. return 8192;
  222. if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
  223. return 16384;
  224. return 0;
  225. }
  226. int
  227. main (int argc, char *const *argv)
  228. {
  229. unsigned int errorCount = 0;
  230. oneone = (NULL != strrchr (argv[0], (int) '/')) ?
  231. (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
  232. if (0 != curl_global_init (CURL_GLOBAL_WIN32))
  233. return 2;
  234. errorCount += testExternalGet ();
  235. if (errorCount != 0)
  236. fprintf (stderr, "Error (code: %u)\n", errorCount);
  237. curl_global_cleanup ();
  238. return errorCount != 0; /* 0 == pass */
  239. }