diff options
Diffstat (limited to 'indra/newview/llxmlrpctransaction.cpp')
-rw-r--r-- | indra/newview/llxmlrpctransaction.cpp | 829 |
1 files changed, 359 insertions, 470 deletions
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index ba7e8d7298..7fbcb5fc04 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -1,32 +1,32 @@ -/** +/** * @file llxmlrpctransaction.cpp - * @brief LLXMLRPCTransaction and related class implementations + * @brief LLXMLRPCTransaction and related class implementations * * $LicenseInfo:firstyear=2006&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$ */ #include "llviewerprecompiledheaders.h" // include this to get winsock2 because openssl attempts to include winsock1 -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include <openssl/x509_vfy.h> #include <openssl/ssl.h> #include "llsecapi.h" @@ -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" @@ -65,7 +54,7 @@ namespace boost { - using ::boost::movelib::unique_ptr; // move unique_ptr into the boost namespace. + using ::boost::movelib::unique_ptr; // move unique_ptr into the boost namespace. } // Static instance of LLXMLRPCListener declared here so that every time we @@ -75,545 +64,445 @@ 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: - Handler(LLCore::HttpRequest::ptr_t &request, LLXMLRPCTransaction::Impl *impl); - virtual ~Handler(); +public: + Handler(LLCore::HttpRequest::ptr_t &request, LLXMLRPCTransaction::Impl *impl); - virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); + void onCompleted(LLCore::HttpHandle handle, + LLCore::HttpResponse* response) override; - typedef boost::shared_ptr<LLXMLRPCTransaction::Handler> ptr_t; + typedef std::shared_ptr<LLXMLRPCTransaction::Handler> ptr_t; private: - - LLXMLRPCTransaction::Impl *mImpl; - LLCore::HttpRequest::ptr_t mRequest; + LLXMLRPCTransaction::Impl *mImpl; + LLCore::HttpRequest::ptr_t mRequest; }; class LLXMLRPCTransaction::Impl { public: - typedef LLXMLRPCTransaction::EStatus EStatus; + typedef LLXMLRPCTransaction::EStatus EStatus; - LLCore::HttpRequest::ptr_t mHttpRequest; + LLCore::HttpRequest::ptr_t mHttpRequest; - EStatus mStatus; - CURLcode mCurlCode; - std::string mStatusMessage; - std::string mStatusURI; - LLCore::HttpResponse::TransferStats::ptr_t mTransferStats; - Handler::ptr_t mHandler; - LLCore::HttpHandle mPostH; + EStatus mStatus; + CURLcode mCurlCode; + std::string mStatusMessage; + std::string mStatusURI; + LLCore::HttpResponse::TransferStats::ptr_t mTransferStats; + Handler::ptr_t mHandler; + LLCore::HttpHandle mPostH; - std::string mURI; + std::string mURI; + std::string mProxyAddress; - std::string mProxyAddress; + std::string mResponseText; + LLSD mResponseData; + bool mHasResponse; + bool mResponseParsed; - std::string mResponseText; - XMLRPC_REQUEST mResponse; - std::string mCertStore; - LLSD mErrorCertData; + std::string mCertStore; + 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(); + bool process(); - void setStatus(EStatus code, const std::string& message = "", const std::string& uri = ""); - void setHttpStatus(const LLCore::HttpStatus &status); + 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); + bool parseResponse(LLXMLNodePtr root); + bool parseValue(LLSD& target, LLXMLNodePtr source); }; -LLXMLRPCTransaction::Handler::Handler(LLCore::HttpRequest::ptr_t &request, - LLXMLRPCTransaction::Impl *impl) : - mImpl(impl), - mRequest(request) -{ -} - -LLXMLRPCTransaction::Handler::~Handler() +LLXMLRPCTransaction::Handler::Handler(LLCore::HttpRequest::ptr_t &request, + LLXMLRPCTransaction::Impl *impl) : + mImpl(impl), + mRequest(request) { } -void LLXMLRPCTransaction::Handler::onCompleted(LLCore::HttpHandle handle, - LLCore::HttpResponse * response) +void LLXMLRPCTransaction::Handler::onCompleted(LLCore::HttpHandle handle, + LLCore::HttpResponse * response) { - LLCore::HttpStatus status = response->getStatus(); + LLCore::HttpStatus status = response->getStatus(); - if (!status) - { + if (!status) + { mImpl->setHttpStatus(status); LLSD errordata = status.getErrorData(); mImpl->mErrorCertData = errordata; - if ((status.toULong() != CURLE_SSL_PEER_CERTIFICATE) && - (status.toULong() != CURLE_SSL_CACERT)) - { - // if we have a curl error that's not already been handled - // (a non cert error), then generate the warning message as - // appropriate - LL_WARNS() << "LLXMLRPCTransaction error " - << status.toHex() << ": " << status.toString() << LL_ENDL; - LL_WARNS() << "LLXMLRPCTransaction request URI: " - << mImpl->mURI << LL_ENDL; - } - - return; - } - - mImpl->setStatus(LLXMLRPCTransaction::StatusComplete); - mImpl->mTransferStats = response->getTransferStats(); - - // 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()]; - - body->read(0, bodydata, body->size()); - - mImpl->mResponse = XMLRPC_REQUEST_FromXML(bodydata, body->size(), 0); - - delete[] bodydata; - - bool hasError = false; - bool hasFault = false; - int faultCode = 0; - std::string faultString; - - LLXMLRPCValue error(XMLRPC_RequestGetError(mImpl->mResponse)); - if (error.isValid()) - { - hasError = true; - faultCode = error["faultCode"].asInt(); - faultString = error["faultString"].asString(); - } - else if (XMLRPC_ResponseIsFault(mImpl->mResponse)) - { - hasFault = true; - faultCode = XMLRPC_GetResponseFaultCode(mImpl->mResponse); - faultString = XMLRPC_GetResponseFaultString(mImpl->mResponse); - } - - if (hasError || hasFault) - { - 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 ((status.toULong() != CURLE_SSL_PEER_CERTIFICATE) && + (status.toULong() != CURLE_SSL_CACERT)) + { + // if we have a curl error that's not already been handled + // (a non cert error), then generate the warning message as + // appropriate + LL_WARNS() << "LLXMLRPCTransaction error " + << status.toHex() << ": " << status.toString() << LL_ENDL; + LL_WARNS() << "LLXMLRPCTransaction request URI: " + << mImpl->mURI << LL_ENDL; + } -} + return; + } -//========================================================================= + mImpl->mTransferStats = response->getTransferStats(); -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); -} + // 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(); + mImpl->mResponseText.resize(body->size()); + body->read(0, mImpl->mResponseText.data(), body->size()); -LLXMLRPCTransaction::Impl::Impl(const std::string& uri, - const std::string& method, LLXMLRPCValue params, bool useGzip) - : mHttpRequest(), - mStatus(LLXMLRPCTransaction::StatusNotStarted), - mURI(uri), - mResponse(0) -{ - 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); -} - -void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const LLSD& httpParams) -{ - LLCore::HttpOptions::ptr_t httpOpts; - LLCore::HttpHeaders::ptr_t httpHeaders; - - - if (!mHttpRequest) - { - mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest); - } - - // 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 - httpOpts->setMinBackoff(5E6L); - httpOpts->setMaxBackoff(20E6L); - - httpOpts->setTimeout(httpParams.has("timeout") ? httpParams["timeout"].asInteger() : 40L); - if (httpParams.has("retries")) - { - httpOpts->setRetries(httpParams["retries"].asInteger()); - } - if (httpParams.has("DNSCacheTimeout")) - { - httpOpts->setDNSCacheTimeout(httpParams["DNSCacheTimeout"].asInteger()); - } - - bool vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert"); - mCertStore = gSavedSettings.getString("CertStore"); - - 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(), ')'); - - httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); - - ///* Setting the DNS cache timeout to -1 disables it completely. - //This might help with bug #503 */ - //httpOpts->setDNSCacheTimeout(-1); - - LLCore::BufferArray::ptr_t body = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); - - // 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); - - XMLRPC_Free(requestText); - - mHandler = LLXMLRPCTransaction::Handler::ptr_t(new Handler( mHttpRequest, this )); - - mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID, - mURI, body.get(), httpOpts, httpHeaders, mHandler); - + // We do not do the parsing in the HTTP coroutine, since it could exhaust + // the coroutine stack in extreme cases. Instead, we flag the data buffer + // as ready, and let mImpl decode it in its process() method, on the main + // coroutine. HB + mImpl->mHasResponse = true; + mImpl->setStatus(LLXMLRPCTransaction::StatusComplete); } +//========================================================================= -LLXMLRPCTransaction::Impl::~Impl() -{ - if (mResponse) - { - XMLRPC_RequestFree(mResponse, 1); - } +LLXMLRPCTransaction::Impl::Impl +( + const std::string& uri, + const std::string& method, + const LLSD& params, + const LLSD& http_params +) + : mHttpRequest() + , mStatus(LLXMLRPCTransaction::StatusNotStarted) + , mURI(uri) + , mHasResponse(false) + , mResponseParsed(false) +{ + LLCore::HttpOptions::ptr_t httpOpts; + LLCore::HttpHeaders::ptr_t httpHeaders; + + if (!mHttpRequest) + { + mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest); + } + + // 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 + httpOpts->setMinBackoff((LLCore::HttpTime)5E6L); + httpOpts->setMaxBackoff((LLCore::HttpTime)20E6L); + + httpOpts->setTimeout(http_params.has("timeout") ? http_params["timeout"].asInteger() : 40L); + if (http_params.has("retries")) + { + httpOpts->setRetries(http_params["retries"].asInteger()); + } + if (http_params.has("DNSCacheTimeout")) + { + httpOpts->setDNSCacheTimeout(http_params["DNSCacheTimeout"].asInteger()); + } + + bool vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert"); + mCertStore = gSavedSettings.getString("CertStore"); + + 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); + + 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); + + ///* Setting the DNS cache timeout to -1 disables it completely. + //This might help with bug #503 */ + //httpOpts->setDNSCacheTimeout(-1); + + std::string request = + "<?xml version=\"1.0\"?><methodCall><methodName>" + method + + "</methodName><params><param>" + params.asXMLRPCValue() + + "</param></params></methodCall>"; + + LLCore::BufferArray::ptr_t body = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); + + body->append(request.c_str(), request.size()); + + mHandler = LLXMLRPCTransaction::Handler::ptr_t(new Handler(mHttpRequest, this)); + + mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID, + mURI, body.get(), httpOpts, httpHeaders, mHandler); +} + +bool LLXMLRPCTransaction::Impl::parseResponse(LLXMLNodePtr root) +{ + // We have already checked in LLXMLNode::parseBuffer() that root contains + // exactly one child. + if (!root->hasName("methodResponse")) + { + LL_WARNS() << "Invalid root element in XML response; request URI: " + << mURI << LL_ENDL; + return false; + } + + LLXMLNodePtr first = root->getFirstChild(); + LLXMLNodePtr second = first->getFirstChild(); + if (first && !first->getNextSibling() && second && + !second->getNextSibling()) + { + 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: " << mURI << LL_ENDL; + return false; + } + } + else if (first->hasName("params") && + second->hasName("param") && !second->getNextSibling()) + { + LLXMLNodePtr third = second->getFirstChild(); + if (third && !third->getNextSibling() && + parseValue(mResponseData, third)) + { + return true; + } + } + } + + LL_WARNS() << "Invalid response format; request URI: " << mURI << LL_ENDL; + return false; +} + +bool LLXMLRPCTransaction::Impl::parseValue(LLSD& target, LLXMLNodePtr src) +{ + return src->fromXMLRPCValue(target); } bool LLXMLRPCTransaction::Impl::process() { - if (!mPostH || !mHttpRequest) - { - LL_WARNS() << "transaction failed." << LL_ENDL; - return true; //failed, quit. - } - - switch (mStatus) - { - case LLXMLRPCTransaction::StatusComplete: - case LLXMLRPCTransaction::StatusCURLError: - case LLXMLRPCTransaction::StatusXMLRPCError: - case LLXMLRPCTransaction::StatusOtherError: - { - return true; - } - - case LLXMLRPCTransaction::StatusNotStarted: - { - setStatus(LLXMLRPCTransaction::StatusStarted); - break; - } - - default: - break; - } - - LLCore::HttpStatus status = mHttpRequest->update(0); - - status = mHttpRequest->getStatus(); - if (!status) - { - return false; - } - - return false; + if (!mPostH || !mHttpRequest) + { + LL_WARNS() << "transaction failed." << LL_ENDL; + return true; //failed, quit. + } + + // Parse the response when we have one and it has not yet been parsed. HB + if (mHasResponse && !mResponseParsed) + { + LLXMLNodePtr root; + bool strip_escaped_strings = LLXMLNode::sStripEscapedStrings; + LLXMLNode::sStripEscapedStrings = false; + if (!LLXMLNode::parseBuffer(mResponseText.data(), mResponseText.size(), + root, nullptr)) + { + LL_WARNS() << "Failed parsing XML in response; request URI: " + << mURI << LL_ENDL; + } + else if (parseResponse(root)) + { + LL_INFOS() << "XMLRPC response parsed successfully; request URI: " + << mURI << LL_ENDL; + } + else + { + LL_WARNS() << "XMLRPC response parsing failed; request URI: " + << mURI << LL_ENDL; + } + LLXMLNode::sStripEscapedStrings = strip_escaped_strings; + mResponseParsed = true; + } + + switch (mStatus) + { + case LLXMLRPCTransaction::StatusComplete: + case LLXMLRPCTransaction::StatusCURLError: + case LLXMLRPCTransaction::StatusXMLRPCError: + case LLXMLRPCTransaction::StatusOtherError: + { + return true; + } + + case LLXMLRPCTransaction::StatusNotStarted: + { + setStatus(LLXMLRPCTransaction::StatusStarted); + break; + } + + default: + break; + } + + LLCore::HttpStatus status = mHttpRequest->update(0); + + status = mHttpRequest->getStatus(); + if (!status) + { + return false; + } + + return false; } void LLXMLRPCTransaction::Impl::setStatus(EStatus status, - const std::string& message, const std::string& uri) -{ - mStatus = status; - mStatusMessage = message; - mStatusURI = uri; - - if (mStatusMessage.empty()) - { - switch (mStatus) - { - case StatusNotStarted: - mStatusMessage = "(not started)"; - break; - - case StatusStarted: - mStatusMessage = "(waiting for server response)"; - break; - - case StatusDownloading: - mStatusMessage = "(reading server response)"; - break; - - case StatusComplete: - mStatusMessage = "(done)"; - break; - default: - // Usually this means that there's a problem with the login server, - // not with the client. Direct user to status page. - mStatusMessage = LLTrans::getString("server_is_down"); - mStatusURI = "http://status.secondlifegrid.net/"; - } - } + const std::string& message, const std::string& uri) +{ + mStatus = status; + mStatusMessage = message; + mStatusURI = uri; + + if (mStatusMessage.empty()) + { + switch (mStatus) + { + case StatusNotStarted: + mStatusMessage = "(not started)"; + break; + + case StatusStarted: + mStatusMessage = "(waiting for server response)"; + break; + + case StatusDownloading: + mStatusMessage = "(reading server response)"; + break; + + case StatusComplete: + mStatusMessage = "(done)"; + break; + default: + // Usually this means that there's a problem with the login server, + // not with the client. Direct user to status page. + mStatusMessage = LLTrans::getString("server_is_down"); + mStatusURI = "http://status.secondlifegrid.net/"; + } + } } void LLXMLRPCTransaction::Impl::setHttpStatus(const LLCore::HttpStatus &status) { - CURLcode code = static_cast<CURLcode>(status.toULong()); - std::string message; - std::string uri = "http://support.secondlife.com"; - LLURI failuri(mURI); - LLStringUtil::format_map_t args; - - switch (code) - { - case CURLE_COULDNT_RESOLVE_HOST: - args["[HOSTNAME]"] = failuri.hostName(); - message = LLTrans::getString("couldnt_resolve_host", args); - break; + CURLcode code = static_cast<CURLcode>(status.toULong()); + std::string message; + std::string uri = "http://support.secondlife.com"; + LLURI failuri(mURI); + LLStringUtil::format_map_t args; + + switch (code) + { + case CURLE_COULDNT_RESOLVE_HOST: + args["[HOSTNAME]"] = failuri.hostName(); + message = LLTrans::getString("couldnt_resolve_host", args); + break; #if CURLE_SSL_PEER_CERTIFICATE != CURLE_SSL_CACERT - case CURLE_SSL_PEER_CERTIFICATE: - message = LLTrans::getString("ssl_peer_certificate"); - break; + case CURLE_SSL_PEER_CERTIFICATE: + message = LLTrans::getString("ssl_peer_certificate"); + break; #endif - case CURLE_SSL_CACERT: - case CURLE_SSL_CONNECT_ERROR: - message = LLTrans::getString("ssl_connect_error"); - break; + case CURLE_SSL_CACERT: + case CURLE_SSL_CONNECT_ERROR: + message = LLTrans::getString("ssl_connect_error"); + break; - default: - break; - } + default: + break; + } - mCurlCode = code; - setStatus(StatusCURLError, message, uri); + mCurlCode = code; + setStatus(StatusCURLError, message, uri); } - -LLXMLRPCTransaction::LLXMLRPCTransaction( - const std::string& uri, XMLRPC_REQUEST request, bool useGzip, const LLSD& httpParams) -: impl(* new Impl(uri, request, useGzip, httpParams)) -{ } - - -LLXMLRPCTransaction::LLXMLRPCTransaction( - const std::string& uri, - const std::string& method, LLXMLRPCValue params, bool useGzip) -: impl(* new Impl(uri, method, params, useGzip)) -{ } +LLXMLRPCTransaction::LLXMLRPCTransaction +( + const std::string& uri, + const std::string& method, + const LLSD& params, + const LLSD& http_params +) +: impl(*new Impl(uri, method, params, http_params)) +{ +} LLXMLRPCTransaction::~LLXMLRPCTransaction() { - delete &impl; + delete &impl; } bool LLXMLRPCTransaction::process() { - return impl.process(); + return impl.process(); } LLXMLRPCTransaction::EStatus LLXMLRPCTransaction::status(int* curlCode) { - if (curlCode) - { - *curlCode = - (impl.mStatus == StatusCURLError) - ? impl.mCurlCode - : CURLE_OK; - } - - return impl.mStatus; + if (curlCode) + { + *curlCode = + (impl.mStatus == StatusCURLError) + ? impl.mCurlCode + : CURLE_OK; + } + + return impl.mStatus; } std::string LLXMLRPCTransaction::statusMessage() { - return impl.mStatusMessage; + return impl.mStatusMessage; } LLSD LLXMLRPCTransaction::getErrorCertData() { - return impl.mErrorCertData; + return impl.mErrorCertData; } std::string LLXMLRPCTransaction::statusURI() { - return impl.mStatusURI; -} - -XMLRPC_REQUEST LLXMLRPCTransaction::response() -{ - return impl.mResponse; + return impl.mStatusURI; } -LLXMLRPCValue LLXMLRPCTransaction::responseValue() +const LLSD& LLXMLRPCTransaction::response() { - return LLXMLRPCValue(XMLRPC_RequestGetData(impl.mResponse)); + return impl.mResponseData; } F64 LLXMLRPCTransaction::transferRate() { - if (impl.mStatus != StatusComplete) - { - return 0.0L; - } - - double rate_bits_per_sec = impl.mTransferStats->mSpeedDownload * 8.0; - - LL_INFOS("AppInit") << "Buffer size: " << impl.mResponseText.size() << " B" << LL_ENDL; - LL_DEBUGS("AppInit") << "Transfer size: " << impl.mTransferStats->mSizeDownload << " B" << LL_ENDL; - LL_DEBUGS("AppInit") << "Transfer time: " << impl.mTransferStats->mTotalTime << " s" << LL_ENDL; - LL_INFOS("AppInit") << "Transfer rate: " << rate_bits_per_sec / 1000.0 << " Kb/s" << LL_ENDL; - - return rate_bits_per_sec; + if (impl.mStatus != StatusComplete) + { + return 0.0L; + } + + double rate_bits_per_sec = impl.mTransferStats->mSpeedDownload * 8.0; + + LL_INFOS("AppInit") << "Buffer size: " << impl.mResponseText.size() << " B" << LL_ENDL; + LL_DEBUGS("AppInit") << "Transfer size: " << impl.mTransferStats->mSizeDownload << " B" << LL_ENDL; + LL_DEBUGS("AppInit") << "Transfer time: " << impl.mTransferStats->mTotalTime << " s" << LL_ENDL; + LL_INFOS("AppInit") << "Transfer rate: " << rate_bits_per_sec / 1000.0 << " Kb/s" << LL_ENDL; + + return rate_bits_per_sec; } |