Skip to content

Commit

Permalink
qhttp refactor: initial commit of refactor
Browse files Browse the repository at this point in the history
This moves this program from being a FastCGI plugin to hosting its
own web server, courtesy of qhttp.

It is not complete by any means, but works enough to at least let the
control panel start up.  It's missing much functionality, however.

Signed-off-by: Sean Cross <sean@xobs.io>
  • Loading branch information
xobs committed Aug 26, 2016
1 parent 5f5d5d0 commit df87575
Show file tree
Hide file tree
Showing 14 changed files with 1,141 additions and 390 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
@@ -0,0 +1,3 @@
[submodule "qhttp"]
path = qhttp
url = https://github.com/xobs/qhttp.git
1 change: 1 addition & 0 deletions qhttp
Submodule qhttp added at 6f0f68
98 changes: 11 additions & 87 deletions src/NeTVServer.pro
Expand Up @@ -3,95 +3,19 @@
# by adding 'controllers' classes
#

QT = core network
TARGET = NeTVServer
TEMPLATE = app
CONFIG += CONSOLE
QT += core network
QT -= gui
CONFIG += console
osx:CONFIG -= app_bundle

DESTDIR = $$PWD
TARGET = NeTVServer
TEMPLATE = app

CONFIG(debug, debug|release) {
DEFINES += SUPERVERBOSE
}
PRJDIR = ../..
include($$PRJDIR/commondir.pri)

HEADERS = \
static.h \
requestmapper.h \
mot_ctl.h
HEADERS +=

SOURCES = main.cpp \
static.cpp \
requestmapper.cpp \
mot_ctl.cpp
SOURCES += main.cpp

HEADERS += httprequest.h \
httpresponse.h
SOURCES += httprequest.cpp \
httpresponse.cpp

# Include DBus support only on bitbake environment
!exists( /home/torin ) {
message("DBus enabled")
QT += dbus
}

# Hardware bridge
HEADERS += $$PWD/controller/bridgecontroller.h
SOURCES += $$PWD/controller/bridgecontroller.cpp \
$$PWD/controller/bridgecontroller_utils.cpp \
$$PWD/controller/bridgecontroller_slots.cpp


OTHER_FILES += \
../etc/NeTVServer.ini \
../etc/flashpolicy.xml \
../etc/start_netvserver.sh \
../etc/docroot/index.html \
../etc/docroot/xmlbridge.html \
../etc/docroot/favicon.ico \
../etc/docroot/images/chumby.png \
../etc/docroot/scripts/hello.sh \
../etc/docroot/scripts/test_param.sh \
../etc/docroot/scripts/xmlbridge.sh

include(../lib/bfFlashPolicyServer/src/bfFlashpolicyserver.pri)
include(../lib/bfSocketServer/src/bfSocketserver.pri)

# QDBus
contains( QT, dbus ) {
CONFIG += qdbus
DEFINES += ENABLE_DBUS_STUFF
include(../lib/bfDBusMonitor/src/bfDBusMonitor.pri)
}

# Change the name of the target, when is debug mode
CONFIG( debug, debug|release ) {
TARGET = $${TARGET}_debug
BUILD_NAME = debug
}
CONFIG( release, debug|release ) {
TARGET = $${TARGET}
BUILD_NAME = release
}

# Recommended for Bitbake
target.path = /usr/bin
INSTALLS += target

# FastCGI library
LIBS += -lfcgi

# Temporary folders for the auxiliar files
INCLUDEPATH += $$PWD/tmp/$$BUILD_NAME $$PWD/tmp
OBJECTS_DIR = $$PWD/tmp/$$BUILD_NAME
MOC_DIR = $$PWD/tmp/$$BUILD_NAME
UI_DIR = $$PWD/tmp/$$BUILD_NAME
RCC_DIR = $$PWD/tmp/$$BUILD_NAME
DESTDIR = $$PWD/bin

# Hacks for qmake compiling on Torin's development Ubuntu
exists( /home/torin ) {
message("Cross compiling on Torin's Ubuntu development machine")
INCLUDEPATH += /mnt/storage/fcgi/include
LIBS += -L/mnt/storage/fcgi/lib
}
LIBS += -lqhttp
625 changes: 489 additions & 136 deletions src/controller/bridgecontroller.cpp

Large diffs are not rendered by default.

28 changes: 15 additions & 13 deletions src/controller/bridgecontroller.h
@@ -1,11 +1,10 @@
#ifndef BridgeController_H
#define BridgeController_H

#include <QObject>
#include <QSettings>
#include <fcgiapp.h>
#include "httprequest.h"
#include "httpresponse.h"
#include "socketrequesthandler.h"
#include "qhttpserverrequest.hpp"
#include "qhttpserverresponse.hpp"

#define TAG "NeTVServer"
#define BRIDGE_RETURN_STATUS_UNIMPLEMENTED "0"
Expand All @@ -23,11 +22,11 @@
#define STRING_COMMAND_FORWARDED_CLIENT "Command forwarded to TCP clients"
#define STRING_NO_CLIENT_RUNNING "No client is running"

using namespace qhttp::server;

class BridgeController : public QObject, public SocketRequestHandler
class BridgeController : public QObject
{
Q_OBJECT
//Q_DISABLE_COPY(BridgeController);
public:

/** Constructor */
Expand All @@ -36,14 +35,18 @@ class BridgeController : public QObject, public SocketRequestHandler
~BridgeController();

/** Receive & response to HTTP requests */
int handle_fastcgi_request(FCGX_Request *request);
void service(HttpRequest& request, HttpResponse& response);
//int handle_fastcgi_request(FCGX_Request *request);
//void service(HttpRequest& request, HttpResponse& response);
void service(QHttpRequest* req, QHttpResponse* res);

/** Receive & response to socket requests */
void service(SocketRequest& request, SocketResponse& response);
//void service(SocketRequest& request, SocketResponse& response);

void replyToHttpClient(QHttpResponse *response, int numClients, const QByteArray & cmdString);

public slots:

/*
// From dbusmonitor.h
void slot_StateChanged(uint state);
void slot_PropertiesChanged(QByteArray prop_name, QByteArray prop_value);
Expand All @@ -55,14 +58,13 @@ public slots:
void slot_StartAP();
void slot_StartAP_Factory();
void slot_Reboot();
*/

signals:

// To InputDevice module
void signal_SendKeyEvent(QByteArray keyName, bool isPressed, bool autoRepeat);

private:

/** Variables from NeTVServer.ini */
QString docroot; //This docroot is for executing scripts, should not be changed
QString paramsFile;
Expand Down Expand Up @@ -116,10 +118,10 @@ public slots:
QByteArray XMLUnescape(QByteArray inputString);

/** HTTP response */
void DumpStaticFile(QByteArray path, HttpResponse& response);
//void DumpStaticFile(QByteArray path, HttpResponse& response);

public:
static void SetContentType(QString fileName, HttpResponse& response);
//static void SetContentType(QString fileName, HttpResponse& response);
};

#endif // BridgeController_H
177 changes: 23 additions & 154 deletions src/main.cpp
@@ -1,116 +1,24 @@
#include <QCoreApplication>
#include <QDebug>
#include <QProcess>
#include <QStringList>
#include <QDir>
#include <QByteArray>
#include <QStringList>
#include "static.h"
#include "flashpolicyserver.h"
#include "tcpsocketserver.h"
#include "udpsocketserver.h"
#include "requestmapper.h"

#include <stdio.h>
#include <stdlib.h>
#include <fcgiapp.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include "netvserverapplication.h"
#include "nhttprequest.h"
#include "netvhandlers.h"

/** Name of this application */
#define APPNAME "NeTVServer"

#define FCGI_SOCKET "/tmp/bridge.socket"
#define THREAD_COUNT 20


//----------------------------------------------------------------------------------------------------------------
// FastCGI stuffs
//----------------------------------------------------------------------------------------------------------------

/*
* Initial parsing of the request path & redirect to actual handler function
*/
static int
handle_request(FCGX_Request *request)
{
int ret = -1;
char *uri = FCGX_GetParam("REQUEST_URI", request->envp);

if (!strncmp(uri, "/bridge", strlen("/bridge"))) {
ret = Static::bridgeController->handle_fastcgi_request(request);
}

else {
fprintf(stderr, "Unrecognized URI: %s\n", uri);
}

return ret;
}


/*
* Threaded function to handle FastCGI request
*/
static void *
request_thread(void *s_ptr)
{
int rc;
FCGX_Request request;

if (FCGX_InitRequest(&request, *((int *)s_ptr), 0)) {
perror("Unable to init request");
return NULL;
}

while (1) {
static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_lock(&accept_mutex);
rc = FCGX_Accept_r(&request);
pthread_mutex_unlock(&accept_mutex);

handle_request(&request);
FCGX_Finish_r(&request);
}

return NULL;
}



//----------------------------------------------------------------------------------------------------------------
// Qt stuffs
//----------------------------------------------------------------------------------------------------------------

/*
* Return true if there is another instance of this program already running
*/
bool isRunning()
{
QProcess *newProc = new QProcess();
newProc->start("/bin/pidof", QStringList(APPNAME));
newProc->waitForFinished();

QByteArray buffer = newProc->readAllStandardOutput();
newProc->close();
delete newProc;
newProc = NULL;

QStringList pidList = QString(buffer.trimmed()).split(" ", QString::SkipEmptyParts);
if (pidList.length() > 1)
return true;

return false;
}

#include "qhttpserver.hpp"
#include "qhttpserverconnection.hpp"
#include "qhttpserverrequest.hpp"
#include "qhttpserverresponse.hpp"

/*
* Create handlers, listeners and assign them to global pointers in Static class
*/
int initialize_modules()
static int loadConfiguration(void)
{
#if 0
// Configuration file
QString configFileName=Static::getConfigDir()+"/"+APPNAME+".ini";

Expand Down Expand Up @@ -149,62 +57,23 @@ int initialize_modules()
QObject::connect(Static::dbusMonitor, SIGNAL(signal_DeviceAdded(QByteArray)), Static::bridgeController, SLOT(slot_DeviceAdded(QByteArray)));
QObject::connect(Static::dbusMonitor, SIGNAL(signal_DeviceRemoved(QByteArray)), Static::bridgeController, SLOT(slot_DeviceRemoved(QByteArray)));
#endif

#endif
return 0;
}


int main(int argc, char ** argv) {
NeTVServerApplication app(argc, argv);
#if defined(Q_OS_UNIX)
catchUnixSignals({ SIGQUIT, SIGINT, SIGTERM, SIGHUP });
#endif

//----------------------------------------------------------------------------------------------------------------
// main
//----------------------------------------------------------------------------------------------------------------

int main(int argc, char *argv[])
{
QCoreApplication instance(argc, argv);
instance.setApplicationName(APPNAME);
instance.setOrganizationName("");

if (isRunning()) {
qDebug("Another NeTVServer is already running");
return 1;
}

QStringList argsList = instance.arguments();

// If the args list contains "-d", then daemonize
int temp = 0;
if (argsList.contains("-d"))
temp = daemon(0, 0);

// Print out console arguments (if any)
if (argsList.count() > 0)
qDebug("Starting new NeTVServer");

// Initialize global pointers
initialize_modules();

//-----------------------------------------------------------
// FastCGI

int listen_socket;
int i;
pthread_t threads[THREAD_COUNT];

FCGX_Init();
listen_socket = FCGX_OpenSocket(FCGI_SOCKET, 10);
if (listen_socket < 0) {
perror("Unable to open listen socket");
exit(1);
}

for (i=0; i<THREAD_COUNT; i++) {
pthread_create(&threads[i], NULL, request_thread, (void *)&listen_socket);
pthread_detach(threads[i]);
}

//-----------------------------------------------------------

// Qt events loop
return instance.exec();
app.registerBridgeFunction("geturl", handleGetUrl);
app.registerBridgeFunction("getjpeg", handleGetJpeg);
app.registerBridgeFunction("getjpg", handleGetJpeg);
app.registerBridgeFunction("initialhello", handleInitialHello);
app.registerBridgeFunction("getparam", handleGetParam);
app.registerBridgeFunction("", handleDefault);
app.setStaticDocRoot("D:\\Code\\netv-controlpanel");
app.exec();
}

0 comments on commit df87575

Please sign in to comment.