Vidalia 0.2.10
|
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.vidalia-project.net/. No part of Vidalia, including this file, 00007 ** may be copied, modified, propagated, or distributed except according to the 00008 ** terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file BridgeDownloader.cpp 00013 ** \version $Id: BridgeDownloader.cpp 3735 2009-04-28 20:28:01Z edmanm $ 00014 ** \brief Downloads a list of new bridge addresses via HTTPS 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