diff options
Diffstat (limited to 'server/src')
| -rw-r--r-- | server/src/Makefile.am | 2 | ||||
| -rw-r--r-- | server/src/connection.cc | 129 | ||||
| -rw-r--r-- | server/src/connection.h | 57 | ||||
| -rw-r--r-- | server/src/resumeparser.cc | 3 | ||||
| -rw-r--r-- | server/src/server.cc | 169 | ||||
| -rw-r--r-- | server/src/transactionhandler.cc | 5 | ||||
| -rw-r--r-- | server/src/transactionparser.cc | 8 | ||||
| -rw-r--r-- | server/src/widgetgenerator.cc | 8 | 
8 files changed, 228 insertions, 153 deletions
| diff --git a/server/src/Makefile.am b/server/src/Makefile.am index afc72f9..0a3569f 100644 --- a/server/src/Makefile.am +++ b/server/src/Makefile.am @@ -16,6 +16,7 @@ pracrod_SOURCES = \  	database.cc \  	configuration.cc \  	configurationparser.cc \ +	connection.cc \  	connectionpool.cc \  	debug.cc \  	entitylist.cc \ @@ -89,6 +90,7 @@ EXTRA_DIST = \  	artefact.h \  	configuration.h \  	configurationparser.h \ +	connection.h \  	connectionpool.h \  	daemon.h \  	database.h \ diff --git a/server/src/connection.cc b/server/src/connection.cc new file mode 100644 index 0000000..36c030e --- /dev/null +++ b/server/src/connection.cc @@ -0,0 +1,129 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + *            connection.cc + * + *  Fri May  7 11:35:44 CEST 2010 + *  Copyright 2010 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of Pracro. + * + *  Pracro is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  Pracro 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 General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Pracro; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "connection.h" + +#include "transactionhandler.h" +#include "xml_encode_decode.h" + +static std::string error_box(std::string message) +{ +  std::string errorbox = +    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +    "<pracro version=\"1.0\">\n" +    "  <error>" + message + "</error>\n" +    "</pracro>\n"; +  return errorbox; +} + +Connection::Connection(Environment &e, std::string sid, bool c) +  : env(e), parser(&transaction) +{ +  PRACRO_DEBUG(connection, "[%p] CREATE\n", this); + +  sessionid = sid; +  commit = c; +} + +Connection::~Connection() +{ +  PRACRO_DEBUG(connection, "[%p] DESTROY\n", this); +} + +bool Connection::handle(const char *data, size_t size) +{ +  Session *session = NULL; +  if(sessionid == "") { +    // Create new session +    session = env.sessions.newSession(); +  } else { +    // Attach to old session +    session = env.sessions.session(sessionid); + +    // Session didn't exist - create a new one anyway. +    if(session == NULL) session = env.sessions.newSession(); +  } +   +  if(session == NULL) { +    PRACRO_ERR(connection, "New session could not be created."); +    response = error_box(xml_encode("New session could not be created.")); +    return true; +  } +   +  sessionid = session->id(); + +  if(!data || !size) return true; + +  try { +    if(parser.parse(data, size)) { +      { +        SessionAutolock lock(*session); +        response = handleTransaction(transaction, env, *session); +      } + +      if(commit) { +        session->commit(); +        env.sessions.deleteSession(session->id()); +      } + +      return true; +    } +  } catch(...) { +    PRACRO_ERR(server, "Failed to parse data!\n"); +    response = error_box(xml_encode("XML Parse error.")); +    return true; +  } + +  return false; +} + +std::string Connection::getResponse() +{ +  return response; +} + +std::string Connection::getSessionID() +{ +  return sessionid; +} + +#ifdef TEST_CONNECTION +//Additional dependency files +//deps: +//Required cflags (autoconf vars may be used) +//cflags: +//Required link options (autoconf vars may be used) +//libs: +#include "test.h" + +TEST_BEGIN; + +// TODO: Put some testcode here (see test.h for usable macros). + +TEST_END; + +#endif/*TEST_CONNECTION*/ diff --git a/server/src/connection.h b/server/src/connection.h new file mode 100644 index 0000000..f91ddc1 --- /dev/null +++ b/server/src/connection.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + *            connection.h + * + *  Fri May  7 11:35:43 CEST 2010 + *  Copyright 2010 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of Pracro. + * + *  Pracro is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  Pracro 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 General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Pracro; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#ifndef __PRACRO_CONNECTION_H__ +#define __PRACRO_CONNECTION_H__ + +#include <string> +#include "environment.h" +#include "transaction.h" +#include "transactionparser.h" + +class Connection { +public: +  Connection(Environment &e, std::string sessionid, bool commit); +  ~Connection(); + +  bool handle(const char *data, size_t size); + +  std::string getResponse(); +  std::string getSessionID(); + +private: +  std::string sessionid; +  bool commit; +  Environment &env; + +  Transaction transaction; +  TransactionParser parser; + +  std::string response; +}; + +#endif/*__PRACRO_CONNECTION_H__*/ diff --git a/server/src/resumeparser.cc b/server/src/resumeparser.cc index bf3483e..4d514ac 100644 --- a/server/src/resumeparser.cc +++ b/server/src/resumeparser.cc @@ -26,9 +26,10 @@   */  #include "resumeparser.h" -#include "luaresume.h"  #include <string.h> +#include "luaresume.h" +  static std::string resume_parser_format(Resume &r, Commit &commit)  {    const char* format = r.attributes["format"].c_str(); diff --git a/server/src/server.cc b/server/src/server.cc index 4283a11..118db85 100644 --- a/server/src/server.cc +++ b/server/src/server.cc @@ -41,84 +41,8 @@  #include <microhttpd.h>  #include "configuration.h" -#include "transaction.h" -#include "transactionparser.h" -#include "database.h" +#include "connection.h"  #include "log.h" -#include "environment.h" -#include "transactionhandler.h" -#include "connectionpool.h" -#include "session.h" -#include "xml_encode_decode.h" - -static std::string error_box(std::string message) -{ -  std::string errorbox = -    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" -    "<pracro version=\"1.0\">\n" -    "  <error>" + message + "</error>\n" -    "</pracro>\n"; -  return errorbox; -} - -static std::string handleConnection(const std::string &data, -                                    Environment &env, -                                    std::string &sessionid, -                                    bool sessioncommit) -{ -  std::string res; - -  Session *session = NULL; -  if(sessionid == "") { -    session = env.sessions.newSession(); -  } else { -    session = env.sessions.session(sessionid); -    if(session == NULL) session = env.sessions.newSession(); -  } - -  if(session == NULL) { -    PRACRO_ERR(server, "New session could not be created."); -    return error_box(xml_encode("New session could not be created.")); -  } - -  sessionid = session->id(); - -  { -    SessionAutolock lock(*session); - -    if(data.length()) { -      Transaction transaction; -      TransactionParser parser(&transaction); -       -      if(!parser.parse(data.c_str(), data.length())) { -        PRACRO_ERR(server, "Failed to parse data!\n"); -        PRACRO_ERR(server, "DATA:[[%s]]\n", data.c_str()); -        res = error_box(xml_encode("XML Parse error.")); -      } else { -        res = handleTransaction(transaction, env, *session); -      } -    } - -  } - -  if(sessioncommit) { -    session->commit(); -    env.sessions.deleteSession(session->id()); -  } - -  return res; -} - -struct condata { -  std::map<std::string, std::string> headers; -  std::string data; -  size_t data_size; -  std::string url; -  std::string method; -  std::string version; -}; - -//static std::map<struct MHD_Connection *, struct condata> condata;  static int handle_request_callback(void *cls,                                     struct MHD_Connection *con, @@ -129,92 +53,51 @@ static int handle_request_callback(void *cls,                                     unsigned int *data_size,                                     void **con_cls)  { +  int ret = MHD_YES; + +  Connection *connection = (Connection*)*con_cls; +    PRACRO_DEBUG(httpd, "handle_request_callback con:%p condata:%p\n",                 con, *con_cls);    // Test for new connection -  if(*con_cls == NULL) { -    PRACRO_DEBUG(httpd, -                 "handle_request(url=\"%s\", method=\"%s\"," -                 " version=\"%s\", data_size=\"%d\")\n", -                 url, method, version, *data_size); - -    struct condata *cd = new struct condata; -    cd->url = url; -    cd->method = method; -    cd->version = version; -    cd->data_size = 0; -    cd->data = ""; - +  if(connection == NULL) { +    std::string sessionid;      const char *sid = MHD_lookup_connection_value(con, MHD_HEADER_KIND,                                                    "SessionID"); -    if(sid) cd->headers["SessionID"] = sid; +    if(sid) sessionid = sid;      const char *scm = MHD_lookup_connection_value(con, MHD_HEADER_KIND,                                                    "SessionCommit"); -    if(scm) cd->headers["SessionCommit"] = scm; - -    const char *csz = MHD_lookup_connection_value(con, MHD_HEADER_KIND, -                                                  "Content-Length"); -    if(csz) { -      cd->headers["Content-Length"] = csz; -      cd->data_size = atol(csz); -      PRACRO_DEBUG(httpd, "Content-Length: %s (%d)\n", csz, cd->data_size); -    } - -    *con_cls = cd; +    Environment *env = (Environment *)cls; +    connection = new Connection(*env, sessionid, scm != NULL); +    *con_cls = connection;    } -  struct condata *cd = (struct condata*)*con_cls; -  cd->data.append(data, *data_size); - -  int ret = MHD_YES; +  if(!connection) return MHD_NO; -  PRACRO_DEBUG(httpd, "Waiting for %d bytes of data. Got %d (total %d)\n", -               cd->data_size, *data_size, cd->data.length()); - -  if(cd->data.length() >= cd->data_size) { - -    Environment *env = (Environment *)cls; - -    const char *sid = MHD_lookup_connection_value(con, MHD_HEADER_KIND, -                                                  "SessionID"); -    std::string sessionid; -    if(sid) sessionid = sid; -     -    const char *sessioncommit = -      MHD_lookup_connection_value(con, MHD_HEADER_KIND, "SessionCommit"); -     -    PRACRO_DEBUG(httpd, "Starting to handle SessionID: %s%s\n", -                 sessionid.c_str(), -                 sessioncommit != NULL?" COMMIT":""); -     -    PRACRO_DEBUG(httpd, "Data: [%s]\n", cd->data.c_str()); -     -    std::string reply = -      handleConnection(cd->data, *env, sessionid, sessioncommit != NULL); +  if(connection->handle(data, *data_size)) { +    std::string response = connection->getResponse(); +    PRACRO_DEBUG(httpd, "Sending response: [[%s]]\n", response.c_str()); +      struct MHD_Response *rsp = -      MHD_create_response_from_data(reply.length(), (char*)reply.c_str(), -                                    MHD_NO, MHD_YES); +      MHD_create_response_from_data(response.size(), +                                    (void*)response.data(), +                                    MHD_NO,   // must free +                                    MHD_YES); // must copy +          MHD_add_response_header(rsp, MHD_HTTP_HEADER_CONTENT_TYPE,                              "text/plain; charset=UTF-8"); -    if(sessionid != "") { -      MHD_add_response_header(rsp, "SessionID", sessionid.c_str()); -    } +    MHD_add_response_header(rsp, "SessionID", +                            connection->getSessionID().c_str());      ret = MHD_queue_response(con, MHD_HTTP_OK, rsp);      MHD_destroy_response(rsp); -    PRACRO_DEBUG(httpd, "Finished handling SessionID: %s%s\n", -                 sessionid.c_str(), -                 sessioncommit != NULL?" COMMIT":""); - - -    delete cd; +    delete connection;      *con_cls = NULL; -    }    *data_size = 0; @@ -231,8 +114,8 @@ void requestCompletedCallback(void *cls,    // If connection was interrupted prematurely delete the content data here.    if(*con_cls) { -    struct condata *cd = (struct condata*)*con_cls; -    delete cd; +    Connection *connection = (Connection*)*con_cls; +    delete connection;      *con_cls = NULL;    }  } diff --git a/server/src/transactionhandler.cc b/server/src/transactionhandler.cc index 7a45800..662896b 100644 --- a/server/src/transactionhandler.cc +++ b/server/src/transactionhandler.cc @@ -219,8 +219,9 @@ static std::string handleRequest(Transaction &transaction, Environment &env,          if(completed) {            answer += "      <resume>"; -          answer += db->getResume(transaction.cpr, macro, time(NULL) - -                                  Conf::db_max_ttl); +          answer += xml_encode(db->getResume(transaction.cpr, +                                             macro, +                                             time(NULL) - Conf::db_max_ttl));            answer += "</resume>\n";          } diff --git a/server/src/transactionparser.cc b/server/src/transactionparser.cc index 7422a13..7595bb2 100644 --- a/server/src/transactionparser.cc +++ b/server/src/transactionparser.cc @@ -72,17 +72,17 @@ void TransactionParser::startTag(std::string name,    if(name == "field") {      if(!transaction->commits.size()) {        PRACRO_ERR(transactionparser, "Field without a commit tag!"); -      return; +      throw std::exception();      }      if(attributes.find("name") == attributes.end()) {        PRACRO_ERR(transactionparser, "Field is missing 'name' attribute"); -      return; +      throw std::exception();      }      if(attributes.find("value") == attributes.end()) {        PRACRO_ERR(transactionparser, "Field is missing 'value' attribute"); -      return; +      throw std::exception();      }      transaction->commits.back().fields[attributes["name"]] = @@ -101,6 +101,8 @@ void TransactionParser::parseError(const char *buf, size_t len,    PRACRO_ERR(transactionparser, "\tBuffer %u bytes: [%s]\n",               len, xml.c_str()); + +  throw std::exception();  }  #ifdef TEST_TRANSACTIONPARSER diff --git a/server/src/widgetgenerator.cc b/server/src/widgetgenerator.cc index 1e60479..425c71e 100644 --- a/server/src/widgetgenerator.cc +++ b/server/src/widgetgenerator.cc @@ -109,9 +109,9 @@ static std::string send_macro_widget(Macro ¯o,      if(luamap != "") {        Value value = mapper.map(luamap);        if(value.timestamp > now - Conf::pentominos_max_ttl) { -        widget.attributes["value"] = xml_encode(value.value); +        widget.attributes["value"] = value.value;          timestamp = value.timestamp; -        prefilled = xml_encode(value.source); +        prefilled = value.source;        }        PRACRO_DEBUG(prefill, "map: (%s, %d)\n", @@ -137,7 +137,7 @@ static std::string send_macro_widget(Macro ¯o,      if(values[widget.attributes["name"]].timestamp > timestamp) {        if(values[widget.attributes["name"]].timestamp > now - Conf::db_max_ttl) { -        widget.attributes["value"] = xml_encode(values[widget.attributes["name"]].value); +        widget.attributes["value"] = values[widget.attributes["name"]].value;          timestamp = values[widget.attributes["name"]].timestamp;          prefilled = "pracro";        } @@ -152,7 +152,7 @@ static std::string send_macro_widget(Macro ¯o,    while(p != widget.attributes.end()) {      if(p->first != "tagname" && p->first != "map") {        if( ! (p->first == "name" && p->second == "") ) -        result += " " + p->first + "=\"" + p->second + "\""; +        result += " " + p->first + "=\"" + xml_encode(p->second) + "\"";      }      p++;    } | 
