/* * Copyright (C) 2007 by Ishan Arora * ishanarora@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "httpconnection.h" #include "httpserver.h" #include "eventmanager.h" #include "json.h" #include #include #include #include #include #include #include #include HttpConnection::HttpConnection(QTcpSocket *socket, HttpServer *parent) : QObject(parent), socket(socket), parent(parent) { socket->setParent(this); connect(socket, SIGNAL(readyRead()), this, SLOT(read())); connect(socket, SIGNAL(disconnected()), this, SLOT(deleteLater())); } HttpConnection::~HttpConnection() { delete socket; } void HttpConnection::processDownloadedFile(QString url, QString file_path) { qDebug("URL %s successfully downloaded !", (const char*)url.toUtf8()); emit torrentReadyToBeDownloaded(file_path, false, url, false); } void HttpConnection::handleDownloadFailure(QString url, QString reason) { std::cerr << "Could not download " << (const char*)url.toUtf8() << ", reason: " << (const char*)reason.toUtf8() << "\n"; } void HttpConnection::read() { QByteArray input = socket->readAll(); /*qDebug(" -------"); qDebug("|REQUEST|"); qDebug(" -------"); */ //qDebug("%s", input.toAscii().constData()); if(input.size() > 100000) { qDebug("Request too big"); generator.setStatusLine(400, "Bad Request"); write(); return; } parser.write(input); if(parser.isError()) { generator.setStatusLine(400, "Bad Request"); write(); } else if (parser.isParsable()) respond(); } void HttpConnection::write() { QByteArray output = generator.toByteArray(); /*qDebug(" --------"); qDebug("|RESPONSE|"); qDebug(" --------"); qDebug()<write(output); socket->disconnectFromHost(); } void HttpConnection::respond() { //qDebug("Respond called"); QStringList auth = parser.value("Authorization").split(" ", QString::SkipEmptyParts); if (auth.size() != 2 || QString::compare(auth[0], "Basic", Qt::CaseInsensitive) != 0 || !parent->isAuthorized(auth[1].toUtf8())) { generator.setStatusLine(401, "Unauthorized"); generator.setValue("WWW-Authenticate", "Basic realm=\"you know what\""); write(); return; } QString url = parser.url(); QStringList list = url.split('/', QString::SkipEmptyParts); if (list.contains(".") || list.contains("..")) { respondNotFound(); return; } if (list.size() == 0) list.append("index.html"); if (list.size() == 2) { if (list[0] == "json") { if (list[1] == "events") { respondJson(); return; } } if (list[0] == "command") { QString command = list[1]; respondCommand(command); generator.setStatusLine(200, "OK"); write(); return; } } if (list[0] == "images") list[0] = "Icons"; else list.prepend("webui"); url = ":/" + list.join("/"); QFile file(url); if(!file.open(QIODevice::ReadOnly)) { respondNotFound(); return; } QString ext = list.last(); int index = ext.lastIndexOf('.') + 1; if (index > 0) ext.remove(0, index); else ext.clear(); QByteArray data = file.readAll(); generator.setStatusLine(200, "OK"); generator.setContentTypeByExt(ext); generator.setMessage(data); write(); } void HttpConnection::respondNotFound() { generator.setStatusLine(404, "File not found"); write(); } void HttpConnection::respondJson() { EventManager* manager = parent->eventManager(); QVariant data = manager->getEventList(); QString string = toJson(data); generator.setStatusLine(200, "OK"); generator.setContentTypeByExt("js"); generator.setMessage(string); write(); } void HttpConnection::respondCommand(QString command) { if(command == "download") { QString urls = parser.post("urls"); QStringList list = urls.split('\n'); foreach(QString url, list){ url = url.trimmed(); if(!url.isEmpty()){ qDebug("Downloading url: %s", (const char*)url.toUtf8()); emit UrlReadyToBeDownloaded(url); } } return; } if(command == "upload") { QByteArray torrentfile = parser.torrent(); // XXX: Trick to get a unique filename QString filePath; QTemporaryFile *tmpfile = new QTemporaryFile(); if (tmpfile->open()) { filePath = tmpfile->fileName(); } delete tmpfile; // write it to HD QFile torrent(filePath); if(torrent.open(QIODevice::WriteOnly)) { torrent.write(torrentfile); torrent.close(); } emit torrentReadyToBeDownloaded(filePath, false, QString(), false); return; } if(command == "resumeall") { emit resumeAllTorrents(); return; } if(command == "pauseall") { emit pauseAllTorrents(); return; } if(command == "resume") { emit resumeTorrent(parser.post("hash")); return; } if(command == "pause") { emit pauseTorrent(parser.post("hash")); return; } if(command == "delete") { emit deleteTorrent(parser.post("hash")); return; } }