From 19c610538968a94cb1f923f4df562432fe417fae Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 7 Jan 2014 17:56:20 +0100 Subject: [PATCH] + Implement a lightweight TCP server --- src/Mod/Web/App/AppWeb.cpp | 50 ++++++++++++++ src/Mod/Web/App/AppWebPy.cpp | 103 ++++++++++++++++++++++++++++ src/Mod/Web/App/CMakeLists.txt | 65 ++++++++++++++++++ src/Mod/Web/App/PreCompiled.cpp | 24 +++++++ src/Mod/Web/App/PreCompiled.h | 61 +++++++++++++++++ src/Mod/Web/App/Server.cpp | 118 ++++++++++++++++++++++++++++++++ src/Mod/Web/App/Server.h | 74 ++++++++++++++++++++ src/Mod/Web/CMakeLists.txt | 1 + 8 files changed, 496 insertions(+) create mode 100644 src/Mod/Web/App/AppWeb.cpp create mode 100644 src/Mod/Web/App/AppWebPy.cpp create mode 100644 src/Mod/Web/App/CMakeLists.txt create mode 100644 src/Mod/Web/App/PreCompiled.cpp create mode 100644 src/Mod/Web/App/PreCompiled.h create mode 100644 src/Mod/Web/App/Server.cpp create mode 100644 src/Mod/Web/App/Server.h diff --git a/src/Mod/Web/App/AppWeb.cpp b/src/Mod/Web/App/AppWeb.cpp new file mode 100644 index 000000000..5981b56a8 --- /dev/null +++ b/src/Mod/Web/App/AppWeb.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (c) 2014 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" +#ifndef _PreComp_ +# include +#endif + +#include + + +/* registration table */ +extern struct PyMethodDef Web_methods[]; + +PyDoc_STRVAR(module_Web_doc, +"This module is the Web module."); + + +/* Python entry */ +extern "C" { +void WebAppExport initWeb() { + + // ADD YOUR CODE HERE + // + // + (void) Py_InitModule3("Web", Web_methods, module_Web_doc); /* mod name, table ptr */ + Base::Console().Log("Loading Web module... done\n"); +} + +} // extern "C" diff --git a/src/Mod/Web/App/AppWebPy.cpp b/src/Mod/Web/App/AppWebPy.cpp new file mode 100644 index 000000000..a98281aa8 --- /dev/null +++ b/src/Mod/Web/App/AppWebPy.cpp @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (c) 2014 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" +#ifndef _PreComp_ +#endif + +#include + +#include +#include +#include +#include +#include "Server.h" + +using namespace Web; + + +// See http://docs.python.org/2/library/socketserver.html +/* +import socket +import threading +import SocketServer + + +ip = "127.0.0.1" +port=54880 + +def client(ip, port, message): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect((ip, port)) + try: + sock.sendall(message) + response = sock.recv(1024) + print "Received: {}".format(response) + finally: + sock.close() + + + +client(ip, port, "print 'Hello World 1'") +client(ip, port, "import FreeCAD\nFreeCAD.newDocument()") +client(ip, port, "Hello World 3\n") + +*/ + +/* module functions */ +static PyObject * startServer(PyObject *self, PyObject *args) +{ + const char* addr = "127.0.0.1"; + int port=0; + if (!PyArg_ParseTuple(args, "|si",&addr,&port)) + return NULL; + + PY_TRY { + AppServer* server = new AppServer(); + + if (server->listen(QHostAddress(QString::fromLatin1(addr)), port)) { + QString a = server->serverAddress().toString(); + quint16 p = server->serverPort(); + Py::Tuple t(2); + t.setItem(0, Py::String((const char*)a.toLatin1())); + t.setItem(1, Py::Int(p)); + return Py::new_reference_to(t); + } + else { + QString a = server->serverAddress().toString(); + quint16 p = server->serverPort(); + server->deleteLater(); + PyErr_Format(PyExc_RuntimeError, "Server failed to listen at address %s and port %d", (const char*)a.toLatin1(), p); + return 0; + } + } PY_CATCH; + + Py_Return; +} + +/* registration table */ +struct PyMethodDef Web_methods[] = { + {"startServer",startServer ,METH_VARARGS, + "startServer(address=127.0.0.1,port=0) -- Start a server."}, + {NULL, NULL} /* end of table marker */ +}; diff --git a/src/Mod/Web/App/CMakeLists.txt b/src/Mod/Web/App/CMakeLists.txt new file mode 100644 index 000000000..d81a29721 --- /dev/null +++ b/src/Mod/Web/App/CMakeLists.txt @@ -0,0 +1,65 @@ + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${Boost_INCLUDE_DIRS} + ${OCC_INCLUDE_DIR} + ${PYTHON_INCLUDE_PATH} + ${ZLIB_INCLUDE_DIR} + ${XERCESC_INCLUDE_DIR} + ${QT_INCLUDE_DIR} +) + +if(MSVC) + set(Web_LIBS + FreeCADApp + ${QT_DEBUG_LIBRARIES} + ${QT_LIBRARIES} + ) +else(MSVC) + set(Web_LIBS + FreeCADApp + ${QT_LIBRARIES} + ) +endif(MSVC) + +set(Web_MOC_HDRS + Server.h +) +fc_wrap_cpp(Web_MOC_SRCS ${Web_MOC_HDRS}) +SOURCE_GROUP("Moc" FILES ${Web_MOC_SRCS}) + +SET(Web_SRCS + AppWeb.cpp + AppWebPy.cpp + PreCompiled.cpp + PreCompiled.h + Server.cpp + Server.h +) + +add_library(Web SHARED ${Web_SRCS}) +target_link_libraries(Web ${Web_LIBS}) + + +fc_target_copy_resource(Web + ${CMAKE_SOURCE_DIR}/src/Mod/Web + ${CMAKE_BINARY_DIR}/Mod/Web + Init.py) + +if(MSVC) + set_target_properties(Web PROPERTIES SUFFIX ".pyd") + set_target_properties(Web PROPERTIES DEBUG_OUTPUT_NAME "Web_d") + set_target_properties(Web PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Mod/Web) + set_target_properties(Web PROPERTIES PREFIX "../") +elseif(MINGW) + set_target_properties(Web PROPERTIES SUFFIX ".pyd") + set_target_properties(Web PROPERTIES DEBUG_OUTPUT_NAME "Web_d") + set_target_properties(Web PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Mod/Web) + set_target_properties(Web PROPERTIES PREFIX "") +else(MSVC) + set_target_properties(Web PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Mod/Web) + set_target_properties(Web PROPERTIES PREFIX "") + set_target_properties(Fem PROPERTIES INSTALL_RPATH ${INSTALL_RPATH}) +endif(MSVC) + +install(TARGETS Web DESTINATION lib) diff --git a/src/Mod/Web/App/PreCompiled.cpp b/src/Mod/Web/App/PreCompiled.cpp new file mode 100644 index 000000000..d771f2b92 --- /dev/null +++ b/src/Mod/Web/App/PreCompiled.cpp @@ -0,0 +1,24 @@ +/*************************************************************************** + * Copyright (c) 2014 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" diff --git a/src/Mod/Web/App/PreCompiled.h b/src/Mod/Web/App/PreCompiled.h new file mode 100644 index 000000000..2ca1cbb6c --- /dev/null +++ b/src/Mod/Web/App/PreCompiled.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (c) 2014 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef APP_PRECOMPILED_H +#define APP_PRECOMPILED_H + +#include + +// Exporting of App classes +#ifdef FC_OS_WIN32 +# define WebAppExport __declspec(dllexport) +#else // for Linux +# define WebAppExport +#endif + +#ifdef _PreComp_ + +// standard +#include +#include +#include + +// STL +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Xerces +#include + +#endif //_PreComp_ + +#endif + diff --git a/src/Mod/Web/App/Server.cpp b/src/Mod/Web/App/Server.cpp new file mode 100644 index 000000000..02f8c2698 --- /dev/null +++ b/src/Mod/Web/App/Server.cpp @@ -0,0 +1,118 @@ +/*************************************************************************** + * Copyright (c) 2014 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#include +#include +# include + +#include "Server.h" +#include +#include + +using namespace Web; + + +ServerEvent::ServerEvent(QTcpSocket* sock, const QByteArray& msg) + : QEvent(QEvent::User), sock(sock), text(msg) +{ +} + +ServerEvent::~ServerEvent() +{ +} + +QTcpSocket* ServerEvent::socket() const +{ + return sock; +} + +const QByteArray& ServerEvent::request() const +{ + return text; +} + +AppServer::AppServer(QObject* parent) + : QTcpServer(parent) +{ +} + +void AppServer::incomingConnection(int socket) +{ + QTcpSocket* s = new QTcpSocket(this); + connect(s, SIGNAL(readyRead()), this, SLOT(readClient())); + connect(s, SIGNAL(disconnected()), this, SLOT(discardClient())); + s->setSocketDescriptor(socket); +} + +void AppServer::readClient() +{ + QTcpSocket* socket = (QTcpSocket*)sender(); + if (socket->bytesAvailable() > 0) { + QByteArray request = socket->readAll(); + QCoreApplication::postEvent(this, new ServerEvent(socket, request)); + } +// if (socket->state() == QTcpSocket::UnconnectedState) { +// //mark the socket for deletion but do not destroy immediately +// socket->deleteLater(); +// } +} + +void AppServer::discardClient() +{ + QTcpSocket* socket = (QTcpSocket*)sender(); + socket->deleteLater(); +} + +void AppServer::customEvent(QEvent* e) +{ + ServerEvent* ev = static_cast(e); + QByteArray msg = ev->request(); + QTcpSocket* socket = ev->socket(); + + std::string str; + + try { + Base::Interpreter().runString(msg); + } + catch (Base::PyException &e) { + str = e.what(); + str += "\n\n"; + str += e.getStackTrace(); + } + catch (Base::Exception &e) { + str = e.what(); + } + catch (std::exception &e) { + str = e.what(); + } + catch (...) { + str = "Unknown exception thrown"; + } + + socket->write(str.c_str()); + socket->close(); +} + +#include "moc_Server.cpp" diff --git a/src/Mod/Web/App/Server.h b/src/Mod/Web/App/Server.h new file mode 100644 index 000000000..80785d715 --- /dev/null +++ b/src/Mod/Web/App/Server.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (c) 2014 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef WEB_SERVER_H +#define WEB_SERVER_H + +#include +#include +#include +#include +#include + + +namespace Web { + +class ServerEvent : public QEvent +{ +public: + ServerEvent(QTcpSocket* socket, const QByteArray&); + ~ServerEvent(); + + QTcpSocket* socket() const; + const QByteArray& request() const; + +private: + QTcpSocket* sock; + QByteArray text; +}; + +/** + * The Server class implements a simple TCP server. + */ +class AppServer : public QTcpServer +{ + Q_OBJECT + +public: + AppServer(QObject* parent = 0); + + void incomingConnection(int socket); + +protected: + void customEvent(QEvent* e); + +private Q_SLOTS: + void readClient(); + void discardClient(); + +private: +}; + +} + +#endif //Web_SERVER_H diff --git a/src/Mod/Web/CMakeLists.txt b/src/Mod/Web/CMakeLists.txt index 228094410..f9122617f 100644 --- a/src/Mod/Web/CMakeLists.txt +++ b/src/Mod/Web/CMakeLists.txt @@ -1,4 +1,5 @@ +add_subdirectory(App) if(FREECAD_BUILD_GUI) add_subdirectory(Gui) endif(FREECAD_BUILD_GUI)