summaryrefslogtreecommitdiff
path: root/indra/llcorehttp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcorehttp')
-rwxr-xr-xindra/llcorehttp/CMakeLists.txt6
-rwxr-xr-xindra/llcorehttp/_httplibcurl.cpp35
-rwxr-xr-xindra/llcorehttp/_httplibcurl.h8
-rwxr-xr-xindra/llcorehttp/_httpopcancel.h5
-rwxr-xr-xindra/llcorehttp/_httpoperation.cpp123
-rwxr-xr-xindra/llcorehttp/_httpoperation.h52
-rwxr-xr-xindra/llcorehttp/_httpoprequest.cpp43
-rwxr-xr-xindra/llcorehttp/_httpoprequest.h3
-rwxr-xr-xindra/llcorehttp/_httpopsetget.h3
-rwxr-xr-xindra/llcorehttp/_httpopsetpriority.h1
-rwxr-xr-xindra/llcorehttp/_httppolicy.cpp49
-rwxr-xr-xindra/llcorehttp/_httppolicy.h8
-rwxr-xr-xindra/llcorehttp/_httpreadyqueue.h6
-rwxr-xr-xindra/llcorehttp/_httpreplyqueue.cpp19
-rwxr-xr-xindra/llcorehttp/_httpreplyqueue.h23
-rwxr-xr-xindra/llcorehttp/_httprequestqueue.cpp15
-rwxr-xr-xindra/llcorehttp/_httprequestqueue.h8
-rwxr-xr-xindra/llcorehttp/_httpretryqueue.h6
-rwxr-xr-xindra/llcorehttp/_httpservice.cpp19
-rwxr-xr-xindra/llcorehttp/examples/http_texture_load.cpp11
-rwxr-xr-xindra/llcorehttp/httpcommon.cpp179
-rwxr-xr-xindra/llcorehttp/httpcommon.h16
-rwxr-xr-xindra/llcorehttp/httphandler.h3
-rwxr-xr-xindra/llcorehttp/httprequest.cpp217
-rwxr-xr-xindra/llcorehttp/httprequest.h35
-rwxr-xr-xindra/llcorehttp/llhttpconstants.cpp135
-rwxr-xr-xindra/llcorehttp/llhttpconstants.h219
-rwxr-xr-xindra/llcorehttp/tests/llcorehttp_test.cpp2
-rwxr-xr-xindra/llcorehttp/tests/test_httpoperation.hpp20
-rwxr-xr-xindra/llcorehttp/tests/test_httprequest.hpp187
-rwxr-xr-xindra/llcorehttp/tests/test_httprequestqueue.hpp32
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