| | |
| | | #include <QCoreApplication> |
| | | #include <QTcpServer> |
| | | #include <QTcpSocket> |
| | | #include <QTextStream> |
| | | #include <QDateTime> |
| | | #include <QStringList> |
| | | #include <QDir> |
| | | #include <QSettings> |
| | | #include "mbwatchapp.h" |
| | | |
| | | #include "qtservice.h" |
| | | |
| | | // HttpDaemon is the the class that implements the simple HTTP server. |
| | | class HttpDaemon : public QTcpServer |
| | | { |
| | | Q_OBJECT |
| | | public: |
| | | HttpDaemon(quint16 port, QObject* parent = 0) |
| | | : QTcpServer(parent), disabled(false) |
| | | { |
| | | listen(QHostAddress::Any, port); |
| | | } |
| | | |
| | | void incomingConnection(qintptr socket) |
| | | { |
| | | if (disabled) |
| | | return; |
| | | |
| | | // When a new client connects, the server constructs a QTcpSocket and all |
| | | // communication with the client is done over this QTcpSocket. QTcpSocket |
| | | // works asynchronously, this means that all the communication is done |
| | | // in the two slots readClient() and discardClient(). |
| | | QTcpSocket* s = new QTcpSocket(this); |
| | | connect(s, SIGNAL(readyRead()), this, SLOT(readClient())); |
| | | connect(s, SIGNAL(disconnected()), this, SLOT(discardClient())); |
| | | s->setSocketDescriptor(socket); |
| | | |
| | | QtServiceBase::instance()->logMessage("New Connection"); |
| | | } |
| | | |
| | | void pause() |
| | | { |
| | | disabled = true; |
| | | } |
| | | |
| | | void resume() |
| | | { |
| | | disabled = false; |
| | | } |
| | | |
| | | private slots: |
| | | void readClient() |
| | | { |
| | | if (disabled) |
| | | return; |
| | | |
| | | // This slot is called when the client sent data to the server. The |
| | | // server looks if it was a get request and sends a very simple HTML |
| | | // document back. |
| | | QTcpSocket* socket = (QTcpSocket*)sender(); |
| | | if (socket->canReadLine()) { |
| | | QStringList tokens = QString(socket->readLine()).split(QRegExp("[ \r\n][ \r\n]*")); |
| | | if (tokens[0] == "GET") { |
| | | QTextStream os(socket); |
| | | os.setAutoDetectUnicode(true); |
| | | os << "HTTP/1.0 200 Ok\r\n" |
| | | "Content-Type: text/html; charset=\"utf-8\"\r\n" |
| | | "\r\n" |
| | | "<h1>Nothing to see here</h1>\n" |
| | | << QDateTime::currentDateTime().toString() << "\n"; |
| | | socket->close(); |
| | | |
| | | QtServiceBase::instance()->logMessage("Wrote to client"); |
| | | |
| | | if (socket->state() == QTcpSocket::UnconnectedState) { |
| | | delete socket; |
| | | QtServiceBase::instance()->logMessage("Connection closed"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | void discardClient() |
| | | { |
| | | QTcpSocket* socket = (QTcpSocket*)sender(); |
| | | socket->deleteLater(); |
| | | |
| | | QtServiceBase::instance()->logMessage("Connection closed"); |
| | | } |
| | | |
| | | private: |
| | | bool disabled; |
| | | }; |
| | | |
| | | class HttpService : public QtService<QCoreApplication> |
| | | { |
| | | public: |
| | | HttpService(int argc, char **argv) |
| | | : QtService<QCoreApplication>(argc, argv, "Qt HTTP Daemon") |
| | | { |
| | | setServiceDescription("A dummy HTTP service implemented with Qt"); |
| | | setServiceFlags(QtServiceBase::CanBeSuspended); |
| | | } |
| | | |
| | | protected: |
| | | void start() |
| | | { |
| | | QCoreApplication *app = application(); |
| | | |
| | | #if QT_VERSION < 0x040100 |
| | | quint16 port = (app->argc() > 1) ? |
| | | QString::fromLocal8Bit(app->argv()[1]).toUShort() : 8888; |
| | | #else |
| | | const QStringList arguments = QCoreApplication::arguments(); |
| | | quint16 port = (arguments.size() > 1) ? |
| | | arguments.at(1).toUShort() : 8888; |
| | | #endif |
| | | port = 8888; |
| | | daemon = new HttpDaemon(port, app); |
| | | |
| | | if (!daemon->isListening()) { |
| | | logMessage(QString("Failed to bind to port %1").arg(daemon->serverPort()), QtServiceBase::Error); |
| | | app->quit(); |
| | | } |
| | | } |
| | | |
| | | void pause() |
| | | { |
| | | daemon->pause(); |
| | | } |
| | | |
| | | void resume() |
| | | { |
| | | daemon->resume(); |
| | | } |
| | | |
| | | private: |
| | | HttpDaemon *daemon; |
| | | }; |
| | | |
| | | #include "main.moc" |
| | | |
| | | int main(int argc, char **argv) |
| | | int main(int argc, char *argv[]) |
| | | { |
| | | #if !defined(Q_OS_WIN) |
| | | // QtService stores service settings in SystemScope, which normally require root privileges. |
| | |
| | | QSettings::setPath(QSettings::NativeFormat, QSettings::SystemScope, QDir::tempPath()); |
| | | qWarning("(Example uses dummy settings file: %s/QtSoftware.conf)", QDir::tempPath().toLatin1().constData()); |
| | | #endif |
| | | HttpService service(argc, argv); |
| | | CMBWatchApp service(argc, argv); |
| | | return service.exec(); |
| | | } |