aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/lluri.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llcommon/lluri.cpp482
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 41std::string LLURI::escape(const std::string& str, const std::string & allowed)
41// mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
42// escaped = "%" hex hex
43static 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 65std::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 90namespace
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
303LLURI::LLURI() 116LLURI::LLURI()
304{ 117{
@@ -371,24 +184,23 @@ LLURI::~LLURI()
371{ 184{
372} 185}
373 186
374 187// static
375LLURI LLURI::buildHTTP(const std::string& host_port, 188LLURI 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
411LLURI LLURI::buildHTTP(const std::string& host_port, 223LLURI 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
248LLURI 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
256LLURI 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
265namespace {
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
436LLURI LLURI::buildAgentPresenceURI(const LLUUID& agent_id, LLApp* app) 289LLURI LLURI::buildAgentPresenceURI(const LLUUID& agent_id, LLApp* app)
437{ 290{
291 return buildBackboneURL(app, "agent", agent_id.asString(), "presence");
292}
293
294// static
295LLURI LLURI::buildBulkAgentPresenceURI(LLApp* app)
296{
297 return buildBackboneURL(app, "agent", "presence");
298}
299
300// static
301LLURI 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
454LLURI LLURI::buildBulkAgentPresenceURI(LLApp* app) 318LLURI LLURI::buildAgentSessionURI(const LLUUID& agent_id, LLApp* app)
319{
320 return buildBackboneURL(app, "agent", agent_id.asString(), "session");
321}
322
323// static
324LLURI 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
471LLURI LLURI::buildAgentSessionURI(const LLUUID& agent_id, LLApp* app) 343LLURI 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
640std::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
655std::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}