Permalink
Browse files

http, feat: support keep-alive in HttpClient.

  • Loading branch information...
xicilion committed Jun 20, 2018
1 parent d6b7d8a commit 1adbf8dfb9f11f975a64531e58a719009280f313
View
@@ -21,6 +21,8 @@ class HttpClient : public HttpClient_base {
, m_enableCookie(true)
, m_autoRedirect(true)
, m_maxBodySize(-1)
, m_poolSize(128)
, m_poolTimeout(10000)
{
m_cookies = new NArray();
m_userAgent = "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36";
@@ -39,6 +41,10 @@ class HttpClient : public HttpClient_base {
virtual result_t set_maxBodySize(int32_t newVal);
virtual result_t get_userAgent(exlib::string& retVal);
virtual result_t set_userAgent(exlib::string newVal);
virtual result_t get_poolSize(int32_t& retVal);
virtual result_t set_poolSize(int32_t newVal);
virtual result_t get_poolTimeout(int32_t& retVal);
virtual result_t set_poolTimeout(int32_t newVal);
virtual result_t request(Stream_base* conn, HttpRequest_base* req, obj_ptr<HttpResponse_base>& retVal, AsyncEvent* ac);
virtual result_t request(exlib::string method, exlib::string url, v8::Local<v8::Object> opts, obj_ptr<HttpResponse_base>& retVal, AsyncEvent* ac);
virtual result_t get(exlib::string url, v8::Local<v8::Object> headers, obj_ptr<HttpResponse_base>& retVal, AsyncEvent* ac);
@@ -58,12 +64,77 @@ class HttpClient : public HttpClient_base {
return m_userAgent;
}
public:
void clean_coon(date_t d)
{
std::vector<obj_ptr<Conn>> keep_conns;
m_lock.lock();
while (((int32_t)m_conns.size() > m_poolSize)
|| (m_conns.size() && d.diff(m_conns[0]->d) > (double)m_poolTimeout)) {
keep_conns.push_back(m_conns[0]);
m_conns.erase(m_conns.begin());
}
m_lock.unlock();
}
void save_conn(exlib::string url, Stream_base* _conn)
{
obj_ptr<Conn> conn = new Conn();
conn->d.now();
conn->url = url;
conn->conn = _conn;
clean_coon(conn->d);
m_lock.lock();
m_conns.push_back(conn);
if ((int32_t)m_conns.size() > m_poolSize) {
conn = m_conns[0];
m_conns.erase(m_conns.begin());
}
m_lock.unlock();
}
bool get_conn(exlib::string url, obj_ptr<Stream_base>& _conn)
{
date_t d;
d.now();
clean_coon(d);
m_lock.lock();
for (std::vector<obj_ptr<Conn>>::iterator it = m_conns.begin(); it != m_conns.end(); it++)
if ((*it)->url == url) {
_conn = (*it)->conn;
m_conns.erase(it);
m_lock.unlock();
return true;
}
m_lock.unlock();
return false;
}
private:
class Conn : public obj_base {
public:
date_t d;
exlib::string url;
obj_ptr<Stream_base> conn;
};
std::vector<obj_ptr<Conn>> m_conns;
int32_t m_poolSize;
int32_t m_poolTimeout;
private:
result_t update(HttpCookie_base* cookie);
private:
obj_ptr<NArray> m_cookies;
exlib::spinlock m_lock_cookies;
exlib::spinlock m_lock;
int32_t m_timeout;
bool m_enableCookie;
bool m_autoRedirect;
@@ -37,6 +37,10 @@ class HttpClient_base : public object_base {
virtual result_t set_autoRedirect(bool newVal) = 0;
virtual result_t get_userAgent(exlib::string& retVal) = 0;
virtual result_t set_userAgent(exlib::string newVal) = 0;
virtual result_t get_poolSize(int32_t& retVal) = 0;
virtual result_t set_poolSize(int32_t newVal) = 0;
virtual result_t get_poolTimeout(int32_t& retVal) = 0;
virtual result_t set_poolTimeout(int32_t newVal) = 0;
virtual result_t request(Stream_base* conn, HttpRequest_base* req, obj_ptr<HttpResponse_base>& retVal, AsyncEvent* ac) = 0;
virtual result_t request(exlib::string method, exlib::string url, v8::Local<v8::Object> opts, obj_ptr<HttpResponse_base>& retVal, AsyncEvent* ac) = 0;
virtual result_t get(exlib::string url, v8::Local<v8::Object> opts, obj_ptr<HttpResponse_base>& retVal, AsyncEvent* ac) = 0;
@@ -62,6 +66,10 @@ class HttpClient_base : public object_base {
static void s_set_autoRedirect(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);
static void s_get_userAgent(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args);
static void s_set_userAgent(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);
static void s_get_poolSize(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args);
static void s_set_poolSize(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);
static void s_get_poolTimeout(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args);
static void s_set_poolTimeout(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);
static void s_request(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_get(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_post(const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -108,7 +116,9 @@ inline ClassInfo& HttpClient_base::class_info()
{ "maxBodySize", s_get_maxBodySize, s_set_maxBodySize, false },
{ "enableCookie", s_get_enableCookie, s_set_enableCookie, false },
{ "autoRedirect", s_get_autoRedirect, s_set_autoRedirect, false },
{ "userAgent", s_get_userAgent, s_set_userAgent, false }
{ "userAgent", s_get_userAgent, s_set_userAgent, false },
{ "poolSize", s_get_poolSize, s_set_poolSize, false },
{ "poolTimeout", s_get_poolTimeout, s_set_poolTimeout, false }
};
static ClassData s_cd = {
@@ -280,6 +290,56 @@ inline void HttpClient_base::s_set_userAgent(v8::Local<v8::Name> property, v8::L
PROPERTY_SET_LEAVE();
}
inline void HttpClient_base::s_get_poolSize(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args)
{
int32_t vr;
METHOD_NAME("HttpClient.poolSize");
METHOD_INSTANCE(HttpClient_base);
PROPERTY_ENTER();
hr = pInst->get_poolSize(vr);
METHOD_RETURN();
}
inline void HttpClient_base::s_set_poolSize(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args)
{
METHOD_NAME("HttpClient.poolSize");
METHOD_INSTANCE(HttpClient_base);
PROPERTY_ENTER();
PROPERTY_VAL(int32_t);
hr = pInst->set_poolSize(v0);
PROPERTY_SET_LEAVE();
}
inline void HttpClient_base::s_get_poolTimeout(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args)
{
int32_t vr;
METHOD_NAME("HttpClient.poolTimeout");
METHOD_INSTANCE(HttpClient_base);
PROPERTY_ENTER();
hr = pInst->get_poolTimeout(vr);
METHOD_RETURN();
}
inline void HttpClient_base::s_set_poolTimeout(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args)
{
METHOD_NAME("HttpClient.poolTimeout");
METHOD_INSTANCE(HttpClient_base);
PROPERTY_ENTER();
PROPERTY_VAL(int32_t);
hr = pInst->set_poolTimeout(v0);
PROPERTY_SET_LEAVE();
}
inline void HttpClient_base::s_request(const v8::FunctionCallbackInfo<v8::Value>& args)
{
obj_ptr<HttpResponse_base> vr;
View
@@ -39,10 +39,14 @@ class http_base : public object_base {
static result_t set_enableCookie(bool newVal);
static result_t get_autoRedirect(bool& retVal);
static result_t set_autoRedirect(bool newVal);
virtual result_t get_maxBodySize(int32_t& retVal) = 0;
virtual result_t set_maxBodySize(int32_t newVal) = 0;
static result_t get_maxBodySize(int32_t& retVal);
static result_t set_maxBodySize(int32_t newVal);
static result_t get_userAgent(exlib::string& retVal);
static result_t set_userAgent(exlib::string newVal);
static result_t get_poolSize(int32_t& retVal);
static result_t set_poolSize(int32_t newVal);
static result_t get_poolTimeout(int32_t& retVal);
static result_t set_poolTimeout(int32_t newVal);
static result_t fileHandler(exlib::string root, v8::Local<v8::Object> mimes, bool autoIndex, obj_ptr<Handler_base>& retVal);
static result_t request(Stream_base* conn, HttpRequest_base* req, obj_ptr<HttpResponse_base>& retVal, AsyncEvent* ac);
static result_t request(exlib::string method, exlib::string url, v8::Local<v8::Object> opts, obj_ptr<HttpResponse_base>& retVal, AsyncEvent* ac);
@@ -76,6 +80,10 @@ class http_base : public object_base {
static void s_set_maxBodySize(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);
static void s_get_userAgent(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args);
static void s_set_userAgent(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);
static void s_get_poolSize(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args);
static void s_set_poolSize(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);
static void s_get_poolTimeout(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args);
static void s_set_poolTimeout(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);
static void s_fileHandler(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_request(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_get(const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -140,8 +148,10 @@ inline ClassInfo& http_base::class_info()
{ "timeout", s_get_timeout, s_set_timeout, true },
{ "enableCookie", s_get_enableCookie, s_set_enableCookie, true },
{ "autoRedirect", s_get_autoRedirect, s_set_autoRedirect, true },
{ "maxBodySize", s_get_maxBodySize, s_set_maxBodySize, false },
{ "userAgent", s_get_userAgent, s_set_userAgent, true }
{ "maxBodySize", s_get_maxBodySize, s_set_maxBodySize, true },
{ "userAgent", s_get_userAgent, s_set_userAgent, true },
{ "poolSize", s_get_poolSize, s_set_poolSize, true },
{ "poolTimeout", s_get_poolTimeout, s_set_poolTimeout, true }
};
static ClassData s_cd = {
@@ -252,22 +262,20 @@ inline void http_base::s_get_maxBodySize(v8::Local<v8::Name> property, const v8:
int32_t vr;
METHOD_NAME("http.maxBodySize");
METHOD_INSTANCE(http_base);
PROPERTY_ENTER();
hr = pInst->get_maxBodySize(vr);
hr = get_maxBodySize(vr);
METHOD_RETURN();
}
inline void http_base::s_set_maxBodySize(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args)
{
METHOD_NAME("http.maxBodySize");
METHOD_INSTANCE(http_base);
PROPERTY_ENTER();
PROPERTY_VAL(int32_t);
hr = pInst->set_maxBodySize(v0);
hr = set_maxBodySize(v0);
PROPERTY_SET_LEAVE();
}
@@ -295,6 +303,52 @@ inline void http_base::s_set_userAgent(v8::Local<v8::Name> property, v8::Local<v
PROPERTY_SET_LEAVE();
}
inline void http_base::s_get_poolSize(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args)
{
int32_t vr;
METHOD_NAME("http.poolSize");
PROPERTY_ENTER();
hr = get_poolSize(vr);
METHOD_RETURN();
}
inline void http_base::s_set_poolSize(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args)
{
METHOD_NAME("http.poolSize");
PROPERTY_ENTER();
PROPERTY_VAL(int32_t);
hr = set_poolSize(v0);
PROPERTY_SET_LEAVE();
}
inline void http_base::s_get_poolTimeout(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args)
{
int32_t vr;
METHOD_NAME("http.poolTimeout");
PROPERTY_ENTER();
hr = get_poolTimeout(vr);
METHOD_RETURN();
}
inline void http_base::s_set_poolTimeout(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args)
{
METHOD_NAME("http.poolTimeout");
PROPERTY_ENTER();
PROPERTY_VAL(int32_t);
hr = set_poolTimeout(v0);
PROPERTY_SET_LEAVE();
}
inline void http_base::s_fileHandler(const v8::FunctionCallbackInfo<v8::Value>& args)
{
obj_ptr<Handler_base> vr;
Oops, something went wrong.

0 comments on commit 1adbf8d

Please sign in to comment.