linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #06168
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3082: fix [L#668548] as well as implement chunked transfer encoding per HTTP/1.1 Specification
------------------------------------------------------------
revno: 3082
author: Crise
committer: iceman50 <bdcdevel@xxxxxxxxx>
branch nick: dcplusplus
timestamp: Sat 2012-10-20 11:10:39 -0500
message:
fix [L#668548] as well as implement chunked transfer encoding per HTTP/1.1 Specification
modified:
dcpp/BufferedSocket.cpp
dcpp/FavoriteManager.cpp
dcpp/FavoriteManager.h
dcpp/HttpConnection.cpp
dcpp/HttpConnection.h
dcpp/HttpConnectionListener.h
dcpp/HttpDownload.cpp
dcpp/HttpDownload.h
win32/AboutDlg.cpp
win32/MainWindow.cpp
win32/MainWindow.h
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'dcpp/BufferedSocket.cpp'
--- dcpp/BufferedSocket.cpp 2012-06-22 14:46:44 +0000
+++ dcpp/BufferedSocket.cpp 2012-10-20 16:10:39 +0000
@@ -279,6 +279,7 @@
if(dataBytes == 0) {
mode = MODE_LINE;
fire(BufferedSocketListener::ModeChange());
+ break; // break loop, in case setDataMode is called with less than read buffer size
}
}
}
=== modified file 'dcpp/FavoriteManager.cpp'
--- dcpp/FavoriteManager.cpp 2012-07-13 19:41:18 +0000
+++ dcpp/FavoriteManager.cpp 2012-10-20 16:10:39 +0000
@@ -790,6 +790,8 @@
bool parseSuccess = false;
c->removeListener(this);
if(useHttp) {
+ if(c->getMimeType() == "application/x-bzip2")
+ listType = TYPE_BZIP2;
parseSuccess = onHttpFinished(true);
}
running = false;
@@ -801,14 +803,6 @@
if(useHttp)
fire(FavoriteManagerListener::DownloadStarting(), aLine);
}
-void FavoriteManager::on(TypeNormal, HttpConnection*) noexcept {
- if(useHttp)
- listType = TYPE_NORMAL;
-}
-void FavoriteManager::on(TypeBZ2, HttpConnection*) noexcept {
- if(useHttp)
- listType = TYPE_BZIP2;
-}
void FavoriteManager::on(Retried, HttpConnection*, bool connected) noexcept {
if(connected)
downloadBuf.clear();
=== modified file 'dcpp/FavoriteManager.h'
--- dcpp/FavoriteManager.h 2012-05-15 23:26:22 +0000
+++ dcpp/FavoriteManager.h 2012-10-20 16:10:39 +0000
@@ -165,8 +165,6 @@
void on(Failed, HttpConnection*, const string&) noexcept;
void on(Complete, HttpConnection*, const string&, bool) noexcept;
void on(Redirected, HttpConnection*, const string&) noexcept;
- void on(TypeNormal, HttpConnection*) noexcept;
- void on(TypeBZ2, HttpConnection*) noexcept;
void on(Retried, HttpConnection*, bool) noexcept;
bool onHttpFinished(bool fromHttp) noexcept;
=== modified file 'dcpp/HttpConnection.cpp'
--- dcpp/HttpConnection.cpp 2012-07-13 18:50:28 +0000
+++ dcpp/HttpConnection.cpp 2012-10-20 16:10:39 +0000
@@ -28,11 +28,12 @@
static const std::string CORAL_SUFFIX = ".nyud.net";
-HttpConnection::HttpConnection(bool coralize) :
-ok(false),
+HttpConnection::HttpConnection(bool coralize, const string& aUserAgent) :
+userAgent(aUserAgent),
port("80"),
size(-1),
-moved302(false),
+done(0),
+connState(CONN_UNKNOWN),
coralizeState(coralize ? CST_DEFAULT : CST_NOCORALIZE),
socket(0)
{
@@ -40,8 +41,7 @@
HttpConnection::~HttpConnection() {
if(socket) {
- socket->removeListener(this);
- BufferedSocket::putSocket(socket);
+ abortRequest(true);
}
}
@@ -52,21 +52,48 @@
* @param aUrl Full URL of file
* @return A string with the content, or empty if download failed
*/
-void HttpConnection::downloadFile(const string& aUrl) {
- dcassert(Util::findSubString(aUrl, "http://") == 0);
+void HttpConnection::downloadFile(const string& aFile) {
+ currentUrl = aFile;
+ prepareRequest(TYPE_GET);
+}
+
+/**
+ * Initiates a basic urlencoded form submission
+ * @param aFile Fully qualified file URL
+ * @param aData StringMap with the args and values
+ */
+void HttpConnection::postData(const string& aUrl, const StringMap& aData) {
currentUrl = aUrl;
+ coralizeState = CST_NOCORALIZE;
+ requestBody.clear();
+
+ for(StringMap::const_iterator i = aData.begin(); i != aData.end(); ++i)
+ requestBody += "&" + Util::encodeURI(i->first) + "=" + Util::encodeURI(i->second);
+
+ if (!requestBody.empty()) requestBody = requestBody.substr(1);
+ prepareRequest(TYPE_POST);
+}
+
+void HttpConnection::prepareRequest(RequestType type) {
+ dcassert(Util::findSubString(currentUrl, "http://") == 0 || Util::findSubString(currentUrl, "https://") == 0);
Util::sanitizeUrl(currentUrl);
- // reset all settings (as in constructor), moved here from onLine(302) because ok was not reset properly
- moved302 = false;
- ok = false;
+ // Reset the connection states
+ if(connState == CONN_OK || connState == CONN_FAILED)
+ userAgent.clear();
+
size = -1;
+ done = 0;
+ connState = CONN_UNKNOWN;
+ connType = type;
+
+ // method selection
+ method = (connType == TYPE_POST) ? "POST" : "GET";
+
// set download type
- if(Util::stricmp(currentUrl.substr(currentUrl.size() - 4), ".bz2") == 0) {
- fire(HttpConnectionListener::TypeBZ2(), this);
- } else {
- fire(HttpConnectionListener::TypeNormal(), this);
- }
+ if(stricmp(currentUrl.substr(currentUrl.size() - 4).c_str(), ".bz2") == 0) {
+ mimeType = "application/x-bzip2";
+ } else mimeType.clear();
string proto, query, fragment;
if(SETTING(HTTP_PROXY).empty()) {
@@ -87,23 +114,37 @@
} else {
coralizeState = CST_NOCORALIZE;
}
-
}
if(port.empty())
port = "80";
- if(!socket) {
+ if(userAgent.empty())
+ userAgent = dcpp::fullVersionString;
+
+ if(!socket)
socket = BufferedSocket::getSocket(0x0a);
- }
+
+
socket->addListener(this);
try {
- socket->connect(server, port, false, false, false);
+ socket->connect(server, port, (proto == "https"), true, false);
} catch(const Exception& e) {
fire(HttpConnectionListener::Failed(), this, e.getError() + " (" + currentUrl + ")");
+ connState = CONN_FAILED;
}
}
+void HttpConnection::abortRequest(bool disconnect) {
+ dcassert(socket);
+
+ socket->removeListener(this);
+ if(disconnect) socket->disconnect();
+
+ BufferedSocket::putSocket(socket);
+ socket = NULL;
+}
+
void HttpConnection::on(BufferedSocketListener::Connected) noexcept {
dcassert(socket);
socket->write("GET " + file + " HTTP/1.1\r\n");
@@ -115,86 +156,108 @@
string tfile, tport, proto, query, fragment;
Util::decodeUrl(file, proto, sRemoteServer, tport, tfile, query, fragment);
}
+
socket->write("Host: " + sRemoteServer + "\r\n");
socket->write("Connection: close\r\n"); // we'll only be doing one request
socket->write("Cache-Control: no-cache\r\n\r\n");
+ if (connType == TYPE_POST) socket->write(requestBody);
if (coralizeState == CST_DEFAULT) coralizeState = CST_CONNECTED;
}
void HttpConnection::on(BufferedSocketListener::Line, const string& aLine) noexcept {
- if(!ok) {
- dcdebug("%s\n",aLine.c_str());
- if(aLine.find("200") == string::npos) {
- if(aLine.find("301") != string::npos || aLine.find("302") != string::npos){
- moved302 = true;
+ if(connState == CONN_CHUNKED && aLine.size() > 1) {
+ string::size_type i;
+ string chunkSizeStr;
+ if((i = aLine.find(";")) == string::npos) {
+ chunkSizeStr = aLine.substr(0, aLine.length() - 1);
+ } else chunkSizeStr = aLine.substr(0, i);
+
+ unsigned long chunkSize = strtoul(chunkSizeStr.c_str(), NULL, 16);
+ if(chunkSize == 0 || chunkSize == ULONG_MAX) {
+ abortRequest(true);
+
+ if(chunkSize == 0) {
+ fire(HttpConnectionListener::Complete(), this, currentUrl, SETTING(CORAL) && coralizeState != CST_NOCORALIZE);
+ connState = CONN_OK;
} else {
- socket->disconnect();
- socket->removeListener(this);
- BufferedSocket::putSocket(socket);
- socket = NULL;
- if(SETTING(CORAL) && coralizeState != CST_NOCORALIZE) {
- fire(HttpConnectionListener::Retried(), this, coralizeState == CST_CONNECTED);
- coralizeState = CST_NOCORALIZE;
- dcdebug("HTTP error with Coral, retrying : %s\n",currentUrl.c_str());
- downloadFile(currentUrl);
- return;
- }
- fire(HttpConnectionListener::Failed(), this, str(F_("%1% (%2%)") % aLine % currentUrl));
- coralizeState = CST_DEFAULT;
+ fire(HttpConnectionListener::Failed(), this, "Transfer-encoding error (" + currentUrl + ")");
+ connState = CONN_FAILED;
+ }
+
+ coralizeState = CST_DEFAULT;
+ } else socket->setDataMode(chunkSize);
+ } else if(connState == CONN_UNKNOWN) {
+ if(aLine.find("200") != string::npos) {
+ connState = CONN_OK;
+ } else if(aLine.find("301") != string::npos || aLine.find("302") != string::npos) {
+ connState = CONN_MOVED;
+ } else {
+ abortRequest(true);
+
+ if(SETTING(CORAL) && coralizeState != CST_NOCORALIZE) {
+ fire(HttpConnectionListener::Retried(), this, coralizeState == CST_CONNECTED);
+ coralizeState = CST_NOCORALIZE;
+ dcdebug("HTTP error with Coral, retrying : %s\n",currentUrl.c_str());
+ downloadFile(currentUrl);
return;
}
+
+ fire(HttpConnectionListener::Failed(), this, str(F_("%1% (%2%)") % aLine % currentUrl));
+ connState = CONN_FAILED;
+ coralizeState = CST_DEFAULT;
}
- ok = true;
- } else if(moved302 && Util::findSubString(aLine, "Location") != string::npos){
- dcassert(socket);
- socket->removeListener(this);
- socket->disconnect();
- BufferedSocket::putSocket(socket);
- socket = NULL;
+ } else if(connState == CONN_MOVED && Util::findSubString(aLine, "Location") != string::npos) {
+ abortRequest(true);
- string location302 = aLine.substr(10, aLine.length() - 10);
- Util::sanitizeUrl(location302);
+ string location = aLine.substr(10, aLine.length() - 10);
+ Util::sanitizeUrl(location);
// make sure we can also handle redirects with relative paths
- if(Util::strnicmp(location302.c_str(), "http://", 7) != 0) {
- if(location302[0] == '/') {
+ if(location.find("://") == string::npos) {
+ if(location[0] == '/') {
string proto, query, fragment;
Util::decodeUrl(currentUrl, proto, server, port, file, query, fragment);
- string tmp = "http://" + server;
- if(port != "80")
+ string tmp = proto + "://" + server;
+ if(port != "80" || port != "443")
tmp += ':' + port;
- location302 = tmp + location302;
+ location = tmp + location;
} else {
string::size_type i = currentUrl.rfind('/');
dcassert(i != string::npos);
- location302 = currentUrl.substr(0, i + 1) + location302;
+ location = currentUrl.substr(0, i + 1) + location;
}
}
- if(location302 == currentUrl) {
+ if(location == currentUrl) {
+ connState = CONN_FAILED;
fire(HttpConnectionListener::Failed(), this, str(F_("Endless redirection loop (%1%)") % currentUrl));
return;
}
- fire(HttpConnectionListener::Redirected(), this, location302);
-
- coralizeState = CST_DEFAULT;
- downloadFile(location302);
-
- } else if(aLine == "\x0d") {
- socket->setDataMode(size);
+ fire(HttpConnectionListener::Redirected(), this, location);
+
+ if (coralizeState != CST_NOCORALIZE)
+ coralizeState = CST_DEFAULT;
+
+ downloadFile(location);
+ } else if(aLine[0] == 0x0d) {
+ if(size != -1) {
+ socket->setDataMode(size);
+ } else connState = CONN_CHUNKED;
} else if(Util::findSubString(aLine, "Content-Length") != string::npos) {
size = Util::toInt(aLine.substr(16, aLine.length() - 17));
- } else if(Util::findSubString(aLine, "Content-Encoding") != string::npos) {
- if(aLine.substr(18, aLine.length() - 19) == "x-bzip2")
- fire(HttpConnectionListener::TypeBZ2(), this);
+ } else if(mimeType.empty()) {
+ if(Util::findSubString(aLine, "Content-Encoding") != string::npos) {
+ if(aLine.substr(18, aLine.length() - 19) == "x-bzip2")
+ mimeType = "application/x-bzip2";
+ } else if(Util::findSubString(aLine, "Content-Type") != string::npos) {
+ mimeType = aLine.substr(14, aLine.length() - 15);
+ }
}
}
void HttpConnection::on(BufferedSocketListener::Failed, const string& aLine) noexcept {
- socket->removeListener(this);
- BufferedSocket::putSocket(socket);
- socket = NULL;
+ abortRequest(false);
if(SETTING(CORAL) && coralizeState != CST_NOCORALIZE) {
fire(HttpConnectionListener::Retried(), this, coralizeState == CST_CONNECTED);
coralizeState = CST_NOCORALIZE;
@@ -202,20 +265,32 @@
downloadFile(currentUrl);
return;
}
+
+ connState = CONN_FAILED;
coralizeState = CST_DEFAULT;
fire(HttpConnectionListener::Failed(), this, str(F_("%1% (%2%)") % aLine % currentUrl));
}
void HttpConnection::on(BufferedSocketListener::ModeChange) noexcept {
- socket->removeListener(this);
- socket->disconnect();
- BufferedSocket::putSocket(socket);
- socket = NULL;
- fire(HttpConnectionListener::Complete(), this, currentUrl, SETTING(CORAL) && coralizeState != CST_NOCORALIZE);
- coralizeState = CST_DEFAULT;
+ if(connState != CONN_CHUNKED) {
+ abortRequest(true);
+
+ fire(HttpConnectionListener::Complete(), this, currentUrl, SETTING(CORAL) && coralizeState != CST_NOCORALIZE);
+ coralizeState = CST_DEFAULT;
+ }
}
void HttpConnection::on(BufferedSocketListener::Data, uint8_t* aBuf, size_t aLen) noexcept {
+ if(size != -1 && static_cast<size_t>(size - done) < aLen) {
+ abortRequest(true);
+
+ connState = CONN_FAILED;
+ coralizeState = CST_DEFAULT;
+ fire(HttpConnectionListener::Failed(), this, "Too much data in response body (" + currentUrl + ")");
+ return;
+ }
+
fire(HttpConnectionListener::Data(), this, aBuf, aLen);
+ done += aLen;
}
} // namespace dcpp
=== modified file 'dcpp/HttpConnection.h'
--- dcpp/HttpConnection.h 2012-01-13 20:55:20 +0000
+++ dcpp/HttpConnection.h 2012-10-20 16:10:39 +0000
@@ -22,6 +22,7 @@
#include "BufferedSocketListener.h"
#include "HttpConnectionListener.h"
#include "Speaker.h"
+#include "Util.h"
namespace dcpp {
@@ -30,25 +31,43 @@
class HttpConnection : BufferedSocketListener, public Speaker<HttpConnectionListener>, boost::noncopyable
{
public:
- HttpConnection(bool coralize = true);
+ HttpConnection(bool coralize = true, const string& aUserAgent = Util::emptyString);
virtual ~HttpConnection();
void downloadFile(const string& aUrl);
+ void postData(const string& aUrl, const StringMap& aData);
+
+ const string& getMimeType() const { return mimeType; }
+
+ int64_t getSize() const { return size; }
+ int64_t getDone() const { return done; }
private:
- enum CoralizeState { CST_DEFAULT, CST_CONNECTED, CST_NOCORALIZE };
-
- string currentUrl;
- string file;
- string server;
- bool ok;
- string port;
- int64_t size;
- bool moved302;
-
- CoralizeState coralizeState;
-
- BufferedSocket* socket;
+ enum RequestType { TYPE_GET, TYPE_POST };
+ enum ConnectionStates { CONN_UNKNOWN, CONN_OK, CONN_FAILED, CONN_MOVED, CONN_CHUNKED };
+ enum CoralizeStates { CST_DEFAULT, CST_CONNECTED, CST_NOCORALIZE };
+
+ string currentUrl;
+ string userAgent;
+ string method;
+ string file;
+ string server;
+ string port;
+
+ string requestBody;
+
+ string mimeType;
+ int64_t size;
+ int64_t done;
+
+ ConnectionStates connState;
+ CoralizeStates coralizeState;
+ RequestType connType;
+
+ BufferedSocket* socket;
+
+ void prepareRequest(RequestType type);
+ void abortRequest(bool disconnect);
// BufferedSocketListener
void on(Connected) noexcept;
@@ -56,9 +75,6 @@
void on(Data, uint8_t*, size_t) noexcept;
void on(ModeChange) noexcept;
void on(Failed, const string&) noexcept;
-
- void onConnected();
- void onLine(const string& aLine);
};
} // namespace dcpp
=== modified file 'dcpp/HttpConnectionListener.h'
--- dcpp/HttpConnectionListener.h 2012-01-13 20:55:20 +0000
+++ dcpp/HttpConnectionListener.h 2012-10-20 16:10:39 +0000
@@ -36,16 +36,12 @@
typedef X<1> Failed;
typedef X<2> Complete;
typedef X<3> Redirected;
- typedef X<4> TypeNormal;
- typedef X<5> TypeBZ2;
- typedef X<6> Retried;
+ typedef X<4> Retried;
virtual void on(Data, HttpConnection*, const uint8_t*, size_t) noexcept = 0;
virtual void on(Failed, HttpConnection*, const string&) noexcept = 0;
virtual void on(Complete, HttpConnection*, const string&, bool) noexcept = 0;
virtual void on(Redirected, HttpConnection*, const string&) noexcept { }
- virtual void on(TypeNormal, HttpConnection*) noexcept { }
- virtual void on(TypeBZ2, HttpConnection*) noexcept { }
virtual void on(Retried, HttpConnection*, bool) noexcept { }
};
=== modified file 'dcpp/HttpDownload.cpp'
--- dcpp/HttpDownload.cpp 2012-01-13 20:55:20 +0000
+++ dcpp/HttpDownload.cpp 2012-10-20 16:10:39 +0000
@@ -21,31 +21,41 @@
namespace dcpp {
-HttpDownload::HttpDownload(const string& address, CompletionF f, bool coralize) :
+HttpDownload::HttpDownload(const string& address, CompletionFunc f, bool coralize) :
c(coralize),
-f(f)
+f(f),
+buf("")
{
c.addListener(this);
c.downloadFile(address);
}
+HttpDownload::HttpDownload(const string& address, const StringMap& data, CompletionFunc f, bool coralize) :
+c(coralize),
+f(f),
+buf("")
+{
+ c.addListener(this);
+ c.postData(address, data);
+}
+
HttpDownload::~HttpDownload() {
c.removeListener(this);
}
-void HttpDownload::on(HttpConnectionListener::Data, HttpConnection*, const uint8_t* buf_, size_t len) noexcept {
+void HttpDownload::on(HttpConnectionListener::Data, HttpConnection* c, const uint8_t* buf_, size_t len) noexcept {
+ if(buf.empty() && c->getSize() != -1)
+ buf.reserve(c->getSize());
buf.append(reinterpret_cast<const char*>(buf_), len);
}
-void HttpDownload::on(HttpConnectionListener::Failed, HttpConnection*, const string& status_) noexcept {
+void HttpDownload::on(HttpConnectionListener::Failed, HttpConnection*, const string& line) noexcept {
buf.clear();
- status = status_;
- f();
+ f(false, line);
}
-void HttpDownload::on(HttpConnectionListener::Complete, HttpConnection*, const string& status_, bool) noexcept {
- status = status_;
- f();
+void HttpDownload::on(HttpConnectionListener::Complete, HttpConnection*, const string& line, bool) noexcept {
+ f(true, buf);
}
void HttpDownload::on(HttpConnectionListener::Retried, HttpConnection*, bool connected) noexcept {
=== modified file 'dcpp/HttpDownload.h'
--- dcpp/HttpDownload.h 2012-01-13 20:55:20 +0000
+++ dcpp/HttpDownload.h 2012-10-20 16:10:39 +0000
@@ -27,19 +27,21 @@
/** Helper struct to manage a single HTTP download. Calls a completion function when finished. */
struct HttpDownload : private HttpConnectionListener, private boost::noncopyable {
+ typedef std::function<void (bool success, const string& result)> CompletionFunc;
+
+ explicit HttpDownload(const string& address, CompletionFunc f, bool coralize = true);
+ explicit HttpDownload(const string& address, const StringMap& data, CompletionFunc f, bool coralize = true);
+ ~HttpDownload();
+
+private:
HttpConnection c;
string buf;
- string status;
- typedef std::function<void ()> CompletionF;
- CompletionF f;
-
- explicit HttpDownload(const string& address, CompletionF f, bool coralize = true);
- ~HttpDownload();
+ CompletionFunc f;
// HttpConnectionListener
- void on(HttpConnectionListener::Data, HttpConnection*, const uint8_t* buf_, size_t len) noexcept;
- void on(HttpConnectionListener::Failed, HttpConnection*, const string& status_) noexcept;
- void on(HttpConnectionListener::Complete, HttpConnection*, const string& status_, bool) noexcept;
+ void on(HttpConnectionListener::Data, HttpConnection* c, const uint8_t* buf_, size_t len) noexcept;
+ void on(HttpConnectionListener::Failed, HttpConnection*, const string& line) noexcept;
+ void on(HttpConnectionListener::Complete, HttpConnection*, const string& line, bool) noexcept;
void on(HttpConnectionListener::Retried, HttpConnection*, bool connected) noexcept;
};
=== modified file 'win32/AboutDlg.cpp'
--- win32/AboutDlg.cpp 2012-10-11 16:37:31 +0000
+++ win32/AboutDlg.cpp 2012-10-20 16:10:39 +0000
@@ -152,7 +152,7 @@
centerWindow();
c.reset(new HttpDownload("http://dcplusplus.sourceforge.net/version.xml",
- [this] { callAsync([=] { completeDownload(); }); }));
+ [this](bool success, const string& result) { callAsync([=] { completeDownload(success, result); }); }));
return false;
}
@@ -162,13 +162,13 @@
grid->resize(dwt::Rectangle(3, 3, sz.x - 6, sz.y - 6));
}
-void AboutDlg::completeDownload() {
+void AboutDlg::completeDownload(bool success, const string& result) {
tstring str;
- if(!c->buf.empty()) {
+ if(success && !result.empty()) {
try {
SimpleXML xml;
- xml.fromXML(c->buf);
+ xml.fromXML(result);
if(xml.findChild("DCUpdate")) {
xml.stepIn();
if(xml.findChild("Version")) {
@@ -183,7 +183,7 @@
}
}
- version->setText(str.empty() ? Text::toT(c->status) : str);
+ version->setText(str.empty() ? Text::toT(result) : str);
c.reset();
}
=== modified file 'win32/MainWindow.cpp'
--- win32/MainWindow.cpp 2012-09-13 19:56:10 +0000
+++ win32/MainWindow.cpp 2012-10-20 16:10:39 +0000
@@ -174,7 +174,7 @@
TimerManager::getInstance()->start();
conns[CONN_VERSION].reset(new HttpDownload("http://dcplusplus.sourceforge.net/version.xml",
- [this] { callAsync([=] { completeVersionUpdate(); }); }));
+ [this](bool success, const string& result) { callAsync([=] { completeVersionUpdate(success, result); }); }));
try {
ConnectivityManager::getInstance()->setup(true);
@@ -1308,12 +1308,12 @@
}
}
-void MainWindow::completeVersionUpdate() {
+void MainWindow::completeVersionUpdate(bool success, const string& result) {
if(!conns[CONN_VERSION]) { return; }
try {
SimpleXML xml;
- xml.fromXML(conns[CONN_VERSION]->buf);
+ xml.fromXML(result);
xml.stepIn();
string url = Text::fromT(links.homepage);
@@ -1456,17 +1456,17 @@
LogManager::getInstance()->message(str(F_("Updating the %1% GeoIP database...") % (v6 ? "IPv6" : "IPv4")));
conn.reset(new HttpDownload(Text::fromT(v6 ? links.geoip6 : links.geoip4),
- [this, v6] { callAsync([=] { completeGeoUpdate(v6); }); }, false));
+ [this, v6](bool success, const string& result) { callAsync([=] { completeGeoUpdate(v6, success, result); }); }, false));
}
-void MainWindow::completeGeoUpdate(bool v6) {
+void MainWindow::completeGeoUpdate(bool v6, bool success, const string& result) {
auto& conn = conns[v6 ? CONN_GEO_V6 : CONN_GEO_V4];
if(!conn) { return; }
ScopedFunctor([&conn] { conn.reset(); });
- if(!conn->buf.empty()) {
+ if(success && !result.empty()) {
try {
- File(GeoManager::getDbPath(v6) + ".gz", File::WRITE, File::CREATE | File::TRUNCATE).write(conn->buf);
+ File(GeoManager::getDbPath(v6) + ".gz", File::WRITE, File::CREATE | File::TRUNCATE).write(result);
GeoManager::getInstance()->update(v6);
LogManager::getInstance()->message(str(F_("The %1% GeoIP database has been successfully updated") % (v6 ? "IPv6" : "IPv4")));
return;
=== modified file 'win32/MainWindow.h'
--- win32/MainWindow.h 2012-06-18 16:32:14 +0000
+++ win32/MainWindow.h 2012-10-20 16:10:39 +0000
@@ -206,12 +206,12 @@
void fillLimiterMenu(Menu* menu, bool upload);
void statusMessage(time_t t, const string& m);
- void completeVersionUpdate();
+ void completeVersionUpdate(bool success, const string& result);
void checkGeoUpdate();
void checkGeoUpdate(bool v6);
void updateGeo();
void updateGeo(bool v6);
- void completeGeoUpdate(bool v6);
+ void completeGeoUpdate(bool v6, bool success, const string& result);
bool filter(MSG& msg);