f29ee5314d
Too many ways to shoot self in foot with this gem.
406 linhas
12 KiB
C++
406 linhas
12 KiB
C++
/*
|
|
+----------------------------------------------------------------------+
|
|
| HipHop for PHP |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
|
|
+----------------------------------------------------------------------+
|
|
| This source file is subject to version 3.01 of the PHP license, |
|
|
| that is bundled with this package in the file LICENSE, and is |
|
|
| available through the world-wide-web at the following url: |
|
|
| http://www.php.net/license/3_01.txt |
|
|
| If you did not receive a copy of the PHP license and are unable to |
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
| license@php.net so we can mail you a copy immediately. |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
#include <test/test_ext_curl.h>
|
|
#include <runtime/ext/ext_curl.h>
|
|
#include <runtime/ext/ext_output.h>
|
|
#include <runtime/ext/ext_zlib.h>
|
|
#include <runtime/base/server/libevent_server.h>
|
|
|
|
#define PORT_MIN 7100
|
|
#define PORT_MAX 7120
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
class TestCurlRequestHandler : public RequestHandler {
|
|
public:
|
|
// implementing RequestHandler
|
|
virtual void handleRequest(Transport *transport) {
|
|
transport->addHeader("ECHOED", transport->getHeader("ECHO").c_str());
|
|
|
|
if (transport->getMethod() == Transport::POST) {
|
|
int len = 0;
|
|
const void *data = transport->getPostData(len);
|
|
String res = "POST: ";
|
|
res += String((char*)data, len, CopyString);
|
|
transport->sendString(res.c_str());
|
|
} else {
|
|
transport->sendString("OK");
|
|
}
|
|
}
|
|
};
|
|
|
|
static int s_server_port = 0;
|
|
|
|
static std::string get_request_uri() {
|
|
return "http://localhost:" + boost::lexical_cast<string>(s_server_port) +
|
|
"/request";
|
|
}
|
|
|
|
static ServerPtr runServer() {
|
|
for (s_server_port = PORT_MIN; s_server_port <= PORT_MAX; s_server_port++) {
|
|
try {
|
|
ServerPtr server(new TypedServer<LibEventServer, TestCurlRequestHandler>
|
|
("127.0.0.1", s_server_port, 4, -1));
|
|
server->start();
|
|
return server;
|
|
|
|
} catch (const FailedToListenException& e) {
|
|
if (s_server_port == PORT_MAX) throw;
|
|
}
|
|
}
|
|
return ServerPtr();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool TestExtCurl::RunTests(const std::string &which) {
|
|
bool ret = true;
|
|
|
|
DECLARE_TEST_FUNCTIONS("function curl_write_func($s1, $s2) {"
|
|
" print 'curl_write_func called with ';"
|
|
" print $s2;"
|
|
" return strlen($s2);"
|
|
"}");
|
|
|
|
ServerPtr server = runServer();
|
|
|
|
RUN_TEST(test_curl_init);
|
|
RUN_TEST(test_curl_copy_handle);
|
|
RUN_TEST(test_curl_version);
|
|
RUN_TEST(test_curl_setopt);
|
|
RUN_TEST(test_curl_setopt_array);
|
|
RUN_TEST(test_curl_exec);
|
|
RUN_TEST(test_curl_getinfo);
|
|
RUN_TEST(test_curl_errno);
|
|
RUN_TEST(test_curl_error);
|
|
RUN_TEST(test_curl_close);
|
|
RUN_TEST(test_curl_multi_init);
|
|
RUN_TEST(test_curl_multi_add_handle);
|
|
RUN_TEST(test_curl_multi_remove_handle);
|
|
RUN_TEST(test_curl_multi_exec);
|
|
RUN_TEST(test_curl_multi_select);
|
|
RUN_TEST(test_curl_multi_getcontent);
|
|
RUN_TEST(test_curl_multi_info_read);
|
|
RUN_TEST(test_curl_multi_close);
|
|
RUN_TEST(test_evhttp_set_cache);
|
|
RUN_TEST(test_evhttp_get);
|
|
RUN_TEST(test_evhttp_post);
|
|
RUN_TEST(test_evhttp_post_gzip);
|
|
RUN_TEST(test_evhttp_async_get);
|
|
RUN_TEST(test_evhttp_async_post);
|
|
RUN_TEST(test_evhttp_recv);
|
|
|
|
server->stop();
|
|
|
|
return ret;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool TestExtCurl::test_curl_init() {
|
|
Variant c = f_curl_init();
|
|
VS(f_curl_errno(c), 0);
|
|
VS(f_curl_error(c), "");
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_copy_handle() {
|
|
Variant c = f_curl_init();
|
|
f_curl_setopt(c, k_CURLOPT_URL, String(get_request_uri()));
|
|
f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
|
|
Variant cpy = f_curl_copy_handle(c);
|
|
f_curl_close(c); // to test cpy is still working fine
|
|
Variant res = f_curl_exec(cpy);
|
|
if (res.toString() != "OK") {
|
|
// XXX: t1782098
|
|
return CountSkip();
|
|
}
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_version() {
|
|
Variant ret = f_curl_version();
|
|
VERIFY(!ret["protocols"].toArray().empty());
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_setopt() {
|
|
Variant c = f_curl_init();
|
|
f_curl_setopt(c, k_CURLOPT_URL, String(get_request_uri()));
|
|
f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
|
|
Variant res = f_curl_exec(c);
|
|
VS(res, "OK");
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_setopt_array() {
|
|
Variant c = f_curl_init();
|
|
f_curl_setopt_array
|
|
(c,
|
|
CREATE_MAP2(k_CURLOPT_URL, String(get_request_uri()),
|
|
k_CURLOPT_RETURNTRANSFER, true));
|
|
Variant res = f_curl_exec(c);
|
|
VS(res, "OK");
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_exec() {
|
|
{
|
|
Variant c = f_curl_init(String(get_request_uri()));
|
|
f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
|
|
Variant res = f_curl_exec(c);
|
|
VS(res, "OK");
|
|
}
|
|
{
|
|
Variant c = f_curl_init(String(get_request_uri()));
|
|
f_curl_setopt(c, k_CURLOPT_WRITEFUNCTION, "curl_write_func");
|
|
f_ob_start();
|
|
f_curl_exec(c);
|
|
String res = f_ob_get_contents();
|
|
VS(res, "curl_write_func called with OK");
|
|
f_ob_end_clean();
|
|
}
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_getinfo() {
|
|
Variant c = f_curl_init(String(get_request_uri()));
|
|
f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
|
|
f_curl_exec(c);
|
|
Variant ret = f_curl_getinfo(c);
|
|
VS(ret["url"], String(get_request_uri()));
|
|
ret = f_curl_getinfo(c, k_CURLINFO_EFFECTIVE_URL);
|
|
VS(ret, String(get_request_uri()));
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_errno() {
|
|
Variant c = f_curl_init("http://www.thereisnosuchanurl");
|
|
f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
|
|
f_curl_exec(c);
|
|
Variant err = f_curl_errno(c);
|
|
VS(err, k_CURLE_COULDNT_RESOLVE_HOST);
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_error() {
|
|
Variant c = f_curl_init("http://www.thereisnosuchanurl");
|
|
f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
|
|
f_curl_exec(c);
|
|
Variant err = f_curl_error(c);
|
|
VERIFY(err == "Couldn't resolve host 'www.thereisnosuchanurl'" ||
|
|
err == "Could not resolve host: www.thereisnosuchanurl"
|
|
" (Domain name not found)");
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_close() {
|
|
Variant c = f_curl_init(String(get_request_uri()));
|
|
f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
|
|
f_curl_exec(c);
|
|
f_curl_close(c);
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_multi_init() {
|
|
f_curl_multi_init();
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_multi_add_handle() {
|
|
Object mh = f_curl_multi_init();
|
|
Variant c1 = f_curl_init(String(get_request_uri()));
|
|
Variant c2 = f_curl_init(String(get_request_uri()));
|
|
f_curl_multi_add_handle(mh, c1);
|
|
f_curl_multi_add_handle(mh, c2);
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_multi_remove_handle() {
|
|
Object mh = f_curl_multi_init();
|
|
Variant c1 = f_curl_init(String(get_request_uri()));
|
|
Variant c2 = f_curl_init(String(get_request_uri()));
|
|
f_curl_multi_add_handle(mh, c1);
|
|
f_curl_multi_add_handle(mh, c2);
|
|
f_curl_multi_remove_handle(mh, c1);
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_multi_exec() {
|
|
Object mh = f_curl_multi_init();
|
|
Variant c1 = f_curl_init(String(get_request_uri()));
|
|
Variant c2 = f_curl_init(String(get_request_uri()));
|
|
f_curl_setopt(c1, k_CURLOPT_RETURNTRANSFER, true);
|
|
f_curl_setopt(c2, k_CURLOPT_RETURNTRANSFER, true);
|
|
f_curl_multi_add_handle(mh, c1);
|
|
f_curl_multi_add_handle(mh, c2);
|
|
|
|
Variant still_running;
|
|
do {
|
|
f_curl_multi_exec(mh, ref(still_running));
|
|
} while (more(still_running, 0));
|
|
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_multi_select() {
|
|
Object mh = f_curl_multi_init();
|
|
Variant c1 = f_curl_init(String(get_request_uri()));
|
|
Variant c2 = f_curl_init(String(get_request_uri()));
|
|
f_curl_multi_add_handle(mh, c1);
|
|
f_curl_multi_add_handle(mh, c2);
|
|
VS(f_curl_multi_select(mh), 0);
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_multi_getcontent() {
|
|
Object mh = f_curl_multi_init();
|
|
Variant c1 = f_curl_init(String(get_request_uri()));
|
|
Variant c2 = f_curl_init(String(get_request_uri()));
|
|
f_curl_setopt(c1, k_CURLOPT_RETURNTRANSFER, true);
|
|
f_curl_setopt(c2, k_CURLOPT_RETURNTRANSFER, true);
|
|
f_curl_multi_add_handle(mh, c1);
|
|
f_curl_multi_add_handle(mh, c2);
|
|
|
|
Variant still_running;
|
|
do {
|
|
f_curl_multi_exec(mh, ref(still_running));
|
|
} while (more(still_running, 0));
|
|
|
|
VS(f_curl_multi_getcontent(c1), "OK");
|
|
VS(f_curl_multi_getcontent(c1), "OK");
|
|
VS(f_curl_multi_getcontent(c2), "OK");
|
|
VS(f_curl_multi_getcontent(c2), "OK");
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_multi_info_read() {
|
|
Object mh = f_curl_multi_init();
|
|
Variant c1 = f_curl_init(String(get_request_uri()));
|
|
Variant c2 = f_curl_init(String(get_request_uri()));
|
|
f_curl_setopt(c1, k_CURLOPT_RETURNTRANSFER, true);
|
|
f_curl_setopt(c2, k_CURLOPT_RETURNTRANSFER, true);
|
|
f_curl_multi_add_handle(mh, c1);
|
|
f_curl_multi_add_handle(mh, c2);
|
|
|
|
Variant still_running;
|
|
do {
|
|
f_curl_multi_exec(mh, ref(still_running));
|
|
} while (more(still_running, 0));
|
|
|
|
Variant ret = f_curl_multi_info_read(mh);
|
|
VS(ret["result"], 0);
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_curl_multi_close() {
|
|
Object mh = f_curl_multi_init();
|
|
Variant c1 = f_curl_init(String(get_request_uri()));
|
|
Variant c2 = f_curl_init(String(get_request_uri()));
|
|
f_curl_setopt(c1, k_CURLOPT_RETURNTRANSFER, true);
|
|
f_curl_setopt(c2, k_CURLOPT_RETURNTRANSFER, true);
|
|
f_curl_multi_add_handle(mh, c1);
|
|
f_curl_multi_add_handle(mh, c2);
|
|
|
|
Variant still_running;
|
|
do {
|
|
f_curl_multi_exec(mh, ref(still_running));
|
|
} while (more(still_running, 0));
|
|
|
|
f_curl_multi_close(mh);
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_evhttp_set_cache() {
|
|
f_evhttp_set_cache("localhost", 4, s_server_port);
|
|
for (int i = 0; i < 10; i++) {
|
|
Variant ret = f_evhttp_get(String(get_request_uri()),
|
|
CREATE_VECTOR1("ECHO: foo"));
|
|
VS(ret["code"], 200);
|
|
VS(ret["response"], "OK");
|
|
VS(ret["headers"][0], "ECHOED: foo");
|
|
VS(ret["headers"][4], "Content-Length: 2");
|
|
}
|
|
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_evhttp_get() {
|
|
Variant ret = f_evhttp_get(String(get_request_uri()),
|
|
CREATE_VECTOR1("ECHO: foo"));
|
|
VS(ret["code"], 200);
|
|
VS(ret["response"], "OK");
|
|
VS(ret["headers"][0], "ECHOED: foo");
|
|
VS(ret["headers"][4], "Content-Length: 2");
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_evhttp_post() {
|
|
Variant ret = f_evhttp_post(String(get_request_uri()), "echo",
|
|
CREATE_VECTOR1("ECHO: foo"));
|
|
VS(ret["code"], 200);
|
|
VS(ret["response"], "POST: echo");
|
|
VS(ret["headers"][0], "ECHOED: foo");
|
|
VS(ret["headers"][4], "Content-Length: 10");
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_evhttp_post_gzip() {
|
|
// we fill up 2k to avoid the "oh it's < 1000 bytes, forget compression"
|
|
// logic in Transport's implementation.
|
|
char fullPostBody[2048];
|
|
memcpy(fullPostBody, "POST: ", 6);
|
|
char* postBody = fullPostBody + 6;
|
|
memset(postBody, 'a', sizeof(fullPostBody) - 7);
|
|
fullPostBody[sizeof(fullPostBody) - 1] = '\0';
|
|
Variant ret = f_evhttp_post(String(get_request_uri()), postBody,
|
|
CREATE_VECTOR2("ECHO: foo",
|
|
"Accept-Encoding: gzip"));
|
|
VS(ret["code"], 200);
|
|
VS(ret["response"], fullPostBody);
|
|
VS(ret["headers"][0], "ECHOED: foo");
|
|
VS(ret["headers"][1], "Content-Encoding: gzip");
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_evhttp_async_get() {
|
|
Variant ret = f_evhttp_async_get(String(get_request_uri()),
|
|
CREATE_VECTOR1("ECHO: foo"));
|
|
ret = f_evhttp_recv(ret);
|
|
VS(ret["code"], 200);
|
|
VS(ret["response"], "OK");
|
|
VS(ret["headers"][0], "ECHOED: foo");
|
|
VS(ret["headers"][4], "Content-Length: 2");
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_evhttp_async_post() {
|
|
Variant ret = f_evhttp_async_post(String(get_request_uri()), "echo",
|
|
CREATE_VECTOR1("ECHO: foo"));
|
|
ret = f_evhttp_recv(ret);
|
|
VS(ret["code"], 200);
|
|
VS(ret["response"], "POST: echo");
|
|
VS(ret["headers"][0], "ECHOED: foo");
|
|
VS(ret["headers"][4], "Content-Length: 10");
|
|
return Count(true);
|
|
}
|
|
|
|
bool TestExtCurl::test_evhttp_recv() {
|
|
// tested in test_evhttp_async_get() and test_evhttp_async_post()
|
|
return Count(true);
|
|
}
|