diff --git a/nel/include/nel/gui/group_html.h b/nel/include/nel/gui/group_html.h
index 3c94e7fa9..c94bec024 100644
--- a/nel/include/nel/gui/group_html.h
+++ b/nel/include/nel/gui/group_html.h
@@ -47,6 +47,20 @@ namespace NLGUI
extern std::string CurrentCookie;
+ class ICurlDownloadCB
+ {
+ public:
+ ICurlDownloadCB(const std::string &url)
+ : url(url)
+ {}
+
+ virtual ~ICurlDownloadCB() {};
+
+ virtual void finish() = 0;
+
+ std::string url;
+ };
+
// HTML group
/**
* Widget to have a resizable scrolltext and its scrollbar
@@ -133,9 +147,8 @@ namespace NLGUI
void endParagraph();
// add image download (used by view_bitmap.cpp to load web images)
- void addImageDownload(const std::string &url, CViewBase *img, const CStyleParams &style = CStyleParams(), const TImageType type = NormalImage, const std::string &placeholder = "web_del.tga");
- // remove image from download list if present
- void removeImageDownload(CViewBase *img);
+ ICurlDownloadCB *addImageDownload(const std::string &url, CViewBase *img, const CStyleParams &style = CStyleParams(), const TImageType type = NormalImage, const std::string &placeholder = "web_del.tga");
+ void removeImageDownload(ICurlDownloadCB *handle, CViewBase *img);
std::string localImageName(const std::string &url);
// Timeout
@@ -817,48 +830,89 @@ namespace NLGUI
// decode all HTML entities
static std::string decodeHTMLEntities(const std::string &str);
- struct CDataImageDownload
+ class CDataDownload : public ICurlDownloadCB
{
public:
- CDataImageDownload(CViewBase *img, CStyleParams style, TImageType type): Image(img), Style(style), Type(type)
- {
- }
+ CDataDownload(const std::string &u, const std::string &d)
+ : ICurlDownloadCB(u), data(NULL), fp(NULL), dest(d), redirects(0), ConnectionTimeout(60)
+ {}
+ virtual ~CDataDownload();
+
public:
- CViewBase * Image;
- CStyleParams Style;
- TImageType Type;
+ CCurlWWWData *data;
+ std::string dest;
+ std::string tmpdest;
+ uint32 redirects;
+ FILE *fp;
+ uint32 ConnectionTimeout;
+ };
+
+ class StylesheetDownloadCB : public CDataDownload
+ {
+ public:
+ StylesheetDownloadCB(const std::string &url, const std::string &dest, CGroupHTML *parent)
+ : CDataDownload(url, dest), Parent(parent)
+ {}
+
+ virtual void finish() NL_OVERRIDE;
+
+ private:
+ CGroupHTML *Parent;
};
- struct CDataDownload
+ class ImageDownloadCB : public CDataDownload
{
public:
- CDataDownload(const std::string &u, const std::string &d, TDataType t, CViewBase *i, const std::string &s, const std::string &m, const CStyleParams &style = CStyleParams(), const TImageType imagetype = NormalImage)
- : data(NULL), fp(NULL), url(u), dest(d), type(t), luaScript(s), md5sum(m), redirects(0), ConnectionTimeout(60)
+ struct SImageInfo
+ {
+ SImageInfo(CViewBase *img, const CStyleParams &style, TImageType type)
+ : Image(img), Style(style), Type(type)
+ {}
+
+ CViewBase *Image;
+ CStyleParams Style;
+ TImageType Type;
+ };
+
+ ImageDownloadCB(const std::string &url, const std::string &dest, CViewBase *img, const CStyleParams &style, TImageType type, CGroupHTML *parent)
+ : CDataDownload(url, dest), Parent(parent)
{
- if (t == ImgType) imgs.push_back(CDataImageDownload(i, style, imagetype));
+ addImage(img, style, type);
}
- ~CDataDownload();
+ virtual void finish() NL_OVERRIDE;
+
+ void addImage(CViewBase *img, const CStyleParams &style, TImageType type);
+ void removeImage(CViewBase *img);
+
+ private:
+ std::vector Images;
+ CGroupHTML *Parent;
+ CStyleParams Style;
+ TImageType Type;
+ };
+
+ class BnpDownloadCB : public CDataDownload
+ {
public:
- CCurlWWWData *data;
- std::string url;
- std::string dest;
- std::string tmpdest;
- std::string luaScript;
- std::string md5sum;
- TDataType type;
- uint32 redirects;
- FILE *fp;
- std::vector imgs;
- uint32 ConnectionTimeout;
+ BnpDownloadCB(const std::string &url, const std::string &dest, const std::string md5sum, const std::string lua, CGroupHTML *parent)
+ : CDataDownload(url, dest), Parent(parent), m_md5sum(md5sum), m_lua(lua)
+ {}
+
+ virtual void finish() NL_OVERRIDE;
+
+ private:
+ CGroupHTML *Parent;
+ std::string m_md5sum;
+ std::string m_lua;
};
- std::list Curls;
+ std::list Curls;
CURLM *MultiCurl;
int RunningCurls;
- bool startCurlDownload(CDataDownload &download);
- void finishCurlDownload(const CDataDownload &download);
+ bool startCurlDownload(CDataDownload *download);
+ void finishCurlDownload(CDataDownload *download);
void pumpCurlQueue();
void initImageDownload();
@@ -888,7 +942,7 @@ namespace NLGUI
// _CurlWWW download finished
void htmlDownloadFinished(bool success, const std::string &error);
// images, stylesheets, etc finished downloading
- void dataDownloadFinished(bool success, const std::string &error, CDataDownload &data);
+ void dataDownloadFinished(bool success, const std::string &error, CDataDownload *data);
// HtmlType download finished
void htmlDownloadFinished(const std::string &content, const std::string &type, long code);
diff --git a/nel/include/nel/gui/view_bitmap.h b/nel/include/nel/gui/view_bitmap.h
index f7a77cb30..958fdcc5c 100644
--- a/nel/include/nel/gui/view_bitmap.h
+++ b/nel/include/nel/gui/view_bitmap.h
@@ -28,6 +28,7 @@
namespace NLGUI
{
+ class ICurlDownloadCB;
/**
* class implementing a bitmap view
@@ -61,7 +62,7 @@ namespace NLGUI
_TxtHeight = -1;
// Support for https://.. textures
- _HtmlDownload = false;
+ _HtmlDownload = NULL;
}
/// Destructor
@@ -141,7 +142,9 @@ namespace NLGUI
bool _Flip : 1;
bool _Tile : 1;
bool _InheritGCAlpha : 1;
- bool _HtmlDownload : 1;
+
+ // pointer to active curl download object
+ ICurlDownloadCB *_HtmlDownload;
// For single texture
diff --git a/nel/src/gui/group_html.cpp b/nel/src/gui/group_html.cpp
index 75d7eb64c..0c48b92a8 100644
--- a/nel/src/gui/group_html.cpp
+++ b/nel/src/gui/group_html.cpp
@@ -266,6 +266,120 @@ namespace NLGUI
data = NULL;
}
+ void CGroupHTML::StylesheetDownloadCB::finish()
+ {
+ if (CFile::fileExists(tmpdest))
+ {
+ if (CFile::fileExists(dest))
+ {
+ CFile::deleteFile(dest);
+ }
+ CFile::moveFile(dest, tmpdest);
+ }
+ Parent->cssDownloadFinished(url, dest);
+ }
+
+ void CGroupHTML::ImageDownloadCB::addImage(CViewBase *img, const CStyleParams &style, TImageType type)
+ {
+ Images.push_back(SImageInfo(img, style, type));
+ }
+
+ void CGroupHTML::ImageDownloadCB::removeImage(CViewBase *img)
+ {
+ for(std::vector::iterator it = Images.begin(); it != Images.end(); ++it)
+ {
+ if (it->Image == img)
+ {
+ Images.erase(it);
+ break;
+ }
+ }
+ }
+
+ void CGroupHTML::ImageDownloadCB::finish()
+ {
+ // tmpdest file does not exist if download skipped (ie cache was used)
+ if (CFile::fileExists(tmpdest) || CFile::getFileSize(tmpdest) == 0)
+ {
+ try {
+ // verify that image is not corrupted
+ uint32 w, h;
+ CBitmap::loadSize(tmpdest, w, h);
+ if (w != 0 && h != 0)
+ {
+ if (CFile::fileExists(dest))
+ CFile::deleteFile(dest);
+ }
+ }
+ catch(const NLMISC::Exception &e)
+ {
+ // exception message has .tmp file name, so keep it for further analysis
+ nlwarning("Invalid image (%s) from url (%s): %s", tmpdest.c_str(), url.c_str(), e.what());
+ }
+
+ // to reload image on page, the easiest seems to be changing texture
+ // to temp file temporarily. that forces driver to reload texture from disk
+ // ITexture::touch() seem not to do this.
+ // cache was updated, first set texture as temp file
+ for(std::vector::iterator it = Images.begin(); it != Images.end(); ++it)
+ {
+ SImageInfo &img = *it;
+ Parent->setImage(img.Image, tmpdest, img.Type);
+ Parent->setImageSize(img.Image, img.Style);
+ }
+
+ CFile::moveFile(dest, tmpdest);
+ }
+
+ if (!CFile::fileExists(dest) || CFile::getFileSize(dest) == 0)
+ {
+ // placeholder if cached image failed
+ dest = "web_del.tga";
+ }
+
+ // even if image was cached, incase there was 'http://' image set to CViewBitmap
+ for(std::vector::iterator it = Images.begin(); it != Images.end(); ++it)
+ {
+ SImageInfo &img = *it;
+ Parent->setImage(img.Image, dest, img.Type);
+ Parent->setImageSize(img.Image, img.Style);
+ }
+ }
+
+ void CGroupHTML::BnpDownloadCB::finish()
+ {
+ bool verified = false;
+ // no tmpfile if file was already in cache
+ if (CFile::fileExists(tmpdest))
+ {
+ verified = m_md5sum.empty() || (m_md5sum != getMD5(tmpdest).toString());
+ if (verified)
+ {
+ if (CFile::fileExists(dest))
+ {
+ CFile::deleteFile(dest);
+ }
+ CFile::moveFile(dest, tmpdest);
+ }
+ else
+ {
+ CFile::deleteFile(tmpdest);
+ }
+ }
+ else if (CFile::fileExists(dest))
+ {
+ verified = m_md5sum.empty() || (m_md5sum != getMD5(dest).toString());
+ }
+
+ if (!m_lua.empty())
+ {
+ std::string script = "\nlocal __CURRENT_WINDOW__ = \""+Parent->getId()+"\"";
+ script += toString("\nlocal __DOWNLOAD_STATUS__ = %s\n", verified ? "true" : "false");
+ script += m_lua;
+ CLuaManager::getInstance().executeLuaScript(script, true );
+ }
+ }
+
// Check if domain is on TrustedDomain
bool CGroupHTML::isTrustedDomain(const string &domain)
{
@@ -479,17 +593,17 @@ namespace NLGUI
{
if (RunningCurls < options.curlMaxConnections)
{
- std::list::iterator it=Curls.begin();
- uint c = 0;
+ std::list::iterator it=Curls.begin();
while(it != Curls.end() && RunningCurls < options.curlMaxConnections)
{
- if (it->data == NULL)
+ if ((*it)->data == NULL)
{
LOG_DL("(%s) starting new download '%s'", _Id.c_str(), it->url.c_str());
if (!startCurlDownload(*it))
{
LOG_DL("(%s) failed to start '%s)'", _Id.c_str(), it->url.c_str());
finishCurlDownload(*it);
+
it = Curls.erase(it);
continue;
}
@@ -504,11 +618,11 @@ namespace NLGUI
}
// Add url to MultiCurl queue and return cURL handle
- bool CGroupHTML::startCurlDownload(CDataDownload &download)
+ bool CGroupHTML::startCurlDownload(CDataDownload *download)
{
if (!MultiCurl)
{
- nlwarning("Invalid MultiCurl handle, unable to download '%s'", download.url.c_str());
+ nlwarning("Invalid MultiCurl handle, unable to download '%s'", download->url.c_str());
return false;
}
@@ -516,28 +630,28 @@ namespace NLGUI
time(¤tTime);
CHttpCacheObject cache;
- if (CFile::fileExists(download.dest))
- cache = CHttpCache::getInstance()->lookup(download.dest);
+ if (CFile::fileExists(download->dest))
+ cache = CHttpCache::getInstance()->lookup(download->dest);
if (cache.Expires > currentTime)
{
- LOG_DL("Cache for (%s) is not expired (%s, expires:%d)", download.url.c_str(), download.dest.c_str(), cache.Expires - currentTime);
+ LOG_DL("Cache for (%s) is not expired (%s, expires:%d)", download->url.c_str(), download->dest.c_str(), cache.Expires - currentTime);
return false;
}
// use browser Id so that two browsers would not use same temp file
- download.tmpdest = localImageName(_Id + download.dest) + ".tmp";
+ download->tmpdest = localImageName(_Id + download->dest) + ".tmp";
// erase the tmp file if exists
- if (CFile::fileExists(download.tmpdest))
+ if (CFile::fileExists(download->tmpdest))
{
- CFile::deleteFile(download.tmpdest);
+ CFile::deleteFile(download->tmpdest);
}
- FILE *fp = nlfopen (download.tmpdest, "wb");
+ FILE *fp = nlfopen (download->tmpdest, "wb");
if (fp == NULL)
{
- nlwarning("Can't open file '%s' for writing: code=%d '%s'", download.tmpdest.c_str (), errno, strerror(errno));
+ nlwarning("Can't open file '%s' for writing: code=%d '%s'", download->tmpdest.c_str (), errno, strerror(errno));
return false;
}
@@ -545,28 +659,28 @@ namespace NLGUI
if (!curl)
{
fclose(fp);
- CFile::deleteFile(download.tmpdest);
+ CFile::deleteFile(download->tmpdest);
- nlwarning("Creating cURL handle failed, unable to download '%s'", download.url.c_str());
+ nlwarning("Creating cURL handle failed, unable to download '%s'", download->url.c_str());
return false;
}
- LOG_DL("curl easy handle %p created for '%s'", curl, download.url.c_str());
+ LOG_DL("curl easy handle %p created for '%s'", curl, download->url.c_str());
// https://
- if (toLowerAscii(download.url.substr(0, 8)) == "https://")
+ if (toLowerAscii(download->url.substr(0, 8)) == "https://")
{
// if supported, use custom SSL context function to load certificates
NLWEB::CCurlCertificates::useCertificates(curl);
}
- download.data = new CCurlWWWData(curl, download.url);
- download.fp = fp;
+ download->data = new CCurlWWWData(curl, download->url);
+ download->fp = fp;
// initial connection timeout, curl default is 300sec
- curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, download.ConnectionTimeout);
+ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, download->ConnectionTimeout);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, true);
- curl_easy_setopt(curl, CURLOPT_URL, download.url.c_str());
+ curl_easy_setopt(curl, CURLOPT_URL, download->url.c_str());
// limit curl to HTTP and HTTPS protocols only
curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
@@ -580,16 +694,16 @@ namespace NLGUI
headers.push_back("If-Modified-Since: " + cache.LastModified);
if (headers.size() > 0)
- download.data->sendHeaders(headers);
+ download->data->sendHeaders(headers);
// catch headers
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, NLGUI::curlHeaderCallback);
- curl_easy_setopt(curl, CURLOPT_WRITEHEADER, download.data);
+ curl_easy_setopt(curl, CURLOPT_WRITEHEADER, download->data);
std::string userAgent = options.appName + "/" + options.appVersion;
curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str());
- CUrlParser uri(download.url);
+ CUrlParser uri(download->url);
if (!uri.host.empty())
sendCookies(curl, uri.host, isTrustedDomain(uri.host));
@@ -599,7 +713,7 @@ namespace NLGUI
CURLMcode ret = curl_multi_add_handle(MultiCurl, curl);
if (ret != CURLM_OK)
{
- nlwarning("cURL multi handle %p error %d on '%s'", curl, ret, download.url.c_str());
+ nlwarning("cURL multi handle %p error %d on '%s'", curl, ret, download->url.c_str());
return false;
}
@@ -607,118 +721,21 @@ namespace NLGUI
return true;
}
- void CGroupHTML::finishCurlDownload(const CDataDownload &download)
+ void CGroupHTML::finishCurlDownload(CDataDownload *download)
{
- if (download.type == ImgType)
+ if (download)
{
- if (CFile::fileExists(download.tmpdest) && CFile::getFileSize(download.tmpdest) > 0)
- {
- try
- {
- // verify that image is not corrupted
- uint32 w, h;
- CBitmap::loadSize(download.tmpdest, w, h);
- if (w != 0 && h != 0)
- {
- if (CFile::fileExists(download.dest))
- CFile::deleteFile(download.dest);
-
- // to reload image on page, the easiest seems to be changing texture
- // to temp file temporarily. that forces driver to reload texture from disk
- // ITexture::touch() seem not to do this.
- // cache was updated, first set texture as temp file
- for(uint i = 0; i < download.imgs.size(); i++)
- {
- setImage(download.imgs[i].Image, download.tmpdest, download.imgs[i].Type);
- setImageSize(download.imgs[i].Image, download.imgs[i].Style);
- }
-
- CFile::moveFile(download.dest, download.tmpdest);
- }
- }
- catch(const NLMISC::Exception &e)
- {
- // exception message has .tmp file name, so keep it for further analysis
- nlwarning("Invalid image (%s) from url (%s): %s", download.tmpdest.c_str(), download.url.c_str(), e.what());
- }
- }
-
- if (CFile::fileExists(download.dest) && CFile::getFileSize(download.dest) > 0)
- {
- try
- {
- // verify that image is not corrupted
- uint32 w, h;
- CBitmap::loadSize(download.dest, w, h);
- if (w != 0 && h != 0)
- for(uint i = 0; i < download.imgs.size(); i++)
- {
- setImage(download.imgs[i].Image, download.dest, download.imgs[i].Type);
- setImageSize(download.imgs[i].Image, download.imgs[i].Style);
- }
- }
- catch(const NLMISC::Exception &e)
- {
- nlwarning("Invalid image (%s) from url (%s): %s", download.dest.c_str(), download.url.c_str(), e.what());
- }
- }
-
- return;
+ download->finish();
+ delete download;
}
-
- if (download.type == StylesheetType)
- {
- if (CFile::fileExists(download.tmpdest))
- {
- if (CFile::fileExists(download.dest))
- {
- CFile::deleteFile(download.dest);
- }
- CFile::moveFile(download.dest, download.tmpdest);
- }
- cssDownloadFinished(download.url, download.dest);
-
- return;
- }
-
- if (download.type == BnpType)
+ else
{
- bool verified = false;
- // no tmpfile if file was already in cache
- if (CFile::fileExists(download.tmpdest))
- {
- verified = download.md5sum.empty() || (download.md5sum != getMD5(download.tmpdest).toString());
- if (verified)
- {
- if (CFile::fileExists(download.dest))
- {
- CFile::deleteFile(download.dest);
- }
- CFile::moveFile(download.dest, download.tmpdest);
- }
- else
- {
- CFile::deleteFile(download.tmpdest);
- }
- }
- else if (CFile::fileExists(download.dest))
- {
- verified = download.md5sum.empty() || (download.md5sum != getMD5(download.dest).toString());
- }
-
- std::string script = "\nlocal __CURRENT_WINDOW__ = \""+this->_Id+"\"";
- script += toString("\nlocal __DOWNLOAD_STATUS__ = %s\n", verified ? "true" : "false");
- script += download.luaScript;
- CLuaManager::getInstance().executeLuaScript(script, true );
-
- return;
+ nlwarning("Unknown CURL download (nullptr)");
}
-
- nlwarning("Unknown CURL download type (%d) finished '%s'", download.type, download.url.c_str());
}
// Add a image download request in the multi_curl
- void CGroupHTML::addImageDownload(const string &url, CViewBase *img, const CStyleParams &style, TImageType type, const std::string &placeholder)
+ ICurlDownloadCB *CGroupHTML::addImageDownload(const string &url, CViewBase *img, const CStyleParams &style, TImageType type, const std::string &placeholder)
{
std::string finalUrl;
img->setModulateGlobalColor(style.GlobalColor);
@@ -728,7 +745,7 @@ namespace NLGUI
{
setImage(img, decodeURIComponent(url), type);
setImageSize(img, style);
- return;
+ return NULL;
}
// load the image from local files/bnp
@@ -737,7 +754,7 @@ namespace NLGUI
{
setImage(img, image, type);
setImageSize(img, style);
- return;
+ return NULL;
}
finalUrl = upgradeInsecureUrl(getAbsoluteUrl(url));
@@ -759,36 +776,40 @@ namespace NLGUI
}
// Search if we are not already downloading this url.
- for(std::list::iterator it = Curls.begin(); it != Curls.end(); ++it)
+ for(std::list::iterator it = Curls.begin(); it != Curls.end(); ++it)
{
- if(it->url == finalUrl)
+ if((*it)->url == finalUrl)
{
LOG_DL("already downloading '%s' img %p", finalUrl.c_str(), img);
- it->imgs.push_back(CDataImageDownload(img, style, type));
- return;
+ ImageDownloadCB *cb = dynamic_cast(*it);
+ if (cb)
+ {
+ cb->addImage(img, style, type);
+ // return pointer to shared ImageDownloadCB
+ return cb;
+ }
+ else
+ {
+ nlwarning("Found image download '%s', but casting to ImageDownloadCB failed", finalUrl.c_str());
+ }
}
}
- Curls.push_back(CDataDownload(finalUrl, dest, ImgType, img, "", "", style, type));
- pumpCurlQueue();
+ Curls.push_back(new ImageDownloadCB(finalUrl, dest, img, style, type, this));
+ // as we return pointer to callback, skip starting downloads just now
+ //pumpCurlQueue();
+ return Curls.back();
}
- void CGroupHTML::removeImageDownload(CViewBase *img)
+ void CGroupHTML::removeImageDownload(ICurlDownloadCB *handle, CViewBase *img)
{
- for(std::list::iterator it = Curls.begin(); it != Curls.end(); ++it)
- {
- // check all active downloads because image does not keep url around
- std::vector::iterator imgIter = it->imgs.begin();
- while(imgIter != it->imgs.end())
- {
- if (imgIter->Image == img)
- {
- it->imgs.erase(imgIter);
- break;
- }
- ++imgIter;
- }
+ ImageDownloadCB *cb = dynamic_cast(handle);
+ if (!cb) {
+ nlwarning("Trying to remove image from downloads, but ICurlDownloadCB pointer did not cast to ImageDownloadCB");
+ return;
}
+ // image will be removed from handle, but handle is kept and image will be downloaded
+ cb->removeImage(img);
}
void CGroupHTML::initImageDownload()
@@ -815,9 +836,9 @@ namespace NLGUI
url = upgradeInsecureUrl(getAbsoluteUrl(url));
// Search if we are not already downloading this url.
- for(std::list::const_iterator it = Curls.begin(); it != Curls.end(); ++it)
+ for(std::list::const_iterator it = Curls.begin(); it != Curls.end(); ++it)
{
- if(it->url == url)
+ if((*it)->url == url)
{
LOG_DL("already downloading '%s'", url.c_str());
return false;
@@ -842,7 +863,7 @@ namespace NLGUI
}
if (action != "delete")
{
- Curls.push_back(CDataDownload(url, dest, BnpType, NULL, script, md5sum));
+ Curls.push_back(new BnpDownloadCB(url, dest, md5sum, script, this));
pumpCurlQueue();
}
else
@@ -871,7 +892,7 @@ namespace NLGUI
_StylesheetQueue.back().Url = url;
// push to the front of the queue
- Curls.push_front(CDataDownload(url, localImageName(url), StylesheetType, NULL, "", ""));
+ Curls.push_front(new StylesheetDownloadCB(url, localImageName(url), this));
}
pumpCurlQueue();
}
@@ -915,9 +936,9 @@ namespace NLGUI
}
else
{
- for(std::list::iterator it = Curls.begin(); it != Curls.end(); ++it)
+ for(std::list::iterator it = Curls.begin(); it != Curls.end(); ++it)
{
- if(it->data && it->data->Request == msg->easy_handle)
+ if((*it)->data && (*it)->data->Request == msg->easy_handle)
{
std::string error;
bool success = msg->data.result == CURLE_OK;
@@ -956,27 +977,30 @@ namespace NLGUI
}
// remove all queued and already started downloads
- for(std::list::iterator it = Curls.begin(); it != Curls.end(); ++it)
+ for(std::list::iterator it = Curls.begin(); it != Curls.end(); ++it)
{
- if (it->data)
+ CDataDownload &dl = *(*it);
+ if (dl.data)
{
- LOG_DL("(%s) stop data url '%s'", _Id.c_str(), it->url.c_str());
+ LOG_DL("(%s) stop data url '%s'", _Id.c_str(), dl.url.c_str());
if (MultiCurl)
{
- curl_multi_remove_handle(MultiCurl, it->data->Request);
+ curl_multi_remove_handle(MultiCurl, dl.data->Request);
}
// close and remove temp file
- if (it->fp)
+ if (dl.fp)
{
- fclose(it->fp);
+ fclose(dl.fp);
- if (CFile::fileExists(it->tmpdest))
+ if (CFile::fileExists(dl.tmpdest))
{
- CFile::deleteFile(it->tmpdest);
+ CFile::deleteFile(dl.tmpdest);
}
}
}
+ // release CDataDownload
+ delete *it;
}
Curls.clear();
@@ -2935,10 +2959,10 @@ namespace NLGUI
LOG_DL("Clear pointers to %d curls", Curls.size());
// remove image refs from downloads
- for(std::list::iterator it = Curls.begin(); it != Curls.end(); ++it)
+ /*for(std::list::iterator it = Curls.begin(); it != Curls.end(); ++it)
{
it->imgs.clear();
- }
+ }*/
}
// ***************************************************************************
@@ -3691,96 +3715,98 @@ namespace NLGUI
updateRefreshButton();
}
- void CGroupHTML::dataDownloadFinished(bool success, const std::string &error, CDataDownload &data)
+ void CGroupHTML::dataDownloadFinished(bool success, const std::string &error, CDataDownload *data)
{
- fclose(data.fp);
+ fclose(data->fp);
- CUrlParser uri(data.url);
+ CUrlParser uri(data->url);
if (!uri.host.empty())
{
- receiveCookies(data.data->Request, uri.host, isTrustedDomain(uri.host));
+ receiveCookies(data->data->Request, uri.host, isTrustedDomain(uri.host));
}
long code = -1;
- curl_easy_getinfo(data.data->Request, CURLINFO_RESPONSE_CODE, &code);
+ curl_easy_getinfo(data->data->Request, CURLINFO_RESPONSE_CODE, &code);
- LOG_DL("(%s) transfer '%p' completed with http code %d, url (len %d) '%s'", _Id.c_str(), data.data->Request, code, data.url.size(), data.url.c_str());
- curl_multi_remove_handle(MultiCurl, data.data->Request);
+ LOG_DL("(%s) transfer '%p' completed with http code %d, url (len %d) '%s'", _Id.c_str(), data->data->Request, code, data->url.size(), data->url.c_str());
+ curl_multi_remove_handle(MultiCurl, data->data->Request);
// save HSTS header from all requests regardless of HTTP code
if (success)
{
- if (data.data->hasHSTSHeader())
+ if (data->data->hasHSTSHeader())
{
- CStrictTransportSecurity::getInstance()->setFromHeader(uri.host, data.data->getHSTSHeader());
+ CStrictTransportSecurity::getInstance()->setFromHeader(uri.host, data->data->getHSTSHeader());
}
// 2XX success, 304 Not Modified
if ((code >= 200 && code <= 204) || code == 304)
{
CHttpCacheObject obj;
- obj.Expires = data.data->getExpires();
- obj.Etag = data.data->getEtag();
- obj.LastModified = data.data->getLastModified();
+ obj.Expires = data->data->getExpires();
+ obj.Etag = data->data->getEtag();
+ obj.LastModified = data->data->getLastModified();
- CHttpCache::getInstance()->store(data.dest, obj);
- if (code == 304 && CFile::fileExists(data.tmpdest))
+ CHttpCache::getInstance()->store(data->dest, obj);
+ if (code == 304 && CFile::fileExists(data->tmpdest))
{
- CFile::deleteFile(data.tmpdest);
+ CFile::deleteFile(data->tmpdest);
}
}
else if ((code >= 301 && code <= 303) || code == 307 || code == 308)
{
- if (data.redirects < DEFAULT_RYZOM_REDIRECT_LIMIT)
+ if (data->redirects < DEFAULT_RYZOM_REDIRECT_LIMIT)
{
- std::string location(data.data->getLocationHeader());
+ std::string location(data->data->getLocationHeader());
if (!location.empty())
{
CUrlParser uri(location);
if (!uri.isAbsolute())
{
- uri.inherit(data.url);
+ uri.inherit(data->url);
location = uri.toString();
}
+ // clear old request state, and curl easy handle
+ delete data->data;
+ data->data = NULL;
+ data->fp = NULL;
+ data->url = location;
+ data->redirects++;
+
// push same request in the front of the queue
// cache filename is based of original url
Curls.push_front(data);
- // clear old request state
- Curls.front().data = NULL;
- Curls.front().fp = NULL;
- Curls.front().url = location;
- Curls.front().redirects++;
LOG_DL("Redirect '%s'", location.c_str());
// no finished callback called, so cleanup old temp
- if (CFile::fileExists(data.tmpdest))
+ if (CFile::fileExists(data->tmpdest))
{
- CFile::deleteFile(data.tmpdest);
+ CFile::deleteFile(data->tmpdest);
}
return;
}
- nlwarning("Redirected to empty url '%s'", data.url.c_str());
+ nlwarning("Redirected to empty url '%s'", data->url.c_str());
}
else
{
- nlwarning("Redirect limit reached for '%s'", data.url.c_str());
+ nlwarning("Redirect limit reached for '%s'", data->url.c_str());
}
}
else
{
- nlwarning("HTTP request failed with code [%d] for '%s'\n",code, data.url.c_str());
+ nlwarning("HTTP request failed with code [%d] for '%s'\n",code, data->url.c_str());
// 404, 500, etc
- if (CFile::fileExists(data.dest))
+ if (CFile::fileExists(data->dest))
{
- CFile::deleteFile(data.dest);
+ CFile::deleteFile(data->dest);
}
}
}
else
{
- nlwarning("DATA download failed '%s', error '%s'", data.url.c_str(), error.c_str());
+ nlwarning("DATA download failed '%s', error '%s'", data->url.c_str(), error.c_str());
}
finishCurlDownload(data);
diff --git a/nel/src/gui/view_bitmap.cpp b/nel/src/gui/view_bitmap.cpp
index 4186a4362..89c944a18 100644
--- a/nel/src/gui/view_bitmap.cpp
+++ b/nel/src/gui/view_bitmap.cpp
@@ -46,8 +46,8 @@ namespace NLGUI
{
CGroupHTML *groupHtml = dynamic_cast(CWidgetManager::getInstance()->getElementFromId("ui:interface:webig:content:html"));
if (groupHtml) {
- _HtmlDownload = false;
- groupHtml->removeImageDownload(dynamic_cast(this));
+ groupHtml->removeImageDownload(_HtmlDownload, dynamic_cast(this));
+ _HtmlDownload = NULL;
}
}
}
@@ -476,12 +476,14 @@ namespace NLGUI
if (!CFile::fileExists(localname))
localname = "web_del.tga";
_TextureId.setTexture (localname.c_str(), _TxtOffsetX, _TxtOffsetY, _TxtWidth, _TxtHeight, false);
- _HtmlDownload = true;
- groupHtml->addImageDownload(TxName, dynamic_cast(this));
+ _HtmlDownload = groupHtml->addImageDownload(TxName, dynamic_cast(this));
}
}
else
+ {
+ _HtmlDownload = NULL;
_TextureId.setTexture (TxName.c_str (), _TxtOffsetX, _TxtOffsetY, _TxtWidth, _TxtHeight, false);
+ }
}
// ----------------------------------------------------------------------------