HttpClient: Fix crash when process redirect

This commit is contained in:
halx99 2021-07-06 02:44:57 +08:00
parent af0a0f1598
commit f4969ee388
3 changed files with 51 additions and 77 deletions

View File

@ -42,37 +42,29 @@ namespace network {
static HttpClient* _httpClient = nullptr; // pointer to singleton
template<typename _Cont, typename _Fty>
template <typename _Cont, typename _Fty>
static void __clearQueueUnsafe(_Cont& queue, _Fty pred) {
for (auto it = queue.unsafe_begin(); it != queue.unsafe_end();)
{
if (!pred || pred((*it)))
{
for (auto it = queue.unsafe_begin(); it != queue.unsafe_end();) {
if (!pred || pred((*it))) {
(*it)->release();
it = queue.unsafe_erase(it);
}
else
{
} else {
++it;
}
}
}
// HttpClient implementation
HttpClient* HttpClient::getInstance()
{
if (_httpClient == nullptr)
{
HttpClient* HttpClient::getInstance() {
if (_httpClient == nullptr) {
_httpClient = new (std::nothrow) HttpClient();
}
return _httpClient;
}
void HttpClient::destroyInstance()
{
if (nullptr == _httpClient)
{
void HttpClient::destroyInstance() {
if (nullptr == _httpClient) {
CCLOG("HttpClient singleton is nullptr");
return;
}
@ -84,34 +76,24 @@ void HttpClient::destroyInstance()
CCLOG("HttpClient::destroyInstance() finished!");
}
void HttpClient::enableCookies(const char* cookieFile)
{
void HttpClient::enableCookies(const char* cookieFile) {
std::lock_guard<std::recursive_mutex> lock(_cookieFileMutex);
if (cookieFile)
{
if (cookieFile) {
_cookieFilename = std::string(cookieFile);
}
else
{
} else {
_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);
_sslCaFilename = caFile;
_service->set_option(yasio::YOPT_S_SSL_CACERT, _sslCaFilename.c_str());
}
HttpClient::HttpClient()
: _isInited(false)
, _dispatchOnWorkThread(false)
, _timeoutForConnect(30)
, _timeoutForRead(60)
, _cookie(nullptr)
, _clearResponsePredicate(nullptr)
{
: _isInited(false), _dispatchOnWorkThread(false), _timeoutForConnect(30), _timeoutForRead(60), _cookie(nullptr),
_clearResponsePredicate(nullptr) {
CCLOG("In the constructor of HttpClient!");
_scheduler = Director::getInstance()->getScheduler();
@ -126,14 +108,12 @@ HttpClient::HttpClient()
_isInited = true;
}
HttpClient::~HttpClient()
{
HttpClient::~HttpClient() {
delete _service;
CCLOG("HttpClient destructor");
}
bool HttpClient::send(HttpRequest* request)
{
bool HttpClient::send(HttpRequest* request) {
if (!request)
return false;
@ -159,10 +139,12 @@ void HttpClient::processResponse(HttpResponse* response, const std::string& url)
if (channelIndex != -1) {
if (response->prepareForProcess(url)) {
response->_responseHeaders.clear(); // redirect needs clear old response headers
auto& requestUri = response->getRequestUri();
auto channelHandle = _service->channel_at(channelIndex);
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())
_service->open(channelIndex, YCK_SSL_CLIENT);
else
@ -239,7 +221,7 @@ void HttpClient::handleNetworkEvent(yasio::io_event* event) {
bool userAgentSpecified = false;
bool contentTypeSpecified = false;
if(!headers.empty()) {
if (!headers.empty()) {
using namespace cxx17; // for string_view literal
for (auto& header : headers) {
obs.write_bytes(header);
@ -358,44 +340,37 @@ void HttpClient::clearResponseQueue() {
__clearQueueUnsafe(_responseQueue, ClearResponsePredicate{});
}
void HttpClient::setTimeoutForConnect(int value)
{
void HttpClient::setTimeoutForConnect(int value) {
std::lock_guard<std::recursive_mutex> lock(_timeoutForConnectMutex);
_timeoutForConnect = value;
_service->set_option(YOPT_S_CONNECT_TIMEOUT, value);
}
int HttpClient::getTimeoutForConnect()
{
int HttpClient::getTimeoutForConnect() {
std::lock_guard<std::recursive_mutex> lock(_timeoutForConnectMutex);
return _timeoutForConnect;
}
void HttpClient::setTimeoutForRead(int value)
{
void HttpClient::setTimeoutForRead(int value) {
std::lock_guard<std::recursive_mutex> lock(_timeoutForReadMutex);
_timeoutForRead = value;
}
int HttpClient::getTimeoutForRead()
{
int HttpClient::getTimeoutForRead() {
std::lock_guard<std::recursive_mutex> lock(_timeoutForReadMutex);
return _timeoutForRead;
}
const std::string& HttpClient::getCookieFilename()
{
const std::string& HttpClient::getCookieFilename() {
std::lock_guard<std::recursive_mutex> lock(_cookieFileMutex);
return _cookieFilename;
}
const std::string& HttpClient::getSSLVerification()
{
const std::string& HttpClient::getSSLVerification() {
std::lock_guard<std::recursive_mutex> lock(_sslCaFileMutex);
return _sslCaFilename;
}
}
} // namespace network
NS_CC_END

View File

@ -107,7 +107,7 @@ public:
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.
please make sure request->_requestData is clear before calling "send" here.

View File

@ -173,7 +173,6 @@ private:
_finished = false;
_responseData.clear();
_currentHeader.clear();
_responseHeaders.clear();
_responseCode = -1;
_internalCode = 0;