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 using Communicator::eventBreakConnection;
56 MyHandler a_httpHandler;
57 http::Request a_httpRequest;
59 void eventReceiveMessage (ClientSocket &, const Message&) throw (RuntimeException);
60 void eventBreakConnection (Server* server) throw ();
61 void eventStartup () throw (RuntimeException);
64 class IHTTPClient : public anna::comm::Application {
68 Server* getServer () const throw () { return a_server; }
71 MyCommunicator a_communicator;
74 void initialize () throw (RuntimeException);
75 void run () throw (RuntimeException);
80 bool st_xmlResponse (false);
82 int main (int argc, const char** argv)
84 CommandLine& commandLine (CommandLine::instantiate ());
87 http::functions::initialize ();
90 commandLine.initialize (argv, argc);
91 commandLine.verify ();
93 Logger::setLevel (Logger::Debug);
94 Logger::initialize ("ihttp_client", new TraceWriter ("file.trace", 4096000));
98 catch (Exception& ex) {
99 cout << ex.asString () << endl;
105 IHTTPClient::IHTTPClient () :
106 Application ("ihttp_client", "IHTTPClient", "2.0.0")
108 CommandLine& commandLine (CommandLine::instantiate ());
110 commandLine.add ("p", CommandLine::Argument::Mandatory, "Puerto en el que el servidor atiende respuestas.");
111 commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccion IP Puerto en el que el servidor atiende respuestas.");
112 commandLine.add ("xml", CommandLine::Argument::Optional, "Documento XML que contiene la peticion");
113 commandLine.add ("nocheck", CommandLine::Argument::Optional, "Indicador para que no comprueba la validaded del HTML", false);
114 commandLine.add ("version", CommandLine::Argument::Optional, "Indica la version HTTP usada para enviar");
115 commandLine.add ("uri", CommandLine::Argument::Optional, "URI a usar");
116 commandLine.add ("m", CommandLine::Argument::Optional, "Metodo HTTP a usar");
117 commandLine.add ("xmlresponse", CommandLine::Argument::Optional, "Visualiza la respuesta como un documento XML", false);
118 commandLine.add ("overquota", CommandLine::Argument::Optional, "Numero de bytes a recibir sin identificar el protocolo");
119 commandLine.add ("c", CommandLine::Argument::Optional, "Valor de la cookie");
122 void IHTTPClient::initialize ()
123 throw (RuntimeException)
125 CommandLine& cl (CommandLine::instantiate ());
127 Network& network = Network::instantiate ();
129 Host* host = network.find_host ("host000");
130 host->assign (network.find (Device::asAddress (cl.getValue ("a"))));
132 comm::TransportFactory& ttff = http::Transport::getFactory ();
133 if (cl.exists ("overquota") == true)
134 ttff.setOverQuotaSize (cl.getIntegerValue ("overquota"));
136 a_server = host->createServer ("http_server", cl.getIntegerValue ("p"), false, &ttff);
139 void IHTTPClient::run ()
140 throw (RuntimeException)
142 a_communicator.accept ();
145 void MyCommunicator::eventStartup ()
146 throw (RuntimeException)
148 CommandLine& cl (CommandLine::instantiate ());
150 const char* filename = (cl.exists ("xml")) ? cl.getValue ("xml"): NULL;
152 if (filename == NULL) {
153 a_httpRequest.clearBody ();
156 if (cl.exists ("nocheck") == false) {
157 xml::DocumentFile xmlDocument;
158 xmlDocument.initialize (filename);
159 a_httpRequest.setBody (xmlDocument.getContent ());
162 io::TextReader reader;
163 reader.open (filename);
164 DataBlock body (true);
167 while ((line = reader.fetch ()) != NULL)
168 body.append (line, anna_strlen (line));
170 http::Header* header = a_httpRequest.createHeader (http::Header::Type::Connection);
171 header->setValue (" Keep-Alive ");
173 a_httpRequest.setBody (body);
177 if (cl.exists ("version"))
178 a_httpRequest.setVersion (cl.getValue ("version"));
180 if (cl.exists ("uri"))
181 a_httpRequest.setURI (cl.getValue ("uri"));
183 if (cl.exists ("xmlresponse"))
184 st_xmlResponse = true;
186 if (cl.exists ("m")) {
187 http::Method::Type::_v type = http::Method::Type::asEnum (cl.getValue ("m"));
189 if (type == http::Method::Type::None) {
190 string msg ("Metodo HTTP no reconocido. ");
191 msg += http::Method::Type::asList ();
192 throw RuntimeException (msg, ANNA_FILE_LOCATION);
195 a_httpRequest.setMethod (type);
198 if (cl.exists ("c") == true) {
199 http::Header* header = a_httpRequest.createHeader ("Cookie");
200 header->setValue (cl.getValue ("c"));
201 cout << "Con cookie: " << cl.getValue ("c") << " | " << header->asString () << endl << endl;
204 // Header requeridos por la plataforma MovilForum para enviar mensajes WapPush
205 a_httpRequest.createHeader (http::Header::Type::ContentType)->setValue ("text/xml; charset=\"iso-8859-1\"");
206 a_httpRequest.createHeader (http::Header::Type::UserAgent)->setValue ("ANNA.http 1.x");
208 string host = anna::functions::asString ("%s:%d", cl.getValue ("a"), cl.getIntegerValue ("p"));
209 a_httpRequest.createHeader (http::Header::Type::Host)->setValue (host);
210 a_httpRequest.createHeader (http::Header::Type::Authorization)->setValue (" Basic VGlkTGNtOlQxZExjbQ==");
212 static_cast <IHTTPClient&> (anna::comm::functions::getApp ()).getServer ()->send (a_httpRequest);
215 void MyCommunicator::eventReceiveMessage (ClientSocket& clientSocket, const Message& message)
216 throw (RuntimeException)
218 LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
220 if (clientSocket.support (http::Transport::className ()) == false)
223 a_httpHandler.apply (clientSocket, message);
226 void MyCommunicator::eventBreakConnection (Server* server)
229 cout << "Perdida conexion con " << server->asString () << endl;
233 void MyHandler::evResponse (ClientSocket& clientSocket, const http::Response& response)
234 throw (RuntimeException)
236 const DataBlock& body = response.getBody ();
238 cout << "HTTP StatusCode: " << response.getStatusCode () << endl;
239 cout << "HTTP Text: " << response.getReasonPhrase () << endl;
241 if (st_xmlResponse == false)
242 cout << "Resultado: \n" << anna::functions::asString (body, 24) << endl << endl;
245 xml::DocumentMemory xmlDoc;
246 xmlDoc.initialize (response.getBody ());
247 cout << xmlDoc.getContentAsCString () << endl << endl;
249 catch (RuntimeException& ex) {
254 app::functions::component <Communicator> (ANNA_FILE_LOCATION)->requestStop ();