Remove warnings
[anna.git] / example / http / xmlSender / main.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
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 //
7
8
9 /*
10    Envia una peticion de interseccion sobre HTTP/XML para ihttp_server
11
12    El cliente de esta aplicacion es: ihttp_server.p => Transporte: http::Transport.
13 */
14 #include <iostream>
15
16 #include <string.h>
17
18 #include <anna/core/core.hpp>
19 #include <anna/comm/comm.hpp>
20
21 #include <anna/app/functions.hpp>
22
23 #include <anna/xml/DocumentFile.hpp>
24 #include <anna/xml/DocumentMemory.hpp>
25
26 #include <anna/io/TextReader.hpp>
27
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>
33
34 class MyHandler : public http::Handler {
35 public:
36    MyHandler () : http::Handler ("ihttp_client::MyHandler") {;}
37
38 private:
39    http::Response a_httpResponse;
40
41    void evRequest (ClientSocket&, const http::Request&) throw (RuntimeException) {;}
42    void evResponse (ClientSocket&, const http::Response&) throw (RuntimeException);
43 };
44
45 class MyCommunicator : public Communicator {
46 public:
47    MyCommunicator () : Communicator (), a_httpRequest ()
48    {
49       a_httpRequest.setMethod (http::Method::Type::Get);
50       a_httpRequest.setURI ("ihttp_client");
51    }
52
53 private:
54    using Communicator::eventBreakConnection;
55
56    MyHandler a_httpHandler;
57    http::Request a_httpRequest;
58
59    void eventReceiveMessage (ClientSocket &, const Message&) throw (RuntimeException);
60    void eventBreakConnection (Server* server) throw ();
61    void eventStartup () throw (RuntimeException);
62 };
63
64 class IHTTPClient : public anna::comm::Application {
65 public:
66    IHTTPClient ();
67
68    Server* getServer () const throw () { return a_server; }
69
70 private:
71    MyCommunicator a_communicator;
72    Server* a_server;
73
74    void initialize () throw (RuntimeException);
75    void run () throw (RuntimeException);
76 };
77
78 using namespace std;
79
80 bool st_xmlResponse (false);
81
82 int main (int argc, const char** argv)
83 {
84    CommandLine& commandLine (CommandLine::instantiate ());
85    IHTTPClient app;
86
87    http::functions::initialize ();
88
89    try {
90       commandLine.initialize (argv, argc);
91       commandLine.verify ();
92
93       Logger::setLevel (Logger::Debug);
94       Logger::initialize ("ihttp_client", new TraceWriter ("file.trace", 4096000));
95
96       app.start ();
97    }
98    catch (Exception& ex) {
99       cout << ex.asString () << endl;
100    }
101
102    return 0;
103 }
104
105 IHTTPClient::IHTTPClient () :
106    Application ("ihttp_client", "IHTTPClient", "2.0.0")
107 {
108    CommandLine& commandLine (CommandLine::instantiate ());
109
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");
120 }
121
122 void IHTTPClient::initialize () 
123    throw (RuntimeException)
124 {
125    CommandLine& cl (CommandLine::instantiate ());
126
127    Network& network = Network::instantiate ();
128
129    Host* host = network.find_host ("host000");
130    host->assign (network.find (Device::asAddress (cl.getValue ("a"))));
131
132    comm::TransportFactory& ttff = http::Transport::getFactory ();
133    if (cl.exists ("overquota") == true) 
134       ttff.setOverQuotaSize (cl.getIntegerValue ("overquota"));
135
136    a_server = host->createServer ("http_server", cl.getIntegerValue ("p"), false, &ttff);
137 }
138
139 void IHTTPClient::run ()
140    throw (RuntimeException)
141 {
142    a_communicator.accept ();
143 }
144
145 void MyCommunicator::eventStartup ()
146    throw (RuntimeException)
147 {
148    CommandLine& cl (CommandLine::instantiate ());
149
150    const char* filename = (cl.exists ("xml")) ? cl.getValue ("xml"): NULL;
151
152    if (filename == NULL) {
153       a_httpRequest.clearBody ();
154    }
155    else {
156       if (cl.exists ("nocheck") == false) {
157          xml::DocumentFile xmlDocument;
158          xmlDocument.initialize (filename);
159          a_httpRequest.setBody (xmlDocument.getContent ());
160       }
161       else {
162          io::TextReader reader;
163          reader.open (filename);
164          DataBlock body (true);
165          const char* line;
166    
167          while ((line = reader.fetch ()) != NULL)
168             body.append (line, anna_strlen (line));
169    
170          http::Header* header = a_httpRequest.createHeader (http::Header::Type::Connection);
171          header->setValue ("   Keep-Alive    ");
172    
173          a_httpRequest.setBody (body);
174       }
175    }
176
177    if (cl.exists ("version"))
178       a_httpRequest.setVersion (cl.getValue ("version"));
179
180    if (cl.exists ("uri"))
181       a_httpRequest.setURI (cl.getValue ("uri"));
182
183    if (cl.exists ("xmlresponse"))
184       st_xmlResponse = true;
185
186    if (cl.exists ("m")) {
187       http::Method::Type::_v type = http::Method::Type::asEnum (cl.getValue ("m"));
188
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);
193       }
194
195       a_httpRequest.setMethod (type);
196    }
197
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;
202    }
203
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");
207
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==");
211    
212    static_cast <IHTTPClient&> (anna::comm::functions::getApp ()).getServer ()->send (a_httpRequest);
213 }
214
215 void MyCommunicator::eventReceiveMessage (ClientSocket& clientSocket, const Message& message)
216    throw (RuntimeException)
217 {
218    LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
219
220    if (clientSocket.support (http::Transport::className ()) == false)
221       return;
222
223    a_httpHandler.apply (clientSocket, message);
224 }
225
226 void MyCommunicator::eventBreakConnection (Server* server) 
227    throw ()
228 {
229    cout << "Perdida conexion con " << server->asString () << endl;
230    requestStop ();
231 }
232
233 void MyHandler::evResponse (ClientSocket& clientSocket, const http::Response& response)
234    throw (RuntimeException)
235 {
236    const DataBlock& body = response.getBody ();
237    
238    cout << "HTTP StatusCode: " << response.getStatusCode () << endl;
239    cout << "HTTP Text: " << response.getReasonPhrase () << endl;
240
241    if (st_xmlResponse == false)
242       cout << "Resultado: \n" << anna::functions::asString (body, 24) << endl << endl;
243    else {
244       try {
245          xml::DocumentMemory xmlDoc;
246          xmlDoc.initialize (response.getBody ());
247          cout << xmlDoc.getContentAsCString () << endl << endl;
248       }
249       catch (RuntimeException& ex) {
250          ex.trace ();
251       }
252    }
253
254    app::functions::component <Communicator> (ANNA_FILE_LOCATION)->requestStop ();
255 }
256