X-Git-Url: https://git.llucax.com/z.facultad/75.42/plaqui.git/blobdiff_plain/b92547a5de3a3fb4f14a2bea4a4e776b8da3cb5c..dafb509182bac9b314202fe7dfaf58206da5ccbe:/Server/src/httprequest.cpp diff --git a/Server/src/httprequest.cpp b/Server/src/httprequest.cpp index 2fb8661..1da38a7 100644 --- a/Server/src/httprequest.cpp +++ b/Server/src/httprequest.cpp @@ -39,98 +39,100 @@ namespace Server { HTTPRequest::~HTTPRequest(void) { #ifdef DEBUG - cerr << __FILE__ << ": destructor." << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": destructor." << endl; #endif // DEBUG } -HTTPRequest::HTTPRequest(const string& uri, const HTTPMethod& method, - const string& query, const string& version): - HTTPMessage(version), method(method), uri(uri), query(query) { +HTTPRequest::HTTPRequest(const string& uri, const HTTPMethod& method, + const string& query, const string& body, const string& version): + HTTPMessage(body, version), method(method), uri(uri), query(query) { #ifdef DEBUG - cerr << __FILE__ << ": uri = " << uri << " | " - << "method = " << ((method == GET) ? "GET" : "POST") << " | " + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": uri = " << uri << " | " + << "method = " << method_str() << " | " << "query = " << query << " | " + << "body.length = " << body.length() << " | " << "version = " << version << endl; #endif // DEBUG } -/* -HTTPRequest::HTTPRequest(const Serializable& body, - const string& version): - HTTPMessage(body, version) { -#ifdef DEBUG - cerr << __FILE__ << ": http_version = " << http_version - << " | body = " << body.serialize() << endl; -#endif // DEBUG -} - -HTTPRequest::HTTPRequest(const string& uri, - const HTTPRequest::HTTPMethod& method, - string& query, string& version): - HTTPMessage(body, version) { -#ifdef DEBUG - cerr << __FILE__ << ": http_version = " << http_version - << " | body = " << body.serialize() << endl; -#endif // DEBUG +string HTTPRequest::method_str(void) const { + switch (method) { + case POST: + return "POST"; + case GET: + default: + return "GET"; + } } -*/ -istream& operator>>(istream& is, HTTPRequest& req) { +istream& operator>>(istream& is, HTTPRequest& req) + throw(HTTPError, sockerr, ios::failure) { #ifdef DEBUG - cerr << __FILE__ << ": operator>>()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": operator>>()" << endl; #endif // DEBUG char buf[BUFSIZ]; // Obtengo primera línea (request) - is.getline(buf, BUFSIZ); + if (!is.getline(buf, BUFSIZ)) { + // Fin de archivo. + throw ios::failure("eof"); + } #ifdef DEBUG - cerr << "Recibiendo linea: " << buf << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ":\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("?"); @@ -146,16 +148,17 @@ istream& operator>>(istream& is, HTTPRequest& req) { return is; } -ostream& operator<<(ostream& os, const HTTPRequest& req) { +ostream& operator<<(ostream& os, const HTTPRequest& req) throw(sockerr) { #ifdef DEBUG - cerr << __FILE__ << ": operator<<()" << endl; + cerr << __FILE__ << "(" << __LINE__ << ")" + << ": operator<<()" << endl; #endif // DEBUG - os << req.method << " " << req.uri; + os << req.method_str() << " " << req.uri; if (req.query.length()) { os << "?" << req.query; } - // TODO ver que este bien el \r\l - os << " HTTP/" << req.version << "\r\n" << static_cast(req); + os << " HTTP/" << req.version << "\r\n" + << static_cast(req); return os; }