]> git.llucax.com Git - z.facultad/75.42/plaqui.git/blobdiff - Server/src/httprequest.cpp
* Se agrega el TIP de luca
[z.facultad/75.42/plaqui.git] / Server / src / httprequest.cpp
index 2fb866158d3e2fc49157e102e9c4e7fd3985565c..1da38a7404bcd69bfb3d15daad2ce11d4973871d 100644 (file)
@@ -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<const HTTPMessage&>(req);
+       os << " HTTP/" << req.version << "\r\n"
+               << static_cast<const HTTPMessage&>(req);
        return os;
 }