New feature for KGet: Webinterface.
[kdenetwork.git] / kget / extensions / webinterface / httpserver.cpp
blob205e32725c5b7fbebe86ba867700db3e8f7df60d
1 /* This file is part of the KDE project
3 Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9 */
11 #include "httpserver.h"
13 #include "core/transferhandler.h"
14 #include "core/kget.h"
15 #include "settings.h"
17 #include <KDebug>
18 #include <KMessageBox>
19 #include <KStandardDirs>
21 #include <QTcpServer>
22 #include <QTcpSocket>
23 #include <QFile>
24 #include <QDir>
25 #include <QHttpRequestHeader>
26 #include <QDateTime>
28 HttpServer::HttpServer(QWidget *parent)
29 : QObject(parent)
31 tcpServer = new QTcpServer(this);
32 if (!tcpServer->listen(QHostAddress::Any, Settings::webinterfacePort())) {
33 KMessageBox::error(0, i18n("Unable to start the server: %1.", tcpServer->errorString()));
34 return;
37 connect(tcpServer, SIGNAL(newConnection()), this, SLOT(handleRequest()));
40 void HttpServer::handleRequest()
42 int responseCode = 200;
43 QString responseText = "OK";
44 QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
46 connect(clientConnection, SIGNAL(disconnected()),
47 clientConnection, SLOT(deleteLater()));
49 if (!clientConnection->waitForReadyRead()) {
50 clientConnection->disconnectFromHost();
53 QByteArray request(clientConnection->readAll());
54 QHttpRequestHeader header(request);
56 QByteArray data;
58 if (header.path().endsWith("data.json")) {
59 data.append("{\"downloads\":[");
60 bool needsToBeClosed = false;
61 foreach(TransferHandler *transfer, KGet::allTransfers()) {
62 if (needsToBeClosed)
63 data.append(","); // close the last line
64 data.append(QString("{\"name\":\"" + transfer->source().fileName() +
65 "\", \"status\":\"" + transfer->statusText() +
66 "\", \"size\":\"" + KIO::convertSize(transfer->totalSize()) +
67 "\", \"progress\":\"" + QString::number(transfer->percent()) + "%\"}").toUtf8());
68 needsToBeClosed = true;
70 data.append("]}");
71 } else if (header.path().startsWith("/add")) {
72 kDebug(5001) << request;
74 QString args = header.path().right(header.path().length() - 5);
76 if (!args.isEmpty()) {
77 QStringList argList = args.split('&');
78 foreach(QString s, argList) {
79 QStringList map = s.split('=');
80 QString url = QUrl::fromPercentEncoding(QByteArray(map.at(1).toUtf8()));
81 kDebug() << url;
82 KGet::addTransfer(url, QDir::homePath(), "My Downloads"); //TODO: folders and groups..
83 data.append(QString("Ok, %1 added!").arg(url).toUtf8());
86 } else { // read it from filesystem
87 QString fileName = header.path().replace("..", ""); // disallow changing directory
88 if (fileName.endsWith('/'))
89 fileName = "index.htm";
91 QString path = KStandardDirs::locate("data", "kget/www/" + fileName);
92 QFile file(path);
94 if (path.isEmpty() || !file.open(QIODevice::ReadOnly)) {
95 responseCode = 404;
96 responseText = "Not Found";
97 // DO NOT TRANSLATE THE FOLLOWING MESSAGE! webserver messages are never translated.
98 QString notfoundText = QString("<html><head><title>404 Not Found</title></head><body>"
99 "<h1>Not Found</h1>The requested URL <code>%1</code> "
100 "was not found on this server.</body></html>")
101 .arg(header.path());
102 data.append(notfoundText.toUtf8());
103 } else {
104 while (!file.atEnd()) {
105 data.append(file.readLine());
110 // for HTTP informations see: http://www.jmarshall.com/easy/http/
111 QByteArray block;
112 block.append(QString("HTTP/1.1 %1 %2\r\n").arg(responseCode).arg(responseText).toUtf8());
113 block.append(QString("Date: %1 GMT\r\n").arg(QDateTime(QDateTime::currentDateTime())
114 .toString("ddd, dd MMM yyyy hh:mm:ss")).toUtf8());
115 block.append(QString("Server: KGet\r\n").toUtf8()); //TODO: add KGet version
116 if (header.path().endsWith(".png") && responseCode == 200)
117 block.append(QString("Content-Type: image/png\r\n").toUtf8());
118 else if (header.path().endsWith(".json") && responseCode == 200)
119 block.append(QString("Content-Type: application/x-json\r\n").toUtf8());
120 else
121 block.append(QString("Content-Type: text/html; charset=UTF-8\r\n").toUtf8());
122 block.append(QString("Content-Length: " + QString::number(data.length())+"\r\n").toUtf8());
123 block.append(QString("\r\n").toUtf8());
124 block.append(data);
126 clientConnection->write(block);
127 clientConnection->disconnectFromHost();