mirror of https://github.com/axmolengine/axmol.git
HttpClient: Fix crash when process redirect
This commit is contained in:
parent
af0a0f1598
commit
f4969ee388
|
@ -42,37 +42,29 @@ namespace network {
|
||||||
|
|
||||||
static HttpClient* _httpClient = nullptr; // pointer to singleton
|
static HttpClient* _httpClient = nullptr; // pointer to singleton
|
||||||
|
|
||||||
template<typename _Cont, typename _Fty>
|
template <typename _Cont, typename _Fty>
|
||||||
static void __clearQueueUnsafe(_Cont& queue, _Fty pred) {
|
static void __clearQueueUnsafe(_Cont& queue, _Fty pred) {
|
||||||
for (auto it = queue.unsafe_begin(); it != queue.unsafe_end();)
|
for (auto it = queue.unsafe_begin(); it != queue.unsafe_end();) {
|
||||||
{
|
if (!pred || pred((*it))) {
|
||||||
if (!pred || pred((*it)))
|
|
||||||
{
|
|
||||||
(*it)->release();
|
(*it)->release();
|
||||||
it = queue.unsafe_erase(it);
|
it = queue.unsafe_erase(it);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HttpClient implementation
|
// HttpClient implementation
|
||||||
HttpClient* HttpClient::getInstance()
|
HttpClient* HttpClient::getInstance() {
|
||||||
{
|
if (_httpClient == nullptr) {
|
||||||
if (_httpClient == nullptr)
|
|
||||||
{
|
|
||||||
_httpClient = new (std::nothrow) HttpClient();
|
_httpClient = new (std::nothrow) HttpClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _httpClient;
|
return _httpClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::destroyInstance()
|
void HttpClient::destroyInstance() {
|
||||||
{
|
if (nullptr == _httpClient) {
|
||||||
if (nullptr == _httpClient)
|
|
||||||
{
|
|
||||||
CCLOG("HttpClient singleton is nullptr");
|
CCLOG("HttpClient singleton is nullptr");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -84,34 +76,24 @@ void HttpClient::destroyInstance()
|
||||||
CCLOG("HttpClient::destroyInstance() finished!");
|
CCLOG("HttpClient::destroyInstance() finished!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::enableCookies(const char* cookieFile)
|
void HttpClient::enableCookies(const char* cookieFile) {
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(_cookieFileMutex);
|
std::lock_guard<std::recursive_mutex> lock(_cookieFileMutex);
|
||||||
if (cookieFile)
|
if (cookieFile) {
|
||||||
{
|
|
||||||
_cookieFilename = std::string(cookieFile);
|
_cookieFilename = std::string(cookieFile);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
_cookieFilename = (FileUtils::getInstance()->getNativeWritableAbsolutePath() + "cookieFile.txt");
|
_cookieFilename = (FileUtils::getInstance()->getNativeWritableAbsolutePath() + "cookieFile.txt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::setSSLVerification(const std::string& caFile)
|
void HttpClient::setSSLVerification(const std::string& caFile) {
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(_sslCaFileMutex);
|
std::lock_guard<std::recursive_mutex> lock(_sslCaFileMutex);
|
||||||
_sslCaFilename = caFile;
|
_sslCaFilename = caFile;
|
||||||
_service->set_option(yasio::YOPT_S_SSL_CACERT, _sslCaFilename.c_str());
|
_service->set_option(yasio::YOPT_S_SSL_CACERT, _sslCaFilename.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpClient::HttpClient()
|
HttpClient::HttpClient()
|
||||||
: _isInited(false)
|
: _isInited(false), _dispatchOnWorkThread(false), _timeoutForConnect(30), _timeoutForRead(60), _cookie(nullptr),
|
||||||
, _dispatchOnWorkThread(false)
|
_clearResponsePredicate(nullptr) {
|
||||||
, _timeoutForConnect(30)
|
|
||||||
, _timeoutForRead(60)
|
|
||||||
, _cookie(nullptr)
|
|
||||||
, _clearResponsePredicate(nullptr)
|
|
||||||
{
|
|
||||||
CCLOG("In the constructor of HttpClient!");
|
CCLOG("In the constructor of HttpClient!");
|
||||||
_scheduler = Director::getInstance()->getScheduler();
|
_scheduler = Director::getInstance()->getScheduler();
|
||||||
|
|
||||||
|
@ -126,14 +108,12 @@ HttpClient::HttpClient()
|
||||||
_isInited = true;
|
_isInited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpClient::~HttpClient()
|
HttpClient::~HttpClient() {
|
||||||
{
|
|
||||||
delete _service;
|
delete _service;
|
||||||
CCLOG("HttpClient destructor");
|
CCLOG("HttpClient destructor");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HttpClient::send(HttpRequest* request)
|
bool HttpClient::send(HttpRequest* request) {
|
||||||
{
|
|
||||||
if (!request)
|
if (!request)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -159,10 +139,12 @@ void HttpClient::processResponse(HttpResponse* response, const std::string& url)
|
||||||
|
|
||||||
if (channelIndex != -1) {
|
if (channelIndex != -1) {
|
||||||
if (response->prepareForProcess(url)) {
|
if (response->prepareForProcess(url)) {
|
||||||
|
response->_responseHeaders.clear(); // redirect needs clear old response headers
|
||||||
auto& requestUri = response->getRequestUri();
|
auto& requestUri = response->getRequestUri();
|
||||||
auto channelHandle = _service->channel_at(channelIndex);
|
auto channelHandle = _service->channel_at(channelIndex);
|
||||||
channelHandle->ud_.ptr = response;
|
channelHandle->ud_.ptr = response;
|
||||||
_service->set_option(YOPT_C_REMOTE_ENDPOINT, channelIndex, requestUri.getHost().c_str(), (int) requestUri.getPort());
|
_service->set_option(
|
||||||
|
YOPT_C_REMOTE_ENDPOINT, channelIndex, requestUri.getHost().c_str(), (int) requestUri.getPort());
|
||||||
if (requestUri.isSecure())
|
if (requestUri.isSecure())
|
||||||
_service->open(channelIndex, YCK_SSL_CLIENT);
|
_service->open(channelIndex, YCK_SSL_CLIENT);
|
||||||
else
|
else
|
||||||
|
@ -239,7 +221,7 @@ void HttpClient::handleNetworkEvent(yasio::io_event* event) {
|
||||||
|
|
||||||
bool userAgentSpecified = false;
|
bool userAgentSpecified = false;
|
||||||
bool contentTypeSpecified = false;
|
bool contentTypeSpecified = false;
|
||||||
if(!headers.empty()) {
|
if (!headers.empty()) {
|
||||||
using namespace cxx17; // for string_view literal
|
using namespace cxx17; // for string_view literal
|
||||||
for (auto& header : headers) {
|
for (auto& header : headers) {
|
||||||
obs.write_bytes(header);
|
obs.write_bytes(header);
|
||||||
|
@ -358,44 +340,37 @@ void HttpClient::clearResponseQueue() {
|
||||||
__clearQueueUnsafe(_responseQueue, ClearResponsePredicate{});
|
__clearQueueUnsafe(_responseQueue, ClearResponsePredicate{});
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::setTimeoutForConnect(int value)
|
void HttpClient::setTimeoutForConnect(int value) {
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(_timeoutForConnectMutex);
|
std::lock_guard<std::recursive_mutex> lock(_timeoutForConnectMutex);
|
||||||
_timeoutForConnect = value;
|
_timeoutForConnect = value;
|
||||||
_service->set_option(YOPT_S_CONNECT_TIMEOUT, value);
|
_service->set_option(YOPT_S_CONNECT_TIMEOUT, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
int HttpClient::getTimeoutForConnect()
|
int HttpClient::getTimeoutForConnect() {
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(_timeoutForConnectMutex);
|
std::lock_guard<std::recursive_mutex> lock(_timeoutForConnectMutex);
|
||||||
return _timeoutForConnect;
|
return _timeoutForConnect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::setTimeoutForRead(int value)
|
void HttpClient::setTimeoutForRead(int value) {
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(_timeoutForReadMutex);
|
std::lock_guard<std::recursive_mutex> lock(_timeoutForReadMutex);
|
||||||
_timeoutForRead = value;
|
_timeoutForRead = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int HttpClient::getTimeoutForRead()
|
int HttpClient::getTimeoutForRead() {
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(_timeoutForReadMutex);
|
std::lock_guard<std::recursive_mutex> lock(_timeoutForReadMutex);
|
||||||
return _timeoutForRead;
|
return _timeoutForRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& HttpClient::getCookieFilename()
|
const std::string& HttpClient::getCookieFilename() {
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(_cookieFileMutex);
|
std::lock_guard<std::recursive_mutex> lock(_cookieFileMutex);
|
||||||
return _cookieFilename;
|
return _cookieFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& HttpClient::getSSLVerification()
|
const std::string& HttpClient::getSSLVerification() {
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lock(_sslCaFileMutex);
|
std::lock_guard<std::recursive_mutex> lock(_sslCaFileMutex);
|
||||||
return _sslCaFilename;
|
return _sslCaFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace network
|
||||||
|
|
||||||
NS_CC_END
|
NS_CC_END
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ public:
|
||||||
const std::string& getSSLVerification();
|
const std::string& getSSLVerification();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a get request to task queue
|
* Send http request concurrently, non-blocking
|
||||||
*
|
*
|
||||||
* @param request a HttpRequest object, which includes url, response callback etc.
|
* @param request a HttpRequest object, which includes url, response callback etc.
|
||||||
please make sure request->_requestData is clear before calling "send" here.
|
please make sure request->_requestData is clear before calling "send" here.
|
||||||
|
|
|
@ -173,7 +173,6 @@ private:
|
||||||
_finished = false;
|
_finished = false;
|
||||||
_responseData.clear();
|
_responseData.clear();
|
||||||
_currentHeader.clear();
|
_currentHeader.clear();
|
||||||
_responseHeaders.clear();
|
|
||||||
_responseCode = -1;
|
_responseCode = -1;
|
||||||
_internalCode = 0;
|
_internalCode = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue