test_httpreq.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /* _
  2. * ___ __ _ __ _ _ _(_)
  3. * / __|/ _` |/ _` | | | | |
  4. * \__ \ (_| | (_| | |_| | |
  5. * |___/\__,_|\__, |\__,_|_|
  6. * |___/
  7. *
  8. * Cross-platform library which helps to develop web servers or frameworks.
  9. *
  10. * Copyright (C) 2016-2020 Silvio Clecio <[email protected]>
  11. *
  12. * Sagui library is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU Lesser General Public
  14. * License as published by the Free Software Foundation; either
  15. * version 2.1 of the License, or (at your option) any later version.
  16. *
  17. * Sagui library is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20. * Lesser General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Lesser General Public
  23. * License along with Sagui library; if not, write to the Free Software
  24. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  25. */
  26. #include "sg_assert.h"
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include "sg_httpreq.h"
  30. #include <sagui.h>
  31. static void test__httpreq_new(struct sg_httpsrv *srv) {
  32. struct MHD_Connection *con = sg_alloc(64);
  33. struct sg_httpreq *req = sg__httpreq_new(srv, con, "abc", "def", "ghi");
  34. ASSERT(req);
  35. ASSERT(req->srv == srv);
  36. ASSERT(strcmp(req->version, "abc") == 0);
  37. ASSERT(strcmp(req->method, "def") == 0);
  38. ASSERT(strcmp(req->path, "ghi") == 0);
  39. sg_free(con);
  40. sg__httpreq_free(req);
  41. }
  42. static void test__httpreq_free(void) {
  43. sg__httpreq_free(NULL);
  44. }
  45. static void dummy_httpreq_cb(void *cls, struct sg_httpreq *req,
  46. struct sg_httpres *res) {
  47. (void) cls;
  48. (void) req;
  49. (void) res;
  50. }
  51. static void test_httpreq_srv(struct sg_httpreq *req) {
  52. struct sg_httpsrv *srv;
  53. errno = 0;
  54. ASSERT(!sg_httpreq_srv(NULL));
  55. ASSERT(errno == EINVAL);
  56. ASSERT(sg_httpreq_srv(req));
  57. errno = 0;
  58. req->srv = NULL;
  59. ASSERT(!sg_httpreq_srv(req));
  60. ASSERT(errno == 0);
  61. srv = sg_httpsrv_new(dummy_httpreq_cb, NULL);
  62. req->srv = srv;
  63. ASSERT(sg_httpreq_srv(req) == srv);
  64. sg_httpsrv_free(srv);
  65. ASSERT(errno == 0);
  66. }
  67. static void test_httpreq_headers(struct sg_httpreq *req) {
  68. struct sg_strmap **headers;
  69. errno = 0;
  70. ASSERT(!sg_httpreq_headers(NULL));
  71. ASSERT(errno == EINVAL);
  72. errno = 0;
  73. req->headers = NULL;
  74. ASSERT(sg_httpreq_headers(req));
  75. ASSERT(errno == 0);
  76. headers = sg_httpreq_headers(req);
  77. ASSERT(headers);
  78. ASSERT(sg_strmap_count(*headers) == 0);
  79. sg_strmap_add(&req->headers, "foo", "bar");
  80. sg_strmap_add(&req->headers, "abc", "123");
  81. ASSERT(sg_strmap_count(*headers) == 2);
  82. ASSERT(strcmp(sg_strmap_get(*headers, "foo"), "bar") == 0);
  83. ASSERT(strcmp(sg_strmap_get(*headers, "abc"), "123") == 0);
  84. }
  85. static void test_httpreq_cookies(struct sg_httpreq *req) {
  86. struct sg_strmap **cookies;
  87. errno = 0;
  88. ASSERT(!sg_httpreq_cookies(NULL));
  89. ASSERT(errno == EINVAL);
  90. errno = 0;
  91. req->cookies = NULL;
  92. ASSERT(sg_httpreq_cookies(req));
  93. ASSERT(errno == 0);
  94. cookies = sg_httpreq_cookies(req);
  95. ASSERT(cookies);
  96. ASSERT(sg_strmap_count(*cookies) == 0);
  97. sg_strmap_add(&req->cookies, "foo", "bar");
  98. sg_strmap_add(&req->cookies, "abc", "123");
  99. ASSERT(sg_strmap_count(*cookies) == 2);
  100. ASSERT(strcmp(sg_strmap_get(*cookies, "foo"), "bar") == 0);
  101. ASSERT(strcmp(sg_strmap_get(*cookies, "abc"), "123") == 0);
  102. }
  103. static void test_httpreq_params(struct sg_httpreq *req) {
  104. struct sg_strmap **params;
  105. errno = 0;
  106. ASSERT(!sg_httpreq_params(NULL));
  107. ASSERT(errno == EINVAL);
  108. errno = 0;
  109. req->params = NULL;
  110. ASSERT(sg_httpreq_params(req));
  111. ASSERT(errno == 0);
  112. params = sg_httpreq_params(req);
  113. ASSERT(params);
  114. ASSERT(sg_strmap_count(*params) == 0);
  115. sg_strmap_add(&req->params, "foo", "bar");
  116. sg_strmap_add(&req->params, "abc", "123");
  117. ASSERT(sg_strmap_count(*params) == 2);
  118. ASSERT(strcmp(sg_strmap_get(*params, "foo"), "bar") == 0);
  119. ASSERT(strcmp(sg_strmap_get(*params, "abc"), "123") == 0);
  120. }
  121. static void test_httpreq_fields(struct sg_httpreq *req) {
  122. struct sg_strmap **fields;
  123. errno = 0;
  124. ASSERT(!sg_httpreq_fields(NULL));
  125. ASSERT(errno == EINVAL);
  126. errno = 0;
  127. req->fields = NULL;
  128. ASSERT(sg_httpreq_fields(req));
  129. ASSERT(errno == 0);
  130. fields = sg_httpreq_fields(req);
  131. ASSERT(fields);
  132. ASSERT(sg_strmap_count(*fields) == 0);
  133. sg_strmap_add(&req->fields, "foo", "bar");
  134. sg_strmap_add(&req->fields, "abc", "123");
  135. ASSERT(sg_strmap_count(*fields) == 2);
  136. ASSERT(strcmp(sg_strmap_get(*fields, "foo"), "bar") == 0);
  137. ASSERT(strcmp(sg_strmap_get(*fields, "abc"), "123") == 0);
  138. }
  139. static void test_httpreq_version(struct sg_httpreq *req) {
  140. errno = 0;
  141. ASSERT(!sg_httpreq_version(NULL));
  142. ASSERT(errno == EINVAL);
  143. errno = 0;
  144. req->version = NULL;
  145. ASSERT(!sg_httpreq_version(req));
  146. ASSERT(errno == 0);
  147. req->version = "1.0";
  148. ASSERT(strcmp(sg_httpreq_version(req), "1.0") == 0);
  149. req->version = "1.1";
  150. ASSERT(strcmp(sg_httpreq_version(req), "1.1") == 0);
  151. }
  152. static void test_httpreq_method(struct sg_httpreq *req) {
  153. errno = 0;
  154. ASSERT(!sg_httpreq_method(NULL));
  155. ASSERT(errno == EINVAL);
  156. errno = 0;
  157. req->method = NULL;
  158. ASSERT(!sg_httpreq_method(req));
  159. ASSERT(errno == 0);
  160. req->method = "GET";
  161. ASSERT(strcmp(sg_httpreq_method(req), "GET") == 0);
  162. req->method = "POST";
  163. ASSERT(strcmp(sg_httpreq_method(req), "POST") == 0);
  164. }
  165. static void test_httpreq_path(struct sg_httpreq *req) {
  166. errno = 0;
  167. ASSERT(!sg_httpreq_path(NULL));
  168. ASSERT(errno == EINVAL);
  169. errno = 0;
  170. req->path = NULL;
  171. ASSERT(!sg_httpreq_path(req));
  172. ASSERT(errno == 0);
  173. req->path = "/foo";
  174. ASSERT(strcmp(sg_httpreq_path(req), "/foo") == 0);
  175. req->path = "/bar";
  176. ASSERT(strcmp(sg_httpreq_path(req), "/bar") == 0);
  177. }
  178. static void test_httpreq_payload(struct sg_httpreq *req) {
  179. struct sg_str *old_payload;
  180. errno = 0;
  181. ASSERT(!sg_httpreq_payload(NULL));
  182. ASSERT(errno == EINVAL);
  183. errno = 0;
  184. old_payload = req->payload;
  185. req->payload = NULL;
  186. ASSERT(!sg_httpreq_payload(req));
  187. req->payload = old_payload;
  188. ASSERT(errno == 0);
  189. ASSERT(sg_str_length(sg_httpreq_payload(req)) == 0);
  190. sg_str_printf(sg_httpreq_payload(req), "%s", "abc");
  191. ASSERT(strcmp(sg_str_content(sg_httpreq_payload(req)), "abc") == 0);
  192. sg_str_printf(sg_httpreq_payload(req), "%d", 123);
  193. ASSERT(strcmp(sg_str_content(sg_httpreq_payload(req)), "abc123") == 0);
  194. }
  195. static void test_httpreq_is_uploading(struct sg_httpreq *req) {
  196. errno = 0;
  197. ASSERT(!sg_httpreq_is_uploading(NULL));
  198. ASSERT(errno == EINVAL);
  199. errno = 0;
  200. req->is_uploading = false;
  201. ASSERT(!sg_httpreq_is_uploading(req));
  202. ASSERT(errno == 0);
  203. req->is_uploading = true;
  204. ASSERT(sg_httpreq_is_uploading(req));
  205. ASSERT(errno == 0);
  206. }
  207. static void test_httpreq_uploads(struct sg_httpreq *req) {
  208. struct sg_httpupld *tmp;
  209. errno = 0;
  210. ASSERT(!sg_httpreq_uploads(NULL));
  211. ASSERT(errno == EINVAL);
  212. errno = 0;
  213. req->uplds = NULL;
  214. ASSERT(!sg_httpreq_uploads(req));
  215. ASSERT(errno == 0);
  216. req->curr_upld = sg_alloc(sizeof(struct sg_httpupld));
  217. LL_APPEND(req->uplds, req->curr_upld);
  218. req->curr_upld->name = "foo";
  219. ASSERT(strcmp(sg_httpupld_name(req->curr_upld), "foo") == 0);
  220. req->curr_upld = sg_alloc(sizeof(struct sg_httpupld));
  221. LL_APPEND(req->uplds, req->curr_upld);
  222. req->curr_upld->name = "bar";
  223. ASSERT(strcmp(sg_httpupld_name(req->curr_upld), "bar") == 0);
  224. LL_FOREACH_SAFE(req->uplds, req->curr_upld, tmp) {
  225. LL_DELETE(req->uplds, req->curr_upld);
  226. sg_free(req->curr_upld);
  227. }
  228. }
  229. static void test_httpreq_client(void) {
  230. errno = 0;
  231. ASSERT(!sg_httpreq_client(NULL));
  232. ASSERT(errno == EINVAL);
  233. /* more tests in `test_httpsrv_tls_curl.c`. */
  234. }
  235. #ifdef SG_HTTPS_SUPPORT
  236. static void test_httpreq_tls_session(void) {
  237. errno = 0;
  238. ASSERT(!sg_httpreq_tls_session(NULL));
  239. ASSERT(errno == EINVAL);
  240. /* more tests in `test_httpsrv_tls_curl.c`. */
  241. }
  242. #endif /* SG_HTTPS_SUPPORT */
  243. static void test_httpreq_isolate(struct sg_httpreq *req) {
  244. ASSERT(sg_httpreq_isolate(NULL, dummy_httpreq_cb, NULL) == EINVAL);
  245. ASSERT(sg_httpreq_isolate(req, NULL, NULL) == EINVAL);
  246. /* more tests in `test_httpsrv_curl.c`. */
  247. }
  248. static void test_httpreq_set_user_data(struct sg_httpreq *req) {
  249. const char *dummy = "foo";
  250. ASSERT(sg_httpreq_set_user_data(NULL, (void *) dummy) == EINVAL);
  251. ASSERT(sg_httpreq_set_user_data(req, (void *) dummy) == 0);
  252. ASSERT(strcmp(sg_httpreq_user_data(req), "foo") == 0);
  253. dummy = "bar";
  254. ASSERT(sg_httpreq_set_user_data(req, (void *) dummy) == 0);
  255. ASSERT(strcmp(sg_httpreq_user_data(req), "bar") == 0);
  256. }
  257. static void test_httpreq_user_data(struct sg_httpreq *req) {
  258. errno = 0;
  259. ASSERT(!sg_httpreq_user_data(NULL));
  260. ASSERT(errno == EINVAL);
  261. errno = 0;
  262. sg_httpreq_set_user_data(req, NULL);
  263. ASSERT(!sg_httpreq_user_data(req));
  264. ASSERT(errno == 0);
  265. sg_httpreq_set_user_data(req, "foo");
  266. ASSERT(strcmp(sg_httpreq_user_data(req), "foo") == 0);
  267. sg_httpreq_set_user_data(req, "bar");
  268. ASSERT(strcmp(sg_httpreq_user_data(req), "bar") == 0);
  269. }
  270. int main(void) {
  271. struct sg_httpsrv *srv = sg_httpsrv_new(dummy_httpreq_cb, NULL);
  272. struct sg_httpreq *req = sg__httpreq_new(srv, NULL, NULL, NULL, NULL);
  273. test__httpreq_new(srv);
  274. test__httpreq_free();
  275. test_httpreq_srv(req);
  276. test_httpreq_headers(req);
  277. test_httpreq_cookies(req);
  278. test_httpreq_params(req);
  279. test_httpreq_fields(req);
  280. test_httpreq_version(req);
  281. test_httpreq_method(req);
  282. test_httpreq_path(req);
  283. test_httpreq_payload(req);
  284. test_httpreq_is_uploading(req);
  285. test_httpreq_uploads(req);
  286. test_httpreq_client();
  287. #ifdef SG_HTTPS_SUPPORT
  288. test_httpreq_tls_session();
  289. #endif /* SG_HTTPS_SUPPORT */
  290. test_httpreq_isolate(req);
  291. test_httpreq_set_user_data(req);
  292. test_httpreq_user_data(req);
  293. sg__httpreq_free(req);
  294. sg_httpsrv_free(srv);
  295. return EXIT_SUCCESS;
  296. }