From cd17687f01420952712a500107e0f93e7ab8d5f8 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Fri, 15 Aug 2008 23:45:34 -0500 Subject: Second Life viewer sources 1.19.1.0 --- linden/indra/llmessage/llurlrequest.cpp | 209 +++++++------------------------- 1 file changed, 47 insertions(+), 162 deletions(-) (limited to 'linden/indra/llmessage/llurlrequest.cpp') diff --git a/linden/indra/llmessage/llurlrequest.cpp b/linden/indra/llmessage/llurlrequest.cpp index 6c826cd..eabd951 100644 --- a/linden/indra/llmessage/llurlrequest.cpp +++ b/linden/indra/llmessage/llurlrequest.cpp @@ -37,6 +37,7 @@ #include #include +#include "llcurl.h" #include "llioutil.h" #include "llmemtype.h" #include "llpumpio.h" @@ -52,8 +53,7 @@ static const U32 HTTP_STATUS_PIPE_ERROR = 499; const std::string CONTEXT_DEST_URI_SD_LABEL("dest_uri"); -static -size_t headerCallback(void* data, size_t size, size_t nmemb, void* user); +static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user); /** * class LLURLRequestDetail @@ -63,12 +63,8 @@ class LLURLRequestDetail public: LLURLRequestDetail(); ~LLURLRequestDetail(); - CURLM* mCurlMulti; - CURL* mCurl; - struct curl_slist* mHeaders; - char* mURL; - char mCurlErrorBuf[CURL_ERROR_SIZE + 1]; /* Flawfinder: ignore */ - bool mNeedToRemoveEasyHandle; + std::string mURL; + LLCurlEasyRequest* mCurlRequest; LLBufferArray* mResponseBuffer; LLChannelDescriptors mChannels; U8* mLastRead; @@ -77,11 +73,7 @@ public: }; LLURLRequestDetail::LLURLRequestDetail() : - mCurlMulti(NULL), - mCurl(NULL), - mHeaders(NULL), - mURL(NULL), - mNeedToRemoveEasyHandle(false), + mCurlRequest(NULL), mResponseBuffer(NULL), mLastRead(NULL), mBodyLimit(0), @@ -89,34 +81,13 @@ LLURLRequestDetail::LLURLRequestDetail() : { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); - mCurlErrorBuf[0] = '\0'; + mCurlRequest = new LLCurlEasyRequest(); } LLURLRequestDetail::~LLURLRequestDetail() { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); - if(mCurl) - { - if(mNeedToRemoveEasyHandle && mCurlMulti) - { - curl_multi_remove_handle(mCurlMulti, mCurl); - mNeedToRemoveEasyHandle = false; - } - curl_easy_cleanup(mCurl); - mCurl = NULL; - } - if(mCurlMulti) - { - curl_multi_cleanup(mCurlMulti); - mCurlMulti = NULL; - } - if(mHeaders) - { - curl_slist_free_all(mHeaders); - mHeaders = NULL; - } - delete[] mURL; - mURL = NULL; + delete mCurlRequest; mResponseBuffer = NULL; mLastRead = NULL; } @@ -126,9 +97,6 @@ LLURLRequestDetail::~LLURLRequestDetail() * class LLURLRequest */ -static std::string sCAFile(""); -static std::string sCAPath(""); - LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action) : mAction(action) { @@ -155,31 +123,13 @@ LLURLRequest::~LLURLRequest() void LLURLRequest::setURL(const std::string& url) { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); - if(mDetail->mURL) - { - // *NOTE: if any calls to set the url have been made to curl, - // this will probably lead to a crash. - delete[] mDetail->mURL; - mDetail->mURL = NULL; - } - if(!url.empty()) - { - mDetail->mURL = new char[url.size() + 1]; - url.copy(mDetail->mURL, url.size()); - mDetail->mURL[url.size()] = '\0'; - } + mDetail->mURL = url; } void LLURLRequest::addHeader(const char* header) { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); - mDetail->mHeaders = curl_slist_append(mDetail->mHeaders, header); -} - -void LLURLRequest::requestEncoding(const char* encoding) -{ - LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); - curl_easy_setopt(mDetail->mCurl, CURLOPT_ENCODING, encoding); + mDetail->mCurlRequest->slist_append(header); } void LLURLRequest::setBodyLimit(U32 size) @@ -188,22 +138,17 @@ void LLURLRequest::setBodyLimit(U32 size) mDetail->mIsBodyLimitSet = true; } -void LLURLRequest::checkRootCertificate(bool check, const char* caBundle) +void LLURLRequest::checkRootCertificate(bool check) { - curl_easy_setopt(mDetail->mCurl, CURLOPT_SSL_VERIFYPEER, (check? TRUE : FALSE)); - if (caBundle) - { - curl_easy_setopt(mDetail->mCurl, CURLOPT_CAINFO, caBundle); - } + mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, (check? TRUE : FALSE)); + mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, ""); } void LLURLRequest::setCallback(LLURLRequestComplete* callback) { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); mCompletionCallback = callback; - - curl_easy_setopt(mDetail->mCurl, CURLOPT_HEADERFUNCTION, &headerCallback); - curl_easy_setopt(mDetail->mCurl, CURLOPT_WRITEHEADER, callback); + mDetail->mCurlRequest->setHeaderCallback(&headerCallback, (void*)callback); } // Added to mitigate the effect of libcurl looking @@ -235,15 +180,15 @@ void LLURLRequest::useProxy(bool use_proxy) } - lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << env_proxy << llendl; + lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl; if (env_proxy && use_proxy) { - curl_easy_setopt(mDetail->mCurl, CURLOPT_PROXY, env_proxy); + mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy); } else { - curl_easy_setopt(mDetail->mCurl, CURLOPT_PROXY, ""); + mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, ""); } } @@ -309,27 +254,20 @@ LLIOPipe::EStatus LLURLRequest::process_impl( case STATE_PROCESSING_RESPONSE: { PUMP_DEBUG; - const S32 MAX_CALLS = 5; - S32 count = MAX_CALLS; - CURLMcode code; LLIOPipe::EStatus status = STATUS_BREAK; - S32 queue; - do - { - LLFastTimer t2(LLFastTimer::FTM_CURL); - code = curl_multi_perform(mDetail->mCurlMulti, &queue); - }while((CURLM_CALL_MULTI_PERFORM == code) && (queue > 0) && count--); - CURLMsg* curl_msg; - do + mDetail->mCurlRequest->perform(); + while(1) { - curl_msg = curl_multi_info_read(mDetail->mCurlMulti, &queue); - if(curl_msg && (curl_msg->msg == CURLMSG_DONE)) + CURLcode result; + bool newmsg = mDetail->mCurlRequest->getResult(&result); + if (!newmsg) { - mState = STATE_HAVE_RESPONSE; + break; + } - CURLcode result = curl_msg->data.result; - switch(result) - { + mState = STATE_HAVE_RESPONSE; + switch(result) + { case CURLE_OK: case CURLE_WRITE_ERROR: // NB: The error indication means that we stopped the @@ -352,31 +290,21 @@ LLIOPipe::EStatus LLURLRequest::process_impl( mCompletionCallback = NULL; } break; + case CURLE_FAILED_INIT: case CURLE_COULDNT_CONNECT: status = STATUS_NO_CONNECTION; break; default: - llwarns << "URLRequest Error: " << curl_msg->data.result + llwarns << "URLRequest Error: " << result << ", " -#if LL_DARWIN - // curl_easy_strerror was added in libcurl 7.12.0. Unfortunately, the version in the Mac OS X 10.3.9 SDK is 7.10.2... - // There's a problem with the custom curl headers in our build that keeps me from #ifdefing this on the libcurl version number - // (the correct check would be #if LIBCURL_VERSION_NUM >= 0x070c00). We'll fix the header problem soon, but for now - // just punt and print the numeric error code on the Mac. - << curl_msg->data.result -#else // LL_DARWIN - << curl_easy_strerror(curl_msg->data.result) -#endif // LL_DARWIN + << LLCurl::strerror(result) << ", " - << (mDetail->mURL ? mDetail->mURL : "") + << (mDetail->mURL.empty() ? "" : mDetail->mURL) << llendl; status = STATUS_ERROR; break; - } - curl_multi_remove_handle(mDetail->mCurlMulti, mDetail->mCurl); - mDetail->mNeedToRemoveEasyHandle = false; } - }while(curl_msg && (queue > 0)); + } return status; } case STATE_HAVE_RESPONSE: @@ -397,26 +325,9 @@ void LLURLRequest::initialize() LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); mState = STATE_INITIALIZED; mDetail = new LLURLRequestDetail; - mDetail->mCurl = curl_easy_init(); - mDetail->mCurlMulti = curl_multi_init(); - curl_easy_setopt(mDetail->mCurl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(mDetail->mCurl, CURLOPT_WRITEFUNCTION, &downCallback); - curl_easy_setopt(mDetail->mCurl, CURLOPT_WRITEDATA, this); - curl_easy_setopt(mDetail->mCurl, CURLOPT_READFUNCTION, &upCallback); - curl_easy_setopt(mDetail->mCurl, CURLOPT_READDATA, this); - curl_easy_setopt( - mDetail->mCurl, - CURLOPT_ERRORBUFFER, - mDetail->mCurlErrorBuf); - - if(sCAPath != std::string("")) - { - curl_easy_setopt(mDetail->mCurl, CURLOPT_CAPATH, sCAPath.c_str()); - } - if(sCAFile != std::string("")) - { - curl_easy_setopt(mDetail->mCurl, CURLOPT_CAINFO, sCAFile.c_str()); - } + mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1); + mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this); + mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this); } bool LLURLRequest::configure() @@ -429,15 +340,14 @@ bool LLURLRequest::configure() switch(mAction) { case HTTP_HEAD: - curl_easy_setopt(mDetail->mCurl, CURLOPT_HEADER, 1); - curl_easy_setopt(mDetail->mCurl, CURLOPT_NOBODY, 1); - curl_easy_setopt(mDetail->mCurl, CURLOPT_FOLLOWLOCATION, 1); + mDetail->mCurlRequest->setopt(CURLOPT_HEADER, 1); + mDetail->mCurlRequest->setopt(CURLOPT_NOBODY, 1); + mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1); rv = true; break; - case HTTP_GET: - curl_easy_setopt(mDetail->mCurl, CURLOPT_HTTPGET, 1); - curl_easy_setopt(mDetail->mCurl, CURLOPT_FOLLOWLOCATION, 1); + mDetail->mCurlRequest->setopt(CURLOPT_HTTPGET, 1); + mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1); rv = true; break; @@ -446,8 +356,8 @@ bool LLURLRequest::configure() // to turning this on, and I am not too sure what it means. addHeader("Expect:"); - curl_easy_setopt(mDetail->mCurl, CURLOPT_UPLOAD, 1); - curl_easy_setopt(mDetail->mCurl, CURLOPT_INFILESIZE, bytes); + mDetail->mCurlRequest->setopt(CURLOPT_UPLOAD, 1); + mDetail->mCurlRequest->setopt(CURLOPT_INFILESIZE, bytes); rv = true; break; @@ -461,15 +371,13 @@ bool LLURLRequest::configure() addHeader("Content-Type:"); // Set the handle for an http post - curl_easy_setopt(mDetail->mCurl, CURLOPT_POST, 1); - curl_easy_setopt(mDetail->mCurl, CURLOPT_POSTFIELDS, NULL); - curl_easy_setopt(mDetail->mCurl, CURLOPT_POSTFIELDSIZE, bytes); + mDetail->mCurlRequest->setPost(NULL, bytes); rv = true; break; case HTTP_DELETE: // Set the handle for an http post - curl_easy_setopt(mDetail->mCurl, CURLOPT_CUSTOMREQUEST, "DELETE"); + mDetail->mCurlRequest->setoptString(CURLOPT_CUSTOMREQUEST, "DELETE"); rv = true; break; @@ -479,24 +387,14 @@ bool LLURLRequest::configure() } if(rv) { - if(mDetail->mHeaders) - { - curl_easy_setopt( - mDetail->mCurl, - CURLOPT_HTTPHEADER, - mDetail->mHeaders); - } - curl_easy_setopt(mDetail->mCurl, CURLOPT_URL, mDetail->mURL); - lldebugs << "URL: " << mDetail->mURL << llendl; - curl_multi_add_handle(mDetail->mCurlMulti, mDetail->mCurl); - mDetail->mNeedToRemoveEasyHandle = true; + mDetail->mCurlRequest->sendRequest(mDetail->mURL); } return rv; } // static size_t LLURLRequest::downCallback( - void* data, + char* data, size_t size, size_t nmemb, void* user) @@ -530,7 +428,7 @@ size_t LLURLRequest::downCallback( // static size_t LLURLRequest::upCallback( - void* data, + char* data, size_t size, size_t nmemb, void* user) @@ -550,8 +448,7 @@ size_t LLURLRequest::upCallback( return bytes; } -static -size_t headerCallback(void* data, size_t size, size_t nmemb, void* user) +static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user) { const char* headerLine = (const char*)data; size_t headerLen = size * nmemb; @@ -607,18 +504,6 @@ size_t headerCallback(void* data, size_t size, size_t nmemb, void* user) return headerLen; } -//static -void LLURLRequest::setCertificateAuthorityFile(const std::string& file_name) -{ - sCAFile = file_name; -} - -//static -void LLURLRequest::setCertificateAuthorityPath(const std::string& path) -{ - sCAPath = path; -} - /** * LLContextURLExtractor */ -- cgit v1.1