diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h
index 479fc7384..2dc5e80bc 100644
--- a/code/nel/include/nel/gui/group_html.h
+++ b/code/nel/include/nel/gui/group_html.h
@@ -820,7 +820,8 @@ namespace NLGUI
struct CDataDownload
{
public:
- CDataDownload(CURL *c, const std::string &u, const std::string &d, FILE *f, TDataType t, CViewBase *i, const std::string &s, const std::string &m, const CStyleParams &style = CStyleParams()) : curl(c), url(u), dest(d), luaScript(s), md5sum(m), type(t), fp(f)
+ 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())
+ : curl(NULL), fp(NULL), url(u), dest(d), type(t), luaScript(s), md5sum(m)
{
if (t == ImgType) imgs.push_back(CDataImageDownload(i, style));
}
@@ -840,6 +841,8 @@ namespace NLGUI
CURLM *MultiCurl;
int RunningCurls;
+ bool startCurlDownload(CDataDownload &download);
+
void initImageDownload();
void checkImageDownload();
void addImageDownload(const std::string &url, CViewBase *img, const CStyleParams &style = CStyleParams());
diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index c5c4bb532..418704262 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -265,6 +265,61 @@ namespace NLGUI
return dest;
}
+ // Add url to MultiCurl queue and return cURL handle
+ bool CGroupHTML::startCurlDownload(CDataDownload &download)
+ {
+ if (!MultiCurl)
+ {
+ nlwarning("Invalid MultiCurl handle, unable to download '%s'", download.url.c_str());
+ return false;
+ }
+
+ string tmpdest = download.dest + ".tmp";
+
+ // erase the tmp file if exists
+ if (CFile::fileExists(tmpdest))
+ CFile::deleteFile(tmpdest);
+
+ FILE *fp = nlfopen (tmpdest, "wb");
+ if (fp == NULL)
+ {
+ nlwarning("Can't open file '%s' for writing: code=%d '%s'", tmpdest.c_str (), errno, strerror(errno));
+ return false;
+ }
+
+ CURL *curl = curl_easy_init();
+ if (!curl)
+ {
+ fclose(fp);
+ CFile::deleteFile(tmpdest);
+
+ nlwarning("Creating cURL handle failed, unable to download '%s'", download.url.c_str());
+ return false;
+ }
+
+ download.curl = curl;
+ download.fp = fp;
+
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, true);
+ 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);
+ curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
+
+ std::string userAgent = options.appName + "/" + options.appVersion;
+ curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str());
+
+ sendCookies(curl, _DocumentDomain, _TrustedDomain);
+
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
+
+ curl_multi_add_handle(MultiCurl, curl);
+
+ return true;
+ }
+
// Add a image download request in the multi_curl
void CGroupHTML::addImageDownload(const string &url, CViewBase *img, const CStyleParams &style)
{
@@ -285,55 +340,29 @@ namespace NLGUI
// use requested url for local name
string dest = localImageName(url);
- string tmpdest = localImageName(url)+".tmp";
#ifdef LOG_DL
nlwarning("add to download '%s' dest '%s' img %p", finalUrl.c_str(), dest.c_str(), img);
#endif
- // erase the tmp file if exists
- if (NLMISC::CFile::fileExists(tmpdest))
- NLMISC::CFile::deleteFile(tmpdest);
-
if (!NLMISC::CFile::fileExists(dest))
{
- if (!MultiCurl)
- {
- nlwarning("Invalid MultiCurl handle, unable to download '%s'", finalUrl.c_str());
- return;
- }
+ Curls.push_back(CDataDownload(finalUrl, dest, ImgType, img, "", "", style));
+ if (Curls.size() < options.curlMaxConnections) {
+ if (!startCurlDownload(Curls.back()))
+ {
+ Curls.pop_back();
+ return;
+ }
- CURL *curl = curl_easy_init();
- if (!curl)
- {
- nlwarning("Creating cURL handle failed, unable to download '%s'", finalUrl.c_str());
- return;
- }
-
- FILE *fp = nlfopen(tmpdest, "wb");
- if (fp == NULL)
- {
- curl_easy_cleanup(curl);
-
- nlwarning("Can't open file '%s' for writing: code=%d '%s'", tmpdest.c_str (), errno, strerror(errno));
- return;
- }
- curl_easy_setopt(curl, CURLOPT_NOPROGRESS, true);
- curl_easy_setopt(curl, CURLOPT_URL, finalUrl.c_str());
-
- std::string userAgent = options.appName + "/" + options.appVersion;
- curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str());
-
- sendCookies(curl, _DocumentDomain, _TrustedDomain);
-
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
-
- curl_multi_add_handle(MultiCurl, curl);
- Curls.push_back(CDataDownload(curl, finalUrl, dest, fp, ImgType, img, "", "", style));
+ RunningCurls++;
#ifdef LOG_DL
- nlwarning("adding handle %x, %d curls", curl, Curls.size());
+ nlwarning("(%s) adding handle %x, %d curls", _Id.c_str(), Curls.back().curl, Curls.size());
+ }
+ else
+ {
+ nlwarning("(%s) download queued, %d curls", _Id.c_str(), Curls.size());
#endif
- RunningCurls++;
+ }
}
else
{
@@ -378,14 +407,9 @@ namespace NLGUI
}
string dest = localBnpName(url);
- string tmpdest = localBnpName(url)+".tmp";
#ifdef LOG_DL
nlwarning("add to download '%s' dest '%s'", url.c_str(), dest.c_str());
#endif
-
- // erase the tmp file if exists
- if (NLMISC::CFile::fileExists(tmpdest))
- NLMISC::CFile::deleteFile(tmpdest);
// create/delete the local file
if (NLMISC::CFile::fileExists(dest))
@@ -402,39 +426,23 @@ namespace NLGUI
}
if (action != "delete")
{
- if (!MultiCurl)
+ Curls.push_back(CDataDownload(url, dest, BnpType, NULL, script, md5sum));
+ if (Curls.size() < options.curlMaxConnections)
{
- nlwarning("Invalid MultiCurl handle, unable to download '%s'", url.c_str());
- return false;
- }
-
- CURL *curl = curl_easy_init();
- if (!curl)
- {
- nlwarning("Creating cURL handle failed, unable to download '%s'", url.c_str());
- return false;
- }
-
- FILE *fp = nlfopen (tmpdest, "wb");
- if (fp == NULL)
- {
- curl_easy_cleanup(curl);
- nlwarning("Can't open file '%s' for writing: code=%d '%s'", tmpdest.c_str (), errno, strerror(errno));
- return false;
- }
-
- curl_easy_setopt(curl, CURLOPT_NOPROGRESS, true);
- curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
-
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
-
- curl_multi_add_handle(MultiCurl, curl);
- Curls.push_back(CDataDownload(curl, url, dest, fp, BnpType, NULL, script, md5sum));
+ if (!startCurlDownload(Curls.back()))
+ {
+ Curls.pop_back();
+ return false;
+ }
+ RunningCurls++;
#ifdef LOG_DL
- nlwarning("adding handle %x, %d curls", curl, Curls.size());
+ nlwarning("(%s) adding handle %x, %d curls", _Id.c_str(), Curls.back().curl, Curls.size());
+ }
+ else
+ {
+ nlwarning("(%s) download queued, %d curls", _Id.c_str(), Curls.size());
#endif
- RunningCurls++;
+ }
}
else
return true;
@@ -631,7 +639,30 @@ namespace NLGUI
}
}
}
+
RunningCurls = NewRunningCurls;
+
+ if (RunningCurls < options.curlMaxConnections)
+ {
+ for (vector::iterator it=Curls.begin(); itcurl == NULL) {
+ #ifdef LOG_DL
+ nlwarning("(%s) starting new download '%s'", _Id.c_str(), it->url.c_str());
+ #endif
+ if (!startCurlDownload(*it))
+ {
+ Curls.erase(it);
+ break;
+ }
+
+ RunningCurls++;
+ if (RunningCurls >= options.curlMaxConnections)
+ break;
+ }
+ }
+ }
+
#ifdef LOG_DL
if (RunningCurls > 0 || !Curls.empty())
nlwarning("(%s) RunningCurls %d, _Curls %d", _Id.c_str(), RunningCurls, Curls.size());
@@ -4531,6 +4562,18 @@ namespace NLGUI
Curls[i].imgs.clear();
}
+ // remove download that are still queued
+ for (vector::iterator it=Curls.begin(); itcurl == NULL) {
+ #ifdef LOG_DL
+ nlwarning("Remove waiting curl download (%s)", it->url.c_str());
+ #endif
+ it = Curls.erase(it);
+ } else {
+ ++it;
+ }
+ }
}
// ***************************************************************************