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> |