linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #06764
[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; }