MAINT-5507: Remove llcurl, move constant values and untilities to llcorehttp lib
parent
5f7985f6a7
commit
907efc9cc9
|
|
@ -26,6 +26,7 @@ set(llcorehttp_SOURCE_FILES
|
||||||
bufferarray.cpp
|
bufferarray.cpp
|
||||||
bufferstream.cpp
|
bufferstream.cpp
|
||||||
httpcommon.cpp
|
httpcommon.cpp
|
||||||
|
llhttpconstants.cpp
|
||||||
httpheaders.cpp
|
httpheaders.cpp
|
||||||
httpoptions.cpp
|
httpoptions.cpp
|
||||||
httprequest.cpp
|
httprequest.cpp
|
||||||
|
|
@ -51,6 +52,7 @@ set(llcorehttp_HEADER_FILES
|
||||||
bufferarray.h
|
bufferarray.h
|
||||||
bufferstream.h
|
bufferstream.h
|
||||||
httpcommon.h
|
httpcommon.h
|
||||||
|
llhttpconstants.h
|
||||||
httphandler.h
|
httphandler.h
|
||||||
httpheaders.h
|
httpheaders.h
|
||||||
httpoptions.h
|
httpoptions.h
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,24 @@
|
||||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
* $/LicenseInfo$
|
* $/LicenseInfo$
|
||||||
*/
|
*/
|
||||||
|
#if LL_WINDOWS
|
||||||
|
#define SAFE_SSL 1
|
||||||
|
#elif LL_DARWIN
|
||||||
|
#define SAFE_SSL 1
|
||||||
|
#else
|
||||||
|
#define SAFE_SSL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "linden_common.h" // Modifies curl/curl.h interfaces
|
||||||
#include "httpcommon.h"
|
#include "httpcommon.h"
|
||||||
|
#include "llmutex.h"
|
||||||
|
#include "llthread.h"
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#if SAFE_SSL
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace LLCore
|
namespace LLCore
|
||||||
|
|
@ -263,5 +275,151 @@ bool HttpStatus::isRetryable() const
|
||||||
*this == inv_cont_range); // Short data read disagrees with content-range
|
*this == inv_cont_range); // Short data read disagrees with content-range
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace LLCore
|
namespace LLHttp
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
typedef boost::shared_ptr<LLMutex> LLMutex_ptr;
|
||||||
|
std::vector<LLMutex_ptr> sSSLMutex;
|
||||||
|
|
||||||
|
CURL *getCurlTemplateHandle()
|
||||||
|
{
|
||||||
|
static CURL *curlpTemplateHandle = NULL;
|
||||||
|
|
||||||
|
if (curlpTemplateHandle == NULL)
|
||||||
|
{ // Late creation of the template curl handle
|
||||||
|
curlpTemplateHandle = curl_easy_init();
|
||||||
|
if (curlpTemplateHandle == NULL)
|
||||||
|
{
|
||||||
|
LL_WARNS() << "curl error calling curl_easy_init()" << LL_ENDL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CURLcode result = curl_easy_setopt(curlpTemplateHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||||
|
check_curl_code(result, CURLOPT_IPRESOLVE);
|
||||||
|
result = curl_easy_setopt(curlpTemplateHandle, CURLOPT_NOSIGNAL, 1);
|
||||||
|
check_curl_code(result, CURLOPT_NOSIGNAL);
|
||||||
|
result = curl_easy_setopt(curlpTemplateHandle, CURLOPT_NOPROGRESS, 1);
|
||||||
|
check_curl_code(result, CURLOPT_NOPROGRESS);
|
||||||
|
result = curl_easy_setopt(curlpTemplateHandle, CURLOPT_ENCODING, "");
|
||||||
|
check_curl_code(result, CURLOPT_ENCODING);
|
||||||
|
result = curl_easy_setopt(curlpTemplateHandle, CURLOPT_AUTOREFERER, 1);
|
||||||
|
check_curl_code(result, CURLOPT_AUTOREFERER);
|
||||||
|
result = curl_easy_setopt(curlpTemplateHandle, CURLOPT_FOLLOWLOCATION, 1);
|
||||||
|
check_curl_code(result, CURLOPT_FOLLOWLOCATION);
|
||||||
|
result = curl_easy_setopt(curlpTemplateHandle, CURLOPT_SSL_VERIFYPEER, 1);
|
||||||
|
check_curl_code(result, CURLOPT_SSL_VERIFYPEER);
|
||||||
|
result = curl_easy_setopt(curlpTemplateHandle, CURLOPT_SSL_VERIFYHOST, 0);
|
||||||
|
check_curl_code(result, CURLOPT_SSL_VERIFYHOST);
|
||||||
|
|
||||||
|
// The Linksys WRT54G V5 router has an issue with frequent
|
||||||
|
// DNS lookups from LAN machines. If they happen too often,
|
||||||
|
// like for every HTTP request, the router gets annoyed after
|
||||||
|
// about 700 or so requests and starts issuing TCP RSTs to
|
||||||
|
// new connections. Reuse the DNS lookups for even a few
|
||||||
|
// seconds and no RSTs.
|
||||||
|
result = curl_easy_setopt(curlpTemplateHandle, CURLOPT_DNS_CACHE_TIMEOUT, 15);
|
||||||
|
check_curl_code(result, CURLOPT_DNS_CACHE_TIMEOUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return curlpTemplateHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLMutex *getCurlMutex()
|
||||||
|
{
|
||||||
|
static LLMutex* sHandleMutexp = NULL;
|
||||||
|
|
||||||
|
if (!sHandleMutexp)
|
||||||
|
{
|
||||||
|
sHandleMutexp = new LLMutex(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sHandleMutexp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocateEasyCurl(CURL *curlp)
|
||||||
|
{
|
||||||
|
LLMutexLock lock(getCurlMutex());
|
||||||
|
|
||||||
|
curl_easy_cleanup(curlp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if SAFE_SSL
|
||||||
|
//static
|
||||||
|
void ssl_locking_callback(int mode, int type, const char *file, int line)
|
||||||
|
{
|
||||||
|
if (mode & CRYPTO_LOCK)
|
||||||
|
{
|
||||||
|
sSSLMutex[type]->lock();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sSSLMutex[type]->unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
unsigned long ssl_thread_id(void)
|
||||||
|
{
|
||||||
|
return LLThread::currentID();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void initialize()
|
||||||
|
{
|
||||||
|
// Do not change this "unless you are familiar with and mean to control
|
||||||
|
// internal operations of libcurl"
|
||||||
|
// - http://curl.haxx.se/libcurl/c/curl_global_init.html
|
||||||
|
CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
|
||||||
|
|
||||||
|
check_curl_code(code, CURL_GLOBAL_ALL);
|
||||||
|
|
||||||
|
#if SAFE_SSL
|
||||||
|
S32 mutex_count = CRYPTO_num_locks();
|
||||||
|
for (S32 i = 0; i < mutex_count; i++)
|
||||||
|
{
|
||||||
|
sSSLMutex.push_back(LLMutex_ptr(new LLMutex(NULL)));
|
||||||
|
}
|
||||||
|
CRYPTO_set_id_callback(&ssl_thread_id);
|
||||||
|
CRYPTO_set_locking_callback(&ssl_locking_callback);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CURL_ptr createEasyHandle()
|
||||||
|
{
|
||||||
|
LLMutexLock lock(getCurlMutex());
|
||||||
|
|
||||||
|
CURL* handle = curl_easy_duphandle(getCurlTemplateHandle());
|
||||||
|
|
||||||
|
return CURL_ptr(handle, &deallocateEasyCurl);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getCURLVersion()
|
||||||
|
{
|
||||||
|
return std::string(curl_version());
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_curl_code(CURLcode code, int curl_setopt_option)
|
||||||
|
{
|
||||||
|
if (CURLE_OK != code)
|
||||||
|
{
|
||||||
|
// Comment from old llcurl code which may no longer apply:
|
||||||
|
//
|
||||||
|
// linux appears to throw a curl error once per session for a bad initialization
|
||||||
|
// at a pretty random time (when enabling cookies).
|
||||||
|
LL_WARNS() << "libcurl error detected: " << curl_easy_strerror(code)
|
||||||
|
<< ", curl_easy_setopt option: " << curl_setopt_option
|
||||||
|
<< LL_ENDL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} // end namespace LLCore
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,7 @@
|
||||||
#include "boost/weak_ptr.hpp"
|
#include "boost/weak_ptr.hpp"
|
||||||
#include "boost/function.hpp"
|
#include "boost/function.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
namespace LLCore
|
namespace LLCore
|
||||||
{
|
{
|
||||||
|
|
@ -490,6 +491,19 @@ private:
|
||||||
|
|
||||||
}; // end struct HttpStatus
|
}; // end struct HttpStatus
|
||||||
|
|
||||||
|
/// A namespace for several free methods and low level utilities.
|
||||||
|
namespace LLHttp
|
||||||
|
{
|
||||||
|
typedef boost::shared_ptr<CURL> CURL_ptr;
|
||||||
|
|
||||||
|
void initialize();
|
||||||
|
|
||||||
|
CURL_ptr createEasyHandle();
|
||||||
|
std::string getCURLVersion();
|
||||||
|
|
||||||
|
void check_curl_code(CURLcode code, int curl_setopt_option);
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace LLCore
|
} // end namespace LLCore
|
||||||
|
|
||||||
#endif // _LLCORE_HTTP_COMMON_H_
|
#endif // _LLCORE_HTTP_COMMON_H_
|
||||||
|
|
|
||||||
|
|
@ -133,94 +133,3 @@ const std::string HTTP_VERB_MOVE("MOVE");
|
||||||
const std::string HTTP_VERB_OPTIONS("OPTIONS");
|
const std::string HTTP_VERB_OPTIONS("OPTIONS");
|
||||||
const std::string HTTP_VERB_PATCH("PATCH");
|
const std::string HTTP_VERB_PATCH("PATCH");
|
||||||
const std::string HTTP_VERB_COPY("COPY");
|
const std::string HTTP_VERB_COPY("COPY");
|
||||||
|
|
||||||
const std::string& httpMethodAsVerb(EHTTPMethod method)
|
|
||||||
{
|
|
||||||
static const std::string VERBS[] =
|
|
||||||
{
|
|
||||||
HTTP_VERB_INVALID,
|
|
||||||
HTTP_VERB_HEAD,
|
|
||||||
HTTP_VERB_GET,
|
|
||||||
HTTP_VERB_PUT,
|
|
||||||
HTTP_VERB_POST,
|
|
||||||
HTTP_VERB_DELETE,
|
|
||||||
HTTP_VERB_MOVE,
|
|
||||||
HTTP_VERB_OPTIONS,
|
|
||||||
HTTP_VERB_PATCH,
|
|
||||||
HTTP_VERB_COPY
|
|
||||||
};
|
|
||||||
if(((S32)method <=0) || ((S32)method >= HTTP_METHOD_COUNT))
|
|
||||||
{
|
|
||||||
return VERBS[0];
|
|
||||||
}
|
|
||||||
return VERBS[method];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isHttpInformationalStatus(S32 status)
|
|
||||||
{
|
|
||||||
// Check for status 1xx.
|
|
||||||
return((100 <= status) && (status < 200));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isHttpGoodStatus(S32 status)
|
|
||||||
{
|
|
||||||
// Check for status 2xx.
|
|
||||||
return((200 <= status) && (status < 300));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isHttpRedirectStatus(S32 status)
|
|
||||||
{
|
|
||||||
// Check for status 3xx.
|
|
||||||
return((300 <= status) && (status < 400));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isHttpClientErrorStatus(S32 status)
|
|
||||||
{
|
|
||||||
// Status 499 is sometimes used for re-interpreted status 2xx errors
|
|
||||||
// based on body content. Treat these as potentially retryable 'server' status errors,
|
|
||||||
// since we do not have enough context to know if this will always fail.
|
|
||||||
if (HTTP_INTERNAL_ERROR == status) return false;
|
|
||||||
|
|
||||||
// Check for status 5xx.
|
|
||||||
return((400 <= status) && (status < 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isHttpServerErrorStatus(S32 status)
|
|
||||||
{
|
|
||||||
// Status 499 is sometimes used for re-interpreted status 2xx errors.
|
|
||||||
// Allow retry of these, since we don't have enough information in this
|
|
||||||
// context to know if this will always fail.
|
|
||||||
if (HTTP_INTERNAL_ERROR == status) return true;
|
|
||||||
|
|
||||||
// Check for status 5xx.
|
|
||||||
return((500 <= status) && (status < 600));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parses 'Retry-After' header contents and returns seconds until retry should occur.
|
|
||||||
bool getSecondsUntilRetryAfter(const std::string& retry_after, F32& seconds_to_wait)
|
|
||||||
{
|
|
||||||
// *TODO: This needs testing! Not in use yet.
|
|
||||||
// Examples of Retry-After headers:
|
|
||||||
// Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
|
|
||||||
// Retry-After: 120
|
|
||||||
|
|
||||||
// Check for number of seconds version, first:
|
|
||||||
char* end = 0;
|
|
||||||
// Parse as double
|
|
||||||
double seconds = std::strtod(retry_after.c_str(), &end);
|
|
||||||
if ( end != 0 && *end == 0 )
|
|
||||||
{
|
|
||||||
// Successful parse
|
|
||||||
seconds_to_wait = (F32) seconds;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse rfc1123 date.
|
|
||||||
time_t date = curl_getdate(retry_after.c_str(), NULL );
|
|
||||||
if (-1 == date) return false;
|
|
||||||
|
|
||||||
seconds_to_wait = (F64)date - LLTimer::getTotalSeconds();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -116,13 +116,6 @@ enum EHTTPMethod
|
||||||
HTTP_METHOD_COUNT
|
HTTP_METHOD_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string& httpMethodAsVerb(EHTTPMethod method);
|
|
||||||
bool isHttpInformationalStatus(S32 status);
|
|
||||||
bool isHttpGoodStatus(S32 status);
|
|
||||||
bool isHttpRedirectStatus(S32 status);
|
|
||||||
bool isHttpClientErrorStatus(S32 status);
|
|
||||||
bool isHttpServerErrorStatus(S32 status);
|
|
||||||
|
|
||||||
// Parses 'Retry-After' header contents and returns seconds until retry should occur.
|
// Parses 'Retry-After' header contents and returns seconds until retry should occur.
|
||||||
bool getSecondsUntilRetryAfter(const std::string& retry_after, F32& seconds_to_wait);
|
bool getSecondsUntilRetryAfter(const std::string& retry_after, F32& seconds_to_wait);
|
||||||
|
|
||||||
|
|
@ -214,11 +214,13 @@ void LLCrashLogger::gatherFiles()
|
||||||
mFileMap["SettingsXml"] = mDebugLog["SettingsFilename"].asString();
|
mFileMap["SettingsXml"] = mDebugLog["SettingsFilename"].asString();
|
||||||
if(mDebugLog.has("CAFilename"))
|
if(mDebugLog.has("CAFilename"))
|
||||||
{
|
{
|
||||||
LLCurl::setCAFile(mDebugLog["CAFilename"].asString());
|
LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_CA_FILE,
|
||||||
|
LLCore::HttpRequest::GLOBAL_POLICY_ID, mDebugLog["CAFilename"].asString(), NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LLCurl::setCAFile(gDirUtilp->getCAFile());
|
LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_CA_FILE,
|
||||||
|
LLCore::HttpRequest::GLOBAL_POLICY_ID, gDirUtilp->getCAFile(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
LL_INFOS() << "Using log file from debug log " << mFileMap["SecondLifeLog"] << LL_ENDL;
|
LL_INFOS() << "Using log file from debug log " << mFileMap["SecondLifeLog"] << LL_ENDL;
|
||||||
|
|
@ -227,7 +229,8 @@ void LLCrashLogger::gatherFiles()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Figure out the filename of the second life log
|
// Figure out the filename of the second life log
|
||||||
LLCurl::setCAFile(gDirUtilp->getCAFile());
|
LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_CA_FILE,
|
||||||
|
LLCore::HttpRequest::GLOBAL_POLICY_ID, gDirUtilp->getCAFile(), NULL);
|
||||||
|
|
||||||
mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
|
mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
|
||||||
mFileMap["SettingsXml"] = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.xml");
|
mFileMap["SettingsXml"] = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.xml");
|
||||||
|
|
@ -531,7 +534,7 @@ void LLCrashLogger::updateApplication(const std::string& message)
|
||||||
|
|
||||||
bool LLCrashLogger::init()
|
bool LLCrashLogger::init()
|
||||||
{
|
{
|
||||||
LLCurl::initClass(false);
|
LLCore::LLHttp::initialize();
|
||||||
|
|
||||||
// We assume that all the logs we're looking for reside on the current drive
|
// We assume that all the logs we're looking for reside on the current drive
|
||||||
gDirUtilp->initAppDirs("SecondLife");
|
gDirUtilp->initAppDirs("SecondLife");
|
||||||
|
|
|
||||||
|
|
@ -42,13 +42,11 @@ set(llmessage_SOURCE_FILES
|
||||||
llclassifiedflags.cpp
|
llclassifiedflags.cpp
|
||||||
llcoproceduremanager.cpp
|
llcoproceduremanager.cpp
|
||||||
llcorehttputil.cpp
|
llcorehttputil.cpp
|
||||||
llcurl.cpp
|
|
||||||
lldatapacker.cpp
|
lldatapacker.cpp
|
||||||
lldispatcher.cpp
|
lldispatcher.cpp
|
||||||
llexperiencecache.cpp
|
llexperiencecache.cpp
|
||||||
llfiltersd2xmlrpc.cpp
|
llfiltersd2xmlrpc.cpp
|
||||||
llhost.cpp
|
llhost.cpp
|
||||||
llhttpconstants.cpp
|
|
||||||
llhttpnode.cpp
|
llhttpnode.cpp
|
||||||
llhttpsdhandler.cpp
|
llhttpsdhandler.cpp
|
||||||
llinstantmessage.cpp
|
llinstantmessage.cpp
|
||||||
|
|
@ -126,7 +124,6 @@ set(llmessage_HEADER_FILES
|
||||||
llclassifiedflags.h
|
llclassifiedflags.h
|
||||||
llcoproceduremanager.h
|
llcoproceduremanager.h
|
||||||
llcorehttputil.h
|
llcorehttputil.h
|
||||||
llcurl.h
|
|
||||||
lldatapacker.h
|
lldatapacker.h
|
||||||
lldbstrings.h
|
lldbstrings.h
|
||||||
lldispatcher.h
|
lldispatcher.h
|
||||||
|
|
@ -136,7 +133,6 @@ set(llmessage_HEADER_FILES
|
||||||
llfiltersd2xmlrpc.h
|
llfiltersd2xmlrpc.h
|
||||||
llfollowcamparams.h
|
llfollowcamparams.h
|
||||||
llhost.h
|
llhost.h
|
||||||
llhttpconstants.h
|
|
||||||
llhttpnode.h
|
llhttpnode.h
|
||||||
llhttpnodeadapter.h
|
llhttpnodeadapter.h
|
||||||
llhttpsdhandler.h
|
llhttpsdhandler.h
|
||||||
|
|
|
||||||
|
|
@ -1,360 +0,0 @@
|
||||||
/**
|
|
||||||
* @file llcurl.cpp
|
|
||||||
* @author Zero / Donovan
|
|
||||||
* @date 2006-10-15
|
|
||||||
* @brief Implementation of wrapper around libcurl.
|
|
||||||
*
|
|
||||||
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
|
|
||||||
* Second Life Viewer Source Code
|
|
||||||
* Copyright (C) 2010-2013, 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$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if LL_WINDOWS
|
|
||||||
#define SAFE_SSL 1
|
|
||||||
#elif LL_DARWIN
|
|
||||||
#define SAFE_SSL 1
|
|
||||||
#else
|
|
||||||
#define SAFE_SSL 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "linden_common.h"
|
|
||||||
|
|
||||||
#include "llcurl.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#if SAFE_SSL
|
|
||||||
#include <openssl/crypto.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "llbufferstream.h"
|
|
||||||
#include "llproxy.h"
|
|
||||||
#include "llsdserialize.h"
|
|
||||||
#include "llstl.h"
|
|
||||||
#include "llstring.h"
|
|
||||||
#include "llthread.h"
|
|
||||||
#include "lltimer.h"
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
/*
|
|
||||||
The trick to getting curl to do keep-alives is to reuse the
|
|
||||||
same easy handle for the requests. It appears that curl
|
|
||||||
keeps a pool of connections alive for each easy handle, but
|
|
||||||
doesn't share them between easy handles. Therefore it is
|
|
||||||
important to keep a pool of easy handles and reuse them,
|
|
||||||
rather than create and destroy them with each request. This
|
|
||||||
code does this.
|
|
||||||
|
|
||||||
Furthermore, it would behoove us to keep track of which
|
|
||||||
hosts an easy handle was used for and pick an easy handle
|
|
||||||
that matches the next request. This code does not current
|
|
||||||
do this.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// *TODO: TSN remove the commented code from this file
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//static const S32 MAX_ACTIVE_REQUEST_COUNT = 100;
|
|
||||||
|
|
||||||
// DEBUG //
|
|
||||||
S32 gCurlEasyCount = 0;
|
|
||||||
S32 gCurlMultiCount = 0;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//static
|
|
||||||
std::vector<LLMutex*> LLCurl::sSSLMutex;
|
|
||||||
std::string LLCurl::sCAPath;
|
|
||||||
std::string LLCurl::sCAFile;
|
|
||||||
//LLCurlThread* LLCurl::sCurlThread = NULL ;
|
|
||||||
LLMutex* LLCurl::sHandleMutexp = NULL ;
|
|
||||||
S32 LLCurl::sTotalHandles = 0 ;
|
|
||||||
bool LLCurl::sNotQuitting = true;
|
|
||||||
F32 LLCurl::sCurlRequestTimeOut = 120.f; //seonds
|
|
||||||
S32 LLCurl::sMaxHandles = 256; //max number of handles, (multi handles and easy handles combined).
|
|
||||||
CURL* LLCurl::sCurlTemplateStandardHandle = NULL;
|
|
||||||
|
|
||||||
void check_curl_code(CURLcode code)
|
|
||||||
{
|
|
||||||
if (code != CURLE_OK)
|
|
||||||
{
|
|
||||||
// linux appears to throw a curl error once per session for a bad initialization
|
|
||||||
// at a pretty random time (when enabling cookies).
|
|
||||||
LL_WARNS("curl") << "curl error detected: " << curl_easy_strerror(code) << LL_ENDL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void check_curl_multi_code(CURLMcode code)
|
|
||||||
{
|
|
||||||
if (code != CURLM_OK)
|
|
||||||
{
|
|
||||||
// linux appears to throw a curl error once per session for a bad initialization
|
|
||||||
// at a pretty random time (when enabling cookies).
|
|
||||||
LL_WARNS("curl") << "curl multi error detected: " << curl_multi_strerror(code) << LL_ENDL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
void LLCurl::setCAPath(const std::string& path)
|
|
||||||
{
|
|
||||||
sCAPath = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
void LLCurl::setCAFile(const std::string& file)
|
|
||||||
{
|
|
||||||
sCAFile = file;
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
std::string LLCurl::getVersionString()
|
|
||||||
{
|
|
||||||
return std::string(curl_version());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//static
|
|
||||||
std::string LLCurl::strerror(CURLcode errorcode)
|
|
||||||
{
|
|
||||||
return std::string(curl_easy_strerror(errorcode));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#if SAFE_SSL
|
|
||||||
//static
|
|
||||||
void LLCurl::ssl_locking_callback(int mode, int type, const char *file, int line)
|
|
||||||
{
|
|
||||||
if (mode & CRYPTO_LOCK)
|
|
||||||
{
|
|
||||||
LLCurl::sSSLMutex[type]->lock();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LLCurl::sSSLMutex[type]->unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
unsigned long LLCurl::ssl_thread_id(void)
|
|
||||||
{
|
|
||||||
return LLThread::currentID();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void LLCurl::initClass(F32 curl_reuest_timeout, S32 max_number_handles, bool multi_threaded)
|
|
||||||
{
|
|
||||||
sCurlRequestTimeOut = curl_reuest_timeout ; //seconds
|
|
||||||
sMaxHandles = max_number_handles ; //max number of handles, (multi handles and easy handles combined).
|
|
||||||
|
|
||||||
// Do not change this "unless you are familiar with and mean to control
|
|
||||||
// internal operations of libcurl"
|
|
||||||
// - http://curl.haxx.se/libcurl/c/curl_global_init.html
|
|
||||||
CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
|
|
||||||
|
|
||||||
check_curl_code(code);
|
|
||||||
|
|
||||||
#if SAFE_SSL
|
|
||||||
S32 mutex_count = CRYPTO_num_locks();
|
|
||||||
for (S32 i=0; i<mutex_count; i++)
|
|
||||||
{
|
|
||||||
sSSLMutex.push_back(new LLMutex(NULL));
|
|
||||||
}
|
|
||||||
CRYPTO_set_id_callback(&LLCurl::ssl_thread_id);
|
|
||||||
CRYPTO_set_locking_callback(&LLCurl::ssl_locking_callback);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// sCurlThread = new LLCurlThread(multi_threaded) ;
|
|
||||||
if(multi_threaded)
|
|
||||||
{
|
|
||||||
sHandleMutexp = new LLMutex(NULL) ;
|
|
||||||
// Easy::sHandleMutexp = new LLMutex(NULL) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLCurl::cleanupClass()
|
|
||||||
{
|
|
||||||
sNotQuitting = false; //set quitting
|
|
||||||
|
|
||||||
//shut down curl thread
|
|
||||||
// while(1)
|
|
||||||
// {
|
|
||||||
// if(!sCurlThread->update(1)) //finish all tasks
|
|
||||||
// {
|
|
||||||
// break ;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
LL_CHECK_MEMORY
|
|
||||||
// sCurlThread->shutdown() ;
|
|
||||||
LL_CHECK_MEMORY
|
|
||||||
// delete sCurlThread ;
|
|
||||||
// sCurlThread = NULL ;
|
|
||||||
LL_CHECK_MEMORY
|
|
||||||
|
|
||||||
#if SAFE_SSL
|
|
||||||
CRYPTO_set_locking_callback(NULL);
|
|
||||||
for_each(sSSLMutex.begin(), sSSLMutex.end(), DeletePointer());
|
|
||||||
sSSLMutex.clear();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LL_CHECK_MEMORY
|
|
||||||
|
|
||||||
// Free the template easy handle
|
|
||||||
curl_easy_cleanup(sCurlTemplateStandardHandle);
|
|
||||||
sCurlTemplateStandardHandle = NULL;
|
|
||||||
LL_CHECK_MEMORY
|
|
||||||
|
|
||||||
|
|
||||||
delete sHandleMutexp ;
|
|
||||||
sHandleMutexp = NULL ;
|
|
||||||
|
|
||||||
LL_CHECK_MEMORY
|
|
||||||
|
|
||||||
// removed as per https://jira.secondlife.com/browse/SH-3115
|
|
||||||
//llassert(Easy::sActiveHandles.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
CURLM* LLCurl::newMultiHandle()
|
|
||||||
{
|
|
||||||
llassert(sNotQuitting);
|
|
||||||
|
|
||||||
LLMutexLock lock(sHandleMutexp) ;
|
|
||||||
|
|
||||||
if(sTotalHandles + 1 > sMaxHandles)
|
|
||||||
{
|
|
||||||
LL_WARNS() << "no more handles available." << LL_ENDL ;
|
|
||||||
return NULL ; //failed
|
|
||||||
}
|
|
||||||
sTotalHandles++;
|
|
||||||
|
|
||||||
CURLM* ret = curl_multi_init() ;
|
|
||||||
if(!ret)
|
|
||||||
{
|
|
||||||
LL_WARNS() << "curl_multi_init failed." << LL_ENDL ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
CURLMcode LLCurl::deleteMultiHandle(CURLM* handle)
|
|
||||||
{
|
|
||||||
if(handle)
|
|
||||||
{
|
|
||||||
LLMutexLock lock(sHandleMutexp) ;
|
|
||||||
sTotalHandles-- ;
|
|
||||||
return curl_multi_cleanup(handle) ;
|
|
||||||
}
|
|
||||||
return CURLM_OK ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
CURL* LLCurl::newEasyHandle()
|
|
||||||
{
|
|
||||||
llassert(sNotQuitting);
|
|
||||||
LLMutexLock lock(sHandleMutexp) ;
|
|
||||||
|
|
||||||
if(sTotalHandles + 1 > sMaxHandles)
|
|
||||||
{
|
|
||||||
LL_WARNS() << "no more handles available." << LL_ENDL ;
|
|
||||||
return NULL ; //failed
|
|
||||||
}
|
|
||||||
sTotalHandles++;
|
|
||||||
|
|
||||||
CURL* ret = createStandardCurlHandle();
|
|
||||||
if(!ret)
|
|
||||||
{
|
|
||||||
LL_WARNS() << "failed to create curl handle." << LL_ENDL ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
void LLCurl::deleteEasyHandle(CURL* handle)
|
|
||||||
{
|
|
||||||
if(handle)
|
|
||||||
{
|
|
||||||
LLMutexLock lock(sHandleMutexp) ;
|
|
||||||
LL_CHECK_MEMORY
|
|
||||||
curl_easy_cleanup(handle) ;
|
|
||||||
LL_CHECK_MEMORY
|
|
||||||
sTotalHandles-- ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned int LLCurl::MAX_REDIRECTS = 5;
|
|
||||||
|
|
||||||
// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.
|
|
||||||
void LLCurlFF::check_easy_code(CURLcode code)
|
|
||||||
{
|
|
||||||
check_curl_code(code);
|
|
||||||
}
|
|
||||||
// void LLCurlFF::check_multi_code(CURLMcode code)
|
|
||||||
// {
|
|
||||||
// check_curl_multi_code(code);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// Static
|
|
||||||
CURL* LLCurl::createStandardCurlHandle()
|
|
||||||
{
|
|
||||||
if (sCurlTemplateStandardHandle == NULL)
|
|
||||||
{ // Late creation of the template curl handle
|
|
||||||
sCurlTemplateStandardHandle = curl_easy_init();
|
|
||||||
if (sCurlTemplateStandardHandle == NULL)
|
|
||||||
{
|
|
||||||
LL_WARNS() << "curl error calling curl_easy_init()" << LL_ENDL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CURLcode result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
|
||||||
check_curl_code(result);
|
|
||||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_NOSIGNAL, 1);
|
|
||||||
check_curl_code(result);
|
|
||||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_NOPROGRESS, 1);
|
|
||||||
check_curl_code(result);
|
|
||||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_ENCODING, "");
|
|
||||||
check_curl_code(result);
|
|
||||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_AUTOREFERER, 1);
|
|
||||||
check_curl_code(result);
|
|
||||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_FOLLOWLOCATION, 1);
|
|
||||||
check_curl_code(result);
|
|
||||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_SSL_VERIFYPEER, 1);
|
|
||||||
check_curl_code(result);
|
|
||||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_SSL_VERIFYHOST, 0);
|
|
||||||
check_curl_code(result);
|
|
||||||
|
|
||||||
// The Linksys WRT54G V5 router has an issue with frequent
|
|
||||||
// DNS lookups from LAN machines. If they happen too often,
|
|
||||||
// like for every HTTP request, the router gets annoyed after
|
|
||||||
// about 700 or so requests and starts issuing TCP RSTs to
|
|
||||||
// new connections. Reuse the DNS lookups for even a few
|
|
||||||
// seconds and no RSTs.
|
|
||||||
result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_DNS_CACHE_TIMEOUT, 15);
|
|
||||||
check_curl_code(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return curl_easy_duphandle(sCurlTemplateStandardHandle);
|
|
||||||
}
|
|
||||||
|
|
@ -1,142 +0,0 @@
|
||||||
/**
|
|
||||||
* @file llcurl.h
|
|
||||||
* @author Zero / Donovan
|
|
||||||
* @date 2006-10-15
|
|
||||||
* @brief A wrapper around libcurl.
|
|
||||||
*
|
|
||||||
* $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$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LL_LLCURL_H
|
|
||||||
#define LL_LLCURL_H
|
|
||||||
|
|
||||||
#include "linden_common.h"
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <boost/intrusive_ptr.hpp>
|
|
||||||
#include <curl/curl.h> // TODO: remove dependency
|
|
||||||
|
|
||||||
#include "llbuffer.h"
|
|
||||||
#include "llhttpconstants.h"
|
|
||||||
#include "lliopipe.h"
|
|
||||||
#include "llsd.h"
|
|
||||||
#include "llqueuedthread.h"
|
|
||||||
#include "llframetimer.h"
|
|
||||||
#include "llpointer.h"
|
|
||||||
#include "llsingleton.h"
|
|
||||||
|
|
||||||
class LLMutex;
|
|
||||||
//class LLCurlThread;
|
|
||||||
|
|
||||||
// For whatever reason, this is not typedef'd in curl.h
|
|
||||||
typedef size_t (*curl_header_callback)(void *ptr, size_t size, size_t nmemb, void *stream);
|
|
||||||
|
|
||||||
class LLCurl
|
|
||||||
{
|
|
||||||
LOG_CLASS(LLCurl);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ brief Set certificate authority file used to verify HTTPS certs.
|
|
||||||
*/
|
|
||||||
static void setCAFile(const std::string& file);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ brief Set certificate authority path used to verify HTTPS certs.
|
|
||||||
*/
|
|
||||||
static void setCAPath(const std::string& path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ brief Return human-readable string describing libcurl version.
|
|
||||||
*/
|
|
||||||
static std::string getVersionString();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ brief Get certificate authority file used to verify HTTPS certs.
|
|
||||||
*/
|
|
||||||
static const std::string& getCAFile() { return sCAFile; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ brief Get certificate authority path used to verify HTTPS certs.
|
|
||||||
*/
|
|
||||||
static const std::string& getCAPath() { return sCAPath; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ brief Initialize LLCurl class
|
|
||||||
*/
|
|
||||||
static void initClass(F32 curl_reuest_timeout = 120.f, S32 max_number_handles = 256, bool multi_threaded = false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ brief Cleanup LLCurl class
|
|
||||||
*/
|
|
||||||
static void cleanupClass();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ brief curl error code -> string
|
|
||||||
*/
|
|
||||||
static std::string strerror(CURLcode errorcode);
|
|
||||||
|
|
||||||
// For OpenSSL callbacks
|
|
||||||
static std::vector<LLMutex*> sSSLMutex;
|
|
||||||
|
|
||||||
// OpenSSL callbacks
|
|
||||||
static void ssl_locking_callback(int mode, int type, const char *file, int line);
|
|
||||||
static unsigned long ssl_thread_id(void);
|
|
||||||
|
|
||||||
// static LLCurlThread* getCurlThread() { return sCurlThread ;}
|
|
||||||
|
|
||||||
static CURLM* newMultiHandle() ;
|
|
||||||
static CURLMcode deleteMultiHandle(CURLM* handle) ;
|
|
||||||
static CURL* newEasyHandle() ;
|
|
||||||
static void deleteEasyHandle(CURL* handle) ;
|
|
||||||
|
|
||||||
static CURL* createStandardCurlHandle();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static std::string sCAPath;
|
|
||||||
static std::string sCAFile;
|
|
||||||
static const unsigned int MAX_REDIRECTS;
|
|
||||||
// static LLCurlThread* sCurlThread;
|
|
||||||
// static LLCurlThread* sCurlThread;
|
|
||||||
|
|
||||||
static LLMutex* sHandleMutexp ;
|
|
||||||
static S32 sTotalHandles ;
|
|
||||||
static S32 sMaxHandles;
|
|
||||||
static CURL* sCurlTemplateStandardHandle;
|
|
||||||
public:
|
|
||||||
static bool sNotQuitting;
|
|
||||||
static F32 sCurlRequestTimeOut;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.
|
|
||||||
namespace LLCurlFF
|
|
||||||
{
|
|
||||||
void check_easy_code(CURLcode code);
|
|
||||||
//void check_multi_code(CURLMcode code);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // LL_LLCURL_H
|
|
||||||
|
|
@ -30,9 +30,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
#include "httpcommon.h"
|
||||||
#include "llapr.h"
|
#include "llapr.h"
|
||||||
#include "llcurl.h"
|
|
||||||
#include "llhost.h"
|
#include "llhost.h"
|
||||||
|
|
||||||
// Static class variable instances
|
// Static class variable instances
|
||||||
|
|
@ -429,21 +428,21 @@ void LLProxy::applyProxySettings(CURL* handle)
|
||||||
// Now test again to verify that the proxy wasn't disabled between the first check and the lock.
|
// Now test again to verify that the proxy wasn't disabled between the first check and the lock.
|
||||||
if (mHTTPProxyEnabled)
|
if (mHTTPProxyEnabled)
|
||||||
{
|
{
|
||||||
LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()));
|
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()), CURLOPT_PROXY);
|
||||||
LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()));
|
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()), CURLOPT_PROXYPORT);
|
||||||
|
|
||||||
if (mProxyType == LLPROXY_SOCKS)
|
if (mProxyType == LLPROXY_SOCKS)
|
||||||
{
|
{
|
||||||
LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5));
|
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5), CURLOPT_PROXYTYPE);
|
||||||
if (mAuthMethodSelected == METHOD_PASSWORD)
|
if (mAuthMethodSelected == METHOD_PASSWORD)
|
||||||
{
|
{
|
||||||
std::string auth_string = mSocksUsername + ":" + mSocksPassword;
|
std::string auth_string = mSocksUsername + ":" + mSocksPassword;
|
||||||
LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()));
|
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()), CURLOPT_PROXYUSERPWD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LLCurlFF::check_easy_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP));
|
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP), CURLOPT_PROXYTYPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,12 @@
|
||||||
#ifndef LL_PROXY_H
|
#ifndef LL_PROXY_H
|
||||||
#define LL_PROXY_H
|
#define LL_PROXY_H
|
||||||
|
|
||||||
#include "llcurl.h"
|
|
||||||
#include "llhost.h"
|
#include "llhost.h"
|
||||||
#include "lliosocket.h"
|
#include "lliosocket.h"
|
||||||
#include "llmemory.h"
|
#include "llmemory.h"
|
||||||
#include "llsingleton.h"
|
#include "llsingleton.h"
|
||||||
#include "llthread.h"
|
#include "llthread.h"
|
||||||
|
#include <curl/curl.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// SOCKS error codes returned from the StartProxy method
|
// SOCKS error codes returned from the StartProxy method
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
#include "llhost.h"
|
#include "llhost.h"
|
||||||
#include "llmessageconfig.h"
|
#include "llmessageconfig.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
#include "llhttpconstants.h"
|
||||||
|
|
||||||
|
|
||||||
bool LLTrustedMessageService::validate(const std::string& name, LLSD& context)
|
bool LLTrustedMessageService::validate(const std::string& name, LLSD& context)
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@
|
||||||
#include "lltimer.h"
|
#include "lltimer.h"
|
||||||
#include "llpacketring.h"
|
#include "llpacketring.h"
|
||||||
#include "llhost.h"
|
#include "llhost.h"
|
||||||
#include "llcurl.h"
|
|
||||||
#include "llhttpnode.h"
|
#include "llhttpnode.h"
|
||||||
//#include "llpacketack.h"
|
//#include "llpacketack.h"
|
||||||
#include "llsingleton.h"
|
#include "llsingleton.h"
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "llcurl.h"
|
|
||||||
#include "llhttpretrypolicy.h"
|
#include "llhttpretrypolicy.h"
|
||||||
#include "llviewerinventory.h"
|
#include "llviewerinventory.h"
|
||||||
#include "llcorehttputil.h"
|
#include "llcorehttputil.h"
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,9 @@ LLAppCoreHttp::~LLAppCoreHttp()
|
||||||
|
|
||||||
void LLAppCoreHttp::init()
|
void LLAppCoreHttp::init()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
LLCore::LLHttp::initialize();
|
||||||
|
|
||||||
LLCore::HttpStatus status = LLCore::HttpRequest::createService();
|
LLCore::HttpStatus status = LLCore::HttpRequest::createService();
|
||||||
if (! status)
|
if (! status)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,6 @@
|
||||||
#include "llviewerjoystick.h"
|
#include "llviewerjoystick.h"
|
||||||
#include "llallocator.h"
|
#include "llallocator.h"
|
||||||
#include "llares.h"
|
#include "llares.h"
|
||||||
#include "llcurl.h"
|
|
||||||
#include "llcalc.h"
|
#include "llcalc.h"
|
||||||
#include "llconversationlog.h"
|
#include "llconversationlog.h"
|
||||||
#include "lldxhardware.h"
|
#include "lldxhardware.h"
|
||||||
|
|
@ -828,12 +827,7 @@ bool LLAppViewer::init()
|
||||||
// before consumers (LLTextureFetch).
|
// before consumers (LLTextureFetch).
|
||||||
mAppCoreHttp.init();
|
mAppCoreHttp.init();
|
||||||
|
|
||||||
// *NOTE:Mani - LLCurl::initClass is not thread safe.
|
LL_INFOS("InitInfo") << "LLCore::Http initialized." << LL_ENDL ;
|
||||||
// Called before threads are created.
|
|
||||||
LLCurl::initClass(gSavedSettings.getF32("CurlRequestTimeOut"),
|
|
||||||
gSavedSettings.getS32("CurlMaximumNumberOfHandles"),
|
|
||||||
gSavedSettings.getBOOL("CurlUseMultipleThreads"));
|
|
||||||
LL_INFOS("InitInfo") << "LLCurl initialized." << LL_ENDL ;
|
|
||||||
|
|
||||||
LLMachineID::init();
|
LLMachineID::init();
|
||||||
|
|
||||||
|
|
@ -903,7 +897,7 @@ bool LLAppViewer::init()
|
||||||
// the libs involved in getting to a full login screen.
|
// the libs involved in getting to a full login screen.
|
||||||
//
|
//
|
||||||
LL_INFOS("InitInfo") << "J2C Engine is: " << LLImageJ2C::getEngineInfo() << LL_ENDL;
|
LL_INFOS("InitInfo") << "J2C Engine is: " << LLImageJ2C::getEngineInfo() << LL_ENDL;
|
||||||
LL_INFOS("InitInfo") << "libcurl version is: " << LLCurl::getVersionString() << LL_ENDL;
|
LL_INFOS("InitInfo") << "libcurl version is: " << LLCore::LLHttp::getCURLVersion() << LL_ENDL;
|
||||||
|
|
||||||
/////////////////////////////////////////////////
|
/////////////////////////////////////////////////
|
||||||
// OS-specific login dialogs
|
// OS-specific login dialogs
|
||||||
|
|
@ -1313,7 +1307,6 @@ bool LLAppViewer::mainLoop()
|
||||||
|
|
||||||
// Create IO Pump to use for HTTP Requests.
|
// Create IO Pump to use for HTTP Requests.
|
||||||
gServicePump = new LLPumpIO(gAPRPoolp);
|
gServicePump = new LLPumpIO(gAPRPoolp);
|
||||||
LLCurl::setCAFile(gDirUtilp->getCAFile());
|
|
||||||
|
|
||||||
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
|
// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
|
||||||
|
|
||||||
|
|
@ -3348,7 +3341,7 @@ LLSD LLAppViewer::getViewerInfo() const
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
info["OPENGL_VERSION"] = (const char*)(glGetString(GL_VERSION));
|
info["OPENGL_VERSION"] = (const char*)(glGetString(GL_VERSION));
|
||||||
info["LIBCURL_VERSION"] = LLCurl::getVersionString();
|
info["LIBCURL_VERSION"] = LLCore::LLHttp::getCURLVersion();
|
||||||
info["J2C_VERSION"] = LLImageJ2C::getEngineInfo();
|
info["J2C_VERSION"] = LLImageJ2C::getEngineInfo();
|
||||||
bool want_fullname = true;
|
bool want_fullname = true;
|
||||||
info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : LLSD();
|
info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : LLSD();
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@
|
||||||
// Linden library includes
|
// Linden library includes
|
||||||
#include "llaudioengine.h"
|
#include "llaudioengine.h"
|
||||||
#include "llbutton.h"
|
#include "llbutton.h"
|
||||||
#include "llcurl.h"
|
|
||||||
#include "llglheaders.h"
|
#include "llglheaders.h"
|
||||||
#include "llfloater.h"
|
#include "llfloater.h"
|
||||||
#include "llfloaterreg.h"
|
#include "llfloaterreg.h"
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,23 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "llviewerprecompiledheaders.h"
|
#include "llviewerprecompiledheaders.h"
|
||||||
|
|
||||||
#include "llhttpretrypolicy.h"
|
#include "llhttpretrypolicy.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// Moved from httpconstants.h... only used in this file.
|
||||||
|
bool isHttpServerErrorStatus(S32 status)
|
||||||
|
{
|
||||||
|
// Status 499 is sometimes used for re-interpreted status 2xx errors.
|
||||||
|
// Allow retry of these, since we don't have enough information in this
|
||||||
|
// context to know if this will always fail.
|
||||||
|
if (HTTP_INTERNAL_ERROR == status) return true;
|
||||||
|
|
||||||
|
// Check for status 5xx.
|
||||||
|
return((500 <= status) && (status < 600));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LLAdaptiveRetryPolicy::LLAdaptiveRetryPolicy(F32 min_delay, F32 max_delay, F32 backoff_factor, U32 max_retries, bool retry_on_4xx):
|
LLAdaptiveRetryPolicy::LLAdaptiveRetryPolicy(F32 min_delay, F32 max_delay, F32 backoff_factor, U32 max_retries, bool retry_on_4xx):
|
||||||
mMinDelay(min_delay),
|
mMinDelay(min_delay),
|
||||||
mMaxDelay(max_delay),
|
mMaxDelay(max_delay),
|
||||||
|
|
@ -140,3 +154,34 @@ bool LLAdaptiveRetryPolicy::shouldRetry(F32& seconds_to_wait) const
|
||||||
seconds_to_wait = mShouldRetry ? (F32) mRetryTimer.getRemainingTimeF32() : F32_MAX;
|
seconds_to_wait = mShouldRetry ? (F32) mRetryTimer.getRemainingTimeF32() : F32_MAX;
|
||||||
return mShouldRetry;
|
return mShouldRetry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Moved from httpconstants. Only used by this file.
|
||||||
|
// Parses 'Retry-After' header contents and returns seconds until retry should occur.
|
||||||
|
/*static*/
|
||||||
|
bool LLAdaptiveRetryPolicy::getSecondsUntilRetryAfter(const std::string& retry_after, F32& seconds_to_wait)
|
||||||
|
{
|
||||||
|
// *TODO: This needs testing! Not in use yet.
|
||||||
|
// Examples of Retry-After headers:
|
||||||
|
// Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
|
||||||
|
// Retry-After: 120
|
||||||
|
|
||||||
|
// Check for number of seconds version, first:
|
||||||
|
char* end = 0;
|
||||||
|
// Parse as double
|
||||||
|
double seconds = std::strtod(retry_after.c_str(), &end);
|
||||||
|
if (end != 0 && *end == 0)
|
||||||
|
{
|
||||||
|
// Successful parse
|
||||||
|
seconds_to_wait = (F32)seconds;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse rfc1123 date.
|
||||||
|
time_t date = curl_getdate(retry_after.c_str(), NULL);
|
||||||
|
if (-1 == date) return false;
|
||||||
|
|
||||||
|
seconds_to_wait = (F64)date - LLTimer::getTotalSeconds();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,8 @@ public:
|
||||||
// virtual
|
// virtual
|
||||||
bool shouldRetry(F32& seconds_to_wait) const;
|
bool shouldRetry(F32& seconds_to_wait) const;
|
||||||
|
|
||||||
|
static bool getSecondsUntilRetryAfter(const std::string& retry_after, F32& seconds_to_wait);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void init();
|
void init();
|
||||||
bool getRetryAfter(const LLSD& headers, F32& retry_header_time);
|
bool getRetryAfter(const LLSD& headers, F32& retry_header_time);
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@
|
||||||
#include "llassettype.h"
|
#include "llassettype.h"
|
||||||
#include "llfoldertype.h"
|
#include "llfoldertype.h"
|
||||||
#include "llframetimer.h"
|
#include "llframetimer.h"
|
||||||
#include "llcurl.h"
|
|
||||||
#include "lluuid.h"
|
#include "lluuid.h"
|
||||||
#include "llpermissionsflags.h"
|
#include "llpermissionsflags.h"
|
||||||
#include "llviewerinventory.h"
|
#include "llviewerinventory.h"
|
||||||
|
|
|
||||||
|
|
@ -631,14 +631,8 @@ void LLMediaDataClient::Handler::onFailure(LLCore::HttpResponse * response, LLCo
|
||||||
if (status == LLCore::HttpStatus(HTTP_SERVICE_UNAVAILABLE))
|
if (status == LLCore::HttpStatus(HTTP_SERVICE_UNAVAILABLE))
|
||||||
{
|
{
|
||||||
F32 retry_timeout;
|
F32 retry_timeout;
|
||||||
#if 0
|
|
||||||
// *TODO: Honor server Retry-After header.
|
retry_timeout = mRequest->getRetryTimerDelay();
|
||||||
if (!hasResponseHeader(HTTP_IN_HEADER_RETRY_AFTER)
|
|
||||||
|| !getSecondsUntilRetryAfter(getResponseHeader(HTTP_IN_HEADER_RETRY_AFTER), retry_timeout))
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
retry_timeout = mRequest->getRetryTimerDelay();
|
|
||||||
}
|
|
||||||
|
|
||||||
mRequest->incRetryCount();
|
mRequest->incRetryCount();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@
|
||||||
#include "llappviewer.h"
|
#include "llappviewer.h"
|
||||||
#include "llbufferstream.h"
|
#include "llbufferstream.h"
|
||||||
#include "llcallbacklist.h"
|
#include "llcallbacklist.h"
|
||||||
#include "llcurl.h"
|
|
||||||
#include "lldatapacker.h"
|
#include "lldatapacker.h"
|
||||||
#include "lldeadmantimer.h"
|
#include "lldeadmantimer.h"
|
||||||
#include "llfloatermodelpreview.h"
|
#include "llfloatermodelpreview.h"
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@
|
||||||
#include "llcheckboxctrl.h"
|
#include "llcheckboxctrl.h"
|
||||||
#include "llcommandhandler.h" // for secondlife:///app/login/
|
#include "llcommandhandler.h" // for secondlife:///app/login/
|
||||||
#include "llcombobox.h"
|
#include "llcombobox.h"
|
||||||
#include "llcurl.h"
|
|
||||||
#include "llviewercontrol.h"
|
#include "llviewercontrol.h"
|
||||||
#include "llfloaterpreference.h"
|
#include "llfloaterpreference.h"
|
||||||
#include "llfocusmgr.h"
|
#include "llfocusmgr.h"
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@
|
||||||
#include "lltextureinfo.h"
|
#include "lltextureinfo.h"
|
||||||
#include "llapr.h"
|
#include "llapr.h"
|
||||||
#include "llimageworker.h"
|
#include "llimageworker.h"
|
||||||
#include "llcurl.h"
|
|
||||||
#include "httprequest.h"
|
#include "httprequest.h"
|
||||||
#include "httpoptions.h"
|
#include "httpoptions.h"
|
||||||
#include "httpheaders.h"
|
#include "httpheaders.h"
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@
|
||||||
#include "llxmlrpctransaction.h"
|
#include "llxmlrpctransaction.h"
|
||||||
#include "llxmlrpclistener.h"
|
#include "llxmlrpclistener.h"
|
||||||
|
|
||||||
#include "llcurl.h"
|
|
||||||
#include "httpcommon.h"
|
#include "httpcommon.h"
|
||||||
|
#include "llhttpconstants.h"
|
||||||
#include "httprequest.h"
|
#include "httprequest.h"
|
||||||
#include "httpoptions.h"
|
#include "httpoptions.h"
|
||||||
#include "httpheaders.h"
|
#include "httpheaders.h"
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,6 @@
|
||||||
#include "llspatialpartition.h"
|
#include "llspatialpartition.h"
|
||||||
#include "llmutelist.h"
|
#include "llmutelist.h"
|
||||||
#include "lltoolpie.h"
|
#include "lltoolpie.h"
|
||||||
#include "llcurl.h"
|
|
||||||
#include "llnotifications.h"
|
#include "llnotifications.h"
|
||||||
#include "llpathinglib.h"
|
#include "llpathinglib.h"
|
||||||
#include "llfloaterpathfindingconsole.h"
|
#include "llfloaterpathfindingconsole.h"
|
||||||
|
|
|
||||||
|
|
@ -234,13 +234,13 @@ void RetryPolicyTestObject::test<6>()
|
||||||
|
|
||||||
std::string str1("0");
|
std::string str1("0");
|
||||||
seconds_to_wait = F32_MAX;
|
seconds_to_wait = F32_MAX;
|
||||||
success = getSecondsUntilRetryAfter(str1, seconds_to_wait);
|
success = LLAdaptiveRetryPolicy::getSecondsUntilRetryAfter(str1, seconds_to_wait);
|
||||||
ensure("parse 1", success);
|
ensure("parse 1", success);
|
||||||
ensure_equals("parse 1", seconds_to_wait, 0.0);
|
ensure_equals("parse 1", seconds_to_wait, 0.0);
|
||||||
|
|
||||||
std::string str2("999.9");
|
std::string str2("999.9");
|
||||||
seconds_to_wait = F32_MAX;
|
seconds_to_wait = F32_MAX;
|
||||||
success = getSecondsUntilRetryAfter(str2, seconds_to_wait);
|
success = LLAdaptiveRetryPolicy::getSecondsUntilRetryAfter(str2, seconds_to_wait);
|
||||||
ensure("parse 2", success);
|
ensure("parse 2", success);
|
||||||
ensure_approximately_equals("parse 2", seconds_to_wait, 999.9F, 8);
|
ensure_approximately_equals("parse 2", seconds_to_wait, 999.9F, 8);
|
||||||
|
|
||||||
|
|
@ -248,7 +248,7 @@ void RetryPolicyTestObject::test<6>()
|
||||||
time(&nowseconds);
|
time(&nowseconds);
|
||||||
std::string str3 = LLDate((F64)(nowseconds+44)).asRFC1123();
|
std::string str3 = LLDate((F64)(nowseconds+44)).asRFC1123();
|
||||||
seconds_to_wait = F32_MAX;
|
seconds_to_wait = F32_MAX;
|
||||||
success = getSecondsUntilRetryAfter(str3, seconds_to_wait);
|
success = LLAdaptiveRetryPolicy::getSecondsUntilRetryAfter(str3, seconds_to_wait);
|
||||||
std::cerr << " str3 [" << str3 << "]" << std::endl;
|
std::cerr << " str3 [" << str3 << "]" << std::endl;
|
||||||
ensure("parse 3", success);
|
ensure("parse 3", success);
|
||||||
ensure_approximately_equals_range("parse 3", seconds_to_wait, 44.0F, 2.0F);
|
ensure_approximately_equals_range("parse 3", seconds_to_wait, 44.0F, 2.0F);
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
#include <tut/tut.hpp>
|
#include <tut/tut.hpp>
|
||||||
#include "linden_common.h"
|
#include "linden_common.h"
|
||||||
#include "lltut.h"
|
#include "lltut.h"
|
||||||
|
#include "llhttpconstants.h"
|
||||||
#include "llapr.h"
|
#include "llapr.h"
|
||||||
#include "llmessageconfig.h"
|
#include "llmessageconfig.h"
|
||||||
#include "llsdserialize.h"
|
#include "llsdserialize.h"
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
#include "linden_common.h"
|
#include "linden_common.h"
|
||||||
|
|
||||||
#include "llupdatedownloader.h"
|
#include "llupdatedownloader.h"
|
||||||
|
#include "httpcommon.h"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
@ -39,7 +39,6 @@
|
||||||
#include "llsdserialize.h"
|
#include "llsdserialize.h"
|
||||||
#include "llthread.h"
|
#include "llthread.h"
|
||||||
#include "llupdaterservice.h"
|
#include "llupdaterservice.h"
|
||||||
#include "llcurl.h"
|
|
||||||
|
|
||||||
class LLUpdateDownloader::Implementation:
|
class LLUpdateDownloader::Implementation:
|
||||||
public LLThread
|
public LLThread
|
||||||
|
|
@ -65,7 +64,7 @@ private:
|
||||||
curl_off_t mBandwidthLimit;
|
curl_off_t mBandwidthLimit;
|
||||||
bool mCancelled;
|
bool mCancelled;
|
||||||
LLUpdateDownloader::Client & mClient;
|
LLUpdateDownloader::Client & mClient;
|
||||||
CURL * mCurl;
|
LLCore::LLHttp::CURL_ptr mCurl;
|
||||||
LLSD mDownloadData;
|
LLSD mDownloadData;
|
||||||
llofstream mDownloadStream;
|
llofstream mDownloadStream;
|
||||||
unsigned char mDownloadPercent;
|
unsigned char mDownloadPercent;
|
||||||
|
|
@ -192,7 +191,7 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client &
|
||||||
mBandwidthLimit(0),
|
mBandwidthLimit(0),
|
||||||
mCancelled(false),
|
mCancelled(false),
|
||||||
mClient(client),
|
mClient(client),
|
||||||
mCurl(0),
|
mCurl(),
|
||||||
mDownloadPercent(0),
|
mDownloadPercent(0),
|
||||||
mHeaderList(0)
|
mHeaderList(0)
|
||||||
{
|
{
|
||||||
|
|
@ -212,10 +211,7 @@ LLUpdateDownloader::Implementation::~Implementation()
|
||||||
{
|
{
|
||||||
; // No op.
|
; // No op.
|
||||||
}
|
}
|
||||||
if(mCurl)
|
mCurl.reset();
|
||||||
{
|
|
||||||
LLCurl::deleteEasyHandle(mCurl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -331,9 +327,9 @@ void LLUpdateDownloader::Implementation::setBandwidthLimit(U64 bytesPerSecond)
|
||||||
{
|
{
|
||||||
if((mBandwidthLimit != bytesPerSecond) && isDownloading() && !mDownloadData["required"].asBoolean())
|
if((mBandwidthLimit != bytesPerSecond) && isDownloading() && !mDownloadData["required"].asBoolean())
|
||||||
{
|
{
|
||||||
llassert(mCurl != 0);
|
llassert(static_cast<bool>(mCurl));
|
||||||
mBandwidthLimit = bytesPerSecond;
|
mBandwidthLimit = bytesPerSecond;
|
||||||
CURLcode code = curl_easy_setopt(mCurl, CURLOPT_MAX_RECV_SPEED_LARGE, &mBandwidthLimit);
|
CURLcode code = curl_easy_setopt(mCurl.get(), CURLOPT_MAX_RECV_SPEED_LARGE, &mBandwidthLimit);
|
||||||
if(code != CURLE_OK)
|
if(code != CURLE_OK)
|
||||||
{
|
{
|
||||||
LL_WARNS("UpdaterService") << "unable to change dowload bandwidth" << LL_ENDL;
|
LL_WARNS("UpdaterService") << "unable to change dowload bandwidth" << LL_ENDL;
|
||||||
|
|
@ -416,7 +412,7 @@ int LLUpdateDownloader::Implementation::onProgress(double downloadSize, double b
|
||||||
|
|
||||||
void LLUpdateDownloader::Implementation::run(void)
|
void LLUpdateDownloader::Implementation::run(void)
|
||||||
{
|
{
|
||||||
CURLcode code = curl_easy_perform(mCurl);
|
CURLcode code = curl_easy_perform(mCurl.get());
|
||||||
mDownloadStream.close();
|
mDownloadStream.close();
|
||||||
if(code == CURLE_OK)
|
if(code == CURLE_OK)
|
||||||
{
|
{
|
||||||
|
|
@ -460,36 +456,36 @@ void LLUpdateDownloader::Implementation::run(void)
|
||||||
|
|
||||||
void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader)
|
void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader)
|
||||||
{
|
{
|
||||||
if(mCurl == 0)
|
if(!mCurl)
|
||||||
{
|
{
|
||||||
mCurl = LLCurl::newEasyHandle();
|
mCurl = LLCore::LLHttp::createEasyHandle();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
curl_easy_reset(mCurl);
|
curl_easy_reset(mCurl.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mCurl == 0)
|
if(!mCurl)
|
||||||
{
|
{
|
||||||
throw DownloadError("failed to initialize curl");
|
throw DownloadError("failed to initialize curl");
|
||||||
}
|
}
|
||||||
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, true));
|
throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_NOSIGNAL, true));
|
||||||
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_FOLLOWLOCATION, true));
|
throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_FOLLOWLOCATION, true));
|
||||||
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function));
|
throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_WRITEFUNCTION, &write_function));
|
||||||
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this));
|
throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_WRITEDATA, this));
|
||||||
if(processHeader)
|
if(processHeader)
|
||||||
{
|
{
|
||||||
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function));
|
throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HEADERFUNCTION, &header_function));
|
||||||
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this));
|
throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HEADERDATA, this));
|
||||||
}
|
}
|
||||||
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPGET, true));
|
throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HTTPGET, true));
|
||||||
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_URL, url.c_str()));
|
throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_URL, url.c_str()));
|
||||||
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_PROGRESSFUNCTION, &progress_callback));
|
throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_PROGRESSFUNCTION, &progress_callback));
|
||||||
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_PROGRESSDATA, this));
|
throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_PROGRESSDATA, this));
|
||||||
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_NOPROGRESS, false));
|
throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_NOPROGRESS, false));
|
||||||
// if it's a required update set the bandwidth limit to 0 (unlimited)
|
// if it's a required update set the bandwidth limit to 0 (unlimited)
|
||||||
curl_off_t limit = mDownloadData["required"].asBoolean() ? 0 : mBandwidthLimit;
|
curl_off_t limit = mDownloadData["required"].asBoolean() ? 0 : mBandwidthLimit;
|
||||||
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_MAX_RECV_SPEED_LARGE, limit));
|
throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_MAX_RECV_SPEED_LARGE, limit));
|
||||||
|
|
||||||
mDownloadPercent = 0;
|
mDownloadPercent = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -511,7 +507,7 @@ void LLUpdateDownloader::Implementation::resumeDownloading(size_t startByte)
|
||||||
{
|
{
|
||||||
throw DownloadError("cannot add Range header");
|
throw DownloadError("cannot add Range header");
|
||||||
}
|
}
|
||||||
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, mHeaderList));
|
throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HTTPHEADER, mHeaderList));
|
||||||
|
|
||||||
mDownloadStream.open(mDownloadData["path"].asString().c_str(),
|
mDownloadStream.open(mDownloadData["path"].asString().c_str(),
|
||||||
std::ios_base::out | std::ios_base::binary | std::ios_base::app);
|
std::ios_base::out | std::ios_base::binary | std::ios_base::app);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue