diff options
Diffstat (limited to 'indra/llcorehttp')
31 files changed, 1030 insertions, 458 deletions
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 9631e960c5..4aecf61bd7 100755 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -5,7 +5,6 @@ project(llcorehttp) include(00-Common) include(GoogleMock) include(CURL) -include(CARes) include(OpenSSL) include(ZLIB) include(LLCoreHttp) @@ -26,6 +25,7 @@ set(llcorehttp_SOURCE_FILES bufferarray.cpp bufferstream.cpp httpcommon.cpp + llhttpconstants.cpp httpheaders.cpp httpoptions.cpp httprequest.cpp @@ -51,6 +51,7 @@ set(llcorehttp_HEADER_FILES bufferarray.h bufferstream.h httpcommon.h + llhttpconstants.h httphandler.h httpheaders.h httpoptions.h @@ -89,7 +90,6 @@ add_library (llcorehttp ${llcorehttp_SOURCE_FILES}) target_link_libraries( llcorehttp ${CURL_LIBRARIES} - ${CARES_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} ${BOOST_THREAD_LIBRARY} @@ -127,7 +127,6 @@ if (LL_TESTS) ${LLCOMMON_LIBRARIES} ${GOOGLEMOCK_LIBRARIES} ${CURL_LIBRARIES} - ${CARES_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} ${BOOST_SYSTEM_LIBRARY} @@ -159,7 +158,6 @@ if (LL_TESTS) ${LLCOMMON_LIBRARIES} ${GOOGLEMOCK_LIBRARIES} ${CURL_LIBRARIES} - ${CARES_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} ${BOOST_SYSTEM_LIBRARY} diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 17e997688f..4ebe14e740 100755 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -71,11 +71,10 @@ void HttpLibcurl::shutdown() { while (! mActiveOps.empty()) { - HttpOpRequest * op(* mActiveOps.begin()); + HttpOpRequest::ptr_t op(* mActiveOps.begin()); mActiveOps.erase(mActiveOps.begin()); cancelRequest(op); - op->release(); } if (mMultiHandles) @@ -204,7 +203,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport() // Caller has provided us with a ref count on op. -void HttpLibcurl::addOp(HttpOpRequest * op) +void HttpLibcurl::addOp(const HttpOpRequest::ptr_t &op) { llassert_always(op->mReqPolicy < mPolicyCount); llassert_always(mMultiHandles[op->mReqPolicy] != NULL); @@ -235,21 +234,21 @@ void HttpLibcurl::addOp(HttpOpRequest * op) HttpPolicy & policy(mService->getPolicy()); LL_INFOS(LOG_CORE) << "TRACE, ToActiveQueue, Handle: " - << static_cast<HttpHandle>(op) - << ", Actives: " << mActiveOps.size() - << ", Readies: " << policy.getReadyCount(op->mReqPolicy) - << LL_ENDL; + << op->getHandle() + << ", Actives: " << mActiveOps.size() + << ", Readies: " << policy.getReadyCount(op->mReqPolicy) + << LL_ENDL; } } // Implements the transport part of any cancel operation. // See if the handle is an active operation and if so, -// use the more complicated transport-based cancelation +// use the more complicated transport-based cancellation // method to kill the request. bool HttpLibcurl::cancel(HttpHandle handle) { - HttpOpRequest * op(static_cast<HttpOpRequest *>(handle)); + HttpOpRequest::ptr_t op = HttpOpRequest::fromHandle<HttpOpRequest>(handle); active_set_t::iterator it(mActiveOps.find(op)); if (mActiveOps.end() == it) { @@ -262,7 +261,6 @@ bool HttpLibcurl::cancel(HttpHandle handle) // Drop references mActiveOps.erase(it); --mActiveHandles[op->mReqPolicy]; - op->release(); return true; } @@ -273,7 +271,7 @@ bool HttpLibcurl::cancel(HttpHandle handle) // remove the op from the active list and release the op *after* // calling this method. It must be called first to deliver the // op to the reply queue with refcount intact. -void HttpLibcurl::cancelRequest(HttpOpRequest * op) +void HttpLibcurl::cancelRequest(const HttpOpRequest::ptr_t &op) { // Deactivate request op->mCurlActive = false; @@ -287,7 +285,7 @@ void HttpLibcurl::cancelRequest(HttpOpRequest * op) if (op->mTracing > HTTP_TRACE_OFF) { LL_INFOS(LOG_CORE) << "TRACE, RequestCanceled, Handle: " - << static_cast<HttpHandle>(op) + << op->getHandle() << ", Status: " << op->mStatus.toTerseString() << LL_ENDL; } @@ -301,8 +299,11 @@ void HttpLibcurl::cancelRequest(HttpOpRequest * op) // Keep them synchronized as necessary. bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status) { - HttpOpRequest * op(NULL); - curl_easy_getinfo(handle, CURLINFO_PRIVATE, &op); + HttpHandle ophandle(NULL); + + curl_easy_getinfo(handle, CURLINFO_PRIVATE, &ophandle); + HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(ophandle)); + if (handle != op->mCurlHandle || ! op->mCurlActive) { @@ -364,9 +365,9 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode if (op->mTracing > HTTP_TRACE_OFF) { LL_INFOS(LOG_CORE) << "TRACE, RequestComplete, Handle: " - << static_cast<HttpHandle>(op) - << ", Status: " << op->mStatus.toTerseString() - << LL_ENDL; + << op->getHandle() + << ", Status: " << op->mStatus.toTerseString() + << LL_ENDL; } // Dispatch to next stage diff --git a/indra/llcorehttp/_httplibcurl.h b/indra/llcorehttp/_httplibcurl.h index ffc24c63a8..a71eae59c0 100755 --- a/indra/llcorehttp/_httplibcurl.h +++ b/indra/llcorehttp/_httplibcurl.h @@ -65,6 +65,8 @@ private: void operator=(const HttpLibcurl &); // Not defined public: + typedef boost::shared_ptr<HttpOpRequest> opReqPtr_t; + /// Give cycles to libcurl to run active requests. Completed /// operations (successful or failed) will be retried or handed /// over to the reply queue as final responses. @@ -80,7 +82,7 @@ public: /// request. (No additional references will be added.) /// /// Threading: called by worker thread. - void addOp(HttpOpRequest * op); + void addOp(const opReqPtr_t & op); /// One-time call to set the number of policy classes to be /// serviced and to create the resources for each. Value @@ -148,10 +150,10 @@ protected: /// Invoked to cancel an active request, mainly during shutdown /// and destroy. - void cancelRequest(HttpOpRequest * op); + void cancelRequest(const opReqPtr_t &op); protected: - typedef std::set<HttpOpRequest *> active_set_t; + typedef std::set<opReqPtr_t> active_set_t; /// Simple request handle cache for libcurl. /// diff --git a/indra/llcorehttp/_httpopcancel.h b/indra/llcorehttp/_httpopcancel.h index 336dfdc573..86944eb159 100755 --- a/indra/llcorehttp/_httpopcancel.h +++ b/indra/llcorehttp/_httpopcancel.h @@ -56,13 +56,8 @@ public: /// be canceled. HttpOpCancel(HttpHandle handle); -protected: virtual ~HttpOpCancel(); // Use release() -private: - HttpOpCancel(const HttpOpCancel &); // Not defined - void operator=(const HttpOpCancel &); // Not defined - public: virtual void stageFromRequest(HttpService *); diff --git a/indra/llcorehttp/_httpoperation.cpp b/indra/llcorehttp/_httpoperation.cpp index fefe561f80..333f20d281 100755 --- a/indra/llcorehttp/_httpoperation.cpp +++ b/indra/llcorehttp/_httpoperation.cpp @@ -53,15 +53,18 @@ namespace LLCore // ================================== // HttpOperation // ================================== - - -HttpOperation::HttpOperation() - : LLCoreInt::RefCounted(true), - mReplyQueue(NULL), - mUserHandler(NULL), - mReqPolicy(HttpRequest::DEFAULT_POLICY_ID), - mReqPriority(0U), - mTracing(HTTP_TRACE_OFF) +/*static*/ +HttpOperation::handleMap_t HttpOperation::mHandleMap; +LLCoreInt::HttpMutex HttpOperation::mOpMutex; + +HttpOperation::HttpOperation(): + boost::enable_shared_from_this<HttpOperation>(), + mReplyQueue(), + mUserHandler(), + mReqPolicy(HttpRequest::DEFAULT_POLICY_ID), + mReqPriority(0U), + mTracing(HTTP_TRACE_OFF), + mMyHandle(LLCORE_HTTP_HANDLE_INVALID) { mMetricCreated = totalTime(); } @@ -69,30 +72,17 @@ HttpOperation::HttpOperation() HttpOperation::~HttpOperation() { - setReplyPath(NULL, NULL); + destroyHandle(); + mReplyQueue.reset(); + mUserHandler.reset(); } -void HttpOperation::setReplyPath(HttpReplyQueue * reply_queue, - HttpHandler * user_handler) +void HttpOperation::setReplyPath(HttpReplyQueue::ptr_t reply_queue, + HttpHandler::ptr_t user_handler) { - if (reply_queue != mReplyQueue) - { - if (mReplyQueue) - { - mReplyQueue->release(); - } - - if (reply_queue) - { - reply_queue->addRef(); - } - - mReplyQueue = reply_queue; - } - - // Not refcounted - mUserHandler = user_handler; + mReplyQueue.swap(reply_queue); + mUserHandler.swap(user_handler); } @@ -134,7 +124,7 @@ void HttpOperation::visitNotifier(HttpRequest *) HttpResponse * response = new HttpResponse(); response->setStatus(mStatus); - mUserHandler->onCompleted(static_cast<HttpHandle>(this), response); + mUserHandler->onCompleted(getHandle(), response); response->release(); } @@ -148,20 +138,80 @@ HttpStatus HttpOperation::cancel() return status; } +// Handle methods +HttpHandle HttpOperation::getHandle() +{ + if (mMyHandle == LLCORE_HTTP_HANDLE_INVALID) + return createHandle(); + + return mMyHandle; +} + +HttpHandle HttpOperation::createHandle() +{ + HttpHandle handle = static_cast<HttpHandle>(this); + + { + LLCoreInt::HttpScopedLock lock(mOpMutex); + + mHandleMap[handle] = shared_from_this(); + mMyHandle = handle; + } + + return mMyHandle; +} + +void HttpOperation::destroyHandle() +{ + if (mMyHandle == LLCORE_HTTP_HANDLE_INVALID) + return; + { + LLCoreInt::HttpScopedLock lock(mOpMutex); + + handleMap_t::iterator it = mHandleMap.find(mMyHandle); + if (it != mHandleMap.end()) + mHandleMap.erase(it); + } +} + +/*static*/ +HttpOperation::ptr_t HttpOperation::findByHandle(HttpHandle handle) +{ + wptr_t weak; + + { + LLCoreInt::HttpScopedLock lock(mOpMutex); + + handleMap_t::iterator it = mHandleMap.find(handle); + if (it == mHandleMap.end()) + { + LL_WARNS("LLCore::HTTP") << "Could not find operation for handle " << handle << LL_ENDL; + return ptr_t(); + } + + weak = (*it).second; + } + + if (!weak.expired()) + return weak.lock(); + + return ptr_t(); +} + void HttpOperation::addAsReply() { if (mTracing > HTTP_TRACE_OFF) { LL_INFOS(LOG_CORE) << "TRACE, ToReplyQueue, Handle: " - << static_cast<HttpHandle>(this) + << getHandle() << LL_ENDL; } if (mReplyQueue) { - addRef(); - mReplyQueue->addOp(this); + HttpOperation::ptr_t op = shared_from_this(); + mReplyQueue->addOp(op); } } @@ -244,11 +294,8 @@ void HttpOpSpin::stageFromRequest(HttpService * service) else { ms_sleep(1); // backoff interlock plumbing a bit - this->addRef(); - if (! service->getRequestQueue().addOp(this)) - { - this->release(); - } + HttpOperation::ptr_t opptr = shared_from_this(); + service->getRequestQueue().addOp(opptr); } } diff --git a/indra/llcorehttp/_httpoperation.h b/indra/llcorehttp/_httpoperation.h index 937a61187d..1a75921c09 100755 --- a/indra/llcorehttp/_httpoperation.h +++ b/indra/llcorehttp/_httpoperation.h @@ -30,8 +30,7 @@ #include "httpcommon.h" #include "httprequest.h" -#include "_refcounted.h" - +#include "_mutex.h" namespace LLCore { @@ -69,19 +68,20 @@ class HttpService; /// via queue-like interfaces that are thread compatible /// and those interfaces establish the access rules. -class HttpOperation : public LLCoreInt::RefCounted +class HttpOperation : private boost::noncopyable, + public boost::enable_shared_from_this<HttpOperation> { public: + typedef boost::shared_ptr<HttpOperation> ptr_t; + typedef boost::weak_ptr<HttpOperation> wptr_t; + typedef boost::shared_ptr<HttpReplyQueue> HttpReplyQueuePtr_t; + /// Threading: called by consumer thread. HttpOperation(); -protected: /// Threading: called by any thread. virtual ~HttpOperation(); // Use release() -private: - HttpOperation(const HttpOperation &); // Not defined - void operator=(const HttpOperation &); // Not defined public: /// Register a reply queue and a handler for completion notifications. @@ -110,8 +110,8 @@ public: /// /// Threading: called by consumer thread. /// - void setReplyPath(HttpReplyQueue * reply_queue, - HttpHandler * handler); + void setReplyPath(HttpReplyQueuePtr_t reply_queue, + HttpHandler::ptr_t handler); /// The three possible staging steps in an operation's lifecycle. /// Asynchronous requests like HTTP operations move from the @@ -152,6 +152,18 @@ public: /// Threading: called by worker thread. /// virtual HttpStatus cancel(); + + /// Retrieves a unique handle for this operation. + HttpHandle getHandle(); + + template< class OPT > + static boost::shared_ptr< OPT > fromHandle(HttpHandle handle) + { + ptr_t ptr = findByHandle(handle); + if (!ptr) + return boost::shared_ptr< OPT >(); + return boost::dynamic_pointer_cast< OPT >(ptr); + } protected: /// Delivers request to reply queue on completion. After this @@ -163,8 +175,8 @@ protected: void addAsReply(); protected: - HttpReplyQueue * mReplyQueue; // Have refcount - HttpHandler * mUserHandler; // Naked pointer + HttpReplyQueuePtr_t mReplyQueue; + HttpHandler::ptr_t mUserHandler; public: // Request Data @@ -177,6 +189,21 @@ public: // Tracing, debug and metrics HttpTime mMetricCreated; int mTracing; + +private: + typedef std::map<HttpHandle, wptr_t> handleMap_t; + + HttpHandle createHandle(); + void destroyHandle(); + HttpHandle mMyHandle; + + static handleMap_t mHandleMap; + static LLCoreInt::HttpMutex mOpMutex; + +protected: + static ptr_t findByHandle(HttpHandle handle); + + }; // end class HttpOperation @@ -195,7 +222,6 @@ class HttpOpStop : public HttpOperation public: HttpOpStop(); -protected: virtual ~HttpOpStop(); private: @@ -218,7 +244,6 @@ class HttpOpNull : public HttpOperation public: HttpOpNull(); -protected: virtual ~HttpOpNull(); private: @@ -241,7 +266,6 @@ public: // 1 does a soft spin continuously requeuing itself HttpOpSpin(int mode); -protected: virtual ~HttpOpSpin(); private: diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index 86110f5b46..557f6207b5 100755 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -187,15 +187,15 @@ HttpOpRequest::~HttpOpRequest() void HttpOpRequest::stageFromRequest(HttpService * service) { - addRef(); - service->getPolicy().addOp(this); // transfers refcount + HttpOpRequest::ptr_t self(boost::dynamic_pointer_cast<HttpOpRequest>(shared_from_this())); + service->getPolicy().addOp(self); // transfers refcount } void HttpOpRequest::stageFromReady(HttpService * service) { - addRef(); - service->getTransport().addOp(this); // transfers refcount + HttpOpRequest::ptr_t self(boost::dynamic_pointer_cast<HttpOpRequest>(shared_from_this())); + service->getTransport().addOp(self); // transfers refcount } @@ -261,12 +261,19 @@ void HttpOpRequest::visitNotifier(HttpRequest * request) response->setTransferStats(stats); - mUserHandler->onCompleted(static_cast<HttpHandle>(this), response); + mUserHandler->onCompleted(this->getHandle(), response); response->release(); } } +// /*static*/ +// HttpOpRequest::ptr_t HttpOpRequest::fromHandle(HttpHandle handle) +// { +// +// return boost::dynamic_pointer_cast<HttpOpRequest>((static_cast<HttpOpRequest *>(handle))->shared_from_this()); +// } + HttpStatus HttpOpRequest::cancel() { @@ -488,7 +495,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) check_curl_easy_code(code, CURLOPT_NOPROGRESS); code = curl_easy_setopt(mCurlHandle, CURLOPT_URL, mReqURL.c_str()); check_curl_easy_code(code, CURLOPT_URL); - code = curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, this); + code = curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, getHandle()); check_curl_easy_code(code, CURLOPT_PRIVATE); code = curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, ""); check_curl_easy_code(code, CURLOPT_ENCODING); @@ -499,15 +506,15 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) check_curl_easy_code(code, CURLOPT_MAXREDIRS); code = curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback); check_curl_easy_code(code, CURLOPT_WRITEFUNCTION); - code = curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, this); + code = curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, getHandle()); check_curl_easy_code(code, CURLOPT_WRITEDATA); code = curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback); check_curl_easy_code(code, CURLOPT_READFUNCTION); - code = curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, this); + code = curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, getHandle()); check_curl_easy_code(code, CURLOPT_READDATA); code = curl_easy_setopt(mCurlHandle, CURLOPT_SEEKFUNCTION, seekCallback); check_curl_easy_code(code, CURLOPT_SEEKFUNCTION); - code = curl_easy_setopt(mCurlHandle, CURLOPT_SEEKDATA, this); + code = curl_easy_setopt(mCurlHandle, CURLOPT_SEEKDATA, getHandle()); check_curl_easy_code(code, CURLOPT_SEEKDATA); code = curl_easy_setopt(mCurlHandle, CURLOPT_COOKIEFILE, ""); @@ -517,7 +524,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) { code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_FUNCTION, curlSslCtxCallback); check_curl_easy_code(code, CURLOPT_SSL_CTX_FUNCTION); - code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_DATA, this); + code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_DATA, getHandle()); check_curl_easy_code(code, CURLOPT_SSL_CTX_DATA); mCallbackSSLVerify = gpolicy.mSslCtxCallback; } @@ -776,7 +783,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void * userdata) { - HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata)); + HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata)); if (! op->mReplyBody) { @@ -790,7 +797,7 @@ size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void * userdata) { - HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata)); + HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata)); if (! op->mReqBody) { @@ -819,7 +826,7 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void int HttpOpRequest::seekCallback(void *userdata, curl_off_t offset, int origin) { - HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata)); + HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata)); if (!op->mReqBody) { @@ -855,7 +862,7 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi static const char con_ran_line[] = "content-range"; static const char con_retry_line[] = "retry-after"; - HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata)); + HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata)); const size_t hdr_size(size * nmemb); const char * hdr_data(static_cast<const char *>(data)); // Not null terminated @@ -999,7 +1006,7 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userdata) { - HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata)); + HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata)); if (op->mCallbackSSLVerify) { @@ -1016,7 +1023,7 @@ CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userd int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param) { - HttpOpRequest * op(static_cast<HttpOpRequest *>(param)); + HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(param)); if (op->mCallbackSSLVerify) { @@ -1028,7 +1035,7 @@ int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param) int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffer, size_t len, void * userdata) { - HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata)); + HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata)); std::string safe_line; std::string tag; @@ -1108,7 +1115,7 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe if (logit) { LL_INFOS(LOG_CORE) << "TRACE, LibcurlDebug, Handle: " - << static_cast<HttpHandle>(op) + << op->getHandle() << ", Type: " << tag << ", Data: " << safe_line << LL_ENDL; diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h index 1b449a5abc..dbcc57d0fd 100755 --- a/indra/llcorehttp/_httpoprequest.h +++ b/indra/llcorehttp/_httpoprequest.h @@ -66,9 +66,10 @@ class BufferArray; class HttpOpRequest : public HttpOperation { public: + typedef boost::shared_ptr<HttpOpRequest> ptr_t; + HttpOpRequest(); -protected: virtual ~HttpOpRequest(); // Use release() private: diff --git a/indra/llcorehttp/_httpopsetget.h b/indra/llcorehttp/_httpopsetget.h index a1e76dd429..eabd41e79f 100755 --- a/indra/llcorehttp/_httpopsetget.h +++ b/indra/llcorehttp/_httpopsetget.h @@ -53,9 +53,10 @@ namespace LLCore class HttpOpSetGet : public HttpOperation { public: + typedef boost::shared_ptr<HttpOpSetGet> ptr_t; + HttpOpSetGet(); -protected: virtual ~HttpOpSetGet(); // Use release() private: diff --git a/indra/llcorehttp/_httpopsetpriority.h b/indra/llcorehttp/_httpopsetpriority.h index 31706b737c..43e2aa081b 100755 --- a/indra/llcorehttp/_httpopsetpriority.h +++ b/indra/llcorehttp/_httpopsetpriority.h @@ -51,7 +51,6 @@ class HttpOpSetPriority : public HttpOperation public: HttpOpSetPriority(HttpHandle handle, HttpRequest::priority_t priority); -protected: virtual ~HttpOpSetPriority(); private: diff --git a/indra/llcorehttp/_httppolicy.cpp b/indra/llcorehttp/_httppolicy.cpp index e5d6321401..fd78a5dadc 100755 --- a/indra/llcorehttp/_httppolicy.cpp +++ b/indra/llcorehttp/_httppolicy.cpp @@ -116,21 +116,19 @@ void HttpPolicy::shutdown() HttpRetryQueue & retryq(state.mRetryQueue); while (! retryq.empty()) { - HttpOpRequest * op(retryq.top()); + HttpOpRequest::ptr_t op(retryq.top()); retryq.pop(); op->cancel(); - op->release(); } HttpReadyQueue & readyq(state.mReadyQueue); while (! readyq.empty()) { - HttpOpRequest * op(readyq.top()); + HttpOpRequest::ptr_t op(readyq.top()); readyq.pop(); op->cancel(); - op->release(); } } } @@ -141,7 +139,7 @@ void HttpPolicy::start() } -void HttpPolicy::addOp(HttpOpRequest * op) +void HttpPolicy::addOp(const HttpOpRequest::ptr_t &op) { const int policy_class(op->mReqPolicy); @@ -151,7 +149,7 @@ void HttpPolicy::addOp(HttpOpRequest * op) } -void HttpPolicy::retryOp(HttpOpRequest * op) +void HttpPolicy::retryOp(const HttpOpRequest::ptr_t &op) { static const HttpTime retry_deltas[] = { @@ -180,7 +178,7 @@ void HttpPolicy::retryOp(HttpOpRequest * op) { ++op->mPolicy503Retries; } - LL_DEBUGS(LOG_CORE) << "HTTP request " << static_cast<HttpHandle>(op) + LL_DEBUGS(LOG_CORE) << "HTTP request " << op->getHandle() << " retry " << op->mPolicyRetries << " scheduled in " << (delta / HttpTime(1000)) << " mS (" << (external_delta ? "external" : "internal") @@ -189,10 +187,10 @@ void HttpPolicy::retryOp(HttpOpRequest * op) if (op->mTracing > HTTP_TRACE_OFF) { LL_INFOS(LOG_CORE) << "TRACE, ToRetryQueue, Handle: " - << static_cast<HttpHandle>(op) - << ", Delta: " << (delta / HttpTime(1000)) - << ", Retries: " << op->mPolicyRetries - << LL_ENDL; + << op->getHandle() + << ", Delta: " << (delta / HttpTime(1000)) + << ", Retries: " << op->mPolicyRetries + << LL_ENDL; } mClasses[policy_class]->mRetryQueue.push(op); } @@ -264,14 +262,14 @@ HttpService::ELoopSpeed HttpPolicy::processReadyQueue() // First see if we have any retries... while (needed > 0 && ! retryq.empty()) { - HttpOpRequest * op(retryq.top()); + HttpOpRequest::ptr_t op(retryq.top()); if (op->mPolicyRetryAt > now) break; retryq.pop(); op->stageFromReady(mService); - op->release(); + op.reset(); ++state.mRequestCount; --needed; @@ -296,11 +294,11 @@ HttpService::ELoopSpeed HttpPolicy::processReadyQueue() // Now go on to the new requests... while (needed > 0 && ! readyq.empty()) { - HttpOpRequest * op(readyq.top()); + HttpOpRequest::ptr_t op(readyq.top()); readyq.pop(); op->stageFromReady(mService); - op->release(); + op.reset(); ++state.mRequestCount; --needed; @@ -351,9 +349,9 @@ bool HttpPolicy::changePriority(HttpHandle handle, HttpRequest::priority_t prior { HttpReadyQueue::container_type::iterator cur(iter++); - if (static_cast<HttpHandle>(*cur) == handle) + if ((*cur)->getHandle() == handle) { - HttpOpRequest * op(*cur); + HttpOpRequest::ptr_t op(*cur); c.erase(cur); // All iterators are now invalidated op->mReqPriority = priority; state.mReadyQueue.push(op); // Re-insert using adapter class @@ -378,12 +376,11 @@ bool HttpPolicy::cancel(HttpHandle handle) { HttpRetryQueue::container_type::iterator cur(iter++); - if (static_cast<HttpHandle>(*cur) == handle) + if ((*cur)->getHandle() == handle) { - HttpOpRequest * op(*cur); + HttpOpRequest::ptr_t op(*cur); c1.erase(cur); // All iterators are now invalidated op->cancel(); - op->release(); return true; } } @@ -394,12 +391,11 @@ bool HttpPolicy::cancel(HttpHandle handle) { HttpReadyQueue::container_type::iterator cur(iter++); - if (static_cast<HttpHandle>(*cur) == handle) + if ((*cur)->getHandle() == handle) { - HttpOpRequest * op(*cur); + HttpOpRequest::ptr_t op(*cur); c2.erase(cur); // All iterators are now invalidated op->cancel(); - op->release(); return true; } } @@ -409,7 +405,7 @@ bool HttpPolicy::cancel(HttpHandle handle) } -bool HttpPolicy::stageAfterCompletion(HttpOpRequest * op) +bool HttpPolicy::stageAfterCompletion(const HttpOpRequest::ptr_t &op) { // Retry or finalize if (! op->mStatus) @@ -438,7 +434,7 @@ bool HttpPolicy::stageAfterCompletion(HttpOpRequest * op) // This op is done, finalize it delivering it to the reply queue... if (! op->mStatus) { - LL_WARNS(LOG_CORE) << "HTTP request " << static_cast<HttpHandle>(op) + LL_WARNS(LOG_CORE) << "HTTP request " << op->getHandle() << " failed after " << op->mPolicyRetries << " retries. Reason: " << op->mStatus.toString() << " (" << op->mStatus.toTerseString() << ")" @@ -446,13 +442,12 @@ bool HttpPolicy::stageAfterCompletion(HttpOpRequest * op) } else if (op->mPolicyRetries) { - LL_DEBUGS(LOG_CORE) << "HTTP request " << static_cast<HttpHandle>(op) + LL_DEBUGS(LOG_CORE) << "HTTP request " << op->getHandle() << " succeeded on retry " << op->mPolicyRetries << "." << LL_ENDL; } op->stageFromActive(mService); - op->release(); return false; // not active } diff --git a/indra/llcorehttp/_httppolicy.h b/indra/llcorehttp/_httppolicy.h index 11cd89bbd1..3c4126e14b 100755 --- a/indra/llcorehttp/_httppolicy.h +++ b/indra/llcorehttp/_httppolicy.h @@ -60,6 +60,8 @@ private: void operator=(const HttpPolicy &); // Not defined public: + typedef boost::shared_ptr<HttpOpRequest> opReqPtr_t; + /// Threading: called by init thread. HttpRequest::policy_t createPolicyClass(); @@ -96,7 +98,7 @@ public: /// from queue. /// /// Threading: called by worker thread - void addOp(HttpOpRequest *); + void addOp(const opReqPtr_t &); /// Similar to addOp, used when a caller wants to retry a /// request that has failed. It's placed on a special retry @@ -106,7 +108,7 @@ public: /// order. /// /// Threading: called by worker thread - void retryOp(HttpOpRequest *); + void retryOp(const opReqPtr_t &); /// Attempt to change the priority of an earlier request. /// Request that Shadows HttpService's method @@ -130,7 +132,7 @@ public: /// sent on to the reply queue. /// /// Threading: called by worker thread - bool stageAfterCompletion(HttpOpRequest * op); + bool stageAfterCompletion(const opReqPtr_t &op); /// Get a reference to global policy options. Caller is expected /// to do context checks like no setting once running. These diff --git a/indra/llcorehttp/_httpreadyqueue.h b/indra/llcorehttp/_httpreadyqueue.h index 5f19a9c5f9..7418988ec1 100755 --- a/indra/llcorehttp/_httpreadyqueue.h +++ b/indra/llcorehttp/_httpreadyqueue.h @@ -56,12 +56,12 @@ namespace LLCore #if LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY -typedef std::deque<HttpOpRequest *> HttpReadyQueueBase; +typedef std::deque<HttpOpRequest::ptr_t> HttpReadyQueueBase; #else -typedef std::priority_queue<HttpOpRequest *, - std::deque<HttpOpRequest *>, +typedef std::priority_queue<HttpOpRequest::ptr_t, + std::deque<HttpOpRequest::ptr_t>, LLCore::HttpOpRequestCompare> HttpReadyQueueBase; #endif // LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY diff --git a/indra/llcorehttp/_httpreplyqueue.cpp b/indra/llcorehttp/_httpreplyqueue.cpp index 558b7bdee9..2b138f3ad5 100755 --- a/indra/llcorehttp/_httpreplyqueue.cpp +++ b/indra/llcorehttp/_httpreplyqueue.cpp @@ -39,23 +39,17 @@ namespace LLCore HttpReplyQueue::HttpReplyQueue() - : RefCounted(true) { } HttpReplyQueue::~HttpReplyQueue() { - while (! mQueue.empty()) - { - HttpOperation * op = mQueue.back(); - mQueue.pop_back(); - op->release(); - } + mQueue.clear(); } -void HttpReplyQueue::addOp(HttpOperation * op) +void HttpReplyQueue::addOp(const HttpReplyQueue::opPtr_t &op) { { HttpScopedLock lock(mQueueMutex); @@ -66,15 +60,15 @@ void HttpReplyQueue::addOp(HttpOperation * op) } -HttpOperation * HttpReplyQueue::fetchOp() +HttpReplyQueue::opPtr_t HttpReplyQueue::fetchOp() { - HttpOperation * result(NULL); + HttpOperation::ptr_t result; { HttpScopedLock lock(mQueueMutex); if (mQueue.empty()) - return NULL; + return opPtr_t(); result = mQueue.front(); mQueue.erase(mQueue.begin()); @@ -98,9 +92,6 @@ void HttpReplyQueue::fetchAll(OpContainer & ops) mQueue.swap(ops); } } - - // Caller also acquires the reference counts on each op. - return; } diff --git a/indra/llcorehttp/_httpreplyqueue.h b/indra/llcorehttp/_httpreplyqueue.h index 4220a09a3b..0e39e22dde 100755 --- a/indra/llcorehttp/_httpreplyqueue.h +++ b/indra/llcorehttp/_httpreplyqueue.h @@ -58,21 +58,19 @@ class HttpOperation; /// will be coded anyway so it shouldn't be too much of a /// burden. -class HttpReplyQueue : public LLCoreInt::RefCounted +class HttpReplyQueue : private boost::noncopyable { -public: - /// Caller acquires a Refcount on construction - HttpReplyQueue(); -protected: - virtual ~HttpReplyQueue(); // Use release() +public: + typedef boost::shared_ptr<HttpOperation> opPtr_t; + typedef boost::shared_ptr<HttpReplyQueue> ptr_t; -private: - HttpReplyQueue(const HttpReplyQueue &); // Not defined - void operator=(const HttpReplyQueue &); // Not defined + HttpReplyQueue(); + virtual ~HttpReplyQueue(); public: - typedef std::vector<HttpOperation *> OpContainer; + + typedef std::vector< opPtr_t > OpContainer; /// Insert an object at the back of the reply queue. /// @@ -80,7 +78,7 @@ public: /// through the queue. /// /// Threading: callable by any thread. - void addOp(HttpOperation * op); + void addOp(const opPtr_t &op); /// Fetch an operation from the head of the queue. Returns /// NULL if none exists. @@ -88,7 +86,7 @@ public: /// Caller acquires reference count on returned operation. /// /// Threading: callable by any thread. - HttpOperation * fetchOp(); + opPtr_t fetchOp(); /// Caller acquires reference count on each returned operation /// @@ -96,6 +94,7 @@ public: void fetchAll(OpContainer & ops); protected: + OpContainer mQueue; LLCoreInt::HttpMutex mQueueMutex; LLCoreInt::HttpConditionVariable mQueueCV; diff --git a/indra/llcorehttp/_httprequestqueue.cpp b/indra/llcorehttp/_httprequestqueue.cpp index c16966d078..c6f4ad789f 100755 --- a/indra/llcorehttp/_httprequestqueue.cpp +++ b/indra/llcorehttp/_httprequestqueue.cpp @@ -47,12 +47,7 @@ HttpRequestQueue::HttpRequestQueue() HttpRequestQueue::~HttpRequestQueue() { - while (! mQueue.empty()) - { - HttpOperation * op = mQueue.back(); - mQueue.pop_back(); - op->release(); - } + mQueue.clear(); } @@ -73,7 +68,7 @@ void HttpRequestQueue::term() } -HttpStatus HttpRequestQueue::addOp(HttpOperation * op) +HttpStatus HttpRequestQueue::addOp(const HttpRequestQueue::opPtr_t &op) { bool wake(false); { @@ -95,9 +90,9 @@ HttpStatus HttpRequestQueue::addOp(HttpOperation * op) } -HttpOperation * HttpRequestQueue::fetchOp(bool wait) +HttpRequestQueue::opPtr_t HttpRequestQueue::fetchOp(bool wait) { - HttpOperation * result(NULL); + HttpOperation::ptr_t result; { HttpScopedLock lock(mQueueMutex); @@ -105,7 +100,7 @@ HttpOperation * HttpRequestQueue::fetchOp(bool wait) while (mQueue.empty()) { if (! wait || mQueueStopped) - return NULL; + return HttpOperation::ptr_t(); mQueueCV.wait(lock); } diff --git a/indra/llcorehttp/_httprequestqueue.h b/indra/llcorehttp/_httprequestqueue.h index c9c52b7233..3c3d134b07 100755 --- a/indra/llcorehttp/_httprequestqueue.h +++ b/indra/llcorehttp/_httprequestqueue.h @@ -61,6 +61,8 @@ private: void operator=(const HttpRequestQueue &); // Not defined public: + typedef boost::shared_ptr<HttpOperation> opPtr_t; + static void init(); static void term(); @@ -71,7 +73,7 @@ public: } public: - typedef std::vector<HttpOperation *> OpContainer; + typedef std::vector<opPtr_t> OpContainer; /// Insert an object at the back of the request queue. /// @@ -83,7 +85,7 @@ public: /// an explicit release() call. /// /// Threading: callable by any thread. - HttpStatus addOp(HttpOperation * op); + HttpStatus addOp(const opPtr_t &op); /// Return the operation on the front of the queue. If /// the queue is empty and @wait is false, call returns @@ -95,7 +97,7 @@ public: /// Caller acquires reference count any returned operation /// /// Threading: callable by any thread. - HttpOperation * fetchOp(bool wait); + opPtr_t fetchOp(bool wait); /// Return all queued requests to caller. The @ops argument /// should be empty when called and will be swap()'d with diff --git a/indra/llcorehttp/_httpretryqueue.h b/indra/llcorehttp/_httpretryqueue.h index 745adec09d..5d8c529cff 100755 --- a/indra/llcorehttp/_httpretryqueue.h +++ b/indra/llcorehttp/_httpretryqueue.h @@ -49,15 +49,15 @@ namespace LLCore struct HttpOpRetryCompare { - bool operator()(const HttpOpRequest * lhs, const HttpOpRequest * rhs) + bool operator()(const HttpOpRequest::ptr_t &lhs, const HttpOpRequest::ptr_t &rhs) { return lhs->mPolicyRetryAt < rhs->mPolicyRetryAt; } }; -typedef std::priority_queue<HttpOpRequest *, - std::deque<HttpOpRequest *>, +typedef std::priority_queue<HttpOpRequest::ptr_t, + std::deque<HttpOpRequest::ptr_t>, LLCore::HttpOpRetryCompare> HttpRetryQueueBase; class HttpRetryQueue : public HttpRetryQueueBase diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp index 252db78c89..6c39fdc61b 100755 --- a/indra/llcorehttp/_httpservice.cpp +++ b/indra/llcorehttp/_httpservice.cpp @@ -263,14 +263,13 @@ void HttpService::shutdown() // Cancel requests already on the request queue HttpRequestQueue::OpContainer ops; mRequestQueue->fetchAll(false, ops); - while (! ops.empty()) - { - HttpOperation * op(ops.front()); - ops.erase(ops.begin()); - op->cancel(); - op->release(); - } + for (HttpRequestQueue::OpContainer::iterator it = ops.begin(); + it != ops.end(); ++it) + { + (*it)->cancel(); + } + ops.clear(); // Shutdown transport canceling requests, freeing resources mTransport->shutdown(); @@ -324,7 +323,7 @@ HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop) mRequestQueue->fetchAll(wait_for_req, ops); while (! ops.empty()) { - HttpOperation * op(ops.front()); + HttpOperation::ptr_t op(ops.front()); ops.erase(ops.begin()); // Process operation @@ -338,7 +337,7 @@ HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop) if (op->mTracing > HTTP_TRACE_OFF) { LL_INFOS(LOG_CORE) << "TRACE, FromRequestQueue, Handle: " - << static_cast<HttpHandle>(op) + << op->getHandle() << LL_ENDL; } @@ -347,7 +346,7 @@ HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop) } // Done with operation - op->release(); + op.reset(); } // Queue emptied, allow polling loop to sleep diff --git a/indra/llcorehttp/examples/http_texture_load.cpp b/indra/llcorehttp/examples/http_texture_load.cpp index 737282c7df..b91aaf0593 100755 --- a/indra/llcorehttp/examples/http_texture_load.cpp +++ b/indra/llcorehttp/examples/http_texture_load.cpp @@ -361,7 +361,7 @@ int main(int argc, char** argv) << std::endl; // Clean up - hr->requestStopThread(NULL); + hr->requestStopThread(LLCore::HttpHandler::ptr_t()); ms_sleep(1000); opt.reset(); delete hr; @@ -435,6 +435,11 @@ WorkingSet::~WorkingSet() { } +namespace +{ + void NoOpDeletor(LLCore::HttpHandler *) + { /*NoOp*/ } +} bool WorkingSet::reload(LLCore::HttpRequest * hr, LLCore::HttpOptions::ptr_t & opt) { @@ -464,11 +469,11 @@ bool WorkingSet::reload(LLCore::HttpRequest * hr, LLCore::HttpOptions::ptr_t & o LLCore::HttpHandle handle; if (offset || length) { - handle = hr->requestGetByteRange(0, 0, buffer, offset, length, opt, mHeaders, this); + handle = hr->requestGetByteRange(0, 0, buffer, offset, length, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor)); } else { - handle = hr->requestGet(0, 0, buffer, opt, mHeaders, this); + handle = hr->requestGet(0, 0, buffer, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor)); } if (! handle) { diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp index 99238ea920..c423047bb0 100755 --- a/indra/llcorehttp/httpcommon.cpp +++ b/indra/llcorehttp/httpcommon.cpp @@ -23,12 +23,24 @@ * 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" // Modifies curl/curl.h interfaces #include "httpcommon.h" - +#include "llmutex.h" +#include "llthread.h" #include <curl/curl.h> #include <string> #include <sstream> +#if SAFE_SSL +#include <openssl/crypto.h> +#endif namespace LLCore @@ -263,5 +275,168 @@ bool HttpStatus::isRetryable() const *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 (type >= sSSLMutex.size()) + { + LL_WARNS() << "Attempt to get unknown MUTEX in SSL Lock." << LL_ENDL; + } + + 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 + +} + + +void cleanup() +{ +#if SAFE_SSL + CRYPTO_set_id_callback(NULL); + CRYPTO_set_locking_callback(NULL); + sSSLMutex.clear(); +#endif + + curl_global_cleanup(); +} + + +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 diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h index 898d3d47fa..b2db01d038 100755 --- a/indra/llcorehttp/httpcommon.h +++ b/indra/llcorehttp/httpcommon.h @@ -193,6 +193,7 @@ #include "boost/weak_ptr.hpp" #include "boost/function.hpp" #include <string> +#include <curl/curl.h> namespace LLCore { @@ -208,6 +209,7 @@ namespace LLCore /// becomes invalid and may be recycled for other queued requests. typedef void * HttpHandle; + #define LLCORE_HTTP_HANDLE_INVALID (NULL) /// For internal scheduling and metrics, we use a microsecond @@ -490,6 +492,20 @@ private: }; // end struct HttpStatus +/// A namespace for several free methods and low level utilities. +namespace LLHttp +{ + typedef boost::shared_ptr<CURL> CURL_ptr; + + void initialize(); + void cleanup(); + + CURL_ptr createEasyHandle(); + std::string getCURLVersion(); + + void check_curl_code(CURLcode code, int curl_setopt_option); +} + } // end namespace LLCore #endif // _LLCORE_HTTP_COMMON_H_ diff --git a/indra/llcorehttp/httphandler.h b/indra/llcorehttp/httphandler.h index 7bc9096703..65e043f5d3 100755 --- a/indra/llcorehttp/httphandler.h +++ b/indra/llcorehttp/httphandler.h @@ -58,6 +58,9 @@ class HttpResponse; class HttpHandler { public: + typedef boost::shared_ptr<HttpHandler> ptr_t; + typedef boost::weak_ptr<HttpHandler> wptr_t; + virtual ~HttpHandler() { } diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp index 63233259fb..e09f0c3b18 100755 --- a/indra/llcorehttp/httprequest.cpp +++ b/indra/llcorehttp/httprequest.cpp @@ -55,13 +55,13 @@ namespace LLCore HttpRequest::HttpRequest() - : mReplyQueue(NULL), + : mReplyQueue(), mRequestQueue(NULL) { mRequestQueue = HttpRequestQueue::instanceOf(); mRequestQueue->addRef(); - mReplyQueue = new HttpReplyQueue(); + mReplyQueue.reset( new HttpReplyQueue() ); } @@ -73,11 +73,7 @@ HttpRequest::~HttpRequest() mRequestQueue = NULL; } - if (mReplyQueue) - { - mReplyQueue->release(); - mReplyQueue = NULL; - } + mReplyQueue.reset(); } @@ -128,58 +124,48 @@ HttpStatus HttpRequest::setStaticPolicyOption(EPolicyOption opt, policy_t pclass } HttpHandle HttpRequest::setPolicyOption(EPolicyOption opt, policy_t pclass, - long value, HttpHandler * handler) + long value, HttpHandler::ptr_t handler) { HttpStatus status; - HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpSetGet * op = new HttpOpSetGet(); + HttpOpSetGet::ptr_t op(new HttpOpSetGet()); if (! (status = op->setupSet(opt, pclass, value))) { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } op->setReplyPath(mReplyQueue, handler); if (! (status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } mLastReqStatus = status; - handle = static_cast<HttpHandle>(op); - - return handle; + return op->getHandle(); } HttpHandle HttpRequest::setPolicyOption(EPolicyOption opt, policy_t pclass, - const std::string & value, HttpHandler * handler) + const std::string & value, HttpHandler::ptr_t handler) { HttpStatus status; - HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpSetGet * op = new HttpOpSetGet(); + HttpOpSetGet::ptr_t op (new HttpOpSetGet()); if (! (status = op->setupSet(opt, pclass, value))) { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } op->setReplyPath(mReplyQueue, handler); if (! (status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } mLastReqStatus = status; - handle = static_cast<HttpHandle>(op); - - return handle; + return op->getHandle(); } @@ -199,30 +185,25 @@ HttpHandle HttpRequest::requestGet(policy_t policy_id, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * user_handler) + HttpHandler::ptr_t user_handler) { HttpStatus status; - HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpRequest * op = new HttpOpRequest(); + HttpOpRequest::ptr_t op(new HttpOpRequest()); if (! (status = op->setupGet(policy_id, priority, url, options, headers))) { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } op->setReplyPath(mReplyQueue, user_handler); if (! (status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } mLastReqStatus = status; - handle = static_cast<HttpHandle>(op); - - return handle; + return op->getHandle(); } @@ -233,30 +214,25 @@ HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id, size_t len, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * user_handler) + HttpHandler::ptr_t user_handler) { HttpStatus status; - HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpRequest * op = new HttpOpRequest(); + HttpOpRequest::ptr_t op(new HttpOpRequest()); if (! (status = op->setupGetByteRange(policy_id, priority, url, offset, len, options, headers))) { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } op->setReplyPath(mReplyQueue, user_handler); if (! (status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } mLastReqStatus = status; - handle = static_cast<HttpHandle>(op); - - return handle; + return op->getHandle(); } @@ -266,30 +242,25 @@ HttpHandle HttpRequest::requestPost(policy_t policy_id, BufferArray * body, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * user_handler) + HttpHandler::ptr_t user_handler) { HttpStatus status; - HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpRequest * op = new HttpOpRequest(); + HttpOpRequest::ptr_t op(new HttpOpRequest()); if (! (status = op->setupPost(policy_id, priority, url, body, options, headers))) { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } op->setReplyPath(mReplyQueue, user_handler); if (! (status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } mLastReqStatus = status; - handle = static_cast<HttpHandle>(op); - - return handle; + return op->getHandle(); } @@ -299,30 +270,25 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id, BufferArray * body, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * user_handler) + HttpHandler::ptr_t user_handler) { HttpStatus status; - HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpRequest * op = new HttpOpRequest(); + HttpOpRequest::ptr_t op (new HttpOpRequest()); if (! (status = op->setupPut(policy_id, priority, url, body, options, headers))) { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } op->setReplyPath(mReplyQueue, user_handler); if (! (status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } mLastReqStatus = status; - handle = static_cast<HttpHandle>(op); - - return handle; + return op->getHandle(); } HttpHandle HttpRequest::requestDelete(policy_t policy_id, @@ -330,30 +296,25 @@ HttpHandle HttpRequest::requestDelete(policy_t policy_id, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * user_handler) + HttpHandler::ptr_t user_handler) { HttpStatus status; - HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpRequest * op = new HttpOpRequest(); + HttpOpRequest::ptr_t op(new HttpOpRequest()); if (!(status = op->setupDelete(policy_id, priority, url, options, headers))) { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } op->setReplyPath(mReplyQueue, user_handler); if (!(status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } mLastReqStatus = status; - handle = static_cast<HttpHandle>(op); - - return handle; + return op->getHandle(); } HttpHandle HttpRequest::requestPatch(policy_t policy_id, @@ -362,30 +323,25 @@ HttpHandle HttpRequest::requestPatch(policy_t policy_id, BufferArray * body, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * user_handler) + HttpHandler::ptr_t user_handler) { HttpStatus status; - HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpRequest * op = new HttpOpRequest(); + HttpOpRequest::ptr_t op (new HttpOpRequest()); if (!(status = op->setupPatch(policy_id, priority, url, body, options, headers))) { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } op->setReplyPath(mReplyQueue, user_handler); if (!(status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } mLastReqStatus = status; - handle = static_cast<HttpHandle>(op); - - return handle; + return op->getHandle(); } HttpHandle HttpRequest::requestCopy(policy_t policy_id, @@ -393,30 +349,26 @@ HttpHandle HttpRequest::requestCopy(policy_t policy_id, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * user_handler) + HttpHandler::ptr_t user_handler) { HttpStatus status; - HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpRequest * op = new HttpOpRequest(); + HttpOpRequest::ptr_t op(new HttpOpRequest()); if (!(status = op->setupCopy(policy_id, priority, url, options, headers))) { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } op->setReplyPath(mReplyQueue, user_handler); if (!(status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } mLastReqStatus = status; - handle = static_cast<HttpHandle>(op); + return op->getHandle(); - return handle; } HttpHandle HttpRequest::requestMove(policy_t policy_id, @@ -424,57 +376,48 @@ HttpHandle HttpRequest::requestMove(policy_t policy_id, const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * user_handler) + HttpHandler::ptr_t user_handler) { HttpStatus status; - HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpRequest * op = new HttpOpRequest(); + HttpOpRequest::ptr_t op (new HttpOpRequest()); if (!(status = op->setupMove(policy_id, priority, url, options, headers))) { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } op->setReplyPath(mReplyQueue, user_handler); if (!(status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } mLastReqStatus = status; - handle = static_cast<HttpHandle>(op); - - return handle; + return op->getHandle(); } -HttpHandle HttpRequest::requestNoOp(HttpHandler * user_handler) +HttpHandle HttpRequest::requestNoOp(HttpHandler::ptr_t user_handler) { HttpStatus status; - HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpNull * op = new HttpOpNull(); + HttpOperation::ptr_t op (new HttpOpNull()); op->setReplyPath(mReplyQueue, user_handler); if (! (status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; - return handle; + return LLCORE_HTTP_HANDLE_INVALID; } mLastReqStatus = status; - handle = static_cast<HttpHandle>(op); - - return handle; + return op->getHandle(); } HttpStatus HttpRequest::update(long usecs) { - HttpOperation * op(NULL); + HttpOperation::ptr_t op; if (usecs) { @@ -485,7 +428,7 @@ HttpStatus HttpRequest::update(long usecs) op->visitNotifier(this); // We're done with the operation - op->release(); + op.reset(); } } else @@ -500,13 +443,13 @@ HttpStatus HttpRequest::update(long usecs) ++iter) { // Swap op pointer for NULL; - op = *iter; *iter = NULL; + op.reset(); + op.swap(*iter); // Process operation op->visitNotifier(this); // We're done with the operation - op->release(); } } } @@ -521,46 +464,38 @@ HttpStatus HttpRequest::update(long usecs) // Request Management Methods // ==================================== -HttpHandle HttpRequest::requestCancel(HttpHandle request, HttpHandler * user_handler) +HttpHandle HttpRequest::requestCancel(HttpHandle request, HttpHandler::ptr_t user_handler) { HttpStatus status; - HttpHandle ret_handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpCancel * op = new HttpOpCancel(request); + HttpOperation::ptr_t op(new HttpOpCancel(request)); op->setReplyPath(mReplyQueue, user_handler); if (! (status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; - return ret_handle; + return LLCORE_HTTP_HANDLE_INVALID; } mLastReqStatus = status; - ret_handle = static_cast<HttpHandle>(op); - - return ret_handle; + return op->getHandle(); } HttpHandle HttpRequest::requestSetPriority(HttpHandle request, priority_t priority, - HttpHandler * handler) + HttpHandler::ptr_t handler) { HttpStatus status; - HttpHandle ret_handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpSetPriority * op = new HttpOpSetPriority(request, priority); + HttpOperation::ptr_t op (new HttpOpSetPriority(request, priority)); op->setReplyPath(mReplyQueue, handler); if (! (status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; - return ret_handle; + return LLCORE_HTTP_HANDLE_INVALID; } mLastReqStatus = status; - ret_handle = static_cast<HttpHandle>(op); - - return ret_handle; + return op->getHandle(); } @@ -609,22 +544,21 @@ HttpStatus HttpRequest::startThread() } -HttpHandle HttpRequest::requestStopThread(HttpHandler * user_handler) +HttpHandle HttpRequest::requestStopThread(HttpHandler::ptr_t user_handler) { HttpStatus status; HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpStop * op = new HttpOpStop(); + HttpOperation::ptr_t op(new HttpOpStop()); op->setReplyPath(mReplyQueue, user_handler); if (! (status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; return handle; } mLastReqStatus = status; - handle = static_cast<HttpHandle>(op); + handle = op->getHandle(); return handle; } @@ -635,17 +569,16 @@ HttpHandle HttpRequest::requestSpin(int mode) HttpStatus status; HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); - HttpOpSpin * op = new HttpOpSpin(mode); - op->setReplyPath(mReplyQueue, NULL); + HttpOperation::ptr_t op(new HttpOpSpin(mode)); + op->setReplyPath(mReplyQueue, HttpHandler::ptr_t()); if (! (status = mRequestQueue->addOp(op))) // transfers refcount { - op->release(); mLastReqStatus = status; return handle; } mLastReqStatus = status; - handle = static_cast<HttpHandle>(op); + handle = op->getHandle(); return handle; } diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h index 6c2449266f..17cfdcd7b6 100755 --- a/indra/llcorehttp/httprequest.h +++ b/indra/llcorehttp/httprequest.h @@ -238,7 +238,7 @@ public: /// Prototype for policy based callbacks. The callback methods will be executed /// on the worker thread so no modifications should be made to the HttpHandler object. - typedef boost::function<HttpStatus(const std::string &, HttpHandler const * const, void *)> policyCallback_t; + typedef boost::function<HttpStatus(const std::string &, const HttpHandler::ptr_t &, void *)> policyCallback_t; /// Set a policy option for a global or class parameter at /// startup time (prior to thread start). @@ -270,9 +270,9 @@ public: /// @return Handle of dynamic request. Use @see getStatus() if /// the returned handle is invalid. HttpHandle setPolicyOption(EPolicyOption opt, policy_t pclass, long value, - HttpHandler * handler); + HttpHandler::ptr_t handler); HttpHandle setPolicyOption(EPolicyOption opt, policy_t pclass, const std::string & value, - HttpHandler * handler); + HttpHandler::ptr_t handler); /// @} @@ -350,7 +350,7 @@ public: const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * handler); + HttpHandler::ptr_t handler); /// Queue a full HTTP GET request to be issued with a 'Range' header. @@ -393,7 +393,7 @@ public: size_t len, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * handler); + HttpHandler::ptr_t handler); /// Queue a full HTTP POST. Query arguments and body may @@ -434,7 +434,7 @@ public: BufferArray * body, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * handler); + HttpHandler::ptr_t handler); /// Queue a full HTTP PUT. Query arguments and body may @@ -475,7 +475,7 @@ public: BufferArray * body, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * handler); + HttpHandler::ptr_t handler); /// Queue a full HTTP DELETE. Query arguments and body may @@ -495,7 +495,7 @@ public: const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * user_handler); + HttpHandler::ptr_t user_handler); /// Queue a full HTTP PATCH. Query arguments and body may /// be provided. Caller is responsible for escaping and @@ -518,7 +518,7 @@ public: BufferArray * body, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * user_handler); + HttpHandler::ptr_t user_handler); /// Queue a full HTTP COPY. Query arguments and body may /// be provided. Caller is responsible for escaping and @@ -537,7 +537,7 @@ public: const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * user_handler); + HttpHandler::ptr_t user_handler); /// Queue a full HTTP MOVE. Query arguments and body may /// be provided. Caller is responsible for escaping and @@ -556,7 +556,7 @@ public: const std::string & url, const HttpOptions::ptr_t & options, const HttpHeaders::ptr_t & headers, - HttpHandler * user_handler); + HttpHandler::ptr_t user_handler); /// Queue a NoOp request. /// The request is queued and serviced by the working thread which @@ -566,7 +566,7 @@ public: /// @param handler @see requestGet() /// @return " /// - HttpHandle requestNoOp(HttpHandler * handler); + HttpHandle requestNoOp(HttpHandler::ptr_t handler); /// While all the heavy work is done by the worker thread, notifications /// must be performed in the context of the application thread. These @@ -591,7 +591,7 @@ public: /// /// @{ - HttpHandle requestCancel(HttpHandle request, HttpHandler *); + HttpHandle requestCancel(HttpHandle request, HttpHandler::ptr_t); /// Request that a previously-issued request be reprioritized. /// The status of whether the change itself succeeded arrives @@ -603,7 +603,7 @@ public: /// @param handler @see requestGet() /// @return " /// - HttpHandle requestSetPriority(HttpHandle request, priority_t priority, HttpHandler * handler); + HttpHandle requestSetPriority(HttpHandle request, priority_t priority, HttpHandler::ptr_t handler); /// @} @@ -641,7 +641,7 @@ public: /// As the request cannot be cancelled, the handle /// is generally not useful. /// - HttpHandle requestStopThread(HttpHandler * handler); + HttpHandle requestStopThread(HttpHandler::ptr_t handler); /// Queue a Spin request. /// DEBUG/TESTING ONLY. This puts the worker into a CPU spin for @@ -655,14 +655,15 @@ public: /// @} protected: - void generateNotification(HttpOperation * op); private: + typedef boost::shared_ptr<HttpReplyQueue> HttpReplyQueuePtr_t; + /// @name InstanceData /// /// @{ HttpStatus mLastReqStatus; - HttpReplyQueue * mReplyQueue; + HttpReplyQueuePtr_t mReplyQueue; HttpRequestQueue * mRequestQueue; /// @} diff --git a/indra/llcorehttp/llhttpconstants.cpp b/indra/llcorehttp/llhttpconstants.cpp new file mode 100755 index 0000000000..71d4f19408 --- /dev/null +++ b/indra/llcorehttp/llhttpconstants.cpp @@ -0,0 +1,135 @@ +/** + * @file llhttpconstants.cpp + * @brief Implementation of the HTTP request / response constant lookups + * + * $LicenseInfo:firstyear=2013&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013-2014, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llhttpconstants.h" +#include "lltimer.h" + +// for curl_getdate() (apparently parsing RFC 1123 dates is hard) +#include <curl/curl.h> + +// Outgoing headers. Do *not* use these to check incoming headers. +// For incoming headers, use the lower-case headers, below. +const std::string HTTP_OUT_HEADER_ACCEPT("Accept"); +const std::string HTTP_OUT_HEADER_ACCEPT_CHARSET("Accept-Charset"); +const std::string HTTP_OUT_HEADER_ACCEPT_ENCODING("Accept-Encoding"); +const std::string HTTP_OUT_HEADER_ACCEPT_LANGUAGE("Accept-Language"); +const std::string HTTP_OUT_HEADER_ACCEPT_RANGES("Accept-Ranges"); +const std::string HTTP_OUT_HEADER_AGE("Age"); +const std::string HTTP_OUT_HEADER_ALLOW("Allow"); +const std::string HTTP_OUT_HEADER_AUTHORIZATION("Authorization"); +const std::string HTTP_OUT_HEADER_CACHE_CONTROL("Cache-Control"); +const std::string HTTP_OUT_HEADER_CONNECTION("Connection"); +const std::string HTTP_OUT_HEADER_CONTENT_DESCRIPTION("Content-Description"); +const std::string HTTP_OUT_HEADER_CONTENT_ENCODING("Content-Encoding"); +const std::string HTTP_OUT_HEADER_CONTENT_ID("Content-ID"); +const std::string HTTP_OUT_HEADER_CONTENT_LANGUAGE("Content-Language"); +const std::string HTTP_OUT_HEADER_CONTENT_LENGTH("Content-Length"); +const std::string HTTP_OUT_HEADER_CONTENT_LOCATION("Content-Location"); +const std::string HTTP_OUT_HEADER_CONTENT_MD5("Content-MD5"); +const std::string HTTP_OUT_HEADER_CONTENT_RANGE("Content-Range"); +const std::string HTTP_OUT_HEADER_CONTENT_TRANSFER_ENCODING("Content-Transfer-Encoding"); +const std::string HTTP_OUT_HEADER_CONTENT_TYPE("Content-Type"); +const std::string HTTP_OUT_HEADER_COOKIE("Cookie"); +const std::string HTTP_OUT_HEADER_DATE("Date"); +const std::string HTTP_OUT_HEADER_DESTINATION("Destination"); +const std::string HTTP_OUT_HEADER_ETAG("ETag"); +const std::string HTTP_OUT_HEADER_EXPECT("Expect"); +const std::string HTTP_OUT_HEADER_EXPIRES("Expires"); +const std::string HTTP_OUT_HEADER_FROM("From"); +const std::string HTTP_OUT_HEADER_HOST("Host"); +const std::string HTTP_OUT_HEADER_IF_MATCH("If-Match"); +const std::string HTTP_OUT_HEADER_IF_MODIFIED_SINCE("If-Modified-Since"); +const std::string HTTP_OUT_HEADER_IF_NONE_MATCH("If-None-Match"); +const std::string HTTP_OUT_HEADER_IF_RANGE("If-Range"); +const std::string HTTP_OUT_HEADER_IF_UNMODIFIED_SINCE("If-Unmodified-Since"); +const std::string HTTP_OUT_HEADER_KEEP_ALIVE("Keep-Alive"); +const std::string HTTP_OUT_HEADER_LAST_MODIFIED("Last-Modified"); +const std::string HTTP_OUT_HEADER_LOCATION("Location"); +const std::string HTTP_OUT_HEADER_MAX_FORWARDS("Max-Forwards"); +const std::string HTTP_OUT_HEADER_MIME_VERSION("MIME-Version"); +const std::string HTTP_OUT_HEADER_PRAGMA("Pragma"); +const std::string HTTP_OUT_HEADER_PROXY_AUTHENTICATE("Proxy-Authenticate"); +const std::string HTTP_OUT_HEADER_PROXY_AUTHORIZATION("Proxy-Authorization"); +const std::string HTTP_OUT_HEADER_RANGE("Range"); +const std::string HTTP_OUT_HEADER_REFERER("Referer"); +const std::string HTTP_OUT_HEADER_RETRY_AFTER("Retry-After"); +const std::string HTTP_OUT_HEADER_SERVER("Server"); +const std::string HTTP_OUT_HEADER_SET_COOKIE("Set-Cookie"); +const std::string HTTP_OUT_HEADER_TE("TE"); +const std::string HTTP_OUT_HEADER_TRAILER("Trailer"); +const std::string HTTP_OUT_HEADER_TRANSFER_ENCODING("Transfer-Encoding"); +const std::string HTTP_OUT_HEADER_UPGRADE("Upgrade"); +const std::string HTTP_OUT_HEADER_USER_AGENT("User-Agent"); +const std::string HTTP_OUT_HEADER_VARY("Vary"); +const std::string HTTP_OUT_HEADER_VIA("Via"); +const std::string HTTP_OUT_HEADER_WARNING("Warning"); +const std::string HTTP_OUT_HEADER_WWW_AUTHENTICATE("WWW-Authenticate"); + +// Incoming headers are normalized to lower-case. +const std::string HTTP_IN_HEADER_ACCEPT_LANGUAGE("accept-language"); +const std::string HTTP_IN_HEADER_CACHE_CONTROL("cache-control"); +const std::string HTTP_IN_HEADER_CONTENT_LENGTH("content-length"); +const std::string HTTP_IN_HEADER_CONTENT_LOCATION("content-location"); +const std::string HTTP_IN_HEADER_CONTENT_TYPE("content-type"); +const std::string HTTP_IN_HEADER_HOST("host"); +const std::string HTTP_IN_HEADER_LOCATION("location"); +const std::string HTTP_IN_HEADER_RETRY_AFTER("retry-after"); +const std::string HTTP_IN_HEADER_SET_COOKIE("set-cookie"); +const std::string HTTP_IN_HEADER_USER_AGENT("user-agent"); +const std::string HTTP_IN_HEADER_X_FORWARDED_FOR("x-forwarded-for"); + +const std::string HTTP_CONTENT_LLSD_XML("application/llsd+xml"); +const std::string HTTP_CONTENT_OCTET_STREAM("application/octet-stream"); +const std::string HTTP_CONTENT_VND_LL_MESH("application/vnd.ll.mesh"); +const std::string HTTP_CONTENT_XML("application/xml"); +const std::string HTTP_CONTENT_JSON("application/json"); +const std::string HTTP_CONTENT_TEXT_HTML("text/html"); +const std::string HTTP_CONTENT_TEXT_HTML_UTF8("text/html; charset=utf-8"); +const std::string HTTP_CONTENT_TEXT_PLAIN_UTF8("text/plain; charset=utf-8"); +const std::string HTTP_CONTENT_TEXT_LLSD("text/llsd"); +const std::string HTTP_CONTENT_TEXT_XML("text/xml"); +const std::string HTTP_CONTENT_TEXT_LSL("text/lsl"); +const std::string HTTP_CONTENT_TEXT_PLAIN("text/plain"); +const std::string HTTP_CONTENT_IMAGE_X_J2C("image/x-j2c"); +const std::string HTTP_CONTENT_IMAGE_J2C("image/j2c"); +const std::string HTTP_CONTENT_IMAGE_JPEG("image/jpeg"); +const std::string HTTP_CONTENT_IMAGE_PNG("image/png"); +const std::string HTTP_CONTENT_IMAGE_BMP("image/bmp"); + +const std::string HTTP_NO_CACHE("no-cache"); +const std::string HTTP_NO_CACHE_CONTROL("no-cache, max-age=0"); + +const std::string HTTP_VERB_INVALID("(invalid)"); +const std::string HTTP_VERB_HEAD("HEAD"); +const std::string HTTP_VERB_GET("GET"); +const std::string HTTP_VERB_PUT("PUT"); +const std::string HTTP_VERB_POST("POST"); +const std::string HTTP_VERB_DELETE("DELETE"); +const std::string HTTP_VERB_MOVE("MOVE"); +const std::string HTTP_VERB_OPTIONS("OPTIONS"); +const std::string HTTP_VERB_PATCH("PATCH"); +const std::string HTTP_VERB_COPY("COPY"); diff --git a/indra/llcorehttp/llhttpconstants.h b/indra/llcorehttp/llhttpconstants.h new file mode 100755 index 0000000000..121448854e --- /dev/null +++ b/indra/llcorehttp/llhttpconstants.h @@ -0,0 +1,219 @@ +/** + * @file llhttpconstants.h + * @brief Constants for HTTP requests and responses + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2001-2014, 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_HTTP_CONSTANTS_H +#define LL_HTTP_CONSTANTS_H + +#include "stdtypes.h" + +/////// HTTP STATUS CODES /////// + +// Standard errors from HTTP spec: +// http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1 +const S32 HTTP_CONTINUE = 100; +const S32 HTTP_SWITCHING_PROTOCOLS = 101; + +// Success +const S32 HTTP_OK = 200; +const S32 HTTP_CREATED = 201; +const S32 HTTP_ACCEPTED = 202; +const S32 HTTP_NON_AUTHORITATIVE_INFORMATION = 203; +const S32 HTTP_NO_CONTENT = 204; +const S32 HTTP_RESET_CONTENT = 205; +const S32 HTTP_PARTIAL_CONTENT = 206; + +// Redirection +const S32 HTTP_MULTIPLE_CHOICES = 300; +const S32 HTTP_MOVED_PERMANENTLY = 301; +const S32 HTTP_FOUND = 302; +const S32 HTTP_SEE_OTHER = 303; +const S32 HTTP_NOT_MODIFIED = 304; +const S32 HTTP_USE_PROXY = 305; +const S32 HTTP_TEMPORARY_REDIRECT = 307; + +// Client Error +const S32 HTTP_BAD_REQUEST = 400; +const S32 HTTP_UNAUTHORIZED = 401; +const S32 HTTP_PAYMENT_REQUIRED = 402; +const S32 HTTP_FORBIDDEN = 403; +const S32 HTTP_NOT_FOUND = 404; +const S32 HTTP_METHOD_NOT_ALLOWED = 405; +const S32 HTTP_NOT_ACCEPTABLE = 406; +const S32 HTTP_PROXY_AUTHENTICATION_REQUIRED = 407; +const S32 HTTP_REQUEST_TIME_OUT = 408; +const S32 HTTP_CONFLICT = 409; +const S32 HTTP_GONE = 410; +const S32 HTTP_LENGTH_REQUIRED = 411; +const S32 HTTP_PRECONDITION_FAILED = 412; +const S32 HTTP_REQUEST_ENTITY_TOO_LARGE = 413; +const S32 HTTP_REQUEST_URI_TOO_LARGE = 414; +const S32 HTTP_UNSUPPORTED_MEDIA_TYPE = 415; +const S32 HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416; +const S32 HTTP_EXPECTATION_FAILED = 417; + +// Server Error +const S32 HTTP_INTERNAL_SERVER_ERROR = 500; +const S32 HTTP_NOT_IMPLEMENTED = 501; +const S32 HTTP_BAD_GATEWAY = 502; +const S32 HTTP_SERVICE_UNAVAILABLE = 503; +const S32 HTTP_GATEWAY_TIME_OUT = 504; +const S32 HTTP_VERSION_NOT_SUPPORTED = 505; + +// We combine internal process errors with status codes +// These status codes should not be sent over the wire +// and indicate something went wrong internally. +// If you get these they are not normal. +const S32 HTTP_INTERNAL_CURL_ERROR = 498; +const S32 HTTP_INTERNAL_ERROR = 499; + + +////// HTTP Methods ////// + +extern const std::string HTTP_VERB_INVALID; +extern const std::string HTTP_VERB_HEAD; +extern const std::string HTTP_VERB_GET; +extern const std::string HTTP_VERB_PUT; +extern const std::string HTTP_VERB_POST; +extern const std::string HTTP_VERB_DELETE; +extern const std::string HTTP_VERB_MOVE; +extern const std::string HTTP_VERB_OPTIONS; + +enum EHTTPMethod +{ + HTTP_INVALID = 0, + HTTP_HEAD, + HTTP_GET, + HTTP_PUT, + HTTP_POST, + HTTP_DELETE, + HTTP_MOVE, // Caller will need to set 'Destination' header + HTTP_OPTIONS, + HTTP_PATCH, + HTTP_COPY, + HTTP_METHOD_COUNT +}; + +// Parses 'Retry-After' header contents and returns seconds until retry should occur. +bool getSecondsUntilRetryAfter(const std::string& retry_after, F32& seconds_to_wait); + +//// HTTP Headers ///// + +// Outgoing headers. Do *not* use these to check incoming headers. +// For incoming headers, use the lower-case headers, below. +extern const std::string HTTP_OUT_HEADER_ACCEPT; +extern const std::string HTTP_OUT_HEADER_ACCEPT_CHARSET; +extern const std::string HTTP_OUT_HEADER_ACCEPT_ENCODING; +extern const std::string HTTP_OUT_HEADER_ACCEPT_LANGUAGE; +extern const std::string HTTP_OUT_HEADER_ACCEPT_RANGES; +extern const std::string HTTP_OUT_HEADER_AGE; +extern const std::string HTTP_OUT_HEADER_ALLOW; +extern const std::string HTTP_OUT_HEADER_AUTHORIZATION; +extern const std::string HTTP_OUT_HEADER_CACHE_CONTROL; +extern const std::string HTTP_OUT_HEADER_CONNECTION; +extern const std::string HTTP_OUT_HEADER_CONTENT_DESCRIPTION; +extern const std::string HTTP_OUT_HEADER_CONTENT_ENCODING; +extern const std::string HTTP_OUT_HEADER_CONTENT_ID; +extern const std::string HTTP_OUT_HEADER_CONTENT_LANGUAGE; +extern const std::string HTTP_OUT_HEADER_CONTENT_LENGTH; +extern const std::string HTTP_OUT_HEADER_CONTENT_LOCATION; +extern const std::string HTTP_OUT_HEADER_CONTENT_MD5; +extern const std::string HTTP_OUT_HEADER_CONTENT_RANGE; +extern const std::string HTTP_OUT_HEADER_CONTENT_TRANSFER_ENCODING; +extern const std::string HTTP_OUT_HEADER_CONTENT_TYPE; +extern const std::string HTTP_OUT_HEADER_COOKIE; +extern const std::string HTTP_OUT_HEADER_DATE; +extern const std::string HTTP_OUT_HEADER_DESTINATION; +extern const std::string HTTP_OUT_HEADER_ETAG; +extern const std::string HTTP_OUT_HEADER_EXPECT; +extern const std::string HTTP_OUT_HEADER_EXPIRES; +extern const std::string HTTP_OUT_HEADER_FROM; +extern const std::string HTTP_OUT_HEADER_HOST; +extern const std::string HTTP_OUT_HEADER_IF_MATCH; +extern const std::string HTTP_OUT_HEADER_IF_MODIFIED_SINCE; +extern const std::string HTTP_OUT_HEADER_IF_NONE_MATCH; +extern const std::string HTTP_OUT_HEADER_IF_RANGE; +extern const std::string HTTP_OUT_HEADER_IF_UNMODIFIED_SINCE; +extern const std::string HTTP_OUT_HEADER_KEEP_ALIVE; +extern const std::string HTTP_OUT_HEADER_LAST_MODIFIED; +extern const std::string HTTP_OUT_HEADER_LOCATION; +extern const std::string HTTP_OUT_HEADER_MAX_FORWARDS; +extern const std::string HTTP_OUT_HEADER_MIME_VERSION; +extern const std::string HTTP_OUT_HEADER_PRAGMA; +extern const std::string HTTP_OUT_HEADER_PROXY_AUTHENTICATE; +extern const std::string HTTP_OUT_HEADER_PROXY_AUTHORIZATION; +extern const std::string HTTP_OUT_HEADER_RANGE; +extern const std::string HTTP_OUT_HEADER_REFERER; +extern const std::string HTTP_OUT_HEADER_RETRY_AFTER; +extern const std::string HTTP_OUT_HEADER_SERVER; +extern const std::string HTTP_OUT_HEADER_SET_COOKIE; +extern const std::string HTTP_OUT_HEADER_TE; +extern const std::string HTTP_OUT_HEADER_TRAILER; +extern const std::string HTTP_OUT_HEADER_TRANSFER_ENCODING; +extern const std::string HTTP_OUT_HEADER_UPGRADE; +extern const std::string HTTP_OUT_HEADER_USER_AGENT; +extern const std::string HTTP_OUT_HEADER_VARY; +extern const std::string HTTP_OUT_HEADER_VIA; +extern const std::string HTTP_OUT_HEADER_WARNING; +extern const std::string HTTP_OUT_HEADER_WWW_AUTHENTICATE; + +// Incoming headers are normalized to lower-case. +extern const std::string HTTP_IN_HEADER_ACCEPT_LANGUAGE; +extern const std::string HTTP_IN_HEADER_CACHE_CONTROL; +extern const std::string HTTP_IN_HEADER_CONTENT_LENGTH; +extern const std::string HTTP_IN_HEADER_CONTENT_LOCATION; +extern const std::string HTTP_IN_HEADER_CONTENT_TYPE; +extern const std::string HTTP_IN_HEADER_HOST; +extern const std::string HTTP_IN_HEADER_LOCATION; +extern const std::string HTTP_IN_HEADER_RETRY_AFTER; +extern const std::string HTTP_IN_HEADER_SET_COOKIE; +extern const std::string HTTP_IN_HEADER_USER_AGENT; +extern const std::string HTTP_IN_HEADER_X_FORWARDED_FOR; + +//// HTTP Content Types //// + +extern const std::string HTTP_CONTENT_LLSD_XML; +extern const std::string HTTP_CONTENT_OCTET_STREAM; +extern const std::string HTTP_CONTENT_VND_LL_MESH; +extern const std::string HTTP_CONTENT_XML; +extern const std::string HTTP_CONTENT_JSON; +extern const std::string HTTP_CONTENT_TEXT_HTML; +extern const std::string HTTP_CONTENT_TEXT_HTML_UTF8; +extern const std::string HTTP_CONTENT_TEXT_PLAIN_UTF8; +extern const std::string HTTP_CONTENT_TEXT_LLSD; +extern const std::string HTTP_CONTENT_TEXT_XML; +extern const std::string HTTP_CONTENT_TEXT_LSL; +extern const std::string HTTP_CONTENT_TEXT_PLAIN; +extern const std::string HTTP_CONTENT_IMAGE_X_J2C; +extern const std::string HTTP_CONTENT_IMAGE_J2C; +extern const std::string HTTP_CONTENT_IMAGE_JPEG; +extern const std::string HTTP_CONTENT_IMAGE_PNG; +extern const std::string HTTP_CONTENT_IMAGE_BMP; + +//// HTTP Cache Settings //// +extern const std::string HTTP_NO_CACHE; +extern const std::string HTTP_NO_CACHE_CONTROL; + +#endif diff --git a/indra/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp index e863ddd13f..bef762f5ce 100755 --- a/indra/llcorehttp/tests/llcorehttp_test.cpp +++ b/indra/llcorehttp/tests/llcorehttp_test.cpp @@ -160,7 +160,7 @@ void stop_thread(LLCore::HttpRequest * req) { if (req) { - req->requestStopThread(NULL); + req->requestStopThread(LLCore::HttpHandler::ptr_t()); int count = 0; int limit = 10; diff --git a/indra/llcorehttp/tests/test_httpoperation.hpp b/indra/llcorehttp/tests/test_httpoperation.hpp index 17b1a96878..e7df2337de 100755 --- a/indra/llcorehttp/tests/test_httpoperation.hpp +++ b/indra/llcorehttp/tests/test_httpoperation.hpp @@ -76,12 +76,12 @@ namespace tut mMemTotal = GetMemTotal(); // create a new ref counted object with an implicit reference - HttpOpNull * op = new HttpOpNull(); - ensure(op->getRefCount() == 1); + HttpOperation::ptr_t op (new HttpOpNull()); + ensure(op.use_count() == 1); ensure(mMemTotal < GetMemTotal()); // release the implicit reference, causing the object to be released - op->release(); + op.reset(); // make sure we didn't leak any memory ensure(mMemTotal == GetMemTotal()); @@ -96,26 +96,24 @@ namespace tut mMemTotal = GetMemTotal(); // Get some handlers - TestHandler * h1 = new TestHandler(); + LLCore::HttpHandler::ptr_t h1 (new TestHandler()); // create a new ref counted object with an implicit reference - HttpOpNull * op = new HttpOpNull(); + HttpOperation::ptr_t op (new HttpOpNull()); // Add the handlers - op->setReplyPath(NULL, h1); + op->setReplyPath(LLCore::HttpOperation::HttpReplyQueuePtr_t(), h1); // Check ref count - ensure(op->getRefCount() == 1); + ensure(op.unique() == 1); // release the reference, releasing the operation but // not the handlers. - op->release(); - op = NULL; + op.reset(); ensure(mMemTotal != GetMemTotal()); // release the handlers - delete h1; - h1 = NULL; + h1.reset(); ensure(mMemTotal == GetMemTotal()); } diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp index 1f606bd0c1..463e55dd7e 100755 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -247,7 +247,7 @@ void HttpRequestTestObjectType::test<2>() ensure("Memory being used", mMemTotal < GetMemTotal()); // Issue a NoOp - HttpHandle handle = req->requestNoOp(NULL); + HttpHandle handle = req->requestNoOp(LLCore::HttpHandler::ptr_t()); ensure("Request issued", handle != LLCORE_HTTP_HANDLE_INVALID); // release the request object @@ -275,6 +275,10 @@ void HttpRequestTestObjectType::test<2>() } } +namespace +{ + void NoOpDeletor(LLCore::HttpHandler *) { } +} template <> template <> void HttpRequestTestObjectType::test<3>() @@ -287,7 +291,8 @@ void HttpRequestTestObjectType::test<3>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); - + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); mHandlerCalls = 0; @@ -296,9 +301,8 @@ void HttpRequestTestObjectType::test<3>() try { - // Get singletons created - HttpRequest::createService(); + HttpRequest::createService(); // Start threading early so that thread memory is invariant // over the test. @@ -309,7 +313,7 @@ void HttpRequestTestObjectType::test<3>() ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); // Issue a NoOp - HttpHandle handle = req->requestNoOp(&handler); + HttpHandle handle = req->requestNoOp(handlerp); ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -324,7 +328,7 @@ void HttpRequestTestObjectType::test<3>() ensure("One handler invocation for request", mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -378,7 +382,10 @@ void HttpRequestTestObjectType::test<4>() // references to it after completion of this method. TestHandler2 handler1(this, "handler1"); TestHandler2 handler2(this, "handler2"); - + + LLCore::HttpHandler::ptr_t handler1p(&handler1, NoOpDeletor); + LLCore::HttpHandler::ptr_t handler2p(&handler2, NoOpDeletor); + // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); mHandlerCalls = 0; @@ -388,7 +395,7 @@ void HttpRequestTestObjectType::test<4>() try { - + // Get singletons created HttpRequest::createService(); @@ -402,11 +409,11 @@ void HttpRequestTestObjectType::test<4>() ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); // Issue some NoOps - HttpHandle handle = req1->requestNoOp(&handler1); + HttpHandle handle = req1->requestNoOp(handler1p); ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); handler1.mExpectHandle = handle; - handle = req2->requestNoOp(&handler2); + handle = req2->requestNoOp(handler2p); ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); handler2.mExpectHandle = handle; @@ -423,7 +430,7 @@ void HttpRequestTestObjectType::test<4>() ensure("One handler invocation for request", mHandlerCalls == 2); // Okay, request a shutdown of the servicing thread - handle = req2->requestStopThread(&handler2); + handle = req2->requestStopThread(handler2p); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); handler2.mExpectHandle = handle; @@ -482,7 +489,8 @@ void HttpRequestTestObjectType::test<5>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); - + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); mHandlerCalls = 0; @@ -491,7 +499,6 @@ void HttpRequestTestObjectType::test<5>() try { - // Get singletons created HttpRequest::createService(); @@ -508,7 +515,7 @@ void HttpRequestTestObjectType::test<5>() ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID); // Issue a NoOp - handle = req->requestNoOp(&handler); + handle = req->requestNoOp(handlerp); ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -567,7 +574,8 @@ void HttpRequestTestObjectType::test<6>() try { - + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + // Get singletons created HttpRequest::createService(); @@ -584,7 +592,7 @@ void HttpRequestTestObjectType::test<6>() ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID); // Issue a NoOp - handle = req->requestNoOp(&handler); + handle = req->requestNoOp(handlerp); ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -632,7 +640,9 @@ void HttpRequestTestObjectType::test<7>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); - + + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); mHandlerCalls = 0; @@ -642,7 +652,7 @@ void HttpRequestTestObjectType::test<7>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -665,7 +675,7 @@ void HttpRequestTestObjectType::test<7>() 0, opts, HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -681,7 +691,7 @@ void HttpRequestTestObjectType::test<7>() // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -749,7 +759,8 @@ void HttpRequestTestObjectType::test<8>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); - + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); mHandlerCalls = 0; @@ -758,7 +769,7 @@ void HttpRequestTestObjectType::test<8>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -776,7 +787,7 @@ void HttpRequestTestObjectType::test<8>() url_base, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -792,7 +803,7 @@ void HttpRequestTestObjectType::test<8>() // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -857,7 +868,8 @@ void HttpRequestTestObjectType::test<9>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); - + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); mHandlerCalls = 0; @@ -866,7 +878,7 @@ void HttpRequestTestObjectType::test<9>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -886,7 +898,7 @@ void HttpRequestTestObjectType::test<9>() 0, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -902,7 +914,7 @@ void HttpRequestTestObjectType::test<9>() // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -967,7 +979,8 @@ void HttpRequestTestObjectType::test<10>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); - + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); mHandlerCalls = 0; @@ -977,7 +990,7 @@ void HttpRequestTestObjectType::test<10>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -998,7 +1011,7 @@ void HttpRequestTestObjectType::test<10>() body, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -1014,7 +1027,7 @@ void HttpRequestTestObjectType::test<10>() // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -1085,7 +1098,8 @@ void HttpRequestTestObjectType::test<11>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); - + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); mHandlerCalls = 0; @@ -1095,7 +1109,7 @@ void HttpRequestTestObjectType::test<11>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -1116,7 +1130,7 @@ void HttpRequestTestObjectType::test<11>() body, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -1132,7 +1146,7 @@ void HttpRequestTestObjectType::test<11>() // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -1204,7 +1218,8 @@ void HttpRequestTestObjectType::test<12>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); - + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); mHandlerCalls = 0; @@ -1213,7 +1228,7 @@ void HttpRequestTestObjectType::test<12>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Enable tracing @@ -1236,7 +1251,7 @@ void HttpRequestTestObjectType::test<12>() 0, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -1252,7 +1267,7 @@ void HttpRequestTestObjectType::test<12>() // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -1321,7 +1336,8 @@ void HttpRequestTestObjectType::test<13>() // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); handler.mHeadersRequired.reserve(20); // Avoid memory leak test failure - + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); mHandlerCalls = 0; @@ -1331,7 +1347,7 @@ void HttpRequestTestObjectType::test<13>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Enable tracing @@ -1360,7 +1376,7 @@ void HttpRequestTestObjectType::test<13>() 0, opts, HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); // release options @@ -1380,7 +1396,7 @@ void HttpRequestTestObjectType::test<13>() // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); handler.mHeadersRequired.clear(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -1443,7 +1459,8 @@ void HttpRequestTestObjectType::test<14>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); - std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); @@ -1454,7 +1471,7 @@ void HttpRequestTestObjectType::test<14>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -1478,7 +1495,7 @@ void HttpRequestTestObjectType::test<14>() 0, opts, HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -1494,7 +1511,7 @@ void HttpRequestTestObjectType::test<14>() // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -1563,6 +1580,7 @@ void HttpRequestTestObjectType::test<15>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); // Load and clear the string setting to preload std::string object // for memory return tests. @@ -1577,7 +1595,7 @@ void HttpRequestTestObjectType::test<15>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -1596,7 +1614,7 @@ void HttpRequestTestObjectType::test<15>() url_base, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -1613,7 +1631,7 @@ void HttpRequestTestObjectType::test<15>() // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); handler.mCheckContentType.clear(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -1682,6 +1700,7 @@ void HttpRequestTestObjectType::test<16>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); @@ -1693,7 +1712,7 @@ void HttpRequestTestObjectType::test<16>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -1762,7 +1781,7 @@ void HttpRequestTestObjectType::test<16>() url_base + "reflect/", options, HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -1839,7 +1858,7 @@ void HttpRequestTestObjectType::test<16>() 47, options, headers, - &handler); + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -1858,7 +1877,7 @@ void HttpRequestTestObjectType::test<16>() mStatus = HttpStatus(); handler.mHeadersRequired.clear(); handler.mHeadersDisallowed.clear(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -1923,6 +1942,7 @@ void HttpRequestTestObjectType::test<17>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); @@ -1935,7 +1955,7 @@ void HttpRequestTestObjectType::test<17>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -2019,7 +2039,7 @@ void HttpRequestTestObjectType::test<17>() ba, options, HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); ba->release(); ba = NULL; @@ -2040,7 +2060,7 @@ void HttpRequestTestObjectType::test<17>() mStatus = HttpStatus(); handler.mHeadersRequired.clear(); handler.mHeadersDisallowed.clear(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -2110,6 +2130,7 @@ void HttpRequestTestObjectType::test<18>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); @@ -2122,7 +2143,7 @@ void HttpRequestTestObjectType::test<18>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -2207,7 +2228,7 @@ void HttpRequestTestObjectType::test<18>() ba, options, HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); ba->release(); ba = NULL; @@ -2228,7 +2249,7 @@ void HttpRequestTestObjectType::test<18>() mStatus = HttpStatus(); handler.mHeadersRequired.clear(); handler.mHeadersDisallowed.clear(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -2298,6 +2319,7 @@ void HttpRequestTestObjectType::test<19>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); @@ -2309,7 +2331,7 @@ void HttpRequestTestObjectType::test<19>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -2397,7 +2419,7 @@ void HttpRequestTestObjectType::test<19>() url_base + "reflect/", options, headers, - &handler); + handlerp); ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. @@ -2415,7 +2437,7 @@ void HttpRequestTestObjectType::test<19>() mStatus = HttpStatus(); handler.mHeadersRequired.clear(); handler.mHeadersDisallowed.clear(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -2480,6 +2502,7 @@ void HttpRequestTestObjectType::test<20>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); @@ -2492,7 +2515,8 @@ void HttpRequestTestObjectType::test<20>() try { - // Get singletons created + + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -2596,7 +2620,7 @@ void HttpRequestTestObjectType::test<20>() ba, options, headers, - &handler); + handlerp); ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); ba->release(); ba = NULL; @@ -2617,7 +2641,7 @@ void HttpRequestTestObjectType::test<20>() mStatus = HttpStatus(); handler.mHeadersRequired.clear(); handler.mHeadersDisallowed.clear(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -2686,6 +2710,7 @@ void HttpRequestTestObjectType::test<21>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); @@ -2698,7 +2723,7 @@ void HttpRequestTestObjectType::test<21>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -2796,7 +2821,7 @@ void HttpRequestTestObjectType::test<21>() ba, options, headers, - &handler); + handlerp); ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); ba->release(); ba = NULL; @@ -2817,7 +2842,7 @@ void HttpRequestTestObjectType::test<21>() mStatus = HttpStatus(); handler.mHeadersRequired.clear(); handler.mHeadersDisallowed.clear(); - handle = req->requestStopThread(&handler); + handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -2882,7 +2907,8 @@ void HttpRequestTestObjectType::test<22>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); - + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); mHandlerCalls = 0; @@ -2892,7 +2918,7 @@ void HttpRequestTestObjectType::test<22>() try { - // options set + // options set options = HttpOptions::ptr_t(new HttpOptions()); options->setRetries(1); // Partial_File is retryable and can timeout in here @@ -2923,7 +2949,7 @@ void HttpRequestTestObjectType::test<22>() 25, options, HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); } @@ -2955,7 +2981,7 @@ void HttpRequestTestObjectType::test<22>() 25, options, HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); } @@ -2987,7 +3013,7 @@ void HttpRequestTestObjectType::test<22>() 25, options, HttpHeaders::ptr_t(), - &handler); + handlerp); ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); } @@ -3007,7 +3033,7 @@ void HttpRequestTestObjectType::test<22>() // ====================================== mStatus = HttpStatus(); mHandlerCalls = 0; - HttpHandle handle = req->requestStopThread(&handler); + HttpHandle handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again @@ -3074,7 +3100,8 @@ void HttpRequestTestObjectType::test<23>() // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. TestHandler2 handler(this, "handler"); - std::string url_base(get_base_url() + "/503/"); // path to 503 generators + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + std::string url_base(get_base_url() + "/503/"); // path to 503 generators // record the total amount of dynamically allocated memory mMemTotal = GetMemTotal(); @@ -3085,7 +3112,7 @@ void HttpRequestTestObjectType::test<23>() try { - // Get singletons created + // Get singletons created HttpRequest::createService(); // Start threading early so that thread memory is invariant @@ -3114,7 +3141,7 @@ void HttpRequestTestObjectType::test<23>() 0, opts, HttpHeaders::ptr_t(), - &handler); + handlerp); std::ostringstream testtag; testtag << "Valid handle returned for 503 request #" << i; @@ -3136,7 +3163,7 @@ void HttpRequestTestObjectType::test<23>() // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); mHandlerCalls = 0; - HttpHandle handle = req->requestStopThread(&handler); + HttpHandle handle = req->requestStopThread(handlerp); ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again diff --git a/indra/llcorehttp/tests/test_httprequestqueue.hpp b/indra/llcorehttp/tests/test_httprequestqueue.hpp index 1de2d8f9ab..ef4ce0479b 100755 --- a/indra/llcorehttp/tests/test_httprequestqueue.hpp +++ b/indra/llcorehttp/tests/test_httprequestqueue.hpp @@ -113,16 +113,16 @@ void HttpRequestqueueTestObjectType::test<3>() HttpRequestQueue * rq = HttpRequestQueue::instanceOf(); - HttpOperation * op = new HttpOpNull(); + HttpOperation::ptr_t op(new HttpOpNull()); rq->addOp(op); // transfer my refcount op = rq->fetchOp(true); // Potentially hangs the test on failure - ensure("One goes in, one comes out", NULL != op); - op->release(); + ensure("One goes in, one comes out", static_cast<bool>(op)); + op.reset(); op = rq->fetchOp(false); - ensure("Better not be two of them", NULL == op); + ensure("Better not be two of them", !op); // release the singleton, hold on to the object HttpRequestQueue::term(); @@ -144,13 +144,13 @@ void HttpRequestqueueTestObjectType::test<4>() HttpRequestQueue * rq = HttpRequestQueue::instanceOf(); - HttpOperation * op = new HttpOpNull(); + HttpOperation::ptr_t op (new HttpOpNull()); rq->addOp(op); // transfer my refcount - op = new HttpOpNull(); + op.reset(new HttpOpNull()); rq->addOp(op); // transfer my refcount - op = new HttpOpNull(); + op.reset(new HttpOpNull()); rq->addOp(op); // transfer my refcount { @@ -159,8 +159,9 @@ void HttpRequestqueueTestObjectType::test<4>() ensure("Three go in, three come out", 3 == ops.size()); op = rq->fetchOp(false); - ensure("Better not be any more of them", NULL == op); - + ensure("Better not be any more of them", !op); + op.reset(); + // release the singleton, hold on to the object HttpRequestQueue::term(); @@ -168,12 +169,13 @@ void HttpRequestqueueTestObjectType::test<4>() ensure(mMemTotal < GetMemTotal()); // Release them - while (! ops.empty()) - { - HttpOperation * op = ops.front(); - ops.erase(ops.begin()); - op->release(); - } + ops.clear(); +// while (! ops.empty()) +// { +// HttpOperation * op = ops.front(); +// ops.erase(ops.begin()); +// op->release(); +// } } // Should be clean |