diff -Nru jetserver-0.1.1/debian/changelog jetserver-0.1.2/debian/changelog --- jetserver-0.1.1/debian/changelog 2011-01-02 00:09:04.000000000 +0000 +++ jetserver-0.1.2/debian/changelog 2011-01-04 00:44:39.000000000 +0000 @@ -1,4 +1,4 @@ -jetserver (0.1.1-1) lucid; urgency=low +jetserver (0.1.2-1) lucid; urgency=low * Initial release (Closes: #nnnn) diff -Nru jetserver-0.1.1/debian/control jetserver-0.1.2/debian/control --- jetserver-0.1.1/debian/control 2010-12-29 06:35:11.000000000 +0000 +++ jetserver-0.1.2/debian/control 2011-01-02 00:16:05.000000000 +0000 @@ -35,7 +35,7 @@ communicating with the server. Package: jetserver -Section: libs +Section: web Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: A collection of tightly integrated web server applications. diff -Nru jetserver-0.1.1/debian/jetserver.install jetserver-0.1.2/debian/jetserver.install --- jetserver-0.1.1/debian/jetserver.install 2010-12-28 23:25:31.000000000 +0000 +++ jetserver-0.1.2/debian/jetserver.install 2011-01-04 00:45:26.000000000 +0000 @@ -1 +1,2 @@ usr/bin/* +jetserver.html usr/share/jetserver diff -Nru jetserver-0.1.1/jetserver/CAPIServer.cpp jetserver-0.1.2/jetserver/CAPIServer.cpp --- jetserver-0.1.1/jetserver/CAPIServer.cpp 1970-01-01 00:00:00.000000000 +0000 +++ jetserver-0.1.2/jetserver/CAPIServer.cpp 2011-01-03 22:54:58.000000000 +0000 @@ -0,0 +1,208 @@ +#include "CAPIServer.h" + +// Qt includes +#include + +CAPIServer::CAPIServer() + : m_jetftp() +{ + connect(this,SIGNAL(newConnection()),SLOT(OnConnection())); + + // Listen on port 1025 + listen(QHostAddress::Any, 1025); + + qDebug("Listening for HTTP requests on port 1025..."); +} + +CAPIServer::~CAPIServer() +{ + //... +} + +void CAPIServer::OnConnection() +{ + // Get the next pending connection + QTcpSocket * pSocket = nextPendingConnection(); + + // Data we read from the socket + QString data; // the complete contents + QByteArray chunk; + + do + { + pSocket->waitForReadyRead(); + chunk = pSocket->readAll(); + data.append(chunk); + + // Also break if we read the 2x CRLF + // that designate the end of the header. + if(data.indexOf("\r\n\r\n") != -1) + break; + + } while(chunk.size()); + + // Now break down the HTTP request into its principle + // components. + + // Get the first line of the HTTP header + int iFirstSpace, iSecondSpace; + + if((iFirstSpace = data.indexOf(" ")) != -1) + iSecondSpace = data.indexOf(" ", iFirstSpace + 1); + + if((iFirstSpace == -1) || (iSecondSpace == -1)) + { + delete pSocket; + return; + } + + QString resource = data.mid(iFirstSpace + 1,(iSecondSpace - iFirstSpace - 1)); + + qDebug(tr("API request: %1").arg(resource).toUtf8().data()); + + QString result_str = ProcessRequest(resource); + QByteArray raw_result = result_str.toUtf8(); + + // We need to write a VERY basic header + // to wrap the result we need to send + int iContentLength = raw_result.size(); + + pSocket->write("HTTP/1.1 200 OK\r\n"); + pSocket->write("Content-Type: text/html\r\n"); + pSocket->write(tr("Content-Length: %1\r\n\r\n").arg(iContentLength).toUtf8().data()); + pSocket->write(raw_result); + + pSocket->waitForBytesWritten(); + pSocket->close(); + + delete pSocket; +} + +QString CAPIServer::JSONError(QString error) +{ + return tr("{\"error\":\"%1\"}").arg(error); +} + +QString CAPIServer::XMLError(QString error) +{ + return tr("\n%1").arg(error); +} + +QString CAPIServer::Error(QString error, bool bJSON) +{ + return (bJSON)?JSONError(error):XMLError(error); +} + +QString CAPIServer::Success(bool bJSON) +{ + if(bJSON) + return "{\"status\":\"The operation was performed successfully.\"}"; + else + return "\nThe operation was performed successfully."; +} + +QString CAPIServer::ProcessRequest(QString request) +{ + bool bJSONP = false; + QString jsonp_start, jsonp_end; + + // First check to see if this is a JSONP request + if(request.indexOf("?") != -1) + { + // We have a JSONP request, so find the index + // of the question mark and chop it off at that + // point. + int question_index = request.indexOf("?"); + QString query_string = request.right(request.size() - question_index - 1); + + // Trim the ? off the main string + request.resize(question_index); + + QStringList params = query_string.split("="); + if(params.size() < 2) + return "Invalid query string."; + + // Now make sure it's the query string parameter + if(params[0] != "jsonp") + return "Invalid query string parameter."; + + bJSONP = true; + jsonp_start = params[1] + "("; + jsonp_end = ")"; + } + + // Split the request into tokens + QStringList tokens = request.split('/',QString::SkipEmptyParts); + if(tokens.size() < 2) + return "Invalid API request."; + + bool bJSON = false; // whether we return JSON or XML + if(tokens[0] == "json") bJSON = true; + + if(tokens.size() < 3) + return Error("Invalid API request.",bJSON); + + // Now determine the component we're after. + if(tokens[1] == "jetserver") + return jsonp_start + ProcessJetServerRequest(tokens,bJSON) + jsonp_end; + else if(tokens[1] == "jetftp") + return jsonp_start + ProcessJetFTPRequest(tokens,bJSON) + jsonp_end; + + return Error("Invalid component specified.", bJSON); +} + +QString CAPIServer::ProcessJetServerRequest(QStringList tokens, bool bJSON) +{ + if(tokens[2] == "sockets") + { + if(tokens.size() < 4) + return Error("Invalid API request.",bJSON); + + CApplicationServer * pServer = NULL; + if(tokens[3] == "jetftp") pServer = &m_jetftp; + + if(!pServer) + return Error("Invalid component specified.",bJSON); + + // Now get the connections for that token. + QList connections = pServer->GetSocketNumbers(); + + // Enumerate them and send that to the client + QString result; + + result = (bJSON)?"{\"connections\":[" : "\n"; + + for(int i=0;i\n"; + + result += tr("%1").arg(connections[i]); + } + + result += (bJSON)?"]}":""; + return result; + } + + return Error("Invalid command specified.", bJSON); +} + +QString CAPIServer::ProcessJetFTPRequest(QStringList tokens, bool bJSON) +{ + int conn_num = tokens[2].toInt(); + + CApplicationSocket * pSocket = m_jetftp.GetSocket(conn_num); + + if(pSocket == NULL) + return Error("The specified socket number is invalid.",bJSON); + + // Make sure we have a command + if(tokens.size() < 4) + return Error("Command missing.",bJSON); + + if(tokens[3] == "terminate") + pSocket->SendMessage("TERMINATE"); + + // Then we return the results... + return Success(bJSON); +} diff -Nru jetserver-0.1.1/jetserver/CAPIServer.h jetserver-0.1.2/jetserver/CAPIServer.h --- jetserver-0.1.1/jetserver/CAPIServer.h 1970-01-01 00:00:00.000000000 +0000 +++ jetserver-0.1.2/jetserver/CAPIServer.h 2011-01-03 01:31:37.000000000 +0000 @@ -0,0 +1,41 @@ +#ifndef CAPISERVER_H +#define CAPISERVER_H + +// Qt includes +#include +#include + +// JetServer includes +#include "CJetFTPServer.h" + +class CAPIServer : public QTcpServer +{ + Q_OBJECT + +public: + + CAPIServer(); + ~CAPIServer(); + +public slots: + + void OnConnection(); + +private: + + // Utility functions + QString JSONError(QString); + QString XMLError(QString); + QString Error(QString,bool); + QString Success(bool); + + // Processing functions + QString ProcessRequest(QString); + QString ProcessJetServerRequest(QStringList, bool); + QString ProcessJetFTPRequest(QStringList, bool); + + // Connections to the clients + CJetFTPServer m_jetftp; +}; + +#endif // CAPISERVER_H diff -Nru jetserver-0.1.1/jetserver/CApplicationServer.cpp jetserver-0.1.2/jetserver/CApplicationServer.cpp --- jetserver-0.1.1/jetserver/CApplicationServer.cpp 2011-01-01 23:08:53.000000000 +0000 +++ jetserver-0.1.2/jetserver/CApplicationServer.cpp 2011-01-02 23:22:30.000000000 +0000 @@ -1,7 +1,7 @@ #include "CApplicationServer.h" CApplicationServer::CApplicationServer(QString name, int port) - : m_name(name) + : m_name(name), m_connection_number(0) { // listen on the following port listen(QHostAddress::Any, port); @@ -20,10 +20,23 @@ { CApplicationSocket * pSocket = CreateSocket(handle); + // Now we add this item to our map. + m_map[m_connection_number++] = pSocket; + connect(pSocket,SIGNAL(Finished(CApplicationSocket *)),SLOT(OnComplete(CApplicationSocket *))); } +CApplicationSocket * CApplicationServer::GetSocket(int i) +{ + if(m_map.contains(i)) + return m_map[i]; + return NULL; +} + void CApplicationServer::OnComplete(CApplicationSocket * pSocket) { + // Remove it from our map. + m_map.remove(m_map.key(pSocket)); + delete pSocket; } diff -Nru jetserver-0.1.1/jetserver/CApplicationServer.h jetserver-0.1.2/jetserver/CApplicationServer.h --- jetserver-0.1.1/jetserver/CApplicationServer.h 2011-01-01 23:06:11.000000000 +0000 +++ jetserver-0.1.2/jetserver/CApplicationServer.h 2011-01-03 01:35:21.000000000 +0000 @@ -2,6 +2,7 @@ #define CAPPLICATIONSERVER_H // Qt includes +#include #include // JetServer includes @@ -18,17 +19,27 @@ void incomingConnection(int); + CApplicationSocket * GetSocket(int); + QList GetSocketNumbers() { return m_map.keys(); } + protected: virtual CApplicationSocket * CreateSocket(int) = 0; + // The application name + QString m_name; + + // The map of instances to numbers + // (used to identify the connections) + QMap m_map; + public slots: void OnComplete(CApplicationSocket *); private: - QString m_name; + int m_connection_number; }; diff -Nru jetserver-0.1.1/jetserver/CApplicationSocket.cpp jetserver-0.1.2/jetserver/CApplicationSocket.cpp --- jetserver-0.1.1/jetserver/CApplicationSocket.cpp 2011-01-01 23:16:33.000000000 +0000 +++ jetserver-0.1.2/jetserver/CApplicationSocket.cpp 2011-01-02 23:00:26.000000000 +0000 @@ -5,6 +5,7 @@ { connect(&m_thread,SIGNAL(started()),SLOT(OnInitialize())); connect(this,SIGNAL(disconnected()),SLOT(OnDisconnect())); + connect(this,SIGNAL(WriteMessage(QString)),SLOT(OnMessage(QString))); m_thread.start(); moveToThread(&m_thread); @@ -21,6 +22,13 @@ qDebug(tr("Connection to %1 closed.").arg(m_name).toUtf8().data()); } +void CApplicationSocket::SendMessage(QString message) +{ + // Emit a signal that tells the socket thread + // we have a message to send, and then send that signal. + emit WriteMessage(message); +} + void CApplicationSocket::OnInitialize() { qDebug(tr("Connection to %1 established.").arg(m_name).toUtf8().data()); @@ -36,7 +44,7 @@ void CApplicationSocket::OnData() { // read to the end of the next line - QByteArray data = readLine(); + QByteArray data = readLine().trimmed(); // Split it into command / argument format QString command; @@ -63,6 +71,12 @@ // Otherwise, just ignore it :) } +void CApplicationSocket::OnMessage(QString message) +{ + write(tr("%1\r\n").arg(message).toUtf8()); + waitForBytesWritten(); +} + void CApplicationSocket::OnDisconnect() { // We emit a signal indicating that diff -Nru jetserver-0.1.1/jetserver/CApplicationSocket.h jetserver-0.1.2/jetserver/CApplicationSocket.h --- jetserver-0.1.1/jetserver/CApplicationSocket.h 2011-01-01 23:11:09.000000000 +0000 +++ jetserver-0.1.2/jetserver/CApplicationSocket.h 2011-01-02 22:52:03.000000000 +0000 @@ -15,14 +15,18 @@ CApplicationSocket(QString,int); ~CApplicationSocket(); + void SendMessage(QString); + public slots: void OnInitialize(); void OnData(); + void OnMessage(QString); void OnDisconnect(); signals: + void WriteMessage(QString); void Finished(CApplicationSocket *); private: diff -Nru jetserver-0.1.1/jetserver/jetserver.pro jetserver-0.1.2/jetserver/jetserver.pro --- jetserver-0.1.1/jetserver/jetserver.pro 2011-01-01 22:37:04.000000000 +0000 +++ jetserver-0.1.2/jetserver/jetserver.pro 2011-01-02 00:28:40.000000000 +0000 @@ -20,13 +20,15 @@ CApplicationSocket.cpp \ CJetFTPSocket.cpp \ CApplicationServer.cpp \ - CJetFTPServer.cpp + CJetFTPServer.cpp \ + CAPIServer.cpp HEADERS += \ CApplicationSocket.h \ CJetFTPSocket.h \ CApplicationServer.h \ - CJetFTPServer.h + CJetFTPServer.h \ + CAPIServer.h #----------------------- # required for debian diff -Nru jetserver-0.1.1/jetserver/main.cpp jetserver-0.1.2/jetserver/main.cpp --- jetserver-0.1.1/jetserver/main.cpp 2011-01-01 22:46:27.000000000 +0000 +++ jetserver-0.1.2/jetserver/main.cpp 2011-01-02 21:38:01.000000000 +0000 @@ -18,14 +18,13 @@ #include // JetServer includes -#include "CJetFTPServer.h" -#include "CJetFTPSocket.h" +#include "CAPIServer.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); - CJetFTPServer JetFTP; + CAPIServer api; // HTTP connection to monitoring apps return a.exec(); } diff -Nru jetserver-0.1.1/jetservercommunicator/CJetServerCommunicator.cpp jetserver-0.1.2/jetservercommunicator/CJetServerCommunicator.cpp --- jetserver-0.1.1/jetservercommunicator/CJetServerCommunicator.cpp 2011-01-02 00:01:44.000000000 +0000 +++ jetserver-0.1.2/jetservercommunicator/CJetServerCommunicator.cpp 2011-01-02 23:09:32.000000000 +0000 @@ -7,6 +7,8 @@ { m_socket.connectToHost(QHostAddress::LocalHost, port, QIODevice::ReadWrite); m_socket.waitForConnected(); + + connect(&m_socket,SIGNAL(readyRead()),SLOT(OnMessage())); } CJetServerCommunicator::~CJetServerCommunicator() @@ -29,3 +31,10 @@ m_socket.write(raw_message); m_socket.waitForBytesWritten(); } + +void CJetServerCommunicator::OnMessage() +{ + QByteArray data = m_socket.readLine(); + + emit NewMessage(QString(data).trimmed()); +} diff -Nru jetserver-0.1.1/jetservercommunicator/CJetServerCommunicator.h jetserver-0.1.2/jetservercommunicator/CJetServerCommunicator.h --- jetserver-0.1.1/jetservercommunicator/CJetServerCommunicator.h 2011-01-01 23:47:04.000000000 +0000 +++ jetserver-0.1.2/jetservercommunicator/CJetServerCommunicator.h 2011-01-02 23:02:53.000000000 +0000 @@ -25,6 +25,10 @@ // Used for sending a message void SendMessage(QString); +public slots: + + void OnMessage(); + signals: // Indicates that a new message is available diff -Nru jetserver-0.1.1/jetserver.html jetserver-0.1.2/jetserver.html --- jetserver-0.1.1/jetserver.html 1970-01-01 00:00:00.000000000 +0000 +++ jetserver-0.1.2/jetserver.html 2011-01-04 00:41:45.000000000 +0000 @@ -0,0 +1,120 @@ + + +JetServer JavaScript GUI + + + + +
+

JetServer JavaScript GUI

+
+ + + + + + + + +
JetFTP Status:Fetching...
+
+ +