1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
10 Envia una peticion de interseccion sobre HTTP/XML para ihttp_server
12 El cliente de esta aplicacion es: ihttp_server.p => Transporte: http::Transport.
18 #include <anna/core/core.hpp>
19 #include <anna/comm/comm.hpp>
21 #include <anna/app/functions.hpp>
23 #include <anna/xml/DocumentFile.hpp>
24 #include <anna/xml/DocumentMemory.hpp>
26 #include <anna/io/TextReader.hpp>
28 #include <anna/http/Request.hpp>
29 #include <anna/http/Response.hpp>
30 #include <anna/http/Handler.hpp>
31 #include <anna/http/Transport.hpp>
32 #include <anna/http/functions.hpp>
34 class MyHandler : public http::Handler {
36 MyHandler () : http::Handler ("ihttp_client::MyHandler") {;}
39 http::Response a_httpResponse;
41 void evRequest (ClientSocket&, const http::Request&) throw (RuntimeException) {;}
42 void evResponse (ClientSocket&, const http::Response&) throw (RuntimeException);
45 class MyCommunicator : public Communicator {
47 MyCommunicator () : Communicator (), a_httpRequest ()
49 a_httpRequest.setMethod (http::Method::Type::Get);
50 a_httpRequest.setURI ("ihttp_client");
54 MyHandler a_httpHandler;
55 http::Request a_httpRequest;
57 void eventReceiveMessage (ClientSocket &, const Message&) throw (RuntimeException);
58 void eventBreakConnection (Server* server) throw ();
59 void eventStartup () throw (RuntimeException);
62 class IHTTPClient : public anna::comm::Application {
66 Server* getServer () const throw () { return a_server; }
69 MyCommunicator a_communicator;
72 void initialize () throw (RuntimeException);
73 void run () throw (RuntimeException);
78 bool st_xmlResponse (false);
80 int main (int argc, const char** argv)
82 CommandLine& commandLine (CommandLine::instantiate ());
85 http::functions::initialize ();
88 commandLine.initialize (argv, argc);
89 commandLine.verify ();
91 Logger::setLevel (Logger::Debug);
92 Logger::initialize ("ihttp_client", new TraceWriter ("file.trace", 4096000));
96 catch (Exception& ex) {
97 cout << ex.asString () << endl;
103 IHTTPClient::IHTTPClient () :
104 Application ("ihttp_client", "IHTTPClient", "2.0.0")
106 CommandLine& commandLine (CommandLine::instantiate ());
108 commandLine.add ("p", CommandLine::Argument::Mandatory, "Puerto en el que el servidor atiende respuestas.");
109 commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccion IP Puerto en el que el servidor atiende respuestas.");
110 commandLine.add ("xml", CommandLine::Argument::Optional, "Documento XML que contiene la peticion");
111 commandLine.add ("nocheck", CommandLine::Argument::Optional, "Indicador para que no comprueba la validaded del HTML", false);
112 commandLine.add ("version", CommandLine::Argument::Optional, "Indica la version HTTP usada para enviar");
113 commandLine.add ("uri", CommandLine::Argument::Optional, "URI a usar");
114 commandLine.add ("m", CommandLine::Argument::Optional, "Metodo HTTP a usar");
115 commandLine.add ("xmlresponse", CommandLine::Argument::Optional, "Visualiza la respuesta como un documento XML", false);
116 commandLine.add ("overquota", CommandLine::Argument::Optional, "Numero de bytes a recibir sin identificar el protocolo");
117 commandLine.add ("c", CommandLine::Argument::Optional, "Valor de la cookie");
120 void IHTTPClient::initialize ()
121 throw (RuntimeException)
123 CommandLine& cl (CommandLine::instantiate ());
125 Network& network = Network::instantiate ();
127 Host* host = network.find_host ("host000");
128 host->assign (network.find (Device::asAddress (cl.getValue ("a"))));
130 comm::TransportFactory& ttff = http::Transport::getFactory ();
131 if (cl.exists ("overquota") == true)
132 ttff.setOverQuotaSize (cl.getIntegerValue ("overquota"));
134 a_server = host->createServer ("http_server", cl.getIntegerValue ("p"), false, &ttff);
137 void IHTTPClient::run ()
138 throw (RuntimeException)
140 a_communicator.accept ();
143 void MyCommunicator::eventStartup ()
144 throw (RuntimeException)
146 CommandLine& cl (CommandLine::instantiate ());
148 const char* filename = (cl.exists ("xml")) ? cl.getValue ("xml"): NULL;
150 if (filename == NULL) {
151 a_httpRequest.clearBody ();
154 if (cl.exists ("nocheck") == false) {
155 xml::DocumentFile xmlDocument;
156 xmlDocument.initialize (filename);
157 a_httpRequest.setBody (xmlDocument.getContent ());
160 io::TextReader reader;
161 reader.open (filename);
162 DataBlock body (true);
165 while ((line = reader.fetch ()) != NULL)
166 body.append (line, anna_strlen (line));
168 http::Header* header = a_httpRequest.createHeader (http::Header::Type::Connection);
169 header->setValue (" Keep-Alive ");
171 a_httpRequest.setBody (body);
175 if (cl.exists ("version"))
176 a_httpRequest.setVersion (cl.getValue ("version"));
178 if (cl.exists ("uri"))
179 a_httpRequest.setURI (cl.getValue ("uri"));
181 if (cl.exists ("xmlresponse"))
182 st_xmlResponse = true;
184 if (cl.exists ("m")) {
185 http::Method::Type::_v type = http::Method::Type::asEnum (cl.getValue ("m"));
187 if (type == http::Method::Type::None) {
188 string msg ("Metodo HTTP no reconocido. ");
189 msg += http::Method::Type::asList ();
190 throw RuntimeException (msg, ANNA_FILE_LOCATION);
193 a_httpRequest.setMethod (type);
196 if (cl.exists ("c") == true) {
197 http::Header* header = a_httpRequest.createHeader ("Cookie");
198 header->setValue (cl.getValue ("c"));
199 cout << "Con cookie: " << cl.getValue ("c") << " | " << header->asString () << endl << endl;
202 // Header requeridos por la plataforma MovilForum para enviar mensajes WapPush
203 a_httpRequest.createHeader (http::Header::Type::ContentType)->setValue ("text/xml; charset=\"iso-8859-1\"");
204 a_httpRequest.createHeader (http::Header::Type::UserAgent)->setValue ("ANNA.http 1.x");
206 string host = anna::functions::asString ("%s:%d", cl.getValue ("a"), cl.getIntegerValue ("p"));
207 a_httpRequest.createHeader (http::Header::Type::Host)->setValue (host);
208 a_httpRequest.createHeader (http::Header::Type::Authorization)->setValue (" Basic VGlkTGNtOlQxZExjbQ==");
210 static_cast <IHTTPClient&> (anna::comm::functions::getApp ()).getServer ()->send (a_httpRequest);
213 void MyCommunicator::eventReceiveMessage (ClientSocket& clientSocket, const Message& message)
214 throw (RuntimeException)
216 LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
218 if (clientSocket.support (http::Transport::className ()) == false)
221 a_httpHandler.apply (clientSocket, message);
224 void MyCommunicator::eventBreakConnection (Server* server)
227 cout << "Perdida conexion con " << server->asString () << endl;
231 void MyHandler::evResponse (ClientSocket& clientSocket, const http::Response& response)
232 throw (RuntimeException)
234 const DataBlock& body = response.getBody ();
236 cout << "HTTP StatusCode: " << response.getStatusCode () << endl;
237 cout << "HTTP Text: " << response.getReasonPhrase () << endl;
239 if (st_xmlResponse == false)
240 cout << "Resultado: \n" << anna::functions::asString (body, 24) << endl << endl;
243 xml::DocumentMemory xmlDoc;
244 xmlDoc.initialize (response.getBody ());
245 cout << xmlDoc.getContentAsCString () << endl << endl;
247 catch (RuntimeException& ex) {
252 app::functions::component <Communicator> (ANNA_FILE_LOCATION)->requestStop ();