21 #include <KGlobalSettings>
22 #include <KStandardDirs>
29 #include <QHttpRequestHeader>
36 m_wallet = KWallet::Wallet::openWallet(KWallet::Wallet::LocalWallet(),
38 KWallet::Wallet::Asynchronous);
40 connect(m_wallet, SIGNAL(walletOpened(
bool)), SLOT(init(
bool)));
51 void HttpServer::init(
bool opened)
54 m_wallet->hasFolder(
"KGet") &&
55 m_wallet->setFolder(
"KGet")) {
56 m_wallet->readPassword(
"Webinterface", m_pwd);
58 KGet::showNotification(static_cast<QWidget*>(parent()),
"error", i18n(
"Unable to start WebInterface: Could not open KWallet"));
61 m_tcpServer =
new QTcpServer(
this);
63 KGet::showNotification(static_cast<QWidget*>(parent()),
"error", i18nc(
"@info",
"Unable to start WebInterface: %1", m_tcpServer->errorString()));
67 connect(m_tcpServer, SIGNAL(newConnection()),
this, SLOT(handleRequest()));
73 m_wallet->readPassword(
"Webinterface", m_pwd);
77 void HttpServer::handleRequest()
79 int responseCode = 200;
80 QString responseText =
"OK";
81 QTcpSocket *clientConnection = m_tcpServer->nextPendingConnection();
83 connect(clientConnection, SIGNAL(disconnected()),
84 clientConnection, SLOT(deleteLater()));
86 if (!clientConnection->waitForReadyRead()) {
87 clientConnection->disconnectFromHost();
90 QByteArray request(clientConnection->readAll());
91 QHttpRequestHeader header(request);
96 QString auth = header.value(
"Authorization");
97 if (auth.length() < 6 || QByteArray::fromBase64(auth.right(auth.length() - 6).toUtf8()) !=
100 responseText =
"Authorization Required";
102 QString authRequiredText = QString(
"<html><head><title>401 Authorization Required</title></head><body>"
103 "<h1>Authorization Required</h1>This server could not verify that you "
104 "are authorized to access the document requested. Either you supplied "
105 "the wrong credentials (e.g., bad password), or your browser does "
106 "not understand how to supply the credentials required.</body></html>");
107 data.append(authRequiredText.toUtf8());
110 if (header.path().endsWith(QLatin1String(
"data.json"))) {
111 data.append(
"{\"downloads\":[");
112 bool needsToBeClosed =
false;
116 data.append(QString(
"{\"name\":\"" + transfer->
source().fileName() +
117 "\", \"src\":\"" + transfer->
source().prettyUrl() +
118 "\", \"dest\":\"" + transfer->
dest().pathOrUrl() +
119 "\", \"status\":\"" + transfer->
statusText() +
120 "\", \"size\":\"" + KIO::convertSize(transfer->
totalSize()) +
121 "\", \"progress\":\"" + QString::number(transfer->
percent()) +
"%"
122 "\", \"speed\":\"" + i18nc(
"@item speed of transfer per seconds",
"%1/s",
123 KIO::convertSize(transfer->
downloadSpeed())) +
"\"}").toUtf8());
124 needsToBeClosed =
true;
127 }
else if (header.path().startsWith(QLatin1String(
"/do"))) {
128 kDebug(5001) << request;
130 QString args = header.path().right(header.path().length() - 4);
132 if (!args.isEmpty()) {
136 QStringList argList = args.split(
'&');
137 foreach (
const QString &s, argList) {
138 QStringList map = s.split(
'=');
139 if (map.at(0) ==
"action")
141 else if (map.at(0) ==
"data")
142 data = KUrl::fromPercentEncoding(QByteArray(map.at(1).toUtf8()));
144 else if (map.at(0) ==
"group")
145 group = KUrl::fromPercentEncoding(QByteArray(map.at(1).toUtf8()));
147 kDebug(5001) << action << data << group;
148 if (action ==
"add") {
150 QString defaultFolder;
157 if (defaultFolder.isEmpty()) {
159 if (groups.isEmpty() || groups.first()->defaultFolder().isEmpty()) {
163 groupHandler = groups.first();
164 group = groupHandler->
name();
169 data.append(QString(
"Ok, %1 added!").arg(data).toUtf8());
170 }
else if (action ==
"start") {
174 }
else if (action ==
"stop") {
178 }
else if (action ==
"remove") {
183 kWarning(5001) <<
"not implemented action" << action << data;
187 QString fileName = header.path().remove(
"..");
188 if (fileName.endsWith(
'/'))
189 fileName =
"index.htm";
191 QString path = KStandardDirs::locate(
"data",
"kget/www/" + fileName);
194 if (path.isEmpty() || !file.open(QIODevice::ReadOnly)) {
196 responseText =
"Not Found";
198 QString notfoundText = QString(
"<html><head><title>404 Not Found</title></head><body>"
199 "<h1>Not Found</h1>The requested URL <code>%1</code> "
200 "was not found on this server.</body></html>")
202 data.append(notfoundText.toUtf8());
204 while (!file.atEnd()) {
205 data.append(file.readLine());
208 if (fileName ==
"index.htm") {
209 data.replace(
"#{KGet Webinterface}", i18nc(
"@label",
"KGet Web Interface").toUtf8());
210 data.replace(
"#{Nr}", i18nc(
"@label number",
"Nr").toUtf8());
211 data.replace(
"#{File name}", i18nc(
"@label",
"File name").toUtf8());
212 data.replace(
"#{Finished}", i18nc(
"@label Progress of transfer",
"Finished").toUtf8());
213 data.replace(
"#{Speed}", i18nc(
"@label Speed of transfer",
"Speed").toUtf8());
214 data.replace(
"#{Status}", i18nc(
"@label Status of transfer",
"Status").toUtf8());
215 data.replace(
"#{Start}", i18nc(
"@action:button start a transfer",
"Start").toUtf8());
216 data.replace(
"#{Stop}", i18nc(
"@action:button",
"Stop").toUtf8());
217 data.replace(
"#{Remove}", i18nc(
"@action:button",
"Remove").toUtf8());
218 data.replace(
"#{Source:}", i18nc(
"@label Download from",
"Source:").toUtf8());
219 data.replace(
"#{Saving to:}", i18nc(
"@label Save download to",
"Saving to:").toUtf8());
220 data.replace(
"#{Webinterface}", i18nc(
"@label Title in header",
"Web Interface").toUtf8());
221 data.replace(
"#{Settings}", i18nc(
"@action",
"Settings").toUtf8());
222 data.replace(
"#{Refresh}", i18nc(
"@action",
"Refresh").toUtf8());
223 data.replace(
"#{Enter URL: }", i18nc(
"@action",
"Enter URL: ").toUtf8());
224 data.replace(
"#{OK}", i18nc(
"@action:button",
"OK").toUtf8());
225 data.replace(
"#{Refresh download list every}",
226 i18nc(
"@action Refresh download list every x (seconds)",
"Refresh download list every").toUtf8());
227 data.replace(
"#{seconds}", i18nc(
"@action (Refresh very x )seconds",
"seconds").toUtf8());
228 data.replace(
"#{Save Settings}", i18nc(
"@action:button",
"Save Settings").toUtf8());
229 data.replace(
"#{Downloads}", i18nc(
"@title",
"Downloads").toUtf8());
230 data.replace(
"#{KGet Webinterface | Valid XHTML 1.0 Strict & CSS}",
231 i18nc(
"@label text in footer",
"KGet Web Interface | Valid XHTML 1.0 Strict & CSS").toUtf8().replace(
'&',
"&"));
234 QString groupOptions =
"";
236 groupOptions += QString("<option>%1</option>").arg(group);
237 data.replace("
#{groups}", groupOptions.toUtf8());
244 block.append(QString(
"HTTP/1.1 %1 %2\r\n").arg(responseCode).arg(responseText).toUtf8());
245 block.append(QString(
"Date: %1 GMT\r\n").arg(QDateTime(QDateTime::currentDateTime())
246 .toString(
"ddd, dd MMM yyyy hh:mm:ss")).toUtf8());
247 block.append(QString(
"Server: KGet\r\n").toUtf8());
248 if (responseCode == 401)
249 block.append(QString(
"WWW-Authenticate: Basic realm=\"KGet Webinterface Authorization\"\r\n").toUtf8());
250 if (header.path().endsWith(QLatin1String(
".png")) && responseCode == 200)
251 block.append(QString(
"Content-Type: image/png\r\n").toUtf8());
252 else if (header.path().endsWith(QLatin1String(
".json")) && responseCode == 200)
253 block.append(QString(
"Content-Type: application/x-json\r\n").toUtf8());
254 else if (header.path().endsWith(QLatin1String(
".gif")) && responseCode == 200)
255 block.append(QString(
"Content-Type: image/gif\r\n").toUtf8());
256 else if (header.path().endsWith(QLatin1String(
".js")) && responseCode == 200)
257 block.append(QString(
"Content-Type: text/javascript\r\n").toUtf8());
258 else if (header.path().endsWith(QLatin1String(
".htc")) && responseCode == 200)
259 block.append(QString(
"Content-Type: text/x-component\r\n").toUtf8());
261 block.append(QString(
"Content-Type: text/html; charset=UTF-8\r\n").toUtf8());
262 block.append(QString(
"Content-Length: " + QString::number(data.length())+
"\r\n").toUtf8());
263 block.append(QString(
"\r\n").toUtf8());
266 clientConnection->write(block);
267 clientConnection->disconnectFromHost();
static QString generalDestDir(bool preferXDGDownloadDir=false)
Returns a download directory.
static TransferHandler * addTransfer(KUrl srcUrl, QString destDir=QString(), QString suggestedFileName=QString(), QString groupName=QString(), bool start=false)
Adds a new transfer to the KGet.
static QStringList transferGroupNames()
virtual void start()
These are all Job-related functions.
KIO::filesize_t totalSize() const
static QList< TransferHandler * > allTransfers()
Gets all transfers.
const KUrl & dest() const
QString statusText() const
const KUrl & source() const
static TransferGroupHandler * findGroup(const QString &name)
Get the group with the given name.
int downloadSpeed() const
static QString webinterfaceUser()
Get WebinterfaceUser.
static QList< TransferGroupHandler * > groupsFromExceptions(const KUrl &filename)
HttpServer(QWidget *parent=0)
static KNotification * showNotification(QWidget *parent, const QString &eventType, const QString &text, const QString &icon=QString("dialog-error"), const QString &title=i18n("KGet"), const KNotification::NotificationFlags &flags=KNotification::CloseOnTimeout)
Shows a knotification.
static TransferHandler * findTransfer(const KUrl &src)
Get the transfer with the given url.
static int webinterfacePort()
Get WebinterfacePort.
static bool delTransfer(TransferHandler *transfer, DeleteMode mode=AutoDelete)
Removes a transfer from the KGet.