Remove warnings
[anna.git] / example / http / echo / 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 #include <iostream>
10
11 #include <anna/core/core.hpp>
12 #include <anna/comm/comm.hpp>
13
14 #include <anna/http/Request.hpp>
15 #include <anna/http/Response.hpp>
16 #include <anna/http/Handler.hpp>
17 #include <anna/http/Transport.hpp>
18 #include <anna/http/functions.hpp>
19 #include <anna/http/internal/sccs.hpp>
20 #include <anna/core/internal/sccs.hpp>
21
22 anna_import_sccs_tag (http);
23
24 using namespace std;
25
26 class MyHandler : public http::Handler {
27 public:
28    MyHandler () : http::Handler ("http_echo::MyHandler") { 
29       a_httpResponse.createHeader (http::Header::Type::Date); 
30       a_httpResponse.createHeader (http::Header::Type::Server)->setValue (anna_use_sccs_tag (http));
31    }
32
33    void setNotSend (const bool notSend) throw () { a_notSend = notSend; }
34
35 private:
36    http::Response a_httpResponse;
37    bool a_notSend;
38
39    void evRequest (ClientSocket&, const http::Request& request) throw (RuntimeException);
40    void evResponse (ClientSocket&, const http::Response&) throw (RuntimeException) {;}
41 };
42
43 class MyCommunicator : public comm::Communicator {
44 public:
45    MyCommunicator () {;}
46
47    void setNotSend (const bool notSend) throw () { a_httpHandler.setNotSend (notSend); }
48
49 private:
50    MyHandler a_httpHandler;
51
52    void eventReceiveMessage (comm::ClientSocket &, const Message& message)
53       throw (RuntimeException);
54 };
55
56 class HTTPArithmeticServer : public comm::Application {
57 public:
58    HTTPArithmeticServer ();
59       
60 private:
61    MyCommunicator a_communicator;
62    comm::ServerSocket* a_serverSocket;
63
64    void initialize () throw (RuntimeException);
65    void run () throw (RuntimeException);
66 };
67
68 using namespace std;
69 using namespace anna::comm;
70
71 int main (int argc, const char** argv)
72 {
73    CommandLine& commandLine (CommandLine::instantiate ());
74    HTTPArithmeticServer app;
75
76    http::functions::initialize ();
77
78    srand (time (NULL));
79
80    try {
81       commandLine.initialize (argv, argc);
82       commandLine.verify ();
83
84       Logger::setLevel (Logger::Debug); 
85       Logger::initialize ("http_echo", new anna::TraceWriter ("file.trace", 4048000));
86  
87       app.start ();
88    }
89    catch (Exception& ex) {
90       cout << ex.asString () << endl;
91    }
92    
93    return 0;
94 }
95
96 HTTPArithmeticServer::HTTPArithmeticServer () : 
97    Application ("http_echo", "Servidor de echo", "1.0") 
98 {
99    CommandLine& commandLine (CommandLine::instantiate ());
100       
101    commandLine.add ("p", CommandLine::Argument::Mandatory, "Puerto en el que atender peticiones");
102    commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccin IP en la que atender");
103    commandLine.add ("r", CommandLine::Argument::Optional, "Indicador de reuso de direccin", false);
104    commandLine.add ("notsend", CommandLine::Argument::Optional, "Indicador de no responder al mensaje", false);
105 }
106
107 void HTTPArithmeticServer::initialize () 
108    throw (RuntimeException)
109 {
110    CommandLine& cl (CommandLine::instantiate ());
111
112    int port = cl.getIntegerValue ("p");
113    const comm::Device* device = Network::instantiate ().find (Device::asAddress (cl.getValue ("a")));
114
115    a_serverSocket = new ServerSocket (INetAddress (device, port), cl.exists ("r"), &http::Transport::getFactory ());
116
117    a_communicator.setNotSend (cl.exists ("notsend"));
118 }
119
120 void HTTPArithmeticServer::run ()
121    throw (RuntimeException)
122 {
123    a_communicator.attach (a_serverSocket);
124    a_communicator.accept ();
125 }
126
127 void MyCommunicator::eventReceiveMessage (ClientSocket& clientSocket, const Message& message)
128    throw (RuntimeException)
129 {
130    LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
131
132    if (clientSocket.support (http::Transport::className ()) == false)
133       return;
134
135    static int messageCounter = 0;
136    static int successCounter = 0;
137
138    CongestionController& congestionController = CongestionController::instantiate ();
139
140    messageCounter ++;
141
142    if (congestionController.getAdvice (clientSocket) == CongestionController::Advice::Discard)
143       return;
144
145    successCounter ++;
146
147    a_httpHandler.apply (clientSocket, message);
148 }
149
150 void MyHandler::evRequest (ClientSocket& clientSocket, const http::Request& request)
151    throw (RuntimeException)
152 {
153    const DataBlock& body = request.getBody ();
154
155    LOGINFORMATION (
156       string msg ("Body recibido: ");
157       msg += anna::functions::asString (body);
158       Logger::information (msg, ANNA_FILE_LOCATION);
159    );
160
161    LOGINFORMATION (
162       const http::Header* header;
163       string msg;
164
165       for (http::Request::const_header_iterator ii = request.header_begin (), maxii = request.header_end (); ii != maxii; ii ++) {
166          header = http::Request::header (ii);
167          Logger::information (header->asString (), ANNA_FILE_LOCATION);
168       }
169
170       if ((header = request.find (http::Header::Type::Connection)) != NULL) {
171          if (header->match ("keep-alive", http::Header::Compare::FullMode))
172             Logger::information ("Keep Alive activado en la conexion", ANNA_FILE_LOCATION);
173          else
174             Logger::information ("Keep Alive NO activado en la conexion", ANNA_FILE_LOCATION);
175       }
176    );
177
178    if (a_notSend == true)
179       return;
180
181    a_httpResponse.clearBody ();
182    a_httpResponse.find (http::Header::Type::Date)->setValue ("Mon, 30 Jan 2006 14:36:18 GMT");
183
184    http::Header* userData = a_httpResponse.find ("UserData");
185  
186    if (userData == NULL)
187       userData = a_httpResponse.createHeader ("UserData");
188
189    userData->setValue ("Verificacio del cambio 1.0.7");
190    a_httpResponse.setBody (body);
191
192    try {
193       clientSocket.send (a_httpResponse);
194    }
195    catch (Exception& ex) {
196       ex.trace ();
197    }
198 }
199