diff options
| author | Alexander Gavriliuk <alexandrgproductengine@lindenlab.com> | 2024-07-01 13:34:50 +0200 | 
|---|---|---|
| committer | Guru <alexandrgproductengine@lindenlab.com> | 2024-07-01 20:20:04 +0200 | 
| commit | 2ea5ac0c43e3e28d2b1774f5367d099271a1da32 (patch) | |
| tree | 9526c5a388f3d278e4cf2198480ff6a7ffba6be1 /indra | |
| parent | 9ab2f662f81feb6d8b1b5cdb4fd03d03406ceaa1 (diff) | |
#1111 Remove xmlrpc-epi
Diffstat (limited to 'indra')
36 files changed, 723 insertions, 1901 deletions
| diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 0f338931c0..c067105f68 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -63,7 +63,6 @@ set(cmake_SOURCE_FILES          VisualLeakDetector.cmake          LibVLCPlugin.cmake          WebRTC.cmake -        XmlRpcEpi.cmake          xxHash.cmake          ZLIBNG.cmake          ) diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index 9e3707ff17..dd43ca4916 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -6,5 +6,3 @@ include(EXPAT)  include(Tracy)  include(xxHash)  include(ZLIBNG) - -include(XmlRpcEpi) diff --git a/indra/cmake/XmlRpcEpi.cmake b/indra/cmake/XmlRpcEpi.cmake deleted file mode 100644 index 6409f9d6e2..0000000000 --- a/indra/cmake/XmlRpcEpi.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -*- cmake -*- -include(Prebuilt) - -include_guard() -add_library( ll::xmlrpc-epi INTERFACE IMPORTED ) - -use_system_binary( xmlrpc-epi ) - -use_prebuilt_binary(xmlrpc-epi) -target_link_libraries(ll::xmlrpc-epi INTERFACE xmlrpc-epi ) -target_include_directories( ll::xmlrpc-epi SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index ddf239f306..9045324bf2 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -248,6 +248,24 @@ int LLFile::close(LLFILE * file)      return ret_value;  } +std::string LLFile::getContents(const std::string& filename) +{ +    LLFILE* fp = fopen(filename, "rb"); /* Flawfinder: ignore */ +    if (fp) +    { +        fseek(fp, 0, SEEK_END); +        U32 length = ftell(fp); +        fseek(fp, 0, SEEK_SET); + +        std::vector<char> buffer(length); +        size_t nread = fread(buffer.data(), 1, length, fp); +        fclose(fp); + +        return std::string(buffer.data(), nread); +    } + +    return LLStringUtil::null; +}  int LLFile::remove(const std::string& filename, int supress_error)  { diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 2564671b13..74110343fc 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -67,6 +67,8 @@ public:      static  int     close(LLFILE * file); +    static std::string getContents(const std::string& filename); +      // perms is a permissions mask like 0777 or 0700.  In most cases it will      // be overridden by the user's umask.  It is ignored on Windows.      // mkdir() considers "directory already exists" to be SUCCESS. diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 663ceac22b..b36ff7d263 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -30,6 +30,7 @@  #include "linden_common.h"  #include "llsd.h" +#include "llbase64.h"  #include "llerror.h"  #include "../llmath/llmath.h"  #include "llformat.h" @@ -142,6 +143,8 @@ public:      virtual const String& asStringRef() const { static const std::string empty; return empty; } +    virtual String asXMLRPCValue() const { return "<nil/>"; } +      virtual bool has(const String&) const       { return false; }      virtual LLSD get(const String&) const       { return LLSD(); }      virtual LLSD getKeys() const                { return LLSD::emptyArray(); } @@ -222,6 +225,8 @@ namespace          virtual LLSD::Integer   asInteger() const   { return mValue ? 1 : 0; }          virtual LLSD::Real      asReal() const      { return mValue ? 1 : 0; }          virtual LLSD::String    asString() const; + +        virtual LLSD::String asXMLRPCValue() const { return mValue ? "<boolean>1</boolean>" : "<boolean>0</boolean>"; }      };      LLSD::String ImplBoolean::asString() const @@ -243,6 +248,8 @@ namespace          virtual LLSD::Integer   asInteger() const   { return mValue; }          virtual LLSD::Real      asReal() const      { return mValue; }          virtual LLSD::String    asString() const; + +        virtual LLSD::String asXMLRPCValue() const { return "<int>" + std::to_string(mValue) + "</int>"; }      };      LLSD::String ImplInteger::asString() const @@ -259,6 +266,8 @@ namespace          virtual LLSD::Integer   asInteger() const;          virtual LLSD::Real      asReal() const      { return mValue; }          virtual LLSD::String    asString() const; + +        virtual LLSD::String asXMLRPCValue() const { return "<double>" + std::to_string(mValue) + "</double>"; }      };      LLSD::Boolean ImplReal::asBoolean() const @@ -286,9 +295,11 @@ namespace          virtual LLSD::URI       asURI() const   { return LLURI(mValue); }          virtual size_t          size() const    { return mValue.size(); }          virtual const LLSD::String& asStringRef() const { return mValue; } + +        virtual LLSD::String asXMLRPCValue() const { return "<string>" + LLStringFn::xml_encode(mValue) + "</string>"; }      }; -    LLSD::Integer   ImplString::asInteger() const +    LLSD::Integer ImplString::asInteger() const      {          // This must treat "1.23" not as an error, but as a number, which is          // then truncated down to an integer.  Hence, this code doesn't call @@ -298,7 +309,7 @@ namespace          return (int)asReal();      } -    LLSD::Real      ImplString::asReal() const +    LLSD::Real ImplString::asReal() const      {          F64 v = 0.0;          std::istringstream i_stream(mValue); @@ -323,6 +334,8 @@ namespace          virtual LLSD::String    asString() const{ return mValue.asString(); }          virtual LLSD::UUID      asUUID() const  { return mValue; } + +        virtual LLSD::String asXMLRPCValue() const { return "<string>" + mValue.asString() + "</string>"; }      }; @@ -344,6 +357,8 @@ namespace          }          virtual LLSD::String    asString() const{ return mValue.asString(); }          virtual LLSD::Date      asDate() const  { return mValue; } + +        virtual LLSD::String asXMLRPCValue() const { return "<dateTime.iso8601>" + mValue.toHTTPDateString("%FT%T") + "</dateTime.iso8601>"; }      }; @@ -355,6 +370,8 @@ namespace          virtual LLSD::String    asString() const{ return mValue.asString(); }          virtual LLSD::URI       asURI() const   { return mValue; } + +        virtual LLSD::String asXMLRPCValue() const { return "<string>" + LLStringFn::xml_encode(mValue.asString()) + "</string>"; }      }; @@ -365,13 +382,15 @@ namespace          ImplBinary(const LLSD::Binary& v) : Base(v) { }          virtual const LLSD::Binary& asBinary() const{ return mValue; } + +        virtual LLSD::String asXMLRPCValue() const { return "<base64>" + LLBase64::encode(mValue.data(), mValue.size()) + "</base64>"; }      };      class ImplMap : public LLSD::Impl      {      private: -        typedef std::map<LLSD::String, LLSD>    DataMap; +        typedef std::map<LLSD::String, LLSD> DataMap;          DataMap mData; @@ -387,6 +406,19 @@ namespace          virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } +        virtual LLSD::String asXMLRPCValue() const +        { +            std::ostringstream os; +            os << "<struct>"; +            for (const auto& it : mData) +            { +                os << "<member><name>" << LLStringFn::xml_encode(it.first) << "</name>" +                    << it.second.asXMLRPCValue() << "</member>"; +            } +            os << "</struct>"; +            return os.str(); +        } +          virtual bool has(const LLSD::String&) const;          using LLSD::Impl::get; // Unhiding get(size_t) @@ -511,7 +543,7 @@ namespace      class ImplArray : public LLSD::Impl      {      private: -        typedef std::vector<LLSD>   DataVector; +        typedef std::vector<LLSD> DataVector;          DataVector mData; @@ -527,6 +559,18 @@ namespace          virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } +        virtual LLSD::String asXMLRPCValue() const +        { +            std::ostringstream os; +            os << "<array><data>"; +            for (const auto& it : mData) +            { +                os << it.asXMLRPCValue(); +            } +            os << "</data></array>"; +            return os.str(); +        } +          using LLSD::Impl::get; // Unhiding get(LLSD::String)          using LLSD::Impl::erase; // Unhiding erase(LLSD::String)          using LLSD::Impl::ref; // Unhiding ref(LLSD::String) @@ -872,6 +916,155 @@ const LLSD::Binary& LLSD::asBinary() const  { return safe(impl).asBinary(); }  const LLSD::String& LLSD::asStringRef() const { return safe(impl).asStringRef(); } +LLSD::String LLSD::asXMLRPCValue() const { return "<value>" + safe(impl).asXMLRPCValue() + "</value>"; } + +static bool inline check(bool condition, const char* warning_message) +{ +    if (!condition) +    { +        LL_WARNS() << warning_message << LL_ENDL; +    } + +    return condition; +} + +static bool parseXMLRPCArrayValue(LLSD& target, LLSD::TreeNode* node) +{ +    LLSD::TreeNode* data = node->getFirstChild(); +    if (!check(data, "No array inner XML element (<data> expected)") || +        !check(data->hasName("data"), "Invalid array inner XML element (<data> expected)") || +        !check(!data->getNextSibling(), "Multiple array inner XML elements (single <data> expected)")) +        return false; + +    for (LLSD::TreeNode* item = data->getFirstChild(); item; item = item->getNextSibling()) +    { +        LLSD value; +        if (!value.fromXMLRPCValue(item)) +            return false; + +        target.append(value); +    } + +    return true; +} + +static bool parseXMLRPCStructValue(LLSD& target, LLSD::TreeNode* node) +{ +    for (LLSD::TreeNode* item = node->getFirstChild(); item; item = item->getNextSibling()) +    { +        if (!check(item->hasName("member"), "Invalid struct inner XML element (<member> expected)")) +            return false; + +        std::string name; +        LLSD value; +        for (LLSD::TreeNode* subitem = item->getFirstChild(); subitem; subitem = subitem->getNextSibling()) +        { +            if (subitem->hasName("name")) +            { +                name = LLStringFn::xml_decode(subitem->getTextContents()); +            } +            else if (!value.fromXMLRPCValue(subitem)) +            { +                return false; +            } +        } +        if (!check(!name.empty(), "Empty struct member name")) +            return false; + +        target.insert(name, value); +    } + +    return true; +} + +bool LLSD::fromXMLRPCValue(TreeNode* node) +{ +    clear(); + +    llassert(node); +    if (!node) +        return false; + +    if (!check(node->hasName("value"), "Invalid XML element (<value> expected)")) +        return false; + +    TreeNode* inner = node->getFirstChild(); +    if (!inner) +    { +        check(false, "No inner XML element (value type expected)"); +        // Value with no type qualifier is treated as string +        assign(LLStringFn::xml_decode(node->getTextContents())); +        return true; +    } + +    if (!check(!inner->getNextSibling(), "Multiple inner XML elements (single expected)")) +        return false; + +    if (inner->hasName("string")) +    { +        assign(LLStringFn::xml_decode(inner->getTextContents())); +        return true; +    } + +    if (inner->hasName("int") || inner->hasName("i4")) +    { +        assign(std::stoi(inner->getTextContents())); +        return true; +    } + +    if (inner->hasName("double")) +    { +        assign(std::stod(inner->getTextContents())); +        return true; +    } + +    if (inner->hasName("boolean")) +    { +        assign(!!std::stoi(inner->getTextContents())); +        return true; +    } + +    if (inner->hasName("dateTime.iso8601")) +    { +        assign(Date(inner->getTextContents())); +        return true; +    } + +    if (inner->hasName("base64")) +    { +        std::string decoded = LLBase64::decodeAsString(inner->getTextContents()); +        Binary binary(decoded.size()); +        memcpy(binary.data(), decoded.data(), decoded.size()); +        assign(binary); +        return true; +    } + +    if (inner->hasName("array")) +    { +        if (!parseXMLRPCArrayValue(*this, inner)) +        { +            clear(); +            return false; +        } +        return true; +    } + +    if (inner->hasName("struct")) +    { +        if (!parseXMLRPCStructValue(*this, inner)) +        { +            clear(); +            return false; +        } +        return true; +    } + +    check(false, "Unknown inner XML element (known value type expected)"); +    // Value with unknown type qualifier is treated as string +    assign(LLStringFn::xml_decode(inner->getTextContents())); +    return true; +} +  // const char * helpers  LLSD::LLSD(const char* v) : impl(0)     { ALLOC_LLSD_OBJECT;    assign(v); }  void LLSD::assign(const char* v) diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index a5e735b561..5532decfc3 100644 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -259,10 +259,24 @@ public:          UUID    asUUID() const;          Date    asDate() const;          URI     asURI() const; -        const Binary&   asBinary() const; +        const Binary& asBinary() const;          // asStringRef on any non-string type will return a ref to an empty string. -        const String&   asStringRef() const; +        const String& asStringRef() const; + +        // Return "<value><((type))>((scalar value or recursive calls))</((type))></value>" +        // See http://xmlrpc.com/spec.md +        String asXMLRPCValue() const; + +        struct TreeNode +        { +            virtual bool hasName(const String& name) const = 0; +            virtual String getTextContents() const = 0; +            virtual TreeNode* getFirstChild() const = 0; +            virtual TreeNode* getNextSibling() const = 0; +        }; + +        bool fromXMLRPCValue(TreeNode* node);          operator Boolean() const    { return asBoolean(); }          operator Integer() const    { return asInteger(); } @@ -275,7 +289,7 @@ public:          // This is needed because most platforms do not automatically          // convert the boolean negation as a bool in an if statement. -        bool operator!() const {return !asBoolean();} +        bool operator!() const { return !asBoolean(); }      //@}      /** @name Character Pointer Helpers diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 514d73b24b..6f3d193d6b 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -1208,6 +1208,75 @@ namespace LLStringFn          return output;      } +    using literals_t = std::map<char, std::string>; +    static const literals_t xml_elem_literals = +    { +        { '<', "<" }, +        { '>', ">" }, +        { '&', "&" } +    }; +    static const literals_t xml_attr_literals = +    { +        { '"', """ }, +        { '\'', "'" } +    }; + +    static void literals_encode(std::string& text, const literals_t& literals) +    { +        for (const std::pair<char, std::string> it : literals) +        { +            std::string::size_type pos = 0; +            while ((pos = text.find(it.first, pos)) != std::string::npos) +            { +                text.replace(pos, 1, it.second); +                pos += it.second.size(); +            } +        } +    } + +    static void literals_decode(std::string& text, const literals_t& literals) +    { +        for (const std::pair<char, std::string> it : literals) +        { +            std::string::size_type pos = 0; +            while ((pos = text.find(it.second, pos)) != std::string::npos) +            { +                text[pos++] = it.first; +                text.erase(pos, it.second.size() - 1); +            } +        } +    } + +    /** +     * @brief Replace all characters that are not allowed in XML 1.0 +     * with corresponding literals: [ < > & ] => [ < > & ] +     */ +    std::string xml_encode(const std::string& input, bool for_attribute) +    { +        std::string result(input); +        literals_encode(result, xml_elem_literals); +        if (for_attribute) +        { +            literals_encode(result, xml_attr_literals); +        } +        return result; +    } + +    /** +     * @brief Replace some of XML literals that are defined in XML 1.0 +     * with corresponding characters: [ < > & ] => [ < > & ] +     */ +    std::string xml_decode(const std::string& input, bool for_attribute) +    { +        std::string result(input); +        literals_decode(result, xml_elem_literals); +        if (for_attribute) +        { +            literals_decode(result, xml_attr_literals); +        } +        return result; +    } +      /**       * @brief Replace all control characters (c < 0x20) with replacement in       * string. diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 123f4184b5..b69a068830 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -890,6 +890,20 @@ namespace LLStringFn      /** +     * @brief Replace all characters that are not allowed in XML 1.0 +     * with corresponding literals: [ < > & ] => [ < > & ] +     */ +    LL_COMMON_API std::string xml_encode(const std::string& input, bool for_attribute = false); + + +    /** +     * @brief Replace some of XML literals that are defined in XML 1.0 +     * with corresponding characters: [ < > & ] => [ < > & ] +     */ +    LL_COMMON_API std::string xml_decode(const std::string& input, bool for_attribute = false); + + +    /**       * @brief Replace all control characters (0 <= c < 0x20) with replacement in       * string.   This is safe for utf-8       * diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 5322139304..b2757a7306 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -27,7 +27,6 @@ set(llmessage_SOURCE_FILES      lldatapacker.cpp      lldispatcher.cpp      llexperiencecache.cpp -    llfiltersd2xmlrpc.cpp      llgenericstreamingmessage.cpp      llhost.cpp      llhttpnode.cpp @@ -111,7 +110,6 @@ set(llmessage_HEADER_FILES      lleventflags.h      llexperiencecache.h      llextendedstatus.h -    llfiltersd2xmlrpc.h      llfollowcamparams.h      llgenericstreamingmessage.h      llhost.h @@ -193,7 +191,6 @@ target_link_libraries(          llfilesystem          llmath          llcorehttp -        ll::xmlrpc-epi  )  target_include_directories( llmessage  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp deleted file mode 100644 index 84b56d54bf..0000000000 --- a/indra/llmessage/llfiltersd2xmlrpc.cpp +++ /dev/null @@ -1,778 +0,0 @@ -/** - * @file llfiltersd2xmlrpc.cpp - * @author Phoenix - * @date 2005-04-26 - * - * $LicenseInfo:firstyear=2005&license=viewerlgpl$ - * Second Life Viewer Source Code - * 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. - * - * 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. - * - * 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 - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -/** - * xml rpc request: - * <code> - * <?xml version="1.0"?> - * <methodCall><methodName>examples.getStateName</methodName> - * <params><param><value><i4>41</i4></value></param></params> - * </methodCall> - * </code> - * - * xml rpc response: - * <code> - * <?xml version="1.0"?> - * <methodResponse> - * <params><param><value><string>South Dakota</string></value></param></params> - * </methodResponse> - * </code> - * - * xml rpc fault: - * </code> - * <?xml version="1.0"?> - * <methodResponse> - * <fault><value><struct> - * <member><name>faultCode</name><value><int>4</int></value></member> - * <member><name>faultString</name><value><string>...</string></value></member> - * </struct></value></fault> - * </methodResponse> - * </code> - * - * llsd rpc request: - * <code> - * { 'method':'...', 'parameter':...]} - * </code> - * - * llsd rpc response: - * <code> - * { 'response':... } - * </code> - * - * llsd rpc fault: - * <code> - * { 'fault': {'code':i..., 'description':'...'} } - * </code> - * - */ - -#include "linden_common.h" -#include "llfiltersd2xmlrpc.h" - -#include <sstream> -#include <iterator> - -#ifdef LL_USESYSTEMLIBS -#include <xmlrpc.h> -#else -#include <xmlrpc-epi/xmlrpc.h> -#endif - -#include "apr_base64.h" - -#include "llbuffer.h" -#include "llbufferstream.h" -#include "llfasttimer.h" -#include "llmemorystream.h" -#include "llsd.h" -#include "llsdserialize.h" -#include "lluuid.h" - -// spammy mode -//#define LL_SPEW_STREAM_OUT_DEBUGGING 1 - -/** - * String constants - */ -static const char XML_HEADER[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; -static const char XMLRPC_REQUEST_HEADER_1[] = "<methodCall><methodName>"; -static const char XMLRPC_REQUEST_HEADER_2[] = "</methodName><params>"; -static const char XMLRPC_REQUEST_FOOTER[] = "</params></methodCall>"; -static const char XMLRPC_METHOD_RESPONSE_HEADER[] = "<methodResponse>"; -static const char XMLRPC_METHOD_RESPONSE_FOOTER[] = "</methodResponse>"; -static const char XMLRPC_RESPONSE_HEADER[] = "<params><param>"; -static const char XMLRPC_RESPONSE_FOOTER[] = "</param></params>"; -static const char XMLRPC_FAULT_1[] = "<fault><value><struct><member><name>faultCode</name><value><int>"; -static const char XMLRPC_FAULT_2[] = "</int></value></member><member><name>faultString</name><value><string>"; -static const char XMLRPC_FAULT_3[] = "</string></value></member></struct></value></fault>"; -static const char LLSDRPC_RESPONSE_HEADER[] = "{'response':"; -static const char LLSDRPC_RESPONSE_FOOTER[] = "}"; -const char LLSDRPC_REQUEST_HEADER_1[] = "{'method':'"; -const char LLSDRPC_REQUEST_HEADER_2[] = "', 'parameter': "; -const char LLSDRPC_REQUEST_FOOTER[] = "}"; -static const char LLSDRPC_FAULT_HADER_1[] = "{ 'fault': {'code':i"; -static const char LLSDRPC_FAULT_HADER_2[] = ", 'description':"; -static const char LLSDRPC_FAULT_FOOTER[] = "} }"; -static const S32 DEFAULT_PRECISION = 20; - -/** - * LLFilterSD2XMLRPC - */ -LLFilterSD2XMLRPC::LLFilterSD2XMLRPC() -{ -} - -LLFilterSD2XMLRPC::~LLFilterSD2XMLRPC() -{ -} - -std::string xml_escape_string(const std::string& in) -{ -    std::ostringstream out; -    std::string::const_iterator it = in.begin(); -    std::string::const_iterator end = in.end(); -    for(; it != end; ++it) -    { -        switch((*it)) -        { -        case '<': -            out << "<"; -            break; -        case '>': -            out << ">"; -            break; -        case '&': -            out << "&"; -            break; -        case '\'': -            out << "'"; -            break; -        case '"': -            out << """; -            break; -        default: -            out << (*it); -            break; -        } -    } -    return out.str(); -} - -void LLFilterSD2XMLRPC::streamOut(std::ostream& ostr, const LLSD& sd) -{ -    ostr << "<value>"; -    switch(sd.type()) -    { -    case LLSD::TypeMap: -    { -#if LL_SPEW_STREAM_OUT_DEBUGGING -        LL_INFOS() << "streamOut(map) BEGIN" << LL_ENDL; -#endif -        ostr << "<struct>"; -        if(ostr.fail()) -        { -            LL_INFOS() << "STREAM FAILURE writing struct" << LL_ENDL; -        } -        LLSD::map_const_iterator it = sd.beginMap(); -        LLSD::map_const_iterator end = sd.endMap(); -        for(; it != end; ++it) -        { -            ostr << "<member><name>" << xml_escape_string((*it).first) -                << "</name>"; -            streamOut(ostr, (*it).second); -            if(ostr.fail()) -            { -                LL_INFOS() << "STREAM FAILURE writing '" << (*it).first -                        << "' with sd type " << (*it).second.type() << LL_ENDL; -            } -            ostr << "</member>"; -        } -        ostr << "</struct>"; -#if LL_SPEW_STREAM_OUT_DEBUGGING -        LL_INFOS() << "streamOut(map) END" << LL_ENDL; -#endif -        break; -    } -    case LLSD::TypeArray: -    { -#if LL_SPEW_STREAM_OUT_DEBUGGING -        LL_INFOS() << "streamOut(array) BEGIN" << LL_ENDL; -#endif -        ostr << "<array><data>"; -        LLSD::array_const_iterator it = sd.beginArray(); -        LLSD::array_const_iterator end = sd.endArray(); -        for(; it != end; ++it) -        { -            streamOut(ostr, *it); -            if(ostr.fail()) -            { -                LL_INFOS() << "STREAM FAILURE writing array element sd type " -                        << (*it).type() << LL_ENDL; -            } -        } -#if LL_SPEW_STREAM_OUT_DEBUGGING -        LL_INFOS() << "streamOut(array) END" << LL_ENDL; -#endif -        ostr << "</data></array>"; -        break; -    } -    case LLSD::TypeUndefined: -        // treat undefined as a bool with a false value. -    case LLSD::TypeBoolean: -#if LL_SPEW_STREAM_OUT_DEBUGGING -        LL_INFOS() << "streamOut(bool)" << LL_ENDL; -#endif -        ostr << "<boolean>" << (sd.asBoolean() ? "1" : "0") << "</boolean>"; -        break; -    case LLSD::TypeInteger: -#if LL_SPEW_STREAM_OUT_DEBUGGING -        LL_INFOS() << "streamOut(int)" << LL_ENDL; -#endif -        ostr << "<i4>" << sd.asInteger() << "</i4>"; -        break; -    case LLSD::TypeReal: -#if LL_SPEW_STREAM_OUT_DEBUGGING -        LL_INFOS() << "streamOut(real)" << LL_ENDL; -#endif -        ostr << "<double>" << sd.asReal() << "</double>"; -        break; -    case LLSD::TypeString: -#if LL_SPEW_STREAM_OUT_DEBUGGING -        LL_INFOS() << "streamOut(string)" << LL_ENDL; -#endif -        ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>"; -        break; -    case LLSD::TypeUUID: -#if LL_SPEW_STREAM_OUT_DEBUGGING -        LL_INFOS() << "streamOut(uuid)" << LL_ENDL; -#endif -        // serialize it as a string -        ostr << "<string>" << sd.asString() << "</string>"; -        break; -    case LLSD::TypeURI: -    { -#if LL_SPEW_STREAM_OUT_DEBUGGING -        LL_INFOS() << "streamOut(uri)" << LL_ENDL; -#endif -        // serialize it as a string -        ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>"; -        break; -    } -    case LLSD::TypeBinary: -    { -#if LL_SPEW_STREAM_OUT_DEBUGGING -        LL_INFOS() << "streamOut(binary)" << LL_ENDL; -#endif -        // this is pretty inefficient, but we'll deal with that -        // problem when it becomes one. -        ostr << "<base64>"; -        LLSD::Binary buffer = sd.asBinary(); -        if(!buffer.empty()) -        { -            // *TODO: convert to LLBase64 -            int b64_buffer_length = apr_base64_encode_len(static_cast<int>(buffer.size())); -            char* b64_buffer = new char[b64_buffer_length]; -            b64_buffer_length = apr_base64_encode_binary( -                b64_buffer, -                &buffer[0], -                static_cast<int>(buffer.size())); -            ostr.write(b64_buffer, b64_buffer_length - 1); -            delete[] b64_buffer; -        } -        ostr << "</base64>"; -        break; -    } -    case LLSD::TypeDate: -#if LL_SPEW_STREAM_OUT_DEBUGGING -        LL_INFOS() << "streamOut(date)" << LL_ENDL; -#endif -        // no need to escape this since it will be alpha-numeric. -        ostr << "<dateTime.iso8601>" << sd.asString() << "</dateTime.iso8601>"; -        break; -    default: -        // unhandled type -        LL_WARNS() << "Unhandled structured data type: " << sd.type() -            << LL_ENDL; -        break; -    } -    ostr << "</value>"; -} - -/** - * LLFilterSD2XMLRPCResponse - */ - -LLFilterSD2XMLRPCResponse::LLFilterSD2XMLRPCResponse() -{ -} - -LLFilterSD2XMLRPCResponse::~LLFilterSD2XMLRPCResponse() -{ -} - - -// virtual -LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl( -    const LLChannelDescriptors& channels, -    buffer_ptr_t& buffer, -    bool& eos, -    LLSD& context, -    LLPumpIO* pump) -{ -    LL_PROFILE_ZONE_SCOPED; - -    PUMP_DEBUG; -    // This pipe does not work if it does not have everyting. This -    // could be addressed by making a stream parser for llsd which -    // handled partial information. -    if(!eos) -    { -        return STATUS_BREAK; -    } - -    PUMP_DEBUG; -    // we have everyting in the buffer, so turn the structure data rpc -    // response into an xml rpc response. -    LLBufferStream stream(channels, buffer.get()); -    stream << XML_HEADER << XMLRPC_METHOD_RESPONSE_HEADER; -    LLSD sd; -    LLSDSerialize::fromNotation(sd, stream, buffer->count(channels.in())); - -    PUMP_DEBUG; -    LLIOPipe::EStatus rv = STATUS_ERROR; -    if(sd.has("response")) -    { -        PUMP_DEBUG; -        // it is a normal response. pack it up and ship it out. -        stream.precision(DEFAULT_PRECISION); -        stream << XMLRPC_RESPONSE_HEADER; -        streamOut(stream, sd["response"]); -        stream << XMLRPC_RESPONSE_FOOTER << XMLRPC_METHOD_RESPONSE_FOOTER; -        rv = STATUS_DONE; -    } -    else if(sd.has("fault")) -    { -        PUMP_DEBUG; -        // it is a fault. -        stream << XMLRPC_FAULT_1 << sd["fault"]["code"].asInteger() -            << XMLRPC_FAULT_2 -            << xml_escape_string(sd["fault"]["description"].asString()) -            << XMLRPC_FAULT_3 << XMLRPC_METHOD_RESPONSE_FOOTER; -        rv = STATUS_DONE; -    } -    else -    { -        LL_WARNS() << "Unable to determine the type of LLSD response." << LL_ENDL; -    } -    PUMP_DEBUG; -    return rv; -} - -/** - * LLFilterSD2XMLRPCRequest - */ -LLFilterSD2XMLRPCRequest::LLFilterSD2XMLRPCRequest() -{ -} - -LLFilterSD2XMLRPCRequest::LLFilterSD2XMLRPCRequest(const char* method) -{ -    if(method) -    { -        mMethod.assign(method); -    } -} - -LLFilterSD2XMLRPCRequest::~LLFilterSD2XMLRPCRequest() -{ -} - -// virtual -LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl( -    const LLChannelDescriptors& channels, -    buffer_ptr_t& buffer, -    bool& eos, -    LLSD& context, -    LLPumpIO* pump) -{ -    LL_PROFILE_ZONE_SCOPED; -    // This pipe does not work if it does not have everyting. This -    // could be addressed by making a stream parser for llsd which -    // handled partial information. -    PUMP_DEBUG; -    if(!eos) -    { -        LL_INFOS() << "!eos" << LL_ENDL; -        return STATUS_BREAK; -    } - -    // See if we can parse it -    LLBufferStream stream(channels, buffer.get()); -    LLSD sd; -    LLSDSerialize::fromNotation(sd, stream, buffer->count(channels.in())); -    if(stream.fail()) -    { -        LL_INFOS() << "STREAM FAILURE reading structure data." << LL_ENDL; -    } - -    PUMP_DEBUG; -    // We can get the method and parameters from either the member -    // function or passed in via the buffer. We prefer the buffer if -    // we found a parameter and a method, or fall back to using -    // mMethod and putting everyting in the buffer into the parameter. -    std::string method; -    LLSD param_sd; -    if(sd.has("method") && sd.has("parameter")) -    { -        method = sd["method"].asString(); -        param_sd = sd["parameter"]; -    } -    else -    { -        method = mMethod; -        param_sd = sd; -    } -    if(method.empty()) -    { -        LL_WARNS() << "SD -> XML Request no method found." << LL_ENDL; -        return STATUS_ERROR; -    } - -    PUMP_DEBUG; -    // We have a method, and some kind of parameter, so package it up -    // and send it out. -    LLBufferStream ostream(channels, buffer.get()); -    ostream.precision(DEFAULT_PRECISION); -    if(ostream.fail()) -    { -        LL_INFOS() << "STREAM FAILURE setting precision" << LL_ENDL; -    } -    ostream << XML_HEADER << XMLRPC_REQUEST_HEADER_1 -        << xml_escape_string(method) << XMLRPC_REQUEST_HEADER_2; -    if(ostream.fail()) -    { -        LL_INFOS() << "STREAM FAILURE writing method headers" << LL_ENDL; -    } -    switch(param_sd.type()) -    { -    case LLSD::TypeMap: -        // If the params are a map, then we do not want to iterate -        // through them since the iterators returned will be map -        // ordered un-named values, which will lose the names, and -        // only stream the values, turning it into an array. -        ostream << "<param>"; -        streamOut(ostream, param_sd); -        ostream << "</param>"; -        break; -    case LLSD::TypeArray: -    { - -        LLSD::array_iterator it = param_sd.beginArray(); -        LLSD::array_iterator end = param_sd.endArray(); -        for(; it != end; ++it) -        { -            ostream << "<param>"; -            streamOut(ostream, *it); -            ostream << "</param>"; -        } -        break; -    } -    default: -        ostream << "<param>"; -        streamOut(ostream, param_sd); -        ostream << "</param>"; -        break; -    } - -    stream << XMLRPC_REQUEST_FOOTER; -    return STATUS_DONE; -} - -/** - * LLFilterXMLRPCResponse2LLSD - */ -// this is a c function here since it's really an implementation -// detail that requires a header file just get the definition of the -// parameters. -LLIOPipe::EStatus stream_out(std::ostream& ostr, XMLRPC_VALUE value) -{ -    XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(value); -    LLIOPipe::EStatus status = LLIOPipe::STATUS_OK; -    switch(type) -    { -    case xmlrpc_type_base64: -    { -        S32 len = XMLRPC_GetValueStringLen(value); -        const char* buf = XMLRPC_GetValueBase64(value); -        ostr << " b("; -        if((len > 0) && buf) -        { -            ostr << len << ")\""; -            ostr.write(buf, len); -            ostr << "\""; -        } -        else -        { -            ostr << "0)\"\""; -        } -        break; -    } -    case xmlrpc_type_boolean: -        //LL_DEBUGS() << "stream_out() bool" << LL_ENDL; -        ostr << " " << (XMLRPC_GetValueBoolean(value) ? "true" : "false"); -        break; -    case xmlrpc_type_datetime: -        ostr << " d\"" << XMLRPC_GetValueDateTime_ISO8601(value) << "\""; -        break; -    case xmlrpc_type_double: -        ostr << " r" << XMLRPC_GetValueDouble(value); -        //LL_DEBUGS() << "stream_out() double" << XMLRPC_GetValueDouble(value) -        //       << LL_ENDL; -        break; -    case xmlrpc_type_int: -        ostr << " i" << XMLRPC_GetValueInt(value); -        //LL_DEBUGS() << "stream_out() integer:" << XMLRPC_GetValueInt(value) -        //       << LL_ENDL; -        break; -    case xmlrpc_type_string: -        //LL_DEBUGS() << "stream_out() string: " << str << LL_ENDL; -        ostr << " s(" << XMLRPC_GetValueStringLen(value) << ")'" -            << XMLRPC_GetValueString(value) << "'"; -        break; -    case xmlrpc_type_array: // vector -    case xmlrpc_type_mixed: // vector -    { -        //LL_DEBUGS() << "stream_out() array" << LL_ENDL; -        ostr << " ["; -        U32 needs_comma = 0; -        XMLRPC_VALUE current = XMLRPC_VectorRewind(value); -        while(current && (LLIOPipe::STATUS_OK == status)) -        { -            if(needs_comma++) ostr << ","; -            status = stream_out(ostr, current); -            current = XMLRPC_VectorNext(value); -        } -        ostr << "]"; -        break; -    } -    case xmlrpc_type_struct: // still vector -    { -        //LL_DEBUGS() << "stream_out() struct" << LL_ENDL; -        ostr << " {"; -        std::string name; -        U32 needs_comma = 0; -        XMLRPC_VALUE current = XMLRPC_VectorRewind(value); -        while(current && (LLIOPipe::STATUS_OK == status)) -        { -            if(needs_comma++) ostr << ","; -            name.assign(XMLRPC_GetValueID(current)); -            ostr << "'" << LLSDNotationFormatter::escapeString(name) << "':"; -            status = stream_out(ostr, current); -            current = XMLRPC_VectorNext(value); -        } -        ostr << "}"; -        break; -    } -    case xmlrpc_type_empty: -    case xmlrpc_type_none: -    default: -        status = LLIOPipe::STATUS_ERROR; -        LL_WARNS() << "Found an empty xmlrpc type.." << LL_ENDL; -        // not much we can do here... -        break; -    }; -    return status; -} - -LLFilterXMLRPCResponse2LLSD::LLFilterXMLRPCResponse2LLSD() -{ -} - -LLFilterXMLRPCResponse2LLSD::~LLFilterXMLRPCResponse2LLSD() -{ -} - -LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl( -    const LLChannelDescriptors& channels, -    buffer_ptr_t& buffer, -    bool& eos, -    LLSD& context, -    LLPumpIO* pump) -{ -    LL_PROFILE_ZONE_SCOPED; - -    PUMP_DEBUG; -    if(!eos) return STATUS_BREAK; -    if(!buffer) return STATUS_ERROR; - -    PUMP_DEBUG; -    // *FIX: This technique for reading data is far from optimal. We -    // need to have some kind of istream interface into the xml -    // parser... -    S32 bytes = buffer->countAfter(channels.in(), NULL); -    if(!bytes) return STATUS_ERROR; -    char* buf = new char[bytes + 1]; -    buf[bytes] = '\0'; -    buffer->readAfter(channels.in(), NULL, (U8*)buf, bytes); - -    //LL_DEBUGS() << "xmlrpc response: " << buf << LL_ENDL; - -    PUMP_DEBUG; -    XMLRPC_REQUEST response = XMLRPC_REQUEST_FromXML( -        buf, -        bytes, -        NULL); -    if(!response) -    { -        LL_WARNS() << "XML -> SD Response unable to parse xml." << LL_ENDL; -        delete[] buf; -        return STATUS_ERROR; -    } - -    PUMP_DEBUG; -    LLBufferStream stream(channels, buffer.get()); -    stream.precision(DEFAULT_PRECISION); -    if(XMLRPC_ResponseIsFault(response)) -    { -        PUMP_DEBUG; -        stream << LLSDRPC_FAULT_HADER_1 -               << XMLRPC_GetResponseFaultCode(response) -               << LLSDRPC_FAULT_HADER_2; -        const char* fault_str = XMLRPC_GetResponseFaultString(response); -        std::string fault_string; -        if(fault_str) -        { -            fault_string.assign(fault_str); -        } -        stream << "'" << LLSDNotationFormatter::escapeString(fault_string) -           << "'" <<LLSDRPC_FAULT_FOOTER; -    } -    else -    { -        PUMP_DEBUG; -        stream << LLSDRPC_RESPONSE_HEADER; -        XMLRPC_VALUE param = XMLRPC_RequestGetData(response); -        if(param) -        { -            stream_out(stream, param); -        } -        stream << LLSDRPC_RESPONSE_FOOTER; -    } -    PUMP_DEBUG; -    XMLRPC_RequestFree(response, 1); -    delete[] buf; -    PUMP_DEBUG; -    return STATUS_DONE; -} - -/** - * LLFilterXMLRPCRequest2LLSD - */ -LLFilterXMLRPCRequest2LLSD::LLFilterXMLRPCRequest2LLSD() -{ -} - -LLFilterXMLRPCRequest2LLSD::~LLFilterXMLRPCRequest2LLSD() -{ -} - -LLIOPipe::EStatus LLFilterXMLRPCRequest2LLSD::process_impl( -    const LLChannelDescriptors& channels, -    buffer_ptr_t& buffer, -    bool& eos, -    LLSD& context, -    LLPumpIO* pump) -{ -    LL_PROFILE_ZONE_SCOPED; -    PUMP_DEBUG; -    if(!eos) return STATUS_BREAK; -    if(!buffer) return STATUS_ERROR; - -    PUMP_DEBUG; -    // *FIX: This technique for reading data is far from optimal. We -    // need to have some kind of istream interface into the xml -    // parser... -    S32 bytes = buffer->countAfter(channels.in(), NULL); -    if(!bytes) return STATUS_ERROR; -    char* buf = new char[bytes + 1]; -    buf[bytes] = '\0'; -    buffer->readAfter(channels.in(), NULL, (U8*)buf, bytes); - -    //LL_DEBUGS() << "xmlrpc request: " << buf << LL_ENDL; - -    // Check the value in the buffer. XMLRPC_REQUEST_FromXML will report a error code 4 if -    // values that are less than 0x20 are passed to it, except -    // 0x09: Horizontal tab; 0x0a: New Line; 0x0d: Carriage -    U8* cur_pBuf = (U8*)buf; -    U8 cur_char; -    for (S32 i=0; i<bytes; i++) -    { -        cur_char = *cur_pBuf; -        if (   cur_char < 0x20 -            && 0x09 != cur_char -            && 0x0a != cur_char -            && 0x0d != cur_char ) -        { -            *cur_pBuf = '?'; -        } -        ++cur_pBuf; -    } - -    PUMP_DEBUG; -    XMLRPC_REQUEST request = XMLRPC_REQUEST_FromXML( -        buf, -        bytes, -        NULL); -    if(!request) -    { -        LL_WARNS() << "XML -> SD Request process parse error." << LL_ENDL; -        delete[] buf; -        return STATUS_ERROR; -    } - -    PUMP_DEBUG; -    LLBufferStream stream(channels, buffer.get()); -    stream.precision(DEFAULT_PRECISION); -    const char* name = XMLRPC_RequestGetMethodName(request); -    stream << LLSDRPC_REQUEST_HEADER_1 << (name ? name : "") -           << LLSDRPC_REQUEST_HEADER_2; -    XMLRPC_VALUE param = XMLRPC_RequestGetData(request); -    if(param) -    { -        PUMP_DEBUG; -        S32 size = XMLRPC_VectorSize(param); -        if(size > 1) -        { -            // if there are multiple parameters, stuff the values into -            // an array so that the next step in the chain can read them. -            stream << "["; -        } -        XMLRPC_VALUE current = XMLRPC_VectorRewind(param); -        bool needs_comma = false; -        while(current) -        { -            if(needs_comma) -            { -                stream << ","; -            } -            needs_comma = true; -            stream_out(stream, current); -            current = XMLRPC_VectorNext(param); -        } -        if(size > 1) -        { -            // close the array -            stream << "]"; -        } -    } -    stream << LLSDRPC_REQUEST_FOOTER; -    XMLRPC_RequestFree(request, 1); -    delete[] buf; -    PUMP_DEBUG; -    return STATUS_DONE; -} - diff --git a/indra/llmessage/llfiltersd2xmlrpc.h b/indra/llmessage/llfiltersd2xmlrpc.h deleted file mode 100644 index 55938d3e2b..0000000000 --- a/indra/llmessage/llfiltersd2xmlrpc.h +++ /dev/null @@ -1,271 +0,0 @@ -/** - * @file llfiltersd2xmlrpc.h - * @author Phoenix - * @date 2005-04-26 - * - * $LicenseInfo:firstyear=2005&license=viewerlgpl$ - * Second Life Viewer Source Code - * 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. - * - * 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. - * - * 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 - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLFILTERSD2XMLRPC_H -#define LL_LLFILTERSD2XMLRPC_H - -/** - * These classes implement the necessary pipes for translating between - * xmlrpc and llsd rpc. The llsd rpcs mechanism was developed as an - * extensible and easy to parse serialization grammer which maintains - * a time efficient in-memory representation. - */ - -#include <iosfwd> -#include "lliopipe.h" - -/** - * @class LLFilterSD2XMLRPC - * @brief Filter from serialized LLSD to an XMLRPC method call - * - * This clas provides common functionality for the LLFilterSD2XMLRPRC - * request and response classes. - */ -class LLFilterSD2XMLRPC : public LLIOPipe -{ -public: -    LLFilterSD2XMLRPC(); -    virtual ~LLFilterSD2XMLRPC(); - -protected: -    /** -     * @brief helper method -     */ -    void streamOut(std::ostream& ostr, const LLSD& sd); -}; - -/** - * @class LLFilterSD2XMLRPCResponse - * @brief Filter from serialized LLSD to an XMLRPC response - * - * This class filters a serialized LLSD object to an xmlrpc - * repsonse. Since resonses are limited to a single param, the xmlrprc - * response only serializes it as one object. - * This class correctly handles normal llsd responses as well as llsd - * rpc faults. - * - * For example, if given: - * <code>{'response':[ i200, r3.4, {"foo":"bar"} ]}</code> - * Would generate: - * <code> - *  <?xml version="1.0"?> - *  <methodResponse><params><param><array><data> - *    <value><int>200</int></value> - *    <value><double>3.4</double></value> - *    <value><struct><member> - *      <name>foo</name><value><string>bar</string></value></member> - *      </struct></value> - *  </data></array></param></params></methodResponse> - * </code> - */ -class LLFilterSD2XMLRPCResponse : public LLFilterSD2XMLRPC -{ -public: -    // constructor -    LLFilterSD2XMLRPCResponse(); - -    // destructor -    virtual ~LLFilterSD2XMLRPCResponse(); - -    /* @name LLIOPipe virtual implementations -     */ -    //@{ -protected: -    /** -     * @brief Process the data in buffer. -     */ -    virtual EStatus process_impl( -        const LLChannelDescriptors& channels, -        buffer_ptr_t& buffer, -        bool& eos, -        LLSD& context, -        LLPumpIO* pump); -    //@} -}; - -/** - * @class LLFilterSD2XMLRPCRequest - * @brief Filter from serialized LLSD to an XMLRPC method call - * - * This class will accept any kind of serialized LLSD object, but you - * probably want to have an array on the outer boundary since this - * object will interpret each element in the top level LLSD as a - * parameter into the xmlrpc spec. - * - * For example, you would represent 3 params as: - * <code> - *  {'method'='foo', 'parameter':[i200, r3.4, {"foo":"bar"}]} - * </code> - * To generate: - * <code> - *  <?xml version="1.0"?> - *  <methodCall><params> - *  <param><value><int>200</int></value></param> - *  <param><value><double>3.4</double></value></param> - *  <param><value><struct><member> - *    <name>foo</name><value><string>bar</string></value></member> - *    </struct></value></param> - *  </params></methodCall> - * - * This class will accept 2 different kinds of encodings. The first - * just an array of params as long as you specify the method in the - * constructor. It will also accept a structured data in the form: - * {'method':'$method_name', 'parameter':[...] } In the latter form, the - * encoded 'method' will be used regardless of the construction of the - * object, and the 'parameter' will be used as parameter to the call. - */ -class LLFilterSD2XMLRPCRequest : public LLFilterSD2XMLRPC -{ -public: -    // constructor -    LLFilterSD2XMLRPCRequest(); - -    // constructor -    LLFilterSD2XMLRPCRequest(const char* method); - -    // destructor -    virtual ~LLFilterSD2XMLRPCRequest(); - -    /* @name LLIOPipe virtual implementations -     */ -    //@{ -protected: -    /** -     * @brief Process the data in buffer. -     */ -    virtual EStatus process_impl( -        const LLChannelDescriptors& channels, -        buffer_ptr_t& buffer, -        bool& eos, -        LLSD& context, -        LLPumpIO* pump); -    //@} - -protected: -    // The method name of this request. -    std::string mMethod; -}; - -/** - * @class LLFilterXMLRPCResponse2LLSD - * @brief Filter from serialized XMLRPC method response to LLSD - * - * The xmlrpc spec states that responses can only have one element - * which can be of any supported type. - * This takes in  xml of the form: - * <code> - * <?xml version=\"1.0\"?><methodResponse><params><param> - * <value><string>ok</string></value></param></params></methodResponse> - * </code> - * And processes it into: - *  <code>'ok'</code> - * - */ -class LLFilterXMLRPCResponse2LLSD : public LLIOPipe -{ -public: -    // constructor -    LLFilterXMLRPCResponse2LLSD(); - -    // destructor -    virtual ~LLFilterXMLRPCResponse2LLSD(); - -    /* @name LLIOPipe virtual implementations -     */ -    //@{ -protected: -    /** -     * @brief Process the data in buffer. -     */ -    virtual EStatus process_impl( -        const LLChannelDescriptors& channels, -        buffer_ptr_t& buffer, -        bool& eos, -        LLSD& context, -        LLPumpIO* pump); -    //@} - -protected: -}; - -/** - * @class LLFilterXMLRPCRequest2LLSD - * @brief Filter from serialized XMLRPC method call to LLSD - * - * This takes in  xml of the form: - * <code> - *  <?xml version=\"1.0\"?><methodCall> - *  <methodName>repeat</methodName> - *  <params> - *  <param><value><i4>4</i4></value></param> - *  <param><value><string>ok</string></value></param> - *  </params></methodCall> - * </code> - * And processes it into: - *  <code>{ 'method':'repeat', 'params':[i4, 'ok'] }</code> - */ -class LLFilterXMLRPCRequest2LLSD : public LLIOPipe -{ -public: -    // constructor -    LLFilterXMLRPCRequest2LLSD(); - -    // destructor -    virtual ~LLFilterXMLRPCRequest2LLSD(); - -    /* @name LLIOPipe virtual implementations -     */ -    //@{ -protected: -    /** -     * @brief Process the data in buffer. -     */ -    virtual EStatus process_impl( -        const LLChannelDescriptors& channels, -        buffer_ptr_t& buffer, -        bool& eos, -        LLSD& context, -        LLPumpIO* pump); -    //@} - -protected: -}; - -/** - * @brief This function takes string, and escapes it appropritately - * for inclusion as xml data. - */ -std::string xml_escape_string(const std::string& in); - -/** - * @brief Externally available constants - */ -extern const char LLSDRPC_REQUEST_HEADER_1[]; -extern const char LLSDRPC_REQUEST_HEADER_2[]; -extern const char LLSDRPC_REQUEST_FOOTER[]; - -#endif // LL_LLFILTERSD2XMLRPC_H diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 0fd4516844..7f6b8093fc 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -653,32 +653,24 @@ bool LLXMLNode::updateNode(  // static  bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXMLNode* defaults_tree)  { -    // Read file -    LL_DEBUGS("XMLNode") << "parsing XML file: " << filename << LL_ENDL; -    LLFILE* fp = LLFile::fopen(filename, "rb");     /* Flawfinder: ignore */ -    if (fp == NULL) +    std::string xml = LLFile::getContents(filename); +    if (xml.empty())      { -        node = NULL ; -        return false; +        LL_WARNS("XMLNode") << "no XML file: " << filename << LL_ENDL; +    } +    else if (parseBuffer(xml.data(), xml.size(), node, defaults_tree)) +    { +        return true;      } -    fseek(fp, 0, SEEK_END); -    U32 length = ftell(fp); -    fseek(fp, 0, SEEK_SET); - -    U8* buffer = new U8[length+1]; -    size_t nread = fread(buffer, 1, length, fp); -    buffer[nread] = 0; -    fclose(fp); -    bool rv = parseBuffer(buffer, static_cast<U32>(nread), node, defaults_tree); -    delete [] buffer; -    return rv; +    node = nullptr; +    return false;  }  // static  bool LLXMLNode::parseBuffer( -    U8* buffer, -    U32 length, +    const char* buffer, +    U64 length,      LLXMLNodePtr& node,      LLXMLNode* defaults)  { @@ -693,20 +685,25 @@ bool LLXMLNode::parseBuffer(      file_node->mParser = &my_parser; -    XML_SetUserData(my_parser, (void *)file_node_ptr); +    XML_SetUserData(my_parser, file_node_ptr);      // Do the parsing -    if (XML_Parse(my_parser, (const char *)buffer, length, true) != XML_STATUS_OK) +    bool success = XML_STATUS_OK == XML_Parse(my_parser, buffer, (int)length, true); +    if (!success)      {          LL_WARNS() << "Error parsing xml error code: "                  << XML_ErrorString(XML_GetErrorCode(my_parser))                  << " on line " << XML_GetCurrentLineNumber(my_parser) +                << ", column " << XML_GetCurrentColumnNumber(my_parser)                  << LL_ENDL;      }      // Deinit      XML_ParserFree(my_parser); +    if (!success) +        return false; +      if (!file_node->mChildren || file_node->mChildren->map.size() != 1)      {          LL_WARNS() << "Parse failure - wrong number of top-level nodes xml." diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index b8e29bbfef..b8f9e1ff69 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -129,20 +129,20 @@ public:      void addChild(LLXMLNodePtr& new_child);      void setParent(LLXMLNodePtr& new_parent); // reparent if necessary -    // Serialization +    // Deserialization      static bool parseFile(          const std::string& filename,          LLXMLNodePtr& node, -        LLXMLNode* defaults_tree); +        LLXMLNode* defaults = nullptr);      static bool parseBuffer( -        U8* buffer, -        U32 length, +        const char* buffer, +        U64 length,          LLXMLNodePtr& node, -        LLXMLNode* defaults); +        LLXMLNode* defaults = nullptr);      static bool parseStream(          std::istream& str,          LLXMLNodePtr& node, -        LLXMLNode* defaults); +        LLXMLNode* defaults = nullptr);      static bool updateNode(          LLXMLNodePtr& node,          LLXMLNodePtr& update_node); diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp index 06c87343e2..8a4ab091a3 100644 --- a/indra/newview/llcurrencyuimanager.cpp +++ b/indra/newview/llcurrencyuimanager.cpp @@ -111,16 +111,17 @@ public:      bool hasEstimate() const;      std::string getLocalEstimate() const; -    void startTransaction(TransactionType type, -        const char* method, LLXMLRPCValue params); +    void startTransaction(TransactionType type, const char* method, const LLSD& params); + +    // return true if update needed      bool checkTransaction(); -        // return true if update needed      void setError(const std::string& message, const std::string& uri);      void clearError(); +    // return true if update needed      bool considerUpdateCurrency(); -        // return true if update needed +      void currencyKey(S32);      static void onCurrencyKey(LLLineEditor* caller, void* data); @@ -160,32 +161,29 @@ void LLCurrencyUIManager::Impl::updateCurrencyInfo()          return;      } -    LLXMLRPCValue keywordArgs = LLXMLRPCValue::createStruct(); -    keywordArgs.appendString("agentId", gAgent.getID().asString()); -    keywordArgs.appendString( -        "secureSessionId", -        gAgent.getSecureSessionID().asString()); -    keywordArgs.appendString("language", LLUI::getLanguage()); -    keywordArgs.appendInt("currencyBuy", mUserCurrencyBuy); -    keywordArgs.appendString("viewerChannel", LLVersionInfo::instance().getChannel()); -    keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::instance().getMajor()); -    keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::instance().getMinor()); -    keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::instance().getPatch()); +    const LLVersionInfo& vi(LLVersionInfo::instance()); + +    LLSD params = LLSD::emptyMap(); +    params["agentId"] = gAgent.getID().asString(); +    params["secureSessionId"] = gAgent.getSecureSessionID().asString(); +    params["language"] = LLUI::getLanguage(); +    params["currencyBuy"] = mUserCurrencyBuy; +    params["viewerChannel"] = vi.getChannel(); +    params["viewerMajorVersion"] = vi.getMajor(); +    params["viewerMinorVersion"] = vi.getMinor(); +    params["viewerPatchVersion"] = vi.getPatch();      // With GitHub builds, the build number is too big to fit in a 32-bit int, -    // and XMLRPC_VALUE doesn't deal with integers wider than int. Use string. -    keywordArgs.appendString("viewerBuildVersion", stringize(LLVersionInfo::instance().getBuild())); - -    LLXMLRPCValue params = LLXMLRPCValue::createArray(); -    params.append(keywordArgs); +    // and XMLRPC value doesn't deal with integers wider than int. Use string. +    params["viewerBuildVersion"] = std::to_string(vi.getBuild());      startTransaction(TransactionCurrency, "getCurrencyQuote", params);  }  void LLCurrencyUIManager::Impl::finishCurrencyInfo()  { -    LLXMLRPCValue result = mTransaction->responseValue(); +    const LLSD& result = mTransaction->response(); -    bool success = result["success"].asBool(); +    bool success = result["success"].asBoolean();      if (!success)      {          setError( @@ -195,24 +193,24 @@ void LLCurrencyUIManager::Impl::finishCurrencyInfo()          return;      } -    LLXMLRPCValue currency = result["currency"]; +    const LLSD& currency = result["currency"];      // old XML-RPC server: estimatedCost = value in US cents -    mUSDCurrencyEstimated = currency["estimatedCost"].isValid(); +    mUSDCurrencyEstimated = currency.has("estimatedCost");      if (mUSDCurrencyEstimated)      { -        mUSDCurrencyEstimatedCost = currency["estimatedCost"].asInt(); +        mUSDCurrencyEstimatedCost = currency["estimatedCost"].asInteger();      }      // newer XML-RPC server: estimatedLocalCost = local currency string -    mLocalCurrencyEstimated = currency["estimatedLocalCost"].isValid(); +    mLocalCurrencyEstimated = currency.has("estimatedLocalCost");      if (mLocalCurrencyEstimated)      {          mLocalCurrencyEstimatedCost = currency["estimatedLocalCost"].asString();          mSupportsInternationalBilling = true;      } -    S32 newCurrencyBuy = currency["currencyBuy"].asInt(); +    S32 newCurrencyBuy = currency["currencyBuy"].asInteger();      if (newCurrencyBuy != mUserCurrencyBuy)      {          mUserCurrencyBuy = newCurrencyBuy; @@ -224,36 +222,36 @@ void LLCurrencyUIManager::Impl::finishCurrencyInfo()  void LLCurrencyUIManager::Impl::startCurrencyBuy(const std::string& password)  { -    LLXMLRPCValue keywordArgs = LLXMLRPCValue::createStruct(); -    keywordArgs.appendString("agentId", gAgent.getID().asString()); -    keywordArgs.appendString( -        "secureSessionId", -        gAgent.getSecureSessionID().asString()); -    keywordArgs.appendString("language", LLUI::getLanguage()); -    keywordArgs.appendInt("currencyBuy", mUserCurrencyBuy); +    const LLVersionInfo& vi(LLVersionInfo::instance()); + +    LLSD params = LLSD::emptyMap(); +    params["agentId"] = gAgent.getID().asString(); +    params["secureSessionId"] = gAgent.getSecureSessionID().asString(); +    params["language"] = LLUI::getLanguage(); +    params["currencyBuy"] = mUserCurrencyBuy; +    params["confirm"] = mSiteConfirm; +    params["viewerChannel"] = vi.getChannel(); +    params["viewerMajorVersion"] = vi.getMajor(); +    params["viewerMinorVersion"] = vi.getMinor(); +    params["viewerPatchVersion"] = vi.getPatch(); +    // With GitHub builds, the build number is too big to fit in a 32-bit int, +    // and XMLRPC value doesn't deal with integers wider than int. Use string. +    params["viewerBuildVersion"] = std::to_string(vi.getBuild()); +      if (mUSDCurrencyEstimated)      { -        keywordArgs.appendInt("estimatedCost", mUSDCurrencyEstimatedCost); +        params["estimatedCost"] = mUSDCurrencyEstimatedCost;      } +      if (mLocalCurrencyEstimated)      { -        keywordArgs.appendString("estimatedLocalCost", mLocalCurrencyEstimatedCost); +        params["estimatedLocalCost"] = mLocalCurrencyEstimatedCost;      } -    keywordArgs.appendString("confirm", mSiteConfirm); +      if (!password.empty())      { -        keywordArgs.appendString("password", password); +        params["password"] = password;      } -    keywordArgs.appendString("viewerChannel", LLVersionInfo::instance().getChannel()); -    keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::instance().getMajor()); -    keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::instance().getMinor()); -    keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::instance().getPatch()); -    // With GitHub builds, the build number is too big to fit in a 32-bit int, -    // and XMLRPC_VALUE doesn't deal with integers wider than int. Use string. -    keywordArgs.appendString("viewerBuildVersion", stringize(LLVersionInfo::instance().getBuild())); - -    LLXMLRPCValue params = LLXMLRPCValue::createArray(); -    params.append(keywordArgs);      startTransaction(TransactionBuy, "buyCurrency", params); @@ -263,9 +261,9 @@ void LLCurrencyUIManager::Impl::startCurrencyBuy(const std::string& password)  void LLCurrencyUIManager::Impl::finishCurrencyBuy()  { -    LLXMLRPCValue result = mTransaction->responseValue(); +    const LLSD& result = mTransaction->response(); -    bool success = result["success"].asBool(); +    bool success = result["success"].asBoolean();      if (!success)      {          setError( @@ -282,7 +280,7 @@ void LLCurrencyUIManager::Impl::finishCurrencyBuy()  }  void LLCurrencyUIManager::Impl::startTransaction(TransactionType type, -        const char* method, LLXMLRPCValue params) +        const char* method, const LLSD& params)  {      static std::string transactionURI;      if (transactionURI.empty()) @@ -293,12 +291,7 @@ void LLCurrencyUIManager::Impl::startTransaction(TransactionType type,      delete mTransaction;      mTransactionType = type; -    mTransaction = new LLXMLRPCTransaction( -        transactionURI, -        method, -        params, -        false /* don't use gzip */ -        ); +    mTransaction = new LLXMLRPCTransaction(transactionURI, method, params);      clearError();  } @@ -352,12 +345,17 @@ bool LLCurrencyUIManager::Impl::checkTransaction()      {          setError(mTransaction->statusMessage(), mTransaction->statusURI());      } -    else { +    else +    {          switch (mTransactionType)          { -            case TransactionCurrency:   finishCurrencyInfo();   break; -            case TransactionBuy:        finishCurrencyBuy();    break; -            default: ; +        case TransactionCurrency: +            finishCurrencyInfo(); +            break; +        case TransactionBuy: +            finishCurrencyBuy(); +            break; +        default:;          }      } @@ -385,9 +383,8 @@ void LLCurrencyUIManager::Impl::clearError()  bool LLCurrencyUIManager::Impl::considerUpdateCurrency()  { -    if (mCurrencyChanged -    &&  !mTransaction -    &&  mCurrencyKeyTimer.getElapsedTimeF32() >= CURRENCY_ESTIMATE_FREQUENCY) +    if (mCurrencyChanged && !mTransaction && +        mCurrencyKeyTimer.getElapsedTimeF32() >= CURRENCY_ESTIMATE_FREQUENCY)      {          updateCurrencyInfo();          return true; @@ -408,7 +405,8 @@ void LLCurrencyUIManager::Impl::currencyKey(S32 value)      mUserCurrencyBuy = value; -    if (hasEstimate()) { +    if (hasEstimate()) +    {          clearEstimate();          //cannot just simply refresh the whole UI, as the edit field will          // get reset and the cursor will change... @@ -421,8 +419,7 @@ void LLCurrencyUIManager::Impl::currencyKey(S32 value)  }  // static -void LLCurrencyUIManager::Impl::onCurrencyKey( -        LLLineEditor* caller, void* data) +void LLCurrencyUIManager::Impl::onCurrencyKey(LLLineEditor* caller, void* data)  {      S32 value = atoi(caller->getText().c_str());      LLCurrencyUIManager::Impl* self = (LLCurrencyUIManager::Impl*)data; @@ -589,14 +586,12 @@ bool LLCurrencyUIManager::inProcess()  bool LLCurrencyUIManager::canCancel()  { -    return impl.mTransactionType != Impl::TransactionBuy; +    return !buying();  }  bool LLCurrencyUIManager::canBuy()  { -    return impl.mTransactionType == Impl::TransactionNone -        && impl.hasEstimate() -        && impl.mUserCurrencyBuy > 0; +    return !inProcess() && impl.hasEstimate() && impl.mUserCurrencyBuy > 0;  }  bool LLCurrencyUIManager::buying() diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 570a223908..11505e3047 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -182,7 +182,7 @@ public:      void refreshUI(); -    void startTransaction(TransactionType type, const LLXMLRPCValue& params); +    void startTransaction(TransactionType type, const LLSD& params);      bool checkTransaction();      void tellUserError(const std::string& message, const std::string& uri); @@ -396,11 +396,10 @@ void LLFloaterBuyLandUI::updateParcelInfo()      // Can't have more than region max tasks, regardless of parcel      // object bonus factor.      LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); -    if(region) +    if (region)      {          S32 max_tasks_per_region = (S32)region->getMaxTasks(); -        mParcelSupportedObjects = llmin( -            mParcelSupportedObjects, max_tasks_per_region); +        mParcelSupportedObjects = llmin(mParcelSupportedObjects, max_tasks_per_region);      }      mParcelSoldWithObjects = parcel->getSellWithObjects(); @@ -423,7 +422,7 @@ void LLFloaterBuyLandUI::updateParcelInfo()      // checks that we can buy the land -    if(mIsForGroup && !gAgent.hasPowerInActiveGroup(GP_LAND_DEED)) +    if (mIsForGroup && !gAgent.hasPowerInActiveGroup(GP_LAND_DEED))      {          mCannotBuyReason = getString("cant_buy_for_group");          return; @@ -492,85 +491,56 @@ void LLFloaterBuyLandUI::updateParcelInfo()  void LLFloaterBuyLandUI::updateCovenantInfo()  {      LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); -    if(!region) return; +    if (!region) +        return;      U8 sim_access = region->getSimAccess();      std::string rating = LLViewerRegion::accessToString(sim_access);      LLTextBox* region_name = getChild<LLTextBox>("region_name_text"); -    if (region_name) -    { -        std::string region_name_txt = region->getName() + " ("+rating +")"; -        region_name->setText(region_name_txt); +    std::string region_name_txt = region->getName() + " ("+rating +")"; +    region_name->setText(region_name_txt); -        LLIconCtrl* rating_icon = getChild<LLIconCtrl>("rating_icon"); -        LLRect rect = rating_icon->getRect(); -        S32 region_name_width = llmin(region_name->getRect().getWidth(), region_name->getTextBoundingRect().getWidth()); -        S32 icon_left_pad = region_name->getRect().mLeft + region_name_width + ICON_PAD; -        region_name->setToolTip(region_name->getText()); -        rating_icon->setRect(rect.setOriginAndSize(icon_left_pad, rect.mBottom, rect.getWidth(), rect.getHeight())); +    LLIconCtrl* rating_icon = getChild<LLIconCtrl>("rating_icon"); +    LLRect rect = rating_icon->getRect(); +    S32 region_name_width = llmin(region_name->getRect().getWidth(), region_name->getTextBoundingRect().getWidth()); +    S32 icon_left_pad = region_name->getRect().mLeft + region_name_width + ICON_PAD; +    region_name->setToolTip(region_name->getText()); +    rating_icon->setRect(rect.setOriginAndSize(icon_left_pad, rect.mBottom, rect.getWidth(), rect.getHeight())); -        switch(sim_access) -        { -        case SIM_ACCESS_PG: -            rating_icon->setValue(getString("icon_PG")); -            break; +    switch (sim_access) +    { +    case SIM_ACCESS_PG: +        rating_icon->setValue(getString("icon_PG")); +        break; -        case SIM_ACCESS_ADULT: -            rating_icon->setValue(getString("icon_R")); -            break; +    case SIM_ACCESS_ADULT: +        rating_icon->setValue(getString("icon_R")); +        break; -        default: -            rating_icon->setValue(getString("icon_M")); -        } +    default: +        rating_icon->setValue(getString("icon_M"));      }      LLTextBox* region_type = getChild<LLTextBox>("region_type_text"); -    if (region_type) -    { -        region_type->setText(region->getLocalizedSimProductName()); -        region_type->setToolTip(region->getLocalizedSimProductName()); -    } +    region_type->setText(region->getLocalizedSimProductName()); +    region_type->setToolTip(region->getLocalizedSimProductName());      LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause"); -    if (resellable_clause) -    { -        if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)) -        { -            resellable_clause->setText(getString("can_not_resell")); -        } -        else -        { -            resellable_clause->setText(getString("can_resell")); -        } -    } +    const char* can_resell = region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL) ? "can_not_resell" : "can_resell"; +    resellable_clause->setText(getString(can_resell));      LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause"); -    if (changeable_clause) -    { -        if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES)) -        { -            changeable_clause->setText(getString("can_change")); -        } -        else -        { -            changeable_clause->setText(getString("can_not_change")); -        } -    } +    const char* can_change = region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES) ? "can_change" : "can_not_change"; +    changeable_clause->setText(getString(can_change));      LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant"); -    if(check) -    { -        check->set(false); -        check->setEnabled(true); -        check->setCommitCallback(onChangeAgreeCovenant, this); -    } +    check->set(false); +    check->setEnabled(true); +    check->setCommitCallback(onChangeAgreeCovenant, this);      LLTextBox* box = getChild<LLTextBox>("covenant_text"); -    if(box) -    { -        box->setVisible(false); -    } +    box->setVisible(false);      // send EstateCovenantInfo message      LLMessageSystem *msg = gMessageSystem; @@ -584,10 +554,9 @@ void LLFloaterBuyLandUI::updateCovenantInfo()  // static  void LLFloaterBuyLandUI::onChangeAgreeCovenant(LLUICtrl* ctrl, void* user_data)  { -    LLFloaterBuyLandUI* self = (LLFloaterBuyLandUI*)user_data; -    if(self) +    if (user_data)      { -        self->refreshUI(); +        ((LLFloaterBuyLandUI*)user_data)->refreshUI();      }  } @@ -626,13 +595,13 @@ void LLFloaterBuyLandUI::updateFloaterEstateName(const std::string& name)  void LLFloaterBuyLandUI::updateFloaterLastModified(const std::string& text)  {      LLTextBox* editor = getChild<LLTextBox>("covenant_timestamp_text"); -    if (editor) editor->setText(text); +    editor->setText(text);  }  void LLFloaterBuyLandUI::updateFloaterEstateOwnerName(const std::string& name)  {      LLTextBox* box = getChild<LLTextBox>("estate_owner_text"); -    if (box) box->setText(name); +    box->setText(name);  }  void LLFloaterBuyLandUI::updateWebSiteInfo() @@ -640,9 +609,10 @@ void LLFloaterBuyLandUI::updateWebSiteInfo()      S32 askBillableArea = mIsForGroup ? 0 : mParcelBillableArea;      S32 askCurrencyBuy = mCurrency.getAmount(); -    if (mTransaction && mTransactionType == TransactionPreflight -    &&  mPreflightAskBillableArea == askBillableArea -    &&  mPreflightAskCurrencyBuy == askCurrencyBuy) +    if (mTransaction && +        mTransactionType == TransactionPreflight && +        mPreflightAskBillableArea == askBillableArea && +        mPreflightAskCurrencyBuy == askCurrencyBuy)      {          return;      } @@ -664,27 +634,21 @@ void LLFloaterBuyLandUI::updateWebSiteInfo()      mSiteCurrencyEstimatedCost = 0;  #endif -    LLXMLRPCValue keywordArgs = LLXMLRPCValue::createStruct(); -    keywordArgs.appendString("agentId", gAgent.getID().asString()); -    keywordArgs.appendString( -        "secureSessionId", -        gAgent.getSecureSessionID().asString()); -    keywordArgs.appendString("language", LLUI::getLanguage()); -    keywordArgs.appendInt("billableArea", mPreflightAskBillableArea); -    keywordArgs.appendInt("currencyBuy", mPreflightAskCurrencyBuy); - -    LLXMLRPCValue params = LLXMLRPCValue::createArray(); -    params.append(keywordArgs); +    LLSD params = LLSD::emptyMap(); +    params["agentId"] = gAgent.getID().asString(); +    params["secureSessionId"] = gAgent.getSecureSessionID().asString(); +    params["language"] = LLUI::getLanguage(); +    params["billableArea"] = mPreflightAskBillableArea; +    params["currencyBuy"] = mPreflightAskCurrencyBuy;      startTransaction(TransactionPreflight, params);  }  void LLFloaterBuyLandUI::finishWebSiteInfo()  { +    const LLSD& result = mTransaction->response(); -    LLXMLRPCValue result = mTransaction->responseValue(); - -    mSiteValid = result["success"].asBool(); +    mSiteValid = result["success"].asBoolean();      if (!mSiteValid)      {          tellUserError( @@ -694,31 +658,30 @@ void LLFloaterBuyLandUI::finishWebSiteInfo()          return;      } -    LLXMLRPCValue membership = result["membership"]; -    mSiteMembershipUpgrade = membership["upgrade"].asBool(); +    const LLSD& membership = result["membership"]; +    mSiteMembershipUpgrade = membership["upgrade"].asBoolean();      mSiteMembershipAction = membership["action"].asString();      mSiteMembershipPlanIDs.clear();      mSiteMembershipPlanNames.clear(); -    LLXMLRPCValue levels = membership["levels"]; -    for (LLXMLRPCValue level = levels.rewind(); -        level.isValid(); -        level = levels.next()) +    const LLSD& levels = membership["levels"]; +    for (auto it = levels.beginArray(); it != levels.endArray(); ++it)      { +        const LLSD& level = *it;          mSiteMembershipPlanIDs.push_back(level["id"].asString());          mSiteMembershipPlanNames.push_back(level["description"].asString());      }      mUserPlanChoice = 0; -    LLXMLRPCValue landUse = result["landUse"]; -    mSiteLandUseUpgrade = landUse["upgrade"].asBool(); +    const LLSD& landUse = result["landUse"]; +    mSiteLandUseUpgrade = landUse["upgrade"].asBoolean();      mSiteLandUseAction = landUse["action"].asString(); -    LLXMLRPCValue currency = result["currency"]; -    if (currency["estimatedCost"].isValid()) +    const LLSD& currency = result["currency"]; +    if (currency.has("estimatedCost"))      { -        mCurrency.setUSDEstimate(currency["estimatedCost"].asInt()); +        mCurrency.setUSDEstimate(currency["estimatedCost"].asInteger());      } -    if (currency["estimatedLocalCost"].isValid()) +    if (currency.has("estimatedLocalCost"))      {          mCurrency.setLocalEstimate(currency["estimatedLocalCost"].asString());      } @@ -760,35 +723,30 @@ void LLFloaterBuyLandUI::runWebSitePrep(const std::string& password)          }      } -    LLXMLRPCValue keywordArgs = LLXMLRPCValue::createStruct(); -    keywordArgs.appendString("agentId", gAgent.getID().asString()); -    keywordArgs.appendString( -        "secureSessionId", -        gAgent.getSecureSessionID().asString()); -    keywordArgs.appendString("language", LLUI::getLanguage()); -    keywordArgs.appendString("levelId", newLevel); -    keywordArgs.appendInt("billableArea", -        mIsForGroup ? 0 : mParcelBillableArea); -    keywordArgs.appendInt("currencyBuy", mCurrency.getAmount()); -    keywordArgs.appendInt("estimatedCost", mCurrency.getUSDEstimate()); -    keywordArgs.appendString("estimatedLocalCost", mCurrency.getLocalEstimate()); -    keywordArgs.appendString("confirm", mSiteConfirm); +    LLSD params = LLSD::emptyMap(); +    params["agentId"] = gAgent.getID().asString(); +    params["secureSessionId"] = gAgent.getSecureSessionID().asString(); +    params["language"] = LLUI::getLanguage(); +    params["levelId"] = newLevel; +    params["billableArea"] = mIsForGroup ? 0 : mParcelBillableArea; +    params["currencyBuy"] = mCurrency.getAmount(); +    params["estimatedCost"] = mCurrency.getUSDEstimate(); +    params["estimatedLocalCost"] = mCurrency.getLocalEstimate(); +    params["confirm"] = mSiteConfirm; +      if (!password.empty())      { -        keywordArgs.appendString("password", password); +        params["password"] = password;      } -    LLXMLRPCValue params = LLXMLRPCValue::createArray(); -    params.append(keywordArgs); -      startTransaction(TransactionBuy, params);  }  void LLFloaterBuyLandUI::finishWebSitePrep()  { -    LLXMLRPCValue result = mTransaction->responseValue(); +    const LLSD& result = mTransaction->response(); -    bool success = result["success"].asBool(); +    bool success = result["success"].asBoolean();      if (!success)      {          tellUserError( @@ -850,7 +808,7 @@ void LLFloaterBuyLandUI::updateGroupName(const LLUUID& id,      }  } -void LLFloaterBuyLandUI::startTransaction(TransactionType type, const LLXMLRPCValue& params) +void LLFloaterBuyLandUI::startTransaction(TransactionType type, const LLSD& params)  {      delete mTransaction;      mTransaction = NULL; @@ -878,12 +836,7 @@ void LLFloaterBuyLandUI::startTransaction(TransactionType type, const LLXMLRPCVa              return;      } -    mTransaction = new LLXMLRPCTransaction( -        transaction_uri, -        method, -        params, -        false /* don't use gzip */ -        ); +    mTransaction = new LLXMLRPCTransaction(transaction_uri, method, params);  }  bool LLFloaterBuyLandUI::checkTransaction() diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 282a273be6..d015c0ed95 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -33,9 +33,6 @@  #include "stringize.h"  #include "llsdserialize.h" -// llmessage (!) -#include "llfiltersd2xmlrpc.h" // for xml_escape_string() -  // login  #include "lllogin.h" @@ -612,7 +609,7 @@ std::string construct_start_string()                          << position[VX] << "&"                          << position[VY] << "&"                          << position[VZ]); -            start = xml_escape_string(unescaped_start); +            start = LLStringFn::xml_encode(unescaped_start, true);              break;          }          case LLSLURL::HOME_LOCATION: diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp index 432ec3899a..d80cf2e80e 100644 --- a/indra/newview/llslurl.cpp +++ b/indra/newview/llslurl.cpp @@ -32,13 +32,15 @@  #include "llpanellogin.h"  #include "llviewercontrol.h"  #include "llviewernetwork.h" -#include "llfiltersd2xmlrpc.h" +  #include "curl/curl.h" +  const char* LLSLURL::SLURL_HTTP_SCHEME       = "http";  const char* LLSLURL::SLURL_HTTPS_SCHEME      = "https";  const char* LLSLURL::SLURL_SECONDLIFE_SCHEME = "secondlife";  const char* LLSLURL::SLURL_SECONDLIFE_PATH   = "secondlife";  const char* LLSLURL::SLURL_COM               = "slurl.com"; +  // For DnD - even though www.slurl.com redirects to slurl.com in a browser, you  can copy and drag  // text with www.slurl.com or a link explicitly pointing at www.slurl.com so testing for this  // version is required also. @@ -437,7 +439,7 @@ std::string LLSLURL::getLoginString() const              LL_WARNS("AppInit") << "Unexpected SLURL type (" << (int)mType << ")for login string" << LL_ENDL;              break;      } -    return  xml_escape_string(unescaped_start.str()); +    return  LLStringFn::xml_encode(unescaped_start.str(), true);  }  bool LLSLURL::operator ==(const LLSLURL& rhs) diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp index a571b5544b..4e8320b72a 100644 --- a/indra/newview/llversioninfo.cpp +++ b/indra/newview/llversioninfo.cpp @@ -76,37 +76,37 @@ LLVersionInfo::~LLVersionInfo()  {  } -S32 LLVersionInfo::getMajor() +S32 LLVersionInfo::getMajor() const  {      return LL_VIEWER_VERSION_MAJOR;  } -S32 LLVersionInfo::getMinor() +S32 LLVersionInfo::getMinor() const  {      return LL_VIEWER_VERSION_MINOR;  } -S32 LLVersionInfo::getPatch() +S32 LLVersionInfo::getPatch() const  {      return LL_VIEWER_VERSION_PATCH;  } -U64 LLVersionInfo::getBuild() +U64 LLVersionInfo::getBuild() const  {      return LL_VIEWER_VERSION_BUILD;  } -std::string LLVersionInfo::getVersion() +std::string LLVersionInfo::getVersion() const  {      return version;  } -std::string LLVersionInfo::getShortVersion() +std::string LLVersionInfo::getShortVersion() const  {      return short_version;  } -std::string LLVersionInfo::getChannelAndVersion() +std::string LLVersionInfo::getChannelAndVersion() const  {      if (mVersionChannel.empty())      { @@ -117,7 +117,7 @@ std::string LLVersionInfo::getChannelAndVersion()      return mVersionChannel;  } -std::string LLVersionInfo::getChannel() +std::string LLVersionInfo::getChannel() const  {      return mWorkingChannelName;  } @@ -128,7 +128,7 @@ void LLVersionInfo::resetChannel(const std::string& channel)      mVersionChannel.clear(); // Reset version and channel string til next use.  } -LLVersionInfo::ViewerMaturity LLVersionInfo::getViewerMaturity() +LLVersionInfo::ViewerMaturity LLVersionInfo::getViewerMaturity() const  {      ViewerMaturity maturity; @@ -166,12 +166,12 @@ LLVersionInfo::ViewerMaturity LLVersionInfo::getViewerMaturity()  } -std::string LLVersionInfo::getBuildConfig() +std::string LLVersionInfo::getBuildConfig() const  {      return build_configuration;  } -std::string LLVersionInfo::getReleaseNotes() +std::string LLVersionInfo::getReleaseNotes() const  {      return mReleaseNotes;  } diff --git a/indra/newview/llversioninfo.h b/indra/newview/llversioninfo.h index aed43263a6..237b37a084 100644 --- a/indra/newview/llversioninfo.h +++ b/indra/newview/llversioninfo.h @@ -52,38 +52,38 @@ public:      ~LLVersionInfo();      /// return the major version number as an integer -    S32 getMajor(); +    S32 getMajor() const;      /// return the minor version number as an integer -    S32 getMinor(); +    S32 getMinor() const;      /// return the patch version number as an integer -    S32 getPatch(); +    S32 getPatch() const;      /// return the build number as an integer -    U64 getBuild(); +    U64 getBuild() const;      /// return the full viewer version as a string like "2.0.0.200030" -    std::string getVersion(); +    std::string getVersion() const;      /// return the viewer version as a string like "2.0.0" -    std::string getShortVersion(); +    std::string getShortVersion() const;      /// return the viewer version and channel as a string      /// like "Second Life Release 2.0.0.200030" -    std::string getChannelAndVersion(); +    std::string getChannelAndVersion() const;      /// return the channel name, e.g. "Second Life" -    std::string getChannel(); +    std::string getChannel() const;      /// return the CMake build type -    std::string getBuildConfig(); +    std::string getBuildConfig() const;      /// reset the channel name used by the viewer.      void resetChannel(const std::string& channel);      /// return the bit width of an address -    S32 getAddressSize() { return ADDRESS_SIZE; } +    S32 getAddressSize() const { return ADDRESS_SIZE; }      typedef enum      { @@ -92,11 +92,11 @@ public:          BETA_VIEWER,          RELEASE_VIEWER      } ViewerMaturity; -    ViewerMaturity getViewerMaturity(); +    ViewerMaturity getViewerMaturity() const;      /// get the release-notes URL, once it becomes available -- until then,      /// return empty string -    std::string getReleaseNotes(); +    std::string getReleaseNotes() const;  private:      std::string version; @@ -107,7 +107,7 @@ private:      std::string mWorkingChannelName;      // Storage for the "version and channel" string.      // This will get reset too. -    std::string mVersionChannel; +    mutable std::string mVersionChannel;      std::string build_configuration;      std::string mReleaseNotes;      // Store unique_ptrs to the next couple things so we don't have to explain diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp index 1148e81fd5..7c7bd98bcd 100644 --- a/indra/newview/llxmlrpclistener.cpp +++ b/indra/newview/llxmlrpclistener.cpp @@ -39,12 +39,6 @@  #include <boost/scoped_ptr.hpp>  #include <boost/range.hpp>          // boost::begin(), boost::end() -#ifdef LL_USESYSTEMLIBS -#include <xmlrpc.h> -#else -#include <xmlrpc-epi/xmlrpc.h> -#endif -  #include "curl/curl.h"  // other Linden headers @@ -178,13 +172,6 @@ public:  static const CURLcodeMapper sCURLcodeMapper; -LLXMLRPCListener::LLXMLRPCListener(const std::string& pumpname): -    mBoundListener(LLEventPumps::instance(). -                   obtain(pumpname). -                   listen("LLXMLRPCListener", boost::bind(&LLXMLRPCListener::process, this, _1))) -{ -} -  /**   * Capture an outstanding LLXMLRPCTransaction and poll it periodically until   * done. @@ -213,38 +200,20 @@ public:          mMethod(command["method"]),          mReplyPump(command["reply"])      { -        // LL_ERRS if any of these are missing -        const char* required[] = { "uri", "method", "reply" }; -        // optional: "options" (array of string) -        // Validate the request -        std::set<std::string> missing; -        for (const char** ri = boost::begin(required); ri != boost::end(required); ++ri) +        // LL_ERRS if any of these keys are missing or empty +        if (mUri.empty() || mMethod.empty() || mReplyPump.empty())          { -            // If the command does not contain this required entry, add it to 'missing'. -            if (! command.has(*ri)) -            { -                missing.insert(*ri); -            } -        } -        if (! missing.empty()) -        { -            LL_ERRS("LLXMLRPCListener") << mMethod << " request missing params: "; -            const char* separator = ""; -            for (std::set<std::string>::const_iterator mi(missing.begin()), mend(missing.end()); -                 mi != mend; ++mi) -            { -                LL_CONT << separator << *mi; -                separator = ", "; -            } -            LL_CONT << LL_ENDL; +            LL_ERRS("LLXMLRPCListener") +                << "Some params are missing: " +                << "reply: '" << mReplyPump << "', " +                << "method: '" << mMethod << "', " +                << "uri: '" << mUri << "'" +                << LL_ENDL;          } -        // Build the XMLRPC request. -        XMLRPC_REQUEST request = XMLRPC_RequestNew(); -        XMLRPC_RequestSetMethodName(request, mMethod.c_str()); -        XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); -        XMLRPC_VALUE xparams = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); -        LLSD params(command["params"]); +        LLSD request_params = LLSD::emptyMap(); + +        LLSD params = command.get("params");          if (params.isMap())          {              for (LLSD::map_const_iterator pi(params.beginMap()), pend(params.endMap()); @@ -252,44 +221,33 @@ public:              {                  std::string name(pi->first);                  LLSD param(pi->second); -                if (param.isString()) +                switch (param.type())                  { -                    XMLRPC_VectorAppendString(xparams, name.c_str(), param.asString().c_str(), 0); -                } -                else if (param.isInteger() || param.isBoolean()) -                { -                    XMLRPC_VectorAppendInt(xparams, name.c_str(), param.asInteger()); -                } -                else if (param.isReal()) -                { -                    XMLRPC_VectorAppendDouble(xparams, name.c_str(), param.asReal()); -                } -                else -                { -                    LL_ERRS("LLXMLRPCListener") << mMethod << " request param " -                                                << name << " has unknown type: " << param << LL_ENDL; +                case LLSD::TypeString: +                case LLSD::TypeInteger: +                case LLSD::TypeReal: +                    request_params.insert(name, param); +                    break; +                case LLSD::TypeBoolean: +                    request_params.insert(name, param.asInteger()); +                    break; +                default: +                    LL_ERRS("LLXMLRPCListener") << mMethod +                        << " request param '" << name << "' has unknown type: " << param << LL_ENDL;                  }              }          } -        LLSD options(command["options"]); + +        LLSD options = command.get("options");          if (options.isArray())          { -            XMLRPC_VALUE xoptions = XMLRPC_CreateVector("options", xmlrpc_vector_array); -            for (LLSD::array_const_iterator oi(options.beginArray()), oend(options.endArray()); -                 oi != oend; ++oi) -            { -                XMLRPC_VectorAppendString(xoptions, NULL, oi->asString().c_str(), 0); -            } -            XMLRPC_AddValueToVector(xparams, xoptions); +            request_params.insert("options", options);          } -        XMLRPC_RequestSetData(request, xparams); -        mTransaction.reset(new LLXMLRPCTransaction(mUri, request, true, command.has("http_params")? LLSD(command["http_params"]) : LLSD())); +        LLSD http_params = command.get("http_params"); +        mTransaction.reset(new LLXMLRPCTransaction(mUri, mMethod, request_params, http_params));          mPreviousStatus = mTransaction->status(NULL); -        // Free the XMLRPC_REQUEST object and the attached data values. -        XMLRPC_RequestFree(request, 1); -          // Now ensure that we get regular callbacks to poll for completion.          mBoundListener =              LLEventPumps::instance(). @@ -323,7 +281,7 @@ public:          data["error"] = "";          data["transfer_rate"] = 0.0;          LLEventPump& replyPump(LLEventPumps::instance().obtain(mReplyPump)); -        if (! done) +        if (!done)          {              // Not done yet, carry on.              if (status == LLXMLRPCTransaction::StatusDownloading @@ -367,10 +325,8 @@ public:          // Given 'message', need we care?          if (status == LLXMLRPCTransaction::StatusComplete)          { -            // Success! Parse data. -            std::string status_string(data["status"]); -            data["responses"] = parseResponse(status_string); -            data["status"] = status_string; +            // Success! Retrieve response data. +            data["responses"] = mTransaction->response();          }          // whether successful or not, send reply on requested LLEventPump @@ -388,159 +344,6 @@ public:      }  private: -    /// Derived from LLUserAuth::parseResponse() and parseOptionInto() -    LLSD parseResponse(std::string& status_string) -    { -        // Extract every member into data["responses"] (a map of string -        // values). -        XMLRPC_REQUEST response = mTransaction->response(); -        if (! response) -        { -            LL_DEBUGS("LLXMLRPCListener") << "No response" << LL_ENDL; -            return LLSD(); -        } - -        XMLRPC_VALUE param = XMLRPC_RequestGetData(response); -        if (! param) -        { -            LL_DEBUGS("LLXMLRPCListener") << "Response contains no data" << LL_ENDL; -            return LLSD(); -        } - -        // Now, parse everything -        return parseValues(status_string, "", param); -    } - -    LLSD parseValue(std::string& status_string, const std::string& key, const std::string& key_pfx, XMLRPC_VALUE param) -    { -        LLSD response; - -        XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(param); -        switch (type) -        { -            case xmlrpc_type_empty: -                LL_INFOS("LLXMLRPCListener") << "Empty result for key " << key_pfx << key << LL_ENDL; -                break; -            case xmlrpc_type_base64: -                { -                    S32 len = XMLRPC_GetValueStringLen(param); -                    const char* buf = XMLRPC_GetValueBase64(param); -                    if ((len > 0) && buf) -                    { -                        // During implementation this code was not tested -                        // If you encounter this, please make sure this is correct, -                        // then remove llassert -                        llassert(0); - -                        LLSD::Binary data; -                        data.resize(len); -                        memcpy((void*)&data[0], (void*)buf, len); -                        response = data; -                    } -                    else -                    { -                        LL_WARNS("LLXMLRPCListener") << "Potentially malformed xmlrpc_type_base64 for key " -                            << key_pfx << key << LL_ENDL; -                    } -                    break; -                } -            case xmlrpc_type_boolean: -                { -                    response = LLSD::Boolean(XMLRPC_GetValueBoolean(param)); -                    LL_DEBUGS("LLXMLRPCListener") << "val: " << response << LL_ENDL; -                    break; -                } -            case xmlrpc_type_datetime: -                { -                    std::string iso8601_date(XMLRPC_GetValueDateTime_ISO8601(param)); -                    LL_DEBUGS("LLXMLRPCListener") << "val: " << iso8601_date << LL_ENDL; -                    response = LLSD::Date(iso8601_date); -                    break; -                } -            case xmlrpc_type_double: -                { -                    response = LLSD::Real(XMLRPC_GetValueDouble(param)); -                    LL_DEBUGS("LLXMLRPCListener") << "val: " << response << LL_ENDL; -                    break; -                } -            case xmlrpc_type_int: -                { -                    response = LLSD::Integer(XMLRPC_GetValueInt(param)); -                    LL_DEBUGS("LLXMLRPCListener") << "val: " << response << LL_ENDL; -                    break; -                } -            case xmlrpc_type_string: -                { -                    response = LLSD::String(XMLRPC_GetValueString(param)); -                    LL_DEBUGS("LLXMLRPCListener") << "val: " << response << LL_ENDL; -                    break; -                } -            case xmlrpc_type_mixed: -            case xmlrpc_type_array: -                { -                    // We expect this to be an array of submaps. Walk the array, -                    // recursively parsing each submap and collecting them. -                    LLSD array; -                    int i = 0;          // for descriptive purposes -                    for (XMLRPC_VALUE row = XMLRPC_VectorRewind(param); row; -                         row = XMLRPC_VectorNext(param), ++i) -                    { -                        // Recursive call. For the lower-level key_pfx, if 'key' -                        // is "foo", pass "foo[0]:", then "foo[1]:", etc. In the -                        // nested call, a subkey "bar" will then be logged as -                        // "foo[0]:bar", and so forth. -                        // Parse the scalar subkey/value pairs from this array -                        // entry into a temp submap. Collect such submaps in 'array'. - -                        array.append(parseValue(status_string, "", -                                                 STRINGIZE(key_pfx << key << '[' << i << "]:"), -                                                 row)); -                    } -                    // Having collected an 'array' of 'submap's, insert that whole -                    // 'array' as the value of this 'key'. -                    response = array; -                    break; -                } -            case xmlrpc_type_struct: -                { -                    response = parseValues(status_string, -                                              STRINGIZE(key_pfx << key << ':'), -                                              param); -                    break; -                } -            case xmlrpc_type_none: // Not expected -            default: -                // whoops - unrecognized type -                LL_WARNS("LLXMLRPCListener") << "Unhandled xmlrpc type " << type << " for key " -                    << key_pfx << key << LL_ENDL; -                response = STRINGIZE("<bad XMLRPC type " << type << '>'); -                status_string = "BadType"; -        } -        return response; -    } - -    /** -     * Parse key/value pairs from a given XMLRPC_VALUE into an LLSD map. -     * @param key_pfx Used to describe a given key in log messages. At top -     * level, pass "". When parsing an options array, pass the top-level key -     * name of the array plus the index of the array entry; to this we'll -     * append the subkey of interest. -     * @param param XMLRPC_VALUE iterator. At top level, pass -     * XMLRPC_RequestGetData(XMLRPC_REQUEST). -     */ -    LLSD parseValues(std::string& status_string, const std::string& key_pfx, XMLRPC_VALUE param) -    { -        LLSD responses; -        for (XMLRPC_VALUE current = XMLRPC_VectorRewind(param); current; -             current = XMLRPC_VectorNext(param)) -        { -            std::string key(XMLRPC_GetValueID(current)); -            LL_DEBUGS("LLXMLRPCListener") << "key: " << key_pfx << key << LL_ENDL; -            responses.insert(key, parseValue(status_string, key, key_pfx, current)); -        } -        return responses; -    } -      const LLReqID mReqID;      const std::string mUri;      const std::string mMethod; @@ -550,11 +353,18 @@ private:      LLXMLRPCTransaction::EStatus mPreviousStatus; // To detect state changes.  }; -bool LLXMLRPCListener::process(const LLSD& command) +LLXMLRPCListener::LLXMLRPCListener(const std::string& pumpname) +: mBoundListener(LLEventPumps::instance().obtain(pumpname).listen +( +    "LLXMLRPCListener", +    [&](const LLSD& command) -> bool +    { +        // Allocate a new heap Poller, but do not save a pointer to it. Poller +        // will check its own status and free itself on completion of the request. +        (new Poller(command)); +        // Conventional event listener return +        return false; +    } +))  { -    // Allocate a new heap Poller, but do not save a pointer to it. Poller -    // will check its own status and free itself on completion of the request. -    (new Poller(command)); -    // conventional event listener return -    return false;  } diff --git a/indra/newview/llxmlrpclistener.h b/indra/newview/llxmlrpclistener.h index aaed98eec5..fd75acb8b1 100644 --- a/indra/newview/llxmlrpclistener.h +++ b/indra/newview/llxmlrpclistener.h @@ -42,9 +42,6 @@ public:      /// Specify the pump name on which to listen      LLXMLRPCListener(const std::string& pumpname); -    /// Handle request events on the event pump specified at construction time -    bool process(const LLSD& command); -  private:      LLTempBoundListener mBoundListener;  }; diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index ec6e22cd7a..55622fb6b7 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -42,22 +42,11 @@  #include "bufferarray.h"  #include "llversioninfo.h"  #include "llviewercontrol.h" +#include "llxmlnode.h"  #include "stringize.h"  // Have to include these last to avoid queue redefinition! -#ifdef LL_USESYSTEMLIBS -#include <xmlrpc.h> -#else -#include <xmlrpc-epi/xmlrpc.h> -#endif -// <xmlrpc-epi/queue.h> contains a harmful #define queue xmlrpc_queue. This -// breaks any use of std::queue. Ditch that #define: if any of our code wants -// to reference xmlrpc_queue, let it reference it directly. -#if defined(queue) -#undef queue -#endif -  #include "llappviewer.h"  #include "lltrans.h" @@ -75,111 +64,6 @@ namespace boost  // nothing.  static LLXMLRPCListener listener("LLXMLRPCTransaction"); -LLXMLRPCValue LLXMLRPCValue::operator[](const char* id) const -{ -    return LLXMLRPCValue(XMLRPC_VectorGetValueWithID(mV, id)); -} - -std::string LLXMLRPCValue::asString() const -{ -    const char* s = XMLRPC_GetValueString(mV); -    return s ? s : ""; -} - -int     LLXMLRPCValue::asInt() const    { return XMLRPC_GetValueInt(mV); } -bool    LLXMLRPCValue::asBool() const   { return XMLRPC_GetValueBoolean(mV) != 0; } -double  LLXMLRPCValue::asDouble() const { return XMLRPC_GetValueDouble(mV); } - -LLXMLRPCValue LLXMLRPCValue::rewind() -{ -    return LLXMLRPCValue(XMLRPC_VectorRewind(mV)); -} - -LLXMLRPCValue LLXMLRPCValue::next() -{ -    return LLXMLRPCValue(XMLRPC_VectorNext(mV)); -} - -bool LLXMLRPCValue::isValid() const -{ -    return mV != NULL; -} - -LLXMLRPCValue LLXMLRPCValue::createArray() -{ -    return LLXMLRPCValue(XMLRPC_CreateVector(NULL, xmlrpc_vector_array)); -} - -LLXMLRPCValue LLXMLRPCValue::createStruct() -{ -    return LLXMLRPCValue(XMLRPC_CreateVector(NULL, xmlrpc_vector_struct)); -} - - -void LLXMLRPCValue::append(LLXMLRPCValue& v) -{ -    XMLRPC_AddValueToVector(mV, v.mV); -} - -void LLXMLRPCValue::appendString(const std::string& v) -{ -    XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueString(NULL, v.c_str(), 0)); -} - -void LLXMLRPCValue::appendInt(int v) -{ -    XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueInt(NULL, v)); -} - -void LLXMLRPCValue::appendBool(bool v) -{ -    XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueBoolean(NULL, v)); -} - -void LLXMLRPCValue::appendDouble(double v) -{ -    XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueDouble(NULL, v)); -} - - -void LLXMLRPCValue::append(const char* id, LLXMLRPCValue& v) -{ -    XMLRPC_SetValueID(v.mV, id, 0); -    XMLRPC_AddValueToVector(mV, v.mV); -} - -void LLXMLRPCValue::appendString(const char* id, const std::string& v) -{ -    XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueString(id, v.c_str(), 0)); -} - -void LLXMLRPCValue::appendInt(const char* id, int v) -{ -    XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueInt(id, v)); -} - -void LLXMLRPCValue::appendBool(const char* id, bool v) -{ -    XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueBoolean(id, v)); -} - -void LLXMLRPCValue::appendDouble(const char* id, double v) -{ -    XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueDouble(id, v)); -} - -void LLXMLRPCValue::cleanup() -{ -    XMLRPC_CleanupValue(mV); -    mV = NULL; -} - -XMLRPC_VALUE LLXMLRPCValue::getValue() const -{ -    return mV; -} - -  class LLXMLRPCTransaction::Handler : public LLCore::HttpHandler  {  public: @@ -192,6 +76,9 @@ public:  private: +    bool parseResponse(LLXMLNodePtr root); +    bool parseValue(LLSD& target, LLXMLNodePtr source); +      LLXMLRPCTransaction::Impl *mImpl;      LLCore::HttpRequest::ptr_t mRequest;  }; @@ -213,26 +100,26 @@ public:      LLCore::HttpHandle  mPostH;      std::string         mURI; -      std::string         mProxyAddress;      std::string         mResponseText; -    XMLRPC_REQUEST      mResponse; +    LLSD                mResponseData; +      std::string         mCertStore; -    LLSD mErrorCertData; +    LLSD                mErrorCertData; -    Impl(const std::string& uri, XMLRPC_REQUEST request, bool useGzip, const LLSD& httpParams); -    Impl(const std::string& uri, -        const std::string& method, LLXMLRPCValue params, bool useGzip); -    ~Impl(); +    Impl +    ( +        const std::string& uri, +        const std::string& method, +        const LLSD& params, +        const LLSD& httpParams +    );      bool process();      void setStatus(EStatus code, const std::string& message = "", const std::string& uri = "");      void setHttpStatus(const LLCore::HttpStatus &status); - -private: -    void init(XMLRPC_REQUEST request, bool useGzip, const LLSD& httpParams);  };  LLXMLRPCTransaction::Handler::Handler(LLCore::HttpRequest::ptr_t &request, @@ -275,89 +162,113 @@ void LLXMLRPCTransaction::Handler::onCompleted(LLCore::HttpHandle handle,      mImpl->setStatus(LLXMLRPCTransaction::StatusComplete);      mImpl->mTransferStats = response->getTransferStats(); -    // the contents of a buffer array are potentially noncontiguous, so we +    // The contents of a buffer array are potentially noncontiguous, so we      // will need to copy them into an contiguous block of memory for XMLRPC.      LLCore::BufferArray *body = response->getBody(); -    char * bodydata = new char[body->size()]; +    mImpl->mResponseText.resize(body->size()); -    body->read(0, bodydata, body->size()); +    body->read(0, mImpl->mResponseText.data(), body->size()); -    mImpl->mResponse = XMLRPC_REQUEST_FromXML(bodydata, static_cast<int>(body->size()), 0); +    LLXMLNodePtr root; +    if (!LLXMLNode::parseBuffer(mImpl->mResponseText.data(), body->size(), root, nullptr)) +    { +        LL_WARNS() << "Failed parsing XML response; request URI: " << mImpl->mURI << LL_ENDL; +        return; +    } -    delete[] bodydata; +    if (!parseResponse(root)) +        return; -    bool        hasError = false; -    bool        hasFault = false; -    int         faultCode = 0; -    std::string faultString; +    LL_INFOS() << "XML response parsed successfully; request URI: " << mImpl->mURI << LL_ENDL; +} -    LLXMLRPCValue error(XMLRPC_RequestGetError(mImpl->mResponse)); -    if (error.isValid()) +struct XMLTreeNode final : public LLSD::TreeNode +{ +    XMLTreeNode(const LLXMLNodePtr impl) +        : mImpl(impl) +        , mFirstChild(impl ? create(impl->getFirstChild()) : nullptr) +        , mNextSibling(impl ? create(impl->getNextSibling()) : nullptr)      { -        hasError = true; -        faultCode = error["faultCode"].asInt(); -        faultString = error["faultString"].asString();      } -    else if (XMLRPC_ResponseIsFault(mImpl->mResponse)) + +    static XMLTreeNode* create(LLXMLNodePtr node) { return node ? new XMLTreeNode(node) : nullptr; } + +    virtual bool hasName(const LLSD::String& name) const override { return mImpl && mImpl->hasName(name); } +    virtual LLSD::String getTextContents() const override { return mImpl ? mImpl->getTextContents() : LLStringUtil::null; } +    virtual TreeNode* getFirstChild() const override { return mFirstChild.get(); } +    virtual TreeNode* getNextSibling() const override { return mNextSibling.get(); } + +private: +    const LLXMLNodePtr mImpl; +    const std::shared_ptr<XMLTreeNode> mFirstChild; +    const std::shared_ptr<XMLTreeNode> mNextSibling; +}; + +bool LLXMLRPCTransaction::Handler::parseResponse(LLXMLNodePtr root) +{ +    // We have alreasy checked in LLXMLNode::parseBuffer() +    // that root contains exactly one child +    if (!root->hasName("methodResponse"))      { -        hasFault = true; -        faultCode = XMLRPC_GetResponseFaultCode(mImpl->mResponse); -        faultString = XMLRPC_GetResponseFaultString(mImpl->mResponse); +        LL_WARNS() << "Invalid root element in XML response; request URI: " << mImpl->mURI << LL_ENDL; +        return false;      } -    if (hasError || hasFault) +    LLXMLNodePtr first = root->getFirstChild(); +    LLXMLNodePtr second = first->getFirstChild(); +    if (!first->getNextSibling() && second && !second->getNextSibling())      { -        mImpl->setStatus(LLXMLRPCTransaction::StatusXMLRPCError); - -        LL_WARNS() << "LLXMLRPCTransaction XMLRPC " -            << (hasError ? "error " : "fault ") -            << faultCode << ": " -            << faultString << LL_ENDL; -        LL_WARNS() << "LLXMLRPCTransaction request URI: " -            << mImpl->mURI << LL_ENDL; +        if (first->hasName("fault")) +        { +            LLSD fault; +            if (parseValue(fault, second) && +                fault.isMap() && fault.has("faultCode") && fault.has("faultString")) +            { +                LL_WARNS() << "Request failed;" +                    << " faultCode: '" << fault.get("faultCode").asString() << "'," +                    << " faultString: '" << fault.get("faultString").asString() << "'," +                    << " request URI: " << mImpl->mURI << LL_ENDL; +                return false; +            } +        } +        else if (first->hasName("params") && +            second->hasName("param") && !second->getNextSibling()) +        { +            LLXMLNodePtr third = second->getFirstChild(); +            if (third && !third->getNextSibling() && parseValue(mImpl->mResponseData, third)) +            { +                return true; +            } +        }      } -} - -//========================================================================= +    LL_WARNS() << "Invalid response format; request URI: " << mImpl->mURI << LL_ENDL; -LLXMLRPCTransaction::Impl::Impl(const std::string& uri, -        XMLRPC_REQUEST request, bool useGzip, const LLSD& httpParams) -    : mHttpRequest(), -      mStatus(LLXMLRPCTransaction::StatusNotStarted), -      mURI(uri), -      mResponse(0) -{ -    init(request, useGzip, httpParams); +    return false;  } - -LLXMLRPCTransaction::Impl::Impl(const std::string& uri, -        const std::string& method, LLXMLRPCValue params, bool useGzip) -    : mHttpRequest(), -      mStatus(LLXMLRPCTransaction::StatusNotStarted), -      mURI(uri), -      mResponse(0) +bool LLXMLRPCTransaction::Handler::parseValue(LLSD& target, LLXMLNodePtr source)  { -    XMLRPC_REQUEST request = XMLRPC_RequestNew(); -    XMLRPC_RequestSetMethodName(request, method.c_str()); -    XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); -    XMLRPC_RequestSetData(request, params.getValue()); - -    init(request, useGzip, LLSD()); -    // DEV-28398: without this XMLRPC_RequestFree() call, it looks as though -    // the 'request' object is simply leaked. It's less clear to me whether we -    // should also ask to free request value data (second param 1), since the -    // data come from 'params'. -    XMLRPC_RequestFree(request, 1); +    XMLTreeNode tn(source); +    return target.fromXMLRPCValue(&tn);  } -void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const LLSD& httpParams) +//========================================================================= + +LLXMLRPCTransaction::Impl::Impl +( +    const std::string& uri, +    const std::string& method, +    const LLSD& params, +    const LLSD& http_params +) +    : mHttpRequest() +    , mStatus(LLXMLRPCTransaction::StatusNotStarted) +    , mURI(uri)  {      LLCore::HttpOptions::ptr_t httpOpts;      LLCore::HttpHeaders::ptr_t httpHeaders; -      if (!mHttpRequest)      {          mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest); @@ -366,37 +277,34 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const      // LLRefCounted starts with a 1 ref, so don't add a ref in the smart pointer      httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()); -    // delay between repeats will start from 5 sec and grow to 20 sec with each repeat +    // Delay between repeats will start from 5 sec and grow to 20 sec with each repeat      httpOpts->setMinBackoff(5E6L);      httpOpts->setMaxBackoff(20E6L); -    httpOpts->setTimeout(httpParams.has("timeout") ? httpParams["timeout"].asInteger() : 40L); -    if (httpParams.has("retries")) +    httpOpts->setTimeout(http_params.has("timeout") ? http_params["timeout"].asInteger() : 40L); +    if (http_params.has("retries"))      { -        httpOpts->setRetries(httpParams["retries"].asInteger()); +        httpOpts->setRetries(http_params["retries"].asInteger());      } -    if (httpParams.has("DNSCacheTimeout")) +    if (http_params.has("DNSCacheTimeout"))      { -        httpOpts->setDNSCacheTimeout(httpParams["DNSCacheTimeout"].asInteger()); +        httpOpts->setDNSCacheTimeout(http_params["DNSCacheTimeout"].asInteger());      }      bool vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert");      mCertStore = gSavedSettings.getString("CertStore"); -    httpOpts->setSSLVerifyPeer( vefifySSLCert ); -    httpOpts->setSSLVerifyHost( vefifySSLCert ? 2 : 0); +    httpOpts->setSSLVerifyPeer(vefifySSLCert); +    httpOpts->setSSLVerifyHost(vefifySSLCert ? 2 : 0);      // LLRefCounted starts with a 1 ref, so don't add a ref in the smart pointer      httpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());      httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML); -    std::string user_agent = stringize( -        LLVersionInfo::instance().getChannel(), ' ', -        LLVersionInfo::instance().getMajor(), '.', -        LLVersionInfo::instance().getMinor(), '.', -        LLVersionInfo::instance().getPatch(), " (", -        LLVersionInfo::instance().getBuild(), ')'); +    const LLVersionInfo& vi(LLVersionInfo::instance()); +    std::string user_agent = vi.getChannel() + llformat(" %d.%d.%d (%llu)", +        vi.getMajor(), vi.getMinor(), vi.getPatch(), vi.getBuild());      httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); @@ -404,31 +312,19 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const      //This might help with bug #503 */      //httpOpts->setDNSCacheTimeout(-1); -    LLCore::BufferArray::ptr_t body = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); +    std::string request = +        "<?xml version=\"1.0\"?><methodCall><methodName>" + method + +        "</methodName><params><param>" + params.asXMLRPCValue() + +        "</param></params></methodCall>"; -    // TODO: See if there is a way to serialize to a preallocated buffer I'm -    // not fond of the copy here. -    int requestSize(0); -    char * requestText = XMLRPC_REQUEST_ToXML(request, &requestSize); - -    body->append(requestText, requestSize); +    LLCore::BufferArray::ptr_t body = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); -    XMLRPC_Free(requestText); +    body->append(request.c_str(), request.size()); -    mHandler = LLXMLRPCTransaction::Handler::ptr_t(new Handler( mHttpRequest, this )); +    mHandler = LLXMLRPCTransaction::Handler::ptr_t(new Handler(mHttpRequest, this));      mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID,          mURI, body.get(), httpOpts, httpHeaders, mHandler); - -} - - -LLXMLRPCTransaction::Impl::~Impl() -{ -    if (mResponse) -    { -        XMLRPC_RequestFree(mResponse, 1); -    }  }  bool LLXMLRPCTransaction::Impl::process() @@ -539,18 +435,16 @@ void LLXMLRPCTransaction::Impl::setHttpStatus(const LLCore::HttpStatus &status)  } - -LLXMLRPCTransaction::LLXMLRPCTransaction( -    const std::string& uri, XMLRPC_REQUEST request, bool useGzip, const LLSD& httpParams) -: impl(* new Impl(uri, request, useGzip, httpParams)) -{ } - - -LLXMLRPCTransaction::LLXMLRPCTransaction( +LLXMLRPCTransaction::LLXMLRPCTransaction +(      const std::string& uri, -    const std::string& method, LLXMLRPCValue params, bool useGzip) -: impl(* new Impl(uri, method, params, useGzip)) -{ } +    const std::string& method, +    const LLSD& params, +    const LLSD& http_params +) +: impl(*new Impl(uri, method, params, http_params)) +{ +}  LLXMLRPCTransaction::~LLXMLRPCTransaction()  { @@ -590,14 +484,9 @@ std::string LLXMLRPCTransaction::statusURI()      return impl.mStatusURI;  } -XMLRPC_REQUEST LLXMLRPCTransaction::response() -{ -    return impl.mResponse; -} - -LLXMLRPCValue LLXMLRPCTransaction::responseValue() +const LLSD& LLXMLRPCTransaction::response()  { -    return LLXMLRPCValue(XMLRPC_RequestGetData(impl.mResponse)); +    return impl.mResponseData;  } diff --git a/indra/newview/llxmlrpctransaction.h b/indra/newview/llxmlrpctransaction.h index 4c8796f936..f7a38f5f90 100644 --- a/indra/newview/llxmlrpctransaction.h +++ b/indra/newview/llxmlrpctransaction.h @@ -29,73 +29,22 @@  #include <string> -typedef struct _xmlrpc_request* XMLRPC_REQUEST; -typedef struct _xmlrpc_value* XMLRPC_VALUE; -    // foward decl of types from xmlrpc.h (this usage is type safe) -class LLCertificate; - -class LLXMLRPCValue -    // a c++ wrapper around XMLRPC_VALUE -{ -public: -    LLXMLRPCValue()                     : mV(NULL) { } -    LLXMLRPCValue(XMLRPC_VALUE value)   : mV(value) { } - -    bool isValid() const; - -    std::string asString()  const; -    int         asInt()     const; -    bool        asBool()    const; -    double      asDouble()  const; - -    LLXMLRPCValue operator[](const char*) const; - -    LLXMLRPCValue rewind(); -    LLXMLRPCValue next(); - -    static LLXMLRPCValue createArray(); -    static LLXMLRPCValue createStruct(); - -    void append(LLXMLRPCValue&); -    void appendString(const std::string&); -    void appendInt(int); -    void appendBool(bool); -    void appendDouble(double); -    void appendValue(LLXMLRPCValue&); - -    void append(const char*, LLXMLRPCValue&); -    void appendString(const char*, const std::string&); -    void appendInt(const char*, int); -    void appendBool(const char*, bool); -    void appendDouble(const char*, double); -    void appendValue(const char*, LLXMLRPCValue&); - -    void cleanup(); -        // only call this on the top level created value - -    XMLRPC_VALUE getValue() const; - -private: -    XMLRPC_VALUE mV; -}; - - +/// An asynchronous request and responses via XML-RPC  class LLXMLRPCTransaction -    // an asynchronous request and responses via XML-RPC  {  public: -    LLXMLRPCTransaction(const std::string& uri, -        XMLRPC_REQUEST request, bool useGzip = true, const LLSD& httpParams = LLSD()); -        // does not take ownership of the request object -        // request can be freed as soon as the transaction is constructed - -    LLXMLRPCTransaction(const std::string& uri, -        const std::string& method, LLXMLRPCValue params, bool useGzip = true); -        // *does* take control of the request value, you must not free it +    LLXMLRPCTransaction +    ( +        const std::string& uri, +        const std::string& method, +        const LLSD& params, +        const LLSD& http_params = LLSD() +    );      ~LLXMLRPCTransaction(); -    typedef enum e_status { +    typedef enum e_status +    {          StatusNotStarted,          StatusStarted,          StatusDownloading, @@ -105,26 +54,25 @@ public:          StatusOtherError      } EStatus; +    /// Run the request a little, returns true when done      bool process(); -        // run the request a little, returns true when done +    /// Return a status, and extended CURL code, if code isn't null      EStatus status(int* curlCode); -        // return status, and extended CURL code, if code isn't null      LLSD getErrorCertData(); + +    /// Return a message string, suitable for showing the user      std::string statusMessage(); -        // return a message string, suitable for showing the user + +    /// Return a URI for the user with more information (can be empty)      std::string statusURI(); -        // return a URI for the user with more information -        // can be empty -    XMLRPC_REQUEST response(); -    LLXMLRPCValue responseValue(); -        // only valid if StatusComplete, otherwise NULL -        // retains ownership of the result object, don't free it +    /// Only non-empty if StatusComplete, otherwise Undefined +    const LLSD& response(); +    /// Only valid if StsatusComplete, otherwise 0.0      F64 transferRate(); -        // only valid if StsatusComplete, otherwise 0.0  private:      class Handler; @@ -133,6 +81,4 @@ private:      Impl& impl;  }; - -  #endif // LLXMLRPCTRANSACTION_H diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml index 7bcae69779..604eb7c58f 100644 --- a/indra/newview/skins/default/xui/da/floater_about.xml +++ b/indra/newview/skins/default/xui/da/floater_about.xml @@ -69,7 +69,6 @@ OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.  PCRE Copyright (c) 1997-2008 University of Cambridge  SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga  SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -xmlrpc-epi Copyright (C) 2000 Epinions, Inc.  xxHash Copyright (C) 2012-2020 Yann Collet.  zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.  google-perftools Copyright (c) 2005, Google Inc. diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml index 10ccf0d5da..320db7f654 100644 --- a/indra/newview/skins/default/xui/de/floater_about.xml +++ b/indra/newview/skins/default/xui/de/floater_about.xml @@ -28,7 +28,6 @@ mit Open-Source-Beiträgen von:</text>          PCRE Copyright (c) 1997-2012 University of Cambridge.          SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga.          SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com). -        xmlrpc-epi Copyright (C) 2000 Epinions, Inc.          xxHash Copyright (C) 2012-2020 Yann Collet.          zlib Copyright (C) 1995-2012 Jean-loup Gailly und Mark Adler. diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index ff2fa93cbb..126cd84d56 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -111,7 +111,6 @@ Dummy Name replaced at run time          PCRE Copyright (c) 1997-2012 University of Cambridge          SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga          SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -        xmlrpc-epi Copyright (C) 2000 Epinions, Inc.          xxHash Copyright (C) 2012-2020 Yann Collet.          zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml index e14ba32f69..8103a95376 100644 --- a/indra/newview/skins/default/xui/es/floater_about.xml +++ b/indra/newview/skins/default/xui/es/floater_about.xml @@ -28,7 +28,6 @@ con contribuciones de código abierto de:</text>          PCRE Copyright (c) 1997-2012 University of Cambridge          SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga          SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -        xmlrpc-epi Copyright (C) 2000 Epinions, Inc.          xxHash Copyright (C) 2012-2020 Yann Collet.          zlib Copyright (C) 1995-2012 Jean-loup Gailly y Mark Adler. diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml index 09da1fb5fd..b6ea621177 100644 --- a/indra/newview/skins/default/xui/fr/floater_about.xml +++ b/indra/newview/skins/default/xui/fr/floater_about.xml @@ -28,7 +28,6 @@ avec les contributions Open Source de :</text>          PCRE Copyright (c) 1997-2012 University of Cambridge          SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga          SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -        xmlrpc-epi Copyright (C) 2000 Epinions, Inc.          xxHash Copyright (C) 2012-2020 Yann Collet.          zlib Copyright (C) 1995-2012 Jean-Loup Gailly et Mark Adler. diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml index 7e195d3ca9..77be47d749 100644 --- a/indra/newview/skins/default/xui/it/floater_about.xml +++ b/indra/newview/skins/default/xui/it/floater_about.xml @@ -28,7 +28,6 @@ con contributi open source da:</text>          PCRE Copyright (c) 1997-2012 University of Cambridge          SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga          SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -        xmlrpc-epi Copyright (C) 2000 Epinions, Inc.          xxHash Copyright (C) 2012-2020 Yann Collet.          zlib Copyright (C) 1995-2012 Jean-loup Gailly e Mark Adler. diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml index 12d763be37..6cd22f6a31 100644 --- a/indra/newview/skins/default/xui/ja/floater_about.xml +++ b/indra/newview/skins/default/xui/ja/floater_about.xml @@ -33,7 +33,6 @@ OpenSSL Copyright (C) 1998-2008 The OpenSSL Project.  PCRE Copyright (c) 1997-2012 University of Cambridge  SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga  SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -xmlrpc-epi Copyright (C) 2000 Epinions, Inc.  xxHash Copyright (C) 2012-2020 Yann Collet.  zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml index aaed728f84..0e95c53109 100644 --- a/indra/newview/skins/default/xui/pt/floater_about.xml +++ b/indra/newview/skins/default/xui/pt/floater_about.xml @@ -28,7 +28,6 @@ com contribuições de código aberto de:</text>          PCRE Copyright (c) 1997-2012 University of Cambridge          SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga          SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -        xmlrpc-epi Copyright (C) 2000 Epinions, Inc.          xxHash Copyright (C) 2012-2020 Yann Collet.          zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. diff --git a/indra/newview/skins/default/xui/ru/floater_about.xml b/indra/newview/skins/default/xui/ru/floater_about.xml index a65a979ccd..22827bc397 100644 --- a/indra/newview/skins/default/xui/ru/floater_about.xml +++ b/indra/newview/skins/default/xui/ru/floater_about.xml @@ -28,7 +28,6 @@          PCRE (c) 1997-2012, Кембриджский университет          SDL (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga          SSLeay (C) 1995-1998 Eric Young (eay@cryptsoft.com) -        xmlrpc-epi (C) 2000 Epinions, Inc.          xxHash Copyright (C) 2012-2020 Yann Collet.          zlib (C) 1995-2012 Jean-loup Gailly и Mark Adler. diff --git a/indra/newview/skins/default/xui/tr/floater_about.xml b/indra/newview/skins/default/xui/tr/floater_about.xml index 40ca3707c3..ca21bee464 100644 --- a/indra/newview/skins/default/xui/tr/floater_about.xml +++ b/indra/newview/skins/default/xui/tr/floater_about.xml @@ -28,7 +28,6 @@ açık kaynak kod katkısında bulunanlar şunlardır:</text>          PCRE Telif Hakkı (c) 1997-2012 University of Cambridge          SDL Telif Hakkı (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga          SSLeay Telif Hakkı (C) 1995-1998 Eric Young (eay@cryptsoft.com) -        xmlrpc-epi Telif Hakkı (C) 2000 Epinions, Inc.          xxHash Copyright (C) 2012-2020 Yann Collet.          zlib Telif Hakkı (C) 1995-2012 Jean-loup Gailly ve Mark Adler. diff --git a/indra/newview/skins/default/xui/zh/floater_about.xml b/indra/newview/skins/default/xui/zh/floater_about.xml index a56ae753d1..727f598894 100644 --- a/indra/newview/skins/default/xui/zh/floater_about.xml +++ b/indra/newview/skins/default/xui/zh/floater_about.xml @@ -28,7 +28,6 @@          PCRE Copyright (c) 1997-2012 University of Cambridge          SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga          SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -        xmlrpc-epi Copyright (C) 2000 Epinions, Inc.          xxHash Copyright (C) 2012-2020 Yann Collet.          zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index 2a0468f3ad..48fecb4f22 100644 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -66,6 +66,16 @@ public:      LLEventPump& getEventPump() { return mPump; }  private: +    LLSD hidePasswd(const LLSD& data) +    { +        LLSD result(data); +        if (result.has("params") && result["params"].has("passwd")) +        { +            result["params"]["passwd"] = "*******"; +        } +        return result; +    } +      LLSD getProgressEventLLSD(const std::string& state, const std::string& change,                             const LLSD& data = LLSD())      { @@ -74,15 +84,16 @@ private:          status_data["change"] = change;          status_data["progress"] = 0.0f; -        if(mAuthResponse.has("transfer_rate")) +        if (mAuthResponse.has("transfer_rate"))          {              status_data["transfer_rate"] = mAuthResponse["transfer_rate"];          } -        if(data.isDefined()) +        if (data.isDefined())          {              status_data["data"] = data;          } +          return status_data;      } @@ -119,17 +130,18 @@ private:  void LLLogin::Impl::connect(const std::string& uri, const LLSD& login_params)  { -    LL_DEBUGS("LLLogin") << " connect with  uri '" << uri << "', login_params " << login_params << LL_ENDL; +    LL_DEBUGS("LLLogin") << " connect with uri '" << uri << "', login_params " << login_params << LL_ENDL;      // Launch a coroutine with our login_() method. Run the coroutine until      // its first wait; at that point, return here.      std::string coroname = -        LLCoros::instance().launch("LLLogin::Impl::login_", -                                   boost::bind(&Impl::loginCoro, this, uri, login_params)); -    LL_DEBUGS("LLLogin") << " connected with  uri '" << uri << "', login_params " << login_params << LL_ENDL; +        LLCoros::instance().launch("LLLogin::Impl::login_", [&]() { loginCoro(uri, login_params); }); + +    LL_DEBUGS("LLLogin") << " connected with uri '" << uri << "', login_params " << login_params << LL_ENDL;  } -namespace { +namespace +{  // Instantiate this rendezvous point at namespace scope so it's already  // present no matter how early the updater might post to it.  // Use an LLEventMailDrop, which has future-like semantics: regardless of the @@ -140,12 +152,8 @@ static LLEventMailDrop sSyncPoint("LoginSync");  void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)  { -    LLSD printable_params = login_params; -    if (printable_params.has("params") -        && printable_params["params"].has("passwd")) -    { -        printable_params["params"]["passwd"] = "*******"; -    } +    LLSD printable_params = hidePasswd(login_params); +      try      {          LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::getName() @@ -171,12 +179,7 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)              ++attempts;              LLSD progress_data;              progress_data["attempt"] = attempts; -            progress_data["request"] = request; -            if (progress_data["request"].has("params") -                && progress_data["request"]["params"].has("passwd")) -            { -                progress_data["request"]["params"]["passwd"] = "*******"; -            } +            progress_data["request"] = hidePasswd(request);              sendProgressEvent("offline", "authenticating", progress_data);              // We expect zero or more "Downloading" status events, followed by | 
