diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llcommon/lluri.cpp | 482 |
1 files changed, 157 insertions, 325 deletions
diff --git a/linden/indra/llcommon/lluri.cpp b/linden/indra/llcommon/lluri.cpp index e697ec1..bc3540e 100644 --- a/linden/indra/llcommon/lluri.cpp +++ b/linden/indra/llcommon/lluri.cpp | |||
@@ -32,273 +32,86 @@ | |||
32 | #include "llapp.h" | 32 | #include "llapp.h" |
33 | #include "lluri.h" | 33 | #include "lluri.h" |
34 | #include "llsd.h" | 34 | #include "llsd.h" |
35 | 35 | #include <iomanip> | |
36 | |||
36 | #include "../llmath/lluuid.h" | 37 | #include "../llmath/lluuid.h" |
37 | 38 | ||
38 | // uric = reserved | unreserved | escaped | 39 | |
39 | // reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," | 40 | // static |
40 | // unreserved = alphanum | mark | 41 | std::string LLURI::escape(const std::string& str, const std::string & allowed) |
41 | // mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" | ||
42 | // escaped = "%" hex hex | ||
43 | static const char* ESCAPED_CHARACTERS[256] = | ||
44 | { | 42 | { |
45 | "%00", // 0 | 43 | std::ostringstream ostr; |
46 | "%01", // 1 | 44 | |
47 | "%02", // 2 | 45 | std::string::const_iterator it = str.begin(); |
48 | "%03", // 3 | 46 | std::string::const_iterator end = str.end(); |
49 | "%04", // 4 | 47 | for(; it != end; ++it) |
50 | "%05", // 5 | 48 | { |
51 | "%06", // 6 | 49 | std::string::value_type c = *it; |
52 | "%07", // 7 | 50 | if(allowed.find(c) == std::string::npos) |
53 | "%08", // 8 | 51 | { |
54 | "%09", // 9 | 52 | ostr << "%" |
55 | "%0a", // 10 | 53 | << std::uppercase << std::hex << std::setw(2) << std::setfill('0') |
56 | "%0b", // 11 | 54 | << static_cast<U32>(c); |
57 | "%0c", // 12 | 55 | } |
58 | "%0d", // 13 | 56 | else |
59 | "%0e", // 14 | 57 | { |
60 | "%0f", // 15 | 58 | ostr << c; |
61 | "%10", // 16 | 59 | } |
62 | "%11", // 17 | 60 | } |
63 | "%12", // 18 | 61 | return ostr.str(); |
64 | "%13", // 19 | 62 | } |
65 | "%14", // 20 | 63 | |
66 | "%15", // 21 | 64 | // static |
67 | "%16", // 22 | 65 | std::string LLURI::unescape(const std::string& str) |
68 | "%17", // 23 | 66 | { |
69 | "%18", // 24 | 67 | std::ostringstream ostr; |
70 | "%19", // 25 | 68 | std::string::const_iterator it = str.begin(); |
71 | "%1a", // 26 | 69 | std::string::const_iterator end = str.end(); |
72 | "%1b", // 27 | 70 | for(; it != end; ++it) |
73 | "%1c", // 28 | 71 | { |
74 | "%1d", // 29 | 72 | if((*it) == '%') |
75 | "%1e", // 30 | 73 | { |
76 | "%1f", // 31 | 74 | ++it; |
77 | "%20", // 32 | 75 | if(it == end) break; |
78 | "!", // 33 | 76 | U8 c = hex_as_nybble(*it++); |
79 | "%22", // 34 | 77 | c = c << 4; |
80 | "%23", // 35 | 78 | if (it == end) break; |
81 | "$", // 36 | 79 | c |= hex_as_nybble(*it); |
82 | "%25", // 37 | 80 | ostr.put((char)c); |
83 | "&", // 38 | 81 | } |
84 | "'", // 39 | 82 | else |
85 | "(", // 40 | 83 | { |
86 | ")", // 41 | 84 | ostr.put(*it); |
87 | "*", // 42 | 85 | } |
88 | "+", // 43 | 86 | } |
89 | ",", // 44 | 87 | return ostr.str(); |
90 | "-", // 45 | 88 | } |
91 | ".", // 46 | 89 | |
92 | "/", // 47 | 90 | namespace |
93 | "0", // 48 | 91 | { |
94 | "1", // 49 | 92 | const std::string unreserved() |
95 | "2", // 50 | 93 | { |
96 | "3", // 51 | 94 | static const std::string s = |
97 | "4", // 52 | 95 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" |
98 | "5", // 53 | 96 | "0123456789" |
99 | "6", // 54 | 97 | "-._~"; |
100 | "7", // 55 | 98 | return s; |
101 | "8", // 56 | 99 | } |
102 | "9", // 57 | 100 | const std::string sub_delims() |
103 | ":", // 58 | 101 | { |
104 | ";", // 59 | 102 | static const std::string s = "!$&'()*+,;="; |
105 | "%3c", // 60 | 103 | return s; |
106 | "=", // 61 | 104 | } |
107 | "%3e", // 62 | 105 | |
108 | "?", // 63 | 106 | std::string escapeHostAndPort(const std::string& s) |
109 | "@", // 64 | 107 | { return LLURI::escape(s, unreserved() + sub_delims() +":"); } |
110 | "A", // 65 | 108 | std::string escapePathComponent(const std::string& s) |
111 | "B", // 66 | 109 | { return LLURI::escape(s, unreserved() + sub_delims() + ":@"); } |
112 | "C", // 67 | 110 | std::string escapeQueryVariable(const std::string& s) |
113 | "D", // 68 | 111 | { return LLURI::escape(s, unreserved() + ":@!$'()*+,"); } // sub_delims - "&;=" + ":@" |
114 | "E", // 69 | 112 | std::string escapeQueryValue(const std::string& s) |
115 | "F", // 70 | 113 | { return LLURI::escape(s, unreserved() + ":@!$'()*+,="); } // sub_delims - "&;" + ":@" |
116 | "G", // 71 | 114 | } |
117 | "H", // 72 | ||
118 | "I", // 73 | ||
119 | "J", // 74 | ||
120 | "K", // 75 | ||
121 | "L", // 76 | ||
122 | "M", // 77 | ||
123 | "N", // 78 | ||
124 | "O", // 79 | ||
125 | "P", // 80 | ||
126 | "Q", // 81 | ||
127 | "R", // 82 | ||
128 | "S", // 83 | ||
129 | "T", // 84 | ||
130 | "U", // 85 | ||
131 | "V", // 86 | ||
132 | "W", // 87 | ||
133 | "X", // 88 | ||
134 | "Y", // 89 | ||
135 | "Z", // 90 | ||
136 | "%5b", // 91 | ||
137 | "%5c", // 92 | ||
138 | "%5d", // 93 | ||
139 | "%5e", // 94 | ||
140 | "_", // 95 | ||
141 | "%60", // 96 | ||
142 | "a", // 97 | ||
143 | "b", // 98 | ||
144 | "c", // 99 | ||
145 | "d", // 100 | ||
146 | "e", // 101 | ||
147 | "f", // 102 | ||
148 | "g", // 103 | ||
149 | "h", // 104 | ||
150 | "i", // 105 | ||
151 | "j", // 106 | ||
152 | "k", // 107 | ||
153 | "l", // 108 | ||
154 | "m", // 109 | ||
155 | "n", // 110 | ||
156 | "o", // 111 | ||
157 | "p", // 112 | ||
158 | "q", // 113 | ||
159 | "r", // 114 | ||
160 | "s", // 115 | ||
161 | "t", // 116 | ||
162 | "u", // 117 | ||
163 | "v", // 118 | ||
164 | "w", // 119 | ||
165 | "x", // 120 | ||
166 | "y", // 121 | ||
167 | "z", // 122 | ||
168 | "%7b", // 123 | ||
169 | "%7c", // 124 | ||
170 | "%7d", // 125 | ||
171 | "~", // 126 | ||
172 | "%7f", // 127 | ||
173 | "%80", // 128 | ||
174 | "%81", // 129 | ||
175 | "%82", // 130 | ||
176 | "%83", // 131 | ||
177 | "%84", // 132 | ||
178 | "%85", // 133 | ||
179 | "%86", // 134 | ||
180 | "%87", // 135 | ||
181 | "%88", // 136 | ||
182 | "%89", // 137 | ||
183 | "%8a", // 138 | ||
184 | "%8b", // 139 | ||
185 | "%8c", // 140 | ||
186 | "%8d", // 141 | ||
187 | "%8e", // 142 | ||
188 | "%8f", // 143 | ||
189 | "%90", // 144 | ||
190 | "%91", // 145 | ||
191 | "%92", // 146 | ||
192 | "%93", // 147 | ||
193 | "%94", // 148 | ||
194 | "%95", // 149 | ||
195 | "%96", // 150 | ||
196 | "%97", // 151 | ||
197 | "%98", // 152 | ||
198 | "%99", // 153 | ||
199 | "%9a", // 154 | ||
200 | "%9b", // 155 | ||
201 | "%9c", // 156 | ||
202 | "%9d", // 157 | ||
203 | "%9e", // 158 | ||
204 | "%9f", // 159 | ||
205 | "%a0", // 160 | ||
206 | "%a1", // 161 | ||
207 | "%a2", // 162 | ||
208 | "%a3", // 163 | ||
209 | "%a4", // 164 | ||
210 | "%a5", // 165 | ||
211 | "%a6", // 166 | ||
212 | "%a7", // 167 | ||
213 | "%a8", // 168 | ||
214 | "%a9", // 169 | ||
215 | "%aa", // 170 | ||
216 | "%ab", // 171 | ||
217 | "%ac", // 172 | ||
218 | "%ad", // 173 | ||
219 | "%ae", // 174 | ||
220 | "%af", // 175 | ||
221 | "%b0", // 176 | ||
222 | "%b1", // 177 | ||
223 | "%b2", // 178 | ||
224 | "%b3", // 179 | ||
225 | "%b4", // 180 | ||
226 | "%b5", // 181 | ||
227 | "%b6", // 182 | ||
228 | "%b7", // 183 | ||
229 | "%b8", // 184 | ||
230 | "%b9", // 185 | ||
231 | "%ba", // 186 | ||
232 | "%bb", // 187 | ||
233 | "%bc", // 188 | ||
234 | "%bd", // 189 | ||
235 | "%be", // 190 | ||
236 | "%bf", // 191 | ||
237 | "%c0", // 192 | ||
238 | "%c1", // 193 | ||
239 | "%c2", // 194 | ||
240 | "%c3", // 195 | ||
241 | "%c4", // 196 | ||
242 | "%c5", // 197 | ||
243 | "%c6", // 198 | ||
244 | "%c7", // 199 | ||
245 | "%c8", // 200 | ||
246 | "%c9", // 201 | ||
247 | "%ca", // 202 | ||
248 | "%cb", // 203 | ||
249 | "%cc", // 204 | ||
250 | "%cd", // 205 | ||
251 | "%ce", // 206 | ||
252 | "%cf", // 207 | ||
253 | "%d0", // 208 | ||
254 | "%d1", // 209 | ||
255 | "%d2", // 210 | ||
256 | "%d3", // 211 | ||
257 | "%d4", // 212 | ||
258 | "%d5", // 213 | ||
259 | "%d6", // 214 | ||
260 | "%d7", // 215 | ||
261 | "%d8", // 216 | ||
262 | "%d9", // 217 | ||
263 | "%da", // 218 | ||
264 | "%db", // 219 | ||
265 | "%dc", // 220 | ||
266 | "%dd", // 221 | ||
267 | "%de", // 222 | ||
268 | "%df", // 223 | ||
269 | "%e0", // 224 | ||
270 | "%e1", // 225 | ||
271 | "%e2", // 226 | ||
272 | "%e3", // 227 | ||
273 | "%e4", // 228 | ||
274 | "%e5", // 229 | ||
275 | "%e6", // 230 | ||
276 | "%e7", // 231 | ||
277 | "%e8", // 232 | ||
278 | "%e9", // 233 | ||
279 | "%ea", // 234 | ||
280 | "%eb", // 235 | ||
281 | "%ec", // 236 | ||
282 | "%ed", // 237 | ||
283 | "%ee", // 238 | ||
284 | "%ef", // 239 | ||
285 | "%f0", // 240 | ||
286 | "%f1", // 241 | ||
287 | "%f2", // 242 | ||
288 | "%f3", // 243 | ||
289 | "%f4", // 244 | ||
290 | "%f5", // 245 | ||
291 | "%f6", // 246 | ||
292 | "%f7", // 247 | ||
293 | "%f8", // 248 | ||
294 | "%f9", // 249 | ||
295 | "%fa", // 250 | ||
296 | "%fb", // 251 | ||
297 | "%fc", // 252 | ||
298 | "%fd", // 253 | ||
299 | "%fe", // 254 | ||
300 | "%ff" // 255 | ||
301 | }; | ||
302 | 115 | ||
303 | LLURI::LLURI() | 116 | LLURI::LLURI() |
304 | { | 117 | { |
@@ -371,24 +184,23 @@ LLURI::~LLURI() | |||
371 | { | 184 | { |
372 | } | 185 | } |
373 | 186 | ||
374 | 187 | // static | |
375 | LLURI LLURI::buildHTTP(const std::string& host_port, | 188 | LLURI LLURI::buildHTTP(const std::string& prefix, |
376 | const LLSD& path) | 189 | const LLSD& path) |
377 | { | 190 | { |
378 | LLURI result; | 191 | LLURI result; |
379 | 192 | ||
380 | // TODO: deal with '/' '?' '#' in host_port | 193 | // TODO: deal with '/' '?' '#' in host_port |
381 | S32 index = host_port.find("://"); | 194 | if (prefix.find("://") != prefix.npos) |
382 | if (index != host_port.npos) | ||
383 | { | 195 | { |
384 | // The scheme is part of the host_port | 196 | // it is a prefix |
385 | result.mScheme = ""; | 197 | result = LLURI(prefix); |
386 | result.mEscapedAuthority = escape(host_port); | ||
387 | } | 198 | } |
388 | else | 199 | else |
389 | { | 200 | { |
390 | result.mScheme = "HTTP"; | 201 | // it is just a host and optional port |
391 | result.mEscapedAuthority = "//" + escape(host_port); | 202 | result.mScheme = "http"; |
203 | result.mEscapedAuthority = escapeHostAndPort(prefix); | ||
392 | } | 204 | } |
393 | 205 | ||
394 | if (path.isArray()) | 206 | if (path.isArray()) |
@@ -399,20 +211,20 @@ LLURI LLURI::buildHTTP(const std::string& host_port, | |||
399 | ++it) | 211 | ++it) |
400 | { | 212 | { |
401 | lldebugs << "PATH: inserting " << it->asString() << llendl; | 213 | lldebugs << "PATH: inserting " << it->asString() << llendl; |
402 | result.mEscapedPath += "/" + escape(it->asString()); | 214 | result.mEscapedPath += "/" + escapePathComponent(it->asString()); |
403 | } | 215 | } |
404 | } | 216 | } |
405 | result.mEscapedOpaque = result.mEscapedAuthority + | 217 | result.mEscapedOpaque = "//" + result.mEscapedAuthority + |
406 | result.mEscapedPath; | 218 | result.mEscapedPath; |
407 | return result; | 219 | return result; |
408 | } | 220 | } |
409 | 221 | ||
410 | // static | 222 | // static |
411 | LLURI LLURI::buildHTTP(const std::string& host_port, | 223 | LLURI LLURI::buildHTTP(const std::string& prefix, |
412 | const LLSD& path, | 224 | const LLSD& path, |
413 | const LLSD& query) | 225 | const LLSD& query) |
414 | { | 226 | { |
415 | LLURI result = buildHTTP(host_port, path); | 227 | LLURI result = buildHTTP(prefix, path); |
416 | // break out and escape each query component | 228 | // break out and escape each query component |
417 | if (query.isMap()) | 229 | if (query.isMap()) |
418 | { | 230 | { |
@@ -420,8 +232,8 @@ LLURI LLURI::buildHTTP(const std::string& host_port, | |||
420 | it != query.endMap(); | 232 | it != query.endMap(); |
421 | it++) | 233 | it++) |
422 | { | 234 | { |
423 | result.mEscapedQuery += escape(it->first) + | 235 | result.mEscapedQuery += escapeQueryVariable(it->first) + |
424 | (it->second.isUndefined() ? "" : "=" + it->second.asString()) + | 236 | (it->second.isUndefined() ? "" : "=" + escapeQueryValue(it->second.asString())) + |
425 | "&"; | 237 | "&"; |
426 | } | 238 | } |
427 | if (query.size() > 0) | 239 | if (query.size() > 0) |
@@ -433,8 +245,61 @@ LLURI LLURI::buildHTTP(const std::string& host_port, | |||
433 | } | 245 | } |
434 | 246 | ||
435 | // static | 247 | // static |
248 | LLURI LLURI::buildHTTP(const std::string& host, | ||
249 | const U32& port, | ||
250 | const LLSD& path) | ||
251 | { | ||
252 | return LLURI::buildHTTP(llformat("%s:%u", host.c_str(), port), path); | ||
253 | } | ||
254 | |||
255 | // static | ||
256 | LLURI LLURI::buildHTTP(const std::string& host, | ||
257 | const U32& port, | ||
258 | const LLSD& path, | ||
259 | const LLSD& query) | ||
260 | { | ||
261 | return LLURI::buildHTTP(llformat("%s:%u", host.c_str(), port), path, query); | ||
262 | } | ||
263 | |||
264 | |||
265 | namespace { | ||
266 | LLURI buildBackboneURL(LLApp* app, | ||
267 | const std::string& p1 = "", | ||
268 | const std::string& p2 = "", | ||
269 | const std::string& p3 = "") | ||
270 | { | ||
271 | std::string host = "localhost:12040"; | ||
272 | |||
273 | if (app) | ||
274 | { | ||
275 | host = app->getOption("backbone-host-port").asString(); | ||
276 | } | ||
277 | |||
278 | LLSD path = LLSD::emptyArray(); | ||
279 | if (!p1.empty()) path.append(p1); | ||
280 | if (!p2.empty()) path.append(p2); | ||
281 | if (!p3.empty()) path.append(p3); | ||
282 | |||
283 | return LLURI::buildHTTP(host, path); | ||
284 | } | ||
285 | } | ||
286 | |||
287 | |||
288 | // static | ||
436 | LLURI LLURI::buildAgentPresenceURI(const LLUUID& agent_id, LLApp* app) | 289 | LLURI LLURI::buildAgentPresenceURI(const LLUUID& agent_id, LLApp* app) |
437 | { | 290 | { |
291 | return buildBackboneURL(app, "agent", agent_id.asString(), "presence"); | ||
292 | } | ||
293 | |||
294 | // static | ||
295 | LLURI LLURI::buildBulkAgentPresenceURI(LLApp* app) | ||
296 | { | ||
297 | return buildBackboneURL(app, "agent", "presence"); | ||
298 | } | ||
299 | |||
300 | // static | ||
301 | LLURI LLURI::buildBulkAgentNamesURI(LLApp* app) | ||
302 | { | ||
438 | std::string host = "localhost:12040"; | 303 | std::string host = "localhost:12040"; |
439 | 304 | ||
440 | if (app) | 305 | if (app) |
@@ -444,14 +309,19 @@ LLURI LLURI::buildAgentPresenceURI(const LLUUID& agent_id, LLApp* app) | |||
444 | 309 | ||
445 | LLSD path = LLSD::emptyArray(); | 310 | LLSD path = LLSD::emptyArray(); |
446 | path.append("agent"); | 311 | path.append("agent"); |
447 | path.append(agent_id); | 312 | path.append("names"); |
448 | path.append("presence"); | ||
449 | 313 | ||
450 | return buildHTTP(host, path); | 314 | return buildHTTP(host, path); |
451 | } | 315 | } |
452 | 316 | ||
453 | // static | 317 | // static |
454 | LLURI LLURI::buildBulkAgentPresenceURI(LLApp* app) | 318 | LLURI LLURI::buildAgentSessionURI(const LLUUID& agent_id, LLApp* app) |
319 | { | ||
320 | return buildBackboneURL(app, "agent", agent_id.asString(), "session"); | ||
321 | } | ||
322 | |||
323 | // static | ||
324 | LLURI LLURI::buildInventoryHostURI(const LLUUID& agent_id, LLApp* app) | ||
455 | { | 325 | { |
456 | std::string host = "localhost:12040"; | 326 | std::string host = "localhost:12040"; |
457 | 327 | ||
@@ -462,13 +332,15 @@ LLURI LLURI::buildBulkAgentPresenceURI(LLApp* app) | |||
462 | 332 | ||
463 | LLSD path = LLSD::emptyArray(); | 333 | LLSD path = LLSD::emptyArray(); |
464 | path.append("agent"); | 334 | path.append("agent"); |
465 | path.append("presence"); | 335 | path.append(agent_id); |
336 | path.append("inventory"); | ||
337 | path.append("host"); | ||
466 | 338 | ||
467 | return buildHTTP(host, path); | 339 | return buildHTTP(host, path); |
468 | } | 340 | } |
469 | 341 | ||
470 | // static | 342 | // static |
471 | LLURI LLURI::buildAgentSessionURI(const LLUUID& agent_id, LLApp* app) | 343 | LLURI LLURI::buildAgentNameURI(const LLUUID& agent_id, LLApp* app) |
472 | { | 344 | { |
473 | std::string host = "localhost:12040"; | 345 | std::string host = "localhost:12040"; |
474 | 346 | ||
@@ -480,7 +352,7 @@ LLURI LLURI::buildAgentSessionURI(const LLUUID& agent_id, LLApp* app) | |||
480 | LLSD path = LLSD::emptyArray(); | 352 | LLSD path = LLSD::emptyArray(); |
481 | path.append("agent"); | 353 | path.append("agent"); |
482 | path.append(agent_id); | 354 | path.append(agent_id); |
483 | path.append("session"); | 355 | path.append("name"); |
484 | 356 | ||
485 | return buildHTTP(host, path); | 357 | return buildHTTP(host, path); |
486 | } | 358 | } |
@@ -636,43 +508,3 @@ LLSD LLURI::queryMap(std::string escaped_query_string) | |||
636 | return result; | 508 | return result; |
637 | } | 509 | } |
638 | 510 | ||
639 | // static | ||
640 | std::string LLURI::escape(const std::string& str) | ||
641 | { | ||
642 | std::ostringstream ostr; | ||
643 | std::string::const_iterator it = str.begin(); | ||
644 | std::string::const_iterator end = str.end(); | ||
645 | S32 c; | ||
646 | for(; it != end; ++it) | ||
647 | { | ||
648 | c = (S32)(*it); | ||
649 | ostr << ESCAPED_CHARACTERS[c]; | ||
650 | } | ||
651 | return ostr.str(); | ||
652 | } | ||
653 | |||
654 | // static | ||
655 | std::string LLURI::unescape(const std::string& str) | ||
656 | { | ||
657 | std::ostringstream ostr; | ||
658 | std::string::const_iterator it = str.begin(); | ||
659 | std::string::const_iterator end = str.end(); | ||
660 | for(; it != end; ++it) | ||
661 | { | ||
662 | if((*it) == '%') | ||
663 | { | ||
664 | ++it; | ||
665 | if(it == end) break; | ||
666 | U8 c = hex_as_nybble(*it++); | ||
667 | c = c << 4; | ||
668 | if (it == end) break; | ||
669 | c |= hex_as_nybble(*it); | ||
670 | ostr.put((char)c); | ||
671 | } | ||
672 | else | ||
673 | { | ||
674 | ostr.put(*it); | ||
675 | } | ||
676 | } | ||
677 | return ostr.str(); | ||
678 | } | ||