PageRenderTime 31ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/src/test/test_ext_curl.cpp

https://github.com/kevlund/hiphop-php
C++ | 398 lines | 325 code | 51 blank | 22 comment | 13 complexity | 1ef0eed047ae0896e6cd46b42070c3fd MD5 | raw file
  1. /*
  2. +----------------------------------------------------------------------+
  3. | HipHop for PHP |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. */
  16. #include <test/test_ext_curl.h>
  17. #include <runtime/ext/ext_curl.h>
  18. #include <runtime/ext/ext_output.h>
  19. #include <runtime/ext/ext_zlib.h>
  20. #include <runtime/base/server/libevent_server.h>
  21. using namespace std;
  22. #define PORT_MIN 7100
  23. #define PORT_MAX 7120
  24. ///////////////////////////////////////////////////////////////////////////////
  25. class TestRequestHandler : public RequestHandler {
  26. public:
  27. // implementing RequestHandler
  28. virtual void handleRequest(Transport *transport) {
  29. transport->addHeader("ECHOED", transport->getHeader("ECHO").c_str());
  30. if (transport->getMethod() == Transport::POST) {
  31. int len = 0;
  32. const void *data = transport->getPostData(len);
  33. String res = "POST: ";
  34. res += String((char*)data, len, CopyString);
  35. transport->sendString(res);
  36. } else {
  37. transport->sendString("OK");
  38. }
  39. }
  40. };
  41. static int s_server_port = 0;
  42. static std::string get_request_uri() {
  43. return "http://localhost:" + boost::lexical_cast<string>(s_server_port) +
  44. "/request";
  45. }
  46. static ServerPtr runServer() {
  47. for (s_server_port = PORT_MIN; s_server_port <= PORT_MAX; s_server_port++) {
  48. try {
  49. ServerPtr server(new TypedServer<LibEventServer, TestRequestHandler>
  50. ("127.0.0.1", s_server_port, 4, -1));
  51. server->start();
  52. return server;
  53. } catch (FailedToListenException e) {
  54. if (s_server_port == PORT_MAX) throw;
  55. }
  56. }
  57. return ServerPtr();
  58. }
  59. ///////////////////////////////////////////////////////////////////////////////
  60. bool TestExtCurl::RunTests(const std::string &which) {
  61. bool ret = true;
  62. ServerPtr server = runServer();
  63. RUN_TEST(test_curl_init);
  64. RUN_TEST(test_curl_copy_handle);
  65. RUN_TEST(test_curl_version);
  66. RUN_TEST(test_curl_setopt);
  67. RUN_TEST(test_curl_setopt_array);
  68. RUN_TEST(test_curl_exec);
  69. RUN_TEST(test_curl_getinfo);
  70. RUN_TEST(test_curl_errno);
  71. RUN_TEST(test_curl_error);
  72. RUN_TEST(test_curl_close);
  73. RUN_TEST(test_curl_multi_init);
  74. RUN_TEST(test_curl_multi_add_handle);
  75. RUN_TEST(test_curl_multi_remove_handle);
  76. RUN_TEST(test_curl_multi_exec);
  77. RUN_TEST(test_curl_multi_select);
  78. RUN_TEST(test_curl_multi_getcontent);
  79. RUN_TEST(test_curl_multi_info_read);
  80. RUN_TEST(test_curl_multi_close);
  81. RUN_TEST(test_evhttp_set_cache);
  82. RUN_TEST(test_evhttp_get);
  83. RUN_TEST(test_evhttp_post);
  84. RUN_TEST(test_evhttp_post_gzip);
  85. RUN_TEST(test_evhttp_async_get);
  86. RUN_TEST(test_evhttp_async_post);
  87. RUN_TEST(test_evhttp_recv);
  88. server->stop();
  89. return ret;
  90. }
  91. ///////////////////////////////////////////////////////////////////////////////
  92. bool TestExtCurl::test_curl_init() {
  93. Variant c = f_curl_init();
  94. VS(f_curl_errno(c), 0);
  95. VS(f_curl_error(c), "");
  96. return Count(true);
  97. }
  98. bool TestExtCurl::test_curl_copy_handle() {
  99. Variant c = f_curl_init();
  100. f_curl_setopt(c, k_CURLOPT_URL, String(get_request_uri()));
  101. f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
  102. Variant cpy = f_curl_copy_handle(c);
  103. f_curl_close(c); // to test cpy is still working fine
  104. Variant res = f_curl_exec(cpy);
  105. VS(res, "OK");
  106. return Count(true);
  107. }
  108. bool TestExtCurl::test_curl_version() {
  109. Variant ret = f_curl_version();
  110. VERIFY(!ret["protocols"].toArray().empty());
  111. return Count(true);
  112. }
  113. bool TestExtCurl::test_curl_setopt() {
  114. Variant c = f_curl_init();
  115. f_curl_setopt(c, k_CURLOPT_URL, String(get_request_uri()));
  116. f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
  117. Variant res = f_curl_exec(c);
  118. VS(res, "OK");
  119. return Count(true);
  120. }
  121. bool TestExtCurl::test_curl_setopt_array() {
  122. Variant c = f_curl_init();
  123. f_curl_setopt_array
  124. (c,
  125. CREATE_MAP2(k_CURLOPT_URL, String(get_request_uri()),
  126. k_CURLOPT_RETURNTRANSFER, true));
  127. Variant res = f_curl_exec(c);
  128. VS(res, "OK");
  129. return Count(true);
  130. }
  131. bool TestExtCurl::test_curl_exec() {
  132. {
  133. Variant c = f_curl_init(String(get_request_uri()));
  134. f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
  135. Variant res = f_curl_exec(c);
  136. VS(res, "OK");
  137. }
  138. {
  139. Variant c = f_curl_init(String(get_request_uri()));
  140. f_curl_setopt(c, k_CURLOPT_WRITEFUNCTION, "curl_write_func");
  141. f_ob_start();
  142. f_curl_exec(c);
  143. String res = f_ob_get_contents();
  144. VS(res, "curl_write_func called with OK");
  145. f_ob_end_clean();
  146. }
  147. return Count(true);
  148. }
  149. bool TestExtCurl::test_curl_getinfo() {
  150. Variant c = f_curl_init(String(get_request_uri()));
  151. f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
  152. f_curl_exec(c);
  153. Variant ret = f_curl_getinfo(c);
  154. VS(ret["url"], String(get_request_uri()));
  155. ret = f_curl_getinfo(c, k_CURLINFO_EFFECTIVE_URL);
  156. VS(ret, String(get_request_uri()));
  157. return Count(true);
  158. }
  159. bool TestExtCurl::test_curl_errno() {
  160. Variant c = f_curl_init("http://www.thereisnosuchanurl");
  161. f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
  162. f_curl_exec(c);
  163. Variant err = f_curl_errno(c);
  164. VS(err, k_CURLE_COULDNT_RESOLVE_HOST);
  165. return Count(true);
  166. }
  167. bool TestExtCurl::test_curl_error() {
  168. Variant c = f_curl_init("http://www.thereisnosuchanurl");
  169. f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
  170. f_curl_exec(c);
  171. Variant err = f_curl_error(c);
  172. VERIFY(err == "Couldn't resolve host 'www.thereisnosuchanurl'" ||
  173. err == "Could not resolve host: www.thereisnosuchanurl"
  174. " (Domain name not found)");
  175. return Count(true);
  176. }
  177. bool TestExtCurl::test_curl_close() {
  178. Variant c = f_curl_init(String(get_request_uri()));
  179. f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
  180. f_curl_exec(c);
  181. f_curl_close(c);
  182. return Count(true);
  183. }
  184. bool TestExtCurl::test_curl_multi_init() {
  185. f_curl_multi_init();
  186. return Count(true);
  187. }
  188. bool TestExtCurl::test_curl_multi_add_handle() {
  189. Object mh = f_curl_multi_init();
  190. Variant c1 = f_curl_init(String(get_request_uri()));
  191. Variant c2 = f_curl_init(String(get_request_uri()));
  192. f_curl_multi_add_handle(mh, c1);
  193. f_curl_multi_add_handle(mh, c2);
  194. return Count(true);
  195. }
  196. bool TestExtCurl::test_curl_multi_remove_handle() {
  197. Object mh = f_curl_multi_init();
  198. Variant c1 = f_curl_init(String(get_request_uri()));
  199. Variant c2 = f_curl_init(String(get_request_uri()));
  200. f_curl_multi_add_handle(mh, c1);
  201. f_curl_multi_add_handle(mh, c2);
  202. f_curl_multi_remove_handle(mh, c1);
  203. return Count(true);
  204. }
  205. bool TestExtCurl::test_curl_multi_exec() {
  206. Object mh = f_curl_multi_init();
  207. Variant c1 = f_curl_init(String(get_request_uri()));
  208. Variant c2 = f_curl_init(String(get_request_uri()));
  209. f_curl_setopt(c1, k_CURLOPT_RETURNTRANSFER, true);
  210. f_curl_setopt(c2, k_CURLOPT_RETURNTRANSFER, true);
  211. f_curl_multi_add_handle(mh, c1);
  212. f_curl_multi_add_handle(mh, c2);
  213. Variant still_running;
  214. do {
  215. f_curl_multi_exec(mh, ref(still_running));
  216. } while (more(still_running, 0));
  217. return Count(true);
  218. }
  219. bool TestExtCurl::test_curl_multi_select() {
  220. Object mh = f_curl_multi_init();
  221. Variant c1 = f_curl_init(String(get_request_uri()));
  222. Variant c2 = f_curl_init(String(get_request_uri()));
  223. f_curl_multi_add_handle(mh, c1);
  224. f_curl_multi_add_handle(mh, c2);
  225. VS(f_curl_multi_select(mh), 0);
  226. return Count(true);
  227. }
  228. bool TestExtCurl::test_curl_multi_getcontent() {
  229. Object mh = f_curl_multi_init();
  230. Variant c1 = f_curl_init(String(get_request_uri()));
  231. Variant c2 = f_curl_init(String(get_request_uri()));
  232. f_curl_setopt(c1, k_CURLOPT_RETURNTRANSFER, true);
  233. f_curl_setopt(c2, k_CURLOPT_RETURNTRANSFER, true);
  234. f_curl_multi_add_handle(mh, c1);
  235. f_curl_multi_add_handle(mh, c2);
  236. Variant still_running;
  237. do {
  238. f_curl_multi_exec(mh, ref(still_running));
  239. } while (more(still_running, 0));
  240. VS(f_curl_multi_getcontent(c1), "OK");
  241. VS(f_curl_multi_getcontent(c1), "OK");
  242. VS(f_curl_multi_getcontent(c2), "OK");
  243. VS(f_curl_multi_getcontent(c2), "OK");
  244. return Count(true);
  245. }
  246. bool TestExtCurl::test_curl_multi_info_read() {
  247. Object mh = f_curl_multi_init();
  248. Variant c1 = f_curl_init(String(get_request_uri()));
  249. Variant c2 = f_curl_init(String(get_request_uri()));
  250. f_curl_setopt(c1, k_CURLOPT_RETURNTRANSFER, true);
  251. f_curl_setopt(c2, k_CURLOPT_RETURNTRANSFER, true);
  252. f_curl_multi_add_handle(mh, c1);
  253. f_curl_multi_add_handle(mh, c2);
  254. Variant still_running;
  255. do {
  256. f_curl_multi_exec(mh, ref(still_running));
  257. } while (more(still_running, 0));
  258. Variant ret = f_curl_multi_info_read(mh);
  259. VS(ret["result"], 0);
  260. return Count(true);
  261. }
  262. bool TestExtCurl::test_curl_multi_close() {
  263. Object mh = f_curl_multi_init();
  264. Variant c1 = f_curl_init(String(get_request_uri()));
  265. Variant c2 = f_curl_init(String(get_request_uri()));
  266. f_curl_setopt(c1, k_CURLOPT_RETURNTRANSFER, true);
  267. f_curl_setopt(c2, k_CURLOPT_RETURNTRANSFER, true);
  268. f_curl_multi_add_handle(mh, c1);
  269. f_curl_multi_add_handle(mh, c2);
  270. Variant still_running;
  271. do {
  272. f_curl_multi_exec(mh, ref(still_running));
  273. } while (more(still_running, 0));
  274. f_curl_multi_close(mh);
  275. return Count(true);
  276. }
  277. bool TestExtCurl::test_evhttp_set_cache() {
  278. f_evhttp_set_cache("localhost", 4, s_server_port);
  279. for (int i = 0; i < 10; i++) {
  280. Variant ret = f_evhttp_get(String(get_request_uri()),
  281. CREATE_VECTOR1("ECHO: foo"));
  282. VS(ret["code"], 200);
  283. VS(ret["response"], "OK");
  284. VS(ret["headers"][0], "ECHOED: foo");
  285. VS(ret["headers"][4], "Content-Length: 2");
  286. }
  287. return Count(true);
  288. }
  289. bool TestExtCurl::test_evhttp_get() {
  290. Variant ret = f_evhttp_get(String(get_request_uri()),
  291. CREATE_VECTOR1("ECHO: foo"));
  292. VS(ret["code"], 200);
  293. VS(ret["response"], "OK");
  294. VS(ret["headers"][0], "ECHOED: foo");
  295. VS(ret["headers"][4], "Content-Length: 2");
  296. return Count(true);
  297. }
  298. bool TestExtCurl::test_evhttp_post() {
  299. Variant ret = f_evhttp_post(String(get_request_uri()), "echo",
  300. CREATE_VECTOR1("ECHO: foo"));
  301. VS(ret["code"], 200);
  302. VS(ret["response"], "POST: echo");
  303. VS(ret["headers"][0], "ECHOED: foo");
  304. VS(ret["headers"][4], "Content-Length: 10");
  305. return Count(true);
  306. }
  307. bool TestExtCurl::test_evhttp_post_gzip() {
  308. // we fill up 2k to avoid the "oh it's < 1000 bytes, forget compression"
  309. // logic in Transport's implementation.
  310. char fullPostBody[2048];
  311. memcpy(fullPostBody, "POST: ", 6);
  312. char* postBody = fullPostBody + 6;
  313. memset(postBody, 'a', sizeof(fullPostBody) - 7);
  314. fullPostBody[sizeof(fullPostBody) - 1] = '\0';
  315. Variant ret = f_evhttp_post(String(get_request_uri()), postBody,
  316. CREATE_VECTOR2("ECHO: foo",
  317. "Accept-Encoding: gzip"));
  318. VS(ret["code"], 200);
  319. VS(ret["response"], fullPostBody);
  320. VS(ret["headers"][0], "ECHOED: foo");
  321. VS(ret["headers"][1], "Content-Encoding: gzip");
  322. return Count(true);
  323. }
  324. bool TestExtCurl::test_evhttp_async_get() {
  325. Variant ret = f_evhttp_async_get(String(get_request_uri()),
  326. CREATE_VECTOR1("ECHO: foo"));
  327. ret = f_evhttp_recv(ret);
  328. VS(ret["code"], 200);
  329. VS(ret["response"], "OK");
  330. VS(ret["headers"][0], "ECHOED: foo");
  331. VS(ret["headers"][4], "Content-Length: 2");
  332. return Count(true);
  333. }
  334. bool TestExtCurl::test_evhttp_async_post() {
  335. Variant ret = f_evhttp_async_post(String(get_request_uri()), "echo",
  336. CREATE_VECTOR1("ECHO: foo"));
  337. ret = f_evhttp_recv(ret);
  338. VS(ret["code"], 200);
  339. VS(ret["response"], "POST: echo");
  340. VS(ret["headers"][0], "ECHOED: foo");
  341. VS(ret["headers"][4], "Content-Length: 10");
  342. return Count(true);
  343. }
  344. bool TestExtCurl::test_evhttp_recv() {
  345. // tested in test_evhttp_async_get() and test_evhttp_async_post()
  346. return Count(true);
  347. }