diff options
Diffstat (limited to 'linden/indra/llmessage/llservicebuilder.cpp')
-rw-r--r-- | linden/indra/llmessage/llservicebuilder.cpp | 103 |
1 files changed, 101 insertions, 2 deletions
diff --git a/linden/indra/llmessage/llservicebuilder.cpp b/linden/indra/llmessage/llservicebuilder.cpp index ae46bc0..6ffd480 100644 --- a/linden/indra/llmessage/llservicebuilder.cpp +++ b/linden/indra/llmessage/llservicebuilder.cpp | |||
@@ -12,12 +12,12 @@ | |||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | 12 | * ("GPL"), unless you have obtained a separate licensing agreement |
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | 13 | * ("Other License"), formally executed by you and Linden Lab. Terms of |
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | 14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or |
15 | * online at http://secondlife.com/developers/opensource/gplv2 | 15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 |
16 | * | 16 | * |
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlife.com/developers/opensource/flossexception | 20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
21 | * | 21 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 22 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 23 | * that you have read and understood your obligations described above, |
@@ -116,6 +116,104 @@ std::string LLServiceBuilder::buildServiceURI( | |||
116 | // Find the Service Name | 116 | // Find the Service Name |
117 | if(!service_url.empty() && option_map.isMap()) | 117 | if(!service_url.empty() && option_map.isMap()) |
118 | { | 118 | { |
119 | // throw in a ridiculously large limiter to make sure we don't | ||
120 | // loop forever with bad input. | ||
121 | int iterations = 100; | ||
122 | bool keep_looping = true; | ||
123 | while(keep_looping) | ||
124 | { | ||
125 | if(0 == --iterations) | ||
126 | { | ||
127 | keep_looping = false; | ||
128 | } | ||
129 | |||
130 | int depth = 0; | ||
131 | int deepest = 0; | ||
132 | bool find_match = false; | ||
133 | std::string::iterator iter(service_url.begin()); | ||
134 | std::string::iterator end(service_url.end()); | ||
135 | std::string::iterator deepest_node(service_url.end()); | ||
136 | std::string::iterator deepest_node_end(service_url.end()); | ||
137 | for(; iter != end; ++iter) | ||
138 | { | ||
139 | switch(*iter) | ||
140 | { | ||
141 | case '{': | ||
142 | ++depth; | ||
143 | if(depth > deepest) | ||
144 | { | ||
145 | deepest = depth; | ||
146 | deepest_node = iter; | ||
147 | find_match = true; | ||
148 | } | ||
149 | break; | ||
150 | case '}': | ||
151 | --depth; | ||
152 | if(find_match) | ||
153 | { | ||
154 | deepest_node_end = iter; | ||
155 | find_match = false; | ||
156 | } | ||
157 | break; | ||
158 | default: | ||
159 | break; | ||
160 | } | ||
161 | } | ||
162 | if((deepest_node == end) || (deepest_node_end == end)) | ||
163 | { | ||
164 | break; | ||
165 | } | ||
166 | |||
167 | // *NOTE: since the c++ implementation only understands | ||
168 | // params and straight string substitution, so it's a | ||
169 | // known distance of 2 to skip the directive. | ||
170 | std::string key(deepest_node + 2, deepest_node_end); | ||
171 | LLSD value = option_map[key]; | ||
172 | switch(*(deepest_node + 1)) | ||
173 | { | ||
174 | case '$': | ||
175 | if(value.isDefined()) | ||
176 | { | ||
177 | service_url.replace( | ||
178 | deepest_node, | ||
179 | deepest_node_end + 1, | ||
180 | value.asString()); | ||
181 | } | ||
182 | else | ||
183 | { | ||
184 | llinfos << "Unknown key: " << key << llendl; | ||
185 | keep_looping = false; | ||
186 | } | ||
187 | break; | ||
188 | case '%': | ||
189 | { | ||
190 | std::string query_str = LLURI::mapToQueryString(value); | ||
191 | service_url.replace( | ||
192 | deepest_node, | ||
193 | deepest_node_end + 1, | ||
194 | query_str); | ||
195 | } | ||
196 | break; | ||
197 | default: | ||
198 | llinfos << "Unknown directive: " << *(deepest_node + 1) | ||
199 | << llendl; | ||
200 | keep_looping = false; | ||
201 | break; | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | if (service_url.find('{') != std::string::npos) | ||
206 | { | ||
207 | llwarns << "Constructed a likely bogus service URL: " << service_url | ||
208 | << llendl; | ||
209 | } | ||
210 | return service_url; | ||
211 | } | ||
212 | |||
213 | |||
214 | |||
215 | // Old, not as good implementation. Phoenix 2007-10-15 | ||
216 | #if 0 | ||
119 | // Do brace replacements - NOT CURRENTLY RECURSIVE | 217 | // Do brace replacements - NOT CURRENTLY RECURSIVE |
120 | for(LLSD::map_const_iterator option_itr = option_map.beginMap(); | 218 | for(LLSD::map_const_iterator option_itr = option_map.beginMap(); |
121 | option_itr != option_map.endMap(); | 219 | option_itr != option_map.endMap(); |
@@ -157,3 +255,4 @@ std::string LLServiceBuilder::buildServiceURI( | |||
157 | 255 | ||
158 | return service_url; | 256 | return service_url; |
159 | } | 257 | } |
258 | #endif | ||