/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * server.cc * * Wed Aug 22 12:16:03 CEST 2007 * Copyright 2007 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 "server.h" #include #include #include "httpd.h" #include "configuration.h" #include "environment.h" #include "connection.h" #include "client_connection.h" #include "admin_connection.h" class PracroHttpd : public Httpd { public: PracroHttpd() {} ~PracroHttpd() { env.sessions.store(); } void error(const std::string &err) { fprintf(stderr, "ERROR: %s\n", err.c_str()); fflush(stderr); } void *begin(const std::string &url, const std::string &method, const std::string &version, headers_t &getargs, headers_t &headers) { Connection *connection = NULL; if(headers.find("User-Agent") != headers.end() && headers["User-Agent"].find("Pracro") == std::string::npos) { // Admin connection = new AdminConnection(env, getargs); } else { // Pracro client ClientConnection::Parameters parms; if(headers.contains("SessionID")) parms.sessionid = headers["SessionID"]; if(headers.contains("SessionPatientID")) parms.patientid = headers["SessionPatientID"]; if(headers.contains("SessionTemplate")) parms.templ = headers["SessionTemplate"]; parms.commit = headers.contains("SessionCommit"); parms.nocommit = headers.contains("SessionNoCommit"); parms.discard = headers.contains("SessionDiscard"); connection = new ClientConnection(env, parms); } return connection; } bool data(void *ptr, const char *data, unsigned int data_size) { if(ptr) { Connection *connection = (Connection *)ptr; connection->handle(data, data_size); } return true; } bool complete(void *ptr, Httpd::Reply &reply) { if(ptr) { Connection *connection = (Connection *)ptr; // Flush and do commit/discard connection->handle(NULL, 0); reply.data = connection->getResponse(); reply.headers = connection->getHeaders(); reply.status = 200; // http 'OK' } else { reply.data = "Admin"; reply.status = 200; // http 'OK' } return true; } void cleanup(void *ptr) { if(ptr) { Connection *connection = (Connection *)ptr; delete connection; } } private: Environment env; }; extern bool pracro_is_running; void server() { PracroHttpd httpd; #ifndef WITHOUT_SSL if(Conf::use_ssl) httpd.listen_ssl(Conf::server_port, Conf::ssl_key, Conf::ssl_cert, Conf::connection_limit, Conf::connection_timeout); else #endif httpd.listen(Conf::server_port, Conf::connection_limit, Conf::connection_timeout); while(pracro_is_running) sleep(1); DEBUG(server, "Server gracefully shut down.\n"); } #ifdef TEST_SERVER #include #include bool pracro_is_running = true; char request[] = "\n" "\n" " \n" "\n"; int main() { Conf::xml_basedir = "../xml/"; // Make sure wo don't interrupt an already running server. Conf::server_port = 32100; Conf::database_backend = "testdb"; pid_t pid = fork(); switch(pid) { case -1: // error perror("fork() failed!\n"); return 1; case 0: // child try { server(); } catch(Exception &e) { printf(e.what()); return 1; } return 0; default: // parent try { // sleep(1); // Make sure the server is started. TCPSocket socket; socket.connect("localhost", Conf::server_port); socket.write(request); // sleep(1); // Make sure the server has handled the request. char buf[32]; memset(buf, 0, sizeof(buf)); // while(socket.read(buf, 31, 1000)) { while(socket.read(buf, 31, 1000000)) { printf(buf); fflush(stdout); memset(buf, 0, sizeof(buf)); } } catch(Exception &e) { printf(e.what()); kill(pid, SIGKILL); // Kill the server again. return 1; } kill(pid, SIGKILL); // Kill the server again. return 0; } return 1; } #endif/*TEST_SERVER*/