Abort curl connections setting the timeout (avoid crash closing connections)

This commit is contained in:
David Capello 2016-05-17 16:13:25 -03:00
parent c875e24928
commit d495c4d18a
4 changed files with 33 additions and 35 deletions

View File

@ -18,30 +18,26 @@
namespace net {
class HttpRequestImpl
{
class HttpRequestImpl {
public:
HttpRequestImpl(const std::string& url)
: m_curl(curl_easy_init())
, m_headerlist(NULL)
, m_response(NULL)
{
, m_headerlist(nullptr)
, m_response(nullptr) {
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, this);
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, &HttpRequestImpl::writeBodyCallback);
curl_easy_setopt(m_curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(m_curl, CURLOPT_NOSIGNAL, 1);
}
~HttpRequestImpl()
{
~HttpRequestImpl() {
if (m_headerlist)
curl_slist_free_all(m_headerlist);
curl_easy_cleanup(m_curl);
}
void setHeaders(const HttpHeaders& headers)
{
void setHeaders(const HttpHeaders& headers) {
if (m_headerlist) {
curl_slist_free_all(m_headerlist);
m_headerlist = NULL;
@ -59,31 +55,31 @@ public:
curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, m_headerlist);
}
void send(HttpResponse& response)
{
bool send(HttpResponse& response) {
m_response = &response;
curl_easy_perform(m_curl);
int res = curl_easy_perform(m_curl);
if (res != CURLE_OK)
return false;
long code;
curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &code);
m_response->setStatus(code);
return true;
}
void abort()
{
curl_easy_cleanup(m_curl);
void abort() {
curl_easy_setopt(m_curl, CURLOPT_TIMEOUT_MS, 1);
curl_easy_setopt(m_curl, CURLOPT_CONNECTTIMEOUT_MS, 1);
}
private:
std::size_t writeBody(char* ptr, std::size_t bytes)
{
std::size_t writeBody(char* ptr, std::size_t bytes) {
ASSERT(m_response != NULL);
m_response->write(ptr, bytes);
return bytes;
}
static std::size_t writeBodyCallback(char* ptr, std::size_t size, std::size_t nmemb, void* userdata)
{
static std::size_t writeBodyCallback(char* ptr, std::size_t size, std::size_t nmemb, void* userdata) {
HttpRequestImpl* req = reinterpret_cast<HttpRequestImpl*>(userdata);
return req->writeBody(ptr, size*nmemb);
}
@ -108,9 +104,9 @@ void HttpRequest::setHeaders(const HttpHeaders& headers)
m_impl->setHeaders(headers);
}
void HttpRequest::send(HttpResponse& response)
bool HttpRequest::send(HttpResponse& response)
{
m_impl->send(response);
return m_impl->send(response);
}
void HttpRequest::abort()

View File

@ -1,5 +1,5 @@
// Aseprite Network Library
// Copyright (c) 2001-2015 David Capello
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -18,14 +18,13 @@ class HttpHeaders;
class HttpRequestImpl;
class HttpResponse;
class HttpRequest
{
class HttpRequest {
public:
HttpRequest(const std::string& url);
~HttpRequest();
void setHeaders(const HttpHeaders& headers);
void send(HttpResponse& response);
bool send(HttpResponse& response);
void abort();
private:

View File

@ -96,7 +96,7 @@ public:
m_request->abort();
}
void checkNewVersion(const Uuid& uuid, const std::string& extraParams, CheckUpdateDelegate* delegate)
bool checkNewVersion(const Uuid& uuid, const std::string& extraParams, CheckUpdateDelegate* delegate)
{
#ifndef UPDATE_URL
#define UPDATE_URL ""
@ -120,13 +120,16 @@ public:
std::stringstream body;
net::HttpResponse response(&body);
m_request->send(response);
if (m_request->send(response)) {
TRACE("Checking updates: %s (User-Agent: %s)\n", url.c_str(), getUserAgent().c_str());
TRACE("Response:\n--\n%s--\n", body.str().c_str());
TRACE("Checking updates: %s (User-Agent: %s)\n", url.c_str(), getUserAgent().c_str());
TRACE("Response:\n--\n%s--\n", body.str().c_str());
CheckUpdateResponse data(body.str());
delegate->onResponse(data);
CheckUpdateResponse data(body.str());
delegate->onResponse(data);
return true;
}
else
return false;
}
private:
@ -148,9 +151,9 @@ void CheckUpdate::abort()
m_impl->abort();
}
void CheckUpdate::checkNewVersion(const Uuid& uuid, const std::string& extraParams, CheckUpdateDelegate* delegate)
bool CheckUpdate::checkNewVersion(const Uuid& uuid, const std::string& extraParams, CheckUpdateDelegate* delegate)
{
m_impl->checkNewVersion(uuid, extraParams, delegate);
return m_impl->checkNewVersion(uuid, extraParams, delegate);
}
} // namespace updater

View File

@ -80,7 +80,7 @@ namespace updater {
// Sends a request to the "updates server" and calls the delegate
// when the response is received.
void checkNewVersion(const Uuid& uuid, const std::string& extraParams, CheckUpdateDelegate* delegate);
bool checkNewVersion(const Uuid& uuid, const std::string& extraParams, CheckUpdateDelegate* delegate);
private:
class CheckUpdateImpl;