diff options
Diffstat (limited to 'server/src/server.cc')
| -rw-r--r-- | server/src/server.cc | 188 | 
1 files changed, 57 insertions, 131 deletions
| diff --git a/server/src/server.cc b/server/src/server.cc index 1f85479..f8f2d83 100644 --- a/server/src/server.cc +++ b/server/src/server.cc @@ -28,168 +28,94 @@  #include <config.h> -#include "tcpsocket.h" -#include <errno.h> - -#include <stdlib.h> - -// For fork -#include <sys/types.h> -#include <unistd.h> -#include <string.h> - -#include <microhttpd.h> - +#include "httpd.h"  #include "configuration.h" +#include "environment.h"  #include "connection.h" -#include "log.h" -static int handle_request_callback(void *cls, -                                   struct MHD_Connection *con, -                                   const char *url, -                                   const char *method, -                                   const char *version, -                                   const char *data, -                                   unsigned int *data_size, -                                   void **con_cls) -{ -  int ret = MHD_YES; - -  Connection *connection = (Connection*)*con_cls; +class PracroHttpd : public Httpd { +public: +  PracroHttpd() {} +  ~PracroHttpd() +  { +    env.sessions.store(); +  } -  PRACRO_DEBUG(httpd, "handle_request_callback con:%p condata:%p\n", -               con, *con_cls); +  void error(const std::string &err) +  { +    fprintf(stderr, "ERROR: %s\n", err.c_str()); +    fflush(stderr); +  } -  // Test for new connection -  if(connection == NULL) { +  void *begin(const std::string &url, +              const std::string &method, +              const std::string &version, +              headers_t &headers) +  {      std::string sessionid; -    const char *sid = MHD_lookup_connection_value(con, MHD_HEADER_KIND, -                                                  "SessionID"); -    if(sid) sessionid = sid; - -    const char *scm = MHD_lookup_connection_value(con, MHD_HEADER_KIND, -                                                  "SessionCommit"); +    if(headers.contains("SessionID")) sessionid = headers["SessionID"]; +     +    bool commit = headers.contains("SessionCommit"); +    bool discard = headers.contains("Sessiondiscard"); -    const char *sdc = MHD_lookup_connection_value(con, MHD_HEADER_KIND, -                                                  "SessionDiscard"); +    Connection *connection = new Connection(env, sessionid, commit, discard); -    Environment *env = (Environment *)cls; -    connection = new Connection(*env, sessionid, scm != NULL, sdc != NULL); -    *con_cls = connection; +    return connection;    } -  if(!connection) return MHD_NO; - -  if(connection->handle(data, *data_size)) { -    std::string response = connection->getResponse(); -     -    PRACRO_DEBUG(httpd, "Sending response: [[%s]]\n", response.c_str()); +  bool data(void *ptr, const char *data, unsigned int data_size) +  { +    Connection *connection = (Connection *)ptr; +    connection->handle(data, data_size); +    return true; +  } -    struct MHD_Response *rsp = -      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"); +  bool complete(void *ptr, Httpd::Reply &reply) +  { +    Connection *connection = (Connection *)ptr; -    MHD_add_response_header(rsp, "SessionID", -                            connection->getSessionID().c_str()); +    reply.data = connection->getResponse(); +    reply.headers["Content-Type"] = "text/plain; charset=UTF-8"; +    reply.headers["SessionID"] = connection->getSessionID(); +    reply.status = 200; // http 'OK' -    ret = MHD_queue_response(con, MHD_HTTP_OK, rsp); -    MHD_destroy_response(rsp); -     -    delete connection; -    *con_cls = NULL; +    return true;    } -  *data_size = 0; - -  return ret; -} - -void requestCompletedCallback(void *cls, -                              struct MHD_Connection *con, -                              void **con_cls, -                              enum MHD_RequestTerminationCode toe) -{ -  PRACRO_DEBUG(httpd, "requestCompletedCallback %p\n", con); - -  // If connection was interrupted prematurely delete the content data here. -  if(*con_cls) { -    Connection *connection = (Connection*)*con_cls; +  void cleanup(void *ptr) +  { +    Connection *connection = (Connection *)ptr;      delete connection; -    *con_cls = NULL;    } -} -static void httpderr(void *arg, const char *fmt, va_list ap) -{ -  PRACRO_ERR_VA(server, fmt, ap); -} +private: +  Environment env; +}; + +  extern bool pracro_is_running;  void server()  { -  srand(time(NULL)); - -  //  bool forceshutdown = false; -  port_t port = Conf::server_port; - -  int flags = MHD_USE_DEBUG | MHD_USE_SELECT_INTERNALLY; -  // | MHD_USE_PEDANTIC_CHECKS -#ifndef WITHOUT_SSL -  if(Conf::use_ssl) flags |= MHD_USE_SSL; -#endif - -  PRACRO_DEBUG(server, "Server running on port %d.\n", port); - -  Environment env; +  PracroHttpd httpd; -  struct MHD_Daemon *d; -  d = MHD_start_daemon(flags, port, NULL, NULL, -                       handle_request_callback, &env, -                       MHD_OPTION_NOTIFY_COMPLETED, -                          requestCompletedCallback, NULL, -                       MHD_OPTION_CONNECTION_LIMIT, Conf::connection_limit,  #ifndef WITHOUT_SSL -                       MHD_OPTION_HTTPS_MEM_KEY, Conf::ssl_key.c_str(), -                       MHD_OPTION_HTTPS_MEM_CERT, Conf::ssl_cert.c_str(), +  if(Conf::use_ssl) httpd.listen_ssl(Conf::server_port, +                                     Conf::ssl_key, +                                     Conf::ssl_cert, +                                     Conf::connection_limit, +                                     Conf::connection_timeout); +  else  #endif -                       MHD_OPTION_CONNECTION_TIMEOUT, Conf::connection_timeout, -                       MHD_OPTION_EXTERNAL_LOGGER, httpderr, NULL, -                       MHD_OPTION_END); +    httpd.listen(Conf::server_port, +                 Conf::connection_limit, +                 Conf::connection_timeout); -  if(!d) { -    PRACRO_ERR(server, "Failed to initialise MHD_start_daemon!\n"); -    return; -  } -  // again:    while(pracro_is_running) sleep(1); -  /* -  if(!forceshutdown && env.sessions.size() != 0) { -    char *errbuf; -    if(asprintf(&errbuf, "There are %d live sessions." -                " Kill again to force shutdown.\n", -                env.sessions.size()) != -1) { -      PRACRO_ERR_LOG(server, "%s", errbuf); -      log(errbuf); -      free(errbuf); -    } -    pracro_is_running = true; -    forceshutdown = true; -    goto again; -  } -  */ -  env.sessions.store(); - -  MHD_stop_daemon(d);    PRACRO_DEBUG(server, "Server gracefully shut down.\n");  } -  #ifdef TEST_SERVER  #include <sys/types.h> | 
