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/tracing/Logger.hpp>
13 #include <anna/http/Request.hpp>
15 #include <anna/http/wims20/ServerSide.hpp>
21 * (1) Si estamos esperando http://xxx/zzzz hay que verificar que no vamos a dar por buena una
22 * expresión con la forma: http://xxx/zzzzAAAAAA, p.e.
24 void http::wims20::ServerSide::decode(const http::Request& request)
25 throw(RuntimeException) {
27 const string& uri = request.getURI();
28 // Calcula la parte corta que hemos definido para el servicio
29 const string& shortFixedPart = Abstract::calculeShortFixedPart();
30 const int fixedLen = shortFixedPart.length();
33 if(uri.compare(0, fixedLen, shortFixedPart) != 0)
35 else if(uri [fixedLen] != '/') // (1)
39 string msg("http::wims20::ServerSide::decode | URI: ");
41 msg += " | URI does not match with service '";
42 msg += shortFixedPart;
44 throw RuntimeException(msg, ANNA_FILE_LOCATION);
47 // http://domain-openapis/path-openapis/serviceID/guid/other_possible_levels?query_parameters
48 // Quita toda la parte "http://domain-openapis/path-openapis"
49 string hierarchyAndParameter = uri.substr(fixedLen + 1);
50 // Separa la jerarguía de los parámetros (si los hay).
51 const Tokenizer& tthp = split(SplitCode::HierarchyAndParameter, hierarchyAndParameter);
52 const int size = tthp.size();
54 if(size == 0 || size > 2) {
57 msg += "' is not valid";
58 throw RuntimeException(msg, ANNA_FILE_LOCATION);
64 decodeHierarchy(tthp [0]);
67 decodeHierarchy(tthp [0]);
68 decodeParameters(tthp [1]);
71 } catch(RuntimeException& ex) {
74 msg += "' is not valid | ";
76 throw RuntimeException(msg, ex.getFromFile(), ex.getFromLine());
80 string msg("http::wims20::ServerSide::decode | URI: ");
84 Logger::debug(msg, ANNA_FILE_LOCATION);
88 const string* http::wims20::ServerSide::getValue(const char* name, const Exception::Mode::_v mode) const
89 throw(RuntimeException) {
90 const string* result = NULL;
92 if(hasParameters() == true) {
93 for(const_parameter_iterator ii = parameter_begin(), maxii = parameter_end(); ii != maxii; ii ++) {
94 if(parameter_name(ii) == name) {
95 const string& value = parameter_value(ii);
102 if(result == NULL && (mode == Exception::Mode::Throw || mode == Exception::Mode::Trace)) {
103 string msg(asString());
104 msg += " | Parameter '";
106 msg += "' not found";
107 RuntimeException ex(msg, ANNA_FILE_LOCATION);
109 if(mode == Exception::Mode::Throw)
118 const char* http::wims20::ServerSide::getCStringValue(const char* name, const Exception::Mode::_v mode) const
119 throw(RuntimeException) {
120 const string* temp = getValue(name, mode);
121 return (temp == NULL) ? NULL : temp->c_str();
124 int http::wims20::ServerSide::getIntegerValue(const char* name, const Exception::Mode::_v mode) const
125 throw(RuntimeException) {
126 const string* tmp = getValue(name, mode);
131 const char* value = tmp->c_str();
132 return (anna_strncmp(value, "0x", 2) == 0) ? strtol(value + 2, NULL, 16) : atoi(value);
135 /* Nos ha debido llegar algo así como: serviceID/guid/*{other_possible_levels}
137 void http::wims20::ServerSide::decodeHierarchy(const std::string& hierarchy)
138 throw(RuntimeException) {
139 const Tokenizer& items = split(SplitCode::HierarchyItem, hierarchy);
140 Abstract::setServiceID(items [0]);
141 Abstract::setGUID(items [1]);
143 if(items.size() > 2) {
144 Tokenizer::const_iterator maxii, ii = items.begin();
148 for(maxii = items.end(); ii != maxii; ii ++)
149 Abstract::other_level_add(Tokenizer::data(ii));
153 /* Nos ha debido llegar algo así como: name=value&*{nameN=valueN}
155 void http::wims20::ServerSide::decodeParameters(const std::string& parameters)
156 throw(RuntimeException) {
157 const Tokenizer& tkparams = split(SplitCode::Parameters, parameters);
159 for(Tokenizer::const_iterator ii = tkparams.begin(), maxii = tkparams.end(); ii != maxii; ii ++) {
160 const string& parameter = Tokenizer::data(ii);
161 // Separa los XXX=YYYY
162 const Tokenizer& tkparam = split(SplitCode::ParameterAndArgument, parameter);
163 Abstract::parameter_set(tkparam [0], tkparam [1]);
167 const Tokenizer& http::wims20::ServerSide::split(const SplitCode::_v splitZone, const std::string& str)
168 throw(RuntimeException) {
169 static const char* separator [] = { "?", "/", "&", "=", NULL };
170 a_tokenizer [splitZone].apply(str, separator [splitZone]);
172 string msg("String: ");
174 msg += " | Separator: ";
175 msg += separator [splitZone];
176 Logger::debug(msg, ANNA_FILE_LOCATION);
178 return a_tokenizer [splitZone];