/* -*- c++ -*- * * previewstreamer.cpp * * Copyright (C) 2004 Petter E. Stokke * * 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 "previewstreamer.h" #include "hostmanager.h" #include "donkeyhost.h" #include "donkeyprotocol.h" #include "fileinfo.h" #include #include #include #include #include #include PreviewStreamerServer::PreviewStreamerServer() : GenericHTTPServer("127.0.0.1", 37435) { } GenericHTTPSession* PreviewStreamerServer::buildSession(KExtendedSocket* sock) { return new PreviewStreamer(this, sock); } PreviewStreamer::PreviewStreamer(GenericHTTPServer* parent, KExtendedSocket* sock) : GenericHTTPSession(parent, sock) , m_donkey(0) , m_job(0) , m_headerSent(false) { } PreviewStreamer::~PreviewStreamer() { delete m_job; delete m_donkey; } bool PreviewStreamer::processRequest(const QHttpRequestHeader& header, const QByteArray&) { KURL url(header.path()); QString p(url.path(-1)); kdDebug() << "Requested path \"" << p << "\"" << endl; QStringList path(QStringList::split('/', url.path(-1))); if (path.count() != 4 && path.count() != 3) return false; HostManager* hosts = new HostManager(this, 0, true); if (!hosts->validHostName(path[0])) { httpError(404, i18n("Unknown host ID")); return true; } m_host = dynamic_cast(hosts->hostProperties(path[0])); if (!m_host) { httpError(404, i18n("Not an MLDonkey host")); return true; } bool badAuth = true; if (path.count() == 4) { if (m_host->password() == path[2]) badAuth = false; } if (path.count() == 3) { if (m_host->password().isEmpty()) badAuth = false; } if (m_host->username() != path[1]) badAuth = true; if (badAuth) { httpError(404, i18n("Incorrect authentication tokens provided")); return true; } bool ok = false; m_id = path[path.count() - 1].toInt(&ok); if (!ok) return ok; m_donkey = new DonkeyProtocol(true, this); connect(m_donkey, SIGNAL(signalConnected()), this, SLOT(donkeyConnected())); connect(m_donkey, SIGNAL(signalDisconnected(int)), this, SLOT(donkeyDisconnected(int))); connect(m_donkey, SIGNAL(updatedDownloadFiles()), this, SLOT(donkeyMsgReceived())); connect(m_donkey, SIGNAL(updatedDownloadedFiles()), this, SLOT(donkeyMsgReceived())); m_donkey->setHost(m_host); m_donkey->connectToCore(); return true; } void PreviewStreamer::donkeyConnected() { m_ct = 0; m_donkey->updateDownloadFiles(); m_donkey->updateDownloadedFiles(); } void PreviewStreamer::donkeyDisconnected(int err) { QString msg; switch (err) { case ProtocolInterface::AuthenticationError: msg = i18n("Incorrect authentication tokens provided"); break; case ProtocolInterface::NoError: deleteLater(); return; case ProtocolInterface::ConnectionRefusedError: msg = i18n("Core is not running"); break; default: msg = i18n("Problem communicating with core"); break; } httpError(404, msg); } void PreviewStreamer::donkeyMsgReceived() { m_ct++; if (m_ct < 2) return; m_file = m_donkey->findDownloadFileNo(m_id); if (!m_file) m_file = m_donkey->findDownloadedFileNo(m_id); if (!m_file) { httpError(404); return; } KURL path; path.setProtocol("http"); path.setUser(m_host->username()); path.setPass(m_host->password()); path.setHost(m_host->address()); path.setPort(m_host->httpPort()); path.setPath("/preview_download"); path.setQuery(QString("?q=%1").arg(m_file->fileNo())); m_streamed = 0; m_ct = time(0); m_job = KIO::get(path, false, false); connect(m_job, SIGNAL(data(KIO::Job*, const QByteArray&)), this, SLOT(dataArrived(KIO::Job*, const QByteArray&))); connect(m_job, SIGNAL(result(KIO::Job*)), this, SLOT(ioResult(KIO::Job*))); } void PreviewStreamer::dataArrived(KIO::Job*, const QByteArray& data) { if (!m_headerSent) { KMimeType::Ptr mimeType = KMimeType::findByPath(m_file->fileName()); sendResponseHeader(mimeType->property("Name").toString(), m_file->fileSize()); m_headerSent = true; } m_streamed += data.size(); sendData(data); if (time(0) > m_ct + 3) { m_ct = time(0); } } void PreviewStreamer::ioResult(KIO::Job*) { // if (job->error()) endRequest(); } #include "previewstreamer.moc"