1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
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 the copyright holder 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
39 #include <anna/core/tracing/Logger.hpp>
41 #include <anna/http/Request.hpp>
43 #include <anna/http/wims20/ServerSide.hpp>
49 * (1) Si estamos esperando http://xxx/zzzz hay que verificar que no vamos a dar por buena una
50 * expresión con la forma: http://xxx/zzzzAAAAAA, p.e.
52 void http::wims20::ServerSide::decode(const http::Request& request)
53 throw(RuntimeException) {
55 const string& uri = request.getURI();
56 // Calcula la parte corta que hemos definido para el servicio
57 const string& shortFixedPart = Abstract::calculeShortFixedPart();
58 const int fixedLen = shortFixedPart.length();
61 if(uri.compare(0, fixedLen, shortFixedPart) != 0)
63 else if(uri [fixedLen] != '/') // (1)
67 string msg("http::wims20::ServerSide::decode | URI: ");
69 msg += " | URI does not match with service '";
70 msg += shortFixedPart;
72 throw RuntimeException(msg, ANNA_FILE_LOCATION);
75 // http://domain-openapis/path-openapis/serviceID/guid/other_possible_levels?query_parameters
76 // Quita toda la parte "http://domain-openapis/path-openapis"
77 string hierarchyAndParameter = uri.substr(fixedLen + 1);
78 // Separa la jerarguía de los parámetros (si los hay).
79 const Tokenizer& tthp = split(SplitCode::HierarchyAndParameter, hierarchyAndParameter);
80 const int size = tthp.size();
82 if(size == 0 || size > 2) {
85 msg += "' is not valid";
86 throw RuntimeException(msg, ANNA_FILE_LOCATION);
92 decodeHierarchy(tthp [0]);
95 decodeHierarchy(tthp [0]);
96 decodeParameters(tthp [1]);
99 } catch(RuntimeException& ex) {
102 msg += "' is not valid | ";
104 throw RuntimeException(msg, ex.getFromFile(), ex.getFromLine());
108 string msg("http::wims20::ServerSide::decode | URI: ");
110 msg += " | Result: ";
112 Logger::debug(msg, ANNA_FILE_LOCATION);
116 const string* http::wims20::ServerSide::getValue(const char* name, const Exception::Mode::_v mode) const
117 throw(RuntimeException) {
118 const string* result = NULL;
120 if(hasParameters() == true) {
121 for(const_parameter_iterator ii = parameter_begin(), maxii = parameter_end(); ii != maxii; ii ++) {
122 if(parameter_name(ii) == name) {
123 const string& value = parameter_value(ii);
130 if(result == NULL && (mode == Exception::Mode::Throw || mode == Exception::Mode::Trace)) {
131 string msg(asString());
132 msg += " | Parameter '";
134 msg += "' not found";
135 RuntimeException ex(msg, ANNA_FILE_LOCATION);
137 if(mode == Exception::Mode::Throw)
146 const char* http::wims20::ServerSide::getCStringValue(const char* name, const Exception::Mode::_v mode) const
147 throw(RuntimeException) {
148 const string* temp = getValue(name, mode);
149 return (temp == NULL) ? NULL : temp->c_str();
152 int http::wims20::ServerSide::getIntegerValue(const char* name, const Exception::Mode::_v mode) const
153 throw(RuntimeException) {
154 const string* tmp = getValue(name, mode);
159 const char* value = tmp->c_str();
160 return (anna_strncmp(value, "0x", 2) == 0) ? strtol(value + 2, NULL, 16) : atoi(value);
163 /* Nos ha debido llegar algo así como: serviceID/guid/*{other_possible_levels}
165 void http::wims20::ServerSide::decodeHierarchy(const std::string& hierarchy)
166 throw(RuntimeException) {
167 const Tokenizer& items = split(SplitCode::HierarchyItem, hierarchy);
168 Abstract::setServiceID(items [0]);
169 Abstract::setGUID(items [1]);
171 if(items.size() > 2) {
172 Tokenizer::const_iterator maxii, ii = items.begin();
176 for(maxii = items.end(); ii != maxii; ii ++)
177 Abstract::other_level_add(Tokenizer::data(ii));
181 /* Nos ha debido llegar algo así como: name=value&*{nameN=valueN}
183 void http::wims20::ServerSide::decodeParameters(const std::string& parameters)
184 throw(RuntimeException) {
185 const Tokenizer& tkparams = split(SplitCode::Parameters, parameters);
187 for(Tokenizer::const_iterator ii = tkparams.begin(), maxii = tkparams.end(); ii != maxii; ii ++) {
188 const string& parameter = Tokenizer::data(ii);
189 // Separa los XXX=YYYY
190 const Tokenizer& tkparam = split(SplitCode::ParameterAndArgument, parameter);
191 Abstract::parameter_set(tkparam [0], tkparam [1]);
195 const Tokenizer& http::wims20::ServerSide::split(const SplitCode::_v splitZone, const std::string& str)
196 throw(RuntimeException) {
197 static const char* separator [] = { "?", "/", "&", "=", NULL };
198 a_tokenizer [splitZone].apply(str, separator [splitZone]);
200 string msg("String: ");
202 msg += " | Separator: ";
203 msg += separator [splitZone];
204 Logger::debug(msg, ANNA_FILE_LOCATION);
206 return a_tokenizer [splitZone];