------------------------------------------------------------ revno: 3259 committer: poy <p...@123gen.com> 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; }
_______________________________________________ Mailing list: https://launchpad.net/~linuxdcpp-team Post to : linuxdcpp-team@lists.launchpad.net Unsubscribe : https://launchpad.net/~linuxdcpp-team More help : https://help.launchpad.net/ListHelp