diff options
-rw-r--r-- | indra/llmessage/llproxy.cpp | 149 | ||||
-rw-r--r-- | indra/llmessage/llproxy.h | 99 | ||||
-rw-r--r-- | indra/newview/llstartup.cpp | 129 | ||||
-rw-r--r-- | indra/newview/llstartup.h | 2 | ||||
-rw-r--r-- | indra/newview/llxmlrpctransaction.cpp | 4 |
5 files changed, 285 insertions, 98 deletions
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp index bdffa34fbc..3f4a6accbf 100644 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -34,8 +34,6 @@ #include "llapr.h" #include "llcurl.h" #include "llhost.h" -#include "message.h" -#include "net.h" // Static class variable instances @@ -44,10 +42,10 @@ // member is also static bool LLProxy::sUDPProxyEnabled = false; -// Some helpful TCP functions +// Some helpful TCP static functions. +static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, LLHost host); // Open a TCP channel to a given host static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP channel -static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake LLProxy::LLProxy(): mHTTPProxyEnabled(false), @@ -70,9 +68,15 @@ LLProxy::~LLProxy() mHTTPProxyEnabled = false; } -// Perform a SOCKS 5 authentication and UDP association to the proxy -// specified by proxy, and associate UDP port message_port -S32 LLProxy::proxyHandshake(LLHost proxy, U32 message_port) +/** + * @brief Open the SOCKS 5 TCP control channel. + * + * Perform a SOCKS 5 authentication and UDP association to the proxy server. + * + * @param proxy The SOCKS 5 server to connect to. + * @return SOCKS_OK if successful, otherwise a socks error code from llproxy.h. + */ +S32 LLProxy::proxyHandshake(LLHost proxy) { S32 result; @@ -169,6 +173,16 @@ S32 LLProxy::proxyHandshake(LLHost proxy, U32 message_port) return SOCKS_OK; } +/** + * @brief Initiates a SOCKS 5 proxy session. + * + * Performs basic checks on host to verify that it is a valid address. Opens the control channel + * and then negotiates the proxy connection with the server. + * + * + * @param host Socks server to connect to. + * @return SOCKS_OK if successful, otherwise a SOCKS error code defined in llproxy.h. + */ S32 LLProxy::startSOCKSProxy(LLHost host) { S32 status = SOCKS_OK; @@ -198,7 +212,7 @@ S32 LLProxy::startSOCKSProxy(LLHost host) if (status == SOCKS_OK) { - status = proxyHandshake(mTCPProxy, (U32)gMessageSystem->mPort); + status = proxyHandshake(mTCPProxy); } if (status == SOCKS_OK) { @@ -211,6 +225,13 @@ S32 LLProxy::startSOCKSProxy(LLHost host) return status; } +/** + * @brief Stop using the SOCKS 5 proxy. + * + * This will stop sending UDP packets through the SOCKS 5 proxy + * and will also stop the HTTP proxy if it is configured to use SOCKS. + * The proxy control channel will also be disconnected. + */ void LLProxy::stopSOCKSProxy() { sUDPProxyEnabled = false; @@ -230,6 +251,9 @@ void LLProxy::stopSOCKSProxy() } } +/** + * @brief Set the proxy's SOCKS authentication method to none. + */ void LLProxy::setAuthNone() { LLMutexLock lock(&mProxyMutex); @@ -237,6 +261,18 @@ void LLProxy::setAuthNone() mAuthMethodSelected = METHOD_NOAUTH; } +/** + * @brief Set the proxy's SOCKS authentication method to password. + * + * Check whether the lengths of the supplied username + * and password conform to the lengths allowed by the + * SOCKS protocol. + * + * @param username The SOCKS username to send. + * @param password The SOCKS password to send. + * @return Return true if applying the settings was successful. No changes are made if false. + * + */ bool LLProxy::setAuthPassword(const std::string &username, const std::string &password) { if (username.length() > SOCKSMAXUSERNAMELEN || password.length() > SOCKSMAXPASSWORDLEN || @@ -255,6 +291,15 @@ bool LLProxy::setAuthPassword(const std::string &username, const std::string &pa return true; } +/** + * @brief Enable the HTTP proxy for either SOCKS or HTTP. + * + * Check the supplied host to see if it is a valid IP and port. + * + * @param httpHost Proxy server to connect to. + * @param type Is the host a SOCKS or HTTP proxy. + * @return Return true if applying the setting was successful. No changes are made if false. + */ bool LLProxy::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type) { if (!httpHost.isOk()) @@ -273,15 +318,31 @@ bool LLProxy::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type) return true; } +/** + * @brief Enable the HTTP proxy without changing the proxy settings. + * + * This should not be called unless the proxy has already been set up. + * + * @return Return true only if the current settings are valid and the proxy was enabled. + */ bool LLProxy::enableHTTPProxy() { + bool ok; + LLMutexLock lock(&mProxyMutex); - mHTTPProxyEnabled = true; + ok = (mHTTPProxy.isOk()); + if (ok) + { + mHTTPProxyEnabled = true; + } - return true; + return ok; } +/** + * @brief Disable the HTTP proxy. + */ void LLProxy::disableHTTPProxy() { LLMutexLock lock(&mProxyMutex); @@ -289,39 +350,59 @@ void LLProxy::disableHTTPProxy() mHTTPProxyEnabled = false; } -// Get the HTTP proxy address and port +/** + * @brief Get the HTTP proxy address and port + */ +// LLHost LLProxy::getHTTPProxy() const { LLMutexLock lock(&mProxyMutex); return mHTTPProxy; } -// Get the currently selected HTTP proxy type +/** + * @brief Get the currently selected HTTP proxy type + */ LLHttpProxyType LLProxy::getHTTPProxyType() const { LLMutexLock lock(&mProxyMutex); return mProxyType; } +/** + * @brief Get the SOCKS 5 password. + */ std::string LLProxy::getSocksPwd() const { LLMutexLock lock(&mProxyMutex); return mSocksPassword; } +/** + * @brief Get the SOCKS 5 username. + */ std::string LLProxy::getSocksUser() const { LLMutexLock lock(&mProxyMutex); return mSocksUsername; } -// get the currently selected auth method +/** + * @brief Get the currently selected SOCKS 5 authentication method. + * + * @return Returns either none or password. + */ LLSocks5AuthType LLProxy::getSelectedAuthMethod() const { LLMutexLock lock(&mProxyMutex); return mAuthMethodSelected; } +/** + * @brief Stop the LLProxy and make certain that any APR pools and classes are deleted before terminating APR. + * + * Deletes the LLProxy singleton, destroying the APR pool used by the control channel as well as . + */ //static void LLProxy::cleanupClass() { @@ -329,7 +410,6 @@ void LLProxy::cleanupClass() deleteSingleton(); } -// Apply proxy settings to CuRL request if either type of HTTP proxy is enabled. void LLProxy::applyProxySettings(LLCurlEasyRequest* handle) { applyProxySettings(handle->getEasy()); @@ -340,6 +420,17 @@ void LLProxy::applyProxySettings(LLCurl::Easy* handle) applyProxySettings(handle->getCurlHandle()); } +/** + * @brief Apply proxy settings to a CuRL request if an HTTP proxy is enabled. + * + * This method has been designed to be safe to call from + * any thread in the viewer. This allows requests in the + * texture fetch thread to be aware of the proxy settings. + * When the HTTP proxy is enabled, the proxy mutex will + * be locked every time this method is called. + * + * @param handle A pointer to a valid CURL request, before it has been performed. + */ void LLProxy::applyProxySettings(CURL* handle) { // Do a faster unlocked check to see if we are supposed to proxy. @@ -370,6 +461,19 @@ void LLProxy::applyProxySettings(CURL* handle) } } +/** + * @brief Send one TCP packet and receive one in return. + * + * This operation is done synchronously with a 1000ms timeout. Therefore, it should not be used when a blocking + * operation would impact the operation of the viewer. + * + * @param handle_ptr Pointer to a connected LLSocket of type STREAM_TCP. + * @param dataout Data to send. + * @param outlen Length of dataout. + * @param datain Buffer for received data. Undefined if return value is not APR_SUCCESS. + * @param maxinlen Maximum possible length of received data. Short reads are allowed. + * @return Indicates APR status code of exchange. APR_SUCCESS if exchange was successful, -1 if invalid data length was received. + */ static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen) { apr_socket_t* apr_socket = handle->getSocket(); @@ -414,9 +518,18 @@ static S32 tcp_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outl return rv; } +/** + * @brief Open a LLSocket and do a blocking connect to the chosen host. + * + * Checks for a successful connection, and makes sure the connection is closed if it fails. + * + * @param pool APR pool to pass into the LLSocket. + * @param host The host to open the connection to. + * @return The created socket. Will evaluate as NULL if the connection is unsuccessful. + */ static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, LLHost host) { - LLSocket::ptr_t socket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); + LLSocket::ptr_t socket = LLSocket::create(pool, LLSocket::STREAM_TCP); bool connected = socket->blockingConnect(host); if (!connected) { @@ -426,7 +539,11 @@ static LLSocket::ptr_t tcp_open_channel(apr_pool_t* pool, LLHost host) return socket; } -// Pass a pointer-to-pointer to avoid changing use_count(). +/** + * @brief Close the socket. + * + * @param handle_ptr A pointer-to-pointer to avoid increasing the use count. + */ static void tcp_close_channel(LLSocket::ptr_t* handle_ptr) { LL_DEBUGS("Proxy") << "Resetting proxy LLSocket handle, use_count == " << handle_ptr->use_count() << LL_ENDL; diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index 534455a6dd..29e7e28567 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -35,7 +35,7 @@ #include "llthread.h" #include <string> -// Error codes returned from the StartProxy method +// SOCKS error codes returned from the StartProxy method #define SOCKS_OK 0 #define SOCKS_CONNECT_ERROR (-1) @@ -166,11 +166,86 @@ enum LLSocks5AuthType METHOD_PASSWORD = 0x02 // Client supports username/password }; +/** + * @brief Manage SOCKS 5 UDP proxy and HTTP proxy. + * + * This class is responsible for managing two interconnected tasks, + * connecting to a SOCKS 5 proxy for use by LLPacketRing to send UDP + * packets and managing proxy settings for HTTP requests. + * + * <h1>Threading:</h1> + * Because HTTP requests can be generated in threads outside the + * main thread, it is necessary for some of the information stored + * by this class to be available to other threads. The members that + * need to be read across threads are in a labeled section below. + * To protect those members, a mutex, mProxyMutex should be locked + * before reading or writing those members. Methods that can lock + * mProxyMutex are in a labeled section below. Those methods should + * not be called while the mutex is already locked. + * + * There is also a LLAtomic type flag (mHTTPProxyEnabled) that is used + * to track whether the HTTP proxy is currently enabled. This allows + * for faster unlocked checks to see if the proxy is enabled. This + * allows us to cut down on the performance hit when the proxy is + * disabled compared to before this class was introduced. + * + * <h1>UDP Proxying:</h1> + * UDP datagrams are proxied via a SOCKS 5 proxy with the UDP associate + * command. To initiate the proxy, a TCP socket connection is opened + * to the SOCKS 5 host, and after a handshake exchange, the server + * returns a port and address to send the UDP traffic that is to be + * proxied to. The LLProxy class tracks this address and port after the + * exchange and provides it to LLPacketRing when required to. All UDP + * proxy management occurs in the main thread. + * + * <h1>HTTP Proxying:</h1> + * This class allows all viewer HTTP packets to be sent through a proxy. + * The user can select whether to send HTTP packets through a standard + * "web" HTTP proxy, through a SOCKS 5 proxy, or to not proxy HTTP + * communication. This class does not manage the integrated web browser + * proxy, which is handled in llviewermedia.cpp. + * + * The implementation of HTTP proxying is handled by libcurl. LLProxy + * is responsible for managing the HTTP proxy options and provides a + * thread-safe method to apply those options to a curl request + * (LLProxy::applyProxySettings()). This method is overloaded + * to accommodate the various abstraction libcurl layers that exist + * throughout the viewer (LLCurlEasyRequest, LLCurl::Easy, and CURL). + * + * If you are working with LLCurl or LLCurlEasyRequest objects, + * the configured proxy settings will be applied in the constructors + * of those request handles. If you are working with CURL objects + * directly, you will need to pass the handle of the request to + * applyProxySettings() before issuing the request. + * + * To ensure thread safety, all LLProxy members that relate to the HTTP + * proxy require the LLProxyMutex to be locked before accessing. + */ class LLProxy: public LLSingleton<LLProxy> { LOG_CLASS(LLProxy); public: + // METHODS THAT DO NOT LOCK mProxyMutex! + LLProxy(); + + // static check for enabled status for UDP packets + static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; } + + // check for enabled status for HTTP packets + // mHTTPProxyEnabled is atomic, so no locking is required for thread safety. + bool isHTTPProxyEnabled() const { return mHTTPProxyEnabled; } + + // Get the UDP proxy address and port + LLHost getUDPProxy() const { return mUDPProxy; } + + // Get the SOCKS 5 TCP control channel address and port + LLHost getTCPProxy() const { return mTCPProxy; } + + // END OF NON-LOCKING METHODS + + // METHODS THAT DO LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED! + ~LLProxy(); // Start a connection to the SOCKS 5 proxy @@ -188,16 +263,9 @@ public: // Set up to use No Auth when connecting to the SOCKS proxy void setAuthNone(); - // get the currently selected auth method + // Get the currently selected auth method. LLSocks5AuthType getSelectedAuthMethod() const; - // static check for enabled status for UDP packets - static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; } - - // check for enabled status for HTTP packets - // mHTTPProxyEnabled is atomic, so no locking is required for thread safety. - bool isHTTPProxyEnabled() const { return mHTTPProxyEnabled; } - // Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy // as specified in type bool enableHTTPProxy(LLHost httpHost, LLHttpProxyType type); @@ -211,12 +279,6 @@ public: void applyProxySettings(LLCurl::Easy* handle); void applyProxySettings(LLCurlEasyRequest* handle); - // Get the UDP proxy address and port - LLHost getUDPProxy() const { return mUDPProxy; } - - // Get the SOCKS 5 TCP control channel address and port - LLHost getTCPProxy() const { return mTCPProxy; } - // Get the HTTP proxy address and port LLHost getHTTPProxy() const; @@ -226,9 +288,10 @@ public: std::string getSocksPwd() const; std::string getSocksUser() const; + // END OF LOCKING METHODS private: // Open a communication channel to the SOCKS 5 proxy proxy, at port messagePort - S32 proxyHandshake(LLHost proxy, U32 messagePort); + S32 proxyHandshake(LLHost proxy); private: // Is the HTTP proxy enabled? @@ -255,6 +318,8 @@ private: // APR pool for the socket apr_pool_t* mPool; + // END OF UNSHARED MEMBERS + // MEMBERS WRITTEN IN MAIN THREAD AND READ IN ANY THREAD. ONLY READ OR WRITE AFTER LOCKING mProxyMutex! // HTTP proxy address and port @@ -270,6 +335,8 @@ private: std::string mSocksUsername; // SOCKS 5 password std::string mSocksPassword; + + // END OF SHARED MEMBERS }; #endif diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index c5c143963b..c34f84e2d9 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -387,6 +387,14 @@ bool idle_startup() LLNotificationsUtil::add(gViewerWindow->getInitAlert()); } + //------------------------------------------------- + // Init the SOCKS 5 proxy if the user has configured + // one. We need to do this early in case the user + // is using SOCKS for HTTP so we get the login + // screen and HTTP tables via SOCKS. + //------------------------------------------------- + LLStartUp::startLLProxy(); + gSavedSettings.setS32("LastFeatureVersion", LLFeatureManager::getInstance()->getVersion()); gSavedSettings.setS32("LastGPUClass", LLFeatureManager::getInstance()->getGPUClass()); @@ -594,23 +602,6 @@ bool idle_startup() LL_INFOS("AppInit") << "Message System Initialized." << LL_ENDL; //------------------------------------------------- - // Init the SOCKS 5 proxy and open the control TCP - // connection if the user has configured a Proxy - // We need to do this early in case the user is using - // socks for HTTP so we get the login screen via SOCKS - // We don't do anything if proxy setup was - // unsuccessful, since the user can configure their - // proxy settings before starting to log in. - //------------------------------------------------- - - LLStartUp::handleSocksProxy(); - // If we started a proxy, try to grab the table files again. - if (LLProxy::getInstance()->isHTTPProxyEnabled()) - { - LLFeatureManager::getInstance()->fetchHTTPTables(); - } - - //------------------------------------------------- // Init audio, which may be needed for prefs dialog // or audio cues in connection UI. //------------------------------------------------- @@ -828,10 +819,10 @@ bool idle_startup() // Post login screen, we should see if any settings have changed that may // require us to either start/stop or change the socks proxy. As various communications // past this point may require the proxy to be up. - if (!LLStartUp::handleSocksProxy()) + if (!LLStartUp::startLLProxy()) { // Proxy start up failed, we should now bail the state machine - // handleSocksProxy() will have reported an error to the user + // startLLProxy() will have reported an error to the user // already, so we just go back to the login screen. The user // could then change the preferences to fix the issue. @@ -2770,53 +2761,22 @@ void LLStartUp::setStartSLURL(const LLSLURL& slurl) } } -bool LLStartUp::handleSocksProxy() +/** + * Read all proxy configuration settings and set up both the HTTP proxy and + * SOCKS proxy as needed. + * + * Any errors that are encountered will result in showing the user a notification. + * When an error is encountered, + * + * @return Returns true if setup was successful, false if an error was encountered. + */ +bool LLStartUp::startLLProxy() { bool proxy_ok = true; std::string httpProxyType = gSavedSettings.getString("Socks5HttpProxyType"); - // Determine the HTTP proxy type (if any) - if ((httpProxyType.compare("Web") == 0) && gSavedSettings.getBOOL("BrowserProxyEnabled")) - { - LLHost http_host; - http_host.setHostByName(gSavedSettings.getString("BrowserProxyAddress")); - http_host.setPort(gSavedSettings.getS32("BrowserProxyPort")); - if (!LLProxy::getInstance()->enableHTTPProxy(http_host, LLPROXY_HTTP)) - { - LLSD subs; - subs["HOST"] = http_host.getIPString(); - subs["PORT"] = (S32)http_host.getPort(); - LLNotificationsUtil::add("PROXY_INVALID_HTTP_HOST", subs); - proxy_ok = false; - } - } - else if ((httpProxyType.compare("Socks") == 0) && gSavedSettings.getBOOL("Socks5ProxyEnabled")) - { - LLHost socks_host; - socks_host.setHostByName(gSavedSettings.getString("Socks5ProxyHost")); - socks_host.setPort(gSavedSettings.getU32("Socks5ProxyPort")); - if (!LLProxy::getInstance()->enableHTTPProxy(socks_host, LLPROXY_SOCKS)) - { - LLSD subs; - subs["HOST"] = socks_host.getIPString(); - subs["PORT"] = (S32)socks_host.getPort(); - LLNotificationsUtil::add("PROXY_INVALID_SOCKS_HOST", subs); - proxy_ok = false; - } - } - else if (httpProxyType.compare("None") == 0) - { - LLProxy::getInstance()->disableHTTPProxy(); - } - else - { - LL_WARNS("Proxy") << "Invalid HTTP proxy configuration."<< LL_ENDL; - gSavedSettings.setString("Socks5HttpProxyType", "None"); - LLProxy::getInstance()->disableHTTPProxy(); - } - // Set up SOCKS proxy (if needed) - if (gSavedSettings.getBOOL("Socks5ProxyEnabled") && proxy_ok) + if (gSavedSettings.getBOOL("Socks5ProxyEnabled")) { // Determine and update LLProxy with the saved authentication system std::string auth_type = gSavedSettings.getString("Socks5AuthType"); @@ -2915,6 +2875,53 @@ bool LLStartUp::handleSocksProxy() LLProxy::getInstance()->stopSOCKSProxy(); // ensure no UDP proxy is running and it's all cleaned up } + if (proxy_ok) + { + // Determine the HTTP proxy type (if any) + if ((httpProxyType.compare("Web") == 0) && gSavedSettings.getBOOL("BrowserProxyEnabled")) + { + LLHost http_host; + http_host.setHostByName(gSavedSettings.getString("BrowserProxyAddress")); + http_host.setPort(gSavedSettings.getS32("BrowserProxyPort")); + if (!LLProxy::getInstance()->enableHTTPProxy(http_host, LLPROXY_HTTP)) + { + LLSD subs; + subs["HOST"] = http_host.getIPString(); + subs["PORT"] = (S32)http_host.getPort(); + LLNotificationsUtil::add("PROXY_INVALID_HTTP_HOST", subs); + proxy_ok = false; + } + } + else if ((httpProxyType.compare("Socks") == 0) && gSavedSettings.getBOOL("Socks5ProxyEnabled")) + { + LLHost socks_host; + socks_host.setHostByName(gSavedSettings.getString("Socks5ProxyHost")); + socks_host.setPort(gSavedSettings.getU32("Socks5ProxyPort")); + if (!LLProxy::getInstance()->enableHTTPProxy(socks_host, LLPROXY_SOCKS)) + { + LLSD subs; + subs["HOST"] = socks_host.getIPString(); + subs["PORT"] = (S32)socks_host.getPort(); + LLNotificationsUtil::add("PROXY_INVALID_SOCKS_HOST", subs); + proxy_ok = false; + } + } + else if (httpProxyType.compare("None") == 0) + { + LLProxy::getInstance()->disableHTTPProxy(); + } + else + { + LL_WARNS("Proxy") << "Invalid HTTP proxy configuration."<< LL_ENDL; + + // Set the missing or wrong configuration back to something valid. + gSavedSettings.setString("Socks5HttpProxyType", "None"); + LLProxy::getInstance()->disableHTTPProxy(); + + // Leave proxy_ok alone, since this isn't necessarily fatal. + } + } + return proxy_ok; } diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 7292e4d68c..99a644eb9c 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -113,7 +113,7 @@ public: static void setStartSLURL(const LLSLURL& slurl); static LLSLURL& getStartSLURL() { return sStartSLURL; } - static bool handleSocksProxy(); // Initialize the SOCKS 5 proxy + static bool startLLProxy(); // Initialize the SOCKS 5 proxy private: static LLSLURL sStartSLURL; diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 7683d4feb5..f483ba5af8 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -41,8 +41,6 @@ #include "llappviewer.h" #include "lltrans.h" -#include "llproxy.h" - // Static instance of LLXMLRPCListener declared here so that every time we // bring in this code, we instantiate a listener. If we put the static // instance of LLXMLRPCListener into llxmlrpclistener.cpp, the linker would @@ -308,8 +306,6 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip) mCurlRequest = new LLCurlEasyRequest(); } mErrorCert = NULL; - - LLProxy::getInstance()->applyProxySettings(mCurlRequest); // mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // useful for debugging mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1); |