X-Git-Url: https://git.llucax.com/z.facultad/75.42/plaqui.git/blobdiff_plain/a9d033a0a6748c192d30c9c65ebcc8b1a96cd43b..1767eccd7e3ea6de4101d6d29c1d29ac0fba2a51:/Server/src/server.cpp?ds=sidebyside diff --git a/Server/src/server.cpp b/Server/src/server.cpp index bb66fe5..32b23e5 100644 --- a/Server/src/server.cpp +++ b/Server/src/server.cpp @@ -29,8 +29,9 @@ #include "plaqui/server/connection.h" #include "plaqui/server/controlserver.h" #include -// FIXME - sacar sstream (a menos que se necesite) +#include #include +#include #ifdef DEBUG # include "plaqui/server/string.h" # include @@ -44,55 +45,59 @@ namespace Server { Server::~Server(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG - // Termino plantas. - Glib::Mutex::Lock lock(plants_mutex); - for (PlantList::iterator i = plants.end(); i != plants.end(); i++) { - i->second->finish(true); + // Mando a terminar todas las plantas. + plants_mutex.lock(); + for (PlantList::iterator i = plants.begin(); i != plants.end(); i++) { + i->second->finish(); + } + PlantList::size_type count = plants.size(); + plants_mutex.unlock(); + // Espero que terminen realmente. + while (count) { + Glib::usleep(10000); // 10 milisegundos + plants_mutex.lock(); + count = plants.size(); + plants_mutex.unlock(); } } -Server::Server(const string& plant_filename, const Connection::Port& port): - TCPServer(port) { +Server::Server(const string& plant_filename, const Connection::Port& port) + throw(sockerr): TCPServer(port) { #ifdef DEBUG - cerr << __FILE__ << ": port = " << port << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": port = " << port << endl; #endif // DEBUG - // FIXME + // FIXME - hacer que se puedan cargar mas plantas bien. Glib::Mutex::Lock lock(plants_mutex); plants["default"] = new Plant(plant_filename); - plants["default"]->signal_finished().connect( - SigC::bind( - SigC::slot_class(*this, &Server::on_plant_finished), - "default")); + plants["default"]->signal_finished().connect(SigC::bind( + SigC::slot_class(*this, &Server::on_plant_finished), + "default")); plants["default"]->run(); } -Connection* Server::new_connection( - const sockbuf::sockdesc& sd) { +Connection* Server::new_connection(const sockbuf::sockdesc& sd) { #ifdef DEBUG - cerr << __FILE__ << ": new_connection(sd = " << sd.sock << ")" + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": new_connection(sd = " << sd.sock << ")" << endl; #endif // DEBUG ControlServer* connection = new ControlServer(sd); // TODO verificar si el new se hace bien? no creo. - connection->signal_command_received().connect( - SigC::bind( - SigC::slot_class(*this, &Server::on_control_command_received), - connection)); + connection->signal_command_received().connect(SigC::bind( + SigC::slot_class(*this, &Server::on_control_command_received), + connection)); // TODO: return connection; } -void Server::on_plant_updated(const Plant* plant) { -#ifdef DEBUG - cerr << __FILE__ << ": on_plant_updated(plant = " << plant << ")." << endl; -#endif // DEBUG -} - void Server::on_plant_finished(const char* plant) { #ifdef DEBUG - cerr << __FILE__ << ": on_plant_finished(plant_name = " << plant << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": on_plant_finished(plant_name = " << plant << endl; #endif // DEBUG Glib::Mutex::Lock lock(plants_mutex); plants.erase(plant); @@ -102,7 +107,8 @@ void Server::on_plant_finished(const char* plant) { void Server::on_control_command_received(const Command& command, ControlServer* controlserver) { #ifdef DEBUG - cerr << __FILE__ << ": on_control_command_received(target = " + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": on_control_command_received(target = " << command.get_target() << ", command = " << command.get_command() << ", args = [" << String::join(command.get_args(), ", ") << "])" << endl; @@ -113,12 +119,18 @@ void Server::on_control_command_received(const Command& command, if (command.get_command() == "status") { response = cmd_server_status(); } else if (command.get_command() == "stop") { - finish(); response = new HTTPResponse(HTTPMessage::OK, - "El server se apagará en instantes..."); + ""); + // XXX - Sin mandar la respuesta enseguida podría ser que el server + // cierre la conexión antes de mandar la respuesta. + //response->headers["Content-Type"] = "text/xml; charset=iso-8859-1"; + //controlserver->send(*response); + //delete response; + finish(); + //return; } else { response = new HTTPResponse(HTTPMessage::NOT_FOUND, - "Invalid command for 'server' taget!"); + ""); } } else if (command.get_target() == "connection") { if (command.get_command() == "list") { @@ -127,7 +139,7 @@ void Server::on_control_command_received(const Command& command, response = cmd_connection_stop(command); } else { response = new HTTPResponse(HTTPMessage::NOT_FOUND, - "Invalid command for 'connection' taget!"); + ""); } } else if (command.get_target() == "transmission") { if (command.get_command() == "list") { @@ -138,24 +150,27 @@ void Server::on_control_command_received(const Command& command, response = cmd_transmission_stop(command); } else { response = new HTTPResponse(HTTPMessage::NOT_FOUND, - "Invalid command for 'transmission' taget!"); + ""); } } else if (command.get_target() == "plant") { if (command.get_command() == "list") { response = cmd_plant_list(); } else if (command.get_command() == "get") { response = cmd_plant_get(command); + } else if (command.get_command() == "set") { + response = cmd_plant_set(command); } else if (command.get_command() == "stop") { response = cmd_plant_stop(command); } else { response = new HTTPResponse(HTTPMessage::NOT_FOUND, - "Invalid command for 'plant' taget!"); + ""); } } else { - response = new HTTPResponse(HTTPMessage::NOT_FOUND, "Invalid taget!"); + response = new HTTPResponse(HTTPMessage::NOT_FOUND, + ""); } // FIXME - response->headers["Content-Type"] = "text/html; charset=iso-8859-1"; + response->headers["Content-Type"] = "text/xml; charset=iso-8859-1"; //response->headers["Connection"] = "close"; controlserver->send(*response); delete response; @@ -168,69 +183,32 @@ void Server::on_control_command_received(const Command& command, HTTPResponse* Server::cmd_server_status(void) const { // FIXME - stringstream response_xml; - response_xml << "" << endl; - response_xml << " " << endl; - response_xml << " PlaQui v0.8" << endl; - response_xml << " " << endl; - response_xml << " " << endl; - response_xml << "

PlaQui

" << endl; - response_xml << "

versión 0.8

" << endl; -/* response_xml << "

Comando

" << endl; - response_xml << "
    " << endl; - response_xml << "
  • Target: " << command.get_target() << endl; - response_xml << "
  • Command: " << command.get_command() << endl; - response_xml << "
  • Argumentos:" << endl; - response_xml << "
      " << endl; - for (Command::Arguments::const_iterator i = command.get_args().begin(); - i != command.get_args().end(); i++) { - response_xml << "
    1. " << *i << "
    2. " << endl; - } - response_xml << "
    " << endl; - response_xml << "
" << endl;*/ - response_xml << "

Desarrollado por

" << endl; - response_xml << "
    " << endl; - response_xml << "
  • Nicolás Dimov.
  • " << endl; - response_xml << "
  • Leandro Lucarella.
  • " << endl; - response_xml << "
  • Ricardo Markiewicz.
  • " << endl; - response_xml << "
" << endl; - response_xml << "
" << endl; - response_xml << " Copyleft 2003 - bajo los " << endl; - response_xml << " términos de la licencia GPL" << endl; - response_xml << "
" << endl; - response_xml << " " << endl; - response_xml << "" << endl; - return new HTTPResponse(HTTPMessage::OK, response_xml.str()); + stringstream xml; + xml << "" << endl; + xml << "\t" VERSION "" << endl; + xml << "\t" << endl; + xml << "\t\tNicolás Dimov" << endl; + xml << "\t\tLeandro Lucarella" << endl; + xml << "\t\tRicardo Markiewicz" << endl; + xml << "\t" << endl; + xml << "" << endl; + return new HTTPResponse(HTTPMessage::OK, xml.str()); } HTTPResponse* Server::cmd_connection_list(void) { // FIXME TCPServer::ConnectionInfoList cil = get_connected(); - stringstream response_xml; - response_xml << "" << endl; - response_xml << " " << endl; - response_xml << " PlaQui v0.8" << endl; - response_xml << " " << endl; - response_xml << " " << endl; - response_xml << "

PlaQui

" << endl; - response_xml << "

versión 0.8

" << endl; - response_xml << "

Lista de conexiones:

" << endl; - response_xml << "
    " << endl; + stringstream xml; + xml << "" << endl; for (TCPServer::ConnectionInfoList::const_iterator i = cil.begin(); i != cil.end(); i++) { - response_xml << "
  • " << i->host - << ":" << i->port << " [host << "/" << i->port << "\">deconectar]
  • " - << endl; + xml << "\t" << endl; + xml << "\t\t" << i->host << "" << endl; + xml << "\t\t" << i->port << "" << endl; + xml << "\t" << endl; } - response_xml << "
" << endl; - response_xml << "
" << endl; - response_xml << " Copyleft 2003 - bajo los " << endl; - response_xml << " términos de la licencia GPL" << endl; - response_xml << "
" << endl; - response_xml << " " << endl; - response_xml << "" << endl; - return new HTTPResponse(HTTPMessage::OK, response_xml.str()); + xml << "" << endl; + return new HTTPResponse(HTTPMessage::OK, xml.str()); } HTTPResponse* Server::cmd_connection_stop(const Command& command) { @@ -238,74 +216,60 @@ HTTPResponse* Server::cmd_connection_stop(const Command& command) { Connection::Port port; if (args.size() < 2) { return new HTTPResponse(HTTPMessage::CONFLICT, - "Faltan argumentos."); - } else if (disconnect(args[0], String(args[1]).to(port))) { + ""); + } else if (disconnect(args[0], to(args[1], port))) { return new HTTPResponse(HTTPMessage::OK, - string("La conexión a ") + args[0] + ":" + args[1] - + " se cerrará en instantes..."); + string(""); } else { return new HTTPResponse(HTTPMessage::NOT_FOUND, - string("No existe una conexión a ") + args[0] - + ":" + args[1]); + string(""); } } HTTPResponse* Server::cmd_transmission_list(void) { // FIXME - stringstream response_xml; - response_xml << "" << endl; - response_xml << " " << endl; - response_xml << " PlaQui v0.8" << endl; - response_xml << " " << endl; - response_xml << " " << endl; - response_xml << "

PlaQui

" << endl; - response_xml << "

versión 0.8

" << endl; - response_xml << "

Lista de transmisiones:

" << endl; - response_xml << "
    " << endl; + stringstream xml; + xml << "" << endl; /*TODO plants_mutex.lock(); for (PlantList::const_iterator i = plants.begin(); i != plants.end(); i++) { trans - response_xml << "
  • " << (*i)->get_host() << ":" + xml << "
  • " << (*i)->get_host() << ":" << (*i)->get_port() << " [get_host() << "/" << (*i)->get_port() << "\">desconectar]
  • " << endl; } transmissions_mutex.unlock();*/ - response_xml << "
" << endl; - response_xml << "
" << endl; - response_xml << " Copyleft 2003 - bajo los " << endl; - response_xml << " términos de la licencia GPL" << endl; - response_xml << "
" << endl; - response_xml << " " << endl; - response_xml << "" << endl; - return new HTTPResponse(HTTPMessage::OK, response_xml.str()); + xml << "" << endl; + return new HTTPResponse(HTTPMessage::OK, xml.str()); } HTTPResponse* Server::cmd_transmission_start(const Command& command) { const Command::Arguments& args = command.get_args(); if (args.size() < 3) { return new HTTPResponse(HTTPMessage::CONFLICT, - "Faltan argumentos."); + ""); } else { string plant = args[0]; string host = args[1]; - Connection::Port port = String(args[2]).to(port); + Connection::Port port = to(args[2], port); Glib::Mutex::Lock lock(plants_mutex); PlantList::iterator p = plants.find(plant); if (p == plants.end()) { return new HTTPResponse(HTTPMessage::NOT_FOUND, - string("No existe la planta '") + plant + "'."); + string(""); // TODO - agregar chequeo de que la transmision a ese host:port no // exista para otra planta? } else if (plants[plant]->transmission_start(host, port)) { return new HTTPResponse(HTTPMessage::OK, - string("Se empieza a transmitir la planta '") + plant - + "' a " + host + ":" + String().from(port) + "."); + string(""); } else { return new HTTPResponse(HTTPMessage::INTERNAL_SERVER_ERROR, - string("Error al crear la transmisión a de la planta '") - + plant + "' a " + host + ":" + args[2] + "."); + string(""); } } } @@ -314,91 +278,111 @@ HTTPResponse* Server::cmd_transmission_stop(const Command& command) { const Command::Arguments& args = command.get_args(); if (args.size() < 2) { return new HTTPResponse(HTTPMessage::CONFLICT, - "Faltan argumentos."); + ""); } else { const string& host = args[0]; - Connection::Port port = String(args[1]).to(port); + Connection::Port port = to(args[1], port); for (PlantList::iterator i = plants.begin(); i != plants.end(); i++) { // TODO - agregar chequeo para saber si existe una conexion (para // tirar error de que no hay conexion o de que no se pudo // desconectar. if (i->second->transmission_stop(host, port)) { return new HTTPResponse(HTTPMessage::OK, - string("Se finaliza la transmisión de la planta '") - + i->first + "' a " + host + ":" + args[1] + "."); + string("first + "' a " + host + ":" + args[1] + ".\" />"); } } return new HTTPResponse(HTTPMessage::NOT_FOUND, - string("No se puede finalizar la transmisión a ") - + host + ":" + args[1] + "."); + string(""); } } HTTPResponse* Server::cmd_plant_list(void) { // FIXME - stringstream response_xml; - response_xml << "" << endl; - response_xml << " " << endl; - response_xml << " PlaQui v0.8" << endl; - response_xml << " " << endl; - response_xml << " " << endl; - response_xml << "

PlaQui

" << endl; - response_xml << "

versión 0.8

" << endl; - response_xml << "

Lista de plantas:

" << endl; - response_xml << "
    " << endl; + stringstream xml; + xml << "" << endl; plants_mutex.lock(); for (PlantList::const_iterator i = plants.begin(); i != plants.end(); i++) { - response_xml << "
  • " << i->first - << " [first << "\">parar]
  • " - << endl; + xml << "\t" << endl; + xml << "\t\t" << i->first << "" << endl; + xml << "\t" << endl; } plants_mutex.unlock(); - response_xml << "
" << endl; - response_xml << "
" << endl; - response_xml << " Copyleft 2003 - bajo los " << endl; - response_xml << " términos de la licencia GPL" << endl; - response_xml << "
" << endl; - response_xml << " " << endl; - response_xml << "" << endl; - return new HTTPResponse(HTTPMessage::OK, response_xml.str()); + xml << "" << endl; + return new HTTPResponse(HTTPMessage::OK, xml.str()); } HTTPResponse* Server::cmd_plant_get(const Command& command) { if (!command.get_args().size()) { return new HTTPResponse(HTTPMessage::CONFLICT, - "Faltan argumentos."); + ""); } Glib::Mutex::Lock lock(plants_mutex); - string name = command.get_args()[0]; - if (plants.find(name) == plants.end()) { + string plant = command.get_args()[0]; + if (plants.find(plant) == plants.end()) { return new HTTPResponse(HTTPMessage::NOT_FOUND, - string("No existe la planta ") + name); + string(""); } - string xml = plants[name]->get_xml(); + // TODO try/catch? + string xml = plants[plant]->get_xml(); if (xml.length()) { return new HTTPResponse(HTTPMessage::OK, xml); } else { return new HTTPResponse(HTTPMessage::INTERNAL_SERVER_ERROR, - ("No se pudo obtener el XML de la planta ") + name); + (""); } } +HTTPResponse* Server::cmd_plant_set(const Command& command) { + const Command::Arguments& args = command.get_args(); + if (args.size() < 4) { + return new HTTPResponse(HTTPMessage::CONFLICT, + ""); + } + string plant = args[0]; + string element = args[1]; + string key = args[2]; + if (key != "open") { + return new HTTPResponse(HTTPMessage::NOT_FOUND, + string(""); + } + string value = args[3]; + Glib::Mutex::Lock lock(plants_mutex); + PlantList::iterator p = plants.find(plant); + if (p == plants.end()) { + return new HTTPResponse(HTTPMessage::NOT_FOUND, + string(""); + } + bool open = true; + if ((value == "false") || (value == "0") || (value == "off") + || (value == "no")) { + open = false; + } + if (!plants[plant]->set_open(element, open)) { + return new HTTPResponse(HTTPMessage::CONFLICT, + string(""); + } + return new HTTPResponse(HTTPMessage::OK, + string(""); +} + HTTPResponse* Server::cmd_plant_stop(const Command& command) { if (!command.get_args().size()) { return new HTTPResponse(HTTPMessage::CONFLICT, - "Faltan argumentos."); + ""); } Glib::Mutex::Lock lock(plants_mutex); const string name = command.get_args()[0]; if (plants.find(name) == plants.end()) { return new HTTPResponse(HTTPMessage::NOT_FOUND, - string("No existe la planta ") + name); + string(""); } // TODO Ver si al frenar la planta se destruye (no deberia!!!) plants[name]->finish(); return new HTTPResponse(HTTPMessage::OK, - string("La planta '") + name + "' se cerrará en instantes..."); + string(""); } } // namespace Server