BridgeDownloader.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "BridgeDownloader.h"
00018 #include "Vidalia.h"
00019
00020 #include <QSslSocket>
00021
00022 #define BRIDGEDB_HOST "bridges.torproject.org"
00023 #define BRIDGEDB_PORT 443
00024
00025
00026 BridgeDownloader::BridgeDownloader(QObject *parent)
00027 : QObject(parent),
00028 _requestId(0)
00029 {
00030 _https = new QHttp(BRIDGEDB_HOST, QHttp::ConnectionModeHttps,
00031 BRIDGEDB_PORT, this);
00032
00033 connect(_https, SIGNAL(stateChanged(int)),
00034 this, SLOT(httpsStateChanged(int)));
00035 connect(_https, SIGNAL(requestFinished(int, bool)),
00036 this, SLOT(httpsRequestFinished(int, bool)));
00037 connect(_https, SIGNAL(dataReadProgress(int, int)),
00038 this, SIGNAL(downloadProgress(int, int)));
00039 connect(_https, SIGNAL(sslErrors(QList<QSslError>)),
00040 this, SLOT(sslErrors(QList<QSslError>)));
00041 }
00042
00043 void
00044 BridgeDownloader::setProxy(const QString &host, int port,
00045 const QString &username, const QString &password)
00046 {
00047 _https->setProxy(host, port, username, password);
00048 }
00049
00050 bool
00051 BridgeDownloader::downloadBridges(BridgeDownloadMethod method)
00052 {
00053 if (! isMethodSupported(method))
00054 return false;
00055
00056 switch (method) {
00057 case DownloadMethodHttps:
00058 startHttpsDownload();
00059 break;
00060
00061 default:
00062 break;
00063 }
00064 return true;
00065 }
00066
00067 bool
00068 BridgeDownloader::isMethodSupported(BridgeDownloadMethod method)
00069 {
00070 switch (method) {
00071 case DownloadMethodHttps:
00072 return QSslSocket::supportsSsl();
00073
00074 default:
00075 break;
00076 }
00077 return false;
00078 }
00079
00080 void
00081 BridgeDownloader::startHttpsDownload()
00082 {
00083 emit statusChanged(tr("Starting HTTPS bridge request..."));
00084 emit downloadProgress(0, 0);
00085
00086 _requestId = _https->get("/?format=plain");
00087 vInfo("Sending an HTTPS bridge request to %1:%2 (id %3).").arg(BRIDGEDB_HOST)
00088 .arg(BRIDGEDB_PORT)
00089 .arg(_requestId);
00090 }
00091
00092 void
00093 BridgeDownloader::cancelBridgeRequest()
00094 {
00095 _https->abort();
00096 }
00097
00098 void
00099 BridgeDownloader::httpsStateChanged(int state)
00100 {
00101 switch (state) {
00102 case QHttp::Connecting:
00103 emit statusChanged(tr("Connecting to %1:%2...").arg(BRIDGEDB_HOST)
00104 .arg(BRIDGEDB_PORT));
00105 break;
00106
00107 case QHttp::Sending:
00108 emit statusChanged(tr("Sending an HTTPS request for bridges..."));
00109 break;
00110
00111 case QHttp::Reading:
00112 emit statusChanged(tr("Downloading a list of bridges..."));
00113 break;
00114
00115 default:
00116 break;
00117 }
00118 }
00119
00120 void
00121 BridgeDownloader::httpsRequestFinished(int id, bool error)
00122 {
00123 if (id != _requestId)
00124 return;
00125
00126 if (error) {
00127 QString errorString = _https->errorString();
00128 vWarn("Bridge request failed (id %1): %2").arg(id).arg(errorString);
00129
00130 emit bridgeRequestFailed(errorString);
00131 } else {
00132 QByteArray response = _https->readAll();
00133 vInfo("Bridge request complete (id %1): received %2 bytes.").arg(id)
00134 .arg(response.size());
00135
00136 QStringList bridges, lines = QString(response).split("\n");
00137 foreach (QString line, lines) {
00138 line = line.trimmed();
00139 if (line.startsWith("bridge ", Qt::CaseInsensitive))
00140 bridges << line;
00141 }
00142 emit bridgeRequestFinished(bridges);
00143 }
00144 _https->close();
00145 }
00146
00147 void
00148 BridgeDownloader::sslErrors(const QList<QSslError> &sslErrors)
00149 {
00150 QString errorString;
00151 QStringList errorStrings;
00152
00153 vWarn("%1 SSL error(s) when requesting bridge information (id %2):")
00154 .arg(sslErrors.size())
00155 .arg(_requestId);
00156 foreach (QSslError sslError, sslErrors) {
00157 errorString = sslError.errorString();
00158 errorStrings << errorString;
00159 vWarn(" SSL Error: %1").arg(errorString);
00160 }
00161 }
00162