← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2620: Handle GeoIP database updates from within the program

 

------------------------------------------------------------
revno: 2620
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Sat 2011-10-01 16:33:43 +0200
message:
  Handle GeoIP database updates from within the program
modified:
  changelog.txt
  dcpp/FavoriteManager.cpp
  dcpp/FavoriteManager.h
  dcpp/HttpConnection.cpp
  dcpp/HttpConnection.h
  dcpp/Util.cpp
  dcpp/Util.h
  dcpp/ZUtils.cpp
  win32/AboutDlg.cpp
  win32/AboutDlg.h
  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 'changelog.txt'
--- changelog.txt	2011-09-30 12:13:00 +0000
+++ changelog.txt	2011-10-01 14:33:43 +0000
@@ -45,6 +45,7 @@
 * [L#425667] More accurate indexing time left calculation (poy)
 * Switch to binary GeoIP databases, add the IPv6 one (poy)
 * The country format can be customized, see help for available codes (poy)
+* Handle GeoIP database updates from within the program (iceman50, poy)
 
 -- 0.782 2011-03-05 --
 * Prevent a remote crash triggered via malformed user commands (poy)

=== modified file 'dcpp/FavoriteManager.cpp'
--- dcpp/FavoriteManager.cpp	2011-08-11 13:02:19 +0000
+++ dcpp/FavoriteManager.cpp	2011-10-01 14:33:43 +0000
@@ -836,9 +836,9 @@
 	if(useHttp)
 		listType = TYPE_BZIP2;
 }
-void FavoriteManager::on(Retried, HttpConnection*, const bool Connected) noexcept {
-	if (Connected)
-		downloadBuf = Util::emptyString;
+void FavoriteManager::on(Retried, HttpConnection*, bool connected) noexcept {
+	if(connected)
+		downloadBuf.clear();
 }
 
 void FavoriteManager::on(UserUpdated, const OnlineUser& user) noexcept {

=== modified file 'dcpp/FavoriteManager.h'
--- dcpp/FavoriteManager.h	2011-04-13 19:16:51 +0000
+++ dcpp/FavoriteManager.h	2011-10-01 14:33:43 +0000
@@ -161,7 +161,7 @@
 	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*, const bool) noexcept; 
+	virtual void on(Retried, HttpConnection*, bool) noexcept; 
 
 	bool onHttpFinished(bool fromHttp) noexcept;
 

=== modified file 'dcpp/HttpConnection.cpp'
--- dcpp/HttpConnection.cpp	2011-08-11 13:02:19 +0000
+++ dcpp/HttpConnection.cpp	2011-10-01 14:33:43 +0000
@@ -27,6 +27,23 @@
 
 static const std::string CORAL_SUFFIX = ".nyud.net";
 
+HttpConnection::HttpConnection(CoralizeState coralizeState) :
+ok(false),
+port("80"),
+size(-1),
+moved302(false),
+coralizeState(coralizeState),
+socket(0)
+{
+}
+
+HttpConnection::~HttpConnection() {
+	if(socket) {
+		socket->removeListener(this);
+		BufferedSocket::putSocket(socket);
+	}
+}
+
 /**
  * Downloads a file and returns it as a string
  * @todo Report exceptions
@@ -125,7 +142,7 @@
 					downloadFile(currentUrl);
 					return;
 				}
-				fire(HttpConnectionListener::Failed(), this, aLine + " (" + currentUrl + ")");
+				fire(HttpConnectionListener::Failed(), this, str(F_("%1% (%2%)") % aLine % currentUrl));
 				coralizeState = CST_DEFAULT;
 				return;
 			}

=== modified file 'dcpp/HttpConnection.h'
--- dcpp/HttpConnection.h	2011-08-11 13:02:19 +0000
+++ dcpp/HttpConnection.h	2011-10-01 14:33:43 +0000
@@ -44,26 +44,19 @@
 	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*, const bool) noexcept { }
+	virtual void on(Retried, HttpConnection*, bool) noexcept { }
 };
 
-class HttpConnection : BufferedSocketListener, public Speaker<HttpConnectionListener>
+class HttpConnection : BufferedSocketListener, public Speaker<HttpConnectionListener>, boost::noncopyable
 {
 public:
+	enum CoralizeState { CST_DEFAULT, CST_CONNECTED, CST_NOCORALIZE };
+	HttpConnection(CoralizeState coralizeState = CST_DEFAULT);
+	virtual ~HttpConnection();
+
 	void downloadFile(const string& aUrl);
-	HttpConnection() : ok(false), port("80"), size(-1), moved302(false), coralizeState(CST_DEFAULT), socket(NULL) { }
-	virtual ~HttpConnection() {
-		if(socket) {
-			socket->removeListener(this);
-			BufferedSocket::putSocket(socket);
-		}
-	}
 
 private:
-
-	HttpConnection(const HttpConnection&);
-	HttpConnection& operator=(const HttpConnection&);
-
 	string currentUrl;
 	string file;
 	string server;
@@ -72,8 +65,7 @@
 	int64_t size;
 	bool moved302;
 
-	enum CoralizeStates {CST_DEFAULT, CST_CONNECTED, CST_NOCORALIZE};
-	CoralizeStates coralizeState;
+	CoralizeState coralizeState;
 
 	BufferedSocket* socket;
 
@@ -86,7 +78,6 @@
 
 	void onConnected();
 	void onLine(const string& aLine);
-
 };
 
 } // namespace dcpp

=== modified file 'dcpp/Util.cpp'
--- dcpp/Util.cpp	2011-09-30 11:33:12 +0000
+++ dcpp/Util.cpp	2011-10-01 14:33:43 +0000
@@ -197,8 +197,8 @@
 	File::ensureDirectory(paths[PATH_USER_CONFIG]);
 	File::ensureDirectory(paths[PATH_USER_LOCAL]);
 
-	geo6.init(getPath(PATH_USER_LOCAL) + "GeoIPv6.dat");
-	geo4.init(getPath(PATH_USER_LOCAL) + "GeoIP.dat");
+	geo6.init(getGeoPath(true));
+	geo4.init(getGeoPath(false));
 }
 
 void Util::migrate(const string& file) {
@@ -250,6 +250,10 @@
 	}
 }
 
+string Util::getGeoPath(bool v6) {
+	return getPath(PATH_USER_LOCAL) + (v6 ? "GeoIPv6.dat" : "GeoIP.dat");
+}
+
 #ifdef _WIN32
 static const char badChars[] = {
 	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,

=== modified file 'dcpp/Util.h'
--- dcpp/Util.h	2011-09-30 11:33:12 +0000
+++ dcpp/Util.h	2011-10-01 14:33:43 +0000
@@ -157,6 +157,8 @@
 	static string getHubListsPath() { return getPath(PATH_HUB_LISTS); }
 	/** Notepad filename */
 	static string getNotepadFile() { return getPath(PATH_NOTEPAD); }
+	/** GeoIP database path */
+	static string getGeoPath(bool v6);
 
 	static string translateError(int aError);
 

=== modified file 'dcpp/ZUtils.cpp'
--- dcpp/ZUtils.cpp	2011-09-28 17:00:17 +0000
+++ dcpp/ZUtils.cpp	2011-10-01 14:33:43 +0000
@@ -135,7 +135,7 @@
 	if(!gz) {
 		throw Exception(_("Error during decompression"));
 	}
-	File f(target, File::WRITE, File::CREATE);
+	File f(target, File::WRITE, File::CREATE | File::TRUNCATE);
 
 	const size_t BUF_SIZE = 64 * 1024;
 	ByteVector buf(BUF_SIZE);

=== modified file 'win32/AboutDlg.cpp'
--- win32/AboutDlg.cpp	2011-06-24 16:08:35 +0000
+++ win32/AboutDlg.cpp	2011-10-01 14:33:43 +0000
@@ -185,9 +185,7 @@
 	conn->removeListener(this);
 }
 
-void AboutDlg::on(HttpConnectionListener::Retried, HttpConnection* /*conn*/, const bool Connected) noexcept {
-	if (Connected)
-		downBuf = Util::emptyString;
+void AboutDlg::on(HttpConnectionListener::Retried, HttpConnection* /*conn*/, bool connected) noexcept {
+	if(connected)
+		downBuf.clear();
 }
-
-

=== modified file 'win32/AboutDlg.h'
--- win32/AboutDlg.h	2011-05-04 19:32:00 +0000
+++ win32/AboutDlg.h	2011-10-01 14:33:43 +0000
@@ -46,10 +46,10 @@
 
 	void layout();
 
-	virtual void on(HttpConnectionListener::Data, HttpConnection* /*conn*/, const uint8_t* buf, size_t len) noexcept;
-	virtual void on(HttpConnectionListener::Complete, HttpConnection* conn, const string&, bool) noexcept;
-	virtual void on(HttpConnectionListener::Failed, HttpConnection* conn, const string& aLine) noexcept;
-	virtual void on(HttpConnectionListener::Retried, HttpConnection* conn, const bool Connected) noexcept;		
+	void on(HttpConnectionListener::Data, HttpConnection* /*conn*/, const uint8_t* buf, size_t len) noexcept;
+	void on(HttpConnectionListener::Complete, HttpConnection* conn, const string&, bool) noexcept;
+	void on(HttpConnectionListener::Failed, HttpConnection* conn, const string& aLine) noexcept;
+	void on(HttpConnectionListener::Retried, HttpConnection* conn, bool connected) noexcept;		
 };
 
 #endif // !defined(DCPLUSPLUS_WIN32_ABOUT_DLG_H)

=== modified file 'win32/MainWindow.cpp'
--- win32/MainWindow.cpp	2011-09-23 11:47:15 +0000
+++ win32/MainWindow.cpp	2011-10-01 14:33:43 +0000
@@ -20,25 +20,26 @@
 
 #include "MainWindow.h"
 
-#include <dcpp/SettingsManager.h>
-#include <dcpp/ResourceManager.h>
-#include <dcpp/version.h>
+#include <dcpp/Client.h>
+#include <dcpp/ClientManager.h>
+#include <dcpp/ConnectionManager.h>
+#include <dcpp/ConnectivityManager.h>
+#include <dcpp/Download.h>
 #include <dcpp/DownloadManager.h>
-#include <dcpp/UploadManager.h>
 #include <dcpp/FavoriteManager.h>
 #include <dcpp/LogManager.h>
-#include <dcpp/Client.h>
-#include <dcpp/TimerManager.h>
+#include <dcpp/QueueManager.h>
+#include <dcpp/ResourceManager.h>
+#include <dcpp/ScopedFunctor.h>
 #include <dcpp/SearchManager.h>
-#include <dcpp/ConnectionManager.h>
+#include <dcpp/SettingsManager.h>
 #include <dcpp/ShareManager.h>
-#include <dcpp/QueueManager.h>
-#include <dcpp/ClientManager.h>
-#include <dcpp/ConnectivityManager.h>
-#include <dcpp/Download.h>
-#include <dcpp/WindowInfo.h>
 #include <dcpp/SimpleXML.h>
 #include <dcpp/ThrottleManager.h>
+#include <dcpp/TimerManager.h>
+#include <dcpp/UploadManager.h>
+#include <dcpp/version.h>
+#include <dcpp/WindowInfo.h>
 
 #include <dwt/Application.h>
 #include <dwt/widgets/MessageBox.h>
@@ -97,7 +98,6 @@
 tabs(0),
 slotsSpin(0),
 tray_pm(false),
-c(0),
 stopperThread(NULL),
 lastUp(0),
 lastDown(0),
@@ -164,13 +164,16 @@
 
 	filterIter = dwt::Application::instance().addFilter([this](MSG &msg) { return filter(msg); });
 
+	File::ensureDirectory(SETTING(LOG_DIRECTORY));
+
 	TimerManager::getInstance()->start();
 
-	c = new HttpConnection;
-	c->addListener(this);
-	c->downloadFile("http://dcplusplus.sourceforge.net/version.xml";);
+	conns[CONN_VERSION].reset(new HttpConnWrapper("http://dcplusplus.sourceforge.net/version.xml";, this, [this] { completeVersionUpdate(); }));
 
-	File::ensureDirectory(SETTING(LOG_DIRECTORY));
+	if(BOOLSETTING(GET_USER_COUNTRY)) {
+		checkGeoUpdate(true);
+		checkGeoUpdate(false);
+	}
 
 	try {
 		ConnectivityManager::getInstance()->setup(true);
@@ -280,6 +283,8 @@
 
 		file->appendItem(T_("Settings\tCtrl+F3"), [this] { handleSettings(); }, WinUtil::menuIcon(IDI_SETTINGS));
 		file->appendSeparator();
+		file->appendItem(T_("GeoIP database update"), [this] { updateGeo(true); updateGeo(false); });
+		file->appendSeparator();
 		file->appendItem(T_("E&xit\tAlt+F4"), [this] { GCC_WTF->close(true); }, WinUtil::menuIcon(IDI_EXIT));
 	}
 
@@ -359,10 +364,6 @@
 		help->appendItem(T_("Donate (paypal)"), [this] { WinUtil::openLink(links.donate); }, WinUtil::menuIcon(IDI_DONATE));
 		help->appendItem(T_("Blog"), [this] { WinUtil::openLink(links.blog); });
 		help->appendItem(T_("Community news"), [this] { WinUtil::openLink(links.community); });
-		help->appendSeparator();
-
-		help->appendItem(T_("GeoIP database update (IPv6)"), [this] { WinUtil::openLink(links.geoip6); });
-		help->appendItem(T_("GeoIP database update (IPv4)"), [this] { WinUtil::openLink(links.geoip4); });
 	}
 
 	mainMenu->setMenu();
@@ -920,11 +921,10 @@
 bool MainWindow::handleClosing() {
 	if(!closing()) {
 		if ( !BOOLSETTING(CONFIRM_EXIT) || (dwt::MessageBox(this).show(T_("Really exit?"), _T(APPNAME) _T(" ") _T(VERSIONSTRING), dwt::MessageBox::BOX_YESNO, dwt::MessageBox::BOX_ICONQUESTION) == IDYES)) {
-			if (c != NULL) {
-				c->removeListener(this);
-				delete c;
-				c = NULL;
-			}
+
+			for(uint8_t i = 0; i < CONN_LAST; ++i)
+				conns[i].reset();
+
 			saveWindowSettings();
 
 			setVisible(false);
@@ -1180,47 +1180,10 @@
 	}
 }
 
-void MainWindow::parseCommandLine(const tstring& cmdLine)
-{
-	string::size_type i = 0;
-	string::size_type j;
-
-	if( (j = cmdLine.find(_T("dchub://"), i)) != string::npos ||
-		(j = cmdLine.find(_T("adc://"), i)) != string::npos ||
-		(j = cmdLine.find(_T("adcs://"), i)) != string::npos ||
-		(j = cmdLine.find(_T("magnet:?"), i)) != string::npos )
-	{
-		WinUtil::parseDBLClick(cmdLine.substr(j));
-	}
-}
-
-LRESULT MainWindow::handleCopyData(LPARAM lParam) {
-	parseCommandLine(Text::toT(WinUtil::getAppName() + " ") + reinterpret_cast<LPCTSTR>(reinterpret_cast<COPYDATASTRUCT*>(lParam)->lpData));
-	return TRUE;
-}
-
-void MainWindow::handleHashProgress() {
-	HashProgressDlg(this, false).run();
-}
-
-void MainWindow::handleCloseFavGroup(bool reversed) {
-	tstring group;
-	if(chooseFavHubGroup(reversed ? T_("Close hubs not in a favorite group") : T_("Close all hubs of a favorite group"), group))
-		HubFrame::closeFavGroup(Text::fromT(group), reversed);
-}
-
-void MainWindow::handleAbout() {
-	AboutDlg(this).run();
-}
-
-void MainWindow::handleOpenDownloadsDir() {
-	WinUtil::openFile(Text::toT(SETTING(DOWNLOAD_DIRECTORY)));
-}
-
-void MainWindow::on(HttpConnectionListener::Complete, HttpConnection* /*aConn*/, const string&, bool) noexcept {
+void MainWindow::completeVersionUpdate() {
 	try {
 		SimpleXML xml;
-		xml.fromXML(versionInfo);
+		xml.fromXML(conns[CONN_VERSION]->buf);
 		xml.stepIn();
 
 		string url = Text::fromT(links.homepage);
@@ -1241,7 +1204,10 @@
 							const string& msg = xml.getChildData();
 							dwt::MessageBox(this).show(Text::toT(msg), Text::toT(title));
 						} else {
-							if(dwt::MessageBox(this).show(str(TF_("%1%\nOpen download page?") % Text::toT(xml.getChildData())), Text::toT(title), dwt::MessageBox::BOX_YESNO, dwt::MessageBox::BOX_ICONQUESTION) == IDYES) {
+							if(dwt::MessageBox(this).show(
+								str(TF_("%1%\nOpen download page?") % Text::toT(xml.getChildData())), Text::toT(title),
+								dwt::MessageBox::BOX_YESNO, dwt::MessageBox::BOX_ICONQUESTION) == IDYES)
+							{
 								WinUtil::openLink(Text::toT(url));
 							}
 						}
@@ -1260,7 +1226,6 @@
 			if(xml.findChild("Downloads")) {
 				links.downloads = Text::toT(xml.getChildData());
 			}
-			xml.resetCurrentChild();
 			if(xml.findChild("GeoIPv6")) {
 				links.geoip6 = Text::toT(xml.getChildData());
 			}
@@ -1314,18 +1279,85 @@
 		}
 
 		xml.stepOut();
-	} catch (const Exception&) {
-		// ...
-	}
+	} catch (const Exception&) { }
+
+	conns[CONN_VERSION].reset();
+}
+
+void MainWindow::checkGeoUpdate(bool v6) {
+	// update when the database is non-existent or older than 16 days (GeoIP updates every month).
+	try {
+		File f(Util::getGeoPath(v6) + ".gz", File::READ, File::OPEN);
+		if(f.getSize() > 0 && f.getLastModified() > GET_TIME() - 3600 * 24 * 16) {
+			return;
+		}
+	} catch(const FileException&) { }
+	updateGeo(v6);
+}
+
+void MainWindow::updateGeo(bool v6) {
+	auto& conn = conns[v6 ? CONN_GEO_V6 : CONN_GEO_V4];
+	if(conn.get())
+		return;
+
+	LogManager::getInstance()->message(str(F_("Updating the %1% GeoIP database...") % (v6 ? "IPv6" : "IPv4")));
+	conn.reset(new HttpConnWrapper(Text::fromT(v6 ? links.geoip6 : links.geoip4), this,
+		[this, v6] { completeGeoUpdate(v6); }, HttpConnection::CST_NOCORALIZE));
+}
+
+void MainWindow::completeGeoUpdate(bool v6) {
+	auto& conn = conns[v6 ? CONN_GEO_V6 : CONN_GEO_V4];
+	ScopedFunctor([&conn] { conn.reset(); });
+
+	if(!conn->buf.empty()) {
+		try {
+			File(Util::getGeoPath(v6) + ".gz", File::WRITE, File::CREATE | File::TRUNCATE).write(conn->buf);
+			File f(Util::getGeoPath(v6), File::WRITE, File::CREATE | File::TRUNCATE); // clear the previous db
+			LogManager::getInstance()->message(str(F_("The %1% GeoIP database has been successfully updated; restart DC++ to apply") % (v6 ? "IPv6" : "IPv4")));
+			return;
+		} catch(const FileException&) { }
+	}
+	LogManager::getInstance()->message(str(F_("The %1% GeoIP database could not be updated") % (v6 ? "IPv6" : "IPv4")));
+}
+
+void MainWindow::parseCommandLine(const tstring& cmdLine)
+{
+	string::size_type i = 0;
+	string::size_type j;
+
+	if( (j = cmdLine.find(_T("dchub://"), i)) != string::npos ||
+		(j = cmdLine.find(_T("adc://"), i)) != string::npos ||
+		(j = cmdLine.find(_T("adcs://"), i)) != string::npos ||
+		(j = cmdLine.find(_T("magnet:?"), i)) != string::npos )
+	{
+		WinUtil::parseDBLClick(cmdLine.substr(j));
+	}
+}
+
+LRESULT MainWindow::handleCopyData(LPARAM lParam) {
+	parseCommandLine(Text::toT(WinUtil::getAppName() + " ") + reinterpret_cast<LPCTSTR>(reinterpret_cast<COPYDATASTRUCT*>(lParam)->lpData));
+	return TRUE;
+}
+
+void MainWindow::handleHashProgress() {
+	HashProgressDlg(this, false).run();
+}
+
+void MainWindow::handleCloseFavGroup(bool reversed) {
+	tstring group;
+	if(chooseFavHubGroup(reversed ? T_("Close hubs not in a favorite group") : T_("Close all hubs of a favorite group"), group))
+		HubFrame::closeFavGroup(Text::fromT(group), reversed);
+}
+
+void MainWindow::handleAbout() {
+	AboutDlg(this).run();
+}
+
+void MainWindow::handleOpenDownloadsDir() {
+	WinUtil::openFile(Text::toT(SETTING(DOWNLOAD_DIRECTORY)));
 }
 
 LRESULT MainWindow::handleEndSession() {
-	if (c != NULL) {
-		c->removeListener(this);
-		delete c;
-		c = NULL;
-	}
-
 	saveSettings();
 	QueueManager::getInstance()->saveQueue();
 
@@ -1499,14 +1531,48 @@
 	sendMessage(WM_SYSCOMMAND, SC_CONTEXTHELP);
 }
 
-void MainWindow::on(HttpConnectionListener::Data, HttpConnection* /*conn*/, const uint8_t* buf, size_t len) noexcept {
-	versionInfo += string((const char*)buf, len);
-}
-
- void MainWindow::on(HttpConnectionListener::Retried, HttpConnection* /*conn*/, const bool Connected) noexcept {
- 	if (Connected)
- 		versionInfo = Util::emptyString;
- }
+MainWindow::HttpConnWrapper::HttpConnWrapper(const string& address, MainWindow* mw, CompletionF f, HttpConnection::CoralizeState coralizeState) :
+c(new HttpConnection(coralizeState)),
+mw(mw),
+f(f)
+{
+	c->addListener(mw);
+	c->downloadFile(address);
+}
+
+MainWindow::HttpConnWrapper::~HttpConnWrapper() {
+	c->removeListener(mw);
+	delete c;
+}
+
+MainWindow::HttpConnWrapper* MainWindow::getConn(HttpConnection* conn) const {
+	for(uint8_t i = 0; i < CONN_LAST; ++i) {
+		if(conns[i].get() && conns[i]->c == conn) {
+			return conns[i].get();
+		}
+	}
+	return 0;
+}
+
+void MainWindow::on(HttpConnectionListener::Data, HttpConnection* conn, const uint8_t* buf, size_t len) noexcept {
+	getConn(conn)->buf.append(reinterpret_cast<const char*>(buf), len);
+}
+
+void MainWindow::on(HttpConnectionListener::Failed, HttpConnection* conn, const string&) noexcept {
+	auto c = getConn(conn);
+	c->buf.clear();
+	callAsync([c] { c->f(); });
+}
+
+void MainWindow::on(HttpConnectionListener::Complete, HttpConnection* conn, const string&, bool) noexcept {
+	auto c = getConn(conn);
+	callAsync([c] { c->f(); });
+}
+
+void MainWindow::on(HttpConnectionListener::Retried, HttpConnection* conn, bool connected) noexcept {
+	if(connected)
+		getConn(conn)->buf.clear();
+}
 
 void MainWindow::on(PartialList, const HintedUser& aUser, const string& text) noexcept {
 	callAsync([this, aUser, text] { DirectoryListingFrame::openWindow(getTabView(), aUser, text, 0); });

=== modified file 'win32/MainWindow.h'
--- win32/MainWindow.h	2011-09-23 11:47:15 +0000
+++ win32/MainWindow.h	2011-10-01 14:33:43 +0000
@@ -102,11 +102,31 @@
 		tstring community;
 	} links;
 
+	struct HttpConnWrapper : boost::noncopyable {
+		HttpConnection* c;
+		string buf;
+		MainWindow* mw;
+		typedef std::function<void ()> CompletionF;
+		CompletionF f;
+
+		explicit HttpConnWrapper(const string& address, MainWindow* mw, CompletionF f,
+			HttpConnection::CoralizeState coralizeState = HttpConnection::CST_DEFAULT);
+		~HttpConnWrapper();
+	};
+
 	enum {
 		TIMER_STATUS,
 		TIMER_SAVE
 	};
 
+	enum {
+		CONN_VERSION,
+		CONN_GEO_V6,
+		CONN_GEO_V4,
+
+		CONN_LAST
+	};
+
 	RebarPtr rebar;
 	SplitterContainerPtr paned;
 	MenuPtr mainMenu;
@@ -121,8 +141,7 @@
 
 	bool tray_pm;
 
-	HttpConnection* c;
-	string versionInfo;
+	unique_ptr<HttpConnWrapper> conns[CONN_LAST];
 
 	HANDLE stopperThread;
 
@@ -199,6 +218,12 @@
 	void fillLimiterMenu(MenuPtr menu, bool upload);
 	void statusMessage(time_t t, const string& m);
 
+	void completeVersionUpdate();
+	void checkGeoUpdate(bool v6);
+	void updateGeo(bool v6);
+	void completeGeoUpdate(bool v6);
+	HttpConnWrapper* getConn(HttpConnection* conn) const;
+
 	bool filter(MSG& msg);
 
 	bool handleClosing();
@@ -207,16 +232,17 @@
 	static DWORD WINAPI stopper(void* p);
 
 	// LogManagerListener
-	virtual void on(LogManagerListener::Message, time_t t, const string& m) noexcept;
+	void on(LogManagerListener::Message, time_t t, const string& m) noexcept;
 
 	// HttpConnectionListener
-	virtual void on(HttpConnectionListener::Complete, HttpConnection* conn, string const& /*aLine*/, bool /*fromCoral*/) noexcept;
-	virtual void on(HttpConnectionListener::Data, HttpConnection* /*conn*/, const uint8_t* buf, size_t len) noexcept;
-	virtual void on(HttpConnectionListener::Retried, HttpConnection* /*conn*/, const bool Connected) noexcept;		
-		
+	void on(HttpConnectionListener::Data, HttpConnection* conn, const uint8_t* buf, size_t len) noexcept;
+	void on(HttpConnectionListener::Failed, HttpConnection* conn, const string&) noexcept;
+	void on(HttpConnectionListener::Complete, HttpConnection* conn, const string& /*aLine*/, bool /*fromCoral*/) noexcept;
+	void on(HttpConnectionListener::Retried, HttpConnection* conn, bool connected) noexcept;
+
 	// QueueManagerListener
-	virtual void on(QueueManagerListener::Finished, QueueItem* qi, const string& dir, int64_t speed) noexcept;
-	virtual void on(PartialList, const HintedUser&, const string& text) noexcept;
+	void on(QueueManagerListener::Finished, QueueItem* qi, const string& dir, int64_t speed) noexcept;
+	void on(PartialList, const HintedUser&, const string& text) noexcept;
 };
 
 #endif // !defined(MAIN_FRM_H)