← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3259: "decoralization"

 

------------------------------------------------------------
revno: 3259
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Mon 2013-04-15 00:01:23 +0200
message:
  "decoralization"
modified:
  changelog.txt
  dcpp/BufferedSocket.cpp
  dcpp/FavoriteManager.cpp
  dcpp/HttpConnection.cpp
  dcpp/HttpConnection.h
  dcpp/HttpConnectionListener.h
  dcpp/HttpManager.cpp
  dcpp/HttpManager.h
  dcpp/HttpManagerListener.h
  win32/MainWindow.cpp
  win32/TransferView.cpp
  win32/TransferView.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	2013-04-12 21:10:13 +0000
+++ changelog.txt	2013-04-14 22:01:23 +0000
@@ -5,6 +5,7 @@
 * Add a tab menu command to disconnect a hub (poy)
 * Validate input before trying a TTH search (emtee)
 * Display HTTP downloads in the transfer list (poy)
+* [L#190964] Handle more connection errors (poy)
 
 -- 0.811 2013-03-04 --
 * Fix status bar parts when the window is too small (poy)

=== modified file 'dcpp/BufferedSocket.cpp'
--- dcpp/BufferedSocket.cpp	2013-01-27 18:04:17 +0000
+++ dcpp/BufferedSocket.cpp	2013-04-14 22:01:23 +0000
@@ -517,7 +517,7 @@
 		sock->disconnect();
 	}
 
-	if(state == RUNNING) {
+	if(state != FAILED) {
 		state = FAILED;
 		fire(BufferedSocketListener::Failed(), aError);
 	}

=== modified file 'dcpp/FavoriteManager.cpp'
--- dcpp/FavoriteManager.cpp	2013-04-13 15:08:45 +0000
+++ dcpp/FavoriteManager.cpp	2013-04-14 22:01:23 +0000
@@ -787,7 +787,7 @@
 	}	
 	running = false;
 	if(parseSuccess) {
-		fire(FavoriteManagerListener::DownloadFinished(), c->getUrl(), c->coralized());
+		fire(FavoriteManagerListener::DownloadFinished(), c->getUrl(), c->getCoralized());
 	}
 }
 

=== modified file 'dcpp/HttpConnection.cpp'
--- dcpp/HttpConnection.cpp	2013-04-13 15:08:45 +0000
+++ dcpp/HttpConnection.cpp	2013-04-14 22:01:23 +0000
@@ -29,7 +29,8 @@
 
 static const std::string CORAL_SUFFIX = ".nyud.net";
 
-HttpConnection::HttpConnection(bool coralize, const string& aUserAgent) :
+HttpConnection::HttpConnection(const string& aUserAgent) :
+coralized(false),
 userAgent(aUserAgent),
 port("80"),
 size(-1),
@@ -38,7 +39,6 @@
 lastPos(0),
 lastTick(0),
 connState(CONN_UNKNOWN),
-coralizeState(coralize ? CST_DEFAULT : CST_NOCORALIZE),
 socket(0)
 {
 }
@@ -66,7 +66,6 @@
  * @param aData StringMap with the args and values
  */
 void HttpConnection::download(const StringMap& postData) {
-	coralizeState = CST_NOCORALIZE;
 	requestBody.clear();
 
 	for(auto& i: postData)
@@ -76,10 +75,6 @@
 	prepareRequest(TYPE_POST);
 }
 
-bool HttpConnection::coralized() const {
-	return SETTING(CORAL) && coralizeState != CST_NOCORALIZE;
-}
-
 void HttpConnection::prepareRequest(RequestType type) {
 	dcassert(Util::findSubString(url, "http://";) == 0 || Util::findSubString(url, "https://";) == 0);
 	Util::sanitizeUrl(url);
@@ -118,12 +113,10 @@
 	if(!query.empty())
 		file += '?' + query;
 
-	if(coralized()) {
-		if(server.length() > CORAL_SUFFIX.length() && server.compare(server.length() - CORAL_SUFFIX.length(), CORAL_SUFFIX.length(), CORAL_SUFFIX) !=0) {
-			server += CORAL_SUFFIX;
-		} else {
-			coralizeState = CST_NOCORALIZE;
-		}
+	if(coralized && server.size() > CORAL_SUFFIX.size() &&
+		server.compare(server.size() - CORAL_SUFFIX.size(), CORAL_SUFFIX.size(), CORAL_SUFFIX) != 0)
+	{
+		server += CORAL_SUFFIX;
 	}
 
 	if(port.empty())
@@ -140,8 +133,8 @@
 	try {
 		socket->connect(server, port, (proto == "https"), true, false);
 	} catch(const Exception& e) {
+		connState = CONN_FAILED;
 		fire(HttpConnectionListener::Failed(), this, str(F_("%1% (%2%)") % e.getError() % url));
-		connState = CONN_FAILED;
 	}
 }
 
@@ -185,7 +178,6 @@
 	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 {
@@ -201,14 +193,12 @@
 			abortRequest(true);
 
 			if(chunkSize == 0) {
+				connState = CONN_OK;
 				fire(HttpConnectionListener::Complete(), this);
-				connState = CONN_OK;
 			} else {
+				connState = CONN_FAILED;
 				fire(HttpConnectionListener::Failed(), this, str(F_("Transfer-encoding error (%1%)") % url));
-				connState = CONN_FAILED;
 			}
-
-			coralizeState = CST_DEFAULT;
 		} else socket->setDataMode(chunkSize);
 
 	} else if(connState == CONN_UNKNOWN) {
@@ -218,18 +208,8 @@
 			connState = CONN_MOVED; 
 		} else {
 			abortRequest(true);
-
-			if(coralized()) {
-				fire(HttpConnectionListener::Retried(), this, coralizeState == CST_CONNECTED);
-				coralizeState = CST_NOCORALIZE;
-				dcdebug("HTTP error with Coral, retrying : %s\n", url.c_str());
-				download();
-				return;
-			}
-
+			connState = CONN_FAILED;
 			fire(HttpConnectionListener::Failed(), this, str(F_("%1% (%2%)") % aLine % url));
-			connState = CONN_FAILED;
-			coralizeState = CST_DEFAULT;
 		}
 
 	} else if(connState == CONN_MOVED && Util::findSubString(aLine, "Location") != string::npos) {
@@ -261,9 +241,6 @@
 		}
 
 		fire(HttpConnectionListener::Redirected(), this, location);
-
-		if(coralizeState != CST_NOCORALIZE)
-			coralizeState = CST_DEFAULT;
 		url = location;
 		download();
 
@@ -287,16 +264,7 @@
 
 void HttpConnection::on(BufferedSocketListener::Failed, const string& aLine) noexcept {
 	abortRequest(false);
-	if(coralized()) {
-		fire(HttpConnectionListener::Retried(), this, coralizeState == CST_CONNECTED);
-		coralizeState = CST_NOCORALIZE;
-		dcdebug("Coralized address failed, retrying : %s\n", url.c_str());
-		download();
-		return;
-	}
-
 	connState = CONN_FAILED;
-	coralizeState = CST_DEFAULT;
 	fire(HttpConnectionListener::Failed(), this, str(F_("%1% (%2%)") % aLine % url));
 }
 
@@ -305,7 +273,6 @@
 		abortRequest(true);
 
 		fire(HttpConnectionListener::Complete(), this);
-		coralizeState = CST_DEFAULT;
 	}
 }
 void HttpConnection::on(BufferedSocketListener::Data, uint8_t* aBuf, size_t aLen) noexcept {
@@ -313,7 +280,6 @@
 		abortRequest(true);
 
 		connState = CONN_FAILED;
-		coralizeState = CST_DEFAULT;
 		fire(HttpConnectionListener::Failed(), this, str(F_("Too much data in response body (%1%)") % url));
 		return;
 	}

=== modified file 'dcpp/HttpConnection.h'
--- dcpp/HttpConnection.h	2013-04-13 15:08:45 +0000
+++ dcpp/HttpConnection.h	2013-04-14 22:01:23 +0000
@@ -34,7 +34,7 @@
 class HttpConnection : BufferedSocketListener, public Speaker<HttpConnectionListener>, boost::noncopyable
 {
 public:
-	HttpConnection(bool coralize = true, const string& aUserAgent = Util::emptyString);
+	HttpConnection(const string& aUserAgent = Util::emptyString);
 	virtual ~HttpConnection();
 
 	void download();
@@ -46,14 +46,12 @@
 	int64_t getDone() const { return done; }
 	double getSpeed() const { return speed; }
 
-	bool coralized() const;
-
 	GETSET(string, url, Url);
+	GETSET(bool, coralized, Coralized);
 
 private:
 	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 userAgent;
 	string method;
@@ -73,7 +71,6 @@
 	uint64_t lastTick;
 
 	ConnectionStates connState;
-	CoralizeStates coralizeState;
 	RequestType connType;
 
 	BufferedSocket* socket;

=== modified file 'dcpp/HttpConnectionListener.h'
--- dcpp/HttpConnectionListener.h	2013-04-13 15:08:45 +0000
+++ dcpp/HttpConnectionListener.h	2013-04-14 22:01:23 +0000
@@ -37,13 +37,11 @@
 	typedef X<1> Failed;
 	typedef X<2> Complete;
 	typedef X<3> Redirected;
-	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*) noexcept = 0;
 	virtual void on(Redirected, HttpConnection*, const string&) noexcept = 0;
-	virtual void on(Retried, HttpConnection*, bool) noexcept = 0;
 };
 
 } // namespace dcpp

=== modified file 'dcpp/HttpManager.cpp'
--- dcpp/HttpManager.cpp	2013-04-14 20:28:35 +0000
+++ dcpp/HttpManager.cpp	2013-04-14 22:01:23 +0000
@@ -21,6 +21,7 @@
 
 #include "format.h"
 #include "HttpConnection.h"
+#include "SettingsManager.h"
 #include "Streams.h"
 
 namespace dcpp {
@@ -30,31 +31,32 @@
 }
 
 HttpManager::~HttpManager() {
-	TimerManager::getInstance()->removeListener(this);
 }
 
 HttpConnection* HttpManager::download(string url, OutputStream* stream) {
-	auto conn = makeConn(move(url), stream);
+	auto conn = makeConn(move(url), SETTING(CORAL), stream);
 	conn->download();
 	return conn;
 }
 
 HttpConnection* HttpManager::download(string url, const StringMap& postData, OutputStream* stream) {
-	auto conn = makeConn(move(url), stream);
+	auto conn = makeConn(move(url), false, stream);
 	conn->download(postData);
 	return conn;
 }
 
 void HttpManager::disconnect(const string& url) {
 	HttpConnection* c = nullptr;
-	OutputStream* stream;
+	OutputStream* stream = nullptr;
 
 	{
 		Lock l(cs);
 		conns.erase(std::remove_if(conns.begin(), conns.end(), [&](const Conn& conn) -> bool {
 			if(conn.c->getUrl() == url) {
 				c = conn.c;
-				stream = conn.stream;
+				if(conn.manageStream) {
+					stream = conn.stream;
+				}
 				return true;
 			}
 			return false;
@@ -65,25 +67,34 @@
 		fire(HttpManagerListener::Failed(), c, _("Disconnected"));
 		fire(HttpManagerListener::Removed(), c);
 		delete c;
-		delete stream;
+		if(stream) {
+			delete stream;
+		}
 	}
 }
 
 void HttpManager::shutdown() {
+	TimerManager::getInstance()->removeListener(this);
+
 	Lock l(cs);
-	for(auto& conn: conns) { delete conn.c; delete conn.stream; }
-	conns.clear();
+	for(auto& conn: conns) {
+		delete conn.c;
+		if(conn.manageStream) {
+			delete conn.stream;
+		}
+	}
 }
 
-HttpConnection* HttpManager::makeConn(string&& url, OutputStream* stream) {
+HttpConnection* HttpManager::makeConn(string&& url, bool coralized, OutputStream* stream) {
 	auto c = new HttpConnection();
 	{
 		Lock l(cs);
-		Conn conn { c, stream ? stream : new StringOutputStream(), 0 };
+		Conn conn { c, stream ? stream : new StringOutputStream(), !stream, 0 };
 		conns.push_back(move(conn));
 	}
 	c->addListener(this);
 	c->setUrl(move(url));
+	c->setCoralized(coralized);
 	fire(HttpManagerListener::Added(), c);
 	return c;
 }
@@ -97,9 +108,26 @@
 	return nullptr;
 }
 
+void HttpManager::resetStream(HttpConnection* c) {
+	OutputStream* stream = nullptr;
+	{
+		Lock l(cs);
+		auto conn = findConn(c);
+		if(conn->manageStream) {
+			stream = conn->stream;
+		}
+	}
+	if(stream) {
+		static_cast<StringOutputStream*>(stream)->stringRef().clear();
+	} else {
+		fire(HttpManagerListener::ResetStream(), c);
+	}
+}
+
 void HttpManager::removeLater(HttpConnection* c) {
+	auto later = GET_TICK() + 60 * 1000;
 	Lock l(cs);
-	findConn(c)->remove = GET_TICK() + 60 * 1000;
+	findConn(c)->remove = later;
 }
 
 void HttpManager::on(HttpConnectionListener::Data, HttpConnection* c, const uint8_t* data, size_t len) noexcept {
@@ -113,6 +141,14 @@
 }
 
 void HttpManager::on(HttpConnectionListener::Failed, HttpConnection* c, const string& str) noexcept {
+	resetStream(c);
+
+	if(c->getCoralized()) {
+		c->setCoralized(false);
+		c->download();
+		return;
+	}
+
 	fire(HttpManagerListener::Failed(), c, str);
 	removeLater(c);
 }
@@ -130,16 +166,11 @@
 
 void HttpManager::on(HttpConnectionListener::Redirected, HttpConnection* c, const string& redirect) noexcept {
 	fire(HttpManagerListener::Removed(), c);
+	resetStream(c);
 	c->setUrl(redirect);
 	fire(HttpManagerListener::Added(), c);
 }
 
-void HttpManager::on(HttpConnectionListener::Retried, HttpConnection* c, bool connected) noexcept {
-	if(connected) {
-		/// @todo reset / redirect
-	}
-}
-
 void HttpManager::on(TimerManagerListener::Minute, uint64_t tick) noexcept {
 	vector<pair<HttpConnection*, OutputStream*>> removed;
 
@@ -147,7 +178,7 @@
 		Lock l(cs);
 		conns.erase(std::remove_if(conns.begin(), conns.end(), [tick, &removed](const Conn& conn) -> bool {
 			if(conn.remove && tick > conn.remove) {
-				removed.emplace_back(conn.c, conn.stream);
+				removed.emplace_back(conn.c, conn.manageStream ? conn.stream : nullptr);
 				return true;
 			}
 			return false;
@@ -157,7 +188,9 @@
 	for(auto& rem: removed) {
 		fire(HttpManagerListener::Removed(), rem.first);
 		delete rem.first;
-		delete rem.second;
+		if(rem.second) {
+			delete rem.second;
+		}
 	}
 }
 

=== modified file 'dcpp/HttpManager.h'
--- dcpp/HttpManager.h	2013-04-13 15:08:45 +0000
+++ dcpp/HttpManager.h	2013-04-14 22:01:23 +0000
@@ -53,15 +53,16 @@
 	void shutdown();
 
 private:
-	struct Conn { HttpConnection* c; OutputStream* stream; uint64_t remove; };
+	struct Conn { HttpConnection* c; OutputStream* stream; bool manageStream; uint64_t remove; };
 
 	friend class Singleton<HttpManager>;
 
 	HttpManager();
 	virtual ~HttpManager();
 
-	HttpConnection* makeConn(string&& url, OutputStream* stream);
+	HttpConnection* makeConn(string&& url, bool coralized, OutputStream* stream);
 	Conn* findConn(HttpConnection* c);
+	void resetStream(HttpConnection* c);
 	void removeLater(HttpConnection* c);
 
 	// HttpConnectionListener
@@ -69,7 +70,6 @@
 	void on(HttpConnectionListener::Failed, HttpConnection*, const string&) noexcept;
 	void on(HttpConnectionListener::Complete, HttpConnection*) noexcept;
 	void on(HttpConnectionListener::Redirected, HttpConnection*, const string&) noexcept;
-	void on(HttpConnectionListener::Retried, HttpConnection*, bool) noexcept;
 
 	// TimerManagerListener
 	void on(TimerManagerListener::Minute, uint64_t tick) noexcept;

=== modified file 'dcpp/HttpManagerListener.h'
--- dcpp/HttpManagerListener.h	2013-04-13 15:08:45 +0000
+++ dcpp/HttpManagerListener.h	2013-04-14 22:01:23 +0000
@@ -37,12 +37,14 @@
 	typedef X<1> Updated;
 	typedef X<2> Failed;
 	typedef X<3> Complete;
-	typedef X<4> Removed;
+	typedef X<4> ResetStream;
+	typedef X<5> Removed;
 
 	virtual void on(Added, HttpConnection*) noexcept { }
 	virtual void on(Updated, HttpConnection*) noexcept { }
 	virtual void on(Failed, HttpConnection*, const string&) noexcept { }
 	virtual void on(Complete, HttpConnection*, OutputStream*) noexcept { }
+	virtual void on(ResetStream, HttpConnection*) noexcept { }
 	virtual void on(Removed, HttpConnection*) noexcept { }
 };
 

=== modified file 'win32/MainWindow.cpp'
--- win32/MainWindow.cpp	2013-04-14 20:28:35 +0000
+++ win32/MainWindow.cpp	2013-04-14 22:01:23 +0000
@@ -1767,7 +1767,7 @@
 		callAsync([str, this] { completeGeoUpdate(true, true, str); });
 
 	} else if(c == conns[CONN_GEO_V4]) {
-		conns[CONN_GEO_V4] = nulllptr;
+		conns[CONN_GEO_V4] = nullptr;
 
 		auto str = static_cast<StringOutputStream*>(stream)->getString();
 		callAsync([str, this] { completeGeoUpdate(false, true, str); });

=== modified file 'win32/TransferView.cpp'
--- win32/TransferView.cpp	2013-04-13 15:08:45 +0000
+++ win32/TransferView.cpp	2013-04-14 22:01:23 +0000
@@ -980,7 +980,7 @@
 		statusString += _T(" ");
 	}
 	statusString += str(TF_("Downloading %1%") % getFile(d));
-	ui->setStatusString(statusString);
+	ui->setStatusString(move(statusString));
 
 	updatedConn(ui);
 }
@@ -1023,7 +1023,7 @@
 		statusString += _T(" ");
 	}
 	statusString += str(TF_("Uploading %1%") % getFile(u));
-	ui->setStatusString(statusString);
+	ui->setStatusString(move(statusString));
 
 	addedConn(ui);
 }
@@ -1040,8 +1040,13 @@
 
 void TransferView::on(HttpManagerListener::Added, HttpConnection* c) noexcept {
 	auto ui = makeHttpUI(c);
+
 	ui->setStatus(STATUS_RUNNING);
-	ui->setStatusString(T_("Downloading"));
+
+	tstring statusString = T_("Downloading");
+	if(c->getCoralized()) { statusString += _T(" [Coral]"); }
+	ui->setStatusString(move(statusString));
+
 	ui->setTransferred(c->getDone(), c->getDone(), c->getSize());
 
 	addedConn(ui);
@@ -1066,8 +1071,13 @@
 
 void TransferView::on(HttpManagerListener::Complete, HttpConnection* c, OutputStream*) noexcept {
 	auto ui = makeHttpUI(c);
+
 	ui->setStatus(STATUS_WAITING);
-	ui->setStatusString(T_("Download finished"));
+
+	tstring statusString = T_("Download finished");
+	if(c->getCoralized()) { statusString += _T(" [Coral]"); }
+	ui->setStatusString(move(statusString));
+
 	ui->setTransferred(c->getDone(), c->getDone(), c->getSize());
 
 	updatedConn(ui);

=== modified file 'win32/TransferView.h'
--- win32/TransferView.h	2013-04-13 15:08:45 +0000
+++ win32/TransferView.h	2013-04-14 22:01:23 +0000
@@ -206,7 +206,7 @@
 		int64_t size;
 		void setSpeed(int64_t aSpeed) { speed = aSpeed; updateMask |= MASK_SPEED; }
 		int64_t speed;
-		void setStatusString(const tstring& aStatusString) { statusString = aStatusString; updateMask |= MASK_STATUS_STRING; }
+		void setStatusString(tstring&& aStatusString) { statusString = move(aStatusString); updateMask |= MASK_STATUS_STRING; }
 		tstring statusString;
 
 		void setCipher(const tstring& aCipher) { cipher = aCipher; updateMask |= MASK_CIPHER; }