aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/lluri.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcommon/lluri.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llcommon/lluri.cpp')
-rw-r--r--linden/indra/llcommon/lluri.cpp598
1 files changed, 598 insertions, 0 deletions
diff --git a/linden/indra/llcommon/lluri.cpp b/linden/indra/llcommon/lluri.cpp
new file mode 100644
index 0000000..2eb0f11
--- /dev/null
+++ b/linden/indra/llcommon/lluri.cpp
@@ -0,0 +1,598 @@
1/**
2 * @file lluri.cpp
3 * @author Phoenix
4 * @date 2006-02-08
5 * @brief Implementation of the LLURI class.
6 *
7 * Copyright (c) 2006-2007, Linden Research, Inc.
8 *
9 * The source code in this file ("Source Code") is provided by Linden Lab
10 * to you under the terms of the GNU General Public License, version 2.0
11 * ("GPL"), unless you have obtained a separate licensing agreement
12 * ("Other License"), formally executed by you and Linden Lab. Terms of
13 * the GPL can be found in doc/GPL-license.txt in this distribution, or
14 * online at http://secondlife.com/developers/opensource/gplv2
15 *
16 * There are special exceptions to the terms and conditions of the GPL as
17 * it is applied to this Source Code. View the full text of the exception
18 * in the file doc/FLOSS-exception.txt in this software distribution, or
19 * online at http://secondlife.com/developers/opensource/flossexception
20 *
21 * By copying, modifying or distributing this software, you acknowledge
22 * that you have read and understood your obligations described above,
23 * and agree to abide by those obligations.
24 *
25 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
26 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
27 * COMPLETENESS OR PERFORMANCE.
28 */
29
30#include "linden_common.h"
31#include "lluri.h"
32#include "llsd.h"
33
34// uric = reserved | unreserved | escaped
35// reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
36// unreserved = alphanum | mark
37// mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
38// escaped = "%" hex hex
39static const char* ESCAPED_CHARACTERS[256] =
40{
41 "%00", // 0
42 "%01", // 1
43 "%02", // 2
44 "%03", // 3
45 "%04", // 4
46 "%05", // 5
47 "%06", // 6
48 "%07", // 7
49 "%08", // 8
50 "%09", // 9
51 "%0a", // 10
52 "%0b", // 11
53 "%0c", // 12
54 "%0d", // 13
55 "%0e", // 14
56 "%0f", // 15
57 "%10", // 16
58 "%11", // 17
59 "%12", // 18
60 "%13", // 19
61 "%14", // 20
62 "%15", // 21
63 "%16", // 22
64 "%17", // 23
65 "%18", // 24
66 "%19", // 25
67 "%1a", // 26
68 "%1b", // 27
69 "%1c", // 28
70 "%1d", // 29
71 "%1e", // 30
72 "%1f", // 31
73 "%20", // 32
74 "!", // 33
75 "%22", // 34
76 "%23", // 35
77 "$", // 36
78 "%25", // 37
79 "&", // 38
80 "'", // 39
81 "(", // 40
82 ")", // 41
83 "*", // 42
84 "+", // 43
85 ",", // 44
86 "-", // 45
87 ".", // 46
88 "/", // 47
89 "0", // 48
90 "1", // 49
91 "2", // 50
92 "3", // 51
93 "4", // 52
94 "5", // 53
95 "6", // 54
96 "7", // 55
97 "8", // 56
98 "9", // 57
99 ":", // 58
100 ";", // 59
101 "%3c", // 60
102 "=", // 61
103 "%3e", // 62
104 "?", // 63
105 "@", // 64
106 "A", // 65
107 "B", // 66
108 "C", // 67
109 "D", // 68
110 "E", // 69
111 "F", // 70
112 "G", // 71
113 "H", // 72
114 "I", // 73
115 "J", // 74
116 "K", // 75
117 "L", // 76
118 "M", // 77
119 "N", // 78
120 "O", // 79
121 "P", // 80
122 "Q", // 81
123 "R", // 82
124 "S", // 83
125 "T", // 84
126 "U", // 85
127 "V", // 86
128 "W", // 87
129 "X", // 88
130 "Y", // 89
131 "Z", // 90
132 "%5b", // 91
133 "%5c", // 92
134 "%5d", // 93
135 "%5e", // 94
136 "_", // 95
137 "%60", // 96
138 "a", // 97
139 "b", // 98
140 "c", // 99
141 "d", // 100
142 "e", // 101
143 "f", // 102
144 "g", // 103
145 "h", // 104
146 "i", // 105
147 "j", // 106
148 "k", // 107
149 "l", // 108
150 "m", // 109
151 "n", // 110
152 "o", // 111
153 "p", // 112
154 "q", // 113
155 "r", // 114
156 "s", // 115
157 "t", // 116
158 "u", // 117
159 "v", // 118
160 "w", // 119
161 "x", // 120
162 "y", // 121
163 "z", // 122
164 "%7b", // 123
165 "%7c", // 124
166 "%7d", // 125
167 "~", // 126
168 "%7f", // 127
169 "%80", // 128
170 "%81", // 129
171 "%82", // 130
172 "%83", // 131
173 "%84", // 132
174 "%85", // 133
175 "%86", // 134
176 "%87", // 135
177 "%88", // 136
178 "%89", // 137
179 "%8a", // 138
180 "%8b", // 139
181 "%8c", // 140
182 "%8d", // 141
183 "%8e", // 142
184 "%8f", // 143
185 "%90", // 144
186 "%91", // 145
187 "%92", // 146
188 "%93", // 147
189 "%94", // 148
190 "%95", // 149
191 "%96", // 150
192 "%97", // 151
193 "%98", // 152
194 "%99", // 153
195 "%9a", // 154
196 "%9b", // 155
197 "%9c", // 156
198 "%9d", // 157
199 "%9e", // 158
200 "%9f", // 159
201 "%a0", // 160
202 "%a1", // 161
203 "%a2", // 162
204 "%a3", // 163
205 "%a4", // 164
206 "%a5", // 165
207 "%a6", // 166
208 "%a7", // 167
209 "%a8", // 168
210 "%a9", // 169
211 "%aa", // 170
212 "%ab", // 171
213 "%ac", // 172
214 "%ad", // 173
215 "%ae", // 174
216 "%af", // 175
217 "%b0", // 176
218 "%b1", // 177
219 "%b2", // 178
220 "%b3", // 179
221 "%b4", // 180
222 "%b5", // 181
223 "%b6", // 182
224 "%b7", // 183
225 "%b8", // 184
226 "%b9", // 185
227 "%ba", // 186
228 "%bb", // 187
229 "%bc", // 188
230 "%bd", // 189
231 "%be", // 190
232 "%bf", // 191
233 "%c0", // 192
234 "%c1", // 193
235 "%c2", // 194
236 "%c3", // 195
237 "%c4", // 196
238 "%c5", // 197
239 "%c6", // 198
240 "%c7", // 199
241 "%c8", // 200
242 "%c9", // 201
243 "%ca", // 202
244 "%cb", // 203
245 "%cc", // 204
246 "%cd", // 205
247 "%ce", // 206
248 "%cf", // 207
249 "%d0", // 208
250 "%d1", // 209
251 "%d2", // 210
252 "%d3", // 211
253 "%d4", // 212
254 "%d5", // 213
255 "%d6", // 214
256 "%d7", // 215
257 "%d8", // 216
258 "%d9", // 217
259 "%da", // 218
260 "%db", // 219
261 "%dc", // 220
262 "%dd", // 221
263 "%de", // 222
264 "%df", // 223
265 "%e0", // 224
266 "%e1", // 225
267 "%e2", // 226
268 "%e3", // 227
269 "%e4", // 228
270 "%e5", // 229
271 "%e6", // 230
272 "%e7", // 231
273 "%e8", // 232
274 "%e9", // 233
275 "%ea", // 234
276 "%eb", // 235
277 "%ec", // 236
278 "%ed", // 237
279 "%ee", // 238
280 "%ef", // 239
281 "%f0", // 240
282 "%f1", // 241
283 "%f2", // 242
284 "%f3", // 243
285 "%f4", // 244
286 "%f5", // 245
287 "%f6", // 246
288 "%f7", // 247
289 "%f8", // 248
290 "%f9", // 249
291 "%fa", // 250
292 "%fb", // 251
293 "%fc", // 252
294 "%fd", // 253
295 "%fe", // 254
296 "%ff" // 255
297};
298
299LLURI::LLURI()
300{
301}
302
303LLURI::LLURI(const std::string& escaped_str)
304{
305 std::string::size_type delim_pos, delim_pos2;
306 delim_pos = escaped_str.find(':');
307 std::string temp;
308 if (delim_pos == std::string::npos)
309 {
310 mScheme = "";
311 mEscapedOpaque = escaped_str;
312 }
313 else
314 {
315 mScheme = escaped_str.substr(0, delim_pos);
316 mEscapedOpaque = escaped_str.substr(delim_pos+1);
317 }
318
319 if (mScheme == "http" || mScheme == "https" || mScheme == "ftp")
320 {
321 if (mEscapedOpaque.substr(0,2) != "//")
322 {
323 return;
324 }
325
326 delim_pos = mEscapedOpaque.find('/', 2);
327 delim_pos2 = mEscapedOpaque.find('?', 2);
328 // no path, no query
329 if (delim_pos == std::string::npos &&
330 delim_pos2 == std::string::npos)
331 {
332 mEscapedAuthority = mEscapedOpaque.substr(2);
333 mEscapedPath = "";
334 }
335 // path exist, no query
336 else if (delim_pos2 == std::string::npos)
337 {
338 mEscapedAuthority = mEscapedOpaque.substr(2,delim_pos-2);
339 mEscapedPath = mEscapedOpaque.substr(delim_pos);
340 }
341 // no path, only query
342 else if (delim_pos == std::string::npos ||
343 delim_pos2 < delim_pos)
344 {
345 mEscapedAuthority = mEscapedOpaque.substr(2,delim_pos2-2);
346 // query part will be broken out later
347 mEscapedPath = mEscapedOpaque.substr(delim_pos2);
348 }
349 // path and query
350 else
351 {
352 mEscapedAuthority = mEscapedOpaque.substr(2,delim_pos-2);
353 // query part will be broken out later
354 mEscapedPath = mEscapedOpaque.substr(delim_pos);
355 }
356 }
357
358 delim_pos = mEscapedPath.find('?');
359 if (delim_pos != std::string::npos)
360 {
361 mEscapedQuery = mEscapedPath.substr(delim_pos+1);
362 mEscapedPath = mEscapedPath.substr(0,delim_pos);
363 }
364}
365
366LLURI::~LLURI()
367{
368}
369
370
371LLURI LLURI::buildHTTP(const std::string& host_port,
372 const LLSD& path)
373{
374 LLURI result;
375 result.mScheme = "HTTP";
376 // TODO: deal with '/' '?' '#' in host_port
377 result.mEscapedAuthority = "//" + escape(host_port);
378 if (path.isArray())
379 {
380 // break out and escape each path component
381 for (LLSD::array_const_iterator it = path.beginArray();
382 it != path.endArray();
383 ++it)
384 {
385 lldebugs << "PATH: inserting " << it->asString() << llendl;
386 result.mEscapedPath += "/" + escape(it->asString());
387 }
388 }
389 result.mEscapedOpaque = result.mEscapedAuthority +
390 result.mEscapedPath;
391 return result;
392}
393
394// static
395LLURI LLURI::buildHTTP(const std::string& host_port,
396 const LLSD& path,
397 const LLSD& query)
398{
399 LLURI result = buildHTTP(host_port, path);
400 // break out and escape each query component
401 if (query.isMap())
402 {
403 for (LLSD::map_const_iterator it = query.beginMap();
404 it != query.endMap();
405 it++)
406 {
407 result.mEscapedQuery += escape(it->first) +
408 (it->second.isUndefined() ? "" : "=" + it->second.asString()) +
409 "&";
410 }
411 if (query.size() > 0)
412 {
413 result.mEscapedOpaque += "?" + result.mEscapedQuery;
414 }
415 }
416 return result;
417}
418
419std::string LLURI::asString() const
420{
421 if (mScheme.empty())
422 {
423 return mEscapedOpaque;
424 }
425 else
426 {
427 return mScheme + ":" + mEscapedOpaque;
428 }
429}
430
431std::string LLURI::scheme() const
432{
433 return mScheme;
434}
435
436std::string LLURI::opaque() const
437{
438 return unescape(mEscapedOpaque);
439}
440
441std::string LLURI::authority() const
442{
443 return unescape(mEscapedAuthority);
444}
445
446
447namespace {
448 void findAuthorityParts(const std::string& authority,
449 std::string& user,
450 std::string& host,
451 std::string& port)
452 {
453 std::string::size_type start_pos = authority.find('@');
454 if (start_pos == std::string::npos)
455 {
456 user = "";
457 start_pos = 0;
458 }
459 else
460 {
461 user = authority.substr(0, start_pos);
462 start_pos += 1;
463 }
464
465 std::string::size_type end_pos = authority.find(':', start_pos);
466 if (end_pos == std::string::npos)
467 {
468 host = authority.substr(start_pos);
469 port = "";
470 }
471 else
472 {
473 host = authority.substr(start_pos, end_pos - start_pos);
474 port = authority.substr(end_pos + 1);
475 }
476 }
477}
478
479std::string LLURI::hostName() const
480{
481 std::string user, host, port;
482 findAuthorityParts(mEscapedAuthority, user, host, port);
483 return unescape(host);
484}
485
486U16 LLURI::hostPort() const
487{
488 std::string user, host, port;
489 findAuthorityParts(mEscapedAuthority, user, host, port);
490 if (port.empty())
491 {
492 if (mScheme == "http")
493 return 80;
494 if (mScheme == "https")
495 return 443;
496 if (mScheme == "ftp")
497 return 21;
498 return 0;
499 }
500 return atoi(port.c_str());
501}
502
503std::string LLURI::path() const
504{
505 return unescape(mEscapedPath);
506}
507
508std::string LLURI::query() const
509{
510 return unescape(mEscapedQuery);
511}
512
513LLSD LLURI::queryMap() const
514{
515 return queryMap(mEscapedQuery);
516}
517
518// static
519LLSD LLURI::queryMap(std::string escaped_query_string)
520{
521 lldebugs << "LLURI::queryMap query params: " << escaped_query_string << llendl;
522
523 LLSD result = LLSD::emptyArray();
524 while(!escaped_query_string.empty())
525 {
526 // get tuple first
527 std::string tuple;
528 std::string::size_type tuple_begin = escaped_query_string.find('&');
529 if (tuple_begin != std::string::npos)
530 {
531 tuple = escaped_query_string.substr(0, tuple_begin);
532 escaped_query_string = escaped_query_string.substr(tuple_begin+1);
533 }
534 else
535 {
536 tuple = escaped_query_string;
537 escaped_query_string = "";
538 }
539 if (tuple.empty()) continue;
540
541 // parse tuple
542 std::string::size_type key_end = tuple.find('=');
543 if (key_end != std::string::npos)
544 {
545 std::string key = unescape(tuple.substr(0,key_end));
546 std::string value = unescape(tuple.substr(key_end+1));
547 lldebugs << "inserting key " << key << " value " << value << llendl;
548 result[key] = value;
549 }
550 else
551 {
552 lldebugs << "inserting key " << unescape(tuple) << " value true" << llendl;
553 result[unescape(tuple)] = true;
554 }
555 }
556 return result;
557}
558
559// static
560std::string LLURI::escape(const std::string& str)
561{
562 std::ostringstream ostr;
563 std::string::const_iterator it = str.begin();
564 std::string::const_iterator end = str.end();
565 S32 c;
566 for(; it != end; ++it)
567 {
568 c = (S32)(*it);
569 ostr << ESCAPED_CHARACTERS[c];
570 }
571 return ostr.str();
572}
573
574// static
575std::string LLURI::unescape(const std::string& str)
576{
577 std::ostringstream ostr;
578 std::string::const_iterator it = str.begin();
579 std::string::const_iterator end = str.end();
580 for(; it != end; ++it)
581 {
582 if((*it) == '%')
583 {
584 ++it;
585 if(it == end) break;
586 U8 c = hex_as_nybble(*it++);
587 c = c << 4;
588 if (it == end) break;
589 c |= hex_as_nybble(*it);
590 ostr.put((char)c);
591 }
592 else
593 {
594 ostr.put(*it);
595 }
596 }
597 return ostr.str();
598}