From 1782d12938ba89b67a52677d162d4c865f00cbe0 Mon Sep 17 00:00:00 2001 From: deva Date: Tue, 3 Nov 2009 13:49:15 +0000 Subject: First working, but not in any way optimal implementation of a http transport layer. --- client/netcom.cc | 58 +++++++++++---------------- client/netcom.h | 13 +++--- server/src/server.cc | 109 +++++++++++++++++++++++++++++---------------------- 3 files changed, 93 insertions(+), 87 deletions(-) diff --git a/client/netcom.cc b/client/netcom.cc index 3b3abb7..6150227 100644 --- a/client/netcom.cc +++ b/client/netcom.cc @@ -29,28 +29,27 @@ #include #include +#include + #include "widgets/widget.h" NetCom::NetCom(QString host, quint16 port, QString user, QString cpr) { this->user = user; this->cpr = cpr; - socket.connectToHost(host, port); - connect(&socket, SIGNAL(readyRead()), this, SLOT(readyRead())); - socket.waitForConnected(); - transmitting = false; + + connect(&http, SIGNAL(done(bool)), this, SLOT(done(bool))); + http.setHost(host, port); + + transfering = false; } NetCom::~NetCom() { - socket.disconnectFromHost(); } QDomDocument NetCom::send(QString templ, QString macro, bool lockgui) { - printf("Socket state: %d\n", socket.state()); - if(socket.state() != 3) printf("Socket state not connected: %s\n", socket.errorString().toStdString().c_str()); - if(lockgui && qApp->activeWindow()) qApp->activeWindow()->setEnabled(false); if(lockgui) QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); @@ -72,14 +71,15 @@ QDomDocument NetCom::send(QString templ, QString macro, bool lockgui) printf("\nSending request:\n%s", doc.toString().toStdString().c_str()); - socket.write(doc.toByteArray()); - // socket.waitForReadyRead(); + http.post("/", doc.toByteArray()); + QDomDocument res_doc; + transfering = true; + buffer = ""; do { qApp->processEvents(QEventLoop::WaitForMoreEvents); - } while(!res_doc.setContent(buffer)); - - buffer = ""; + } while(transfering); + res_doc.setContent(buffer); QDomElement elem = res_doc.documentElement(); @@ -91,18 +91,8 @@ QDomDocument NetCom::send(QString templ, QString macro, bool lockgui) return res_doc; } -void NetCom::readyRead() -{ - buffer.append(socket.readAll()); -} - void NetCom::send(QVector< Widget* > widgets, QString templ, QString macro, QString version) { - printf("Socket state: %d\n", socket.state()); - if(socket.state() != 3) printf("Socket state not connected: %s\n", socket.errorString().toStdString().c_str()); - - // if(qApp->activeWindow()) qApp->activeWindow()->setEnabled(false); // Moved down! - QDomDocument doc; QDomProcessingInstruction header = doc.createProcessingInstruction("xml", "version='1.0' encoding='UTF-8'"); @@ -139,22 +129,20 @@ void NetCom::send(QVector< Widget* > widgets, QString templ, QString macro, QStr printf("\nSending commit:\n%s", doc.toString().toStdString().c_str()); - socket.write(doc.toByteArray()); - // socket.waitForReadyRead(); + http.post("/", doc.toByteArray()); - // - // Wait for the (hopefully) empty answer. - // + transfering = true; + buffer = ""; do { qApp->processEvents(QEventLoop::WaitForMoreEvents); - } while(!res_doc.setContent(buffer)); - - buffer = ""; - - //QDomElement elem = res_doc.documentElement(); - - printf("\nRecieved commit:\n%s", res_doc.toString().toStdString().c_str()); + } while(transfering); QApplication::restoreOverrideCursor(); if(qApp->activeWindow()) qApp->activeWindow()->setEnabled(true); } + +void NetCom::done(bool) +{ + buffer = http.readAll(); + transfering = false; +} diff --git a/client/netcom.h b/client/netcom.h index 35db221..e11509b 100644 --- a/client/netcom.h +++ b/client/netcom.h @@ -31,6 +31,7 @@ #include #include #include +#include //#include "widgets/widget.h" class Widget; @@ -45,17 +46,17 @@ public: void send(QVector< Widget* > widgets, QString templ, QString macro, QString version); public slots: - void readyRead(); + void done(bool); private: - volatile bool transmitting; - QTcpSocket socket; - - QByteArray buffer; - QDomDocument res_doc; + volatile bool transfering; QString user; QString cpr; + + QHttp http; + + QByteArray buffer; }; #endif/*__PRACRO_NETCOM_H__*/ diff --git a/server/src/server.cc b/server/src/server.cc index f2be8a4..9d3caba 100644 --- a/server/src/server.cc +++ b/server/src/server.cc @@ -36,6 +36,8 @@ #include #include +#include + #include "configuration.h" #include "transaction.h" #include "transactionparser.h" @@ -294,8 +296,11 @@ static std::string handleTransaction(Transaction *transaction, } -static void handleConnection(TCPSocket *socket) +static std::string handleConnection(char *buf, size_t size) { + if(size == 0) + return error_box(xml_encode("Empty document received.")); + TCPSocket pentominos_socket; #ifndef WITHOUT_PENTOMINOS pentominos_socket.connect(Conf::pentominos_addr, Conf::pentominos_port); @@ -308,63 +313,75 @@ static void handleConnection(TCPSocket *socket) MacroList macrolist(Conf::xml_basedir + "/macros"); TemplateList templatelist(Conf::xml_basedir + "/templates"); - ssize_t size; - char buf[4096]; + Transaction transaction; + TransactionParser parser(&transaction); - Transaction *transaction = NULL; - TransactionParser *parser = NULL; - - // while( (size = socket->read(buf, sizeof(buf))) != -1) { - while( (size = socket->read(buf, sizeof(buf))) > 0) { + PRACRO_DEBUG(server, "Read %d bytes from network\n", size); - PRACRO_DEBUG(server, "Read %d bytes from network\n", size); - - while(size) { + if(parser.parse(buf, size)) { + PRACRO_DEBUG(server, "Got complete XML document, %d bytes in current buffer.\n", size); - if(transaction == NULL) { - transaction = new Transaction(); - } + std::string res = handleTransaction(&transaction, pentominos_socket, + db, journalwriter, macrolist, templatelist); + journalwriter.commit(); - if(parser == NULL) { - parser = new TransactionParser(transaction); - } + return res; + } + + PRACRO_ERR(server, "Failed to parse data!\n"); + return error_box(xml_encode("XML Parse error.")); +} - PRACRO_DEBUG(server, "Got %d bytes in read loop\n", size); - if(parser->parse(buf, size)) { - PRACRO_DEBUG(server, "Got complete XML document %d bytes used, %d bytes in current buffer.\n", parser->usedBytes(), size); +static int handle_request(void *cls, + struct MHD_Connection *con, + const char *url, + const char *method, + const char *version, + const char *data, + unsigned int *data_size, + void **ptr) +{ + PRACRO_DEBUG(httpd, "handle_request(url=\"%s\", method=\"%s\", version=\"%s\", data_size=\"%d\")\n", + url, method, version, *data_size); - socket->write(handleTransaction(transaction, pentominos_socket, - db, journalwriter, macrolist, templatelist)); - size = size - parser->usedBytes(); - if(size) { - strcpy(buf, buf + parser->usedBytes()); - PRACRO_DEBUG(server, "Replaying %d bytes.\n", size); - } + std::string reply = handleConnection((char*)data, *data_size); + + struct MHD_Response *rsp; + rsp = MHD_create_response_from_data(reply.length(), (char*)reply.c_str(), MHD_NO, MHD_YES); + MHD_add_response_header(rsp, MHD_HTTP_HEADER_CONTENT_TYPE, "text/plain; charset=UTF-8"); + int ret = MHD_queue_response(con, MHD_HTTP_OK, rsp); + MHD_destroy_response(rsp); - delete transaction; transaction = NULL; - delete parser; parser = NULL; - } else { - size = 0; - memset(buf, 0, sizeof(buf)); - } - } - } + return ret; +} - if(transaction) { - delete transaction; - transaction = NULL; - } +extern bool pracro_is_running; +void server() +{ + port_t port = Conf::server_port; - if(parser) { - delete parser; - parser = NULL; - } + PRACRO_DEBUG(server, "Server running on port %d.\n", port); + + struct MHD_Daemon *d; + d = MHD_start_daemon(MHD_USE_DEBUG | MHD_USE_SELECT_INTERNALLY, + port, + NULL, NULL, + handle_request, NULL, + MHD_OPTION_NOTIFY_COMPLETED, NULL, NULL, + // MHD_OPTION_CONNECTION_LIMIT, 42, + MHD_OPTION_CONNECTION_TIMEOUT, 0, + MHD_OPTION_EXTERNAL_LOGGER, NULL, NULL, + MHD_OPTION_END); + + while(pracro_is_running) sleep(1); - journalwriter.commit(); + MHD_stop_daemon(d); - PRACRO_DEBUG(server, "Out of read loop!\n"); + PRACRO_DEBUG(server, "Server gracefully shut down.\n"); } + +#if 0 //#define NON_FORKING #include extern bool pracro_is_running; @@ -428,7 +445,7 @@ void server() PRACRO_DEBUG(server, "Server gracefully shut down.\n"); } - +#endif//0 #ifdef TEST_SERVER -- cgit v1.2.3