From 1b53a979e1de9034a9755955ea22cd40ed138f23 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Thu, 6 Nov 2003 03:02:24 +0000 Subject: [PATCH] Se agregan mas cosas nuevas, todavia no compila. --- Server/include/plaqui/server/httpheaders.h | 3 +- Server/include/plaqui/server/httpmessage.h | 27 +++-- Server/include/plaqui/server/httprequest.h | 3 +- Server/include/plaqui/server/httpresponse.h | 16 +-- Server/src/httpheaders.cpp | 64 +++------- Server/src/httpmessage.cpp | 26 ++-- Server/src/httprequest.cpp | 43 ++++--- Server/src/httpresponse.cpp | 124 ++++++++++++++++++++ 8 files changed, 200 insertions(+), 106 deletions(-) create mode 100644 Server/src/httpresponse.cpp diff --git a/Server/include/plaqui/server/httpheaders.h b/Server/include/plaqui/server/httpheaders.h index bc4ce02..8eb42ed 100644 --- a/Server/include/plaqui/server/httpheaders.h +++ b/Server/include/plaqui/server/httpheaders.h @@ -48,8 +48,7 @@ namespace Server { /** * Obtiene los datos de las cabeceras HTTP desde un texto. */ - friend std::istream& operator>>(std::istream& is, - const HTTPHeaders& h); + friend std::istream& operator>>(std::istream& is, HTTPHeaders& h); /** * Convierte las cabeceras HTTP a texto. diff --git a/Server/include/plaqui/server/httpmessage.h b/Server/include/plaqui/server/httpmessage.h index cd583e7..888eacf 100644 --- a/Server/include/plaqui/server/httpmessage.h +++ b/Server/include/plaqui/server/httpmessage.h @@ -39,6 +39,11 @@ namespace Server { // Atributos. + private: + + /// Cuerpo del mensaje. + std::string body; + protected: /// Version HTTP. @@ -47,9 +52,6 @@ namespace Server { /// Cabeceras HTTP. HTTPHeaders headers; - /// Cuerpo del mensaje. - std::string body; - // Métodos. public: @@ -67,14 +69,25 @@ namespace Server { /** * Constructor. */ - HTTPMessage(const std::string& body, - const std::string& http_version = "1.1"); + //HTTPMessage(const std::string& body, + // const std::string& http_version = "1.1"); + + /** + * Obtiene el cuerpo del mensaje. + */ + const std::string& get_body(void) const; + + /** + * Establece el cuerpo del mensaje. + * + * \param _body Cuerpo del mensaje. + */ + void set_body(const std::string& _body); /** * Obtiene los datos del pedido HTTP desde un texto. */ - friend std::istream& operator>>(std::istream& is, - const HTTPMessage& m); + friend std::istream& operator>>(std::istream& is, HTTPMessage& m); /** * Convierte el pedido HTTP en texto. diff --git a/Server/include/plaqui/server/httprequest.h b/Server/include/plaqui/server/httprequest.h index 0f21452..55748e7 100644 --- a/Server/include/plaqui/server/httprequest.h +++ b/Server/include/plaqui/server/httprequest.h @@ -109,8 +109,7 @@ namespace Server { /** * Obtiene los datos del pedido HTTP desde un texto. */ - friend std::istream& operator>>(std::istream& is, - const HTTPRequest& req); + friend std::istream& operator>>(std::istream& is, HTTPRequest& req); /** * Convierte el pedido HTTP en texto. diff --git a/Server/include/plaqui/server/httpresponse.h b/Server/include/plaqui/server/httpresponse.h index 936d2a3..f5c0afd 100644 --- a/Server/include/plaqui/server/httpresponse.h +++ b/Server/include/plaqui/server/httpresponse.h @@ -65,27 +65,27 @@ namespace Server { /** * Constructor. */ - HTTPResponse(const Serializable& body, - const std::string& version = "1.1"); + //HTTPResponse(const std::string& body, + // const std::string& version = "1.1"); /** * Constructor. */ - HTTPResponse(unsigned status_code, const std::string& reason, - const std::string& version = "1.1"); + //HTTPResponse(unsigned status_code, const std::string& reason, + // const std::string& version = "1.1"); /** * Constructor. */ - HTTPResponse(unsigned status_code, const std::string& reason, - const std::string& body, - const std::string& version = "1.1"); + //HTTPResponse(unsigned status_code, const std::string& reason, + // const std::string& body, + // const std::string& version = "1.1"); /** * Obtiene los datos de la respuesta HTTP desde un texto. */ friend std::istream& operator>>(std::istream& is, - const HTTPResponse& resp); + HTTPResponse& resp); /** * Convierte la respuesta HTTP en texto. diff --git a/Server/src/httpheaders.cpp b/Server/src/httpheaders.cpp index d0736b2..67ec270 100644 --- a/Server/src/httpheaders.cpp +++ b/Server/src/httpheaders.cpp @@ -36,64 +36,30 @@ PlaQui::Server::HTTPHeaders::~HTTPHeaders(void) { std::cerr << __FILE__ << ": destructor." << std::endl; #endif // DEBUG } -/* -PlaQui::Server::HTTPMessage::HTTPMessage(const std::string& http_version): - http_version(http_version) { -#ifdef DEBUG - std::cerr << __FILE__ << ": http_version = " << http_version << std::endl; -#endif // DEBUG -} -PlaQui::Server::HTTPMessage::HTTPMessage(const std::string& _body, - const std::string& http_version): - http_version(http_version) { +istream& operator>>(std::istream& is, PlaQui::Server::httpheaders& h) { #ifdef DEBUG - std::cerr << __FILE__ << ": http_version = " << http_version - << " | body = " << body << std::endl; + std::cerr << __FILE__ << ": operator>>()" << std::endl; #endif // DEBUG - set_body(_body); + char buf[BUFSIZ]; + is.getline(buf, BUFSIZ); + std::string sbuf = buf; + std::string::size_type pos = sbuf.find(":"); + if (pos == std::string::npos) { + // FIXME poner mejores excepciones. + throw "Wrong header"; + } + (*this)[sbuf.substr(0, pos)] = sbuf.substr(pos + 1); + return is; } -*/ + ostream& operator<<(std::ostream& os, PlaQui::Server::HTTPMessage) { #ifdef DEBUG std::cerr << __FILE__ << ": operator<<()" << std::endl; #endif // DEBUG for (HTTPMessage::const_iterator i = begin(); i != end(); ++i) { - os << i->first << ": " << i->second << std::flush; - return os << headers << "\r\l" // Fin de cabeceras -} - -istream& operator>>(std::istream& is, PlaQui::Server::HTTPMessage) { -#ifdef DEBUG - std::cerr << __FILE__ << ": operator>>()" << std::endl; -#endif // DEBUG - char buf[BUFSIZ]; - bool is_header = true; - stringstream body_ss; - while (is.getline(buf, BUFSIZ)) { - std::string sbuf = buf; - if (sbuf.length()) - if (is_header) { - // TODO esto va al operator>> de HTTPHeaders. - std::string::size_type pos = sbuf.find(":"); - if (pos == std::string::npos) { - // FIXME poner mejores excepciones. - throw "Wrong header"; - } - headers[sbuf.substr(0, pos)] = sbuf.substr(pos + 1); - } else { - body_ss << buf << std::endl; - } - } else { - if (is_header) { - is_header = false; - } else { - body_ss << buf << std::endl; - } - } + os << i->first << ": " << i->second << "\r\l"; } - // TODO El body debería leer solo el content-length. - body = body_ss.str(); - return is; + return os; } diff --git a/Server/src/httpmessage.cpp b/Server/src/httpmessage.cpp index 625d82e..2d3a18b 100644 --- a/Server/src/httpmessage.cpp +++ b/Server/src/httpmessage.cpp @@ -44,6 +44,7 @@ PlaQui::Server::HTTPMessage::HTTPMessage(const std::string& http_version): #endif // DEBUG } +/* PlaQui::Server::HTTPMessage::HTTPMessage(const std::string& _body, const std::string& http_version): http_version(http_version) { @@ -53,6 +54,7 @@ PlaQui::Server::HTTPMessage::HTTPMessage(const std::string& _body, #endif // DEBUG set_body(_body); } +*/ void PlaQui::Server::HTTPMessage::set_body(const std::string& _body) { body = _body; @@ -67,14 +69,6 @@ const std::string& PlaQui::Server::HTTPMessage::get_body(void) { return body; } -ostream& operator<<(std::ostream& os, PlaQui::Server::HTTPMessage) { -#ifdef DEBUG - std::cerr << __FILE__ << ": operator<<()" << std::endl; -#endif // DEBUG - return os << headers << "\r\l" // Fin de cabeceras - << body << std::flush; -} - istream& operator>>(std::istream& is, PlaQui::Server::HTTPMessage) { #ifdef DEBUG std::cerr << __FILE__ << ": operator>>()" << std::endl; @@ -86,13 +80,7 @@ istream& operator>>(std::istream& is, PlaQui::Server::HTTPMessage) { std::string sbuf = buf; if (sbuf.length()) if (is_header) { - // TODO esto va al operator>> de HTTPHeaders. - std::string::size_type pos = sbuf.find(":"); - if (pos == std::string::npos) { - // FIXME poner mejores excepciones. - throw "Wrong header"; - } - headers[sbuf.substr(0, pos)] = sbuf.substr(pos + 1); + istringstream(buf) >> m.headers; } else { body_ss << buf << std::endl; } @@ -109,3 +97,11 @@ istream& operator>>(std::istream& is, PlaQui::Server::HTTPMessage) { return is; } +ostream& operator<<(std::ostream& os, PlaQui::Server::HTTPMessage) { +#ifdef DEBUG + std::cerr << __FILE__ << ": operator<<()" << std::endl; +#endif // DEBUG + return os << headers << "\r\l" // Fin de cabeceras + << body; +} + diff --git a/Server/src/httprequest.cpp b/Server/src/httprequest.cpp index 4c28a51..3614610 100644 --- a/Server/src/httprequest.cpp +++ b/Server/src/httprequest.cpp @@ -44,6 +44,7 @@ PlaQui::Server::HTTPRequest::HTTPRequest(const std::string& version): #endif // DEBUG } +/* PlaQui::Server::HTTPRequest::HTTPRequest(const Serializable& body, const std::string& version): PlaQui::Server::HTTPMessage(body, version) { @@ -62,31 +63,15 @@ PlaQui::Server::HTTPRequest::HTTPRequest(const std::string& uri, << " | body = " << body.serialize() << std::endl; #endif // DEBUG } +*/ -void PlaQui::Server::HTTPRequest::serialize(std::ostream& os) { +std::istream& operator>>(std::istream& is, PlaQui::Server::HTTPRequest& req) { #ifdef DEBUG - std::cerr << __FILE__ << ": serialize()" << std::endl; + std::cerr << __FILE__ << ": operator>>()" << std::endl; #endif // DEBUG - os << method << " " << uri; - if (query_string.length()) { - os << "?" << query; - } - os << "HTTP/" << version << "\r\l" << std::flush; // TODO ver que este bien el \r\l - HTTPMessage::serilize(os); - if (headers.size()) { - headers.serilize(os); - } - os << "\r\l" << std::flush; - if (body.size()) { - body.serilize(os); - } -} - -void PlaQui::Server::HTTPRequest::unserialize(std::istream& is) { - const unsigned BUFFER_SIZE = 4096; - char buf[BUFFER_SIZE]; + char buf[BUFSIZ]; // Obtengo primera línea (request) - is.getline(buf, BUFFER_SIZE); + is.getline(buf, BUFSIZ); #ifdef DEBUG std::cerr << "Recibiendo linea: " << buf << std::endl; #endif // DEBUG @@ -145,7 +130,19 @@ void PlaQui::Server::HTTPRequest::unserialize(std::istream& is) { query = ""; } uri = line.substr(0, pos); - // Fin de request, obtengo cabeceras y cuerpo. - HTTPMessage::unserialize(is); + // Fin de request, obtengo el mensaje. + is >> *(static_cast(this)); +} + +std::ostream& operator<<(std::ostream& os, PlaQui::Server::HTTPRequest& req) { +#ifdef DEBUG + std::cerr << __FILE__ << ": operator<<()" << std::endl; +#endif // DEBUG + os << method << " " << uri; + if (query_string.length()) { + os << "?" << query; + } + // TODO ver que este bien el \r\l + os << " HTTP/" << version << "\r\l" << *(static_cast(this)); } diff --git a/Server/src/httpresponse.cpp b/Server/src/httpresponse.cpp new file mode 100644 index 0000000..fb6ba78 --- /dev/null +++ b/Server/src/httpresponse.cpp @@ -0,0 +1,124 @@ +// 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: dom oct 26 22:11:03 ART 2003 +// Autores: Leandro Lucarella +//---------------------------------------------------------------------------- +// +// $Id$ +// + +#include "plaqui/server/httpresponse.h" +#include "plaqui/server/string.h" +#ifdef DEBUG +# include +#endif // DEBUG + +PlaQui::Server::HTTPRequest::~HTTPResponse(void) { +#ifdef DEBUG + std::cerr << __FILE__ << ": destructor." << std::endl; +#endif // DEBUG +} + +PlaQui::Server::HTTPResponse::HTTPResponse(const std::string& version): + PlaQui::Server::HTTPMessage(version) { +#ifdef DEBUG + std::cerr << __FILE__ << ": http_version = " << http_version << std::endl; +#endif // DEBUG +} + +/* +PlaQui::Server::HTTPResponse::HTTPResponse(const Serializable& body, + const std::string& version): + PlaQui::Server::HTTPMessage(body, version) { +#ifdef DEBUG + std::cerr << __FILE__ << ": http_version = " << http_version + << " | body = " << body.serialize() << std::endl; +#endif // DEBUG +} + +PlaQui::Server::HTTPResponse::HTTPResponse(const std::string& uri, + const PlaQui::Server::HTTPResponse::HTTPMethod& method, + std::string& query, std::string& version): + PlaQui::Server::HTTPMessage(body, version) { +#ifdef DEBUG + std::cerr << __FILE__ << ": http_version = " << http_version + << " | body = " << body.serialize() << std::endl; +#endif // DEBUG +} +*/ + +std::istream& operator>>(std::istream& is, PlaQui::Server::HTTPResponse& req) { +#ifdef DEBUG + std::cerr << __FILE__ << ": operator>>()" << std::endl; +#endif // DEBUG + char buf[BUFSIZ]; + // Obtengo primera línea (request) + is.getline(buf, BUFSIZ); +#ifdef DEBUG + std::cerr << "Recibiendo linea: " << buf << std::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"; + } + // Averiguo la versión. + std::string::size_type pos = line.find_first_of(String::SPACE_CHARS, 5); + std::string ver = line.substr(5, pos); + if ((ver == "1.1") || (ver == "1.0")) { + version = ver; + } else { + // FIXME - poner excepciones lindas. + throw "Invalid HTTP version"; + } + // Si tiene sólo la versión HTTP, no es válido. + line = line.substr(pos + 1).trim(); + if (!line.length()) { + // FIXME - poner excepciones lindas. + throw "Invalid HTTP response"; + } + // Si tiene más espacios, tengo la razón (reason). + pos = line.find_first_of(String::SPACE_CHARS); + if (pos != std::string::npos) { + // Si el resto es un protocolo válido, agrego más variables. + String reas = line.substr(pos + 1).trim(); + line = line.substr(0, pos); + } + line = line.trim(); + // Seteo el código. + if (line.length() != 3) { + // FIXME - poner excepciones lindas. + throw "Invalid response code"; + } + stringstream ss = line; // TODO ver forma mas linda de convertir + ss >> status_code; +} + +std::ostream& operator<<(std::ostream& os, PlaQui::Server::HTTPResponse& req) { +#ifdef DEBUG + std::cerr << __FILE__ << ": operator<<()" << std::endl; +#endif // DEBUG + os << "HTTP/" << version << " " << status_code << " " << reason << "\r\l"; + // TODO ver que este bien el \r\l + os << *(static_cast(this)); +} + -- 2.43.0