Shyotl's old llcurl
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -42,11 +42,8 @@
|
|||||||
#include "lliopipe.h"
|
#include "lliopipe.h"
|
||||||
#include "llsd.h"
|
#include "llsd.h"
|
||||||
#include "llthread.h"
|
#include "llthread.h"
|
||||||
#include "llqueuedthread.h"
|
|
||||||
#include "llframetimer.h"
|
|
||||||
|
|
||||||
class LLMutex;
|
class LLMutex;
|
||||||
class LLCurlThread;
|
|
||||||
|
|
||||||
// For whatever reason, this is not typedef'd in curl.h
|
// 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);
|
typedef size_t (*curl_header_callback)(void *ptr, size_t size, size_t nmemb, void *stream);
|
||||||
@@ -59,6 +56,8 @@ public:
|
|||||||
class Easy;
|
class Easy;
|
||||||
class Multi;
|
class Multi;
|
||||||
|
|
||||||
|
static bool sMultiThreaded;
|
||||||
|
|
||||||
struct TransferInfo
|
struct TransferInfo
|
||||||
{
|
{
|
||||||
TransferInfo() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {}
|
TransferInfo() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {}
|
||||||
@@ -125,7 +124,6 @@ public:
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public: /* but not really -- don't touch this */
|
public: /* but not really -- don't touch this */
|
||||||
U32 mReferenceCount;
|
U32 mReferenceCount;
|
||||||
|
|
||||||
@@ -163,7 +161,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @ brief Initialize LLCurl class
|
* @ brief Initialize LLCurl class
|
||||||
*/
|
*/
|
||||||
static void initClass(F32 curl_reuest_timeout = 120.f, S32 max_number_handles = 256, bool multi_threaded = false);
|
static void initClass(bool multi_threaded = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ brief Cleanup LLCurl class
|
* @ brief Cleanup LLCurl class
|
||||||
@@ -182,25 +180,10 @@ public:
|
|||||||
static void ssl_locking_callback(int mode, int type, const char *file, int line);
|
static void ssl_locking_callback(int mode, int type, const char *file, int line);
|
||||||
static unsigned long ssl_thread_id(void);
|
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) ;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::string sCAPath;
|
static std::string sCAPath;
|
||||||
static std::string sCAFile;
|
static std::string sCAFile;
|
||||||
static const unsigned int MAX_REDIRECTS;
|
static const unsigned int MAX_REDIRECTS;
|
||||||
static LLCurlThread* sCurlThread;
|
|
||||||
|
|
||||||
static LLMutex* sHandleMutexp ;
|
|
||||||
static S32 sTotalHandles ;
|
|
||||||
static S32 sMaxHandles;
|
|
||||||
public:
|
|
||||||
static bool sNotQuitting;
|
|
||||||
static F32 sCurlRequestTimeOut;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class LLCurl::Easy
|
class LLCurl::Easy
|
||||||
@@ -209,7 +192,7 @@ class LLCurl::Easy
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Easy();
|
Easy();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Easy* getEasy();
|
static Easy* getEasy();
|
||||||
~Easy();
|
~Easy();
|
||||||
@@ -218,41 +201,41 @@ public:
|
|||||||
|
|
||||||
void setErrorBuffer();
|
void setErrorBuffer();
|
||||||
void setCA();
|
void setCA();
|
||||||
|
|
||||||
void setopt(CURLoption option, S32 value);
|
void setopt(CURLoption option, S32 value);
|
||||||
// These assume the setter does not free value!
|
// These assume the setter does not free value!
|
||||||
void setopt(CURLoption option, void* value);
|
void setopt(CURLoption option, void* value);
|
||||||
void setopt(CURLoption option, char* value);
|
void setopt(CURLoption option, char* value);
|
||||||
// Copies the string so that it is guaranteed to stick around
|
// Copies the string so that it is gauranteed to stick around
|
||||||
void setoptString(CURLoption option, const std::string& value);
|
void setoptString(CURLoption option, const std::string& value);
|
||||||
|
|
||||||
void slist_append(const char* str);
|
void slist_append(const char* str);
|
||||||
void setHeaders();
|
void setHeaders();
|
||||||
|
|
||||||
U32 report(CURLcode);
|
U32 report(CURLcode);
|
||||||
void getTransferInfo(LLCurl::TransferInfo* info);
|
void getTransferInfo(LLCurl::TransferInfo* info);
|
||||||
|
|
||||||
void prepRequest(const std::string& url, const std::vector<std::string>& headers, LLCurl::ResponderPtr, S32 time_out = 0, bool post = false);
|
void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, S32 time_out = 0, bool post = false);
|
||||||
|
|
||||||
const char* getErrorBuffer();
|
const char* getErrorBuffer();
|
||||||
|
|
||||||
std::stringstream& getInput() { return mInput; }
|
std::stringstream& getInput() { return mInput; }
|
||||||
std::stringstream& getHeaderOutput() { return mHeaderOutput; }
|
std::stringstream& getHeaderOutput() { return mHeaderOutput; }
|
||||||
LLIOPipe::buffer_ptr_t& getOutput() { return mOutput; }
|
LLIOPipe::buffer_ptr_t& getOutput() { return mOutput; }
|
||||||
const LLChannelDescriptors& getChannels() { return mChannels; }
|
const LLChannelDescriptors& getChannels() { return mChannels; }
|
||||||
|
|
||||||
void resetState();
|
void resetState();
|
||||||
|
|
||||||
static CURL* allocEasyHandle();
|
static CURL* allocEasyHandle();
|
||||||
static void releaseEasyHandle(CURL* handle);
|
static void releaseEasyHandle(CURL* handle);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class LLCurl;
|
friend class LLCurl;
|
||||||
friend class LLCurl::Multi;
|
friend class LLCurl::Multi;
|
||||||
|
|
||||||
CURL* mCurlEasyHandle;
|
CURL* mCurlEasyHandle;
|
||||||
struct curl_slist* mHeaders;
|
struct curl_slist* mHeaders;
|
||||||
|
|
||||||
std::stringstream mRequest;
|
std::stringstream mRequest;
|
||||||
LLChannelDescriptors mChannels;
|
LLChannelDescriptors mChannels;
|
||||||
LLIOPipe::buffer_ptr_t mOutput;
|
LLIOPipe::buffer_ptr_t mOutput;
|
||||||
@@ -262,125 +245,70 @@ private:
|
|||||||
|
|
||||||
// Note: char*'s not strings since we pass pointers to curl
|
// Note: char*'s not strings since we pass pointers to curl
|
||||||
std::vector<char*> mStrings;
|
std::vector<char*> mStrings;
|
||||||
|
|
||||||
LLCurl::ResponderPtr mResponder;
|
ResponderPtr mResponder;
|
||||||
|
|
||||||
static std::set<CURL*> sFreeHandles;
|
static std::set<CURL*> sFreeHandles;
|
||||||
static std::set<CURL*> sActiveHandles;
|
static std::set<CURL*> sActiveHandles;
|
||||||
static LLMutex* sHandleMutexp ;
|
static LLMutex* sHandleMutex;
|
||||||
|
static LLMutex* sMultiMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LLCurl::Multi
|
class LLCurl::Multi : public LLThread
|
||||||
{
|
{
|
||||||
LOG_CLASS(Multi);
|
LOG_CLASS(Multi);
|
||||||
|
|
||||||
friend class LLCurlThread ;
|
|
||||||
|
|
||||||
private:
|
|
||||||
~Multi();
|
|
||||||
|
|
||||||
void markDead() ;
|
|
||||||
bool doPerform();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
STATE_READY=0,
|
PERFORM_STATE_READY=0,
|
||||||
STATE_PERFORMING=1,
|
PERFORM_STATE_PERFORMING=1,
|
||||||
STATE_COMPLETED=2
|
PERFORM_STATE_COMPLETED=2
|
||||||
} ePerformState;
|
} ePerformState;
|
||||||
|
|
||||||
Multi(F32 idle_time_out = 0.f);
|
Multi();
|
||||||
|
~Multi();
|
||||||
|
|
||||||
LLCurl::Easy* allocEasy();
|
Easy* allocEasy();
|
||||||
bool addEasy(LLCurl::Easy* easy);
|
bool addEasy(Easy* easy);
|
||||||
void removeEasy(LLCurl::Easy* easy);
|
|
||||||
|
|
||||||
void lock() ;
|
void removeEasy(Easy* easy);
|
||||||
void unlock() ;
|
|
||||||
|
|
||||||
void setState(ePerformState state) ;
|
|
||||||
ePerformState getState() ;
|
|
||||||
|
|
||||||
bool isCompleted() ;
|
|
||||||
bool isValid() {return mCurlMultiHandle != NULL && mValid;}
|
|
||||||
bool isDead() {return mDead;}
|
|
||||||
|
|
||||||
bool waitToComplete() ;
|
|
||||||
|
|
||||||
S32 process();
|
S32 process();
|
||||||
|
void perform();
|
||||||
|
void doPerform();
|
||||||
|
|
||||||
|
virtual void run();
|
||||||
|
|
||||||
CURLMsg* info_read(S32* msgs_in_queue);
|
CURLMsg* info_read(S32* msgs_in_queue);
|
||||||
|
|
||||||
S32 mQueued;
|
S32 mQueued;
|
||||||
S32 mErrorCount;
|
S32 mErrorCount;
|
||||||
|
|
||||||
|
S32 mPerformState;
|
||||||
|
|
||||||
|
LLCondition* mSignal;
|
||||||
|
bool mQuitting;
|
||||||
|
bool mThreaded;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void easyFree(LLCurl::Easy*);
|
void easyFree(Easy*);
|
||||||
void cleanup(bool deleted = false) ;
|
|
||||||
|
|
||||||
CURLM* mCurlMultiHandle;
|
CURLM* mCurlMultiHandle;
|
||||||
|
|
||||||
typedef std::set<LLCurl::Easy*> easy_active_list_t;
|
typedef std::set<Easy*> easy_active_list_t;
|
||||||
easy_active_list_t mEasyActiveList;
|
easy_active_list_t mEasyActiveList;
|
||||||
typedef std::map<CURL*, LLCurl::Easy*> easy_active_map_t;
|
typedef std::map<CURL*, Easy*> easy_active_map_t;
|
||||||
easy_active_map_t mEasyActiveMap;
|
easy_active_map_t mEasyActiveMap;
|
||||||
typedef std::set<LLCurl::Easy*> easy_free_list_t;
|
typedef std::set<Easy*> easy_free_list_t;
|
||||||
easy_free_list_t mEasyFreeList;
|
easy_free_list_t mEasyFreeList;
|
||||||
|
|
||||||
LLQueuedThread::handle_t mHandle ;
|
|
||||||
ePerformState mState;
|
|
||||||
|
|
||||||
BOOL mDead ;
|
|
||||||
BOOL mValid ;
|
|
||||||
LLMutex* mMutexp ;
|
|
||||||
LLMutex* mDeletionMutexp ;
|
|
||||||
LLMutex* mEasyMutexp ;
|
|
||||||
LLFrameTimer mIdleTimer ;
|
|
||||||
F32 mIdleTimeOut;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class LLCurlThread : public LLQueuedThread
|
namespace boost
|
||||||
{
|
{
|
||||||
public:
|
void intrusive_ptr_add_ref(LLCurl::Responder* p);
|
||||||
|
void intrusive_ptr_release(LLCurl::Responder* p);
|
||||||
class CurlRequest : public LLQueuedThread::QueuedRequest
|
};
|
||||||
{
|
|
||||||
protected:
|
|
||||||
virtual ~CurlRequest(); // use deleteRequest()
|
|
||||||
|
|
||||||
public:
|
|
||||||
CurlRequest(handle_t handle, LLCurl::Multi* multi, LLCurlThread* curl_thread);
|
|
||||||
|
|
||||||
/*virtual*/ bool processRequest();
|
|
||||||
/*virtual*/ void finishRequest(bool completed);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// input
|
|
||||||
LLCurl::Multi* mMulti;
|
|
||||||
LLCurlThread* mCurlThread;
|
|
||||||
};
|
|
||||||
friend class CurlRequest;
|
|
||||||
|
|
||||||
public:
|
|
||||||
LLCurlThread(bool threaded = true) ;
|
|
||||||
virtual ~LLCurlThread() ;
|
|
||||||
|
|
||||||
S32 update(F32 max_time_ms);
|
|
||||||
|
|
||||||
void addMulti(LLCurl::Multi* multi) ;
|
|
||||||
void killMulti(LLCurl::Multi* multi) ;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool doMultiPerform(LLCurl::Multi* multi) ;
|
|
||||||
void deleteMulti(LLCurl::Multi* multi) ;
|
|
||||||
void cleanupMulti(LLCurl::Multi* multi) ;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
void intrusive_ptr_add_ref(LLCurl::Responder* p);
|
|
||||||
void intrusive_ptr_release(LLCurl::Responder* p);
|
|
||||||
|
|
||||||
|
|
||||||
class LLCurlRequest
|
class LLCurlRequest
|
||||||
@@ -410,6 +338,7 @@ private:
|
|||||||
LLCurl::Multi* mActiveMulti;
|
LLCurl::Multi* mActiveMulti;
|
||||||
S32 mActiveRequestCount;
|
S32 mActiveRequestCount;
|
||||||
BOOL mProcessing;
|
BOOL mProcessing;
|
||||||
|
U32 mThreadID; // debug
|
||||||
};
|
};
|
||||||
|
|
||||||
class LLCurlEasyRequest
|
class LLCurlEasyRequest
|
||||||
@@ -427,11 +356,9 @@ public:
|
|||||||
void slist_append(const char* str);
|
void slist_append(const char* str);
|
||||||
void sendRequest(const std::string& url);
|
void sendRequest(const std::string& url);
|
||||||
void requestComplete();
|
void requestComplete();
|
||||||
|
void perform();
|
||||||
bool getResult(CURLcode* result, LLCurl::TransferInfo* info = NULL);
|
bool getResult(CURLcode* result, LLCurl::TransferInfo* info = NULL);
|
||||||
std::string getErrorString();
|
std::string getErrorString();
|
||||||
bool isCompleted() {return mMulti->isCompleted() ;}
|
|
||||||
bool wait() { return mMulti->waitToComplete(); }
|
|
||||||
bool isValid() {return mMulti && mMulti->isValid(); }
|
|
||||||
|
|
||||||
LLCurl::Easy* getEasy() const { return mEasy; }
|
LLCurl::Easy* getEasy() const { return mEasy; }
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "linden_common.h"
|
#include "linden_common.h"
|
||||||
#include <openssl/x509_vfy.h>
|
|
||||||
#include "llhttpclient.h"
|
#include "llhttpclient.h"
|
||||||
|
|
||||||
#include "llassetstorage.h"
|
#include "llassetstorage.h"
|
||||||
@@ -40,10 +40,8 @@
|
|||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
|
||||||
const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
|
const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
|
||||||
LLURLRequest::SSLCertVerifyCallback LLHTTPClient::mCertVerifyCallback = NULL;
|
LLURLRequest::SSLCertVerifyCallback LLHTTPClient::mCertVerifyCallback = NULL;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Responder class moved to LLCurl
|
// Responder class moved to LLCurl
|
||||||
@@ -160,7 +158,7 @@ namespace
|
|||||||
fstream.seekg(0, std::ios::end);
|
fstream.seekg(0, std::ios::end);
|
||||||
U32 fileSize = (U32)fstream.tellg();
|
U32 fileSize = (U32)fstream.tellg();
|
||||||
fstream.seekg(0, std::ios::beg);
|
fstream.seekg(0, std::ios::beg);
|
||||||
std::vector<char> fileBuffer(fileSize);
|
std::vector<char> fileBuffer(fileSize); //Mem leak fix'd
|
||||||
fstream.read(&fileBuffer[0], fileSize);
|
fstream.read(&fileBuffer[0], fileSize);
|
||||||
ostream.write(&fileBuffer[0], fileSize);
|
ostream.write(&fileBuffer[0], fileSize);
|
||||||
fstream.close();
|
fstream.close();
|
||||||
@@ -189,11 +187,9 @@ namespace
|
|||||||
|
|
||||||
LLVFile vfile(gVFS, mUUID, mAssetType, LLVFile::READ);
|
LLVFile vfile(gVFS, mUUID, mAssetType, LLVFile::READ);
|
||||||
S32 fileSize = vfile.getSize();
|
S32 fileSize = vfile.getSize();
|
||||||
U8* fileBuffer;
|
std::vector<U8> fileBuffer(fileSize);
|
||||||
fileBuffer = new U8 [fileSize];
|
vfile.read(&fileBuffer[0], fileSize);
|
||||||
vfile.read(fileBuffer, fileSize);
|
ostream.write((char*)&fileBuffer[0], fileSize);
|
||||||
ostream.write((char*)fileBuffer, fileSize);
|
|
||||||
delete [] fileBuffer;
|
|
||||||
eos = true;
|
eos = true;
|
||||||
return STATUS_DONE;
|
return STATUS_DONE;
|
||||||
}
|
}
|
||||||
@@ -202,7 +198,6 @@ namespace
|
|||||||
LLAssetType::EType mAssetType;
|
LLAssetType::EType mAssetType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
LLPumpIO* theClientPump = NULL;
|
LLPumpIO* theClientPump = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,8 +212,7 @@ static void request(
|
|||||||
Injector* body_injector,
|
Injector* body_injector,
|
||||||
LLCurl::ResponderPtr responder,
|
LLCurl::ResponderPtr responder,
|
||||||
const F32 timeout = HTTP_REQUEST_EXPIRY_SECS,
|
const F32 timeout = HTTP_REQUEST_EXPIRY_SECS,
|
||||||
const LLSD& headers = LLSD()
|
const LLSD& headers = LLSD())
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (!LLHTTPClient::hasPump())
|
if (!LLHTTPClient::hasPump())
|
||||||
{
|
{
|
||||||
@@ -228,26 +222,12 @@ static void request(
|
|||||||
LLPumpIO::chain_t chain;
|
LLPumpIO::chain_t chain;
|
||||||
|
|
||||||
LLURLRequest* req = new LLURLRequest(method, url);
|
LLURLRequest* req = new LLURLRequest(method, url);
|
||||||
if(!req->isValid())//failed
|
|
||||||
{
|
|
||||||
delete req ;
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
|
req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
|
||||||
|
|
||||||
|
// Insert custom headers is the caller sent any
|
||||||
lldebugs << LLURLRequest::actionAsVerb(method) << " " << url << " "
|
if (headers.isMap())
|
||||||
<< headers << llendl;
|
{
|
||||||
|
|
||||||
// Insert custom headers if the caller sent any
|
|
||||||
if (headers.isMap())
|
|
||||||
{
|
|
||||||
if (headers.has("Cookie"))
|
|
||||||
{
|
|
||||||
req->allowCookies();
|
|
||||||
}
|
|
||||||
|
|
||||||
LLSD::map_const_iterator iter = headers.beginMap();
|
LLSD::map_const_iterator iter = headers.beginMap();
|
||||||
LLSD::map_const_iterator end = headers.endMap();
|
LLSD::map_const_iterator end = headers.endMap();
|
||||||
|
|
||||||
@@ -429,16 +409,11 @@ static LLSD blocking_request(
|
|||||||
{
|
{
|
||||||
lldebugs << "blockingRequest of " << url << llendl;
|
lldebugs << "blockingRequest of " << url << llendl;
|
||||||
char curl_error_buffer[CURL_ERROR_SIZE] = "\0";
|
char curl_error_buffer[CURL_ERROR_SIZE] = "\0";
|
||||||
CURL* curlp = LLCurl::newEasyHandle();
|
CURL* curlp = curl_easy_init();
|
||||||
llassert_always(curlp != NULL) ;
|
|
||||||
|
|
||||||
LLHTTPBuffer http_buffer;
|
LLHTTPBuffer http_buffer;
|
||||||
std::string body_str;
|
std::string body_str;
|
||||||
|
|
||||||
// other request method checks root cert first, we skip?
|
// other request method checks root cert first, we skip?
|
||||||
|
|
||||||
// Apply configured proxy settings
|
|
||||||
LLProxy::getInstance()->applyProxySettings(curlp);
|
|
||||||
|
|
||||||
// * Set curl handle options
|
// * Set curl handle options
|
||||||
curl_easy_setopt(curlp, CURLOPT_NOSIGNAL, 1); // don't use SIGALRM for timeouts
|
curl_easy_setopt(curlp, CURLOPT_NOSIGNAL, 1); // don't use SIGALRM for timeouts
|
||||||
@@ -447,7 +422,7 @@ static LLSD blocking_request(
|
|||||||
curl_easy_setopt(curlp, CURLOPT_WRITEDATA, &http_buffer);
|
curl_easy_setopt(curlp, CURLOPT_WRITEDATA, &http_buffer);
|
||||||
curl_easy_setopt(curlp, CURLOPT_URL, url.c_str());
|
curl_easy_setopt(curlp, CURLOPT_URL, url.c_str());
|
||||||
curl_easy_setopt(curlp, CURLOPT_ERRORBUFFER, curl_error_buffer);
|
curl_easy_setopt(curlp, CURLOPT_ERRORBUFFER, curl_error_buffer);
|
||||||
|
|
||||||
// * Setup headers (don't forget to free them after the call!)
|
// * Setup headers (don't forget to free them after the call!)
|
||||||
curl_slist* headers_list = NULL;
|
curl_slist* headers_list = NULL;
|
||||||
if (headers.isMap())
|
if (headers.isMap())
|
||||||
@@ -525,7 +500,7 @@ static LLSD blocking_request(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// * Cleanup
|
// * Cleanup
|
||||||
LLCurl::deleteEasyHandle(curlp);
|
curl_easy_cleanup(curlp);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,8 +600,7 @@ bool LLHTTPClient::hasPump()
|
|||||||
return theClientPump != NULL;
|
return theClientPump != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
LLPumpIO &LLHTTPClient::getPump()
|
||||||
LLPumpIO& LLHTTPClient::getPump()
|
|
||||||
{
|
{
|
||||||
return *theClientPump;
|
return *theClientPump;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,10 +34,11 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <boost/intrusive_ptr.hpp>
|
#include <boost/intrusive_ptr.hpp>
|
||||||
#include "llurlrequest.h"
|
|
||||||
#include "llassettype.h"
|
#include "llassettype.h"
|
||||||
#include "llcurl.h"
|
#include "llcurl.h"
|
||||||
#include "lliopipe.h"
|
#include "lliopipe.h"
|
||||||
|
#include "llurlrequest.h"
|
||||||
|
|
||||||
extern const F32 HTTP_REQUEST_EXPIRY_SECS;
|
extern const F32 HTTP_REQUEST_EXPIRY_SECS;
|
||||||
|
|
||||||
@@ -55,7 +56,6 @@ public:
|
|||||||
typedef LLCurl::Responder Responder;
|
typedef LLCurl::Responder Responder;
|
||||||
typedef LLCurl::ResponderPtr ResponderPtr;
|
typedef LLCurl::ResponderPtr ResponderPtr;
|
||||||
|
|
||||||
|
|
||||||
/** @name non-blocking API */
|
/** @name non-blocking API */
|
||||||
//@{
|
//@{
|
||||||
static void head(
|
static void head(
|
||||||
@@ -155,7 +155,7 @@ public:
|
|||||||
///< Hippo special
|
///< Hippo special
|
||||||
|
|
||||||
static void setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback);
|
static void setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback);
|
||||||
static LLURLRequest::SSLCertVerifyCallback getCertVerifyCallback() { return mCertVerifyCallback; }
|
static LLURLRequest::SSLCertVerifyCallback getCertVerifyCallback() { return mCertVerifyCallback; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static LLURLRequest::SSLCertVerifyCallback mCertVerifyCallback;
|
static LLURLRequest::SSLCertVerifyCallback mCertVerifyCallback;
|
||||||
|
|||||||
@@ -32,17 +32,17 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <openssl/x509_vfy.h>
|
#include <openssl/x509_vfy.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
#include "llcurl.h"
|
#include "llcurl.h"
|
||||||
#include "llfasttimer.h"
|
|
||||||
#include "llioutil.h"
|
#include "llioutil.h"
|
||||||
#include "llmemtype.h"
|
#include "llmemtype.h"
|
||||||
#include "llproxy.h"
|
|
||||||
#include "llpumpio.h"
|
#include "llpumpio.h"
|
||||||
#include "llsd.h"
|
#include "llsd.h"
|
||||||
#include "llstring.h"
|
#include "llstring.h"
|
||||||
#include "apr_env.h"
|
#include "apr_env.h"
|
||||||
#include "llapr.h"
|
#include "llapr.h"
|
||||||
#include "llscopedvolatileaprpool.h"
|
#include "llscopedvolatileaprpool.h"
|
||||||
|
#include "llfasttimer.h"
|
||||||
static const U32 HTTP_STATUS_PIPE_ERROR = 499;
|
static const U32 HTTP_STATUS_PIPE_ERROR = 499;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,7 +66,7 @@ public:
|
|||||||
~LLURLRequestDetail();
|
~LLURLRequestDetail();
|
||||||
std::string mURL;
|
std::string mURL;
|
||||||
LLCurlEasyRequest* mCurlRequest;
|
LLCurlEasyRequest* mCurlRequest;
|
||||||
LLIOPipe::buffer_ptr_t mResponseBuffer;
|
LLBufferArray* mResponseBuffer;
|
||||||
LLChannelDescriptors mChannels;
|
LLChannelDescriptors mChannels;
|
||||||
U8* mLastRead;
|
U8* mLastRead;
|
||||||
U32 mBodyLimit;
|
U32 mBodyLimit;
|
||||||
@@ -77,26 +77,21 @@ public:
|
|||||||
|
|
||||||
LLURLRequestDetail::LLURLRequestDetail() :
|
LLURLRequestDetail::LLURLRequestDetail() :
|
||||||
mCurlRequest(NULL),
|
mCurlRequest(NULL),
|
||||||
|
mResponseBuffer(NULL),
|
||||||
mLastRead(NULL),
|
mLastRead(NULL),
|
||||||
mBodyLimit(0),
|
mBodyLimit(0),
|
||||||
mByteAccumulator(0),
|
mByteAccumulator(0),
|
||||||
mIsBodyLimitSet(false),
|
mIsBodyLimitSet(false)
|
||||||
mSSLVerifyCallback(NULL)
|
|
||||||
{
|
{
|
||||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||||
mCurlRequest = new LLCurlEasyRequest();
|
mCurlRequest = new LLCurlEasyRequest();
|
||||||
|
|
||||||
if(!mCurlRequest->isValid()) //failed.
|
|
||||||
{
|
|
||||||
delete mCurlRequest ;
|
|
||||||
mCurlRequest = NULL ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LLURLRequestDetail::~LLURLRequestDetail()
|
LLURLRequestDetail::~LLURLRequestDetail()
|
||||||
{
|
{
|
||||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||||
delete mCurlRequest;
|
delete mCurlRequest;
|
||||||
|
mResponseBuffer = NULL;
|
||||||
mLastRead = NULL;
|
mLastRead = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +100,7 @@ void LLURLRequest::setSSLVerifyCallback(SSLCertVerifyCallback callback, void *pa
|
|||||||
mDetail->mSSLVerifyCallback = callback;
|
mDetail->mSSLVerifyCallback = callback;
|
||||||
mDetail->mCurlRequest->setSSLCtxCallback(LLURLRequest::_sslCtxCallback, (void *)this);
|
mDetail->mCurlRequest->setSSLCtxCallback(LLURLRequest::_sslCtxCallback, (void *)this);
|
||||||
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, true);
|
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, true);
|
||||||
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, 2);
|
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -114,7 +109,7 @@ void LLURLRequest::setSSLVerifyCallback(SSLCertVerifyCallback callback, void *pa
|
|||||||
// used to configure the context for custom cert validation
|
// used to configure the context for custom cert validation
|
||||||
|
|
||||||
CURLcode LLURLRequest::_sslCtxCallback(CURL * curl, void *sslctx, void *param)
|
CURLcode LLURLRequest::_sslCtxCallback(CURL * curl, void *sslctx, void *param)
|
||||||
{
|
{
|
||||||
LLURLRequest *req = (LLURLRequest *)param;
|
LLURLRequest *req = (LLURLRequest *)param;
|
||||||
if(req == NULL || req->mDetail->mSSLVerifyCallback == NULL)
|
if(req == NULL || req->mDetail->mSSLVerifyCallback == NULL)
|
||||||
{
|
{
|
||||||
@@ -128,7 +123,6 @@ CURLcode LLURLRequest::_sslCtxCallback(CURL * curl, void *sslctx, void *param)
|
|||||||
SSL_CTX_set_cert_verify_callback(ctx, req->mDetail->mSSLVerifyCallback, (void *)req);
|
SSL_CTX_set_cert_verify_callback(ctx, req->mDetail->mSSLVerifyCallback, (void *)req);
|
||||||
// the calls are void
|
// the calls are void
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -189,7 +183,6 @@ std::string LLURLRequest::getURL() const
|
|||||||
{
|
{
|
||||||
return mDetail->mURL;
|
return mDetail->mURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLURLRequest::addHeader(const char* header)
|
void LLURLRequest::addHeader(const char* header)
|
||||||
{
|
{
|
||||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||||
@@ -240,9 +233,9 @@ void LLURLRequest::useProxy(bool use_proxy)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = \"" << env_proxy << "\"" << llendl;
|
LL_DEBUGS("Proxy") << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (!env_proxy.empty() ? env_proxy : "(null)") << LL_ENDL;
|
||||||
|
|
||||||
if (use_proxy)
|
if (use_proxy && !env_proxy.empty())
|
||||||
{
|
{
|
||||||
mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy);
|
mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy);
|
||||||
}
|
}
|
||||||
@@ -262,24 +255,12 @@ void LLURLRequest::allowCookies()
|
|||||||
mDetail->mCurlRequest->setoptString(CURLOPT_COOKIEFILE, "");
|
mDetail->mCurlRequest->setoptString(CURLOPT_COOKIEFILE, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
//virtual
|
|
||||||
bool LLURLRequest::isValid()
|
|
||||||
{
|
|
||||||
return mDetail->mCurlRequest && mDetail->mCurlRequest->isValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
LLIOPipe::EStatus LLURLRequest::handleError(
|
LLIOPipe::EStatus LLURLRequest::handleError(
|
||||||
LLIOPipe::EStatus status,
|
LLIOPipe::EStatus status,
|
||||||
LLPumpIO* pump)
|
LLPumpIO* pump)
|
||||||
{
|
{
|
||||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||||
|
|
||||||
if(!isValid())
|
|
||||||
{
|
|
||||||
return STATUS_EXPIRED ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mCompletionCallback && pump)
|
if(mCompletionCallback && pump)
|
||||||
{
|
{
|
||||||
LLURLRequestComplete* complete = NULL;
|
LLURLRequestComplete* complete = NULL;
|
||||||
@@ -309,7 +290,8 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
|
|||||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||||
//llinfos << "LLURLRequest::process_impl()" << llendl;
|
//llinfos << "LLURLRequest::process_impl()" << llendl;
|
||||||
if (!buffer) return STATUS_ERROR;
|
if (!buffer) return STATUS_ERROR;
|
||||||
|
if (!mDetail) return STATUS_ERROR; //Seems to happen on occasion. Need to hunt down why.
|
||||||
|
|
||||||
// we're still waiting or prcessing, check how many
|
// we're still waiting or prcessing, check how many
|
||||||
// bytes we have accumulated.
|
// bytes we have accumulated.
|
||||||
const S32 MIN_ACCUMULATION = 100000;
|
const S32 MIN_ACCUMULATION = 100000;
|
||||||
@@ -348,7 +330,7 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
|
|||||||
|
|
||||||
// *FIX: bit of a hack, but it should work. The configure and
|
// *FIX: bit of a hack, but it should work. The configure and
|
||||||
// callback method expect this information to be ready.
|
// callback method expect this information to be ready.
|
||||||
mDetail->mResponseBuffer = buffer;
|
mDetail->mResponseBuffer = buffer.get();
|
||||||
mDetail->mChannels = channels;
|
mDetail->mChannels = channels;
|
||||||
if(!configure())
|
if(!configure())
|
||||||
{
|
{
|
||||||
@@ -367,10 +349,7 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
|
|||||||
static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform");
|
static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform");
|
||||||
{
|
{
|
||||||
LLFastTimer t(FTM_URL_PERFORM);
|
LLFastTimer t(FTM_URL_PERFORM);
|
||||||
if(!mDetail->mCurlRequest->wait())
|
mDetail->mCurlRequest->perform();
|
||||||
{
|
|
||||||
return status ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
@@ -465,12 +444,6 @@ void LLURLRequest::initialize()
|
|||||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||||
mState = STATE_INITIALIZED;
|
mState = STATE_INITIALIZED;
|
||||||
mDetail = new LLURLRequestDetail;
|
mDetail = new LLURLRequestDetail;
|
||||||
|
|
||||||
if(!isValid())
|
|
||||||
{
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
|
mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
|
||||||
mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this);
|
mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this);
|
||||||
mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this);
|
mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this);
|
||||||
|
|||||||
@@ -40,7 +40,6 @@
|
|||||||
#include "llerror.h"
|
#include "llerror.h"
|
||||||
#include "llcurl.h"
|
#include "llcurl.h"
|
||||||
|
|
||||||
|
|
||||||
extern const std::string CONTEXT_REQUEST;
|
extern const std::string CONTEXT_REQUEST;
|
||||||
extern const std::string CONTEXT_DEST_URI_SD_LABEL;
|
extern const std::string CONTEXT_DEST_URI_SD_LABEL;
|
||||||
extern const std::string CONTEXT_RESPONSE;
|
extern const std::string CONTEXT_RESPONSE;
|
||||||
@@ -145,7 +144,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setSSLVerifyCallback(SSLCertVerifyCallback callback, void * param);
|
void setSSLVerifyCallback(SSLCertVerifyCallback callback, void * param);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return at most size bytes of body.
|
* @brief Return at most size bytes of body.
|
||||||
*
|
*
|
||||||
@@ -190,14 +188,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
void allowCookies();
|
void allowCookies();
|
||||||
|
|
||||||
/*virtual*/ bool isValid() ;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Give this pipe a chance to handle a generated error
|
* @brief Give this pipe a chance to handle a generated error
|
||||||
*/
|
*/
|
||||||
virtual EStatus handleError(EStatus status, LLPumpIO* pump);
|
virtual EStatus handleError(EStatus status, LLPumpIO* pump);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@@ -223,11 +218,11 @@ protected:
|
|||||||
ERequestAction mAction;
|
ERequestAction mAction;
|
||||||
LLURLRequestDetail* mDetail;
|
LLURLRequestDetail* mDetail;
|
||||||
LLIOPipe::ptr_t mCompletionCallback;
|
LLIOPipe::ptr_t mCompletionCallback;
|
||||||
S32 mRequestTransferedBytes;
|
S32 mRequestTransferedBytes;
|
||||||
S32 mResponseTransferedBytes;
|
S32 mResponseTransferedBytes;
|
||||||
|
|
||||||
static CURLcode _sslCtxCallback(CURL * curl, void *sslctx, void *param);
|
static CURLcode _sslCtxCallback(CURL * curl, void *sslctx, void *param);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the object. Called during construction.
|
* @brief Initialize the object. Called during construction.
|
||||||
|
|||||||
@@ -637,9 +637,8 @@ bool LLAppViewer::init()
|
|||||||
mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling"));
|
mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling"));
|
||||||
// *NOTE:Mani - LLCurl::initClass is not thread safe.
|
// *NOTE:Mani - LLCurl::initClass is not thread safe.
|
||||||
// Called before threads are created.
|
// Called before threads are created.
|
||||||
LLCurl::initClass(gSavedSettings.getF32("CurlRequestTimeOut"),
|
LLCurl::initClass(gSavedSettings.getF32("CurlRequestTimeOut"));
|
||||||
gSavedSettings.getS32("CurlMaximumNumberOfHandles"),
|
|
||||||
gSavedSettings.getBOOL("CurlUseMultipleThreads"));
|
|
||||||
LL_INFOS("InitInfo") << "LLCurl initialized." << LL_ENDL ;
|
LL_INFOS("InitInfo") << "LLCurl initialized." << LL_ENDL ;
|
||||||
|
|
||||||
initThreads();
|
initThreads();
|
||||||
|
|||||||
@@ -227,16 +227,6 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
|
|||||||
mCurlRequest = new LLCurlEasyRequest();
|
mCurlRequest = new LLCurlEasyRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!mCurlRequest->isValid())
|
|
||||||
{
|
|
||||||
llwarns << "mCurlRequest is invalid." << llendl ;
|
|
||||||
|
|
||||||
delete mCurlRequest ;
|
|
||||||
mCurlRequest = NULL ;
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LLProxy::getInstance()->applyProxySettings(mCurlRequest);
|
LLProxy::getInstance()->applyProxySettings(mCurlRequest);
|
||||||
|
|
||||||
// mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // usefull for debugging
|
// mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // usefull for debugging
|
||||||
@@ -292,7 +282,7 @@ LLXMLRPCTransaction::Impl::~Impl()
|
|||||||
|
|
||||||
bool LLXMLRPCTransaction::Impl::process()
|
bool LLXMLRPCTransaction::Impl::process()
|
||||||
{
|
{
|
||||||
if(!mCurlRequest || !mCurlRequest->isValid())
|
if(!mCurlRequest || !mCurlRequest->getEasy())
|
||||||
{
|
{
|
||||||
llwarns << "transaction failed." << llendl ;
|
llwarns << "transaction failed." << llendl ;
|
||||||
|
|
||||||
@@ -326,7 +316,7 @@ bool LLXMLRPCTransaction::Impl::process()
|
|||||||
//const F32 MAX_PROCESSING_TIME = 0.05f;
|
//const F32 MAX_PROCESSING_TIME = 0.05f;
|
||||||
//LLTimer timer;
|
//LLTimer timer;
|
||||||
|
|
||||||
mCurlRequest->wait();
|
mCurlRequest->perform();
|
||||||
|
|
||||||
/*while (mCurlRequest->perform() > 0)
|
/*while (mCurlRequest->perform() > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user