test_httpsrv_curl.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  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 <stdio.h>
  28. #include <stdlib.h>
  29. #include <stdbool.h>
  30. #include <unistd.h>
  31. #include <sys/stat.h>
  32. #include <curl/curl.h>
  33. #include <sagui.h>
  34. #define CURL_LOG(e) \
  35. do { \
  36. if ((e) != CURLE_OK) { \
  37. fprintf(stderr, "CURL ERROR: %s\n", curl_easy_strerror((e))); \
  38. fflush(stderr); \
  39. } \
  40. } while (0)
  41. #ifndef TEST_HTTPSRV_CURL_PORT
  42. #define TEST_HTTPSRV_CURL_PORT 8080
  43. #endif /* TEST_HTTPSRV_CURL_PORT */
  44. #ifndef TEST_HTTPSRV_CURL_BASE_PATH
  45. #ifdef __ANDROID__
  46. #define TEST_HTTPSRV_CURL_BASE_PATH SG_ANDROID_TESTS_DEST_DIR "/"
  47. #else
  48. #ifdef _WIN32
  49. #define TEST_HTTPSRV_CURL_BASE_PATH ""
  50. #else /* _WIN32 */
  51. #define TEST_HTTPSRV_CURL_BASE_PATH "/tmp/"
  52. #endif /* _WIN32 */
  53. #endif /* __ANDROID__ */
  54. #endif /* TEST_HTTPSRV_CURL_BASE_PATH */
  55. #define OK_MSG "libsagui [OK]"
  56. #define ERROR_MSG "libsagui [ERROR]"
  57. #define DENIED_MSG "Denied"
  58. #define PAGE \
  59. "<html><head><title>Hello world</title></head><body>Hello " \
  60. "world</body></html>"
  61. static bool strmatch(const char *s1, const char *s2) {
  62. if (!s1 || !s2)
  63. return false;
  64. return strcmp(s1, s2) == 0;
  65. }
  66. #ifdef SG_HTTP_COMPRESSION
  67. static char *ftos(const char *filename) {
  68. FILE *file;
  69. struct stat sbuf;
  70. char *str;
  71. if (stat(filename, &sbuf) != 0)
  72. return NULL;
  73. str = malloc(sbuf.st_size + 1);
  74. if (!str)
  75. return NULL;
  76. file = fopen(filename, "rb");
  77. if (!file) {
  78. free(str);
  79. return NULL;
  80. }
  81. fread(str, 1, sbuf.st_size, file);
  82. fclose(file);
  83. str[sbuf.st_size] = '\0';
  84. return str;
  85. }
  86. #endif /* SG_HTTP_COMPRESSION */
  87. static ssize_t httpres_stream_read_cb(void *handle, __SG_UNUSED uint64_t offset,
  88. char *buf, size_t size) {
  89. ssize_t have = fread(buf, 1, size, handle);
  90. if ((have == 0) || (have < 0))
  91. return sg_eor(have < 0);
  92. return have;
  93. }
  94. static void httpres_stream_free_cb(void *handle) {
  95. ASSERT(fclose(handle) == 0);
  96. }
  97. static void httpreq_isolated_cb(__SG_UNUSED void *cls,
  98. __SG_UNUSED struct sg_httpreq *req,
  99. struct sg_httpres *res) {
  100. usleep(1000 * 500);
  101. sg_httpres_send(res, OK_MSG, "text/plain", 200);
  102. }
  103. static bool httpauth_cb(__SG_UNUSED void *cls, struct sg_httpauth *auth,
  104. struct sg_httpreq *req,
  105. __SG_UNUSED struct sg_httpres *res) {
  106. char *data = strdup("abc123");
  107. bool pass, *auth_403 = cls;
  108. ASSERT(sg_httpauth_set_realm(auth, "My realm") == 0);
  109. ASSERT(sg_httpreq_set_user_data(req, data) == 0);
  110. pass = strmatch(sg_httpauth_usr(auth), "foo") &&
  111. strmatch(sg_httpauth_pwd(auth), "bar");
  112. if (!pass) {
  113. sg_free(data);
  114. if (*auth_403)
  115. ASSERT(sg_httpauth_deny2(auth, DENIED_MSG, "text/plain", 403) == 0);
  116. else
  117. ASSERT(sg_httpauth_deny(auth, DENIED_MSG, "text/plain") == 0);
  118. if (strcmp(sg_httpreq_path(req), "/cancel-auth") == 0)
  119. ASSERT(sg_httpauth_cancel(auth) == 0);
  120. }
  121. return pass;
  122. }
  123. static void httpsrv_err_cb(__SG_UNUSED void *cls, const char *err) {
  124. fprintf(stderr, "%s", err);
  125. fflush(stderr);
  126. }
  127. static void httpsrv_req_cb(__SG_UNUSED void *cls, struct sg_httpreq *req,
  128. struct sg_httpres *res) {
  129. const char *filename1 = TEST_HTTPSRV_CURL_BASE_PATH "foo_uploaded.txt";
  130. const char *filename2 = TEST_HTTPSRV_CURL_BASE_PATH "bar_uploaded.txt";
  131. const size_t len = 3;
  132. struct sg_strmap **headers;
  133. struct sg_strmap **params;
  134. struct sg_strmap **cookies;
  135. struct sg_strmap **fields;
  136. struct sg_str *payload;
  137. struct sg_httpupld *upld;
  138. FILE *tmp_file;
  139. char filename[PATH_MAX];
  140. char text[35];
  141. char *data;
  142. #ifdef SG_HTTP_COMPRESSION
  143. struct stat sbuf;
  144. const char *header;
  145. #endif /* SG_HTTP_COMPRESSION */
  146. data = sg_httpreq_user_data(req);
  147. ASSERT(data);
  148. ASSERT(strcmp(data, "abc123") == 0);
  149. sg_free(data);
  150. ASSERT(strcmp(sg_httpreq_version(req), "HTTP/1.1") == 0);
  151. if (strcmp(sg_httpreq_path(req), "/") == 0) {
  152. ASSERT(strcmp(sg_httpreq_method(req), "GET") == 0);
  153. ASSERT(!sg_httpreq_is_uploading(req));
  154. headers = sg_httpreq_headers(req);
  155. ASSERT(*headers);
  156. cookies = sg_httpreq_cookies(req);
  157. ASSERT(*cookies);
  158. params = sg_httpreq_params(req);
  159. ASSERT(*params);
  160. ASSERT(strcmp(sg_strmap_get(*headers, "header1"), "header-value1") == 0);
  161. ASSERT(strcmp(sg_strmap_get(*headers, "header2"), "header-value2") == 0);
  162. ASSERT(strcmp(sg_strmap_get(*cookies, "cookie1"), "cookie-value1") == 0);
  163. ASSERT(strcmp(sg_strmap_get(*cookies, "cookie2"), "cookie-value2") == 0);
  164. ASSERT(strcmp(sg_strmap_get(*params, "param1"), "param-value1") == 0);
  165. ASSERT(strcmp(sg_strmap_get(*params, "param2"), "param-value2") == 0);
  166. #ifdef SG_HTTP_COMPRESSION
  167. headers = sg_httpreq_headers(req);
  168. if (headers) {
  169. header = sg_strmap_get(*headers, "Accept-Encoding");
  170. if (header && strstr(header, "deflate")) {
  171. sg_httpres_zsend(res, PAGE, "text/html", 200);
  172. return;
  173. }
  174. }
  175. #endif /* SG_HTTP_COMPRESSION */
  176. sg_httpres_send(res, OK_MSG, "text/plain", 200);
  177. return;
  178. }
  179. if (strcmp(sg_httpreq_path(req), "/form") == 0) {
  180. ASSERT(strcmp(sg_httpreq_method(req), "POST") == 0);
  181. ASSERT(sg_httpreq_is_uploading(req));
  182. fields = sg_httpreq_fields(req);
  183. ASSERT(*fields);
  184. ASSERT(strcmp(sg_strmap_get(*fields, "field1"), "field-value1") == 0);
  185. ASSERT(strcmp(sg_strmap_get(*fields, "field2"), "field-value2") == 0);
  186. sg_httpres_send(res, OK_MSG, "text/plain", 200);
  187. return;
  188. }
  189. if (strcmp(sg_httpreq_path(req), "/payload") == 0) {
  190. ASSERT(strcmp(sg_httpreq_method(req), "POST") == 0);
  191. ASSERT(sg_httpreq_is_uploading(req));
  192. payload = sg_httpreq_payload(req);
  193. ASSERT(payload);
  194. ASSERT(strcmp(sg_str_content(payload), "{\"foo\":\"bar\"}") == 0);
  195. sg_httpres_send(res, OK_MSG, "text/plain", 200);
  196. return;
  197. }
  198. if (strcmp(sg_httpreq_path(req), "/upload") == 0) {
  199. ASSERT(strcmp(sg_httpreq_method(req), "POST") == 0);
  200. ASSERT(sg_httpreq_is_uploading(req));
  201. fields = sg_httpreq_fields(req);
  202. ASSERT(*fields);
  203. ASSERT(strcmp(sg_strmap_get(*fields, "form-field1"), "form-field-value1") ==
  204. 0);
  205. ASSERT(strcmp(sg_strmap_get(*fields, "form-field2"), "form-field-value2") ==
  206. 0);
  207. unlink(filename1);
  208. ASSERT(access(filename1, F_OK) == -1);
  209. unlink(filename2);
  210. ASSERT(access(filename2, F_OK) == -1);
  211. upld = sg_httpreq_uploads(req);
  212. while (upld) {
  213. if (strcmp(sg_httpupld_name(upld), "foo.txt") == 0) {
  214. ASSERT(sg_httpupld_save_as(upld, filename1, true) == 0);
  215. ASSERT(access(filename1, F_OK) == 0);
  216. tmp_file = fopen(filename1, "r");
  217. ASSERT(tmp_file);
  218. memset(text, 0, sizeof(text));
  219. ASSERT(fread(text, 1, len, tmp_file) == len);
  220. ASSERT(fclose(tmp_file) == 0);
  221. ASSERT(strcmp(text, "foo") == 0);
  222. } else if (strcmp(sg_httpupld_name(upld), "bar.txt") == 0) {
  223. ASSERT(sg_httpupld_save_as(upld, filename2, true) == 0);
  224. ASSERT(access(filename2, F_OK) == 0);
  225. tmp_file = fopen(filename2, "r");
  226. ASSERT(tmp_file);
  227. memset(text, 0, sizeof(text));
  228. ASSERT(fread(text, 1, len, tmp_file) == len);
  229. ASSERT(fclose(tmp_file) == 0);
  230. ASSERT(strcmp(text, "bar") == 0);
  231. }
  232. sg_httpuplds_next(&upld);
  233. }
  234. sg_httpres_send(res, OK_MSG, "text/plain", 200);
  235. return;
  236. }
  237. if (strcmp(sg_httpreq_path(req), "/download") == 0) {
  238. ASSERT(strcmp(sg_httpreq_method(req), "GET") == 0);
  239. snprintf(filename, sizeof(filename), "%s",
  240. sg_strmap_get(*sg_httpreq_params(req), "filename"));
  241. ASSERT(sg_httpres_download(res, filename, 200) == 0);
  242. return;
  243. }
  244. if (strcmp(sg_httpreq_path(req), "/offset") == 0) {
  245. ASSERT(strcmp(sg_httpreq_method(req), "GET") == 0);
  246. snprintf(filename, sizeof(filename), "%s",
  247. sg_strmap_get(*sg_httpreq_params(req), "filename"));
  248. ASSERT(sg_httpres_sendfile(res, 0, 0, 1, filename, false, 200) == 0);
  249. return;
  250. }
  251. #ifdef SG_HTTP_COMPRESSION
  252. if (strcmp(sg_httpreq_path(req), "/zoffset") == 0) {
  253. ASSERT(strcmp(sg_httpreq_method(req), "GET") == 0);
  254. ASSERT(stat(__FILE__, &sbuf) > -1);
  255. ASSERT(sbuf.st_size > 100);
  256. ASSERT(sg_httpres_zsendfile(res, sbuf.st_size - 20, 0, 10, __FILE__, false,
  257. 200) == 0);
  258. return;
  259. }
  260. #endif /* SG_HTTP_COMPRESSION */
  261. if (strcmp(sg_httpreq_path(req), "/data") == 0) {
  262. ASSERT(strcmp(sg_httpreq_method(req), "GET") == 0);
  263. memset(text, 0, sizeof(text));
  264. snprintf(text, sizeof(text), "abc");
  265. ASSERT(sg_httpres_sendbinary(res, text, len, "text/plain", 200) == 0);
  266. return;
  267. }
  268. #ifdef SG_HTTP_COMPRESSION
  269. if (strcmp(sg_httpreq_path(req), "/zdata") == 0) {
  270. ASSERT(strcmp(sg_httpreq_method(req), "GET") == 0);
  271. memset(text, 0, sizeof(text));
  272. snprintf(text, sizeof(text), "fooooooooooobaaaaaaaaaarrrrrrrrrrr");
  273. ASSERT(sg_httpres_zsendbinary(res, text, sizeof(text), "text/plain", 200) ==
  274. 0);
  275. return;
  276. }
  277. #endif /* SG_HTTP_COMPRESSION */
  278. if (strcmp(sg_httpreq_path(req), "/stream") == 0) {
  279. ASSERT(strcmp(sg_httpreq_method(req), "GET") == 0);
  280. ASSERT(access(filename1, F_OK) == 0);
  281. tmp_file = fopen(filename1, "r");
  282. ASSERT(tmp_file);
  283. sg_httpres_sendstream(res, len, httpres_stream_read_cb, tmp_file,
  284. httpres_stream_free_cb, 200);
  285. return;
  286. }
  287. #ifdef SG_HTTP_COMPRESSION
  288. if (strcmp(sg_httpreq_path(req), "/zstream") == 0) {
  289. ASSERT(strcmp(sg_httpreq_method(req), "GET") == 0);
  290. tmp_file = fopen(__FILE__, "rb");
  291. ASSERT(tmp_file);
  292. sg_httpres_zsendstream(res, httpres_stream_read_cb, tmp_file,
  293. httpres_stream_free_cb, 200);
  294. return;
  295. }
  296. #endif /* SG_HTTP_COMPRESSION */
  297. if (strcmp(sg_httpreq_path(req), "/sleep") == 0) {
  298. ASSERT(sg_httpreq_isolate(req, httpreq_isolated_cb, NULL) == 0);
  299. ASSERT(sg_httpreq_isolate(req, httpreq_isolated_cb, NULL) == EALREADY);
  300. return;
  301. }
  302. sg_httpres_send(res, ERROR_MSG, "text/plain", 500);
  303. }
  304. static size_t curl_write_func(void *ptr, size_t size, size_t nmemb,
  305. struct sg_str *res) {
  306. sg_str_write(res, ptr, size * nmemb);
  307. return size * nmemb;
  308. }
  309. int main(void) {
  310. const char *filename1 = TEST_HTTPSRV_CURL_BASE_PATH "foo.txt";
  311. const char *filename2 = TEST_HTTPSRV_CURL_BASE_PATH "bar.txt";
  312. const size_t len = 3;
  313. struct sg_httpsrv *srv;
  314. CURLcode *curl;
  315. CURLcode ret;
  316. struct sg_str *res;
  317. struct curl_slist *headers;
  318. curl_mime *form;
  319. curl_mimepart *field;
  320. FILE *tmp_file;
  321. char url[100];
  322. char text[4];
  323. #ifdef SG_HTTP_COMPRESSION
  324. curl_off_t cl;
  325. char *str;
  326. char *tmp;
  327. size_t size;
  328. #endif /* SG_HTTP_COMPRESSION */
  329. long status;
  330. bool auth_403;
  331. curl_global_init(CURL_GLOBAL_ALL);
  332. srv = sg_httpsrv_new2(httpauth_cb, httpsrv_req_cb, httpsrv_err_cb, &auth_403);
  333. ASSERT(srv);
  334. curl = curl_easy_init();
  335. ASSERT(curl);
  336. res = sg_str_new();
  337. ASSERT(res);
  338. ASSERT(sg_httpsrv_listen(srv, TEST_HTTPSRV_CURL_PORT, false));
  339. ASSERT(curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1) ==
  340. CURLE_OK);
  341. snprintf(url, sizeof(url),
  342. "http://localhost:%d?param1=param-value1&param2=param-value2",
  343. TEST_HTTPSRV_CURL_PORT);
  344. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  345. ASSERT(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_func) ==
  346. CURLE_OK);
  347. ASSERT(curl_easy_setopt(curl, CURLOPT_WRITEDATA, res) == CURLE_OK);
  348. headers = curl_slist_append(NULL, "header1: header-value1");
  349. ASSERT(headers);
  350. headers = curl_slist_append(headers, "header2: header-value2");
  351. ASSERT(headers);
  352. ASSERT(curl_easy_setopt(curl, CURLOPT_HTTPHEADER,
  353. (struct curl_slist *) headers) == CURLE_OK);
  354. ASSERT(curl_easy_setopt(curl, CURLOPT_COOKIE,
  355. "cookie1=cookie-value1; cookie2=cookie-value2;") ==
  356. CURLE_OK);
  357. auth_403 = false;
  358. ASSERT(sg_str_clear(res) == 0);
  359. ret = curl_easy_perform(curl);
  360. CURL_LOG(ret);
  361. ASSERT(ret == CURLE_OK);
  362. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  363. ASSERT(status == 401);
  364. ASSERT(strcmp(sg_str_content(res), DENIED_MSG) == 0);
  365. auth_403 = true;
  366. ASSERT(sg_str_clear(res) == 0);
  367. ret = curl_easy_perform(curl);
  368. CURL_LOG(ret);
  369. ASSERT(ret == CURLE_OK);
  370. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  371. ASSERT(status == 403);
  372. ASSERT(strcmp(sg_str_content(res), DENIED_MSG) == 0);
  373. auth_403 = false;
  374. ASSERT(curl_easy_setopt(curl, CURLOPT_USERPWD, "wrong:pass") == CURLE_OK);
  375. ASSERT(sg_str_clear(res) == 0);
  376. ret = curl_easy_perform(curl);
  377. CURL_LOG(ret);
  378. ASSERT(ret == CURLE_OK);
  379. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  380. ASSERT(status == 401);
  381. ASSERT(strcmp(sg_str_content(res), DENIED_MSG) == 0);
  382. ASSERT(curl_easy_setopt(curl, CURLOPT_USERPWD, "foo:bar") == CURLE_OK);
  383. ASSERT(sg_str_clear(res) == 0);
  384. ret = curl_easy_perform(curl);
  385. CURL_LOG(ret);
  386. ASSERT(ret == CURLE_OK);
  387. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  388. ASSERT(status == 200);
  389. ASSERT(strcmp(sg_str_content(res), OK_MSG) == 0);
  390. #ifdef SG_HTTP_COMPRESSION
  391. ASSERT(sg_str_clear(res) == 0);
  392. ASSERT(curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "deflate") ==
  393. CURLE_OK);
  394. ret = curl_easy_perform(curl);
  395. CURL_LOG(ret);
  396. ASSERT(ret == CURLE_OK);
  397. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  398. ASSERT(status == 200);
  399. ASSERT(strcmp(sg_str_content(res), PAGE) == 0);
  400. ASSERT(curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &cl) ==
  401. CURLE_OK);
  402. ASSERT((curl_off_t) strlen(PAGE) > cl);
  403. #endif /* SG_HTTP_COMPRESSION */
  404. snprintf(url, sizeof(url), "http://localhost:%d/cancel-auth",
  405. TEST_HTTPSRV_CURL_PORT);
  406. ASSERT(curl_easy_setopt(curl, CURLOPT_USERPWD, "wrong:pass") == CURLE_OK);
  407. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  408. ASSERT(sg_str_clear(res) == 0);
  409. ret = curl_easy_perform(curl);
  410. CURL_LOG(ret);
  411. ASSERT(ret == CURLE_OK);
  412. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  413. ASSERT(status == 500);
  414. ASSERT(strcmp(sg_str_content(res), DENIED_MSG) == 0);
  415. snprintf(url, sizeof(url), "http://localhost:%d/wrong",
  416. TEST_HTTPSRV_CURL_PORT);
  417. ASSERT(curl_easy_setopt(curl, CURLOPT_USERPWD, "foo:bar") == CURLE_OK);
  418. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  419. ASSERT(sg_str_clear(res) == 0);
  420. ret = curl_easy_perform(curl);
  421. CURL_LOG(ret);
  422. ASSERT(ret == CURLE_OK);
  423. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  424. ASSERT(status == 500);
  425. ASSERT(strcmp(sg_str_content(res), ERROR_MSG) == 0);
  426. snprintf(url, sizeof(url), "http://localhost:%d/form",
  427. TEST_HTTPSRV_CURL_PORT);
  428. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  429. ASSERT(curl_easy_setopt(curl, CURLOPT_POSTFIELDS,
  430. "field1=field-value1&field2=field-value2") ==
  431. CURLE_OK);
  432. ASSERT(sg_str_clear(res) == 0);
  433. ret = curl_easy_perform(curl);
  434. CURL_LOG(ret);
  435. ASSERT(ret == CURLE_OK);
  436. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  437. ASSERT(status == 200);
  438. ASSERT(strcmp(sg_str_content(res), OK_MSG) == 0);
  439. snprintf(url, sizeof(url), "http://localhost:%d/payload",
  440. TEST_HTTPSRV_CURL_PORT);
  441. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  442. curl_slist_free_all(headers);
  443. ASSERT(headers = curl_slist_append(NULL, "Content-Type: application/json"));
  444. ASSERT(curl_easy_setopt(curl, CURLOPT_HTTPHEADER,
  445. (struct curl_slist *) headers) == CURLE_OK);
  446. ASSERT(curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"foo\":\"bar\"}") ==
  447. CURLE_OK);
  448. ASSERT(sg_str_clear(res) == 0);
  449. ret = curl_easy_perform(curl);
  450. CURL_LOG(ret);
  451. ASSERT(ret == CURLE_OK);
  452. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  453. ASSERT(status == 200);
  454. ASSERT(strcmp(sg_str_content(res), OK_MSG) == 0);
  455. snprintf(url, sizeof(url), "http://localhost:%d/upload",
  456. TEST_HTTPSRV_CURL_PORT);
  457. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  458. ASSERT(form = curl_mime_init(curl));
  459. ASSERT(field = curl_mime_addpart(form));
  460. ASSERT(curl_mime_name(field, "form-field1") == CURLE_OK);
  461. ASSERT(curl_mime_data(field, "form-field-value1", CURL_ZERO_TERMINATED) ==
  462. CURLE_OK);
  463. ASSERT(field = curl_mime_addpart(form));
  464. ASSERT(curl_mime_name(field, "form-field2") == CURLE_OK);
  465. ASSERT(curl_mime_data(field, "form-field-value2", CURL_ZERO_TERMINATED) ==
  466. CURLE_OK);
  467. unlink(filename1);
  468. ASSERT(access(filename1, F_OK) == -1);
  469. ASSERT(tmp_file = fopen(filename1, "w"));
  470. memset(text, 0, sizeof(text));
  471. snprintf(text, sizeof(text), "foo");
  472. ASSERT(fwrite(text, 1, len, tmp_file) == len);
  473. ASSERT(fclose(tmp_file) == 0);
  474. ASSERT(access(filename1, F_OK) == 0);
  475. unlink(filename2);
  476. ASSERT(access(filename2, F_OK) == -1);
  477. tmp_file = fopen(filename2, "w");
  478. ASSERT(tmp_file);
  479. memset(text, 0, sizeof(text));
  480. snprintf(text, sizeof(text), "bar");
  481. ASSERT(fwrite(text, 1, len, tmp_file) == len);
  482. ASSERT(fclose(tmp_file) == 0);
  483. ASSERT(access(filename2, F_OK) == 0);
  484. field = curl_mime_addpart(form);
  485. ASSERT(field);
  486. ASSERT(curl_mime_name(field, "file1") == CURLE_OK);
  487. ASSERT(curl_mime_filedata(field, filename1) == CURLE_OK);
  488. field = curl_mime_addpart(form);
  489. ASSERT(field);
  490. ASSERT(curl_mime_name(field, "file2") == CURLE_OK);
  491. ASSERT(curl_mime_filedata(field, filename2) == CURLE_OK);
  492. ASSERT(curl_easy_setopt(curl, CURLOPT_MIMEPOST, form) == CURLE_OK);
  493. curl_slist_free_all(headers);
  494. headers = curl_slist_append(NULL, "Content-Type: multipart/form-data");
  495. ASSERT(headers);
  496. ASSERT(curl_easy_setopt(curl, CURLOPT_HTTPHEADER,
  497. (struct curl_slist *) headers) == CURLE_OK);
  498. ASSERT(sg_str_clear(res) == 0);
  499. ret = curl_easy_perform(curl);
  500. CURL_LOG(ret);
  501. ASSERT(ret == CURLE_OK);
  502. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  503. ASSERT(status == 200);
  504. ASSERT(strcmp(sg_str_content(res), OK_MSG) == 0);
  505. curl_mime_free(form);
  506. curl_easy_reset(curl);
  507. ASSERT(curl_easy_setopt(curl, CURLOPT_USERPWD, "foo:bar") == CURLE_OK);
  508. snprintf(url, sizeof(url), "http://localhost:%d/download?filename=%s",
  509. TEST_HTTPSRV_CURL_PORT, filename1);
  510. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  511. ASSERT(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_func) ==
  512. CURLE_OK);
  513. ASSERT(curl_easy_setopt(curl, CURLOPT_WRITEDATA, res) == CURLE_OK);
  514. ASSERT(sg_str_clear(res) == 0);
  515. ret = curl_easy_perform(curl);
  516. CURL_LOG(ret);
  517. ASSERT(ret == CURLE_OK);
  518. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  519. ASSERT(status == 200);
  520. ASSERT(strcmp(sg_str_content(res), "foo") == 0);
  521. snprintf(url, sizeof(url), "http://localhost:%d/offset?filename=%s",
  522. TEST_HTTPSRV_CURL_PORT, filename1);
  523. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  524. ASSERT(sg_str_clear(res) == 0);
  525. ret = curl_easy_perform(curl);
  526. CURL_LOG(ret);
  527. ASSERT(ret == CURLE_OK);
  528. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  529. ASSERT(status == 200);
  530. ASSERT(strcmp(sg_str_content(res), "oo") == 0);
  531. #ifdef SG_HTTP_COMPRESSION
  532. snprintf(url, sizeof(url), "http://localhost:%d/zoffset",
  533. TEST_HTTPSRV_CURL_PORT);
  534. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  535. ASSERT(curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip") == CURLE_OK);
  536. ASSERT(sg_str_clear(res) == 0);
  537. ret = curl_easy_perform(curl);
  538. CURL_LOG(ret);
  539. ASSERT(ret == CURLE_OK);
  540. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  541. ASSERT(status == 200);
  542. str = ftos(__FILE__);
  543. tmp = str;
  544. ASSERT(str);
  545. size = sg_str_length(res);
  546. ASSERT(strlen(str) > size);
  547. str += 10;
  548. str[size] = '\0';
  549. ASSERT(strcmp(sg_str_content(res), str) == 0);
  550. free(tmp);
  551. #endif /* SG_HTTP_COMPRESSION */
  552. snprintf(url, sizeof(url), "http://localhost:%d/download?filename=%s",
  553. TEST_HTTPSRV_CURL_PORT, filename2);
  554. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  555. ASSERT(sg_str_clear(res) == 0);
  556. ret = curl_easy_perform(curl);
  557. CURL_LOG(ret);
  558. ASSERT(ret == CURLE_OK);
  559. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  560. ASSERT(status == 200);
  561. ASSERT(strcmp(sg_str_content(res), "bar") == 0);
  562. snprintf(url, sizeof(url), "http://localhost:%d/data",
  563. TEST_HTTPSRV_CURL_PORT);
  564. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  565. ASSERT(sg_str_clear(res) == 0);
  566. ret = curl_easy_perform(curl);
  567. CURL_LOG(ret);
  568. ASSERT(ret == CURLE_OK);
  569. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  570. ASSERT(status == 200);
  571. ASSERT(strcmp(sg_str_content(res), "abc") == 0);
  572. #ifdef SG_HTTP_COMPRESSION
  573. snprintf(url, sizeof(url), "http://localhost:%d/zdata",
  574. TEST_HTTPSRV_CURL_PORT);
  575. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  576. ASSERT(curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "deflate") ==
  577. CURLE_OK);
  578. ASSERT(sg_str_clear(res) == 0);
  579. ret = curl_easy_perform(curl);
  580. CURL_LOG(ret);
  581. ASSERT(ret == CURLE_OK);
  582. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  583. ASSERT(status == 200);
  584. ASSERT(strcmp(sg_str_content(res), "fooooooooooobaaaaaaaaaarrrrrrrrrrr") ==
  585. 0);
  586. #endif /* SG_HTTP_COMPRESSION */
  587. snprintf(url, sizeof(url), "http://localhost:%d/stream",
  588. TEST_HTTPSRV_CURL_PORT);
  589. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  590. ASSERT(sg_str_clear(res) == 0);
  591. ret = curl_easy_perform(curl);
  592. CURL_LOG(ret);
  593. ASSERT(ret == CURLE_OK);
  594. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  595. ASSERT(status == 200);
  596. ASSERT(strcmp(sg_str_content(res), "foo") == 0);
  597. #ifdef SG_HTTP_COMPRESSION
  598. snprintf(url, sizeof(url), "http://localhost:%d/zstream",
  599. TEST_HTTPSRV_CURL_PORT);
  600. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  601. ASSERT(curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "deflate") ==
  602. CURLE_OK);
  603. ASSERT(sg_str_clear(res) == 0);
  604. ret = curl_easy_perform(curl);
  605. CURL_LOG(ret);
  606. ASSERT(ret == CURLE_OK);
  607. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  608. ASSERT(status == 200);
  609. str = ftos(__FILE__);
  610. ASSERT(str);
  611. ASSERT(strcmp(sg_str_content(res), str) == 0);
  612. free(str);
  613. #endif /* SG_HTTP_COMPRESSION */
  614. snprintf(url, sizeof(url), "http://localhost:%d/sleep",
  615. TEST_HTTPSRV_CURL_PORT);
  616. ASSERT(curl_easy_setopt(curl, CURLOPT_URL, url) == CURLE_OK);
  617. ASSERT(sg_str_clear(res) == 0);
  618. ret = curl_easy_perform(curl);
  619. CURL_LOG(ret);
  620. ASSERT(ret == CURLE_OK);
  621. ASSERT(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status) == CURLE_OK);
  622. ASSERT(status == 200);
  623. ASSERT(strcmp(sg_str_content(res), OK_MSG) == 0);
  624. ASSERT(sg_httpsrv_shutdown(srv) == 0);
  625. curl_slist_free_all(headers);
  626. sg_str_free(res);
  627. curl_easy_cleanup(curl);
  628. curl_global_cleanup();
  629. sg_httpsrv_free(srv);
  630. return EXIT_SUCCESS;
  631. }