- Ya se envían comandos con la señal command_received() apropiadamente.
- Las respuestas son asincrónicas, ya que los comandos van a encolarse para
esperar que el modelo se actulice.
- Ya se pueden enviar respuestas via ControlServer::send().
Muchos cambios internos entre los que se destacan el correcto funcionamiento de
las excepciones (que venía postergado).
/// Conexión para enviar comandos de control a una planta.
class ControlClient: public Connection {
+ // Atributos.
+
+ private:
+
+ /// Mutex para el socket.
+ Glib::Mutex socket_mutex;
+
+ // Métodos.
+
private:
/**
#include "plaqui/server/connection.h"
#include "plaqui/server/command.h"
+#include "plaqui/server/httpresponse.h"
#include <socket++/sockinet.h>
+#include <sigc++/signal.h>
namespace PlaQui {
private:
+ /// Mutex para el socket.
+ Glib::Mutex socket_mutex;
+
/// Señal para indicar que se recibió un comando.
SignalCommandReceived command_received;
*/
ControlServer(const sockbuf::sockdesc& sd);
+ /**
+ * Envia una respuesta.
+ */
+ void send(const HTTPResponse& response);
+
/**
* Obtiene la señal que avisa cuando se recibió un comando.
*/
--- /dev/null
+// vim: set noexpandtab tabstop=4 shiftwidth=4:
+//----------------------------------------------------------------------------
+// PlaQui
+//----------------------------------------------------------------------------
+// This file is part of PlaQui.
+//
+// PlaQui 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.
+//
+// PlaQui 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 PlaQui; if not, write to the Free Software Foundation, Inc., 59 Temple
+// Place, Suite 330, Boston, MA 02111-1307 USA
+//----------------------------------------------------------------------------
+// Creado: mar nov 11 11:47:25 ART 2003
+// Autores: Leandro Lucarella <llucare@fi.uba.ar>
+//----------------------------------------------------------------------------
+//
+// $Id$
+//
+
+#ifndef PLAQUI_HTTPERROR_H
+#define PLAQUI_HTTPERROR_H
+
+#include <stdexcept>
+#include <string>
+#include <istream>
+#include <ostream>
+
+namespace PlaQui {
+
+namespace Server {
+
+ /// Error HTTP.
+ class HTTPError: public std::runtime_error {
+
+ // Atributos.
+
+ public:
+
+ /// Código de error.
+ unsigned code;
+
+ // Métodos.
+
+ public:
+
+ /**
+ * Destructor.
+ */
+ virtual ~HTTPError(void) throw();
+
+ /**
+ * Constructor.
+ */
+ HTTPError(unsigned code, const std::string& desc) throw();
+
+ };
+
+}
+
+}
+
+#endif // PLAQUI_HTTPERROR_H
#ifndef PLAQUI_HTTPHEADERS_H
#define PLAQUI_HTTPHEADERS_H
+#include "plaqui/server/httperror.h"
#include <map>
#include <string>
#include <istream>
/// Cabeceras HTTP.
class HTTPHeaders: public std::map<std::string, std::string> {
+ // Métodos.
+
public:
/**
/**
* Obtiene los datos de las cabeceras HTTP desde un texto.
*/
- friend std::istream& operator>>(std::istream& is, HTTPHeaders& h);
+ friend std::istream& operator>>(std::istream& is, HTTPHeaders& h)
+ throw(HTTPError);
/**
* Convierte las cabeceras HTTP a texto.
/// Pedido HTTP.
class HTTPMessage {
+ // Constantes.
+
+ public:
+
+ /// \todo TODO completar codigos.
+ static const unsigned OK = 200;
+ static const unsigned BAD_REQUEST = 401;
+ static const unsigned LENGTH_REQUIRED = 411;
+ static const unsigned INTERNAL_SERVER_ERROR = 500;
+ static const unsigned NOT_IMPLEMENTED = 501;
+ static const unsigned HTTP_VERSION_NOT_SUPPORTED = 505;
+
// Atributos.
private:
/**
* Constructor.
*/
- HTTPMessage(const std::string& http_version = "1.1");
+ //HTTPMessage(const std::string& http_version = "1.1");
/**
* Constructor.
*/
- //HTTPMessage(const std::string& body,
- // const std::string& http_version = "1.1");
+ HTTPMessage(const std::string& _body = "",
+ const std::string& _version = "1.1");
/**
* Obtiene el cuerpo del mensaje.
friend std::ostream& operator<<(std::ostream& os,
const HTTPMessage& m);
+ /**
+ * Obtiene la razón según un código.
+ *
+ * \param code Código de estado.
+ */
+ static std::string reason(unsigned code);
+
};
}
#ifndef PLAQUI_HTTPREQUEST_H
#define PLAQUI_HTTPREQUEST_H
-#include "httpmessage.h"
+#include "plaqui/server/httperror.h"
+#include "plaqui/server/httpmessage.h"
#include <string>
#include <istream>
#include <ostream>
/**
* Obtiene los datos del pedido HTTP desde un texto.
*/
- friend std::istream& operator>>(std::istream& is, HTTPRequest& req);
+ friend std::istream& operator>>(std::istream& is, HTTPRequest& req)
+ throw(HTTPError, std::ios::failure);
/**
* Convierte el pedido HTTP en texto.
#ifndef PLAQUI_HTTPRESPONSE_H
#define PLAQUI_HTTPRESPONSE_H
-#include "httpmessage.h"
+#include "plaqui/server/httperror.h"
+#include "plaqui/server/httpmessage.h"
#include <string>
namespace PlaQui {
/// Respuesta HTTP.
class HTTPResponse: public HTTPMessage {
+ // Tipos.
+
+ public:
+
+ typedef enum {
+ INVALID_HTTP_RESPONSE,
+ INVALID_HTTP_VERSION,
+ INVALID_HTTP_RESPONSE_CODE,
+ MISSING_HTTP_RESPONSE_CODE
+ } Error;
+
// Atributos.
protected:
/**
* Constructor.
*/
- //HTTPResponse(const std::string& body,
- // const std::string& version = "1.1");
+ HTTPResponse(const HTTPError& error);
/**
* Constructor.
*/
- //HTTPResponse(unsigned status_code, const std::string& reason,
- // const std::string& version = "1.1");
+ HTTPResponse(unsigned status_code, const std::string& body = "");
/**
* Constructor.
* Obtiene los datos de la respuesta HTTP desde un texto.
*/
friend std::istream& operator>>(std::istream& is,
- HTTPResponse& resp);
+ HTTPResponse& resp) throw(Error, std::ios::failure);
/**
* Convierte la respuesta HTTP en texto.
*
* \todo Hacer un tipo Command abstracto o algo así.
*/
- void on_control_command_received(const Command& command);
+ void on_control_command_received(const Command& command,
+ ControlServer* server);
};
*/
virtual ~String(void);
+ /**
+ * Constructor.
+ */
+ String(void);
+
/**
* Constructor.
*
*/
class TCPServer: public Runnable {
- // Tipos.
+ // Constantes.
private:
/// Cantidad máxima de conexiones pendientes.
- static const unsigned MAX_PENDING_CONNECTIONS;
+ static const unsigned MAX_PENDING_CONNECTIONS = 10;
+
+ // Tipos.
+
+ private:
/// Lista de conexiones de control.
typedef std::list<Connection*> ConnectionList;
objects+=string.o
string.o: $(string_h) string.cpp
+httperror_h=$(INCLUDE_DIR)/httperror.h
+objects+=httperror.o
+httperror.o: $(httperror_h) httperror.cpp
+
httpheaders_h=$(string_h) $(INCLUDE_DIR)/httpheaders.h
objects+=httpheaders.o
httpheaders.o: $(httpheaders_h) httpheaders.cpp
objects+=command.o
command.o: $(command_h) command.cpp
-httpresponse_h=$(string_h) $(httpmessage_h) $(INCLUDE_DIR)/httprequest.h
+httpresponse_h=$(string_h) $(httperror_h) $(httpmessage_h) $(INCLUDE_DIR)/httprequest.h
objects+=httpresponse.o
httpresponse.o: $(httpresponse_h) httpresponse.cpp
#include "plaqui/server/controlserver.h"
#include "plaqui/server/command.h"
-#include "plaqui/server/string.h"
-#include <cstring>
-#include <sstream>
+#include "plaqui/server/httperror.h"
+#include "plaqui/server/httpresponse.h"
+//#include <cstring>
+//#include <sstream>
#ifdef DEBUG
+# include "plaqui/server/string.h"
# include <iostream>
#endif // DEBUG
while (!stop) {
Command command;
try {
+ Glib::Mutex::Lock lock(socket_mutex);
socket >> command;
- } catch (const char* e) {
- cerr << " (" << __LINE__ << ") Error: " << e << endl;
+ // Si se cerró el socket.
+ } catch (const ios::failure& e) {
stop = true;
continue;
- } catch (string e) {
- cerr << " (" << __LINE__ << ") Error: " << e << endl;
- stop = true;
- continue;
- } catch (...) {
- cerr << " (" << __LINE__ << ") Error desconocido!" << endl;
- stop = true;
+ // Si hay un error al parsear el comando, se envia una respuesta con el
+ // error.
+ } catch (const HTTPError& e) {
+#ifdef DEBUG
+ cerr << __FILE__ << " : real_run() ERROR: status_code = "
+ << e.code << " | reason = " << HTTPMessage::reason(e.code)
+ << " | desc = " << e.what() << endl;
+#endif // DEBUG
+ socket << HTTPResponse(e) << flush;
continue;
}
// TODO agregar las verificaciones de abajo a HTTPRequest y padres.
+ // Actualizacion: Estoy usando trim() en casi todos lados, no debería
+ // ser necesario.
/*
// Primera línea no vacía (que debe ser el request).
bool is_first = true;
}
}
*/
- // Manda el comando.
- command_received.emit(command);
#ifdef DEBUG
- cerr << "Comando: target = " << command.get_target()
- << " | command = " << command.get_command()
+ cerr << __FILE__ << " : real_run() Despachando comando: target = "
+ << command.get_target() << " | command = " << command.get_command()
<< " | args = [" << String::join(command.get_args(), ", ") << "]"
<< endl;
#endif // DEBUG
+ // Manda el comando.
+ command_received(command);
// FIXME - hacer respuesta XML.
// La respuesta hay que mandarla asincrónicamente porque no puedo
// responder hasta que la planta no se termine de actualizar, por
// ejemplo.
- stringstream response_xml;
- socket << "HTTP/1.0 200 OK" << endl;
+ //stringstream response_xml;
+ //socket << "HTTP/1.0 200 OK" << endl;
/*
Date: Sun, 19 Oct 2003 15:11:14 GMT
Server: Apache/1.3.28 (Debian GNU/Linux)
Last-Modified: Mon, 28 Apr 2003 07:50:08 GMT
Accept-Ranges: bytes
*/
+/*
socket << "Content-Type: text/html; charset=iso-8859-1" << endl;
response_xml << "<html>" << endl;
response_xml << " <head>" << endl;
response_xml << " <p>versión 0.4</p>" << endl;
response_xml << " <h2>Comando</h2>" << endl;
response_xml << " <ul>" << endl;
-/* response_xml << " <li><b>Versión:</b> " << request.version << endl;
- response_xml << " <li><b>Método:</b> " << (request.method ? "POST" : "GET") << endl;
- response_xml << " <li><b>URI:</b> " << request.uri << endl;
- response_xml << " <li><b>Query:</b> " << request.query << endl;
- for (HTTPHeaders::const_iterator i = request.headers.begin();
- i != request.headers.end(); i++) {
- response_xml << " <li><b>" << i->first << ":</b> "
- << i->second << endl;
- }*/
response_xml << " <li><b>Target:</b> " << command.get_target() << endl;
response_xml << " <li><b>Command:</b> " << command.get_command() << endl;
response_xml << " <li><b>Argumentos:</b>" << endl;
socket << "Content-Length: " << response_xml.str().length() << endl;
socket << endl;
socket << response_xml.str() << flush;
+*/
}
}
+void ControlServer::send(const HTTPResponse& response) {
+ Glib::Mutex::Lock lock(socket_mutex);
+ socket << response << flush;
+}
+
ControlServer::SignalCommandReceived& ControlServer::signal_command_received(void) {
return command_received;
}
--- /dev/null
+// vim: set noexpandtab tabstop=4 shiftwidth=4:
+//----------------------------------------------------------------------------
+// PlaQui
+//----------------------------------------------------------------------------
+// This file is part of PlaQui.
+//
+// PlaQui 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.
+//
+// PlaQui 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 PlaQui; if not, write to the Free Software Foundation, Inc., 59 Temple
+// Place, Suite 330, Boston, MA 02111-1307 USA
+//----------------------------------------------------------------------------
+// Creado: mar nov 11 12:17:18 ART 2003
+// Autores: Leandro Lucarella <llucare@fi.uba.ar>
+//----------------------------------------------------------------------------
+//
+// $Id$
+//
+
+#include "plaqui/server/httperror.h"
+#ifdef DEBUG
+# include <iostream>
+#endif // DEBUG
+
+using namespace std;
+
+namespace PlaQui {
+
+namespace Server {
+
+HTTPError::~HTTPError(void) throw() {
+#ifdef DEBUG
+ cerr << __FILE__ << ": destructor." << endl;
+#endif // DEBUG
+}
+
+HTTPError::HTTPError(unsigned code, const std::string& desc) throw():
+ runtime_error(desc), code(code) {
+#ifdef DEBUG
+ cerr << __FILE__ << ": code = " << code << " | desc = " << desc << endl;
+#endif // DEBUG
+}
+
+} // namespace Server
+
+} // namespace PlaQui
+
//
#include "plaqui/server/httpheaders.h"
+#include "plaqui/server/httperror.h"
#include "plaqui/server/string.h"
//#include <cstdlib>
#ifdef DEBUG
#endif // DEBUG
}
-istream& operator>>(istream& is, HTTPHeaders& h) {
+istream& operator>>(istream& is, HTTPHeaders& h) throw(HTTPError) {
#ifdef DEBUG
cerr << __FILE__ << ": operator>>()" << endl;
#endif // DEBUG
string::size_type pos = sbuf.find(":");
if (pos == string::npos) {
// FIXME poner mejores excepciones.
- throw string("Wrong header: ") + sbuf;
+ throw HTTPError(400, sbuf + ": No es una cabecera válida.");
}
h[sbuf.substr(0, pos)] = String(sbuf.substr(pos + 1)).trim();
#ifdef DEBUG
#endif // DEBUG
}
-HTTPMessage::HTTPMessage(const string& version):
- version(version) {
+HTTPMessage::HTTPMessage(const string& _body, const string& _version):
+ version(_version) {
#ifdef DEBUG
- cerr << __FILE__ << ": version = " << version << endl;
-#endif // DEBUG
-}
-
-/*
-HTTPMessage::HTTPMessage(const string& _body,
- const string& http_version):
- http_version(http_version) {
-#ifdef DEBUG
- cerr << __FILE__ << ": http_version = " << http_version
- << " | body = " << body << endl;
+ cerr << __FILE__ << ": version = " << version << " | body.length = "
+ << _body.length() << endl;
#endif // DEBUG
set_body(_body);
}
-*/
void HTTPMessage::set_body(const string& _body) {
body = _body;
if (body.length()) {
stringstream ss; // TODO ver forma mas linda de convertir
- ss << body.length();
+ ss << (body.length());
+ headers["Accept-Ranges"] = "bytes";
headers["Content-Length"] = ss.str();
}
}
<< m.body;
}
+string HTTPMessage::reason(unsigned code) {
+ switch (code) {
+ // TODO completar los códigos.
+ case OK:
+ return "OK";
+ case BAD_REQUEST:
+ return "Bad Request";
+ case LENGTH_REQUIRED:
+ return "Length Required";
+ case INTERNAL_SERVER_ERROR:
+ return "Internal Server Error";
+ case NOT_IMPLEMENTED:
+ return "Not Implemented";
+ case HTTP_VERSION_NOT_SUPPORTED:
+ return "HTTP Version Not Supported";
+ default:
+ return "";
+ }
+}
+
} // namespace Server
} // namespace PlaQui
}
*/
-istream& operator>>(istream& is, HTTPRequest& req) {
+istream& operator>>(istream& is, HTTPRequest& req)
+ throw(HTTPError, ios::failure) {
#ifdef DEBUG
cerr << __FILE__ << ": operator>>()" << endl;
#endif // DEBUG
char buf[BUFSIZ];
// Obtengo primera línea (request)
- is.getline(buf, BUFSIZ);
+ if (!is.getline(buf, BUFSIZ)) {
+ // No hay más líneas.
+ throw ios::failure("socket closed");
+ }
#ifdef DEBUG
- cerr << "Recibiendo linea: " << buf << endl;
+ cerr << __FILE__ << ":\tRecibiendo linea: " << buf << endl;
#endif // DEBUG
String line(buf);
// Si es la primera línea, es el request.
if (line.length() < 3) {
- // FIXME - poner excepciones lindas.
- throw "HTTP/1.1 501 Method Not Implemented";
+ throw HTTPError(HTTPMessage::BAD_REQUEST, line
+ + ": No tiene un método conocido.");
}
// Averiguo método.
string::size_type pos = line.find_first_of(String::SPACE_CHARS);
String met = line.substr(0, pos);
- if (met.to_upper() == "GET") {
+ met.to_upper();
+ if (met == "GET") {
req.method = HTTPRequest::GET;
- } else if (met.to_upper() == "POST") {
+ } else if (met == "POST") {
req.method = HTTPRequest::POST;
} else {
- // FIXME - poner excepciones lindas.
- throw "HTTP/1.1 501 Method Not Implemented";
+ throw HTTPError(HTTPMessage::NOT_IMPLEMENTED, met
+ + ": No es un método soportado.");
}
// Si tiene sólo el método, no es válido.
line = line.substr(pos + 1);
line.trim();
if (!line.length()) {
- // FIXME - poner excepciones lindas.
- throw "HTTP/1.1 400 Bad Request";
+ throw HTTPError(HTTPMessage::BAD_REQUEST, "Falta URI.");
}
// Si tiene más espacios, tengo la URI y el protocolo (o un error).
pos = line.find_first_of(String::SPACE_CHARS);
if (pos != string::npos) {
// Si el resto es un protocolo válido, agrego más variables.
String protocol = line.substr(pos + 1);
- protocol = protocol.trim();
- if (protocol.to_upper() == "HTTP/1.0") {
+ protocol = protocol.trim().to_upper();
+ if (protocol.substr(0, 5) != "HTTP/") {
+ throw HTTPError(HTTPMessage::BAD_REQUEST,
+ protocol + ": Protocolo desconocido");
+ }
+ if (protocol.substr(5) == "1.0") {
req.version = "1.0";
- } else if (protocol.to_upper() == "HTTP/1.1") {
+ } else if (protocol.substr(5) == "1.1") {
req.version = "1.1";
// Si no es un error.
} else {
- // FIXME - poner excepciones lindas.
- throw "HTTP/1.1 400 Bad Request";
+ throw HTTPError(HTTPMessage::HTTP_VERSION_NOT_SUPPORTED,
+ protocol.substr(5) + ": Versión HTTP no soportada.");
}
line = line.substr(0, pos);
}
// Agrego la URI y sus derivados.
if (!line.length() || (line[0] != '/')) {
// FIXME || request.find_first_not_of(";/?:@&=+$,")) {
- // FIXME - poner excepciones lindas.
- throw "HTTP/1.1 400 Bad Request";
+ throw HTTPError(HTTPMessage::BAD_REQUEST,
+ line + ": La URI no comienza con /.");
}
// Si tiene un query string.
pos = line.find("?");
if (req.query.length()) {
os << "?" << req.query;
}
- // TODO ver que este bien el \r\l
+ // TODO ver que este bien el \n/r
os << " HTTP/" << req.version << "\n\r" << static_cast<const HTTPMessage&>(req);
return os;
}
#endif // DEBUG
}
-/*
-HTTPResponse::HTTPResponse(const Serializable& body,
- const string& version):
- HTTPMessage(body, version) {
+HTTPResponse::HTTPResponse(const HTTPError& error):
+ status_code(error.code) {
#ifdef DEBUG
- cerr << __FILE__ << ": http_version = " << http_version
- << " | body = " << body.serialize() << endl;
+ cerr << __FILE__ << ": HTTPError(status_code = " << error.code
+ << ", reason = " << HTTPMessage::reason(error.code) << ", desc = " << error.what()
+ << ")" << endl;
#endif // DEBUG
+ set_body(string("<plaqui><error desc=\"") + error.what() + "\" /></plaqui>");
}
-HTTPResponse::HTTPResponse(const string& uri,
- const HTTPResponse::HTTPMethod& method,
- string& query, string& version):
- HTTPMessage(body, version) {
+HTTPResponse::HTTPResponse(unsigned status_code, const string& body):
+ HTTPMessage(body), status_code(status_code) {
#ifdef DEBUG
- cerr << __FILE__ << ": http_version = " << http_version
- << " | body = " << body.serialize() << endl;
+ cerr << __FILE__ << ": status_code = " << status_code
+ << " | body.length = " << body.length() << endl;
#endif // DEBUG
}
-*/
-istream& operator>>(istream& is, HTTPResponse& resp) {
+istream& operator>>(istream& is, HTTPResponse& resp)
+ throw (HTTPResponse::Error, ios::failure) {
#ifdef DEBUG
cerr << __FILE__ << ": operator>>()" << endl;
#endif // DEBUG
char buf[BUFSIZ];
// Obtengo primera línea (request)
- is.getline(buf, BUFSIZ);
+ if (!is.getline(buf, BUFSIZ)) {
+ // No hay mas líneas.
+ throw ios::failure("socket closed");
+ }
#ifdef DEBUG
- cerr << "Recibiendo linea: " << buf << endl;
+ cerr << __FILE__ << ":\tRecibiendo linea: " << buf << endl;
#endif // DEBUG
String line(buf);
// Si es la primera línea, es el request.
- if (line.to_upper().substr(0, 4) != "HTTP/") {
- // FIXME - poner excepciones lindas.
- throw "Not a HTTP response";
+ if (String(line.substr(0, 5)).to_upper() != "HTTP/") {
+ throw HTTPResponse::INVALID_HTTP_RESPONSE;
}
// Averiguo la versión.
string::size_type pos = line.find_first_of(String::SPACE_CHARS, 5);
if ((ver == "1.1") || (ver == "1.0")) {
resp.version = ver;
} else {
- // FIXME - poner excepciones lindas.
- throw "Invalid HTTP version";
+ throw HTTPResponse::INVALID_HTTP_VERSION;
}
// Si tiene sólo la versión HTTP, no es válido.
line = line.substr(pos + 1);
line.trim();
if (!line.length()) {
- // FIXME - poner excepciones lindas.
- throw "Invalid HTTP response";
+ throw HTTPResponse::MISSING_HTTP_RESPONSE_CODE;
}
// Si tiene más espacios, tengo la razón (reason).
pos = line.find_first_of(String::SPACE_CHARS);
if (pos != string::npos) {
- String r = line.substr(pos + 1);
- resp.reason = r.trim();
+ //FIXME String r = line.substr(pos + 1);
+ //resp.reason = r.trim();
line = line.substr(0, pos);
}
line = line.trim();
// Seteo el código.
+ // TODO - chequear el codigo a ver si pertenece a uno definido en la RFC.
if (line.length() != 3) {
- // FIXME - poner excepciones lindas.
- throw "Invalid response code";
+ throw HTTPResponse::INVALID_HTTP_RESPONSE_CODE;
}
stringstream ss;
ss << line; // TODO ver forma mas linda de convertir
#ifdef DEBUG
cerr << __FILE__ << ": operator<<()" << endl;
#endif // DEBUG
- os << "HTTP/" << resp.version << " " << resp.status_code << " " << resp.reason << "\n\r";
+ os << "HTTP/" << resp.version << " " << resp.status_code << " "
+ << HTTPMessage::reason(resp.status_code) << "\n\r";
// TODO ver que este bien el \r\l
os << static_cast<const HTTPMessage&>(resp);
return os;
<< endl;
#endif // DEBUG
runner->real_run();
- runner->signal_finished().emit();
+ runner->finished();
delete runner;
}
#include "plaqui/server/connection.h"
#include "plaqui/server/controlserver.h"
#include <sigc++/class_slot.h>
+// FIXME - sacar sstream (a menos que se necesite)
+#include <sstream>
#ifdef DEBUG
# include "plaqui/server/string.h"
# include <iostream>
ControlServer* connection = new ControlServer(sd);
// TODO verificar si el new se hace bien? no creo.
connection->signal_command_received().connect(
- SigC::slot_class(*this, &Server::on_control_command_received));
+ SigC::bind<ControlServer*>(
+ SigC::slot_class(*this, &Server::on_control_command_received),
+ connection));
// TODO:
return connection;
}
}
/// \todo Implementar.
-void Server::on_control_command_received(const Command& command) {
+void Server::on_control_command_received(const Command& command,
+ ControlServer* server) {
#ifdef DEBUG
cerr << __FILE__ << ": on_control_command_received(target = "
<< command.get_target() << ", command = " << command.get_command()
<< ", args = [" << String::join(command.get_args(), ", ") << "])"
<< endl;
#endif // DEBUG
-}
+ // TODO, seguir aca!
+ stringstream response_xml;
+ response_xml << "<html>" << endl;
+ response_xml << " <head>" << endl;
+ response_xml << " <title>PlaQui v0.4</title>" << endl;
+ response_xml << " </head>" << endl;
+ response_xml << " <body>" << endl;
+ response_xml << " <h1>PlaQui</h1>" << endl;
+ response_xml << " <p>versión 0.4</p>" << endl;
+ response_xml << " <h2>Comando</h2>" << endl;
+ response_xml << " <ul>" << endl;
+ response_xml << " <li><b>Target:</b> " << command.get_target() << endl;
+ response_xml << " <li><b>Command:</b> " << command.get_command() << endl;
+ response_xml << " <li><b>Argumentos:</b>" << endl;
+ response_xml << " <ol>" << endl;
+ for (Command::Arguments::const_iterator i = command.get_args().begin();
+ i != command.get_args().end(); i++) {
+ response_xml << " <li>" << *i << "</li>" << endl;
+ }
+ response_xml << " </ol>" << endl;
+ response_xml << " </ul>" << endl;
+ response_xml << " <h2>Desarrollado por</h2>" << endl;
+ response_xml << " <ul>" << endl;
+ response_xml << " <li>Nicolás Dimov.</li>" << endl;
+ response_xml << " <li>Leandro Lucarella.</li>" << endl;
+ response_xml << " <li>Ricardo Markiewicz.</li>" << endl;
+ response_xml << " </ul>" << endl;
+ response_xml << " <address>" << endl;
+ response_xml << " Copyleft 2003 - bajo los " << endl;
+ response_xml << " términos de la licencia GPL" << endl;
+ response_xml << " </address>" << endl;
+ response_xml << " </body>" << endl;
+ response_xml << "</html>" << endl;
+ HTTPResponse response(HTTPMessage::OK, response_xml.str());
+ response.headers["Content-Type"] = "text/html; charset=iso-8859-1";
+ //response.headers["Connection"] = "close";
+ server->send(response);
+ }
} // namespace Server
String::~String(void) {
}
+String::String(void) {
+}
+
String::String(const string& str):
string(str.c_str()) {
}
namespace Server {
-const unsigned TCPServer::MAX_PENDING_CONNECTIONS = 10;
-
TCPServer::~TCPServer(void) {
#ifdef DEBUG
cerr << __FILE__ << ": destructor." << endl;
#endif // DEBUG
}
-void TCPServer::on_connection_finished(
- Connection* connection) {
+void TCPServer::on_connection_finished(Connection* connection) {
#ifdef DEBUG
cerr << __FILE__ << ": on_connection_finished(connection = "
<< connection << ")" << endl;
cd $(LIB_FILES) && $(MAKE)
# Tests
-server_test: $(LIB_FILES)/server.a server_test.cpp
+server_test: $(LIB_FILES)/server.a server_test.o
clean:
rm -f $(TARGETS) *.o