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 //
11 #include <anna/core/core.hpp>
12 #include <anna/comm/comm.hpp>
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>
22 anna_import_sccs_tag (http);
26 class MyHandler : public http::Handler {
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));
33 void setNotSend (const bool notSend) throw () { a_notSend = notSend; }
36 http::Response a_httpResponse;
39 void evRequest (ClientSocket&, const http::Request& request) throw (RuntimeException);
40 void evResponse (ClientSocket&, const http::Response&) throw (RuntimeException) {;}
43 class MyCommunicator : public comm::Communicator {
47 void setNotSend (const bool notSend) throw () { a_httpHandler.setNotSend (notSend); }
50 MyHandler a_httpHandler;
52 void eventReceiveMessage (comm::ClientSocket &, const Message& message)
53 throw (RuntimeException);
56 class HTTPArithmeticServer : public comm::Application {
58 HTTPArithmeticServer ();
61 MyCommunicator a_communicator;
62 comm::ServerSocket* a_serverSocket;
64 void initialize () throw (RuntimeException);
65 void run () throw (RuntimeException);
69 using namespace anna::comm;
71 int main (int argc, const char** argv)
73 CommandLine& commandLine (CommandLine::instantiate ());
74 HTTPArithmeticServer app;
76 http::functions::initialize ();
81 commandLine.initialize (argv, argc);
82 commandLine.verify ();
84 Logger::setLevel (Logger::Debug);
85 Logger::initialize ("http_echo", new anna::TraceWriter ("file.trace", 4048000));
89 catch (Exception& ex) {
90 cout << ex.asString () << endl;
96 HTTPArithmeticServer::HTTPArithmeticServer () :
97 Application ("http_echo", "Servidor de echo", "1.0")
99 CommandLine& commandLine (CommandLine::instantiate ());
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);
107 void HTTPArithmeticServer::initialize ()
108 throw (RuntimeException)
110 CommandLine& cl (CommandLine::instantiate ());
112 int port = cl.getIntegerValue ("p");
113 const comm::Device* device = Network::instantiate ().find (Device::asAddress (cl.getValue ("a")));
115 a_serverSocket = new ServerSocket (INetAddress (device, port), cl.exists ("r"), &http::Transport::getFactory ());
117 a_communicator.setNotSend (cl.exists ("notsend"));
120 void HTTPArithmeticServer::run ()
121 throw (RuntimeException)
123 a_communicator.attach (a_serverSocket);
124 a_communicator.accept ();
127 void MyCommunicator::eventReceiveMessage (ClientSocket& clientSocket, const Message& message)
128 throw (RuntimeException)
130 LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
132 if (clientSocket.support (http::Transport::className ()) == false)
135 static int messageCounter = 0;
136 static int successCounter = 0;
138 CongestionController& congestionController = CongestionController::instantiate ();
142 if (congestionController.getAdvice (clientSocket) == CongestionController::Advice::Discard)
147 a_httpHandler.apply (clientSocket, message);
150 void MyHandler::evRequest (ClientSocket& clientSocket, const http::Request& request)
151 throw (RuntimeException)
153 const DataBlock& body = request.getBody ();
156 string msg ("Body recibido: ");
157 msg += anna::functions::asString (body);
158 Logger::information (msg, ANNA_FILE_LOCATION);
162 const http::Header* header;
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);
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);
174 Logger::information ("Keep Alive NO activado en la conexion", ANNA_FILE_LOCATION);
178 if (a_notSend == true)
181 a_httpResponse.clearBody ();
182 a_httpResponse.find (http::Header::Type::Date)->setValue ("Mon, 30 Jan 2006 14:36:18 GMT");
184 http::Header* userData = a_httpResponse.find ("UserData");
186 if (userData == NULL)
187 userData = a_httpResponse.createHeader ("UserData");
189 userData->setValue ("Verificacio del cambio 1.0.7");
190 a_httpResponse.setBody (body);
193 clientSocket.send (a_httpResponse);
195 catch (Exception& ex) {