diff options
Diffstat (limited to 'indra/llcommon/lluri.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/llcommon/lluri.cpp | 116 |
1 files changed, 79 insertions, 37 deletions
diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp index 9d4f3a98f0..9f12d49244 100644..100755 --- a/indra/llcommon/lluri.cpp +++ b/indra/llcommon/lluri.cpp @@ -4,31 +4,25 @@ * @date 2006-02-08 * @brief Implementation of the LLURI class. * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -43,6 +37,8 @@ // system includes #include <boost/tokenizer.hpp> +#include <boost/algorithm/string/find_iterator.hpp> +#include <boost/algorithm/string/finder.hpp> void encode_character(std::ostream& ostr, std::string::value_type val) { @@ -133,11 +129,30 @@ std::string LLURI::unescape(const std::string& str) { ++it; if(it == end) break; - U8 c = hex_as_nybble(*it++); - c = c << 4; - if (it == end) break; - c |= hex_as_nybble(*it); - ostr.put((char)c); + + if(is_char_hex(*it)) + { + U8 c = hex_as_nybble(*it++); + + c = c << 4; + if (it == end) break; + + if(is_char_hex(*it)) + { + c |= hex_as_nybble(*it); + ostr.put((char)c); + } + else + { + ostr.put((char)c); + ostr.put(*it); + } + } + else + { + ostr.put('%'); + ostr.put(*it); + } } else { @@ -231,7 +246,8 @@ static BOOL isDefault(const std::string& scheme, U16 port) void LLURI::parseAuthorityAndPathUsingOpaque() { if (mScheme == "http" || mScheme == "https" || - mScheme == "ftp" || mScheme == "secondlife" ) + mScheme == "ftp" || mScheme == "secondlife" || + mScheme == "x-grid-location-info") { if (mEscapedOpaque.substr(0,2) != "//") { @@ -322,7 +338,7 @@ LLURI LLURI::buildHTTP(const std::string& prefix, const LLSD& path) { LLURI result; - + // TODO: deal with '/' '?' '#' in host_port if (prefix.find("://") != prefix.npos) { @@ -343,22 +359,48 @@ LLURI LLURI::buildHTTP(const std::string& prefix, it != path.endArray(); ++it) { - lldebugs << "PATH: inserting " << it->asString() << llendl; + LL_DEBUGS() << "PATH: inserting " << it->asString() << LL_ENDL; result.mEscapedPath += "/" + escapePathComponent(it->asString()); } } - else if(path.isString()) + else if (path.isString()) { - result.mEscapedPath += "/" + escapePathComponent(path.asString()); + std::string pathstr(path); + // Trailing slash is significant in HTTP land. If caller specified, + // make a point of preserving. + std::string last_slash; + std::string::size_type len(pathstr.length()); + if (len && pathstr[len-1] == '/') + { + last_slash = "/"; + } + + // Escape every individual path component, recombining with slashes. + for (boost::split_iterator<std::string::const_iterator> + ti(pathstr, boost::first_finder("/")), tend; + ti != tend; ++ti) + { + // Eliminate a leading slash or duplicate slashes anywhere. (Extra + // slashes show up here as empty components.) This test also + // eliminates a trailing slash, hence last_slash above. + if (! ti->empty()) + { + result.mEscapedPath + += "/" + escapePathComponent(std::string(ti->begin(), ti->end())); + } + } + + // Reinstate trailing slash, if any. + result.mEscapedPath += last_slash; } else if(path.isUndefined()) { // do nothing } - else + else { - llwarns << "Valid path arguments to buildHTTP are array, string, or undef, you passed type" - << path.type() << llendl; + LL_WARNS() << "Valid path arguments to buildHTTP are array, string, or undef, you passed type" + << path.type() << LL_ENDL; } result.mEscapedOpaque = "//" + result.mEscapedAuthority + result.mEscapedPath; @@ -542,7 +584,7 @@ LLSD LLURI::queryMap() const // static LLSD LLURI::queryMap(std::string escaped_query_string) { - lldebugs << "LLURI::queryMap query params: " << escaped_query_string << llendl; + LL_DEBUGS() << "LLURI::queryMap query params: " << escaped_query_string << LL_ENDL; LLSD result = LLSD::emptyArray(); while(!escaped_query_string.empty()) @@ -568,12 +610,12 @@ LLSD LLURI::queryMap(std::string escaped_query_string) { std::string key = unescape(tuple.substr(0,key_end)); std::string value = unescape(tuple.substr(key_end+1)); - lldebugs << "inserting key " << key << " value " << value << llendl; + LL_DEBUGS() << "inserting key " << key << " value " << value << LL_ENDL; result[key] = value; } else { - lldebugs << "inserting key " << unescape(tuple) << " value true" << llendl; + LL_DEBUGS() << "inserting key " << unescape(tuple) << " value true" << LL_ENDL; result[unescape(tuple)] = true; } } |