1 // ANNA - Anna is Not 'N' Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // https://bitbucket.org/testillano/anna
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
38 Envia una peticion de interseccion sobre HTTP/XML para ihttp_server
40 El cliente de esta aplicacion es: ihttp_server.p => Transporte: http::Transport.
46 #include <anna/core/core.hpp>
47 #include <anna/comm/comm.hpp>
49 #include <anna/app/functions.hpp>
51 #include <anna/xml/DocumentFile.hpp>
52 #include <anna/xml/DocumentMemory.hpp>
54 #include <anna/io/TextReader.hpp>
56 #include <anna/http/Request.hpp>
57 #include <anna/http/Response.hpp>
58 #include <anna/http/Handler.hpp>
59 #include <anna/http/Transport.hpp>
60 #include <anna/http/functions.hpp>
62 class MyHandler : public http::Handler {
64 MyHandler () : http::Handler ("ihttp_client::MyHandler") {;}
67 http::Response a_httpResponse;
69 void evRequest (ClientSocket&, const http::Request&) throw (RuntimeException) {;}
70 void evResponse (ClientSocket&, const http::Response&) throw (RuntimeException);
73 class MyCommunicator : public Communicator {
75 MyCommunicator () : Communicator (), a_httpRequest ()
77 a_httpRequest.setMethod (http::Method::Type::Get);
78 a_httpRequest.setURI ("ihttp_client");
82 MyHandler a_httpHandler;
83 http::Request a_httpRequest;
85 void eventReceiveMessage (ClientSocket &, const Message&) throw (RuntimeException);
86 void eventBreakConnection (Server* server) throw ();
87 void eventStartup () throw (RuntimeException);
90 class IHTTPClient : public anna::comm::Application {
94 Server* getServer () const throw () { return a_server; }
97 MyCommunicator a_communicator;
100 void initialize () throw (RuntimeException);
101 void run () throw (RuntimeException);
106 bool st_xmlResponse (false);
108 int main (int argc, const char** argv)
110 CommandLine& commandLine (CommandLine::instantiate ());
113 http::functions::initialize ();
116 commandLine.initialize (argv, argc);
117 commandLine.verify ();
119 Logger::setLevel (Logger::Debug);
120 Logger::initialize ("ihttp_client", new TraceWriter ("file.trace", 4096000));
124 catch (Exception& ex) {
125 cout << ex.asString () << endl;
131 IHTTPClient::IHTTPClient () :
132 Application ("ihttp_client", "IHTTPClient", "2.0.0")
134 CommandLine& commandLine (CommandLine::instantiate ());
136 commandLine.add ("p", CommandLine::Argument::Mandatory, "Puerto en el que el servidor atiende respuestas.");
137 commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccin IP Puerto en el que el servidor atiende respuestas.");
138 commandLine.add ("xml", CommandLine::Argument::Optional, "Documento XML que contiene la peticion");
139 commandLine.add ("nocheck", CommandLine::Argument::Optional, "Indicador para que no comprueba la validaded del HTML", false);
140 commandLine.add ("version", CommandLine::Argument::Optional, "Indica la version HTTP usada para enviar");
141 commandLine.add ("uri", CommandLine::Argument::Optional, "URI a usar");
142 commandLine.add ("m", CommandLine::Argument::Optional, "Método HTTP a usar");
143 commandLine.add ("xmlresponse", CommandLine::Argument::Optional, "Visualiza la respuesta como un documento XML", false);
144 commandLine.add ("overquota", CommandLine::Argument::Optional, "Nº de bytes a recibir sin identificar el protocolo");
145 commandLine.add ("c", CommandLine::Argument::Optional, "Valor de la cookie");
148 void IHTTPClient::initialize ()
149 throw (RuntimeException)
151 CommandLine& cl (CommandLine::instantiate ());
153 Network& network = Network::instantiate ();
155 Host* host = network.find_host ("host000");
156 host->assign (network.find (Device::asAddress (cl.getValue ("a"))));
158 comm::TransportFactory& ttff = http::Transport::getFactory ();
159 if (cl.exists ("overquota") == true)
160 ttff.setOverQuotaSize (cl.getIntegerValue ("overquota"));
162 a_server = host->createServer ("http_server", cl.getIntegerValue ("p"), false, &ttff);
165 void IHTTPClient::run ()
166 throw (RuntimeException)
168 a_communicator.accept ();
171 void MyCommunicator::eventStartup ()
172 throw (RuntimeException)
174 CommandLine& cl (CommandLine::instantiate ());
176 const char* filename = (cl.exists ("xml")) ? cl.getValue ("xml"): NULL;
178 if (filename == NULL) {
179 a_httpRequest.clearBody ();
182 if (cl.exists ("nocheck") == false) {
183 xml::DocumentFile xmlDocument;
184 xmlDocument.initialize (filename);
185 a_httpRequest.setBody (xmlDocument.getContent ());
188 io::TextReader reader;
189 reader.open (filename);
190 DataBlock body (true);
193 while ((line = reader.fetch ()) != NULL)
194 body.append (line, anna_strlen (line));
196 http::Header* header = a_httpRequest.createHeader (http::Header::Type::Connection);
197 header->setValue (" Keep-Alive ");
199 a_httpRequest.setBody (body);
203 if (cl.exists ("version"))
204 a_httpRequest.setVersion (cl.getValue ("version"));
206 if (cl.exists ("uri"))
207 a_httpRequest.setURI (cl.getValue ("uri"));
209 if (cl.exists ("xmlresponse"))
210 st_xmlResponse = true;
212 if (cl.exists ("m")) {
213 http::Method::Type::_v type = http::Method::Type::asEnum (cl.getValue ("m"));
215 if (type == http::Method::Type::None) {
216 string msg ("Método HTTP no reconocido. ");
217 msg += http::Method::Type::asList ();
218 throw RuntimeException (msg, ANNA_FILE_LOCATION);
221 a_httpRequest.setMethod (type);
224 if (cl.exists ("c") == true) {
225 http::Header* header = a_httpRequest.createHeader ("Cookie");
226 header->setValue (cl.getValue ("c"));
227 cout << "Con cookie: " << cl.getValue ("c") << " | " << header->asString () << endl << endl;
230 // Header requeridos por la plataforma MovilForum para enviar mensajes WapPush
231 a_httpRequest.createHeader (http::Header::Type::ContentType)->setValue ("text/xml; charset=\"iso-8859-1\"");
232 a_httpRequest.createHeader (http::Header::Type::UserAgent)->setValue ("ANNA.http 1.x");
234 string host = anna::functions::asString ("%s:%d", cl.getValue ("a"), cl.getIntegerValue ("p"));
235 a_httpRequest.createHeader (http::Header::Type::Host)->setValue (host);
236 a_httpRequest.createHeader (http::Header::Type::Authorization)->setValue (" Basic VGlkTGNtOlQxZExjbQ==");
238 static_cast <IHTTPClient&> (anna::comm::functions::getApp ()).getServer ()->send (a_httpRequest);
241 void MyCommunicator::eventReceiveMessage (ClientSocket& clientSocket, const Message& message)
242 throw (RuntimeException)
244 LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
246 if (clientSocket.support (http::Transport::className ()) == false)
249 a_httpHandler.apply (clientSocket, message);
252 void MyCommunicator::eventBreakConnection (Server* server)
255 cout << "Perdida conexión con " << server->asString () << endl;
259 void MyHandler::evResponse (ClientSocket& clientSocket, const http::Response& response)
260 throw (RuntimeException)
262 const DataBlock& body = response.getBody ();
264 cout << "HTTP StatusCode: " << response.getStatusCode () << endl;
265 cout << "HTTP Text: " << response.getReasonPhrase () << endl;
267 if (st_xmlResponse == false)
268 cout << "Resultado: \n" << anna::functions::asString (body, 24) << endl << endl;
271 xml::DocumentMemory xmlDoc;
272 xmlDoc.initialize (response.getBody ());
273 cout << xmlDoc.getContentAsCString () << endl << endl;
275 catch (RuntimeException& ex) {
280 app::functions::component <Communicator> (ANNA_FILE_LOCATION)->requestStop ();