242 lines
9.0 KiB
C++
242 lines
9.0 KiB
C++
#include "precompile.h"
|
|
|
|
#include <a8/sysutils.h>
|
|
#include <a8/mutable_xobject.h>
|
|
#include <a8/openssl.h>
|
|
|
|
#include <f8/udplog.h>
|
|
#include <f8/jsonhttprequest.h>
|
|
|
|
#include "httpproxy.h"
|
|
#include "app.h"
|
|
#include "jsondatamgr.h"
|
|
#include "handlermgr.h"
|
|
|
|
#include "f8/httpclientpool.h"
|
|
|
|
struct HttpProxyRequest
|
|
{
|
|
std::string req_id;
|
|
f8::HttpProxyCb cb;
|
|
std::string url;
|
|
std::shared_ptr<a8::MutableXObject> url_params;
|
|
long long add_tick = 0;
|
|
};
|
|
|
|
static void _ProxyCallback(std::shared_ptr<f8::JsonHttpRequest> request)
|
|
{
|
|
#ifdef MYDEBUG
|
|
f8::UdpLog::Instance()->Debug("ProxyCallbBack request:%s",
|
|
{
|
|
request->GetParams()->ToJsonStr()
|
|
});
|
|
#endif
|
|
std::string seq_id = request->GetParams()->Get("seq_id");
|
|
std::shared_ptr<HttpProxyRequest> req = HttpProxy::Instance()->GetRequest(seq_id);
|
|
if (req) {
|
|
a8::XObject data;
|
|
|
|
data.ReadFromJsonString(request->GetParams()->Get("data").GetString());
|
|
if (data.GetType() == a8::XOT_SIMPLE) {
|
|
data.ReadFromJsonString("{}");
|
|
}
|
|
f8::HttpContext ctx;
|
|
if (request->GetParams()->HasKey("errcode") &&
|
|
request->GetParams()->Get("errcode").GetInt() == 0) {
|
|
req->cb(true, &data, &ctx);
|
|
} else {
|
|
req->cb(false, request->GetParams().get(), &ctx);
|
|
}
|
|
HttpProxy::Instance()->DestoryRequest(req);
|
|
}
|
|
}
|
|
|
|
void HttpProxy::Init()
|
|
{
|
|
request_prefix_ = "game2006_" + a8::XValue(a8::GetMilliSecond()).GetString() + "_";
|
|
HandlerMgr::Instance()->RegisterGMMsgHandler("Proxy@callback", _ProxyCallback);
|
|
}
|
|
|
|
void HttpProxy::UnInit()
|
|
{
|
|
request_hash_.clear();
|
|
}
|
|
|
|
std::string HttpProxy::HttpGet(
|
|
f8::HttpProxyCb cb,
|
|
const std::string& url,
|
|
std::shared_ptr<a8::MutableXObject> url_params
|
|
)
|
|
{
|
|
if (f8::App::Instance()->Terminated()) {
|
|
return "";
|
|
}
|
|
AddSignParams(url, url_params, "");
|
|
std::shared_ptr<HttpProxyRequest> request = std::make_shared<HttpProxyRequest>();
|
|
request->req_id = CreateRequestId();
|
|
request->cb = cb;
|
|
request->url = url;
|
|
request->url_params = url_params;
|
|
request->add_tick = a8::XGetTickCount();
|
|
if (request_hash_.find(request->req_id) != request_hash_.end()) {
|
|
abort();
|
|
}
|
|
request_hash_[request->req_id] = request;
|
|
|
|
auto proxy_url_params = a8::MutableXObject::CreateObject();
|
|
proxy_url_params->SetVal("seq_id", request->req_id);
|
|
proxy_url_params->SetVal("target_url", std::string(url));
|
|
proxy_url_params->SetVal("params", url_params->ToJsonStr());
|
|
proxy_url_params->SetVal("cb_url", a8::Format("http://%s:%d/webapp/index.php?c=Proxy&a=callback",
|
|
{
|
|
JsonDataMgr::Instance()->ip,
|
|
JsonDataMgr::Instance()->listen_port
|
|
}));
|
|
std::string proxy_url;
|
|
JsonDataMgr::Instance()->GetHttpGetProxyUrl(proxy_url);
|
|
f8::HttpClientPool::Instance()->HttpGet
|
|
(
|
|
[request] (bool ok, a8::XObject* rsp_obj, f8::HttpContext* ctx)
|
|
{
|
|
long long cost_time = a8::XGetTickCount() - request->add_tick;
|
|
if (ok) {
|
|
#ifdef MYDEBUG
|
|
f8::UdpLog::Instance()->Debug("ProxyHttpGet ok cost_time:%d url:%s params:%s",
|
|
{
|
|
cost_time,
|
|
request->url,
|
|
request->url_params->ToJsonStr(),
|
|
});
|
|
#endif
|
|
} else {
|
|
f8::UdpLog::Instance()->Warning("ProxyHttpGet error cost_time:%d url:%s params:%s response:%s",
|
|
{
|
|
cost_time,
|
|
request->url,
|
|
request->url_params->ToJsonStr(),
|
|
ctx->response
|
|
});
|
|
request->cb(false, rsp_obj, ctx);
|
|
HttpProxy::Instance()->DestoryRequest(request);
|
|
}
|
|
},
|
|
proxy_url.c_str(),
|
|
*proxy_url_params,
|
|
rand() % MAX_SYS_HTTP_NUM
|
|
);
|
|
return request->req_id;
|
|
}
|
|
|
|
std::string HttpProxy::HttpPost(
|
|
f8::HttpProxyCb cb,
|
|
const std::string& url,
|
|
std::shared_ptr<a8::MutableXObject> url_params,
|
|
const std::string& content
|
|
)
|
|
{
|
|
if (f8::App::Instance()->Terminated()) {
|
|
return "";
|
|
}
|
|
AddSignParams(url, url_params, content);
|
|
std::shared_ptr<HttpProxyRequest> request = std::make_shared<HttpProxyRequest>();
|
|
request->req_id = CreateRequestId();
|
|
request->cb = cb;
|
|
request->url = url;
|
|
request->url_params = url_params;
|
|
request->add_tick = a8::XGetTickCount();
|
|
if (request_hash_.find(request->req_id) != request_hash_.end()) {
|
|
abort();
|
|
}
|
|
request_hash_[request->req_id] = request;
|
|
|
|
|
|
auto proxy_url_params = a8::MutableXObject::CreateObject();
|
|
proxy_url_params->SetVal("seq_id", request->req_id);
|
|
proxy_url_params->SetVal("target_url", std::string(url));
|
|
proxy_url_params->SetVal("params", url_params->ToJsonStr());
|
|
proxy_url_params->SetVal("cb_url", a8::Format("http://%s:%d/webapp/index.php?c=Proxy&a=callback",
|
|
{
|
|
JsonDataMgr::Instance()->ip,
|
|
JsonDataMgr::Instance()->listen_port
|
|
}));
|
|
auto http_headers = a8::MutableXObject::CreateArray();
|
|
http_headers->Push("Content-Type: application/json");
|
|
std::string proxy_url;
|
|
JsonDataMgr::Instance()->GetHttpPostProxyUrl(proxy_url);
|
|
f8::HttpClientPool::Instance()->HttpPost
|
|
(
|
|
[request] (bool ok, a8::XObject* rsp_obj, f8::HttpContext* ctx)
|
|
{
|
|
long long cost_time = a8::XGetTickCount() - request->add_tick;
|
|
if (ok) {
|
|
#ifdef MYDEBUG
|
|
f8::UdpLog::Instance()->Debug("ProxyHttpPost ok cost_time:%d url:%s params:%s",
|
|
{
|
|
cost_time,
|
|
request->url,
|
|
request->url_params->ToJsonStr(),
|
|
});
|
|
#endif
|
|
} else {
|
|
f8::UdpLog::Instance()->Warning("ProxyHttpPost error cost_time:%d url:%s params:%s response:%s",
|
|
{
|
|
cost_time,
|
|
request->url,
|
|
request->url_params->ToJsonStr(),
|
|
ctx->response
|
|
});
|
|
request->cb(false, rsp_obj, ctx);
|
|
HttpProxy::Instance()->DestoryRequest(request);
|
|
}
|
|
},
|
|
proxy_url.c_str(),
|
|
*proxy_url_params,
|
|
content,
|
|
rand() % MAX_SYS_HTTP_NUM,
|
|
http_headers.get()
|
|
);
|
|
return request->req_id;
|
|
}
|
|
|
|
std::string HttpProxy::CreateRequestId()
|
|
{
|
|
return request_prefix_ + f8::App::Instance()->NewGlobalUuid();
|
|
}
|
|
|
|
std::shared_ptr<HttpProxyRequest> HttpProxy::GetRequest(const std::string& req_id)
|
|
{
|
|
auto itr = request_hash_.find(req_id);
|
|
return itr != request_hash_.end() ? itr->second : nullptr;
|
|
}
|
|
|
|
void HttpProxy::DestoryRequest(std::shared_ptr<HttpProxyRequest> request)
|
|
{
|
|
request_hash_.erase(request->req_id);
|
|
}
|
|
|
|
void HttpProxy::AddSignParams(const std::string& url,
|
|
std::shared_ptr<a8::MutableXObject> url_params, const std::string& post_data)
|
|
{
|
|
if (url.find('?') != std::string::npos) {
|
|
A8_ABORT();
|
|
}
|
|
std::string sign_data;
|
|
sign_data.reserve(1024 * 64);
|
|
int nowtime = f8::App::Instance()->GetNowTime();
|
|
{
|
|
std::vector<std::string> keys;
|
|
url_params->GetKeys(keys);
|
|
for (auto& key : keys) {
|
|
std::string val = url_params->Get(key, "").GetString();
|
|
sign_data += key + "=" + val + "&";
|
|
}
|
|
sign_data += post_data;
|
|
}
|
|
{
|
|
sign_data += a8::XValue(nowtime).GetString() + JsonDataMgr::Instance()->GetApiSecretKey();
|
|
}
|
|
std::string sign = a8::openssl::md5(sign_data);
|
|
url_params->SetVal("_timestamp", a8::XValue(nowtime).GetString());
|
|
url_params->SetVal("_sign", sign);
|
|
}
|