2 +----------------------------------------------------------------------+
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 +----------------------------------------------------------------------+
17 #include <test/test_ext_curl.h>
18 #include <runtime/ext/ext_curl.h>
19 #include <runtime/ext/ext_output.h>
20 #include <runtime/ext/ext_zlib.h>
21 #include <runtime/base/server/libevent_server.h>
26 ///////////////////////////////////////////////////////////////////////////////
28 class TestCurlRequestHandler
: public RequestHandler
{
30 // implementing RequestHandler
31 virtual void handleRequest(Transport
*transport
) {
32 transport
->addHeader("ECHOED", transport
->getHeader("ECHO").c_str());
34 if (transport
->getMethod() == Transport::POST
) {
36 const void *data
= transport
->getPostData(len
);
37 String res
= "POST: ";
38 res
+= String((char*)data
, len
, CopyString
);
39 transport
->sendString(res
.c_str());
41 transport
->sendString("OK");
46 static int s_server_port
= 0;
48 static std::string
get_request_uri() {
49 return "http://localhost:" + boost::lexical_cast
<string
>(s_server_port
) +
53 static ServerPtr
runServer() {
54 for (s_server_port
= PORT_MIN
; s_server_port
<= PORT_MAX
; s_server_port
++) {
56 ServerPtr
server(new TypedServer
<LibEventServer
, TestCurlRequestHandler
>
57 ("127.0.0.1", s_server_port
, 4, -1));
61 } catch (const FailedToListenException
& e
) {
62 if (s_server_port
== PORT_MAX
) throw;
68 ///////////////////////////////////////////////////////////////////////////////
70 bool TestExtCurl::RunTests(const std::string
&which
) {
73 DECLARE_TEST_FUNCTIONS("function curl_write_func($s1, $s2) {"
74 " print 'curl_write_func called with ';"
76 " return strlen($s2);"
79 ServerPtr server
= runServer();
81 RUN_TEST(test_curl_init
);
82 RUN_TEST(test_curl_copy_handle
);
83 RUN_TEST(test_curl_version
);
84 RUN_TEST(test_curl_setopt
);
85 RUN_TEST(test_curl_setopt_array
);
86 RUN_TEST(test_curl_exec
);
87 RUN_TEST(test_curl_getinfo
);
88 RUN_TEST(test_curl_errno
);
89 RUN_TEST(test_curl_error
);
90 RUN_TEST(test_curl_close
);
91 RUN_TEST(test_curl_multi_init
);
92 RUN_TEST(test_curl_multi_add_handle
);
93 RUN_TEST(test_curl_multi_remove_handle
);
94 RUN_TEST(test_curl_multi_exec
);
95 RUN_TEST(test_curl_multi_select
);
96 RUN_TEST(test_curl_multi_getcontent
);
97 RUN_TEST(test_curl_multi_info_read
);
98 RUN_TEST(test_curl_multi_close
);
99 RUN_TEST(test_evhttp_set_cache
);
100 RUN_TEST(test_evhttp_get
);
101 RUN_TEST(test_evhttp_post
);
102 RUN_TEST(test_evhttp_post_gzip
);
103 RUN_TEST(test_evhttp_async_get
);
104 RUN_TEST(test_evhttp_async_post
);
105 RUN_TEST(test_evhttp_recv
);
112 ///////////////////////////////////////////////////////////////////////////////
114 bool TestExtCurl::test_curl_init() {
115 Variant c
= f_curl_init();
116 VS(f_curl_errno(c
), 0);
117 VS(f_curl_error(c
), "");
121 bool TestExtCurl::test_curl_copy_handle() {
122 Variant c
= f_curl_init();
123 f_curl_setopt(c
, k_CURLOPT_URL
, String(get_request_uri()));
124 f_curl_setopt(c
, k_CURLOPT_RETURNTRANSFER
, true);
125 Variant cpy
= f_curl_copy_handle(c
);
126 f_curl_close(c
); // to test cpy is still working fine
127 Variant res
= f_curl_exec(cpy
);
128 if (res
.toString() != "OK") {
135 bool TestExtCurl::test_curl_version() {
136 Variant ret
= f_curl_version();
137 VERIFY(!ret
["protocols"].toArray().empty());
141 bool TestExtCurl::test_curl_setopt() {
142 Variant c
= f_curl_init();
143 f_curl_setopt(c
, k_CURLOPT_URL
, String(get_request_uri()));
144 f_curl_setopt(c
, k_CURLOPT_RETURNTRANSFER
, true);
145 Variant res
= f_curl_exec(c
);
150 bool TestExtCurl::test_curl_setopt_array() {
151 Variant c
= f_curl_init();
154 CREATE_MAP2(k_CURLOPT_URL
, String(get_request_uri()),
155 k_CURLOPT_RETURNTRANSFER
, true));
156 Variant res
= f_curl_exec(c
);
161 bool TestExtCurl::test_curl_exec() {
163 Variant c
= f_curl_init(String(get_request_uri()));
164 f_curl_setopt(c
, k_CURLOPT_RETURNTRANSFER
, true);
165 Variant res
= f_curl_exec(c
);
169 Variant c
= f_curl_init(String(get_request_uri()));
170 f_curl_setopt(c
, k_CURLOPT_WRITEFUNCTION
, "curl_write_func");
173 String res
= f_ob_get_contents();
174 VS(res
, "curl_write_func called with OK");
180 bool TestExtCurl::test_curl_getinfo() {
181 Variant c
= f_curl_init(String(get_request_uri()));
182 f_curl_setopt(c
, k_CURLOPT_RETURNTRANSFER
, true);
184 Variant ret
= f_curl_getinfo(c
);
185 VS(ret
["url"], String(get_request_uri()));
186 ret
= f_curl_getinfo(c
, k_CURLINFO_EFFECTIVE_URL
);
187 VS(ret
, String(get_request_uri()));
191 bool TestExtCurl::test_curl_errno() {
192 Variant c
= f_curl_init("http://www.thereisnosuchanurl");
193 f_curl_setopt(c
, k_CURLOPT_RETURNTRANSFER
, true);
195 Variant err
= f_curl_errno(c
);
196 VS(err
, k_CURLE_COULDNT_RESOLVE_HOST
);
200 bool TestExtCurl::test_curl_error() {
201 Variant c
= f_curl_init("http://www.thereisnosuchanurl");
202 f_curl_setopt(c
, k_CURLOPT_RETURNTRANSFER
, true);
204 Variant err
= f_curl_error(c
);
205 VERIFY(err
== "Couldn't resolve host 'www.thereisnosuchanurl'" ||
206 err
== "Could not resolve host: www.thereisnosuchanurl"
207 " (Domain name not found)");
211 bool TestExtCurl::test_curl_close() {
212 Variant c
= f_curl_init(String(get_request_uri()));
213 f_curl_setopt(c
, k_CURLOPT_RETURNTRANSFER
, true);
219 bool TestExtCurl::test_curl_multi_init() {
224 bool TestExtCurl::test_curl_multi_add_handle() {
225 Object mh
= f_curl_multi_init();
226 Variant c1
= f_curl_init(String(get_request_uri()));
227 Variant c2
= f_curl_init(String(get_request_uri()));
228 f_curl_multi_add_handle(mh
, c1
);
229 f_curl_multi_add_handle(mh
, c2
);
233 bool TestExtCurl::test_curl_multi_remove_handle() {
234 Object mh
= f_curl_multi_init();
235 Variant c1
= f_curl_init(String(get_request_uri()));
236 Variant c2
= f_curl_init(String(get_request_uri()));
237 f_curl_multi_add_handle(mh
, c1
);
238 f_curl_multi_add_handle(mh
, c2
);
239 f_curl_multi_remove_handle(mh
, c1
);
243 bool TestExtCurl::test_curl_multi_exec() {
244 Object mh
= f_curl_multi_init();
245 Variant c1
= f_curl_init(String(get_request_uri()));
246 Variant c2
= f_curl_init(String(get_request_uri()));
247 f_curl_setopt(c1
, k_CURLOPT_RETURNTRANSFER
, true);
248 f_curl_setopt(c2
, k_CURLOPT_RETURNTRANSFER
, true);
249 f_curl_multi_add_handle(mh
, c1
);
250 f_curl_multi_add_handle(mh
, c2
);
252 Variant still_running
;
254 f_curl_multi_exec(mh
, ref(still_running
));
255 } while (more(still_running
, 0));
260 bool TestExtCurl::test_curl_multi_select() {
261 Object mh
= f_curl_multi_init();
262 Variant c1
= f_curl_init(String(get_request_uri()));
263 Variant c2
= f_curl_init(String(get_request_uri()));
264 f_curl_multi_add_handle(mh
, c1
);
265 f_curl_multi_add_handle(mh
, c2
);
266 VS(f_curl_multi_select(mh
), 0);
270 bool TestExtCurl::test_curl_multi_getcontent() {
271 Object mh
= f_curl_multi_init();
272 Variant c1
= f_curl_init(String(get_request_uri()));
273 Variant c2
= f_curl_init(String(get_request_uri()));
274 f_curl_setopt(c1
, k_CURLOPT_RETURNTRANSFER
, true);
275 f_curl_setopt(c2
, k_CURLOPT_RETURNTRANSFER
, true);
276 f_curl_multi_add_handle(mh
, c1
);
277 f_curl_multi_add_handle(mh
, c2
);
279 Variant still_running
;
281 f_curl_multi_exec(mh
, ref(still_running
));
282 } while (more(still_running
, 0));
284 VS(f_curl_multi_getcontent(c1
), "OK");
285 VS(f_curl_multi_getcontent(c1
), "OK");
286 VS(f_curl_multi_getcontent(c2
), "OK");
287 VS(f_curl_multi_getcontent(c2
), "OK");
291 bool TestExtCurl::test_curl_multi_info_read() {
292 Object mh
= f_curl_multi_init();
293 Variant c1
= f_curl_init(String(get_request_uri()));
294 Variant c2
= f_curl_init(String(get_request_uri()));
295 f_curl_setopt(c1
, k_CURLOPT_RETURNTRANSFER
, true);
296 f_curl_setopt(c2
, k_CURLOPT_RETURNTRANSFER
, true);
297 f_curl_multi_add_handle(mh
, c1
);
298 f_curl_multi_add_handle(mh
, c2
);
300 Variant still_running
;
302 f_curl_multi_exec(mh
, ref(still_running
));
303 } while (more(still_running
, 0));
305 Variant ret
= f_curl_multi_info_read(mh
);
306 VS(ret
["result"], 0);
310 bool TestExtCurl::test_curl_multi_close() {
311 Object mh
= f_curl_multi_init();
312 Variant c1
= f_curl_init(String(get_request_uri()));
313 Variant c2
= f_curl_init(String(get_request_uri()));
314 f_curl_setopt(c1
, k_CURLOPT_RETURNTRANSFER
, true);
315 f_curl_setopt(c2
, k_CURLOPT_RETURNTRANSFER
, true);
316 f_curl_multi_add_handle(mh
, c1
);
317 f_curl_multi_add_handle(mh
, c2
);
319 Variant still_running
;
321 f_curl_multi_exec(mh
, ref(still_running
));
322 } while (more(still_running
, 0));
324 f_curl_multi_close(mh
);
328 bool TestExtCurl::test_evhttp_set_cache() {
329 f_evhttp_set_cache("localhost", 4, s_server_port
);
330 for (int i
= 0; i
< 10; i
++) {
331 Variant ret
= f_evhttp_get(String(get_request_uri()),
332 CREATE_VECTOR1("ECHO: foo"));
333 VS(ret
["code"], 200);
334 VS(ret
["response"], "OK");
335 VS(ret
["headers"][0], "ECHOED: foo");
336 VS(ret
["headers"][4], "Content-Length: 2");
342 bool TestExtCurl::test_evhttp_get() {
343 Variant ret
= f_evhttp_get(String(get_request_uri()),
344 CREATE_VECTOR1("ECHO: foo"));
345 VS(ret
["code"], 200);
346 VS(ret
["response"], "OK");
347 VS(ret
["headers"][0], "ECHOED: foo");
348 VS(ret
["headers"][4], "Content-Length: 2");
352 bool TestExtCurl::test_evhttp_post() {
353 Variant ret
= f_evhttp_post(String(get_request_uri()), "echo",
354 CREATE_VECTOR1("ECHO: foo"));
355 VS(ret
["code"], 200);
356 VS(ret
["response"], "POST: echo");
357 VS(ret
["headers"][0], "ECHOED: foo");
358 VS(ret
["headers"][4], "Content-Length: 10");
362 bool TestExtCurl::test_evhttp_post_gzip() {
363 // we fill up 2k to avoid the "oh it's < 1000 bytes, forget compression"
364 // logic in Transport's implementation.
365 char fullPostBody
[2048];
366 memcpy(fullPostBody
, "POST: ", 6);
367 char* postBody
= fullPostBody
+ 6;
368 memset(postBody
, 'a', sizeof(fullPostBody
) - 7);
369 fullPostBody
[sizeof(fullPostBody
) - 1] = '\0';
370 Variant ret
= f_evhttp_post(String(get_request_uri()), postBody
,
371 CREATE_VECTOR2("ECHO: foo",
372 "Accept-Encoding: gzip"));
373 VS(ret
["code"], 200);
374 VS(ret
["response"], fullPostBody
);
375 VS(ret
["headers"][0], "ECHOED: foo");
376 VS(ret
["headers"][1], "Content-Encoding: gzip");
380 bool TestExtCurl::test_evhttp_async_get() {
381 Variant ret
= f_evhttp_async_get(String(get_request_uri()),
382 CREATE_VECTOR1("ECHO: foo"));
383 ret
= f_evhttp_recv(ret
);
384 VS(ret
["code"], 200);
385 VS(ret
["response"], "OK");
386 VS(ret
["headers"][0], "ECHOED: foo");
387 VS(ret
["headers"][4], "Content-Length: 2");
391 bool TestExtCurl::test_evhttp_async_post() {
392 Variant ret
= f_evhttp_async_post(String(get_request_uri()), "echo",
393 CREATE_VECTOR1("ECHO: foo"));
394 ret
= f_evhttp_recv(ret
);
395 VS(ret
["code"], 200);
396 VS(ret
["response"], "POST: echo");
397 VS(ret
["headers"][0], "ECHOED: foo");
398 VS(ret
["headers"][4], "Content-Length: 10");
402 bool TestExtCurl::test_evhttp_recv() {
403 // tested in test_evhttp_async_get() and test_evhttp_async_post()