Commit c4e03570 authored by Urs Fleisch's avatar Urs Fleisch
Browse files

Qt4: proxy authentication

parent bc108520
......@@ -11,6 +11,7 @@ Sat Mar 14 12:43:56 CET 2009 Urs Fleisch <ufleisch@users.sourceforge.net>
* Improved:
+ Directory deb to generate Debian packages for KDE 4 and Qt 4 or
KDE 3 and Qt3.
+ Proxy authentication with Qt 4.
* Fixed:
+ Format replacements %c, %y, ... are replaced with empty
......
......@@ -436,11 +436,29 @@ ConfigDialog::ConfigDialog(QWidget* parent, QString& caption) :
m_proxyCheckBox = new QCheckBox(i18n("&Proxy:"), proxyGroupBox);
m_proxyLineEdit = new QLineEdit(proxyGroupBox);
#if QT_VERSION >= 0x040000
QHBoxLayout* hbox = new QHBoxLayout;
hbox->setMargin(2);
hbox->addWidget(m_proxyCheckBox);
hbox->addWidget(m_proxyLineEdit);
proxyGroupBox->setLayout(hbox);
m_proxyAuthenticationCheckBox = new QCheckBox(i18n("&Use authentication with proxy"), proxyGroupBox);
QLabel* proxyUserNameLabel = new QLabel(i18n("Proxy user &name:"), proxyGroupBox);
m_proxyUserNameLineEdit = new QLineEdit(proxyGroupBox);
proxyUserNameLabel->setBuddy(m_proxyUserNameLineEdit);
QLabel* proxyPasswordLabel = new QLabel(i18n("Proxy pass&word:"), proxyGroupBox);
m_proxyPasswordLineEdit = new QLineEdit(proxyGroupBox);
proxyPasswordLabel->setBuddy(m_proxyPasswordLineEdit);
m_proxyPasswordLineEdit->setEchoMode(QLineEdit::Password);
QVBoxLayout* vbox = new QVBoxLayout;
vbox->setMargin(2);
QHBoxLayout* proxyHbox = new QHBoxLayout;
proxyHbox->setMargin(2);
proxyHbox->addWidget(m_proxyCheckBox);
proxyHbox->addWidget(m_proxyLineEdit);
vbox->addLayout(proxyHbox);
vbox->addWidget(m_proxyAuthenticationCheckBox);
QGridLayout* authLayout = new QGridLayout;
authLayout->addWidget(proxyUserNameLabel, 0, 0);
authLayout->addWidget(m_proxyUserNameLineEdit, 0, 1);
authLayout->addWidget(proxyPasswordLabel, 1, 0);
authLayout->addWidget(m_proxyPasswordLineEdit, 1, 1);
vbox->addLayout(authLayout);
proxyGroupBox->setLayout(vbox);
#endif
vlayout->addWidget(proxyGroupBox);
}
......@@ -588,6 +606,11 @@ void ConfigDialog::setConfig(const FormatConfig* fnCfg,
m_browserLineEdit->setText(miscCfg->m_browser);
m_proxyCheckBox->setChecked(miscCfg->m_useProxy);
m_proxyLineEdit->setText(miscCfg->m_proxy);
#if QT_VERSION >= 0x040000
m_proxyAuthenticationCheckBox->setChecked(miscCfg->m_useProxyAuthentication);
m_proxyUserNameLineEdit->setText(miscCfg->m_proxyUserName);
m_proxyPasswordLineEdit->setText(miscCfg->m_proxyPassword);
#endif
#ifndef CONFIG_USE_KDE
m_useApplicationFontCheckBox->setChecked(miscCfg->m_useFont);
m_applicationFontButton->setEnabled(miscCfg->m_useFont);
......@@ -651,6 +674,11 @@ void ConfigDialog::getConfig(FormatConfig* fnCfg,
miscCfg->m_browser = m_browserLineEdit->text();
miscCfg->m_useProxy = m_proxyCheckBox->isChecked();
miscCfg->m_proxy = m_proxyLineEdit->text();
#if QT_VERSION >= 0x040000
miscCfg->m_useProxyAuthentication = m_proxyAuthenticationCheckBox->isChecked();
miscCfg->m_proxyUserName = m_proxyUserNameLineEdit->text();
miscCfg->m_proxyPassword = m_proxyPasswordLineEdit->text();
#endif
#ifndef CONFIG_USE_KDE
if (m_useApplicationFontCheckBox->isChecked()) {
QFont font = QApplication::font();
......
......@@ -169,6 +169,14 @@ private:
QCheckBox* m_proxyCheckBox;
/** Proxy line edit */
QLineEdit* m_proxyLineEdit;
#if QT_VERSION >= 0x040000
/** Use proxy authentication check box */
QCheckBox* m_proxyAuthenticationCheckBox;
/** Proxy user name line edit */
QLineEdit* m_proxyUserNameLineEdit;
/** Proxy password line edit */
QLineEdit* m_proxyPasswordLineEdit;
#endif
#ifndef CONFIG_USE_KDE
QCheckBox* m_useApplicationFontCheckBox;
QPushButton* m_applicationFontButton;
......
......@@ -63,12 +63,14 @@ void DownloadDialog::updateProgressStatus(const QString& msg,
int receivedBytes, int totalBytes)
{
setLabelText(m_url + '\n' + msg);
if (receivedBytes >= 0 && totalBytes >= 0) {
#if QT_VERSION >= 0x040000
setRange(0, totalBytes);
setValue(receivedBytes);
setRange(0, totalBytes);
setValue(receivedBytes);
#else
setProgress(receivedBytes, totalBytes);
setProgress(receivedBytes, totalBytes);
#endif
}
}
/**
......
......@@ -30,31 +30,23 @@
/** Only defined for generation of KDE3 translation files */
#define FOR_KDE3_PO_1 I18N_NOOP("Data received: %1")
#if QT_VERSION >= 0x040000
/**
* Constructor.
*/
HttpClient::HttpClient() :
m_rcvIdx(0), m_rcvBodyIdx(0), m_rcvBodyLen(0)
m_rcvBodyLen(0)
{
#if QT_VERSION >= 0x040000
m_sock = new QTcpSocket();
connect(m_sock, SIGNAL(disconnected()),
this, SLOT(slotConnectionClosed()));
connect(m_sock, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(slotError(QAbstractSocket::SocketError)));
#else
m_sock = new QSocket();
connect(m_sock, SIGNAL(connectionClosed()),
this, SLOT(slotConnectionClosed()));
connect(m_sock, SIGNAL(error(int)),
this, SLOT(slotError(int)));
#endif
connect(m_sock, SIGNAL(hostFound()),
this, SLOT(slotHostFound()));
connect(m_sock, SIGNAL(connected()),
this, SLOT(slotConnected()));
connect(m_sock, SIGNAL(readyRead()),
this, SLOT(slotReadyRead()));
m_http = new QHttp();
connect(m_http, SIGNAL(stateChanged(int)),
this, SLOT(slotStateChanged(int)));
connect(m_http, SIGNAL(dataReadProgress(int, int)),
this, SLOT(slotDataReadProgress(int, int)));
connect(m_http, SIGNAL(done(bool)),
this, SLOT(slotDone(bool)));
connect(m_http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader&)),
this, SLOT(slotResponseHeaderReceived(const QHttpResponseHeader&)));
}
/**
......@@ -62,73 +54,169 @@ HttpClient::HttpClient() :
*/
HttpClient::~HttpClient()
{
m_sock->close();
m_sock->disconnect();
delete m_sock;
m_http->close();
m_http->disconnect();
delete m_http;
}
/**
* Emit a progress signal with step/total steps.
* Called when the connection state changes.
*
* @param text state text
* @param step current step
* @param totalSteps total number of steps
* @param state HTTP connection state
*/
void HttpClient::emitProgress(const QString& text, int step, int totalSteps)
void HttpClient::slotStateChanged(int state)
{
emit progress(text, step, totalSteps);
switch (state) {
case QHttp::HostLookup:
emitProgress(i18n("Ready."), CS_RequestConnection, CS_EstimatedBytes);
break;
case QHttp::Connecting:
emitProgress(i18n("Connecting..."), CS_Connecting, CS_EstimatedBytes);
break;
case QHttp::Sending:
emitProgress(i18n("Host found..."), CS_HostFound, CS_EstimatedBytes);
break;
case QHttp::Reading:
emitProgress(i18n("Request sent..."), CS_RequestSent, CS_EstimatedBytes);
break;
case QHttp::Connected:
emitProgress(i18n("Ready."), -1, -1);
break;
case QHttp::Unconnected:
case QHttp::Closing:
default:
;
}
}
/**
* Emit a progress signal with bytes received/total bytes.
* Called to report connection progress.
*
* @param text state text
* @param done bytes received
* @param total total bytes, 0 if unknown
*/
void HttpClient::emitProgress(const QString& text)
void HttpClient::slotDataReadProgress(int done, int total)
{
emit progress(text, m_rcvIdx - m_rcvBodyIdx, m_rcvBodyLen);
emitProgress(KCM_i18n1("Data received: %1", done), done, total);
}
/**
* Get string with proxy or destination and port.
* If a proxy is set, the proxy is returned, else the real destination.
* Called when the request is finished.
*
* @param dst real destination
* @param error true if error occurred
*/
void HttpClient::slotDone(bool error)
{
if (error) {
QHttp::Error err = m_http->error();
if (err != QHttp::UnexpectedClose) {
QString msg(i18n("Socket error: "));
switch (err) {
case QHttp::ConnectionRefused:
msg += i18n("Connection refused");
break;
case QHttp::HostNotFound:
msg += i18n("Host not found");
break;
default:
msg += m_http->errorString();
}
emitProgress(msg, -1, -1);
}
}
emit bytesReceived(m_http->readAll());
if (!error) {
emitProgress(i18n("Ready."), CS_EstimatedBytes, CS_EstimatedBytes);
}
}
/**
* Called when the response header is available.
*
* @return "destinationname:port".
* @param resp HTTP response header
*/
QString HttpClient::getProxyOrDest(const QString& dst)
void HttpClient::slotResponseHeaderReceived(const QHttpResponseHeader& resp)
{
m_rcvBodyType = resp.contentType();
m_rcvBodyLen = resp.contentLength();
}
/**
* Send a HTTP GET request.
*
* @param server host name
* @param path path of the URL
*/
void HttpClient::sendRequest(const QString& server, const QString& path)
{
m_rcvBodyLen = 0;
m_rcvBodyType = "";
QString dest;
int destPort;
splitNamePort(server, dest, destPort);
m_http->setHost(dest, destPort);
QString proxy, username, password;
int proxyPort = 0;
if (Kid3App::s_miscCfg.m_useProxy) {
dest = Kid3App::s_miscCfg.m_proxy;
splitNamePort(Kid3App::s_miscCfg.m_proxy, proxy, proxyPort);
}
if (dest.isEmpty()) {
dest = dst;
if (Kid3App::s_miscCfg.m_useProxyAuthentication) {
username = Kid3App::s_miscCfg.m_proxyUserName;
password = Kid3App::s_miscCfg.m_proxyPassword;
}
return dest;
m_http->setProxy(proxy, proxyPort, username, password);
QHttpRequestHeader header("GET", path);
header.setValue("User-Agent", "Kid3/" VERSION);
header.setValue("Host", dest);
header.setValue("Connection", "close");
m_http->request(header);
}
void HttpClient::slotHostFound() {}
void HttpClient::slotConnected() {}
void HttpClient::slotConnectionClosed() {}
void HttpClient::slotReadyRead() {}
void HttpClient::slotError(int) {}
#else
/**
* Extract name and port from string.
* Constructor.
*/
HttpClient::HttpClient() :
m_rcvIdx(0), m_rcvBodyIdx(0), m_rcvBodyLen(0)
{
m_sock = new QSocket();
connect(m_sock, SIGNAL(connectionClosed()),
this, SLOT(slotConnectionClosed()));
connect(m_sock, SIGNAL(error(int)),
this, SLOT(slotError(int)));
connect(m_sock, SIGNAL(hostFound()),
this, SLOT(slotHostFound()));
connect(m_sock, SIGNAL(connected()),
this, SLOT(slotConnected()));
connect(m_sock, SIGNAL(readyRead()),
this, SLOT(slotReadyRead()));
}
/**
* Destructor.
*/
HttpClient::~HttpClient()
{
m_sock->close();
m_sock->disconnect();
delete m_sock;
}
/**
* Emit a progress signal with bytes received/total bytes.
*
* @param namePort input string with "name:port"
* @param name output string with "name"
* @param port output integer with port
* @param text state text
*/
void HttpClient::splitNamePort(const QString& namePort,
QString& name, int& port)
void HttpClient::emitProgress(const QString& text)
{
int colPos = namePort.QCM_lastIndexOf(':');
if (colPos >= 0) {
bool ok;
port = namePort.mid(colPos + 1).toInt(&ok);
if (!ok) port = 80;
name = namePort.left(colPos);
} else {
name = namePort;
port = 80;
}
emit progress(text, m_rcvIdx - m_rcvBodyIdx, m_rcvBodyLen);
}
/**
......@@ -164,11 +252,7 @@ void HttpClient::readBytesAvailable()
m_rcvBuf.resize(m_rcvIdx);
}
if (m_rcvBodyIdx == 0 && m_rcvBodyLen == 0) {
#if QT_VERSION >= 0x040000
QByteArray& str(m_rcvBuf);
#else
QCString str(m_rcvBuf.data(), m_rcvIdx + 1);
#endif
int contentLengthPos = str.QCM_indexOf("Content-Length:");
if (contentLengthPos != -1) {
contentLengthPos += 15;
......@@ -215,19 +299,14 @@ void HttpClient::readBytesAvailable()
void HttpClient::slotConnectionClosed()
{
readBytesAvailable();
#if QT_VERSION >= 0x040000
QByteArray body(m_rcvBuf.data() + m_rcvBodyIdx,
m_rcvBuf.size() - m_rcvBodyIdx);
#else
QByteArray body;
body.duplicate(m_rcvBuf.data() + m_rcvBodyIdx,
m_rcvBuf.size() - m_rcvBodyIdx);
body.resize(m_rcvBuf.size() - m_rcvBodyIdx + 1);
body[m_rcvBuf.size() - m_rcvBodyIdx] = '\0';
#endif
emit bytesReceived(body);
m_sock->close();
emitProgress(i18n("Ready."));
emitProgress(i18n("Ready."), CS_EstimatedBytes, CS_EstimatedBytes);
}
/**
......@@ -242,28 +321,6 @@ void HttpClient::slotReadyRead()
/**
* Display information about socket error.
*/
#if QT_VERSION >= 0x040000
void HttpClient::slotError(QAbstractSocket::SocketError err)
{
if (err == QAbstractSocket::RemoteHostClosedError)
return;
QString msg(i18n("Socket error: "));
switch (err) {
case QAbstractSocket::ConnectionRefusedError:
msg += i18n("Connection refused");
break;
case QAbstractSocket::HostNotFoundError:
msg += i18n("Host not found");
break;
case QAbstractSocket::SocketAccessError:
msg += i18n("Read failed");
break;
default:
msg += m_sock->errorString();
}
emitProgress(msg);
}
#else
void HttpClient::slotError(int err)
{
QString msg(i18n("Socket error: "));
......@@ -282,7 +339,6 @@ void HttpClient::slotError(int err)
}
emitProgress(msg);
}
#endif
/**
* Send a HTTP GET request.
......@@ -322,3 +378,64 @@ void HttpClient::sendRequest(const QString& server, const QString& path)
m_sock->connectToHost(dest, destPort);
emitProgress(i18n("Connecting..."), CS_Connecting, CS_EstimatedBytes);
}
/**
* Get string with proxy or destination and port.
* If a proxy is set, the proxy is returned, else the real destination.
*
* @param dst real destination
*
* @return "destinationname:port".
*/
QString HttpClient::getProxyOrDest(const QString& dst)
{
QString dest;
if (Kid3App::s_miscCfg.m_useProxy) {
dest = Kid3App::s_miscCfg.m_proxy;
}
if (dest.isEmpty()) {
dest = dst;
}
return dest;
}
void HttpClient::slotStateChanged(int) {}
void HttpClient::slotDataReadProgress(int, int) {}
void HttpClient::slotDone(bool) {}
void HttpClient::slotResponseHeaderReceived(const QHttpResponseHeader&) {}
#endif
/**
* Emit a progress signal with step/total steps.
*
* @param text state text
* @param step current step
* @param totalSteps total number of steps
*/
void HttpClient::emitProgress(const QString& text, int step, int totalSteps)
{
emit progress(text, step, totalSteps);
}
/**
* Extract name and port from string.
*
* @param namePort input string with "name:port"
* @param name output string with "name"
* @param port output integer with port
*/
void HttpClient::splitNamePort(const QString& namePort,
QString& name, int& port)
{
int colPos = namePort.QCM_lastIndexOf(':');
if (colPos >= 0) {
bool ok;
port = namePort.mid(colPos + 1).toInt(&ok);
if (!ok) port = 80;
name = namePort.left(colPos);
} else {
name = namePort;
port = 80;
}
}
......@@ -32,13 +32,15 @@
#include "qtcompatmac.h"
#if QT_VERSION >= 0x040000
#include <QTcpSocket>
#include <QHttp>
#include <QByteArray>
#else
#include <qsocket.h>
#include <qcstring.h>
#endif
class QHttpResponseHeader;
/**
* Client to connect to HTTP server.
*/
......@@ -134,11 +136,37 @@ private slots:
/**
* Display information about socket error.
*/
#if QT_VERSION >= 0x040000
void slotError(QAbstractSocket::SocketError err);
#else
void slotError(int err);
#endif
/**
* Called when the connection state changes.
*
* @param state HTTP connection state
*/
void slotStateChanged(int state);
/**
* Called to report connection progress.
*
* @param done bytes received
* @param total total bytes, 0 if unknown
*/
void slotDataReadProgress(int done, int total);
/**
* Called when the request is finished.
*
* @param error true if error occurred
*/
void slotDone(bool error);
/**
* Called when the response header is available.
*
* @param resp HTTP response header
*/
void slotResponseHeaderReceived(const QHttpResponseHeader& resp);
private:
/**
......@@ -172,24 +200,25 @@ private:
*/
static QString getProxyOrDest(const QString& dst);
/** request to set */
QString m_request;
/** client socket */
#if QT_VERSION >= 0x040000
QTcpSocket* m_sock;
/** client socket */
QHttp* m_http;
#else
/** client socket */
QSocket* m_sock;
#endif
/** current index in receive buffer */
unsigned long m_rcvIdx;
/** index of entity-body in receive buffer, 0 if not available */
unsigned long m_rcvBodyIdx;
/** receive buffer */
QByteArray m_rcvBuf;
/** request to set */
QString m_request;
#endif
/** content length of entitiy-body, 0 if not available */
unsigned long m_rcvBodyLen;
/** content type */
QString m_rcvBodyType;
/** receive buffer */
QByteArray m_rcvBuf;
};
#endif
......@@ -116,6 +116,9 @@ MiscConfig::MiscConfig(const QString& group) :
m_textEncodingV1(""),
m_textEncoding(TE_ISO8859_1),
m_useProxy(false),
#if QT_VERSION >= 0x040000
m_useProxyAuthentication(false),
#endif
m_onlyCustomGenres(false)
#ifndef CONFIG_USE_KDE
, m_windowX(-1), m_windowY(-1), m_windowWidth(-1), m_windowHeight(-1),
......@@ -167,6 +170,11 @@ void MiscConfig::writeToConfig(
cfg.writeEntry("TextEncoding", m_textEncoding);
cfg.writeEntry("UseProxy", m_useProxy);
cfg.writeEntry("Proxy", m_proxy);
#if QT_VERSION >= 0x040000
cfg.writeEntry("UseProxyAuthentication", m_useProxyAuthentication);
cfg.writeEntry("ProxyUserName", m_proxyUserName);
cfg.writeEntry("ProxyPassword", m_proxyPassword);
#endif
cfg.writeEntry("Browser", m_browser);
cfg.writeEntry("OnlyCustomGenres", m_onlyCustomGenres);
......@@ -227,6 +235,11 @@ void MiscConfig::writeToConfig(
config->QCM_writeEntry("/TextEncoding", m_textEncoding);
config->QCM_writeEntry("/UseProxy", m_useProxy);
config->QCM_writeEntry("/Proxy", m_proxy);
#if QT_VERSION >= 0x040000
config->QCM_writeEntry("/UseProxyAuthentication", m_useProxyAuthentication);
config->QCM_writeEntry("/ProxyUserName", m_proxyUserName);
config->QCM_writeEntry("/ProxyPassword", m_proxyPassword);
#endif
config->QCM_writeEntry("/Browser", m_browser);
config->QCM_writeEntry("/OnlyCustomGenres", m_onlyCustomGenres);
config->QCM_writeEntry("/WindowX", m_windowX);
......@@ -303,6 +316,11 @@ void MiscConfig::readFromConfig(
m_textEncoding = cfg.KCM_readNumEntry("TextEncoding", static_cast<int>(TE_ISO8859_1));
m_useProxy = cfg.KCM_readBoolEntry("UseProxy", m_useProxy);
m_proxy = cfg.readEntry("Proxy", m_proxy);
#if QT_VERSION >= 0x040000
m_useProxyAuthentication = cfg.KCM_readBoolEntry("UseProxyAuthentication", m_useProxyAuthentication);
m_proxyUserName = cfg.readEntry("ProxyUserName", m_proxyUserName);