Vidalia
0.2.15
|
00001 /* 00002 ** This file is part of Vidalia, and is subject to the license terms in the 00003 ** LICENSE file, found in the top level directory of this distribution. If you 00004 ** did not receive the LICENSE file with this file, you may obtain it from the 00005 ** Vidalia source package distributed by the Vidalia Project at 00006 ** http://www.torproject.org/projects/vidalia.html. No part of Vidalia, 00007 ** including this file, may be copied, modified, propagated, or distributed 00008 ** except according to the terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file BridgeDownloader.cpp 00013 ** \brief Downloads a list of new bridge addresses via HTTPS 00014 */ 00015 00016 #include "BridgeDownloader.h" 00017 #include "Vidalia.h" 00018 00019 #define BRIDGEDB_HOST "bridges.torproject.org" 00020 #define BRIDGEDB_PORT 443 00021 00022 BridgeDownloader::BridgeDownloader(QObject *parent) 00023 : QObject(parent) 00024 { 00025 _https = new QNetworkAccessManager(); 00026 00027 connect(_https, SIGNAL(finished(QNetworkReply *)), 00028 this, SLOT(httpsRequestFinished(QNetworkReply *))); 00029 connect(_https, SIGNAL(sslErrors(QNetworkReply *, QList<QSslError>)), 00030 this, SLOT(sslErrors(QNetworkReply *, QList<QSslError>))); 00031 } 00032 00033 void 00034 BridgeDownloader::setProxy(const QString &host, int port, 00035 const QString &username, const QString &password) 00036 { 00037 _https->setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, host, port, username, password)); 00038 } 00039 00040 bool 00041 BridgeDownloader::downloadBridges(BridgeDownloadMethod method) 00042 { 00043 if (! isMethodSupported(method)) 00044 return false; 00045 00046 switch (method) { 00047 case DownloadMethodHttps: 00048 startHttpsDownload(); 00049 break; 00050 00051 default: 00052 break; 00053 } 00054 return true; 00055 } 00056 00057 bool 00058 BridgeDownloader::isMethodSupported(BridgeDownloadMethod method) 00059 { 00060 switch (method) { 00061 case DownloadMethodHttps: 00062 return QSslSocket::supportsSsl(); 00063 00064 default: 00065 break; 00066 } 00067 return false; 00068 } 00069 00070 void 00071 BridgeDownloader::startHttpsDownload() 00072 { 00073 emit statusChanged(tr("Starting HTTPS bridge request...")); 00074 emit downloadProgress(0, 0); 00075 00076 _reply = _https->get(QNetworkRequest(QUrl("https://bridges.torproject.org/?format=plain"))); 00077 connect(_reply, SIGNAL(downloadProgress(qint64, qint64)), 00078 this, SIGNAL(downloadProgress(qint64, qint64))); 00079 vInfo("Sending an HTTPS bridge request to %1:%2.").arg(BRIDGEDB_HOST) 00080 .arg(BRIDGEDB_PORT); 00081 } 00082 00083 void 00084 BridgeDownloader::cancelBridgeRequest() 00085 { 00086 _reply->close(); 00087 disconnect(_reply, 0, 0, 0); 00088 } 00089 00090 void 00091 BridgeDownloader::httpsStateChanged(int state) 00092 { 00093 switch (state) { 00094 case QHttp::Connecting: 00095 emit statusChanged(tr("Connecting to %1:%2...").arg(BRIDGEDB_HOST) 00096 .arg(BRIDGEDB_PORT)); 00097 break; 00098 00099 case QHttp::Sending: 00100 emit statusChanged(tr("Sending an HTTPS request for bridges...")); 00101 break; 00102 00103 case QHttp::Reading: 00104 emit statusChanged(tr("Downloading a list of bridges...")); 00105 break; 00106 00107 default: 00108 break; 00109 } 00110 } 00111 00112 void 00113 BridgeDownloader::httpsRequestFinished(QNetworkReply *reply) 00114 { 00115 if (reply->error() != QNetworkReply::NoError) { 00116 QString errorString = reply->errorString(); 00117 vWarn("Bridge request failed: %2").arg(errorString); 00118 00119 emit bridgeRequestFailed(errorString); 00120 } else { 00121 QByteArray response = reply->readAll(); 00122 vInfo("Bridge request complete: received %2 bytes.").arg(response.size()); 00123 00124 QStringList bridges, lines = QString(response).split("\n"); 00125 foreach (QString line, lines) { 00126 line = line.trimmed(); 00127 if (line.startsWith("bridge ", Qt::CaseInsensitive)) 00128 bridges << line; 00129 } 00130 emit bridgeRequestFinished(bridges); 00131 } 00132 _reply->close(); 00133 disconnect(_reply,0,0,0); 00134 } 00135 00136 void 00137 BridgeDownloader::sslErrors(QNetworkReply *reply, const QList<QSslError> &sslErrors) 00138 { 00139 QString errorString; 00140 QStringList errorStrings; 00141 00142 vWarn("%1 SSL error(s) when requesting bridge information:") 00143 .arg(sslErrors.size()); 00144 foreach (QSslError sslError, sslErrors) { 00145 errorString = sslError.errorString(); 00146 errorStrings << errorString; 00147 vWarn(" SSL Error: %1").arg(errorString); 00148 } 00149 }