]> git.llucax.com Git - z.facultad/75.42/plaqui.git/blob - Server/src/httprequest.cpp
Todavia no compila pero lo subo igual por las dudas.
[z.facultad/75.42/plaqui.git] / Server / src / httprequest.cpp
1 // vim: set noexpandtab tabstop=4 shiftwidth=4:
2 //----------------------------------------------------------------------------
3 //                                  PlaQui
4 //----------------------------------------------------------------------------
5 // This file is part of PlaQui.
6 //
7 // PlaQui is free software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the Free Software
9 // Foundation; either version 2 of the License, or (at your option) any later
10 // version.
11 //
12 // PlaQui is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 // details.
16 //
17 // You should have received a copy of the GNU General Public License along
18 // with PlaQui; if not, write to the Free Software Foundation, Inc., 59 Temple
19 // Place, Suite 330, Boston, MA  02111-1307  USA
20 //----------------------------------------------------------------------------
21 // Creado:  dom oct 26 22:11:03 ART 2003
22 // Autores: Leandro Lucarella <llucare@fi.uba.ar>
23 //----------------------------------------------------------------------------
24 //
25 // $Id$
26 //
27
28 #include "plaqui/server/httprequest.h"
29 #include "plaqui/server/string.h"
30 #ifdef DEBUG
31 #       include <iostream>
32 #endif // DEBUG
33
34 PlaQui::Server::HTTPRequest::~HTTPRequest(void) {
35 #ifdef DEBUG
36         std::cerr << __FILE__ << ": destructor." << std::endl;
37 #endif // DEBUG
38 }
39
40 PlaQui::Server::HTTPRequest::HTTPRequest(const std::string& version):
41                 PlaQui::Server::HTTPMessage(version) {
42 #ifdef DEBUG
43         std::cerr << __FILE__ << ": http_version = " << http_version << std::endl;
44 #endif // DEBUG
45 }
46
47 PlaQui::Server::HTTPRequest::HTTPRequest(const Serializable& body,
48                 const std::string& version):
49                 PlaQui::Server::HTTPMessage(body, version) {
50 #ifdef DEBUG
51         std::cerr << __FILE__ << ": http_version = " << http_version
52                 << " | body = " << body.serialize() << std::endl;
53 #endif // DEBUG
54 }
55
56 PlaQui::Server::HTTPRequest::HTTPRequest(const std::string& uri,
57                 const PlaQui::Server::HTTPRequest::HTTPMethod& method,
58                 std::string& query, std::string& version):
59                 PlaQui::Server::HTTPMessage(body, version) {
60 #ifdef DEBUG
61         std::cerr << __FILE__ << ": http_version = " << http_version
62                 << " | body = " << body.serialize() << std::endl;
63 #endif // DEBUG
64 }
65
66 void PlaQui::Server::HTTPRequest::serialize(std::ostream& os) {
67 #ifdef DEBUG
68         std::cerr << __FILE__ << ": serialize()" << std::endl;
69 #endif // DEBUG
70         os << method << " " << uri;
71         if (query_string.length()) {
72                 os << "?" << query;
73         }
74         os << "HTTP/" << version << "\r\l" << std::flush; // TODO ver que este bien el \r\l
75         HTTPMessage::serilize(os);
76         if (headers.size()) {
77                 headers.serilize(os);
78         }
79         os << "\r\l" << std::flush;
80         if (body.size()) {
81                 body.serilize(os);
82         }
83 }
84
85 void PlaQui::Server::HTTPRequest::unserialize(std::istream& is) {
86         const unsigned BUFFER_SIZE = 4096;
87         char buf[BUFFER_SIZE];
88         // Obtengo primera línea (request)
89         is.getline(buf, BUFFER_SIZE);
90 #ifdef DEBUG
91         std::cerr << "Recibiendo linea: " << buf << std::endl;
92 #endif // DEBUG
93         String line = buf;
94         // Si es la primera línea, es el request.
95         if (line.length() < 3) {
96                 // FIXME - poner excepciones lindas.
97                 throw "HTTP/1.1 501 Method Not Implemented";
98         }
99         // Averiguo método.
100         std::string::size_type pos = line.find_first_of(String::SPACE_CHARS);
101         String met = line.substr(0, pos); 
102         if (met.to_upper() == "GET") {
103                 method = GET;
104         } else if (met.to_upper() == "POST") {
105                 method = POST;
106         } else {
107                 // FIXME - poner excepciones lindas.
108                 throw "HTTP/1.1 501 Method Not Implemented";
109         }
110         // Si tiene sólo el método, no es válido.
111         line = line.substr(pos + 1);
112         iine.trim();
113         if (!line.length()) {
114                 // FIXME - poner excepciones lindas.
115                 throw "HTTP/1.1 400 Bad Request";
116         }
117         // Si tiene más espacios, tengo la URI y el protocolo (o un error).
118         pos = line.find_first_of(String::SPACE_CHARS);
119         if (pos != std::string::npos) {
120                 // Si el resto es un protocolo válido, agrego más variables.
121                 String protocol = line.substr(pos + 1);
122                 protocol = protocol.trim();
123                 if (protocol.to_upper() == "HTTP/1.0") {
124                         version = "1.0";
125                 } else if (protocol.to_upper() == "HTTP/1.1") {
126                         version = "1.1";
127                 // Si no es un error.
128                 } else {
129                         // FIXME - poner excepciones lindas.
130                         throw "HTTP/1.1 400 Bad Request";
131                 }
132                 line = line.substr(0, pos);
133         }
134         // Agrego la URI y sus derivados.
135         if (!line.length() || (line[0] != '/')) {
136                         // FIXME || request.find_first_not_of(";/?:@&=+$,")) {
137                 // FIXME - poner excepciones lindas.
138                 throw "HTTP/1.1 400 Bad Request";
139         }
140         // Si tiene un query string.
141         pos = request.find("?");
142         if (pos != std::string::npos) {
143                 query = line.substr(pos + 1);
144         } else {
145                 query  = "";
146         }
147         uri = line.substr(0, pos);
148         // Fin de request, obtengo cabeceras y cuerpo.
149         HTTPMessage::unserialize(is);
150 }
151