summaryrefslogtreecommitdiff
path: root/indra/llcorehttp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcorehttp')
-rw-r--r--indra/llcorehttp/_httpinternal.h10
-rw-r--r--indra/llcorehttp/_httplibcurl.cpp710
-rw-r--r--indra/llcorehttp/_httplibcurl.h292
-rw-r--r--indra/llcorehttp/_httpopcancel.cpp18
-rw-r--r--indra/llcorehttp/_httpopcancel.h26
-rw-r--r--indra/llcorehttp/_httpoperation.cpp138
-rw-r--r--indra/llcorehttp/_httpoperation.h222
-rw-r--r--indra/llcorehttp/_httpoprequest.cpp1676
-rw-r--r--indra/llcorehttp/_httpoprequest.h222
-rw-r--r--indra/llcorehttp/_httpopsetget.cpp144
-rw-r--r--indra/llcorehttp/_httpopsetget.h46
-rw-r--r--indra/llcorehttp/_httpopsetpriority.cpp24
-rw-r--r--indra/llcorehttp/_httpopsetpriority.h20
-rw-r--r--indra/llcorehttp/_httppolicy.cpp606
-rw-r--r--indra/llcorehttp/_httppolicy.h214
-rw-r--r--indra/llcorehttp/_httppolicyclass.cpp104
-rw-r--r--indra/llcorehttp/_httppolicyclass.h26
-rw-r--r--indra/llcorehttp/_httppolicyglobal.cpp194
-rw-r--r--indra/llcorehttp/_httppolicyglobal.h42
-rw-r--r--indra/llcorehttp/_httpreadyqueue.h90
-rw-r--r--indra/llcorehttp/_httpreplyqueue.cpp44
-rw-r--r--indra/llcorehttp/_httpreplyqueue.h50
-rw-r--r--indra/llcorehttp/_httprequestqueue.cpp116
-rw-r--r--indra/llcorehttp/_httprequestqueue.h142
-rw-r--r--indra/llcorehttp/_httpretryqueue.h54
-rw-r--r--indra/llcorehttp/_httpservice.cpp1162
-rw-r--r--indra/llcorehttp/_httpservice.h276
-rw-r--r--indra/llcorehttp/_mutex.h4
-rw-r--r--indra/llcorehttp/_refcounted.cpp6
-rw-r--r--indra/llcorehttp/_refcounted.h100
-rw-r--r--indra/llcorehttp/_thread.h124
-rw-r--r--indra/llcorehttp/bufferarray.cpp736
-rw-r--r--indra/llcorehttp/bufferarray.h114
-rw-r--r--indra/llcorehttp/bufferstream.cpp394
-rw-r--r--indra/llcorehttp/bufferstream.h74
-rw-r--r--indra/llcorehttp/examples/http_texture_load.cpp1634
-rw-r--r--indra/llcorehttp/httpcommon.cpp392
-rw-r--r--indra/llcorehttp/httpcommon.h452
-rw-r--r--indra/llcorehttp/httphandler.h50
-rw-r--r--indra/llcorehttp/httpheaders.cpp116
-rw-r--r--indra/llcorehttp/httpheaders.h182
-rw-r--r--indra/llcorehttp/httpoptions.cpp24
-rw-r--r--indra/llcorehttp/httpoptions.h220
-rw-r--r--indra/llcorehttp/httprequest.cpp474
-rw-r--r--indra/llcorehttp/httprequest.h1004
-rw-r--r--indra/llcorehttp/httpresponse.cpp52
-rw-r--r--indra/llcorehttp/httpresponse.h288
-rw-r--r--indra/llcorehttp/httpstats.cpp12
-rw-r--r--indra/llcorehttp/httpstats.h10
-rwxr-xr-xindra/llcorehttp/llhttpconstants.cpp10
-rwxr-xr-xindra/llcorehttp/llhttpconstants.h32
-rwxr-xr-xindra/llcorehttp/tests/llcorehttp_test.cpp148
-rw-r--r--indra/llcorehttp/tests/llcorehttp_test.h26
-rw-r--r--indra/llcorehttp/tests/test_allocator.cpp144
-rw-r--r--indra/llcorehttp/tests/test_allocator.h2
-rw-r--r--indra/llcorehttp/tests/test_bufferarray.hpp576
-rw-r--r--indra/llcorehttp/tests/test_bufferstream.hpp288
-rw-r--r--indra/llcorehttp/tests/test_httpheaders.hpp586
-rw-r--r--indra/llcorehttp/tests/test_httpoperation.hpp106
-rw-r--r--indra/llcorehttp/tests/test_httprequest.hpp5248
-rw-r--r--indra/llcorehttp/tests/test_httprequestqueue.hpp124
-rw-r--r--indra/llcorehttp/tests/test_httpstatus.hpp364
-rwxr-xr-xindra/llcorehttp/tests/test_llcorehttp_peer.py6
-rw-r--r--indra/llcorehttp/tests/test_refcounted.hpp136
64 files changed, 10463 insertions, 10463 deletions
diff --git a/indra/llcorehttp/_httpinternal.h b/indra/llcorehttp/_httpinternal.h
index 690ebbecd8..768ef98330 100644
--- a/indra/llcorehttp/_httpinternal.h
+++ b/indra/llcorehttp/_httpinternal.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_INTERNAL_H_
-#define _LLCORE_HTTP_INTERNAL_H_
+#ifndef _LLCORE_HTTP_INTERNAL_H_
+#define _LLCORE_HTTP_INTERNAL_H_
// If you find this included in a public interface header,
@@ -97,14 +97,14 @@
// Reprioritization requests have the side-effect of then
// putting the modified request at the back of the ready queue.
-#define LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY 1
+#define LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY 1
namespace LLCore
{
// Maxium number of policy classes that can be defined.
-// *TODO: Currently limited to the default class + 1, extend.
+// *TODO: Currently limited to the default class + 1, extend.
// (TSN: should this be more dynamically sized. Is there a reason to hard limit the number of policies?)
const int HTTP_POLICY_CLASS_LIMIT = 32;
@@ -168,4 +168,4 @@ const int HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS = 2;
} // end namespace LLCore
-#endif // _LLCORE_HTTP_INTERNAL_H_
+#endif // _LLCORE_HTTP_INTERNAL_H_
diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp
index bd0ac740db..e646271c84 100644
--- a/indra/llcorehttp/_httplibcurl.cpp
+++ b/indra/llcorehttp/_httplibcurl.cpp
@@ -59,80 +59,80 @@ namespace LLCore
HttpLibcurl::HttpLibcurl(HttpService * service)
- : mService(service),
- mHandleCache(),
- mPolicyCount(0),
- mMultiHandles(NULL),
- mActiveHandles(NULL),
- mDirtyPolicy(NULL)
+ : mService(service),
+ mHandleCache(),
+ mPolicyCount(0),
+ mMultiHandles(NULL),
+ mActiveHandles(NULL),
+ mDirtyPolicy(NULL)
{}
HttpLibcurl::~HttpLibcurl()
{
- shutdown();
+ shutdown();
- mService = NULL;
+ mService = NULL;
}
void HttpLibcurl::shutdown()
{
- while (! mActiveOps.empty())
- {
- HttpOpRequest::ptr_t op(* mActiveOps.begin());
- mActiveOps.erase(mActiveOps.begin());
-
- cancelRequest(op);
- }
-
- if (mMultiHandles)
- {
- for (int policy_class(0); policy_class < mPolicyCount; ++policy_class)
- {
- if (mMultiHandles[policy_class])
- {
- curl_multi_cleanup(mMultiHandles[policy_class]);
- mMultiHandles[policy_class] = 0;
- }
- }
-
- delete [] mMultiHandles;
- mMultiHandles = NULL;
-
- delete [] mActiveHandles;
- mActiveHandles = NULL;
-
- delete [] mDirtyPolicy;
- mDirtyPolicy = NULL;
- }
-
- mPolicyCount = 0;
+ while (! mActiveOps.empty())
+ {
+ HttpOpRequest::ptr_t op(* mActiveOps.begin());
+ mActiveOps.erase(mActiveOps.begin());
+
+ cancelRequest(op);
+ }
+
+ if (mMultiHandles)
+ {
+ for (int policy_class(0); policy_class < mPolicyCount; ++policy_class)
+ {
+ if (mMultiHandles[policy_class])
+ {
+ curl_multi_cleanup(mMultiHandles[policy_class]);
+ mMultiHandles[policy_class] = 0;
+ }
+ }
+
+ delete [] mMultiHandles;
+ mMultiHandles = NULL;
+
+ delete [] mActiveHandles;
+ mActiveHandles = NULL;
+
+ delete [] mDirtyPolicy;
+ mDirtyPolicy = NULL;
+ }
+
+ mPolicyCount = 0;
}
void HttpLibcurl::start(int policy_count)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- llassert_always(policy_count <= HTTP_POLICY_CLASS_LIMIT);
- llassert_always(! mMultiHandles); // One-time call only
-
- mPolicyCount = policy_count;
- mMultiHandles = new CURLM * [mPolicyCount];
- mActiveHandles = new int [mPolicyCount];
- mDirtyPolicy = new bool [mPolicyCount];
-
- for (int policy_class(0); policy_class < mPolicyCount; ++policy_class)
- {
- if (NULL == (mMultiHandles[policy_class] = curl_multi_init()))
- {
- LL_ERRS(LOG_CORE) << "Failed to allocate multi handle in libcurl."
- << LL_ENDL;
- }
- mActiveHandles[policy_class] = 0;
- mDirtyPolicy[policy_class] = false;
- policyUpdated(policy_class);
- }
+ llassert_always(policy_count <= HTTP_POLICY_CLASS_LIMIT);
+ llassert_always(! mMultiHandles); // One-time call only
+
+ mPolicyCount = policy_count;
+ mMultiHandles = new CURLM * [mPolicyCount];
+ mActiveHandles = new int [mPolicyCount];
+ mDirtyPolicy = new bool [mPolicyCount];
+
+ for (int policy_class(0); policy_class < mPolicyCount; ++policy_class)
+ {
+ if (NULL == (mMultiHandles[policy_class] = curl_multi_init()))
+ {
+ LL_ERRS(LOG_CORE) << "Failed to allocate multi handle in libcurl."
+ << LL_ENDL;
+ }
+ mActiveHandles[policy_class] = 0;
+ mDirtyPolicy[policy_class] = false;
+ policyUpdated(policy_class);
+ }
}
@@ -145,40 +145,40 @@ void HttpLibcurl::start(int policy_count)
HttpService::ELoopSpeed HttpLibcurl::processTransport()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- HttpService::ELoopSpeed ret(HttpService::REQUEST_SLEEP);
-
- // Give libcurl some cycles to do I/O & callbacks
- for (int policy_class(0); policy_class < mPolicyCount; ++policy_class)
- {
- if (! mMultiHandles[policy_class])
- {
- // No handle, nothing to do.
- continue;
- }
- if (! mActiveHandles[policy_class])
- {
- // If we've gone quiet and there's a dirty update, apply it,
- // otherwise we're done.
- if (mDirtyPolicy[policy_class])
- {
- policyUpdated(policy_class);
- }
- continue;
- }
-
- int running(0);
- CURLMcode status(CURLM_CALL_MULTI_PERFORM);
- do
- {
+ HttpService::ELoopSpeed ret(HttpService::REQUEST_SLEEP);
+
+ // Give libcurl some cycles to do I/O & callbacks
+ for (int policy_class(0); policy_class < mPolicyCount; ++policy_class)
+ {
+ if (! mMultiHandles[policy_class])
+ {
+ // No handle, nothing to do.
+ continue;
+ }
+ if (! mActiveHandles[policy_class])
+ {
+ // If we've gone quiet and there's a dirty update, apply it,
+ // otherwise we're done.
+ if (mDirtyPolicy[policy_class])
+ {
+ policyUpdated(policy_class);
+ }
+ continue;
+ }
+
+ int running(0);
+ CURLMcode status(CURLM_CALL_MULTI_PERFORM);
+ do
+ {
LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("httppt - curl_multi_perform");
- running = 0;
- status = curl_multi_perform(mMultiHandles[policy_class], &running);
- }
- while (0 != running && CURLM_CALL_MULTI_PERFORM == status);
-
- // Run completion on anything done
- CURLMsg * msg(NULL);
- int msgs_in_queue(0);
+ running = 0;
+ status = curl_multi_perform(mMultiHandles[policy_class], &running);
+ }
+ while (0 != running && CURLM_CALL_MULTI_PERFORM == status);
+
+ // Run completion on anything done
+ CURLMsg * msg(NULL);
+ int msgs_in_queue(0);
{
LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("httppt - curl_multi_info_read");
while ((msg = curl_multi_info_read(mMultiHandles[policy_class], &msgs_in_queue)))
@@ -189,8 +189,8 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport()
CURLcode result(msg->data.result);
completeRequest(mMultiHandles[policy_class], handle, result);
- handle = NULL; // No longer valid on return
- ret = HttpService::NORMAL; // If anything completes, we may have a free slot.
+ handle = NULL; // No longer valid on return
+ ret = HttpService::NORMAL; // If anything completes, we may have a free slot.
// Turning around quickly reduces connection gap by 7-10mS.
}
else if (CURLMSG_NONE == msg->msg)
@@ -207,13 +207,13 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport()
msgs_in_queue = 0;
}
}
- }
+ }
- if (! mActiveOps.empty())
- {
- ret = HttpService::NORMAL;
- }
- return ret;
+ if (! mActiveOps.empty())
+ {
+ ret = HttpService::NORMAL;
+ }
+ return ret;
}
@@ -221,40 +221,40 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport()
void HttpLibcurl::addOp(const HttpOpRequest::ptr_t &op)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- llassert_always(op->mReqPolicy < mPolicyCount);
- llassert_always(mMultiHandles[op->mReqPolicy] != NULL);
-
- // Create standard handle
- if (! op->prepareRequest(mService))
- {
- // Couldn't issue request, fail with notification
- // *TODO: Need failure path
- return;
- }
-
- // Make the request live
- CURLMcode code;
- code = curl_multi_add_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle);
- if (CURLM_OK != code)
- {
- // *TODO: Better cleanup and recovery but not much we can do here.
- check_curl_multi_code(code);
- return;
- }
- op->mCurlActive = true;
- mActiveOps.insert(op);
- ++mActiveHandles[op->mReqPolicy];
-
- if (op->mTracing > HTTP_TRACE_OFF)
- {
- HttpPolicy & policy(mService->getPolicy());
-
- LL_INFOS(LOG_CORE) << "TRACE, ToActiveQueue, Handle: "
+ llassert_always(op->mReqPolicy < mPolicyCount);
+ llassert_always(mMultiHandles[op->mReqPolicy] != NULL);
+
+ // Create standard handle
+ if (! op->prepareRequest(mService))
+ {
+ // Couldn't issue request, fail with notification
+ // *TODO: Need failure path
+ return;
+ }
+
+ // Make the request live
+ CURLMcode code;
+ code = curl_multi_add_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle);
+ if (CURLM_OK != code)
+ {
+ // *TODO: Better cleanup and recovery but not much we can do here.
+ check_curl_multi_code(code);
+ return;
+ }
+ op->mCurlActive = true;
+ mActiveOps.insert(op);
+ ++mActiveHandles[op->mReqPolicy];
+
+ if (op->mTracing > HTTP_TRACE_OFF)
+ {
+ HttpPolicy & policy(mService->getPolicy());
+
+ LL_INFOS(LOG_CORE) << "TRACE, ToActiveQueue, Handle: "
<< op->getHandle()
- << ", Actives: " << mActiveOps.size()
- << ", Readies: " << policy.getReadyCount(op->mReqPolicy)
- << LL_ENDL;
- }
+ << ", Actives: " << mActiveOps.size()
+ << ", Readies: " << policy.getReadyCount(op->mReqPolicy)
+ << LL_ENDL;
+ }
}
@@ -266,20 +266,20 @@ bool HttpLibcurl::cancel(HttpHandle handle)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
HttpOpRequest::ptr_t op = HttpOpRequest::fromHandle<HttpOpRequest>(handle);
- active_set_t::iterator it(mActiveOps.find(op));
- if (mActiveOps.end() == it)
- {
- return false;
- }
+ active_set_t::iterator it(mActiveOps.find(op));
+ if (mActiveOps.end() == it)
+ {
+ return false;
+ }
- // Cancel request
- cancelRequest(op);
+ // Cancel request
+ cancelRequest(op);
- // Drop references
- mActiveOps.erase(it);
- --mActiveHandles[op->mReqPolicy];
+ // Drop references
+ mActiveOps.erase(it);
+ --mActiveHandles[op->mReqPolicy];
- return true;
+ return true;
}
@@ -291,25 +291,25 @@ bool HttpLibcurl::cancel(HttpHandle handle)
void HttpLibcurl::cancelRequest(const HttpOpRequest::ptr_t &op)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- // Deactivate request
- op->mCurlActive = false;
-
- // Detach from multi and recycle handle
- curl_multi_remove_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle);
- mHandleCache.freeHandle(op->mCurlHandle);
- op->mCurlHandle = NULL;
-
- // Tracing
- if (op->mTracing > HTTP_TRACE_OFF)
- {
- LL_INFOS(LOG_CORE) << "TRACE, RequestCanceled, Handle: "
- << op->getHandle()
- << ", Status: " << op->mStatus.toTerseString()
- << LL_ENDL;
- }
-
- // Cancel op and deliver for notification
- op->cancel();
+ // Deactivate request
+ op->mCurlActive = false;
+
+ // Detach from multi and recycle handle
+ curl_multi_remove_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle);
+ mHandleCache.freeHandle(op->mCurlHandle);
+ op->mCurlHandle = NULL;
+
+ // Tracing
+ if (op->mTracing > HTTP_TRACE_OFF)
+ {
+ LL_INFOS(LOG_CORE) << "TRACE, RequestCanceled, Handle: "
+ << op->getHandle()
+ << ", Status: " << op->mStatus.toTerseString()
+ << LL_ENDL;
+ }
+
+ // Cancel op and deliver for notification
+ op->cancel();
}
@@ -322,47 +322,47 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode
CURLcode ccode(CURLE_OK);
- ccode = curl_easy_getinfo(handle, CURLINFO_PRIVATE, &ophandle);
+ ccode = curl_easy_getinfo(handle, CURLINFO_PRIVATE, &ophandle);
if (ccode)
{
LL_WARNS(LOG_CORE) << "libcurl error: " << ccode << " Unable to retrieve operation handle from CURL handle" << LL_ENDL;
return false;
}
HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(ophandle));
-
+
if (!op)
{
LL_WARNS() << "Unable to locate operation by handle. May have expired!" << LL_ENDL;
return false;
}
- if (handle != op->mCurlHandle || ! op->mCurlActive)
- {
- LL_WARNS(LOG_CORE) << "libcurl handle and HttpOpRequest handle in disagreement or inactive request."
- << " Handle: " << static_cast<HttpHandle>(handle)
- << LL_ENDL;
- return false;
- }
-
- active_set_t::iterator it(mActiveOps.find(op));
- if (mActiveOps.end() == it)
- {
- LL_WARNS(LOG_CORE) << "libcurl completion for request not on active list. Continuing."
- << " Handle: " << static_cast<HttpHandle>(handle)
- << LL_ENDL;
- return false;
- }
-
- // Deactivate request
- mActiveOps.erase(it);
- --mActiveHandles[op->mReqPolicy];
- op->mCurlActive = false;
-
- // Set final status of request if it hasn't failed by other mechanisms yet
- if (op->mStatus)
- {
- op->mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, status);
- }
+ if (handle != op->mCurlHandle || ! op->mCurlActive)
+ {
+ LL_WARNS(LOG_CORE) << "libcurl handle and HttpOpRequest handle in disagreement or inactive request."
+ << " Handle: " << static_cast<HttpHandle>(handle)
+ << LL_ENDL;
+ return false;
+ }
+
+ active_set_t::iterator it(mActiveOps.find(op));
+ if (mActiveOps.end() == it)
+ {
+ LL_WARNS(LOG_CORE) << "libcurl completion for request not on active list. Continuing."
+ << " Handle: " << static_cast<HttpHandle>(handle)
+ << LL_ENDL;
+ return false;
+ }
+
+ // Deactivate request
+ mActiveOps.erase(it);
+ --mActiveHandles[op->mReqPolicy];
+ op->mCurlActive = false;
+
+ // Set final status of request if it hasn't failed by other mechanisms yet
+ if (op->mStatus)
+ {
+ op->mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, status);
+ }
if (op->mStatus)
{
// note: CURLINFO_RESPONSE_CODE requires a long - https://curl.haxx.se/libcurl/c/CURLINFO_RESPONSE_CODE.html
@@ -407,7 +407,7 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode
{
LL_WARNS(LOG_CORE) << "Attempt to retrieve status from NULL handle!" << LL_ENDL;
}
- }
+ }
if (multi_handle && handle)
{
@@ -417,115 +417,115 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode
}
else
{
- LL_WARNS(LOG_CORE) << "Curl multi_handle or handle is NULL on remove! multi:"
+ LL_WARNS(LOG_CORE) << "Curl multi_handle or handle is NULL on remove! multi:"
<< std::hex << multi_handle << " h:" << std::hex << handle << std::dec << LL_ENDL;
}
op->mCurlHandle = NULL;
- // Tracing
- if (op->mTracing > HTTP_TRACE_OFF)
- {
- LL_INFOS(LOG_CORE) << "TRACE, RequestComplete, Handle: "
+ // Tracing
+ if (op->mTracing > HTTP_TRACE_OFF)
+ {
+ LL_INFOS(LOG_CORE) << "TRACE, RequestComplete, Handle: "
<< op->getHandle()
- << ", Status: " << op->mStatus.toTerseString()
- << LL_ENDL;
- }
+ << ", Status: " << op->mStatus.toTerseString()
+ << LL_ENDL;
+ }
- // Dispatch to next stage
- HttpPolicy & policy(mService->getPolicy());
- bool still_active(policy.stageAfterCompletion(op));
+ // Dispatch to next stage
+ HttpPolicy & policy(mService->getPolicy());
+ bool still_active(policy.stageAfterCompletion(op));
- return still_active;
+ return still_active;
}
int HttpLibcurl::getActiveCount() const
{
- return mActiveOps.size();
+ return mActiveOps.size();
}
int HttpLibcurl::getActiveCountInClass(int policy_class) const
{
- llassert_always(policy_class < mPolicyCount);
+ llassert_always(policy_class < mPolicyCount);
- return mActiveHandles ? mActiveHandles[policy_class] : 0;
+ return mActiveHandles ? mActiveHandles[policy_class] : 0;
}
void HttpLibcurl::policyUpdated(int policy_class)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- if (policy_class < 0 || policy_class >= mPolicyCount || ! mMultiHandles)
- {
- return;
- }
-
- HttpPolicy & policy(mService->getPolicy());
-
- if (! mActiveHandles[policy_class])
- {
- // Clear to set options. As of libcurl 7.37.0, if a pipelining
- // multi handle has active requests and you try to set the
- // multi handle to non-pipelining, the library gets very angry
- // and goes off the rails corrupting memory. A clue that you're
- // about to crash is that you'll get a missing server response
- // error (curl code 9). So, if options are to be set, we let
- // the multi handle run out of requests, then set options, and
- // re-enable request processing.
- //
- // All of this stall mechanism exists for this reason. If
- // libcurl becomes more resilient later, it should be possible
- // to remove all of this. The connection limit settings are fine,
- // it's just that pipelined-to-non-pipelined transition that
- // is fatal at the moment.
-
- HttpPolicyClass & options(policy.getClassOptions(policy_class));
- CURLM * multi_handle(mMultiHandles[policy_class]);
-
- // Enable policy if stalled
- policy.stallPolicy(policy_class, false);
- mDirtyPolicy[policy_class] = false;
-
- if (options.mPipelining > 1)
- {
- // We'll try to do pipelining on this multihandle
- check_curl_multi_setopt(multi_handle,
- CURLMOPT_PIPELINING,
- 1L);
- check_curl_multi_setopt(multi_handle,
- CURLMOPT_MAX_PIPELINE_LENGTH,
- long(options.mPipelining));
- check_curl_multi_setopt(multi_handle,
- CURLMOPT_MAX_HOST_CONNECTIONS,
- long(options.mPerHostConnectionLimit));
- check_curl_multi_setopt(multi_handle,
- CURLMOPT_MAX_TOTAL_CONNECTIONS,
- long(options.mConnectionLimit));
- }
- else
- {
- check_curl_multi_setopt(multi_handle,
- CURLMOPT_PIPELINING,
- 0L);
- check_curl_multi_setopt(multi_handle,
- CURLMOPT_MAX_HOST_CONNECTIONS,
- 0L);
- check_curl_multi_setopt(multi_handle,
- CURLMOPT_MAX_TOTAL_CONNECTIONS,
- long(options.mConnectionLimit));
- }
- }
- else if (! mDirtyPolicy[policy_class])
- {
- // Mark policy dirty and request a stall in the policy.
- // When policy goes idle, we'll re-invoke this method
- // and perform the change. Don't allow this thread to
- // sleep while we're waiting for quiescence, we'll just
- // stop processing.
- mDirtyPolicy[policy_class] = true;
- policy.stallPolicy(policy_class, true);
- }
+ if (policy_class < 0 || policy_class >= mPolicyCount || ! mMultiHandles)
+ {
+ return;
+ }
+
+ HttpPolicy & policy(mService->getPolicy());
+
+ if (! mActiveHandles[policy_class])
+ {
+ // Clear to set options. As of libcurl 7.37.0, if a pipelining
+ // multi handle has active requests and you try to set the
+ // multi handle to non-pipelining, the library gets very angry
+ // and goes off the rails corrupting memory. A clue that you're
+ // about to crash is that you'll get a missing server response
+ // error (curl code 9). So, if options are to be set, we let
+ // the multi handle run out of requests, then set options, and
+ // re-enable request processing.
+ //
+ // All of this stall mechanism exists for this reason. If
+ // libcurl becomes more resilient later, it should be possible
+ // to remove all of this. The connection limit settings are fine,
+ // it's just that pipelined-to-non-pipelined transition that
+ // is fatal at the moment.
+
+ HttpPolicyClass & options(policy.getClassOptions(policy_class));
+ CURLM * multi_handle(mMultiHandles[policy_class]);
+
+ // Enable policy if stalled
+ policy.stallPolicy(policy_class, false);
+ mDirtyPolicy[policy_class] = false;
+
+ if (options.mPipelining > 1)
+ {
+ // We'll try to do pipelining on this multihandle
+ check_curl_multi_setopt(multi_handle,
+ CURLMOPT_PIPELINING,
+ 1L);
+ check_curl_multi_setopt(multi_handle,
+ CURLMOPT_MAX_PIPELINE_LENGTH,
+ long(options.mPipelining));
+ check_curl_multi_setopt(multi_handle,
+ CURLMOPT_MAX_HOST_CONNECTIONS,
+ long(options.mPerHostConnectionLimit));
+ check_curl_multi_setopt(multi_handle,
+ CURLMOPT_MAX_TOTAL_CONNECTIONS,
+ long(options.mConnectionLimit));
+ }
+ else
+ {
+ check_curl_multi_setopt(multi_handle,
+ CURLMOPT_PIPELINING,
+ 0L);
+ check_curl_multi_setopt(multi_handle,
+ CURLMOPT_MAX_HOST_CONNECTIONS,
+ 0L);
+ check_curl_multi_setopt(multi_handle,
+ CURLMOPT_MAX_TOTAL_CONNECTIONS,
+ long(options.mConnectionLimit));
+ }
+ }
+ else if (! mDirtyPolicy[policy_class])
+ {
+ // Mark policy dirty and request a stall in the policy.
+ // When policy goes idle, we'll re-invoke this method
+ // and perform the change. Don't allow this thread to
+ // sleep while we're waiting for quiescence, we'll just
+ // stop processing.
+ mDirtyPolicy[policy_class] = true;
+ policy.stallPolicy(policy_class, true);
+ }
}
// ---------------------------------------
@@ -533,75 +533,75 @@ void HttpLibcurl::policyUpdated(int policy_class)
// ---------------------------------------
HttpLibcurl::HandleCache::HandleCache()
- : mHandleTemplate(NULL)
+ : mHandleTemplate(NULL)
{
- mCache.reserve(50);
+ mCache.reserve(50);
}
HttpLibcurl::HandleCache::~HandleCache()
{
- if (mHandleTemplate)
- {
- curl_easy_cleanup(mHandleTemplate);
- mHandleTemplate = NULL;
- }
-
- for (handle_cache_t::iterator it(mCache.begin()); mCache.end() != it; ++it)
- {
- curl_easy_cleanup(*it);
- }
- mCache.clear();
+ if (mHandleTemplate)
+ {
+ curl_easy_cleanup(mHandleTemplate);
+ mHandleTemplate = NULL;
+ }
+
+ for (handle_cache_t::iterator it(mCache.begin()); mCache.end() != it; ++it)
+ {
+ curl_easy_cleanup(*it);
+ }
+ mCache.clear();
}
CURL * HttpLibcurl::HandleCache::getHandle()
{
- CURL * ret(NULL);
-
- if (! mCache.empty())
- {
- // Fastest path to handle
- ret = mCache.back();
- mCache.pop_back();
- }
- else if (mHandleTemplate)
- {
- // Still fast path
- ret = curl_easy_duphandle(mHandleTemplate);
- }
- else
- {
- // When all else fails
- ret = curl_easy_init();
- }
-
- return ret;
+ CURL * ret(NULL);
+
+ if (! mCache.empty())
+ {
+ // Fastest path to handle
+ ret = mCache.back();
+ mCache.pop_back();
+ }
+ else if (mHandleTemplate)
+ {
+ // Still fast path
+ ret = curl_easy_duphandle(mHandleTemplate);
+ }
+ else
+ {
+ // When all else fails
+ ret = curl_easy_init();
+ }
+
+ return ret;
}
void HttpLibcurl::HandleCache::freeHandle(CURL * handle)
{
- if (! handle)
- {
- return;
- }
-
- curl_easy_reset(handle);
- if (! mHandleTemplate)
- {
- // Save the first freed handle as a template.
- mHandleTemplate = handle;
- }
- else
- {
- // Otherwise add it to the cache
- if (mCache.size() >= mCache.capacity())
- {
- mCache.reserve(mCache.capacity() + 50);
- }
- mCache.push_back(handle);
- }
+ if (! handle)
+ {
+ return;
+ }
+
+ curl_easy_reset(handle);
+ if (! mHandleTemplate)
+ {
+ // Save the first freed handle as a template.
+ mHandleTemplate = handle;
+ }
+ else
+ {
+ // Otherwise add it to the cache
+ if (mCache.size() >= mCache.capacity())
+ {
+ mCache.reserve(mCache.capacity() + 50);
+ }
+ mCache.push_back(handle);
+ }
}
@@ -612,46 +612,46 @@ void HttpLibcurl::HandleCache::freeHandle(CURL * handle)
struct curl_slist * append_headers_to_slist(const HttpHeaders::ptr_t &headers, struct curl_slist * slist)
{
- const HttpHeaders::const_iterator end(headers->end());
- for (HttpHeaders::const_iterator it(headers->begin()); end != it; ++it)
- {
- static const char sep[] = ": ";
- std::string header;
- header.reserve((*it).first.size() + (*it).second.size() + sizeof(sep));
- header.append((*it).first);
- header.append(sep);
- header.append((*it).second);
-
- slist = curl_slist_append(slist, header.c_str());
- }
- return slist;
+ const HttpHeaders::const_iterator end(headers->end());
+ for (HttpHeaders::const_iterator it(headers->begin()); end != it; ++it)
+ {
+ static const char sep[] = ": ";
+ std::string header;
+ header.reserve((*it).first.size() + (*it).second.size() + sizeof(sep));
+ header.append((*it).first);
+ header.append(sep);
+ header.append((*it).second);
+
+ slist = curl_slist_append(slist, header.c_str());
+ }
+ return slist;
}
} // end namespace LLCore
-namespace
+namespace
{
-
+
void check_curl_multi_code(CURLMcode code, int curl_setopt_option)
{
- if (CURLM_OK != code)
- {
- LL_WARNS(LOG_CORE) << "libcurl multi error detected: " << curl_multi_strerror(code)
- << ", curl_multi_setopt option: " << curl_setopt_option
- << LL_ENDL;
- }
+ if (CURLM_OK != code)
+ {
+ LL_WARNS(LOG_CORE) << "libcurl multi error detected: " << curl_multi_strerror(code)
+ << ", curl_multi_setopt option: " << curl_setopt_option
+ << LL_ENDL;
+ }
}
void check_curl_multi_code(CURLMcode code)
{
- if (CURLM_OK != code)
- {
- LL_WARNS(LOG_CORE) << "libcurl multi error detected: " << curl_multi_strerror(code)
- << LL_ENDL;
- }
+ if (CURLM_OK != code)
+ {
+ LL_WARNS(LOG_CORE) << "libcurl multi error detected: " << curl_multi_strerror(code)
+ << LL_ENDL;
+ }
}
} // end anonymous namespace
diff --git a/indra/llcorehttp/_httplibcurl.h b/indra/llcorehttp/_httplibcurl.h
index 61ecc492af..a1b537d354 100644
--- a/indra/llcorehttp/_httplibcurl.h
+++ b/indra/llcorehttp/_httplibcurl.h
@@ -24,10 +24,10 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_LIBCURL_H_
-#define _LLCORE_HTTP_LIBCURL_H_
+#ifndef _LLCORE_HTTP_LIBCURL_H_
+#define _LLCORE_HTTP_LIBCURL_H_
-#include "linden_common.h" // Modifies curl/curl.h interfaces
+#include "linden_common.h" // Modifies curl/curl.h interfaces
#include <curl/curl.h>
#include <curl/multi.h>
@@ -57,165 +57,165 @@ class HttpHeaders;
class HttpLibcurl
{
public:
- HttpLibcurl(HttpService * service);
- virtual ~HttpLibcurl();
+ HttpLibcurl(HttpService * service);
+ virtual ~HttpLibcurl();
private:
- HttpLibcurl(const HttpLibcurl &); // Not defined
- void operator=(const HttpLibcurl &); // Not defined
+ HttpLibcurl(const HttpLibcurl &); // Not defined
+ void operator=(const HttpLibcurl &); // Not defined
public:
typedef std::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.
- ///
- /// @return Indication of how long this method is
- /// willing to wait for next service call.
- ///
- /// Threading: called by worker thread.
- HttpService::ELoopSpeed processTransport();
-
- /// Add request to the active list. Caller is expected to have
- /// provided us with a reference count on the op to hold the
- /// request. (No additional references will be added.)
- ///
- /// Threading: called by worker thread.
+ /// 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.
+ ///
+ /// @return Indication of how long this method is
+ /// willing to wait for next service call.
+ ///
+ /// Threading: called by worker thread.
+ HttpService::ELoopSpeed processTransport();
+
+ /// Add request to the active list. Caller is expected to have
+ /// provided us with a reference count on the op to hold the
+ /// request. (No additional references will be added.)
+ ///
+ /// Threading: called by worker thread.
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
- /// must agree with HttpPolicy::setPolicies() call.
- ///
- /// Threading: called by init thread.
- void start(int policy_count);
-
- /// Synchronously stop libcurl operations. All active requests
- /// are canceled and removed from libcurl's handling. Easy
- /// handles are detached from their multi handles and released.
- /// Multi handles are also released. Canceled requests are
- /// completed with canceled status and made available on their
- /// respective reply queues.
- ///
- /// Can be restarted with a start() call.
- ///
- /// Threading: called by worker thread.
- void shutdown();
-
- /// Return global and per-class counts of active requests.
- ///
- /// Threading: called by worker thread.
- int getActiveCount() const;
- int getActiveCountInClass(int policy_class) const;
-
- /// Attempt to cancel a request identified by handle.
- ///
- /// Interface shadows HttpService's method.
- ///
- /// @return True if handle was found and operation canceled.
- ///
- /// Threading: called by worker thread.
- bool cancel(HttpHandle handle);
-
- /// Informs transport that a particular policy class has had
- /// options changed and so should effect any transport state
- /// change necessary to effect those changes. Used mainly for
- /// initialization and dynamic option setting.
- ///
- /// Threading: called by worker thread.
- void policyUpdated(int policy_class);
-
- /// Allocate a curl handle for caller. May be freed using
- /// either the freeHandle() method or calling curl_easy_cleanup()
- /// directly.
- ///
- /// @return Libcurl handle (CURL *) or NULL on allocation
- /// problem. Handle will be in curl_easy_reset()
- /// condition.
- ///
- /// Threading: callable by worker thread.
- ///
- /// Deprecation: Expect this to go away after _httpoprequest is
- /// refactored bringing code into this class.
- CURL * getHandle()
- {
- return mHandleCache.getHandle();
- }
+ /// One-time call to set the number of policy classes to be
+ /// serviced and to create the resources for each. Value
+ /// must agree with HttpPolicy::setPolicies() call.
+ ///
+ /// Threading: called by init thread.
+ void start(int policy_count);
+
+ /// Synchronously stop libcurl operations. All active requests
+ /// are canceled and removed from libcurl's handling. Easy
+ /// handles are detached from their multi handles and released.
+ /// Multi handles are also released. Canceled requests are
+ /// completed with canceled status and made available on their
+ /// respective reply queues.
+ ///
+ /// Can be restarted with a start() call.
+ ///
+ /// Threading: called by worker thread.
+ void shutdown();
+
+ /// Return global and per-class counts of active requests.
+ ///
+ /// Threading: called by worker thread.
+ int getActiveCount() const;
+ int getActiveCountInClass(int policy_class) const;
+
+ /// Attempt to cancel a request identified by handle.
+ ///
+ /// Interface shadows HttpService's method.
+ ///
+ /// @return True if handle was found and operation canceled.
+ ///
+ /// Threading: called by worker thread.
+ bool cancel(HttpHandle handle);
+
+ /// Informs transport that a particular policy class has had
+ /// options changed and so should effect any transport state
+ /// change necessary to effect those changes. Used mainly for
+ /// initialization and dynamic option setting.
+ ///
+ /// Threading: called by worker thread.
+ void policyUpdated(int policy_class);
+
+ /// Allocate a curl handle for caller. May be freed using
+ /// either the freeHandle() method or calling curl_easy_cleanup()
+ /// directly.
+ ///
+ /// @return Libcurl handle (CURL *) or NULL on allocation
+ /// problem. Handle will be in curl_easy_reset()
+ /// condition.
+ ///
+ /// Threading: callable by worker thread.
+ ///
+ /// Deprecation: Expect this to go away after _httpoprequest is
+ /// refactored bringing code into this class.
+ CURL * getHandle()
+ {
+ return mHandleCache.getHandle();
+ }
protected:
- /// Invoked when libcurl has indicated a request has been processed
- /// to completion and we need to move the request to a new state.
- bool completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status);
+ /// Invoked when libcurl has indicated a request has been processed
+ /// to completion and we need to move the request to a new state.
+ bool completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status);
- /// Invoked to cancel an active request, mainly during shutdown
- /// and destroy.
+ /// Invoked to cancel an active request, mainly during shutdown
+ /// and destroy.
void cancelRequest(const opReqPtr_t &op);
-
+
protected:
typedef std::set<opReqPtr_t> active_set_t;
- /// Simple request handle cache for libcurl.
- ///
- /// Handle creation is somewhat slow and chunky in libcurl and there's
- /// a pretty good speedup to be had from handle re-use. So, a simple
- /// vector is kept of 'freed' handles to be reused as needed. When
- /// that is empty, the first freed handle is kept as a template for
- /// handle duplication. This is still faster than creation from nothing.
- /// And when that fails, we init fresh from curl_easy_init().
- ///
- /// Handles allocated with getHandle() may be freed with either
- /// freeHandle() or curl_easy_cleanup(). Choice may be dictated
- /// by thread constraints.
- ///
- /// Threading: Single-threaded. May only be used by a single thread,
- /// typically the worker thread. If freeing requests' handles in an
- /// unknown threading context, use curl_easy_cleanup() for safety.
-
- class HandleCache
- {
- public:
- HandleCache();
- ~HandleCache();
-
- private:
- HandleCache(const HandleCache &); // Not defined
- void operator=(const HandleCache &); // Not defined
-
- public:
- /// Allocate a curl handle for caller. May be freed using
- /// either the freeHandle() method or calling curl_easy_cleanup()
- /// directly.
- ///
- /// @return Libcurl handle (CURL *) or NULL on allocation
- /// problem.
- ///
- /// Threading: Single-thread (worker) only.
- CURL * getHandle();
-
- /// Free a libcurl handle acquired by whatever means. Thread
- /// safety is left to the caller.
- ///
- /// Threading: Single-thread (worker) only.
- void freeHandle(CURL * handle);
-
- protected:
- typedef std::vector<CURL *> handle_cache_t;
-
- protected:
- CURL * mHandleTemplate; // Template for duplicating new handles
- handle_cache_t mCache; // Cache of old handles
- }; // end class HandleCache
-
+ /// Simple request handle cache for libcurl.
+ ///
+ /// Handle creation is somewhat slow and chunky in libcurl and there's
+ /// a pretty good speedup to be had from handle re-use. So, a simple
+ /// vector is kept of 'freed' handles to be reused as needed. When
+ /// that is empty, the first freed handle is kept as a template for
+ /// handle duplication. This is still faster than creation from nothing.
+ /// And when that fails, we init fresh from curl_easy_init().
+ ///
+ /// Handles allocated with getHandle() may be freed with either
+ /// freeHandle() or curl_easy_cleanup(). Choice may be dictated
+ /// by thread constraints.
+ ///
+ /// Threading: Single-threaded. May only be used by a single thread,
+ /// typically the worker thread. If freeing requests' handles in an
+ /// unknown threading context, use curl_easy_cleanup() for safety.
+
+ class HandleCache
+ {
+ public:
+ HandleCache();
+ ~HandleCache();
+
+ private:
+ HandleCache(const HandleCache &); // Not defined
+ void operator=(const HandleCache &); // Not defined
+
+ public:
+ /// Allocate a curl handle for caller. May be freed using
+ /// either the freeHandle() method or calling curl_easy_cleanup()
+ /// directly.
+ ///
+ /// @return Libcurl handle (CURL *) or NULL on allocation
+ /// problem.
+ ///
+ /// Threading: Single-thread (worker) only.
+ CURL * getHandle();
+
+ /// Free a libcurl handle acquired by whatever means. Thread
+ /// safety is left to the caller.
+ ///
+ /// Threading: Single-thread (worker) only.
+ void freeHandle(CURL * handle);
+
+ protected:
+ typedef std::vector<CURL *> handle_cache_t;
+
+ protected:
+ CURL * mHandleTemplate; // Template for duplicating new handles
+ handle_cache_t mCache; // Cache of old handles
+ }; // end class HandleCache
+
protected:
- HttpService * mService; // Simple reference, not owner
- HandleCache mHandleCache; // Handle allocator, owner
- active_set_t mActiveOps;
- int mPolicyCount;
- CURLM ** mMultiHandles; // One handle per policy class
- int * mActiveHandles; // Active count per policy class
- bool * mDirtyPolicy; // Dirty policy update waiting for stall (per pc)
-
+ HttpService * mService; // Simple reference, not owner
+ HandleCache mHandleCache; // Handle allocator, owner
+ active_set_t mActiveOps;
+ int mPolicyCount;
+ CURLM ** mMultiHandles; // One handle per policy class
+ int * mActiveHandles; // Active count per policy class
+ bool * mDirtyPolicy; // Dirty policy update waiting for stall (per pc)
+
}; // end class HttpLibcurl
} // end namespace LLCore
diff --git a/indra/llcorehttp/_httpopcancel.cpp b/indra/llcorehttp/_httpopcancel.cpp
index c1912eb3db..3b6cd3caa9 100644
--- a/indra/llcorehttp/_httpopcancel.cpp
+++ b/indra/llcorehttp/_httpopcancel.cpp
@@ -43,8 +43,8 @@ namespace LLCore
HttpOpCancel::HttpOpCancel(HttpHandle handle)
- : HttpOperation(),
- mHandle(handle)
+ : HttpOperation(),
+ mHandle(handle)
{}
@@ -59,15 +59,15 @@ HttpOpCancel::~HttpOpCancel()
// its handler.
void HttpOpCancel::stageFromRequest(HttpService * service)
{
- if (! service->cancel(mHandle))
- {
- mStatus = HttpStatus(HttpStatus::LLCORE, HE_HANDLE_NOT_FOUND);
- }
-
- addAsReply();
+ if (! service->cancel(mHandle))
+ {
+ mStatus = HttpStatus(HttpStatus::LLCORE, HE_HANDLE_NOT_FOUND);
+ }
+
+ addAsReply();
}
} // end namespace LLCore
-
+
diff --git a/indra/llcorehttp/_httpopcancel.h b/indra/llcorehttp/_httpopcancel.h
index 86944eb159..ac71a55f4e 100644
--- a/indra/llcorehttp/_httpopcancel.h
+++ b/indra/llcorehttp/_httpopcancel.h
@@ -24,11 +24,11 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_OPCANCEL_H_
-#define _LLCORE_HTTP_OPCANCEL_H_
+#ifndef _LLCORE_HTTP_OPCANCEL_H_
+#define _LLCORE_HTTP_OPCANCEL_H_
-#include "linden_common.h" // Modifies curl/curl.h interfaces
+#include "linden_common.h" // Modifies curl/curl.h interfaces
#include "httpcommon.h"
@@ -52,22 +52,22 @@ namespace LLCore
class HttpOpCancel : public HttpOperation
{
public:
- /// @param handle Handle of previously-issued request to
- /// be canceled.
- HttpOpCancel(HttpHandle handle);
+ /// @param handle Handle of previously-issued request to
+ /// be canceled.
+ HttpOpCancel(HttpHandle handle);
+
+ virtual ~HttpOpCancel(); // Use release()
- virtual ~HttpOpCancel(); // Use release()
-
public:
- virtual void stageFromRequest(HttpService *);
-
+ virtual void stageFromRequest(HttpService *);
+
public:
- // Request data
- HttpHandle mHandle;
+ // Request data
+ HttpHandle mHandle;
}; // end class HttpOpCancel
} // end namespace LLCore
-#endif // _LLCORE_HTTP_OPCANCEL_H_
+#endif // _LLCORE_HTTP_OPCANCEL_H_
diff --git a/indra/llcorehttp/_httpoperation.cpp b/indra/llcorehttp/_httpoperation.cpp
index c3a9bcaf54..2f6c3fce56 100644
--- a/indra/llcorehttp/_httpoperation.cpp
+++ b/indra/llcorehttp/_httpoperation.cpp
@@ -53,9 +53,9 @@ namespace LLCore
// ==================================
// HttpOperation
// ==================================
-/*static*/
+/*static*/
HttpOperation::handleMap_t HttpOperation::mHandleMap;
-LLCoreInt::HttpMutex HttpOperation::mOpMutex;
+LLCoreInt::HttpMutex HttpOperation::mOpMutex;
HttpOperation::HttpOperation():
std::enable_shared_from_this<HttpOperation>(),
@@ -65,7 +65,7 @@ HttpOperation::HttpOperation():
mTracing(HTTP_TRACE_OFF),
mMyHandle(LLCORE_HTTP_HANDLE_INVALID)
{
- mMetricCreated = totalTime();
+ mMetricCreated = totalTime();
}
@@ -78,63 +78,63 @@ HttpOperation::~HttpOperation()
void HttpOperation::setReplyPath(HttpReplyQueue::ptr_t reply_queue,
- HttpHandler::ptr_t user_handler)
+ HttpHandler::ptr_t user_handler)
{
mReplyQueue.swap(reply_queue);
- mUserHandler.swap(user_handler);
+ mUserHandler.swap(user_handler);
}
void HttpOperation::stageFromRequest(HttpService *)
{
- // Default implementation should never be called. This
- // indicates an operation making a transition that isn't
- // defined.
- LL_ERRS(LOG_CORE) << "Default stageFromRequest method may not be called."
- << LL_ENDL;
+ // Default implementation should never be called. This
+ // indicates an operation making a transition that isn't
+ // defined.
+ LL_ERRS(LOG_CORE) << "Default stageFromRequest method may not be called."
+ << LL_ENDL;
}
void HttpOperation::stageFromReady(HttpService *)
{
- // Default implementation should never be called. This
- // indicates an operation making a transition that isn't
- // defined.
- LL_ERRS(LOG_CORE) << "Default stageFromReady method may not be called."
- << LL_ENDL;
+ // Default implementation should never be called. This
+ // indicates an operation making a transition that isn't
+ // defined.
+ LL_ERRS(LOG_CORE) << "Default stageFromReady method may not be called."
+ << LL_ENDL;
}
void HttpOperation::stageFromActive(HttpService *)
{
- // Default implementation should never be called. This
- // indicates an operation making a transition that isn't
- // defined.
- LL_ERRS(LOG_CORE) << "Default stageFromActive method may not be called."
- << LL_ENDL;
+ // Default implementation should never be called. This
+ // indicates an operation making a transition that isn't
+ // defined.
+ LL_ERRS(LOG_CORE) << "Default stageFromActive method may not be called."
+ << LL_ENDL;
}
void HttpOperation::visitNotifier(HttpRequest *)
{
- if (mUserHandler)
- {
- HttpResponse * response = new HttpResponse();
+ if (mUserHandler)
+ {
+ HttpResponse * response = new HttpResponse();
- response->setStatus(mStatus);
- mUserHandler->onCompleted(getHandle(), response);
+ response->setStatus(mStatus);
+ mUserHandler->onCompleted(getHandle(), response);
- response->release();
- }
+ response->release();
+ }
}
HttpStatus HttpOperation::cancel()
{
- HttpStatus status;
+ HttpStatus status;
- return status;
+ return status;
}
// Handle methods
@@ -196,25 +196,25 @@ HttpOperation::ptr_t HttpOperation::findByHandle(HttpHandle handle)
if (!weak.expired())
return weak.lock();
-
+
return ptr_t();
}
void HttpOperation::addAsReply()
{
- if (mTracing > HTTP_TRACE_OFF)
- {
- LL_INFOS(LOG_CORE) << "TRACE, ToReplyQueue, Handle: "
- << getHandle()
- << LL_ENDL;
- }
-
- if (mReplyQueue)
- {
+ if (mTracing > HTTP_TRACE_OFF)
+ {
+ LL_INFOS(LOG_CORE) << "TRACE, ToReplyQueue, Handle: "
+ << getHandle()
+ << LL_ENDL;
+ }
+
+ if (mReplyQueue)
+ {
HttpOperation::ptr_t op = shared_from_this();
- mReplyQueue->addOp(op);
- }
+ mReplyQueue->addOp(op);
+ }
}
@@ -224,7 +224,7 @@ void HttpOperation::addAsReply()
HttpOpStop::HttpOpStop()
- : HttpOperation()
+ : HttpOperation()
{}
@@ -234,11 +234,11 @@ HttpOpStop::~HttpOpStop()
void HttpOpStop::stageFromRequest(HttpService * service)
{
- // Do operations
- service->stopRequested();
-
- // Prepare response if needed
- addAsReply();
+ // Do operations
+ service->stopRequested();
+
+ // Prepare response if needed
+ addAsReply();
}
@@ -248,7 +248,7 @@ void HttpOpStop::stageFromRequest(HttpService * service)
HttpOpNull::HttpOpNull()
- : HttpOperation()
+ : HttpOperation()
{}
@@ -258,13 +258,13 @@ HttpOpNull::~HttpOpNull()
void HttpOpNull::stageFromRequest(HttpService * service)
{
- // Perform op
- // Nothing to perform. This doesn't fall into the libcurl
- // ready/active queues, it just bounces over to the reply
- // queue directly.
-
- // Prepare response if needed
- addAsReply();
+ // Perform op
+ // Nothing to perform. This doesn't fall into the libcurl
+ // ready/active queues, it just bounces over to the reply
+ // queue directly.
+
+ // Prepare response if needed
+ addAsReply();
}
@@ -274,8 +274,8 @@ void HttpOpNull::stageFromRequest(HttpService * service)
HttpOpSpin::HttpOpSpin(int mode)
- : HttpOperation(),
- mMode(mode)
+ : HttpOperation(),
+ mMode(mode)
{}
@@ -285,20 +285,20 @@ HttpOpSpin::~HttpOpSpin()
void HttpOpSpin::stageFromRequest(HttpService * service)
{
- if (0 == mMode)
- {
- // Spin forever
- while (true)
- {
- ms_sleep(100);
- }
- }
- else
- {
- ms_sleep(1); // backoff interlock plumbing a bit
+ if (0 == mMode)
+ {
+ // Spin forever
+ while (true)
+ {
+ ms_sleep(100);
+ }
+ }
+ else
+ {
+ ms_sleep(1); // backoff interlock plumbing a bit
HttpOperation::ptr_t opptr = shared_from_this();
service->getRequestQueue().addOp(opptr);
- }
+ }
}
diff --git a/indra/llcorehttp/_httpoperation.h b/indra/llcorehttp/_httpoperation.h
index b07ef76d49..ff7efe60e9 100644
--- a/indra/llcorehttp/_httpoperation.h
+++ b/indra/llcorehttp/_httpoperation.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_OPERATION_H_
-#define _LLCORE_HTTP_OPERATION_H_
+#ifndef _LLCORE_HTTP_OPERATION_H_
+#define _LLCORE_HTTP_OPERATION_H_
#include "httpcommon.h"
@@ -76,82 +76,82 @@ public:
typedef std::weak_ptr<HttpOperation> wptr_t;
typedef std::shared_ptr<HttpReplyQueue> HttpReplyQueuePtr_t;
- /// Threading: called by consumer thread.
- HttpOperation();
+ /// Threading: called by consumer thread.
+ HttpOperation();
- /// Threading: called by any thread.
- virtual ~HttpOperation(); // Use release()
+ /// Threading: called by any thread.
+ virtual ~HttpOperation(); // Use release()
public:
- /// Register a reply queue and a handler for completion notifications.
- ///
- /// Invokers of operations that want to receive notification that an
- /// operation has been completed do so by binding a reply queue and
- /// a handler object to the request.
- ///
- /// @param reply_queue Pointer to the reply queue where completion
- /// notifications are to be queued (typically
- /// by addAsReply()). This will typically be
- /// the reply queue referenced by the request
- /// object. This method will increment the
- /// refcount on the queue holding the queue
- /// until delivery is complete. Using a reply_queue
- /// even if the handler is NULL has some benefits
- /// for memory deallocation by keeping it in the
- /// originating thread.
- ///
- /// @param handler Possibly NULL pointer to a non-refcounted
- //// handler object to be invoked (onCompleted)
- /// when the operation is finished. Note that
- /// the handler object is never dereferenced
- /// by the worker thread. This is passible data
- /// until notification is performed.
- ///
- /// Threading: called by consumer thread.
- ///
- 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
- /// request queue to the ready queue via stageFromRequest. Then
- /// from the ready queue to the active queue by stageFromReady. And
- /// when complete, to the reply queue via stageFromActive and the
- /// addAsReply utility.
- ///
- /// Immediate mode operations (everything else) move from the
- /// request queue to the reply queue directly via stageFromRequest
- /// and addAsReply with no existence on the ready or active queues.
- ///
- /// These methods will take out a reference count on the request,
- /// caller only needs to dispose of its reference when done with
- /// the request.
- ///
- /// Threading: called by worker thread.
- ///
- virtual void stageFromRequest(HttpService *);
- virtual void stageFromReady(HttpService *);
- virtual void stageFromActive(HttpService *);
-
- /// Delivers a notification to a handler object on completion.
- ///
- /// Once a request is complete and it has been removed from its
- /// reply queue, a handler notification may be delivered by a
- /// call to HttpRequest::update(). This method does the necessary
- /// dispatching.
- ///
- /// Threading: called by consumer thread.
- ///
- virtual void visitNotifier(HttpRequest *);
-
- /// Cancels the operation whether queued or active.
- /// Final status of the request becomes canceled (an error) and
- /// that will be delivered to caller via notification scheme.
- ///
- /// Threading: called by worker thread.
- ///
- virtual HttpStatus cancel();
+ /// Register a reply queue and a handler for completion notifications.
+ ///
+ /// Invokers of operations that want to receive notification that an
+ /// operation has been completed do so by binding a reply queue and
+ /// a handler object to the request.
+ ///
+ /// @param reply_queue Pointer to the reply queue where completion
+ /// notifications are to be queued (typically
+ /// by addAsReply()). This will typically be
+ /// the reply queue referenced by the request
+ /// object. This method will increment the
+ /// refcount on the queue holding the queue
+ /// until delivery is complete. Using a reply_queue
+ /// even if the handler is NULL has some benefits
+ /// for memory deallocation by keeping it in the
+ /// originating thread.
+ ///
+ /// @param handler Possibly NULL pointer to a non-refcounted
+ //// handler object to be invoked (onCompleted)
+ /// when the operation is finished. Note that
+ /// the handler object is never dereferenced
+ /// by the worker thread. This is passible data
+ /// until notification is performed.
+ ///
+ /// Threading: called by consumer thread.
+ ///
+ 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
+ /// request queue to the ready queue via stageFromRequest. Then
+ /// from the ready queue to the active queue by stageFromReady. And
+ /// when complete, to the reply queue via stageFromActive and the
+ /// addAsReply utility.
+ ///
+ /// Immediate mode operations (everything else) move from the
+ /// request queue to the reply queue directly via stageFromRequest
+ /// and addAsReply with no existence on the ready or active queues.
+ ///
+ /// These methods will take out a reference count on the request,
+ /// caller only needs to dispose of its reference when done with
+ /// the request.
+ ///
+ /// Threading: called by worker thread.
+ ///
+ virtual void stageFromRequest(HttpService *);
+ virtual void stageFromReady(HttpService *);
+ virtual void stageFromActive(HttpService *);
+
+ /// Delivers a notification to a handler object on completion.
+ ///
+ /// Once a request is complete and it has been removed from its
+ /// reply queue, a handler notification may be delivered by a
+ /// call to HttpRequest::update(). This method does the necessary
+ /// dispatching.
+ ///
+ /// Threading: called by consumer thread.
+ ///
+ virtual void visitNotifier(HttpRequest *);
+
+ /// Cancels the operation whether queued or active.
+ /// Final status of the request becomes canceled (an error) and
+ /// that will be delivered to caller via notification scheme.
+ ///
+ /// Threading: called by worker thread.
+ ///
+ virtual HttpStatus cancel();
/// Retrieves a unique handle for this operation.
HttpHandle getHandle();
@@ -164,30 +164,30 @@ public:
return std::shared_ptr< OPT >();
return std::dynamic_pointer_cast< OPT >(ptr);
}
-
+
protected:
- /// Delivers request to reply queue on completion. After this
- /// call, worker thread no longer accesses the object and it
- /// is owned by the reply queue.
- ///
- /// Threading: called by worker thread.
- ///
- void addAsReply();
-
+ /// Delivers request to reply queue on completion. After this
+ /// call, worker thread no longer accesses the object and it
+ /// is owned by the reply queue.
+ ///
+ /// Threading: called by worker thread.
+ ///
+ void addAsReply();
+
protected:
HttpReplyQueuePtr_t mReplyQueue;
- HttpHandler::ptr_t mUserHandler;
+ HttpHandler::ptr_t mUserHandler;
public:
- // Request Data
- HttpRequest::policy_t mReqPolicy;
+ // Request Data
+ HttpRequest::policy_t mReqPolicy;
- // Reply Data
- HttpStatus mStatus;
+ // Reply Data
+ HttpStatus mStatus;
- // Tracing, debug and metrics
- HttpTime mMetricCreated;
- int mTracing;
+ // Tracing, debug and metrics
+ HttpTime mMetricCreated;
+ int mTracing;
private:
typedef std::map<HttpHandle, wptr_t> handleMap_t;
@@ -197,7 +197,7 @@ private:
HttpHandle mMyHandle;
static handleMap_t mHandleMap;
- static LLCoreInt::HttpMutex mOpMutex;
+ static LLCoreInt::HttpMutex mOpMutex;
protected:
static ptr_t findByHandle(HttpHandle handle);
@@ -219,16 +219,16 @@ protected:
class HttpOpStop : public HttpOperation
{
public:
- HttpOpStop();
+ HttpOpStop();
- virtual ~HttpOpStop();
+ virtual ~HttpOpStop();
private:
- HttpOpStop(const HttpOpStop &); // Not defined
- void operator=(const HttpOpStop &); // Not defined
+ HttpOpStop(const HttpOpStop &); // Not defined
+ void operator=(const HttpOpStop &); // Not defined
public:
- virtual void stageFromRequest(HttpService *);
+ virtual void stageFromRequest(HttpService *);
}; // end class HttpOpStop
@@ -241,16 +241,16 @@ public:
class HttpOpNull : public HttpOperation
{
public:
- HttpOpNull();
+ HttpOpNull();
- virtual ~HttpOpNull();
+ virtual ~HttpOpNull();
private:
- HttpOpNull(const HttpOpNull &); // Not defined
- void operator=(const HttpOpNull &); // Not defined
+ HttpOpNull(const HttpOpNull &); // Not defined
+ void operator=(const HttpOpNull &); // Not defined
public:
- virtual void stageFromRequest(HttpService *);
+ virtual void stageFromRequest(HttpService *);
}; // end class HttpOpNull
@@ -261,25 +261,25 @@ public:
class HttpOpSpin : public HttpOperation
{
public:
- // 0 does a hard spin in the operation
- // 1 does a soft spin continuously requeuing itself
- HttpOpSpin(int mode);
+ // 0 does a hard spin in the operation
+ // 1 does a soft spin continuously requeuing itself
+ HttpOpSpin(int mode);
- virtual ~HttpOpSpin();
+ virtual ~HttpOpSpin();
private:
- HttpOpSpin(const HttpOpSpin &); // Not defined
- void operator=(const HttpOpSpin &); // Not defined
+ HttpOpSpin(const HttpOpSpin &); // Not defined
+ void operator=(const HttpOpSpin &); // Not defined
public:
- virtual void stageFromRequest(HttpService *);
+ virtual void stageFromRequest(HttpService *);
protected:
- int mMode;
+ int mMode;
}; // end class HttpOpSpin
} // end namespace LLCore
-#endif // _LLCORE_HTTP_OPERATION_H_
+#endif // _LLCORE_HTTP_OPERATION_H_
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 3247146212..5165a6eb62 100644
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -69,22 +69,22 @@ namespace
// have verified that the header tag is present. The 'buffer' argument
// will be processed by strtok_r calls which will modify the buffer.
//
-// @return -1 if invalid and response should be dropped, 0 if valid an
-// correct, 1 if couldn't be parsed. If 0, the first, last,
-// and length arguments are also written. 'length' may be
-// 0 if the length wasn't available to the server.
+// @return -1 if invalid and response should be dropped, 0 if valid an
+// correct, 1 if couldn't be parsed. If 0, the first, last,
+// and length arguments are also written. 'length' may be
+// 0 if the length wasn't available to the server.
//
int parse_content_range_header(char * buffer,
- unsigned int * first,
- unsigned int * last,
- unsigned int * length);
+ unsigned int * first,
+ unsigned int * last,
+ unsigned int * length);
// Similar for Retry-After headers. Only parses the delta form
// of the header, HTTP time formats aren't interesting for client
// purposes.
//
-// @return 0 if successfully parsed and seconds time delta
-// returned in time argument.
+// @return 0 if successfully parsed and seconds time delta
+// returned in time argument.
//
int parse_retry_after_header(char * buffer, int * time);
@@ -95,7 +95,7 @@ int parse_retry_after_header(char * buffer, int * time);
// non-printing or non-ascii characters are replaced with spaces
// otherwise a %XX form of escaping is used.
void escape_libcurl_debug_data(char * buffer, size_t len, bool scrub,
- std::string & safe_line);
+ std::string & safe_line);
// OS-neutral string comparisons of various types.
@@ -127,73 +127,73 @@ namespace LLCore
HttpOpRequest::HttpOpRequest()
- : HttpOperation(),
- mProcFlags(0U),
- mReqMethod(HOR_GET),
- mReqBody(NULL),
- mReqOffset(0),
- mReqLength(0),
- mReqHeaders(),
- mReqOptions(),
- mCurlActive(false),
- mCurlHandle(NULL),
- mCurlService(NULL),
- mCurlHeaders(NULL),
- mCurlBodyPos(0),
- mCurlTemp(NULL),
- mCurlTempLen(0),
- mReplyBody(NULL),
- mReplyOffset(0),
- mReplyLength(0),
- mReplyFullLength(0),
- mReplyHeaders(),
- mPolicyRetries(0),
- mPolicy503Retries(0),
- mPolicyRetryAt(HttpTime(0)),
- mPolicyRetryLimit(HTTP_RETRY_COUNT_DEFAULT),
- mPolicyMinRetryBackoff(HttpTime(HTTP_RETRY_BACKOFF_MIN_DEFAULT)),
- mPolicyMaxRetryBackoff(HttpTime(HTTP_RETRY_BACKOFF_MAX_DEFAULT)),
- mCallbackSSLVerify(NULL)
+ : HttpOperation(),
+ mProcFlags(0U),
+ mReqMethod(HOR_GET),
+ mReqBody(NULL),
+ mReqOffset(0),
+ mReqLength(0),
+ mReqHeaders(),
+ mReqOptions(),
+ mCurlActive(false),
+ mCurlHandle(NULL),
+ mCurlService(NULL),
+ mCurlHeaders(NULL),
+ mCurlBodyPos(0),
+ mCurlTemp(NULL),
+ mCurlTempLen(0),
+ mReplyBody(NULL),
+ mReplyOffset(0),
+ mReplyLength(0),
+ mReplyFullLength(0),
+ mReplyHeaders(),
+ mPolicyRetries(0),
+ mPolicy503Retries(0),
+ mPolicyRetryAt(HttpTime(0)),
+ mPolicyRetryLimit(HTTP_RETRY_COUNT_DEFAULT),
+ mPolicyMinRetryBackoff(HttpTime(HTTP_RETRY_BACKOFF_MIN_DEFAULT)),
+ mPolicyMaxRetryBackoff(HttpTime(HTTP_RETRY_BACKOFF_MAX_DEFAULT)),
+ mCallbackSSLVerify(NULL)
{
- // *NOTE: As members are added, retry initialization/cleanup
- // may need to be extended in @see prepareRequest().
+ // *NOTE: As members are added, retry initialization/cleanup
+ // may need to be extended in @see prepareRequest().
}
HttpOpRequest::~HttpOpRequest()
{
- if (mReqBody)
- {
- mReqBody->release();
- mReqBody = NULL;
- }
-
- if (mCurlHandle)
- {
- // Uncertain of thread context so free using
- // safest method.
- curl_easy_cleanup(mCurlHandle);
- mCurlHandle = NULL;
- }
-
- mCurlService = NULL;
-
- if (mCurlHeaders)
- {
- curl_slist_free_all(mCurlHeaders);
- mCurlHeaders = NULL;
- }
-
- delete [] mCurlTemp;
- mCurlTemp = NULL;
- mCurlTempLen = 0;
-
- if (mReplyBody)
- {
- mReplyBody->release();
- mReplyBody = NULL;
- }
+ if (mReqBody)
+ {
+ mReqBody->release();
+ mReqBody = NULL;
+ }
+
+ if (mCurlHandle)
+ {
+ // Uncertain of thread context so free using
+ // safest method.
+ curl_easy_cleanup(mCurlHandle);
+ mCurlHandle = NULL;
+ }
+
+ mCurlService = NULL;
+
+ if (mCurlHeaders)
+ {
+ curl_slist_free_all(mCurlHeaders);
+ mCurlHeaders = NULL;
+ }
+
+ delete [] mCurlTemp;
+ mCurlTemp = NULL;
+ mCurlTempLen = 0;
+
+ if (mReplyBody)
+ {
+ mReplyBody->release();
+ mReplyBody = NULL;
+ }
}
@@ -202,7 +202,7 @@ void HttpOpRequest::stageFromRequest(HttpService * service)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
HttpOpRequest::ptr_t self(std::dynamic_pointer_cast<HttpOpRequest>(shared_from_this()));
- service->getPolicy().addOp(self); // transfers refcount
+ service->getPolicy().addOp(self); // transfers refcount
}
@@ -210,86 +210,86 @@ void HttpOpRequest::stageFromReady(HttpService * service)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
HttpOpRequest::ptr_t self(std::dynamic_pointer_cast<HttpOpRequest>(shared_from_this()));
- service->getTransport().addOp(self); // transfers refcount
+ service->getTransport().addOp(self); // transfers refcount
}
void HttpOpRequest::stageFromActive(HttpService * service)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- if (mReplyLength)
- {
- // If non-zero, we received and processed a Content-Range
- // header with the response. If there is received data
- // (and there may not be due to protocol violations,
- // HEAD requests, etc., see BUG-2295) Verify that what it
- // says is consistent with the received data.
- if (mReplyBody && mReplyBody->size() && mReplyLength != mReplyBody->size())
- {
- // Not as expected, fail the request
- mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
- }
- }
-
- if (mCurlHeaders)
- {
- // We take these headers out of the request now as they were
- // allocated originally in this thread and the notifier doesn't
- // need them. This eliminates one source of heap moving across
- // threads.
-
- curl_slist_free_all(mCurlHeaders);
- mCurlHeaders = NULL;
- }
-
- // Also not needed on the other side
- delete [] mCurlTemp;
- mCurlTemp = NULL;
- mCurlTempLen = 0;
-
- addAsReply();
+ if (mReplyLength)
+ {
+ // If non-zero, we received and processed a Content-Range
+ // header with the response. If there is received data
+ // (and there may not be due to protocol violations,
+ // HEAD requests, etc., see BUG-2295) Verify that what it
+ // says is consistent with the received data.
+ if (mReplyBody && mReplyBody->size() && mReplyLength != mReplyBody->size())
+ {
+ // Not as expected, fail the request
+ mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
+ }
+ }
+
+ if (mCurlHeaders)
+ {
+ // We take these headers out of the request now as they were
+ // allocated originally in this thread and the notifier doesn't
+ // need them. This eliminates one source of heap moving across
+ // threads.
+
+ curl_slist_free_all(mCurlHeaders);
+ mCurlHeaders = NULL;
+ }
+
+ // Also not needed on the other side
+ delete [] mCurlTemp;
+ mCurlTemp = NULL;
+ mCurlTempLen = 0;
+
+ addAsReply();
}
void HttpOpRequest::visitNotifier(HttpRequest * request)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- if (mUserHandler)
- {
- HttpResponse * response = new HttpResponse();
- response->setStatus(mStatus);
- response->setBody(mReplyBody);
- response->setHeaders(mReplyHeaders);
+ if (mUserHandler)
+ {
+ HttpResponse * response = new HttpResponse();
+ response->setStatus(mStatus);
+ response->setBody(mReplyBody);
+ response->setHeaders(mReplyHeaders);
response->setRequestURL(mReqURL);
response->setRequestMethod(methodToString(mReqMethod));
if (mReplyOffset || mReplyLength)
- {
- // Got an explicit offset/length in response
- response->setRange(mReplyOffset, mReplyLength, mReplyFullLength);
- }
- response->setContentType(mReplyConType);
- response->setRetries(mPolicyRetries, mPolicy503Retries);
-
- HttpResponse::TransferStats::ptr_t stats = HttpResponse::TransferStats::ptr_t(new HttpResponse::TransferStats);
+ {
+ // Got an explicit offset/length in response
+ response->setRange(mReplyOffset, mReplyLength, mReplyFullLength);
+ }
+ response->setContentType(mReplyConType);
+ response->setRetries(mPolicyRetries, mPolicy503Retries);
- curl_easy_getinfo(mCurlHandle, CURLINFO_SIZE_DOWNLOAD, &stats->mSizeDownload);
- curl_easy_getinfo(mCurlHandle, CURLINFO_TOTAL_TIME, &stats->mTotalTime);
- curl_easy_getinfo(mCurlHandle, CURLINFO_SPEED_DOWNLOAD, &stats->mSpeedDownload);
+ HttpResponse::TransferStats::ptr_t stats = HttpResponse::TransferStats::ptr_t(new HttpResponse::TransferStats);
- response->setTransferStats(stats);
+ curl_easy_getinfo(mCurlHandle, CURLINFO_SIZE_DOWNLOAD, &stats->mSizeDownload);
+ curl_easy_getinfo(mCurlHandle, CURLINFO_TOTAL_TIME, &stats->mTotalTime);
+ curl_easy_getinfo(mCurlHandle, CURLINFO_SPEED_DOWNLOAD, &stats->mSpeedDownload);
- mUserHandler->onCompleted(this->getHandle(), response);
+ response->setTransferStats(stats);
- response->release();
- }
+ mUserHandler->onCompleted(this->getHandle(), response);
+
+ response->release();
+ }
}
// /*static*/
// HttpOpRequest::ptr_t HttpOpRequest::fromHandle(HttpHandle handle)
// {
-//
+//
// return std::dynamic_pointer_cast<HttpOpRequest>((static_cast<HttpOpRequest *>(handle))->shared_from_this());
// }
@@ -297,73 +297,73 @@ void HttpOpRequest::visitNotifier(HttpRequest * request)
HttpStatus HttpOpRequest::cancel()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- mStatus = HttpStatus(HttpStatus::LLCORE, HE_OP_CANCELED);
+ mStatus = HttpStatus(HttpStatus::LLCORE, HE_OP_CANCELED);
- addAsReply();
+ addAsReply();
- return HttpStatus();
+ return HttpStatus();
}
HttpStatus HttpOpRequest::setupGet(HttpRequest::policy_t policy_id,
- const std::string & url,
+ const std::string & url,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers)
+ const HttpHeaders::ptr_t & headers)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- setupCommon(policy_id, url, NULL, options, headers);
- mReqMethod = HOR_GET;
-
- return HttpStatus();
+ setupCommon(policy_id, url, NULL, options, headers);
+ mReqMethod = HOR_GET;
+
+ return HttpStatus();
}
HttpStatus HttpOpRequest::setupGetByteRange(HttpRequest::policy_t policy_id,
- const std::string & url,
- size_t offset,
- size_t len,
+ const std::string & url,
+ size_t offset,
+ size_t len,
const HttpOptions::ptr_t & options,
const HttpHeaders::ptr_t & headers)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- setupCommon(policy_id, url, NULL, options, headers);
- mReqMethod = HOR_GET;
- mReqOffset = offset;
- mReqLength = len;
- if (offset || len)
- {
- mProcFlags |= PF_SCAN_RANGE_HEADER;
- }
-
- return HttpStatus();
+ setupCommon(policy_id, url, NULL, options, headers);
+ mReqMethod = HOR_GET;
+ mReqOffset = offset;
+ mReqLength = len;
+ if (offset || len)
+ {
+ mProcFlags |= PF_SCAN_RANGE_HEADER;
+ }
+
+ return HttpStatus();
}
HttpStatus HttpOpRequest::setupPost(HttpRequest::policy_t policy_id,
- const std::string & url,
- BufferArray * body,
+ const std::string & url,
+ BufferArray * body,
const HttpOptions::ptr_t & options,
const HttpHeaders::ptr_t & headers)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- setupCommon(policy_id, url, body, options, headers);
- mReqMethod = HOR_POST;
-
- return HttpStatus();
+ setupCommon(policy_id, url, body, options, headers);
+ mReqMethod = HOR_POST;
+
+ return HttpStatus();
}
HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id,
- const std::string & url,
- BufferArray * body,
+ const std::string & url,
+ BufferArray * body,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers)
+ const HttpHeaders::ptr_t & headers)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- setupCommon(policy_id, url, body, options, headers);
- mReqMethod = HOR_PUT;
-
- return HttpStatus();
+ setupCommon(policy_id, url, body, options, headers);
+ mReqMethod = HOR_PUT;
+
+ return HttpStatus();
}
@@ -421,42 +421,42 @@ HttpStatus HttpOpRequest::setupMove(HttpRequest::policy_t policy_id,
void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
- const std::string & url,
- BufferArray * body,
+ const std::string & url,
+ BufferArray * body,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers)
+ const HttpHeaders::ptr_t & headers)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- mProcFlags = 0U;
- mReqPolicy = policy_id;
- mReqURL = url;
- if (body)
- {
- body->addRef();
- mReqBody = body;
- }
- if (headers && ! mReqHeaders)
- {
- mReqHeaders = headers;
- }
- if (options && !mReqOptions)
- {
- mReqOptions = options;
- if (options->getWantHeaders())
- {
- mProcFlags |= PF_SAVE_HEADERS;
- }
- if (options->getUseRetryAfter())
- {
- mProcFlags |= PF_USE_RETRY_AFTER;
- }
- mPolicyRetryLimit = options->getRetries();
- mPolicyRetryLimit = llclamp(mPolicyRetryLimit, HTTP_RETRY_COUNT_MIN, HTTP_RETRY_COUNT_MAX);
- mTracing = (std::max)(mTracing, llclamp(options->getTrace(), HTTP_TRACE_MIN, HTTP_TRACE_MAX));
-
- mPolicyMinRetryBackoff = llclamp(options->getMinBackoff(), HttpTime(0), HTTP_RETRY_BACKOFF_MAX);
- mPolicyMaxRetryBackoff = llclamp(options->getMaxBackoff(), mPolicyMinRetryBackoff, HTTP_RETRY_BACKOFF_MAX);
- }
+ mProcFlags = 0U;
+ mReqPolicy = policy_id;
+ mReqURL = url;
+ if (body)
+ {
+ body->addRef();
+ mReqBody = body;
+ }
+ if (headers && ! mReqHeaders)
+ {
+ mReqHeaders = headers;
+ }
+ if (options && !mReqOptions)
+ {
+ mReqOptions = options;
+ if (options->getWantHeaders())
+ {
+ mProcFlags |= PF_SAVE_HEADERS;
+ }
+ if (options->getUseRetryAfter())
+ {
+ mProcFlags |= PF_USE_RETRY_AFTER;
+ }
+ mPolicyRetryLimit = options->getRetries();
+ mPolicyRetryLimit = llclamp(mPolicyRetryLimit, HTTP_RETRY_COUNT_MIN, HTTP_RETRY_COUNT_MAX);
+ mTracing = (std::max)(mTracing, llclamp(options->getTrace(), HTTP_TRACE_MIN, HTTP_TRACE_MAX));
+
+ mPolicyMinRetryBackoff = llclamp(options->getMinBackoff(), HttpTime(0), HTTP_RETRY_BACKOFF_MAX);
+ mPolicyMaxRetryBackoff = llclamp(options->getMaxBackoff(), mPolicyMinRetryBackoff, HTTP_RETRY_BACKOFF_MAX);
+ }
}
// Sets all libcurl options and data for a request.
@@ -470,167 +470,167 @@ void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- // Scrub transport and result data for retried op case
- mCurlActive = false;
- mCurlHandle = NULL;
- mCurlService = NULL;
- if (mCurlHeaders)
- {
- curl_slist_free_all(mCurlHeaders);
- mCurlHeaders = NULL;
- }
- mCurlBodyPos = 0;
-
- if (mReplyBody)
- {
- mReplyBody->release();
- mReplyBody = NULL;
- }
- mReplyOffset = 0;
- mReplyLength = 0;
- mReplyFullLength = 0;
+ // Scrub transport and result data for retried op case
+ mCurlActive = false;
+ mCurlHandle = NULL;
+ mCurlService = NULL;
+ if (mCurlHeaders)
+ {
+ curl_slist_free_all(mCurlHeaders);
+ mCurlHeaders = NULL;
+ }
+ mCurlBodyPos = 0;
+
+ if (mReplyBody)
+ {
+ mReplyBody->release();
+ mReplyBody = NULL;
+ }
+ mReplyOffset = 0;
+ mReplyLength = 0;
+ mReplyFullLength = 0;
mReplyHeaders.reset();
- mReplyConType.clear();
-
- // *FIXME: better error handling later
- HttpStatus status;
-
- // Get global and class policy options
- HttpPolicyGlobal & gpolicy(service->getPolicy().getGlobalOptions());
- HttpPolicyClass & cpolicy(service->getPolicy().getClassOptions(mReqPolicy));
-
- mCurlHandle = service->getTransport().getHandle();
- if (! mCurlHandle)
- {
- // We're in trouble. We'll continue but it won't go well.
- LL_WARNS(LOG_CORE) << "Failed to allocate libcurl easy handle. Continuing."
- << LL_ENDL;
- return HttpStatus(HttpStatus::LLCORE, HE_BAD_ALLOC);
- }
-
- check_curl_easy_setopt(mCurlHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
- check_curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1);
- check_curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1);
- check_curl_easy_setopt(mCurlHandle, CURLOPT_URL, mReqURL.c_str());
- check_curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, getHandle());
- check_curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
-
- check_curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1);
- check_curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT);
- check_curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback);
+ mReplyConType.clear();
+
+ // *FIXME: better error handling later
+ HttpStatus status;
+
+ // Get global and class policy options
+ HttpPolicyGlobal & gpolicy(service->getPolicy().getGlobalOptions());
+ HttpPolicyClass & cpolicy(service->getPolicy().getClassOptions(mReqPolicy));
+
+ mCurlHandle = service->getTransport().getHandle();
+ if (! mCurlHandle)
+ {
+ // We're in trouble. We'll continue but it won't go well.
+ LL_WARNS(LOG_CORE) << "Failed to allocate libcurl easy handle. Continuing."
+ << LL_ENDL;
+ return HttpStatus(HttpStatus::LLCORE, HE_BAD_ALLOC);
+ }
+
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1);
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1);
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_URL, mReqURL.c_str());
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, getHandle());
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
+
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1);
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT);
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback);
check_curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, getHandle());
- check_curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback);
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback);
check_curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, getHandle());
check_curl_easy_setopt(mCurlHandle, CURLOPT_SEEKFUNCTION, seekCallback);
check_curl_easy_setopt(mCurlHandle, CURLOPT_SEEKDATA, getHandle());
- check_curl_easy_setopt(mCurlHandle, CURLOPT_COOKIEFILE, "");
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_COOKIEFILE, "");
- if (gpolicy.mSslCtxCallback)
- {
- check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_FUNCTION, curlSslCtxCallback);
+ if (gpolicy.mSslCtxCallback)
+ {
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_FUNCTION, curlSslCtxCallback);
check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_DATA, getHandle());
- mCallbackSSLVerify = gpolicy.mSslCtxCallback;
- }
+ mCallbackSSLVerify = gpolicy.mSslCtxCallback;
+ }
- long follow_redirect(1L);
- long sslPeerV(0L);
- long sslHostV(0L);
+ long follow_redirect(1L);
+ long sslPeerV(0L);
+ long sslHostV(0L);
long dnsCacheTimeout(-1L);
long nobody(0L);
- if (mReqOptions)
- {
- follow_redirect = mReqOptions->getFollowRedirects() ? 1L : 0L;
- sslPeerV = mReqOptions->getSSLVerifyPeer() ? 1L : 0L;
- sslHostV = mReqOptions->getSSLVerifyHost() ? 2L : 0L;
- dnsCacheTimeout = mReqOptions->getDNSCacheTimeout();
+ if (mReqOptions)
+ {
+ follow_redirect = mReqOptions->getFollowRedirects() ? 1L : 0L;
+ sslPeerV = mReqOptions->getSSLVerifyPeer() ? 1L : 0L;
+ sslHostV = mReqOptions->getSSLVerifyHost() ? 2L : 0L;
+ dnsCacheTimeout = mReqOptions->getDNSCacheTimeout();
nobody = mReqOptions->getHeadersOnly() ? 1L : 0L;
- }
- check_curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect);
+ }
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect);
- check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, sslPeerV);
- check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, sslHostV);
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, sslPeerV);
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, sslHostV);
check_curl_easy_setopt(mCurlHandle, CURLOPT_NOBODY, nobody);
- // 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.
- //
- // -1 stores forever
- // 0 never stores
- // any other positive number specifies seconds
- // supposedly curl 7.62.0 can use TTL by default, otherwise default is 60 seconds
- check_curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, dnsCacheTimeout);
-
- if (gpolicy.mUseLLProxy)
- {
- // Use the viewer-based thread-safe API which has a
- // fast/safe check for proxy enable. Would like to
- // encapsulate this someway...
- // Make sure proxy won't be getInstance() from here,
- // it is not thread safe
- LLProxy::applyProxySettings(mCurlHandle);
-
- }
- else if (gpolicy.mHttpProxy.size())
- {
- // *TODO: This is fine for now but get fuller socks5/
- // authentication thing going later....
- check_curl_easy_setopt(mCurlHandle, CURLOPT_PROXY, gpolicy.mHttpProxy.c_str());
- check_curl_easy_setopt(mCurlHandle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
- }
- if (gpolicy.mCAPath.size())
- {
- check_curl_easy_setopt(mCurlHandle, CURLOPT_CAPATH, gpolicy.mCAPath.c_str());
- }
- if (gpolicy.mCAFile.size())
- {
- check_curl_easy_setopt(mCurlHandle, CURLOPT_CAINFO, gpolicy.mCAFile.c_str());
- }
-
- switch (mReqMethod)
- {
- case HOR_GET:
+ // 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.
+ //
+ // -1 stores forever
+ // 0 never stores
+ // any other positive number specifies seconds
+ // supposedly curl 7.62.0 can use TTL by default, otherwise default is 60 seconds
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, dnsCacheTimeout);
+
+ if (gpolicy.mUseLLProxy)
+ {
+ // Use the viewer-based thread-safe API which has a
+ // fast/safe check for proxy enable. Would like to
+ // encapsulate this someway...
+ // Make sure proxy won't be getInstance() from here,
+ // it is not thread safe
+ LLProxy::applyProxySettings(mCurlHandle);
+
+ }
+ else if (gpolicy.mHttpProxy.size())
+ {
+ // *TODO: This is fine for now but get fuller socks5/
+ // authentication thing going later....
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_PROXY, gpolicy.mHttpProxy.c_str());
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+ }
+ if (gpolicy.mCAPath.size())
+ {
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_CAPATH, gpolicy.mCAPath.c_str());
+ }
+ if (gpolicy.mCAFile.size())
+ {
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_CAINFO, gpolicy.mCAFile.c_str());
+ }
+
+ switch (mReqMethod)
+ {
+ case HOR_GET:
if (nobody == 0)
check_curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1);
- break;
-
- case HOR_POST:
- {
- check_curl_easy_setopt(mCurlHandle, CURLOPT_POST, 1);
- check_curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
- long data_size(0);
- if (mReqBody)
- {
- data_size = mReqBody->size();
- }
- check_curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, static_cast<void *>(NULL));
- check_curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size);
- mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
- }
- break;
-
+ break;
+
+ case HOR_POST:
+ {
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_POST, 1);
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
+ long data_size(0);
+ if (mReqBody)
+ {
+ data_size = mReqBody->size();
+ }
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, static_cast<void *>(NULL));
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size);
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
+ }
+ break;
+
case HOR_PATCH:
check_curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "PATCH");
// fall through. The rest is the same as PUT
case HOR_PUT:
- {
- check_curl_easy_setopt(mCurlHandle, CURLOPT_UPLOAD, 1);
- long data_size(0);
- if (mReqBody)
- {
- data_size = mReqBody->size();
- }
- check_curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size);
- mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
- }
- break;
-
+ {
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_UPLOAD, 1);
+ long data_size(0);
+ if (mReqBody)
+ {
+ data_size = mReqBody->size();
+ }
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size);
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
+ }
+ break;
+
case HOR_DELETE:
check_curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
break;
@@ -643,136 +643,136 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
check_curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "MOVE");
break;
- default:
- LL_ERRS(LOG_CORE) << "Invalid HTTP method in request: "
- << int(mReqMethod) << ". Can't recover."
- << LL_ENDL;
- break;
- }
+ default:
+ LL_ERRS(LOG_CORE) << "Invalid HTTP method in request: "
+ << int(mReqMethod) << ". Can't recover."
+ << LL_ENDL;
+ break;
+ }
// *TODO: Should this be 'Keep-Alive' ?
mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
- // Tracing
- if (mTracing >= HTTP_TRACE_CURL_HEADERS)
- {
- check_curl_easy_setopt(mCurlHandle, CURLOPT_VERBOSE, 1);
- check_curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGDATA, this);
- check_curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGFUNCTION, debugCallback);
- }
-
- // There's a CURLOPT for this now...
- if ((mReqOffset || mReqLength) && HOR_GET == mReqMethod)
- {
- static const char * const fmt1("Range: bytes=%lu-%lu");
- static const char * const fmt2("Range: bytes=%lu-");
-
- char range_line[64];
+ // Tracing
+ if (mTracing >= HTTP_TRACE_CURL_HEADERS)
+ {
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_VERBOSE, 1);
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGDATA, this);
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGFUNCTION, debugCallback);
+ }
+
+ // There's a CURLOPT for this now...
+ if ((mReqOffset || mReqLength) && HOR_GET == mReqMethod)
+ {
+ static const char * const fmt1("Range: bytes=%lu-%lu");
+ static const char * const fmt2("Range: bytes=%lu-");
+
+ char range_line[64];
#if LL_WINDOWS
- _snprintf_s(range_line, sizeof(range_line), sizeof(range_line) - 1,
- (mReqLength ? fmt1 : fmt2),
- (unsigned long) mReqOffset, (unsigned long) (mReqOffset + mReqLength - 1));
+ _snprintf_s(range_line, sizeof(range_line), sizeof(range_line) - 1,
+ (mReqLength ? fmt1 : fmt2),
+ (unsigned long) mReqOffset, (unsigned long) (mReqOffset + mReqLength - 1));
#else
- if ( mReqLength )
- {
- snprintf(range_line, sizeof(range_line),
- fmt1,
- (unsigned long) mReqOffset, (unsigned long) (mReqOffset + mReqLength - 1));
- }
- else
- {
- snprintf(range_line, sizeof(range_line),
- fmt2,
- (unsigned long) mReqOffset);
- }
+ if ( mReqLength )
+ {
+ snprintf(range_line, sizeof(range_line),
+ fmt1,
+ (unsigned long) mReqOffset, (unsigned long) (mReqOffset + mReqLength - 1));
+ }
+ else
+ {
+ snprintf(range_line, sizeof(range_line),
+ fmt2,
+ (unsigned long) mReqOffset);
+ }
#endif // LL_WINDOWS
- range_line[sizeof(range_line) - 1] = '\0';
- mCurlHeaders = curl_slist_append(mCurlHeaders, range_line);
- }
-
- mCurlHeaders = curl_slist_append(mCurlHeaders, "Pragma:");
-
- // Request options
- long timeout(HTTP_REQUEST_TIMEOUT_DEFAULT);
- long xfer_timeout(HTTP_REQUEST_XFER_TIMEOUT_DEFAULT);
- if (mReqOptions)
- {
- timeout = mReqOptions->getTimeout();
- timeout = llclamp(timeout, HTTP_REQUEST_TIMEOUT_MIN, HTTP_REQUEST_TIMEOUT_MAX);
- xfer_timeout = mReqOptions->getTransferTimeout();
- xfer_timeout = llclamp(xfer_timeout, HTTP_REQUEST_TIMEOUT_MIN, HTTP_REQUEST_TIMEOUT_MAX);
- }
- if (xfer_timeout == 0L)
- {
- xfer_timeout = timeout;
- }
- if (cpolicy.mPipelining > 1L)
- {
- // Pipelining affects both connection and transfer timeout values.
- // Requests that are added to a pipeling immediately have completed
- // their connection so the connection delay tends to be less than
- // the non-pipelined value. Transfers are the opposite. Transfer
- // timeout starts once the connection is established and completion
- // can be delayed due to the pipelined requests ahead. So, it's
- // a handwave but bump the transfer timeout up by the pipelining
- // depth to give some room.
- //
- // BUG-7698, BUG-7688, BUG-7694 (others). Scylla and Charybdis
- // situation. Operating against a CDN having service issues may
- // lead to requests stalling for an arbitrarily long time with only
- // the CURLOPT_TIMEOUT value leading to a closed connection. Sadly
- // for pipelining, libcurl (7.39.0 and earlier, at minimum) starts
- // the clock on this value as soon as a request is started down
- // the wire. We want a short value to recover and retry from the
- // CDN. We need a long value to safely deal with a succession of
- // piled-up pipelined requests.
- //
- // *TODO: Find a better scheme than timeouts to guarantee liveness.
- // Progress on the connection is what we really want, not timeouts.
- // But we don't have access to that and the request progress indicators
- // (various libcurl callbacks) have the same problem TIMEOUT does.
- //
- // xfer_timeout *= cpolicy.mPipelining;
- xfer_timeout *= 2L;
-
- // Also try requesting HTTP/2.
+ range_line[sizeof(range_line) - 1] = '\0';
+ mCurlHeaders = curl_slist_append(mCurlHeaders, range_line);
+ }
+
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Pragma:");
+
+ // Request options
+ long timeout(HTTP_REQUEST_TIMEOUT_DEFAULT);
+ long xfer_timeout(HTTP_REQUEST_XFER_TIMEOUT_DEFAULT);
+ if (mReqOptions)
+ {
+ timeout = mReqOptions->getTimeout();
+ timeout = llclamp(timeout, HTTP_REQUEST_TIMEOUT_MIN, HTTP_REQUEST_TIMEOUT_MAX);
+ xfer_timeout = mReqOptions->getTransferTimeout();
+ xfer_timeout = llclamp(xfer_timeout, HTTP_REQUEST_TIMEOUT_MIN, HTTP_REQUEST_TIMEOUT_MAX);
+ }
+ if (xfer_timeout == 0L)
+ {
+ xfer_timeout = timeout;
+ }
+ if (cpolicy.mPipelining > 1L)
+ {
+ // Pipelining affects both connection and transfer timeout values.
+ // Requests that are added to a pipeling immediately have completed
+ // their connection so the connection delay tends to be less than
+ // the non-pipelined value. Transfers are the opposite. Transfer
+ // timeout starts once the connection is established and completion
+ // can be delayed due to the pipelined requests ahead. So, it's
+ // a handwave but bump the transfer timeout up by the pipelining
+ // depth to give some room.
+ //
+ // BUG-7698, BUG-7688, BUG-7694 (others). Scylla and Charybdis
+ // situation. Operating against a CDN having service issues may
+ // lead to requests stalling for an arbitrarily long time with only
+ // the CURLOPT_TIMEOUT value leading to a closed connection. Sadly
+ // for pipelining, libcurl (7.39.0 and earlier, at minimum) starts
+ // the clock on this value as soon as a request is started down
+ // the wire. We want a short value to recover and retry from the
+ // CDN. We need a long value to safely deal with a succession of
+ // piled-up pipelined requests.
+ //
+ // *TODO: Find a better scheme than timeouts to guarantee liveness.
+ // Progress on the connection is what we really want, not timeouts.
+ // But we don't have access to that and the request progress indicators
+ // (various libcurl callbacks) have the same problem TIMEOUT does.
+ //
+ // xfer_timeout *= cpolicy.mPipelining;
+ xfer_timeout *= 2L;
+
+ // Also try requesting HTTP/2.
/******************************/
- // but for test purposes, only if overriding VIEWERASSET
- if (getenv("VIEWERASSET"))
+ // but for test purposes, only if overriding VIEWERASSET
+ if (getenv("VIEWERASSET"))
/******************************/
- check_curl_easy_setopt(mCurlHandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
- }
- // *DEBUG: Enable following override for timeout handling and "[curl:bugs] #1420" tests
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
+ }
+ // *DEBUG: Enable following override for timeout handling and "[curl:bugs] #1420" tests
//if (cpolicy.mPipelining)
//{
// xfer_timeout = 1L;
// timeout = 1L;
//}
- check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMEOUT, xfer_timeout);
- check_curl_easy_setopt(mCurlHandle, CURLOPT_CONNECTTIMEOUT, timeout);
-
- // Request headers
- if (mReqHeaders)
- {
- // Caller's headers last to override
- mCurlHeaders = append_headers_to_slist(mReqHeaders, mCurlHeaders);
- }
- check_curl_easy_setopt(mCurlHandle, CURLOPT_HTTPHEADER, mCurlHeaders);
-
- if (mProcFlags & (PF_SCAN_RANGE_HEADER | PF_SAVE_HEADERS | PF_USE_RETRY_AFTER))
- {
- check_curl_easy_setopt(mCurlHandle, CURLOPT_HEADERFUNCTION, headerCallback);
- check_curl_easy_setopt(mCurlHandle, CURLOPT_HEADERDATA, this);
- }
-
- if (status)
- {
- mCurlService = service;
- }
- return status;
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMEOUT, xfer_timeout);
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_CONNECTTIMEOUT, timeout);
+
+ // Request headers
+ if (mReqHeaders)
+ {
+ // Caller's headers last to override
+ mCurlHeaders = append_headers_to_slist(mReqHeaders, mCurlHeaders);
+ }
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_HTTPHEADER, mCurlHeaders);
+
+ if (mProcFlags & (PF_SCAN_RANGE_HEADER | PF_SAVE_HEADERS | PF_USE_RETRY_AFTER))
+ {
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_HEADERFUNCTION, headerCallback);
+ check_curl_easy_setopt(mCurlHandle, CURLOPT_HEADERDATA, this);
+ }
+
+ if (status)
+ {
+ mCurlService = service;
+ }
+ return status;
}
@@ -781,46 +781,46 @@ size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
- if (! op->mReplyBody)
- {
- op->mReplyBody = new BufferArray();
- }
- const size_t req_size(size * nmemb);
- const size_t write_size(op->mReplyBody->append(static_cast<char *>(data), req_size));
+ if (! op->mReplyBody)
+ {
+ op->mReplyBody = new BufferArray();
+ }
+ const size_t req_size(size * nmemb);
+ const size_t write_size(op->mReplyBody->append(static_cast<char *>(data), req_size));
HTTPStats::instance().recordDataDown(write_size);
- return write_size;
+ return write_size;
}
-
+
size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void * userdata)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
- if (! op->mReqBody)
- {
- return 0;
- }
- const size_t req_size(size * nmemb);
- const size_t body_size(op->mReqBody->size());
- if (body_size <= op->mCurlBodyPos)
- {
- if (body_size < op->mCurlBodyPos)
- {
- // Warn but continue if the read position moves beyond end-of-body
- // for some reason.
- LL_WARNS(LOG_CORE) << "Request body position beyond body size. Truncating request body."
- << LL_ENDL;
- }
- return 0;
- }
-
- const size_t do_size((std::min)(req_size, body_size - op->mCurlBodyPos));
- const size_t read_size(op->mReqBody->read(op->mCurlBodyPos, static_cast<char *>(data), do_size));
+ if (! op->mReqBody)
+ {
+ return 0;
+ }
+ const size_t req_size(size * nmemb);
+ const size_t body_size(op->mReqBody->size());
+ if (body_size <= op->mCurlBodyPos)
+ {
+ if (body_size < op->mCurlBodyPos)
+ {
+ // Warn but continue if the read position moves beyond end-of-body
+ // for some reason.
+ LL_WARNS(LOG_CORE) << "Request body position beyond body size. Truncating request body."
+ << LL_ENDL;
+ }
+ return 0;
+ }
+
+ const size_t do_size((std::min)(req_size, body_size - op->mCurlBodyPos));
+ const size_t read_size(op->mReqBody->read(op->mCurlBodyPos, static_cast<char *>(data), do_size));
// FIXME: singleton's instance() is Thread unsafe! Even if stats accumulators inside are.
HTTPStats::instance().recordDataUp(read_size);
op->mCurlBodyPos += read_size;
- return read_size;
+ return read_size;
}
@@ -855,154 +855,154 @@ int HttpOpRequest::seekCallback(void *userdata, curl_off_t offset, int origin)
return 0;
}
-
+
size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, void * userdata)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- static const char status_line[] = "HTTP/";
- static const size_t status_line_len = sizeof(status_line) - 1;
- static const char con_ran_line[] = "content-range";
- static const char con_retry_line[] = "retry-after";
-
+ static const char status_line[] = "HTTP/";
+ static const size_t status_line_len = sizeof(status_line) - 1;
+ static const char con_ran_line[] = "content-range";
+ static const char con_retry_line[] = "retry-after";
+
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
- bool is_header(true);
-
- if (hdr_size >= status_line_len && ! strncmp(status_line, hdr_data, status_line_len))
- {
- // One of possibly several status lines. Reset what we know and start over
- // taking results from the last header stanza we receive.
- op->mReplyOffset = 0;
- op->mReplyLength = 0;
- op->mReplyFullLength = 0;
- op->mReplyRetryAfter = 0;
- op->mStatus = HttpStatus();
- if (op->mReplyHeaders)
- {
- op->mReplyHeaders->clear();
- }
- is_header = false;
- }
-
- // Nothing in here wants a final CR/LF combination. Remove
- // it as much as possible.
- size_t wanted_hdr_size(hdr_size);
- if (wanted_hdr_size && '\n' == hdr_data[wanted_hdr_size - 1])
- {
- if (--wanted_hdr_size && '\r' == hdr_data[wanted_hdr_size - 1])
- {
- --wanted_hdr_size;
- }
- }
-
- // Copy and normalize header fragments for the following
- // stages. Would like to modify the data in-place but that
- // may not be allowed and we need one byte extra for NUL.
- // At the end of this we will have:
- //
- // If ':' present in header:
- // 1. name points to text to left of colon which
- // will be ascii lower-cased and left and right
- // trimmed of whitespace.
- // 2. value points to text to right of colon which
- // will be left trimmed of whitespace.
- // Otherwise:
- // 1. name points to header which will be left
- // trimmed of whitespace.
- // 2. value is NULL
- // Any non-NULL pointer may point to a zero-length string.
- //
- if (wanted_hdr_size >= op->mCurlTempLen)
- {
- delete [] op->mCurlTemp;
- op->mCurlTempLen = 2 * wanted_hdr_size + 1;
- op->mCurlTemp = new char [op->mCurlTempLen];
- }
- memcpy(op->mCurlTemp, hdr_data, wanted_hdr_size);
- op->mCurlTemp[wanted_hdr_size] = '\0';
- char * name(op->mCurlTemp);
- char * value(strchr(name, ':'));
- if (value)
- {
- *value++ = '\0';
- os_strlower(name);
- name = os_strtrim(name);
- value = os_strltrim(value);
- }
- else
- {
- // Doesn't look well-formed, do minimal normalization on it
- name = os_strltrim(name);
- }
-
- // Normalized, now reject headers with empty names.
- if (! *name)
- {
- // No use continuing
- return hdr_size;
- }
-
- // Save header if caller wants them in the response
- if (is_header && op->mProcFlags & PF_SAVE_HEADERS)
- {
- // Save headers in response
- if (! op->mReplyHeaders)
- {
- op->mReplyHeaders = HttpHeaders::ptr_t(new HttpHeaders);
- }
- op->mReplyHeaders->append(name, value ? value : "");
- }
-
- // From this point, header-specific processors are free to
- // modify the header value.
-
- // Detect and parse 'Content-Range' headers
- if (is_header
- && op->mProcFlags & PF_SCAN_RANGE_HEADER
- && value && *value
- && ! strcmp(name, con_ran_line))
- {
- unsigned int first(0), last(0), length(0);
- int status;
-
- if (! (status = parse_content_range_header(value, &first, &last, &length)))
- {
- // Success, record the fragment position
- op->mReplyOffset = first;
- op->mReplyLength = last - first + 1;
- op->mReplyFullLength = length;
- }
- else if (-1 == status)
- {
- // Response is badly formed and shouldn't be accepted
- op->mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
- }
- else
- {
- // Ignore the unparsable.
- LL_INFOS_ONCE(LOG_CORE) << "Problem parsing odd Content-Range header: '"
- << std::string(hdr_data, wanted_hdr_size)
- << "'. Ignoring."
- << LL_ENDL;
- }
- }
-
- // Detect and parse 'Retry-After' headers
- if (is_header
- && op->mProcFlags & PF_USE_RETRY_AFTER
- && value && *value
- && ! strcmp(name, con_retry_line))
- {
- int time(0);
- if (! parse_retry_after_header(value, &time))
- {
- op->mReplyRetryAfter = time;
- }
- }
-
- return hdr_size;
+ const size_t hdr_size(size * nmemb);
+ const char * hdr_data(static_cast<const char *>(data)); // Not null terminated
+ bool is_header(true);
+
+ if (hdr_size >= status_line_len && ! strncmp(status_line, hdr_data, status_line_len))
+ {
+ // One of possibly several status lines. Reset what we know and start over
+ // taking results from the last header stanza we receive.
+ op->mReplyOffset = 0;
+ op->mReplyLength = 0;
+ op->mReplyFullLength = 0;
+ op->mReplyRetryAfter = 0;
+ op->mStatus = HttpStatus();
+ if (op->mReplyHeaders)
+ {
+ op->mReplyHeaders->clear();
+ }
+ is_header = false;
+ }
+
+ // Nothing in here wants a final CR/LF combination. Remove
+ // it as much as possible.
+ size_t wanted_hdr_size(hdr_size);
+ if (wanted_hdr_size && '\n' == hdr_data[wanted_hdr_size - 1])
+ {
+ if (--wanted_hdr_size && '\r' == hdr_data[wanted_hdr_size - 1])
+ {
+ --wanted_hdr_size;
+ }
+ }
+
+ // Copy and normalize header fragments for the following
+ // stages. Would like to modify the data in-place but that
+ // may not be allowed and we need one byte extra for NUL.
+ // At the end of this we will have:
+ //
+ // If ':' present in header:
+ // 1. name points to text to left of colon which
+ // will be ascii lower-cased and left and right
+ // trimmed of whitespace.
+ // 2. value points to text to right of colon which
+ // will be left trimmed of whitespace.
+ // Otherwise:
+ // 1. name points to header which will be left
+ // trimmed of whitespace.
+ // 2. value is NULL
+ // Any non-NULL pointer may point to a zero-length string.
+ //
+ if (wanted_hdr_size >= op->mCurlTempLen)
+ {
+ delete [] op->mCurlTemp;
+ op->mCurlTempLen = 2 * wanted_hdr_size + 1;
+ op->mCurlTemp = new char [op->mCurlTempLen];
+ }
+ memcpy(op->mCurlTemp, hdr_data, wanted_hdr_size);
+ op->mCurlTemp[wanted_hdr_size] = '\0';
+ char * name(op->mCurlTemp);
+ char * value(strchr(name, ':'));
+ if (value)
+ {
+ *value++ = '\0';
+ os_strlower(name);
+ name = os_strtrim(name);
+ value = os_strltrim(value);
+ }
+ else
+ {
+ // Doesn't look well-formed, do minimal normalization on it
+ name = os_strltrim(name);
+ }
+
+ // Normalized, now reject headers with empty names.
+ if (! *name)
+ {
+ // No use continuing
+ return hdr_size;
+ }
+
+ // Save header if caller wants them in the response
+ if (is_header && op->mProcFlags & PF_SAVE_HEADERS)
+ {
+ // Save headers in response
+ if (! op->mReplyHeaders)
+ {
+ op->mReplyHeaders = HttpHeaders::ptr_t(new HttpHeaders);
+ }
+ op->mReplyHeaders->append(name, value ? value : "");
+ }
+
+ // From this point, header-specific processors are free to
+ // modify the header value.
+
+ // Detect and parse 'Content-Range' headers
+ if (is_header
+ && op->mProcFlags & PF_SCAN_RANGE_HEADER
+ && value && *value
+ && ! strcmp(name, con_ran_line))
+ {
+ unsigned int first(0), last(0), length(0);
+ int status;
+
+ if (! (status = parse_content_range_header(value, &first, &last, &length)))
+ {
+ // Success, record the fragment position
+ op->mReplyOffset = first;
+ op->mReplyLength = last - first + 1;
+ op->mReplyFullLength = length;
+ }
+ else if (-1 == status)
+ {
+ // Response is badly formed and shouldn't be accepted
+ op->mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
+ }
+ else
+ {
+ // Ignore the unparsable.
+ LL_INFOS_ONCE(LOG_CORE) << "Problem parsing odd Content-Range header: '"
+ << std::string(hdr_data, wanted_hdr_size)
+ << "'. Ignoring."
+ << LL_ENDL;
+ }
+ }
+
+ // Detect and parse 'Retry-After' headers
+ if (is_header
+ && op->mProcFlags & PF_USE_RETRY_AFTER
+ && value && *value
+ && ! strcmp(name, con_retry_line))
+ {
+ int time(0);
+ if (! parse_retry_after_header(value, &time))
+ {
+ op->mReplyRetryAfter = time;
+ }
+ }
+
+ return hdr_size;
}
@@ -1025,12 +1025,12 @@ CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userd
// Ex: setting urls (assume non-SL) for parcel media in LLFloaterURLEntry
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
}
- // set the verification callback.
- SSL_CTX_set_cert_verify_callback(ctx, sslCertVerifyCallback, userdata);
- // the calls are void
- }
+ // set the verification callback.
+ SSL_CTX_set_cert_verify_callback(ctx, sslCertVerifyCallback, userdata);
+ // the calls are void
+ }
- return CURLE_OK;
+ return CURLE_OK;
}
int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
@@ -1038,12 +1038,12 @@ int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(param));
- if (op->mCallbackSSLVerify)
- {
- op->mStatus = op->mCallbackSSLVerify(op->mReqURL, op->mUserHandler, ctx);
- }
+ if (op->mCallbackSSLVerify)
+ {
+ op->mStatus = op->mCallbackSSLVerify(op->mReqURL, op->mUserHandler, ctx);
+ }
- return (op->mStatus) ? 1 : 0;
+ return (op->mStatus) ? 1 : 0;
}
int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffer, size_t len, void * userdata)
@@ -1051,91 +1051,91 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));
- std::string safe_line;
- std::string tag;
- bool logit(false);
- const size_t log_len((std::min)(len, size_t(256))); // Keep things reasonable in all cases
-
- switch (info)
- {
- case CURLINFO_TEXT:
- if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
- {
- tag = "TEXT";
- escape_libcurl_debug_data(buffer, log_len, true, safe_line);
- logit = true;
- }
- break;
-
- case CURLINFO_HEADER_IN:
- if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
- {
- tag = "HEADERIN";
- escape_libcurl_debug_data(buffer, log_len, true, safe_line);
- logit = true;
- }
- break;
-
- case CURLINFO_HEADER_OUT:
- if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
- {
- tag = "HEADEROUT";
- escape_libcurl_debug_data(buffer, log_len, true, safe_line); // Goes out as one line unlike header_in
- logit = true;
- }
- break;
-
- case CURLINFO_DATA_IN:
- if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
- {
- tag = "DATAIN";
- logit = true;
- if (op->mTracing >= HTTP_TRACE_CURL_BODIES)
- {
- escape_libcurl_debug_data(buffer, log_len, false, safe_line);
- }
- else
- {
- std::ostringstream out;
- out << len << " Bytes";
- safe_line = out.str();
- }
- }
- break;
-
- case CURLINFO_DATA_OUT:
- if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
- {
- tag = "DATAOUT";
- logit = true;
- if (op->mTracing >= HTTP_TRACE_CURL_BODIES)
- {
- escape_libcurl_debug_data(buffer, log_len, false, safe_line);
- }
- else
- {
- std::ostringstream out;
- out << len << " Bytes";
- safe_line = out.str();
- }
- }
- break;
-
- default:
- logit = false;
- break;
- }
-
- if (logit)
- {
- LL_INFOS(LOG_CORE) << "TRACE, LibcurlDebug, Handle: "
- << op->getHandle()
- << ", Type: " << tag
- << ", Data: " << safe_line
- << LL_ENDL;
- }
-
- return 0;
+ std::string safe_line;
+ std::string tag;
+ bool logit(false);
+ const size_t log_len((std::min)(len, size_t(256))); // Keep things reasonable in all cases
+
+ switch (info)
+ {
+ case CURLINFO_TEXT:
+ if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
+ {
+ tag = "TEXT";
+ escape_libcurl_debug_data(buffer, log_len, true, safe_line);
+ logit = true;
+ }
+ break;
+
+ case CURLINFO_HEADER_IN:
+ if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
+ {
+ tag = "HEADERIN";
+ escape_libcurl_debug_data(buffer, log_len, true, safe_line);
+ logit = true;
+ }
+ break;
+
+ case CURLINFO_HEADER_OUT:
+ if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
+ {
+ tag = "HEADEROUT";
+ escape_libcurl_debug_data(buffer, log_len, true, safe_line); // Goes out as one line unlike header_in
+ logit = true;
+ }
+ break;
+
+ case CURLINFO_DATA_IN:
+ if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
+ {
+ tag = "DATAIN";
+ logit = true;
+ if (op->mTracing >= HTTP_TRACE_CURL_BODIES)
+ {
+ escape_libcurl_debug_data(buffer, log_len, false, safe_line);
+ }
+ else
+ {
+ std::ostringstream out;
+ out << len << " Bytes";
+ safe_line = out.str();
+ }
+ }
+ break;
+
+ case CURLINFO_DATA_OUT:
+ if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
+ {
+ tag = "DATAOUT";
+ logit = true;
+ if (op->mTracing >= HTTP_TRACE_CURL_BODIES)
+ {
+ escape_libcurl_debug_data(buffer, log_len, false, safe_line);
+ }
+ else
+ {
+ std::ostringstream out;
+ out << len << " Bytes";
+ safe_line = out.str();
+ }
+ }
+ break;
+
+ default:
+ logit = false;
+ break;
+ }
+
+ if (logit)
+ {
+ LL_INFOS(LOG_CORE) << "TRACE, LibcurlDebug, Handle: "
+ << op->getHandle()
+ << ", Type: " << tag
+ << ", Data: " << safe_line
+ << LL_ENDL;
+ }
+
+ return 0;
}
std::string HttpOpRequest::methodToString(const HttpOpRequest::EMethod &e)
@@ -1169,110 +1169,110 @@ namespace
{
int parse_content_range_header(char * buffer,
- unsigned int * first,
- unsigned int * last,
- unsigned int * length)
+ unsigned int * first,
+ unsigned int * last,
+ unsigned int * length)
{
- static const char * const hdr_whitespace(" \t");
-
- char * tok_state(NULL), * tok(NULL);
- bool match(true);
-
- if (! (tok = os_strtok_r(buffer, hdr_whitespace, &tok_state)))
- match = false;
- else
- match = (0 == os_strcasecmp("bytes", tok));
- if (match && ! (tok = os_strtok_r(NULL, hdr_whitespace, &tok_state)))
- match = false;
- if (match)
- {
- unsigned int lcl_first(0), lcl_last(0), lcl_len(0);
+ static const char * const hdr_whitespace(" \t");
+
+ char * tok_state(NULL), * tok(NULL);
+ bool match(true);
+
+ if (! (tok = os_strtok_r(buffer, hdr_whitespace, &tok_state)))
+ match = false;
+ else
+ match = (0 == os_strcasecmp("bytes", tok));
+ if (match && ! (tok = os_strtok_r(NULL, hdr_whitespace, &tok_state)))
+ match = false;
+ if (match)
+ {
+ unsigned int lcl_first(0), lcl_last(0), lcl_len(0);
#if LL_WINDOWS
- if (3 == sscanf_s(tok, "%u-%u/%u", &lcl_first, &lcl_last, &lcl_len))
+ if (3 == sscanf_s(tok, "%u-%u/%u", &lcl_first, &lcl_last, &lcl_len))
#else
- if (3 == sscanf(tok, "%u-%u/%u", &lcl_first, &lcl_last, &lcl_len))
+ if (3 == sscanf(tok, "%u-%u/%u", &lcl_first, &lcl_last, &lcl_len))
#endif // LL_WINDOWS
- {
- if (lcl_first > lcl_last || lcl_last >= lcl_len)
- return -1;
- *first = lcl_first;
- *last = lcl_last;
- *length = lcl_len;
- return 0;
- }
+ {
+ if (lcl_first > lcl_last || lcl_last >= lcl_len)
+ return -1;
+ *first = lcl_first;
+ *last = lcl_last;
+ *length = lcl_len;
+ return 0;
+ }
#if LL_WINDOWS
- if (2 == sscanf_s(tok, "%u-%u/*", &lcl_first, &lcl_last))
+ if (2 == sscanf_s(tok, "%u-%u/*", &lcl_first, &lcl_last))
#else
- if (2 == sscanf(tok, "%u-%u/*", &lcl_first, &lcl_last))
-#endif // LL_WINDOWS
- {
- if (lcl_first > lcl_last)
- return -1;
- *first = lcl_first;
- *last = lcl_last;
- *length = 0;
- return 0;
- }
- }
-
- // Header is there but badly/unexpectedly formed, try to ignore it.
- return 1;
+ if (2 == sscanf(tok, "%u-%u/*", &lcl_first, &lcl_last))
+#endif // LL_WINDOWS
+ {
+ if (lcl_first > lcl_last)
+ return -1;
+ *first = lcl_first;
+ *last = lcl_last;
+ *length = 0;
+ return 0;
+ }
+ }
+
+ // Header is there but badly/unexpectedly formed, try to ignore it.
+ return 1;
}
int parse_retry_after_header(char * buffer, int * time)
{
- char * endptr(buffer);
- long lcl_time(strtol(buffer, &endptr, 10));
- if (*endptr == '\0' && endptr != buffer && lcl_time > 0)
- {
- *time = lcl_time;
- return 0;
- }
-
- // Could attempt to parse HTTP time here but we're not really
- // interested in it. Scheduling based on wallclock time on
- // user hardware will lead to tears.
-
- // Header is there but badly/unexpectedly formed, try to ignore it.
- return 1;
+ char * endptr(buffer);
+ long lcl_time(strtol(buffer, &endptr, 10));
+ if (*endptr == '\0' && endptr != buffer && lcl_time > 0)
+ {
+ *time = lcl_time;
+ return 0;
+ }
+
+ // Could attempt to parse HTTP time here but we're not really
+ // interested in it. Scheduling based on wallclock time on
+ // user hardware will lead to tears.
+
+ // Header is there but badly/unexpectedly formed, try to ignore it.
+ return 1;
}
void escape_libcurl_debug_data(char * buffer, size_t len, bool scrub, std::string & safe_line)
{
- std::string out;
- len = (std::min)(len, size_t(200));
- out.reserve(3 * len);
- for (int i(0); i < len; ++i)
- {
- unsigned char uc(static_cast<unsigned char>(buffer[i]));
-
- if (uc < 32 || uc > 126)
- {
- if (scrub)
- {
- out.append(1, ' ');
- }
- else
- {
- static const char hex[] = "0123456789ABCDEF";
- char convert[4];
-
- convert[0] = '%';
- convert[1] = hex[(uc >> 4) % 16];
- convert[2] = hex[uc % 16];
- convert[3] = '\0';
- out.append(convert);
- }
- }
- else
- {
- out.append(1, buffer[i]);
- }
- }
- safe_line.swap(out);
+ std::string out;
+ len = (std::min)(len, size_t(200));
+ out.reserve(3 * len);
+ for (int i(0); i < len; ++i)
+ {
+ unsigned char uc(static_cast<unsigned char>(buffer[i]));
+
+ if (uc < 32 || uc > 126)
+ {
+ if (scrub)
+ {
+ out.append(1, ' ');
+ }
+ else
+ {
+ static const char hex[] = "0123456789ABCDEF";
+ char convert[4];
+
+ convert[0] = '%';
+ convert[1] = hex[(uc >> 4) % 16];
+ convert[2] = hex[uc % 16];
+ convert[3] = '\0';
+ out.append(convert);
+ }
+ }
+ else
+ {
+ out.append(1, buffer[i]);
+ }
+ }
+ safe_line.swap(out);
}
@@ -1280,9 +1280,9 @@ void escape_libcurl_debug_data(char * buffer, size_t len, bool scrub, std::strin
int os_strcasecmp(const char *s1, const char *s2)
{
#if LL_WINDOWS
- return _stricmp(s1, s2);
+ return _stricmp(s1, s2);
#else
- return strcasecmp(s1, s2);
+ return strcasecmp(s1, s2);
#endif // LL_WINDOWS
}
@@ -1290,66 +1290,66 @@ int os_strcasecmp(const char *s1, const char *s2)
char * os_strtok_r(char *str, const char *delim, char ** savestate)
{
#if LL_WINDOWS
- return strtok_s(str, delim, savestate);
+ return strtok_s(str, delim, savestate);
#else
- return strtok_r(str, delim, savestate);
+ return strtok_r(str, delim, savestate);
#endif
}
void os_strlower(char * str)
{
- for (char c(0); (c = *str); ++str)
- {
- *str = tolower(c);
- }
+ for (char c(0); (c = *str); ++str)
+ {
+ *str = tolower(c);
+ }
}
char * os_strtrim(char * lstr)
{
- while (' ' == *lstr || '\t' == *lstr)
- {
- ++lstr;
- }
- if (*lstr)
- {
- char * rstr(lstr + strlen(lstr));
- while (lstr < rstr && *--rstr)
- {
- if (' ' == *rstr || '\t' == *rstr)
- {
- *rstr = '\0';
- }
- }
- llassert(lstr <= rstr);
- }
- return lstr;
+ while (' ' == *lstr || '\t' == *lstr)
+ {
+ ++lstr;
+ }
+ if (*lstr)
+ {
+ char * rstr(lstr + strlen(lstr));
+ while (lstr < rstr && *--rstr)
+ {
+ if (' ' == *rstr || '\t' == *rstr)
+ {
+ *rstr = '\0';
+ }
+ }
+ llassert(lstr <= rstr);
+ }
+ return lstr;
}
char * os_strltrim(char * lstr)
{
- while (' ' == *lstr || '\t' == *lstr)
- {
- ++lstr;
- }
- return lstr;
+ while (' ' == *lstr || '\t' == *lstr)
+ {
+ ++lstr;
+ }
+ return lstr;
}
void check_curl_easy_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(LOG_CORE) << "libcurl error detected: " << curl_easy_strerror(code)
- << ", curl_easy_setopt option: " << curl_setopt_option
- << LL_ENDL;
- }
+ 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(LOG_CORE) << "libcurl error detected: " << curl_easy_strerror(code)
+ << ", curl_easy_setopt option: " << curl_setopt_option
+ << LL_ENDL;
+ }
}
} // end anonymous namespace
diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h
index 626064329d..b029bc740c 100644
--- a/indra/llcorehttp/_httpoprequest.h
+++ b/indra/llcorehttp/_httpoprequest.h
@@ -24,11 +24,11 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_OPREQUEST_H_
-#define _LLCORE_HTTP_OPREQUEST_H_
+#ifndef _LLCORE_HTTP_OPREQUEST_H_
+#define _LLCORE_HTTP_OPREQUEST_H_
-#include "linden_common.h" // Modifies curl/curl.h interfaces
+#include "linden_common.h" // Modifies curl/curl.h interfaces
#include <string>
#include <curl/curl.h>
@@ -68,65 +68,65 @@ class HttpOpRequest : public HttpOperation
public:
typedef std::shared_ptr<HttpOpRequest> ptr_t;
- HttpOpRequest();
+ HttpOpRequest();
- virtual ~HttpOpRequest(); // Use release()
+ virtual ~HttpOpRequest(); // Use release()
private:
- HttpOpRequest(const HttpOpRequest &); // Not defined
- void operator=(const HttpOpRequest &); // Not defined
+ HttpOpRequest(const HttpOpRequest &); // Not defined
+ void operator=(const HttpOpRequest &); // Not defined
public:
- enum EMethod
- {
- HOR_GET,
- HOR_POST,
- HOR_PUT,
+ enum EMethod
+ {
+ HOR_GET,
+ HOR_POST,
+ HOR_PUT,
HOR_DELETE,
HOR_PATCH,
HOR_COPY,
HOR_MOVE
- };
+ };
static std::string methodToString(const EMethod &);
- virtual void stageFromRequest(HttpService *);
- virtual void stageFromReady(HttpService *);
- virtual void stageFromActive(HttpService *);
+ virtual void stageFromRequest(HttpService *);
+ virtual void stageFromReady(HttpService *);
+ virtual void stageFromActive(HttpService *);
+
+ virtual void visitNotifier(HttpRequest * request);
- virtual void visitNotifier(HttpRequest * request);
-
public:
- /// Setup Methods
- ///
- /// Basically an RPC setup for each type of HTTP method
- /// invocation with one per method type. These are
- /// generally invoked right after construction.
- ///
- /// Threading: called by application thread
- ///
- HttpStatus setupGet(HttpRequest::policy_t policy_id,
- const std::string & url,
- const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers);
-
- HttpStatus setupGetByteRange(HttpRequest::policy_t policy_id,
- const std::string & url,
- size_t offset,
- size_t len,
+ /// Setup Methods
+ ///
+ /// Basically an RPC setup for each type of HTTP method
+ /// invocation with one per method type. These are
+ /// generally invoked right after construction.
+ ///
+ /// Threading: called by application thread
+ ///
+ HttpStatus setupGet(HttpRequest::policy_t policy_id,
+ const std::string & url,
+ const HttpOptions::ptr_t & options,
+ const HttpHeaders::ptr_t & headers);
+
+ HttpStatus setupGetByteRange(HttpRequest::policy_t policy_id,
+ const std::string & url,
+ size_t offset,
+ size_t len,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers);
-
- HttpStatus setupPost(HttpRequest::policy_t policy_id,
- const std::string & url,
- BufferArray * body,
+ const HttpHeaders::ptr_t & headers);
+
+ HttpStatus setupPost(HttpRequest::policy_t policy_id,
+ const std::string & url,
+ BufferArray * body,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers);
-
- HttpStatus setupPut(HttpRequest::policy_t policy_id,
- const std::string & url,
- BufferArray * body,
+ const HttpHeaders::ptr_t & headers);
+
+ HttpStatus setupPut(HttpRequest::policy_t policy_id,
+ const std::string & url,
+ BufferArray * body,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers);
+ const HttpHeaders::ptr_t & headers);
HttpStatus setupDelete(HttpRequest::policy_t policy_id,
const std::string & url,
@@ -150,82 +150,82 @@ public:
const HttpHeaders::ptr_t & headers);
// Internal method used to setup the libcurl options for a request.
- // Does all the libcurl handle setup in one place.
- //
- // Threading: called by worker thread
- //
- HttpStatus prepareRequest(HttpService * service);
-
- virtual HttpStatus cancel();
+ // Does all the libcurl handle setup in one place.
+ //
+ // Threading: called by worker thread
+ //
+ HttpStatus prepareRequest(HttpService * service);
+
+ virtual HttpStatus cancel();
protected:
- // Common setup for all the request methods.
- //
- // Threading: called by application thread
- //
- void setupCommon(HttpRequest::policy_t policy_id,
- const std::string & url,
- BufferArray * body,
+ // Common setup for all the request methods.
+ //
+ // Threading: called by application thread
+ //
+ void setupCommon(HttpRequest::policy_t policy_id,
+ const std::string & url,
+ BufferArray * body,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers);
-
- // libcurl operational callbacks
- //
- // Threading: called by worker thread
- //
- static size_t writeCallback(void * data, size_t size, size_t nmemb, void * userdata);
- static size_t readCallback(void * data, size_t size, size_t nmemb, void * userdata);
+ const HttpHeaders::ptr_t & headers);
+
+ // libcurl operational callbacks
+ //
+ // Threading: called by worker thread
+ //
+ static size_t writeCallback(void * data, size_t size, size_t nmemb, void * userdata);
+ static size_t readCallback(void * data, size_t size, size_t nmemb, void * userdata);
static int seekCallback(void *data, curl_off_t offset, int origin);
- static size_t headerCallback(void * data, size_t size, size_t nmemb, void * userdata);
- static CURLcode curlSslCtxCallback(CURL *curl, void *ssl_ctx, void *userptr);
- static int sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param);
+ static size_t headerCallback(void * data, size_t size, size_t nmemb, void * userdata);
+ static CURLcode curlSslCtxCallback(CURL *curl, void *ssl_ctx, void *userptr);
+ static int sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param);
- static int debugCallback(CURL *, curl_infotype info, char * buffer, size_t len, void * userdata);
+ static int debugCallback(CURL *, curl_infotype info, char * buffer, size_t len, void * userdata);
protected:
- unsigned int mProcFlags;
- static const unsigned int PF_SCAN_RANGE_HEADER = 0x00000001U;
- static const unsigned int PF_SAVE_HEADERS = 0x00000002U;
- static const unsigned int PF_USE_RETRY_AFTER = 0x00000004U;
+ unsigned int mProcFlags;
+ static const unsigned int PF_SCAN_RANGE_HEADER = 0x00000001U;
+ static const unsigned int PF_SAVE_HEADERS = 0x00000002U;
+ static const unsigned int PF_USE_RETRY_AFTER = 0x00000004U;
- HttpRequest::policyCallback_t mCallbackSSLVerify;
+ HttpRequest::policyCallback_t mCallbackSSLVerify;
public:
- // Request data
- EMethod mReqMethod;
- std::string mReqURL;
- BufferArray * mReqBody;
- off_t mReqOffset;
- size_t mReqLength;
- HttpHeaders::ptr_t mReqHeaders;
+ // Request data
+ EMethod mReqMethod;
+ std::string mReqURL;
+ BufferArray * mReqBody;
+ off_t mReqOffset;
+ size_t mReqLength;
+ HttpHeaders::ptr_t mReqHeaders;
HttpOptions::ptr_t mReqOptions;
- // Transport data
- bool mCurlActive;
- CURL * mCurlHandle;
- HttpService * mCurlService;
- curl_slist * mCurlHeaders;
- size_t mCurlBodyPos;
- char * mCurlTemp; // Scratch buffer for header processing
- size_t mCurlTempLen;
-
- // Result data
- HttpStatus mStatus;
- BufferArray * mReplyBody;
- off_t mReplyOffset;
- size_t mReplyLength;
- size_t mReplyFullLength;
- HttpHeaders::ptr_t mReplyHeaders;
- std::string mReplyConType;
- int mReplyRetryAfter;
-
- // Policy data
- int mPolicyRetries;
- int mPolicy503Retries;
- HttpTime mPolicyRetryAt;
- int mPolicyRetryLimit;
- HttpTime mPolicyMinRetryBackoff; // initial delay between retries (mcs)
- HttpTime mPolicyMaxRetryBackoff;
+ // Transport data
+ bool mCurlActive;
+ CURL * mCurlHandle;
+ HttpService * mCurlService;
+ curl_slist * mCurlHeaders;
+ size_t mCurlBodyPos;
+ char * mCurlTemp; // Scratch buffer for header processing
+ size_t mCurlTempLen;
+
+ // Result data
+ HttpStatus mStatus;
+ BufferArray * mReplyBody;
+ off_t mReplyOffset;
+ size_t mReplyLength;
+ size_t mReplyFullLength;
+ HttpHeaders::ptr_t mReplyHeaders;
+ std::string mReplyConType;
+ int mReplyRetryAfter;
+
+ // Policy data
+ int mPolicyRetries;
+ int mPolicy503Retries;
+ HttpTime mPolicyRetryAt;
+ int mPolicyRetryLimit;
+ HttpTime mPolicyMinRetryBackoff; // initial delay between retries (mcs)
+ HttpTime mPolicyMaxRetryBackoff;
}; // end class HttpOpRequest
@@ -240,5 +240,5 @@ curl_slist * append_headers_to_slist(const HttpHeaders::ptr_t &, curl_slist * sl
} // end namespace LLCore
-#endif // _LLCORE_HTTP_OPREQUEST_H_
+#endif // _LLCORE_HTTP_OPREQUEST_H_
diff --git a/indra/llcorehttp/_httpopsetget.cpp b/indra/llcorehttp/_httpopsetget.cpp
index a5363f9170..8caecd3e76 100644
--- a/indra/llcorehttp/_httpopsetget.cpp
+++ b/indra/llcorehttp/_httpopsetget.cpp
@@ -43,12 +43,12 @@ namespace LLCore
HttpOpSetGet::HttpOpSetGet()
- : HttpOperation(),
- mReqOption(HttpRequest::PO_CONNECTION_LIMIT),
- mReqClass(HttpRequest::INVALID_POLICY_ID),
- mReqDoSet(false),
- mReqLongValue(0L),
- mReplyLongValue(0L)
+ : HttpOperation(),
+ mReqOption(HttpRequest::PO_CONNECTION_LIMIT),
+ mReqClass(HttpRequest::INVALID_POLICY_ID),
+ mReqDoSet(false),
+ mReqLongValue(0L),
+ mReplyLongValue(0L)
{}
@@ -58,89 +58,89 @@ HttpOpSetGet::~HttpOpSetGet()
HttpStatus HttpOpSetGet::setupGet(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass)
{
- HttpStatus status;
-
- mReqOption = opt;
- mReqClass = pclass;
- return status;
+ HttpStatus status;
+
+ mReqOption = opt;
+ mReqClass = pclass;
+ return status;
}
HttpStatus HttpOpSetGet::setupSet(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass, long value)
{
- HttpStatus status;
-
- if (! HttpService::sOptionDesc[opt].mIsLong)
- {
- return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
- }
- if (! HttpService::sOptionDesc[opt].mIsDynamic)
- {
- return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
- }
-
- mReqOption = opt;
- mReqClass = pclass;
- mReqDoSet = true;
- mReqLongValue = value;
-
- return status;
+ HttpStatus status;
+
+ if (! HttpService::sOptionDesc[opt].mIsLong)
+ {
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
+ if (! HttpService::sOptionDesc[opt].mIsDynamic)
+ {
+ return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
+ }
+
+ mReqOption = opt;
+ mReqClass = pclass;
+ mReqDoSet = true;
+ mReqLongValue = value;
+
+ return status;
}
HttpStatus HttpOpSetGet::setupSet(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass, const std::string & value)
{
- HttpStatus status;
-
- if (HttpService::sOptionDesc[opt].mIsLong)
- {
- return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
- }
- if (! HttpService::sOptionDesc[opt].mIsDynamic)
- {
- return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
- }
-
- mReqOption = opt;
- mReqClass = pclass;
- mReqDoSet = true;
- mReqStrValue = value;
-
- return status;
+ HttpStatus status;
+
+ if (HttpService::sOptionDesc[opt].mIsLong)
+ {
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
+ if (! HttpService::sOptionDesc[opt].mIsDynamic)
+ {
+ return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
+ }
+
+ mReqOption = opt;
+ mReqClass = pclass;
+ mReqDoSet = true;
+ mReqStrValue = value;
+
+ return status;
}
void HttpOpSetGet::stageFromRequest(HttpService * service)
{
- if (mReqDoSet)
- {
- if (HttpService::sOptionDesc[mReqOption].mIsLong)
- {
- mStatus = service->setPolicyOption(mReqOption, mReqClass,
- mReqLongValue, &mReplyLongValue);
- }
- else
- {
- mStatus = service->setPolicyOption(mReqOption, mReqClass,
- mReqStrValue, &mReplyStrValue);
- }
- }
- else
- {
- if (HttpService::sOptionDesc[mReqOption].mIsLong)
- {
- mStatus = service->getPolicyOption(mReqOption, mReqClass, &mReplyLongValue);
- }
- else
- {
- mStatus = service->getPolicyOption(mReqOption, mReqClass, &mReplyStrValue);
- }
- }
-
- addAsReply();
+ if (mReqDoSet)
+ {
+ if (HttpService::sOptionDesc[mReqOption].mIsLong)
+ {
+ mStatus = service->setPolicyOption(mReqOption, mReqClass,
+ mReqLongValue, &mReplyLongValue);
+ }
+ else
+ {
+ mStatus = service->setPolicyOption(mReqOption, mReqClass,
+ mReqStrValue, &mReplyStrValue);
+ }
+ }
+ else
+ {
+ if (HttpService::sOptionDesc[mReqOption].mIsLong)
+ {
+ mStatus = service->getPolicyOption(mReqOption, mReqClass, &mReplyLongValue);
+ }
+ else
+ {
+ mStatus = service->getPolicyOption(mReqOption, mReqClass, &mReplyStrValue);
+ }
+ }
+
+ addAsReply();
}
} // end namespace LLCore
-
+
diff --git a/indra/llcorehttp/_httpopsetget.h b/indra/llcorehttp/_httpopsetget.h
index 04ab2446ef..0b927a6b71 100644
--- a/indra/llcorehttp/_httpopsetget.h
+++ b/indra/llcorehttp/_httpopsetget.h
@@ -24,11 +24,11 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_OPSETGET_H_
-#define _LLCORE_HTTP_OPSETGET_H_
+#ifndef _LLCORE_HTTP_OPSETGET_H_
+#define _LLCORE_HTTP_OPSETGET_H_
-#include "linden_common.h" // Modifies curl/curl.h interfaces
+#include "linden_common.h" // Modifies curl/curl.h interfaces
#include "httpcommon.h"
@@ -55,37 +55,37 @@ class HttpOpSetGet : public HttpOperation
public:
typedef std::shared_ptr<HttpOpSetGet> ptr_t;
- HttpOpSetGet();
+ HttpOpSetGet();
- virtual ~HttpOpSetGet(); // Use release()
+ virtual ~HttpOpSetGet(); // Use release()
private:
- HttpOpSetGet(const HttpOpSetGet &); // Not defined
- void operator=(const HttpOpSetGet &); // Not defined
+ HttpOpSetGet(const HttpOpSetGet &); // Not defined
+ void operator=(const HttpOpSetGet &); // Not defined
public:
- /// Threading: called by application thread
- HttpStatus setupGet(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass);
- HttpStatus setupSet(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass, long value);
- HttpStatus setupSet(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass, const std::string & value);
+ /// Threading: called by application thread
+ HttpStatus setupGet(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass);
+ HttpStatus setupSet(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass, long value);
+ HttpStatus setupSet(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass, const std::string & value);
- virtual void stageFromRequest(HttpService *);
+ virtual void stageFromRequest(HttpService *);
public:
- // Request data
- HttpRequest::EPolicyOption mReqOption;
- HttpRequest::policy_t mReqClass;
- bool mReqDoSet;
- long mReqLongValue;
- std::string mReqStrValue;
-
- // Reply Data
- long mReplyLongValue;
- std::string mReplyStrValue;
+ // Request data
+ HttpRequest::EPolicyOption mReqOption;
+ HttpRequest::policy_t mReqClass;
+ bool mReqDoSet;
+ long mReqLongValue;
+ std::string mReqStrValue;
+
+ // Reply Data
+ long mReplyLongValue;
+ std::string mReplyStrValue;
}; // end class HttpOpSetGet
} // end namespace LLCore
-#endif // _LLCORE_HTTP_OPSETGET_H_
+#endif // _LLCORE_HTTP_OPSETGET_H_
diff --git a/indra/llcorehttp/_httpopsetpriority.cpp b/indra/llcorehttp/_httpopsetpriority.cpp
index b99b4e9e4a..b62770e45a 100644
--- a/indra/llcorehttp/_httpopsetpriority.cpp
+++ b/indra/llcorehttp/_httpopsetpriority.cpp
@@ -37,9 +37,9 @@ namespace LLCore
HttpOpSetPriority::HttpOpSetPriority(HttpHandle handle, HttpRequest::priority_t priority)
- : HttpOperation(),
- mHandle(handle),
- mPriority(priority)
+ : HttpOperation(),
+ mHandle(handle),
+ mPriority(priority)
{}
@@ -49,15 +49,15 @@ HttpOpSetPriority::~HttpOpSetPriority()
void HttpOpSetPriority::stageFromRequest(HttpService * service)
{
- // Do operations
- if (! service->changePriority(mHandle, mPriority))
- {
- // Request not found, fail the final status
- mStatus = HttpStatus(HttpStatus::LLCORE, HE_HANDLE_NOT_FOUND);
- }
-
- // Move directly to response queue
- addAsReply();
+ // Do operations
+ if (! service->changePriority(mHandle, mPriority))
+ {
+ // Request not found, fail the final status
+ mStatus = HttpStatus(HttpStatus::LLCORE, HE_HANDLE_NOT_FOUND);
+ }
+
+ // Move directly to response queue
+ addAsReply();
}
diff --git a/indra/llcorehttp/_httpopsetpriority.h b/indra/llcorehttp/_httpopsetpriority.h
index fd543f37cc..b77a220c1b 100644
--- a/indra/llcorehttp/_httpopsetpriority.h
+++ b/indra/llcorehttp/_httpopsetpriority.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_SETPRIORITY_H_
-#define _LLCORE_HTTP_SETPRIORITY_H_
+#ifndef _LLCORE_HTTP_SETPRIORITY_H_
+#define _LLCORE_HTTP_SETPRIORITY_H_
#if 0 // DEPRECATED
#include "httpcommon.h"
@@ -49,24 +49,24 @@ namespace LLCore
class HttpOpSetPriority : public HttpOperation
{
public:
- HttpOpSetPriority(HttpHandle handle);
+ HttpOpSetPriority(HttpHandle handle);
- virtual ~HttpOpSetPriority();
+ virtual ~HttpOpSetPriority();
private:
- HttpOpSetPriority(const HttpOpSetPriority &); // Not defined
- void operator=(const HttpOpSetPriority &); // Not defined
+ HttpOpSetPriority(const HttpOpSetPriority &); // Not defined
+ void operator=(const HttpOpSetPriority &); // Not defined
public:
- virtual void stageFromRequest(HttpService *);
+ virtual void stageFromRequest(HttpService *);
protected:
- // Request Data
- HttpHandle mHandle;
+ // Request Data
+ HttpHandle mHandle;
}; // end class HttpOpSetPriority
} // end namespace LLCore
#endif
-#endif // _LLCORE_HTTP_SETPRIORITY_H_
+#endif // _LLCORE_HTTP_SETPRIORITY_H_
diff --git a/indra/llcorehttp/_httppolicy.cpp b/indra/llcorehttp/_httppolicy.cpp
index 29f50c1693..704c8abb93 100644
--- a/indra/llcorehttp/_httppolicy.cpp
+++ b/indra/llcorehttp/_httppolicy.cpp
@@ -56,82 +56,82 @@ namespace LLCore
struct HttpPolicy::ClassState
{
public:
- ClassState()
- : mThrottleEnd(0),
- mThrottleLeft(0L),
- mRequestCount(0L),
- mStallStaging(false)
- {}
-
- HttpReadyQueue mReadyQueue;
- HttpRetryQueue mRetryQueue;
-
- HttpPolicyClass mOptions;
- HttpTime mThrottleEnd;
- long mThrottleLeft;
- long mRequestCount;
- bool mStallStaging;
+ ClassState()
+ : mThrottleEnd(0),
+ mThrottleLeft(0L),
+ mRequestCount(0L),
+ mStallStaging(false)
+ {}
+
+ HttpReadyQueue mReadyQueue;
+ HttpRetryQueue mRetryQueue;
+
+ HttpPolicyClass mOptions;
+ HttpTime mThrottleEnd;
+ long mThrottleLeft;
+ long mRequestCount;
+ bool mStallStaging;
};
HttpPolicy::HttpPolicy(HttpService * service)
- : mService(service)
+ : mService(service)
{
- // Create default class
- mClasses.push_back(new ClassState());
+ // Create default class
+ mClasses.push_back(new ClassState());
}
HttpPolicy::~HttpPolicy()
{
- shutdown();
-
- for (class_list_t::iterator it(mClasses.begin()); it != mClasses.end(); ++it)
- {
- delete (*it);
- }
- mClasses.clear();
-
- mService = NULL;
+ shutdown();
+
+ for (class_list_t::iterator it(mClasses.begin()); it != mClasses.end(); ++it)
+ {
+ delete (*it);
+ }
+ mClasses.clear();
+
+ mService = NULL;
}
HttpRequest::policy_t HttpPolicy::createPolicyClass()
{
- const HttpRequest::policy_t policy_class(mClasses.size());
- if (policy_class >= HTTP_POLICY_CLASS_LIMIT)
- {
- return HttpRequest::INVALID_POLICY_ID;
- }
- mClasses.push_back(new ClassState());
- return policy_class;
+ const HttpRequest::policy_t policy_class(mClasses.size());
+ if (policy_class >= HTTP_POLICY_CLASS_LIMIT)
+ {
+ return HttpRequest::INVALID_POLICY_ID;
+ }
+ mClasses.push_back(new ClassState());
+ return policy_class;
}
void HttpPolicy::shutdown()
{
- for (int policy_class(0); policy_class < mClasses.size(); ++policy_class)
- {
- ClassState & state(*mClasses[policy_class]);
-
- HttpRetryQueue & retryq(state.mRetryQueue);
- while (! retryq.empty())
- {
- HttpOpRequest::ptr_t op(retryq.top());
- retryq.pop();
-
- op->cancel();
- }
-
- HttpReadyQueue & readyq(state.mReadyQueue);
- while (! readyq.empty())
- {
- HttpOpRequest::ptr_t op(readyq.top());
- readyq.pop();
-
- op->cancel();
- }
- }
+ for (int policy_class(0); policy_class < mClasses.size(); ++policy_class)
+ {
+ ClassState & state(*mClasses[policy_class]);
+
+ HttpRetryQueue & retryq(state.mRetryQueue);
+ while (! retryq.empty())
+ {
+ HttpOpRequest::ptr_t op(retryq.top());
+ retryq.pop();
+
+ op->cancel();
+ }
+
+ HttpReadyQueue & readyq(state.mReadyQueue);
+ while (! readyq.empty())
+ {
+ HttpOpRequest::ptr_t op(readyq.top());
+ readyq.pop();
+
+ op->cancel();
+ }
+ }
}
@@ -142,54 +142,54 @@ void HttpPolicy::start()
void HttpPolicy::addOp(const HttpOpRequest::ptr_t &op)
{
- const int policy_class(op->mReqPolicy);
-
- op->mPolicyRetries = 0;
- op->mPolicy503Retries = 0;
- mClasses[policy_class]->mReadyQueue.push(op);
+ const int policy_class(op->mReqPolicy);
+
+ op->mPolicyRetries = 0;
+ op->mPolicy503Retries = 0;
+ mClasses[policy_class]->mReadyQueue.push(op);
}
void HttpPolicy::retryOp(const HttpOpRequest::ptr_t &op)
{
- static const HttpStatus error_503(503);
-
- const HttpTime now(totalTime());
- const int policy_class(op->mReqPolicy);
-
- HttpTime delta_min = op->mPolicyMinRetryBackoff;
- HttpTime delta_max = op->mPolicyMaxRetryBackoff;
- // mPolicyRetries limited to 100
- U32 delta_factor = op->mPolicyRetries <= 10 ? 1 << op->mPolicyRetries : 1024;
- HttpTime delta = llmin(delta_min * delta_factor, delta_max);
- bool external_delta(false);
-
- if (op->mReplyRetryAfter > 0 && op->mReplyRetryAfter < 30)
- {
- delta = op->mReplyRetryAfter * U64L(1000000);
- external_delta = true;
- }
- op->mPolicyRetryAt = now + delta;
- ++op->mPolicyRetries;
- if (error_503 == op->mStatus)
- {
- ++op->mPolicy503Retries;
- }
- LL_DEBUGS(LOG_CORE) << "HTTP request " << op->getHandle()
- << " retry " << op->mPolicyRetries
- << " scheduled in " << (delta / HttpTime(1000))
- << " mS (" << (external_delta ? "external" : "internal")
- << "). Status: " << op->mStatus.toTerseString()
- << LL_ENDL;
- if (op->mTracing > HTTP_TRACE_OFF)
- {
- LL_INFOS(LOG_CORE) << "TRACE, ToRetryQueue, Handle: "
+ static const HttpStatus error_503(503);
+
+ const HttpTime now(totalTime());
+ const int policy_class(op->mReqPolicy);
+
+ HttpTime delta_min = op->mPolicyMinRetryBackoff;
+ HttpTime delta_max = op->mPolicyMaxRetryBackoff;
+ // mPolicyRetries limited to 100
+ U32 delta_factor = op->mPolicyRetries <= 10 ? 1 << op->mPolicyRetries : 1024;
+ HttpTime delta = llmin(delta_min * delta_factor, delta_max);
+ bool external_delta(false);
+
+ if (op->mReplyRetryAfter > 0 && op->mReplyRetryAfter < 30)
+ {
+ delta = op->mReplyRetryAfter * U64L(1000000);
+ external_delta = true;
+ }
+ op->mPolicyRetryAt = now + delta;
+ ++op->mPolicyRetries;
+ if (error_503 == op->mStatus)
+ {
+ ++op->mPolicy503Retries;
+ }
+ LL_DEBUGS(LOG_CORE) << "HTTP request " << op->getHandle()
+ << " retry " << op->mPolicyRetries
+ << " scheduled in " << (delta / HttpTime(1000))
+ << " mS (" << (external_delta ? "external" : "internal")
+ << "). Status: " << op->mStatus.toTerseString()
+ << LL_ENDL;
+ if (op->mTracing > HTTP_TRACE_OFF)
+ {
+ LL_INFOS(LOG_CORE) << "TRACE, ToRetryQueue, Handle: "
<< op->getHandle()
- << ", Delta: " << (delta / HttpTime(1000))
- << ", Retries: " << op->mPolicyRetries
- << LL_ENDL;
- }
- mClasses[policy_class]->mRetryQueue.push(op);
+ << ", Delta: " << (delta / HttpTime(1000))
+ << ", Retries: " << op->mPolicyRetries
+ << LL_ENDL;
+ }
+ mClasses[policy_class]->mRetryQueue.push(op);
}
@@ -213,242 +213,242 @@ void HttpPolicy::retryOp(const HttpOpRequest::ptr_t &op)
//
HttpService::ELoopSpeed HttpPolicy::processReadyQueue()
{
- const HttpTime now(totalTime());
- HttpService::ELoopSpeed result(HttpService::REQUEST_SLEEP);
- HttpLibcurl & transport(mService->getTransport());
-
- for (int policy_class(0); policy_class < mClasses.size(); ++policy_class)
- {
- ClassState & state(*mClasses[policy_class]);
- HttpRetryQueue & retryq(state.mRetryQueue);
- HttpReadyQueue & readyq(state.mReadyQueue);
-
- if (state.mStallStaging)
- {
- // Stalling but don't sleep. Need to complete operations
- // and get back to servicing queues. Do this test before
- // the retryq/readyq test or you'll get stalls until you
- // click a setting or an asset request comes in.
- result = HttpService::NORMAL;
- continue;
- }
- if (retryq.empty() && readyq.empty())
- {
- continue;
- }
-
- const bool throttle_enabled(state.mOptions.mThrottleRate > 0L);
- const bool throttle_current(throttle_enabled && now < state.mThrottleEnd);
-
- if (throttle_current && state.mThrottleLeft <= 0)
- {
- // Throttled condition, don't serve this class but don't sleep hard.
- result = HttpService::NORMAL;
- continue;
- }
-
- int active(transport.getActiveCountInClass(policy_class));
- int active_limit(state.mOptions.mPipelining > 1L
- ? (state.mOptions.mPerHostConnectionLimit
- * state.mOptions.mPipelining)
- : state.mOptions.mConnectionLimit);
- int needed(active_limit - active); // Expect negatives here
-
- if (needed > 0)
- {
- // First see if we have any retries...
- while (needed > 0 && ! retryq.empty())
- {
- HttpOpRequest::ptr_t op(retryq.top());
- if (op->mPolicyRetryAt > now)
- break;
-
- retryq.pop();
-
- op->stageFromReady(mService);
+ const HttpTime now(totalTime());
+ HttpService::ELoopSpeed result(HttpService::REQUEST_SLEEP);
+ HttpLibcurl & transport(mService->getTransport());
+
+ for (int policy_class(0); policy_class < mClasses.size(); ++policy_class)
+ {
+ ClassState & state(*mClasses[policy_class]);
+ HttpRetryQueue & retryq(state.mRetryQueue);
+ HttpReadyQueue & readyq(state.mReadyQueue);
+
+ if (state.mStallStaging)
+ {
+ // Stalling but don't sleep. Need to complete operations
+ // and get back to servicing queues. Do this test before
+ // the retryq/readyq test or you'll get stalls until you
+ // click a setting or an asset request comes in.
+ result = HttpService::NORMAL;
+ continue;
+ }
+ if (retryq.empty() && readyq.empty())
+ {
+ continue;
+ }
+
+ const bool throttle_enabled(state.mOptions.mThrottleRate > 0L);
+ const bool throttle_current(throttle_enabled && now < state.mThrottleEnd);
+
+ if (throttle_current && state.mThrottleLeft <= 0)
+ {
+ // Throttled condition, don't serve this class but don't sleep hard.
+ result = HttpService::NORMAL;
+ continue;
+ }
+
+ int active(transport.getActiveCountInClass(policy_class));
+ int active_limit(state.mOptions.mPipelining > 1L
+ ? (state.mOptions.mPerHostConnectionLimit
+ * state.mOptions.mPipelining)
+ : state.mOptions.mConnectionLimit);
+ int needed(active_limit - active); // Expect negatives here
+
+ if (needed > 0)
+ {
+ // First see if we have any retries...
+ while (needed > 0 && ! retryq.empty())
+ {
+ HttpOpRequest::ptr_t op(retryq.top());
+ if (op->mPolicyRetryAt > now)
+ break;
+
+ retryq.pop();
+
+ op->stageFromReady(mService);
+ op.reset();
+
+ ++state.mRequestCount;
+ --needed;
+ if (throttle_enabled)
+ {
+ if (now >= state.mThrottleEnd)
+ {
+ // Throttle expired, move to next window
+ LL_DEBUGS(LOG_CORE) << "Throttle expired with " << state.mThrottleLeft
+ << " requests to go and " << state.mRequestCount
+ << " requests issued." << LL_ENDL;
+ state.mThrottleLeft = state.mOptions.mThrottleRate;
+ state.mThrottleEnd = now + HttpTime(1000000);
+ }
+ if (--state.mThrottleLeft <= 0)
+ {
+ goto throttle_on;
+ }
+ }
+ }
+
+ // Now go on to the new requests...
+ while (needed > 0 && ! readyq.empty())
+ {
+ HttpOpRequest::ptr_t op(readyq.top());
+ readyq.pop();
+
+ op->stageFromReady(mService);
op.reset();
- ++state.mRequestCount;
- --needed;
- if (throttle_enabled)
- {
- if (now >= state.mThrottleEnd)
- {
- // Throttle expired, move to next window
- LL_DEBUGS(LOG_CORE) << "Throttle expired with " << state.mThrottleLeft
- << " requests to go and " << state.mRequestCount
- << " requests issued." << LL_ENDL;
- state.mThrottleLeft = state.mOptions.mThrottleRate;
- state.mThrottleEnd = now + HttpTime(1000000);
- }
- if (--state.mThrottleLeft <= 0)
- {
- goto throttle_on;
- }
- }
- }
-
- // Now go on to the new requests...
- while (needed > 0 && ! readyq.empty())
- {
- HttpOpRequest::ptr_t op(readyq.top());
- readyq.pop();
-
- op->stageFromReady(mService);
- op.reset();
-
- ++state.mRequestCount;
- --needed;
- if (throttle_enabled)
- {
- if (now >= state.mThrottleEnd)
- {
- // Throttle expired, move to next window
- LL_DEBUGS(LOG_CORE) << "Throttle expired with " << state.mThrottleLeft
- << " requests to go and " << state.mRequestCount
- << " requests issued." << LL_ENDL;
- state.mThrottleLeft = state.mOptions.mThrottleRate;
- state.mThrottleEnd = now + HttpTime(1000000);
- }
- if (--state.mThrottleLeft <= 0)
- {
- goto throttle_on;
- }
- }
- }
- }
-
- throttle_on:
-
- if (! readyq.empty() || ! retryq.empty())
- {
- // If anything is ready, continue looping...
- result = HttpService::NORMAL;
- }
- } // end foreach policy_class
-
- return result;
+ ++state.mRequestCount;
+ --needed;
+ if (throttle_enabled)
+ {
+ if (now >= state.mThrottleEnd)
+ {
+ // Throttle expired, move to next window
+ LL_DEBUGS(LOG_CORE) << "Throttle expired with " << state.mThrottleLeft
+ << " requests to go and " << state.mRequestCount
+ << " requests issued." << LL_ENDL;
+ state.mThrottleLeft = state.mOptions.mThrottleRate;
+ state.mThrottleEnd = now + HttpTime(1000000);
+ }
+ if (--state.mThrottleLeft <= 0)
+ {
+ goto throttle_on;
+ }
+ }
+ }
+ }
+
+ throttle_on:
+
+ if (! readyq.empty() || ! retryq.empty())
+ {
+ // If anything is ready, continue looping...
+ result = HttpService::NORMAL;
+ }
+ } // end foreach policy_class
+
+ return result;
}
bool HttpPolicy::cancel(HttpHandle handle)
{
- for (int policy_class(0); policy_class < mClasses.size(); ++policy_class)
- {
- ClassState & state(*mClasses[policy_class]);
-
- // Scan retry queue
- HttpRetryQueue::container_type & c1(state.mRetryQueue.get_container());
- for (HttpRetryQueue::container_type::iterator iter(c1.begin()); c1.end() != iter;)
- {
- HttpRetryQueue::container_type::iterator cur(iter++);
-
- if ((*cur)->getHandle() == handle)
- {
- HttpOpRequest::ptr_t op(*cur);
- c1.erase(cur); // All iterators are now invalidated
- op->cancel();
- return true;
- }
- }
-
- // Scan ready queue
- HttpReadyQueue::container_type & c2(state.mReadyQueue.get_container());
- for (HttpReadyQueue::container_type::iterator iter(c2.begin()); c2.end() != iter;)
- {
- HttpReadyQueue::container_type::iterator cur(iter++);
-
- if ((*cur)->getHandle() == handle)
- {
- HttpOpRequest::ptr_t op(*cur);
- c2.erase(cur); // All iterators are now invalidated
- op->cancel();
- return true;
- }
- }
- }
-
- return false;
+ for (int policy_class(0); policy_class < mClasses.size(); ++policy_class)
+ {
+ ClassState & state(*mClasses[policy_class]);
+
+ // Scan retry queue
+ HttpRetryQueue::container_type & c1(state.mRetryQueue.get_container());
+ for (HttpRetryQueue::container_type::iterator iter(c1.begin()); c1.end() != iter;)
+ {
+ HttpRetryQueue::container_type::iterator cur(iter++);
+
+ if ((*cur)->getHandle() == handle)
+ {
+ HttpOpRequest::ptr_t op(*cur);
+ c1.erase(cur); // All iterators are now invalidated
+ op->cancel();
+ return true;
+ }
+ }
+
+ // Scan ready queue
+ HttpReadyQueue::container_type & c2(state.mReadyQueue.get_container());
+ for (HttpReadyQueue::container_type::iterator iter(c2.begin()); c2.end() != iter;)
+ {
+ HttpReadyQueue::container_type::iterator cur(iter++);
+
+ if ((*cur)->getHandle() == handle)
+ {
+ HttpOpRequest::ptr_t op(*cur);
+ c2.erase(cur); // All iterators are now invalidated
+ op->cancel();
+ return true;
+ }
+ }
+ }
+
+ return false;
}
bool HttpPolicy::stageAfterCompletion(const HttpOpRequest::ptr_t &op)
{
- // Retry or finalize
- if (! op->mStatus)
- {
- // *DEBUG: For "[curl:bugs] #1420" tests. This will interfere
- // with unit tests due to allocation retention by logging code.
- // But you won't be checking this in enabled.
+ // Retry or finalize
+ if (! op->mStatus)
+ {
+ // *DEBUG: For "[curl:bugs] #1420" tests. This will interfere
+ // with unit tests due to allocation retention by logging code.
+ // But you won't be checking this in enabled.
#if 0
- if (op->mStatus == HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT))
- {
- LL_WARNS(LOG_CORE) << "HTTP request " << op->getHandle()
- << " timed out."
- << LL_ENDL;
- }
+ if (op->mStatus == HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT))
+ {
+ LL_WARNS(LOG_CORE) << "HTTP request " << op->getHandle()
+ << " timed out."
+ << LL_ENDL;
+ }
#endif
-
- // If this failed, we might want to retry.
- if (op->mPolicyRetries < op->mPolicyRetryLimit && op->mStatus.isRetryable())
- {
- // Okay, worth a retry.
- retryOp(op);
- return true; // still active/ready
- }
- }
-
- // This op is done, finalize it delivering it to the reply queue...
- if (! op->mStatus)
- {
- LL_WARNS(LOG_CORE) << "HTTP request " << op->getHandle()
- << " failed after " << op->mPolicyRetries
- << " retries. Reason: " << op->mStatus.toString()
- << " (" << op->mStatus.toTerseString() << ")"
- << LL_ENDL;
- }
- else if (op->mPolicyRetries)
- {
+
+ // If this failed, we might want to retry.
+ if (op->mPolicyRetries < op->mPolicyRetryLimit && op->mStatus.isRetryable())
+ {
+ // Okay, worth a retry.
+ retryOp(op);
+ return true; // still active/ready
+ }
+ }
+
+ // This op is done, finalize it delivering it to the reply queue...
+ if (! op->mStatus)
+ {
+ LL_WARNS(LOG_CORE) << "HTTP request " << op->getHandle()
+ << " failed after " << op->mPolicyRetries
+ << " retries. Reason: " << op->mStatus.toString()
+ << " (" << op->mStatus.toTerseString() << ")"
+ << LL_ENDL;
+ }
+ else if (op->mPolicyRetries)
+ {
LL_DEBUGS(LOG_CORE) << "HTTP request " << op->getHandle()
- << " succeeded on retry " << op->mPolicyRetries << "."
- << LL_ENDL;
- }
+ << " succeeded on retry " << op->mPolicyRetries << "."
+ << LL_ENDL;
+ }
- op->stageFromActive(mService);
+ op->stageFromActive(mService);
HTTPStats::instance().recordResultCode(op->mStatus.getType());
- return false; // not active
+ return false; // not active
}
-
+
HttpPolicyClass & HttpPolicy::getClassOptions(HttpRequest::policy_t pclass)
{
- llassert_always(pclass >= 0 && pclass < mClasses.size());
-
- return mClasses[pclass]->mOptions;
+ llassert_always(pclass >= 0 && pclass < mClasses.size());
+
+ return mClasses[pclass]->mOptions;
}
int HttpPolicy::getReadyCount(HttpRequest::policy_t policy_class) const
{
- if (policy_class < mClasses.size())
- {
- return (mClasses[policy_class]->mReadyQueue.size()
- + mClasses[policy_class]->mRetryQueue.size());
- }
- return 0;
+ if (policy_class < mClasses.size())
+ {
+ return (mClasses[policy_class]->mReadyQueue.size()
+ + mClasses[policy_class]->mRetryQueue.size());
+ }
+ return 0;
}
bool HttpPolicy::stallPolicy(HttpRequest::policy_t policy_class, bool stall)
{
- bool ret(false);
-
- if (policy_class < mClasses.size())
- {
- ret = mClasses[policy_class]->mStallStaging;
- mClasses[policy_class]->mStallStaging = stall;
- }
- return ret;
+ bool ret(false);
+
+ if (policy_class < mClasses.size())
+ {
+ ret = mClasses[policy_class]->mStallStaging;
+ mClasses[policy_class]->mStallStaging = stall;
+ }
+ return ret;
}
diff --git a/indra/llcorehttp/_httppolicy.h b/indra/llcorehttp/_httppolicy.h
index 955f757c93..a074949f20 100644
--- a/indra/llcorehttp/_httppolicy.h
+++ b/indra/llcorehttp/_httppolicy.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_POLICY_H_
-#define _LLCORE_HTTP_POLICY_H_
+#ifndef _LLCORE_HTTP_POLICY_H_
+#define _LLCORE_HTTP_POLICY_H_
#include "httprequest.h"
@@ -52,123 +52,123 @@ class HttpOpRequest;
class HttpPolicy
{
public:
- HttpPolicy(HttpService *);
- virtual ~HttpPolicy();
+ HttpPolicy(HttpService *);
+ virtual ~HttpPolicy();
private:
- HttpPolicy(const HttpPolicy &); // Not defined
- void operator=(const HttpPolicy &); // Not defined
+ HttpPolicy(const HttpPolicy &); // Not defined
+ void operator=(const HttpPolicy &); // Not defined
public:
typedef std::shared_ptr<HttpOpRequest> opReqPtr_t;
- /// Threading: called by init thread.
- HttpRequest::policy_t createPolicyClass();
-
- /// Cancel all ready and retry requests sending them to
- /// their notification queues. Release state resources
- /// making further request handling impossible.
- ///
- /// Threading: called by worker thread
- void shutdown();
-
- /// Deliver policy definitions and enable handling of
- /// requests. One-time call invoked before starting
- /// the worker thread.
- ///
- /// Threading: called by init thread
- void start();
-
- /// Give the policy layer some cycles to scan the ready
- /// queue promoting higher-priority requests to active
- /// as permited.
- ///
- /// @return Indication of how soon this method
- /// should be called again.
- ///
- /// Threading: called by worker thread
- HttpService::ELoopSpeed processReadyQueue();
-
- /// Add request to a ready queue. Caller is expected to have
- /// provided us with a reference count to hold the request. (No
- /// additional references will be added.)
- ///
- /// OpRequest is owned by the request queue after this call
- /// and should not be modified by anyone until retrieved
- /// from queue.
- ///
- /// Threading: called by worker thread
+ /// Threading: called by init thread.
+ HttpRequest::policy_t createPolicyClass();
+
+ /// Cancel all ready and retry requests sending them to
+ /// their notification queues. Release state resources
+ /// making further request handling impossible.
+ ///
+ /// Threading: called by worker thread
+ void shutdown();
+
+ /// Deliver policy definitions and enable handling of
+ /// requests. One-time call invoked before starting
+ /// the worker thread.
+ ///
+ /// Threading: called by init thread
+ void start();
+
+ /// Give the policy layer some cycles to scan the ready
+ /// queue promoting higher-priority requests to active
+ /// as permited.
+ ///
+ /// @return Indication of how soon this method
+ /// should be called again.
+ ///
+ /// Threading: called by worker thread
+ HttpService::ELoopSpeed processReadyQueue();
+
+ /// Add request to a ready queue. Caller is expected to have
+ /// provided us with a reference count to hold the request. (No
+ /// additional references will be added.)
+ ///
+ /// OpRequest is owned by the request queue after this call
+ /// and should not be modified by anyone until retrieved
+ /// from queue.
+ ///
+ /// Threading: called by worker thread
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
- /// queue but ordered by retry time not priority. Otherwise,
- /// handling is the same and retried operations are considered
- /// before new ones but that doesn't guarantee completion
- /// order.
- ///
- /// Threading: called by worker thread
+ /// Similar to addOp, used when a caller wants to retry a
+ /// request that has failed. It's placed on a special retry
+ /// queue but ordered by retry time not priority. Otherwise,
+ /// handling is the same and retried operations are considered
+ /// before new ones but that doesn't guarantee completion
+ /// order.
+ ///
+ /// Threading: called by worker thread
void retryOp(const opReqPtr_t &);
- /// Attempt to cancel a previous request.
- /// Shadows HttpService's method as well
- ///
- /// Threading: called by worker thread
- bool cancel(HttpHandle handle);
-
- /// When transport is finished with an op and takes it off the
- /// active queue, it is delivered here for dispatch. Policy
- /// may send it back to the ready/retry queues if it needs another
- /// go or we may finalize it and send it on to the reply queue.
- ///
- /// @return Returns true of the request is still active
- /// or ready after staging, false if has been
- /// sent on to the reply queue.
- ///
- /// Threading: called by worker thread
+ /// Attempt to cancel a previous request.
+ /// Shadows HttpService's method as well
+ ///
+ /// Threading: called by worker thread
+ bool cancel(HttpHandle handle);
+
+ /// When transport is finished with an op and takes it off the
+ /// active queue, it is delivered here for dispatch. Policy
+ /// may send it back to the ready/retry queues if it needs another
+ /// go or we may finalize it and send it on to the reply queue.
+ ///
+ /// @return Returns true of the request is still active
+ /// or ready after staging, false if has been
+ /// sent on to the reply queue.
+ ///
+ /// Threading: called by worker thread
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
- /// are done, for example, in @see HttpService interfaces.
- ///
- /// Threading: called by any thread *but* the object may
- /// only be modified by the worker thread once running.
- HttpPolicyGlobal & getGlobalOptions()
- {
- return mGlobalOptions;
- }
-
- /// Get a reference to class policy options. Caller is expected
- /// to do context checks like no setting once running. These
- /// are done, for example, in @see HttpService interfaces.
- ///
- /// Threading: called by any thread *but* the object may
- /// only be modified by the worker thread once running and
- /// read accesses by other threads are exposed to races at
- /// that point.
- HttpPolicyClass & getClassOptions(HttpRequest::policy_t pclass);
-
- /// Get ready counts for a particular policy class
- ///
- /// Threading: called by worker thread
- int getReadyCount(HttpRequest::policy_t policy_class) const;
-
- /// Stall (or unstall) a policy class preventing requests from
- /// transitioning to an active state. Used to allow an HTTP
- /// request policy to empty prior to changing settings or state
- /// that isn't tolerant of changes when work is outstanding.
- ///
- /// Threading: called by worker thread
- bool stallPolicy(HttpRequest::policy_t policy_class, bool stall);
-
+
+ /// Get a reference to global policy options. Caller is expected
+ /// to do context checks like no setting once running. These
+ /// are done, for example, in @see HttpService interfaces.
+ ///
+ /// Threading: called by any thread *but* the object may
+ /// only be modified by the worker thread once running.
+ HttpPolicyGlobal & getGlobalOptions()
+ {
+ return mGlobalOptions;
+ }
+
+ /// Get a reference to class policy options. Caller is expected
+ /// to do context checks like no setting once running. These
+ /// are done, for example, in @see HttpService interfaces.
+ ///
+ /// Threading: called by any thread *but* the object may
+ /// only be modified by the worker thread once running and
+ /// read accesses by other threads are exposed to races at
+ /// that point.
+ HttpPolicyClass & getClassOptions(HttpRequest::policy_t pclass);
+
+ /// Get ready counts for a particular policy class
+ ///
+ /// Threading: called by worker thread
+ int getReadyCount(HttpRequest::policy_t policy_class) const;
+
+ /// Stall (or unstall) a policy class preventing requests from
+ /// transitioning to an active state. Used to allow an HTTP
+ /// request policy to empty prior to changing settings or state
+ /// that isn't tolerant of changes when work is outstanding.
+ ///
+ /// Threading: called by worker thread
+ bool stallPolicy(HttpRequest::policy_t policy_class, bool stall);
+
protected:
- struct ClassState;
- typedef std::vector<ClassState *> class_list_t;
-
- HttpPolicyGlobal mGlobalOptions;
- class_list_t mClasses;
- HttpService * mService; // Naked pointer, not refcounted, not owner
+ struct ClassState;
+ typedef std::vector<ClassState *> class_list_t;
+
+ HttpPolicyGlobal mGlobalOptions;
+ class_list_t mClasses;
+ HttpService * mService; // Naked pointer, not refcounted, not owner
}; // end class HttpPolicy
} // end namespace LLCore
diff --git a/indra/llcorehttp/_httppolicyclass.cpp b/indra/llcorehttp/_httppolicyclass.cpp
index 2c0f650155..811b004032 100644
--- a/indra/llcorehttp/_httppolicyclass.cpp
+++ b/indra/llcorehttp/_httppolicyclass.cpp
@@ -34,10 +34,10 @@ namespace LLCore
HttpPolicyClass::HttpPolicyClass()
- : mConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
- mPerHostConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
- mPipelining(HTTP_PIPELINING_DEFAULT),
- mThrottleRate(HTTP_THROTTLE_RATE_DEFAULT)
+ : mConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
+ mPerHostConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
+ mPipelining(HTTP_PIPELINING_DEFAULT),
+ mThrottleRate(HTTP_THROTTLE_RATE_DEFAULT)
{}
@@ -47,78 +47,78 @@ HttpPolicyClass::~HttpPolicyClass()
HttpPolicyClass & HttpPolicyClass::operator=(const HttpPolicyClass & other)
{
- if (this != &other)
- {
- mConnectionLimit = other.mConnectionLimit;
- mPerHostConnectionLimit = other.mPerHostConnectionLimit;
- mPipelining = other.mPipelining;
- mThrottleRate = other.mThrottleRate;
- }
- return *this;
+ if (this != &other)
+ {
+ mConnectionLimit = other.mConnectionLimit;
+ mPerHostConnectionLimit = other.mPerHostConnectionLimit;
+ mPipelining = other.mPipelining;
+ mThrottleRate = other.mThrottleRate;
+ }
+ return *this;
}
HttpPolicyClass::HttpPolicyClass(const HttpPolicyClass & other)
- : mConnectionLimit(other.mConnectionLimit),
- mPerHostConnectionLimit(other.mPerHostConnectionLimit),
- mPipelining(other.mPipelining),
- mThrottleRate(other.mThrottleRate)
+ : mConnectionLimit(other.mConnectionLimit),
+ mPerHostConnectionLimit(other.mPerHostConnectionLimit),
+ mPipelining(other.mPipelining),
+ mThrottleRate(other.mThrottleRate)
{}
HttpStatus HttpPolicyClass::set(HttpRequest::EPolicyOption opt, long value)
{
- switch (opt)
- {
- case HttpRequest::PO_CONNECTION_LIMIT:
- mConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), long(HTTP_CONNECTION_LIMIT_MAX));
- break;
+ switch (opt)
+ {
+ case HttpRequest::PO_CONNECTION_LIMIT:
+ mConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), long(HTTP_CONNECTION_LIMIT_MAX));
+ break;
- case HttpRequest::PO_PER_HOST_CONNECTION_LIMIT:
- mPerHostConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), mConnectionLimit);
- break;
+ case HttpRequest::PO_PER_HOST_CONNECTION_LIMIT:
+ mPerHostConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), mConnectionLimit);
+ break;
- case HttpRequest::PO_PIPELINING_DEPTH:
- mPipelining = llclamp(value, 0L, HTTP_PIPELINING_MAX);
- break;
+ case HttpRequest::PO_PIPELINING_DEPTH:
+ mPipelining = llclamp(value, 0L, HTTP_PIPELINING_MAX);
+ break;
- case HttpRequest::PO_THROTTLE_RATE:
- mThrottleRate = llclamp(value, 0L, 1000000L);
- break;
+ case HttpRequest::PO_THROTTLE_RATE:
+ mThrottleRate = llclamp(value, 0L, 1000000L);
+ break;
- default:
- return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
- }
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
- return HttpStatus();
+ return HttpStatus();
}
HttpStatus HttpPolicyClass::get(HttpRequest::EPolicyOption opt, long * value) const
{
- switch (opt)
- {
- case HttpRequest::PO_CONNECTION_LIMIT:
- *value = mConnectionLimit;
- break;
+ switch (opt)
+ {
+ case HttpRequest::PO_CONNECTION_LIMIT:
+ *value = mConnectionLimit;
+ break;
- case HttpRequest::PO_PER_HOST_CONNECTION_LIMIT:
- *value = mPerHostConnectionLimit;
- break;
+ case HttpRequest::PO_PER_HOST_CONNECTION_LIMIT:
+ *value = mPerHostConnectionLimit;
+ break;
- case HttpRequest::PO_PIPELINING_DEPTH:
- *value = mPipelining;
- break;
+ case HttpRequest::PO_PIPELINING_DEPTH:
+ *value = mPipelining;
+ break;
- case HttpRequest::PO_THROTTLE_RATE:
- *value = mThrottleRate;
- break;
+ case HttpRequest::PO_THROTTLE_RATE:
+ *value = mThrottleRate;
+ break;
- default:
- return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
- }
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
- return HttpStatus();
+ return HttpStatus();
}
diff --git a/indra/llcorehttp/_httppolicyclass.h b/indra/llcorehttp/_httppolicyclass.h
index 38f1194ded..32bcad4f9c 100644
--- a/indra/llcorehttp/_httppolicyclass.h
+++ b/indra/llcorehttp/_httppolicyclass.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_POLICY_CLASS_H_
-#define _LLCORE_HTTP_POLICY_CLASS_H_
+#ifndef _LLCORE_HTTP_POLICY_CLASS_H_
+#define _LLCORE_HTTP_POLICY_CLASS_H_
#include "httprequest.h"
@@ -49,21 +49,21 @@ namespace LLCore
class HttpPolicyClass
{
public:
- HttpPolicyClass();
- ~HttpPolicyClass();
+ HttpPolicyClass();
+ ~HttpPolicyClass();
- HttpPolicyClass & operator=(const HttpPolicyClass &);
- HttpPolicyClass(const HttpPolicyClass &); // Not defined
+ HttpPolicyClass & operator=(const HttpPolicyClass &);
+ HttpPolicyClass(const HttpPolicyClass &); // Not defined
public:
- HttpStatus set(HttpRequest::EPolicyOption opt, long value);
- HttpStatus get(HttpRequest::EPolicyOption opt, long * value) const;
-
+ HttpStatus set(HttpRequest::EPolicyOption opt, long value);
+ HttpStatus get(HttpRequest::EPolicyOption opt, long * value) const;
+
public:
- long mConnectionLimit;
- long mPerHostConnectionLimit;
- long mPipelining;
- long mThrottleRate;
+ long mConnectionLimit;
+ long mPerHostConnectionLimit;
+ long mPipelining;
+ long mThrottleRate;
}; // end class HttpPolicyClass
} // end namespace LLCore
diff --git a/indra/llcorehttp/_httppolicyglobal.cpp b/indra/llcorehttp/_httppolicyglobal.cpp
index 8da6cba6d0..431df6ba64 100644
--- a/indra/llcorehttp/_httppolicyglobal.cpp
+++ b/indra/llcorehttp/_httppolicyglobal.cpp
@@ -34,9 +34,9 @@ namespace LLCore
HttpPolicyGlobal::HttpPolicyGlobal()
- : mConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
- mTrace(HTTP_TRACE_OFF),
- mUseLLProxy(0)
+ : mConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
+ mTrace(HTTP_TRACE_OFF),
+ mUseLLProxy(0)
{}
@@ -46,145 +46,145 @@ HttpPolicyGlobal::~HttpPolicyGlobal()
HttpPolicyGlobal & HttpPolicyGlobal::operator=(const HttpPolicyGlobal & other)
{
- if (this != &other)
- {
- mConnectionLimit = other.mConnectionLimit;
- mCAPath = other.mCAPath;
- mCAFile = other.mCAFile;
- mHttpProxy = other.mHttpProxy;
- mTrace = other.mTrace;
- mUseLLProxy = other.mUseLLProxy;
- }
- return *this;
+ if (this != &other)
+ {
+ mConnectionLimit = other.mConnectionLimit;
+ mCAPath = other.mCAPath;
+ mCAFile = other.mCAFile;
+ mHttpProxy = other.mHttpProxy;
+ mTrace = other.mTrace;
+ mUseLLProxy = other.mUseLLProxy;
+ }
+ return *this;
}
HttpStatus HttpPolicyGlobal::set(HttpRequest::EPolicyOption opt, long value)
{
- switch (opt)
- {
- case HttpRequest::PO_CONNECTION_LIMIT:
- mConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), long(HTTP_CONNECTION_LIMIT_MAX));
- break;
+ switch (opt)
+ {
+ case HttpRequest::PO_CONNECTION_LIMIT:
+ mConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), long(HTTP_CONNECTION_LIMIT_MAX));
+ break;
- case HttpRequest::PO_TRACE:
- mTrace = llclamp(value, long(HTTP_TRACE_MIN), long(HTTP_TRACE_MAX));
- break;
+ case HttpRequest::PO_TRACE:
+ mTrace = llclamp(value, long(HTTP_TRACE_MIN), long(HTTP_TRACE_MAX));
+ break;
- case HttpRequest::PO_LLPROXY:
- mUseLLProxy = llclamp(value, 0L, 1L);
- break;
+ case HttpRequest::PO_LLPROXY:
+ mUseLLProxy = llclamp(value, 0L, 1L);
+ break;
- default:
- return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
- }
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
- return HttpStatus();
+ return HttpStatus();
}
HttpStatus HttpPolicyGlobal::set(HttpRequest::EPolicyOption opt, const std::string & value)
{
- switch (opt)
- {
- case HttpRequest::PO_CA_PATH:
+ switch (opt)
+ {
+ case HttpRequest::PO_CA_PATH:
LL_DEBUGS("CoreHttp") << "Setting global CA Path to " << value << LL_ENDL;
- mCAPath = value;
- break;
+ mCAPath = value;
+ break;
- case HttpRequest::PO_CA_FILE:
+ case HttpRequest::PO_CA_FILE:
LL_DEBUGS("CoreHttp") << "Setting global CA File to " << value << LL_ENDL;
- mCAFile = value;
- break;
+ mCAFile = value;
+ break;
- case HttpRequest::PO_HTTP_PROXY:
+ case HttpRequest::PO_HTTP_PROXY:
LL_DEBUGS("CoreHttp") << "Setting global Proxy to " << value << LL_ENDL;
- mHttpProxy = value;
- break;
-
- default:
- return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
- }
-
- return HttpStatus();
+ mHttpProxy = value;
+ break;
+
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
+
+ return HttpStatus();
}
HttpStatus HttpPolicyGlobal::set(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback_t value)
{
- switch (opt)
- {
- case HttpRequest::PO_SSL_VERIFY_CALLBACK:
- mSslCtxCallback = value;
- break;
+ switch (opt)
+ {
+ case HttpRequest::PO_SSL_VERIFY_CALLBACK:
+ mSslCtxCallback = value;
+ break;
- default:
- return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
- }
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
- return HttpStatus();
+ return HttpStatus();
}
HttpStatus HttpPolicyGlobal::get(HttpRequest::EPolicyOption opt, long * value) const
{
- switch (opt)
- {
- case HttpRequest::PO_CONNECTION_LIMIT:
- *value = mConnectionLimit;
- break;
+ switch (opt)
+ {
+ case HttpRequest::PO_CONNECTION_LIMIT:
+ *value = mConnectionLimit;
+ break;
- case HttpRequest::PO_TRACE:
- *value = mTrace;
- break;
+ case HttpRequest::PO_TRACE:
+ *value = mTrace;
+ break;
- case HttpRequest::PO_LLPROXY:
- *value = mUseLLProxy;
- break;
+ case HttpRequest::PO_LLPROXY:
+ *value = mUseLLProxy;
+ break;
- default:
- return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
- }
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
- return HttpStatus();
+ return HttpStatus();
}
HttpStatus HttpPolicyGlobal::get(HttpRequest::EPolicyOption opt, std::string * value) const
{
- switch (opt)
- {
- case HttpRequest::PO_CA_PATH:
- *value = mCAPath;
- break;
-
- case HttpRequest::PO_CA_FILE:
- *value = mCAFile;
- break;
-
- case HttpRequest::PO_HTTP_PROXY:
- *value = mHttpProxy;
- break;
-
- default:
- return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
- }
-
- return HttpStatus();
+ switch (opt)
+ {
+ case HttpRequest::PO_CA_PATH:
+ *value = mCAPath;
+ break;
+
+ case HttpRequest::PO_CA_FILE:
+ *value = mCAFile;
+ break;
+
+ case HttpRequest::PO_HTTP_PROXY:
+ *value = mHttpProxy;
+ break;
+
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
+
+ return HttpStatus();
}
HttpStatus HttpPolicyGlobal::get(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback_t * value) const
{
- switch (opt)
- {
- case HttpRequest::PO_SSL_VERIFY_CALLBACK:
- *value = mSslCtxCallback;
- break;
+ switch (opt)
+ {
+ case HttpRequest::PO_SSL_VERIFY_CALLBACK:
+ *value = mSslCtxCallback;
+ break;
- default:
- return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
- }
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
- return HttpStatus();
+ return HttpStatus();
}
} // end namespace LLCore
diff --git a/indra/llcorehttp/_httppolicyglobal.h b/indra/llcorehttp/_httppolicyglobal.h
index e02da4386a..d9114d167f 100644
--- a/indra/llcorehttp/_httppolicyglobal.h
+++ b/indra/llcorehttp/_httppolicyglobal.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_POLICY_GLOBAL_H_
-#define _LLCORE_HTTP_POLICY_GLOBAL_H_
+#ifndef _LLCORE_HTTP_POLICY_GLOBAL_H_
+#define _LLCORE_HTTP_POLICY_GLOBAL_H_
#include "httprequest.h"
@@ -49,30 +49,30 @@ namespace LLCore
class HttpPolicyGlobal
{
public:
- HttpPolicyGlobal();
- ~HttpPolicyGlobal();
+ HttpPolicyGlobal();
+ ~HttpPolicyGlobal();
+
+ HttpPolicyGlobal & operator=(const HttpPolicyGlobal &);
- HttpPolicyGlobal & operator=(const HttpPolicyGlobal &);
-
private:
- HttpPolicyGlobal(const HttpPolicyGlobal &); // Not defined
+ HttpPolicyGlobal(const HttpPolicyGlobal &); // Not defined
public:
- HttpStatus set(HttpRequest::EPolicyOption opt, long value);
- HttpStatus set(HttpRequest::EPolicyOption opt, const std::string & value);
- HttpStatus set(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback_t value);
- HttpStatus get(HttpRequest::EPolicyOption opt, long * value) const;
- HttpStatus get(HttpRequest::EPolicyOption opt, std::string * value) const;
- HttpStatus get(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback_t * value) const;
-
+ HttpStatus set(HttpRequest::EPolicyOption opt, long value);
+ HttpStatus set(HttpRequest::EPolicyOption opt, const std::string & value);
+ HttpStatus set(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback_t value);
+ HttpStatus get(HttpRequest::EPolicyOption opt, long * value) const;
+ HttpStatus get(HttpRequest::EPolicyOption opt, std::string * value) const;
+ HttpStatus get(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback_t * value) const;
+
public:
- long mConnectionLimit;
- std::string mCAPath;
- std::string mCAFile;
- std::string mHttpProxy;
- long mTrace;
- long mUseLLProxy;
- HttpRequest::policyCallback_t mSslCtxCallback;
+ long mConnectionLimit;
+ std::string mCAPath;
+ std::string mCAFile;
+ std::string mHttpProxy;
+ long mTrace;
+ long mUseLLProxy;
+ HttpRequest::policyCallback_t mSslCtxCallback;
}; // end class HttpPolicyGlobal
} // end namespace LLCore
diff --git a/indra/llcorehttp/_httpreadyqueue.h b/indra/llcorehttp/_httpreadyqueue.h
index 7418988ec1..0bc0723511 100644
--- a/indra/llcorehttp/_httpreadyqueue.h
+++ b/indra/llcorehttp/_httpreadyqueue.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_READY_QUEUE_H_
-#define _LLCORE_HTTP_READY_QUEUE_H_
+#ifndef _LLCORE_HTTP_READY_QUEUE_H_
+#define _LLCORE_HTTP_READY_QUEUE_H_
#include <queue>
@@ -61,64 +61,64 @@ typedef std::deque<HttpOpRequest::ptr_t> HttpReadyQueueBase;
#else
typedef std::priority_queue<HttpOpRequest::ptr_t,
- std::deque<HttpOpRequest::ptr_t>,
- LLCore::HttpOpRequestCompare> HttpReadyQueueBase;
+ std::deque<HttpOpRequest::ptr_t>,
+ LLCore::HttpOpRequestCompare> HttpReadyQueueBase;
#endif // LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY
class HttpReadyQueue : public HttpReadyQueueBase
{
public:
- HttpReadyQueue()
- : HttpReadyQueueBase()
- {}
-
- ~HttpReadyQueue()
- {}
-
+ HttpReadyQueue()
+ : HttpReadyQueueBase()
+ {}
+
+ ~HttpReadyQueue()
+ {}
+
protected:
- HttpReadyQueue(const HttpReadyQueue &); // Not defined
- void operator=(const HttpReadyQueue &); // Not defined
+ HttpReadyQueue(const HttpReadyQueue &); // Not defined
+ void operator=(const HttpReadyQueue &); // Not defined
public:
#if LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY
- // Types and methods needed to make a std::deque look
- // more like a std::priority_queue, at least for our
- // purposes.
- typedef HttpReadyQueueBase container_type;
-
- const_reference top() const
- {
- return front();
- }
-
- void pop()
- {
- pop_front();
- }
-
- void push(const value_type & v)
- {
- push_back(v);
- }
-
+ // Types and methods needed to make a std::deque look
+ // more like a std::priority_queue, at least for our
+ // purposes.
+ typedef HttpReadyQueueBase container_type;
+
+ const_reference top() const
+ {
+ return front();
+ }
+
+ void pop()
+ {
+ pop_front();
+ }
+
+ void push(const value_type & v)
+ {
+ push_back(v);
+ }
+
#endif // LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY
-
- const container_type & get_container() const
- {
- return *this;
- }
-
- container_type & get_container()
- {
- return *this;
- }
-
+
+ const container_type & get_container() const
+ {
+ return *this;
+ }
+
+ container_type & get_container()
+ {
+ return *this;
+ }
+
}; // end class HttpReadyQueue
} // end namespace LLCore
-#endif // _LLCORE_HTTP_READY_QUEUE_H_
+#endif // _LLCORE_HTTP_READY_QUEUE_H_
diff --git a/indra/llcorehttp/_httpreplyqueue.cpp b/indra/llcorehttp/_httpreplyqueue.cpp
index 229bfdbe07..6124bb6186 100644
--- a/indra/llcorehttp/_httpreplyqueue.cpp
+++ b/indra/llcorehttp/_httpreplyqueue.cpp
@@ -51,46 +51,46 @@ HttpReplyQueue::~HttpReplyQueue()
void HttpReplyQueue::addOp(const HttpReplyQueue::opPtr_t &op)
{
- {
- HttpScopedLock lock(mQueueMutex);
+ {
+ HttpScopedLock lock(mQueueMutex);
- mQueue.push_back(op);
- }
+ mQueue.push_back(op);
+ }
}
HttpReplyQueue::opPtr_t HttpReplyQueue::fetchOp()
{
- HttpOperation::ptr_t result;
+ HttpOperation::ptr_t result;
- {
- HttpScopedLock lock(mQueueMutex);
+ {
+ HttpScopedLock lock(mQueueMutex);
- if (mQueue.empty())
+ if (mQueue.empty())
return opPtr_t();
- result = mQueue.front();
- mQueue.erase(mQueue.begin());
- }
+ result = mQueue.front();
+ mQueue.erase(mQueue.begin());
+ }
- // Caller also acquires the reference count
- return result;
+ // Caller also acquires the reference count
+ return result;
}
void HttpReplyQueue::fetchAll(OpContainer & ops)
{
- // Not valid putting something back on the queue...
- llassert_always(ops.empty());
+ // Not valid putting something back on the queue...
+ llassert_always(ops.empty());
- {
- HttpScopedLock lock(mQueueMutex);
+ {
+ HttpScopedLock lock(mQueueMutex);
- if (! mQueue.empty())
- {
- mQueue.swap(ops);
- }
- }
+ if (! mQueue.empty())
+ {
+ mQueue.swap(ops);
+ }
+ }
}
diff --git a/indra/llcorehttp/_httpreplyqueue.h b/indra/llcorehttp/_httpreplyqueue.h
index 2de26249ef..d8847fafb5 100644
--- a/indra/llcorehttp/_httpreplyqueue.h
+++ b/indra/llcorehttp/_httpreplyqueue.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_REPLY_QUEUE_H_
-#define _LLCORE_HTTP_REPLY_QUEUE_H_
+#ifndef _LLCORE_HTTP_REPLY_QUEUE_H_
+#define _LLCORE_HTTP_REPLY_QUEUE_H_
#include "_refcounted.h"
@@ -66,42 +66,42 @@ public:
typedef std::shared_ptr<HttpOperation> opPtr_t;
typedef std::shared_ptr<HttpReplyQueue> ptr_t;
- HttpReplyQueue();
- virtual ~HttpReplyQueue();
+ HttpReplyQueue();
+ virtual ~HttpReplyQueue();
public:
typedef std::vector< opPtr_t > OpContainer;
- /// Insert an object at the back of the reply queue.
- ///
- /// Library also takes possession of one reference count to pass
- /// through the queue.
- ///
- /// Threading: callable by any thread.
+ /// Insert an object at the back of the reply queue.
+ ///
+ /// Library also takes possession of one reference count to pass
+ /// through the queue.
+ ///
+ /// Threading: callable by any thread.
void addOp(const opPtr_t &op);
- /// Fetch an operation from the head of the queue. Returns
- /// NULL if none exists.
- ///
- /// Caller acquires reference count on returned operation.
- ///
- /// Threading: callable by any thread.
+ /// Fetch an operation from the head of the queue. Returns
+ /// NULL if none exists.
+ ///
+ /// Caller acquires reference count on returned operation.
+ ///
+ /// Threading: callable by any thread.
opPtr_t fetchOp();
- /// Caller acquires reference count on each returned operation
- ///
- /// Threading: callable by any thread.
- void fetchAll(OpContainer & ops);
-
+ /// Caller acquires reference count on each returned operation
+ ///
+ /// Threading: callable by any thread.
+ void fetchAll(OpContainer & ops);
+
protected:
- OpContainer mQueue;
- LLCoreInt::HttpMutex mQueueMutex;
-
+ OpContainer mQueue;
+ LLCoreInt::HttpMutex mQueueMutex;
+
}; // end class HttpReplyQueue
} // end namespace LLCore
-#endif // _LLCORE_HTTP_REPLY_QUEUE_H_
+#endif // _LLCORE_HTTP_REPLY_QUEUE_H_
diff --git a/indra/llcorehttp/_httprequestqueue.cpp b/indra/llcorehttp/_httprequestqueue.cpp
index ad72bdcce6..df89fb85ec 100644
--- a/indra/llcorehttp/_httprequestqueue.cpp
+++ b/indra/llcorehttp/_httprequestqueue.cpp
@@ -1,6 +1,6 @@
/**
* @file _httprequestqueue.cpp
- * @brief
+ * @brief
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -39,8 +39,8 @@ HttpRequestQueue * HttpRequestQueue::sInstance(NULL);
HttpRequestQueue::HttpRequestQueue()
- : RefCounted(true),
- mQueueStopped(false)
+ : RefCounted(true),
+ mQueueStopped(false)
{
}
@@ -53,99 +53,99 @@ HttpRequestQueue::~HttpRequestQueue()
void HttpRequestQueue::init()
{
- llassert_always(! sInstance);
- sInstance = new HttpRequestQueue();
+ llassert_always(! sInstance);
+ sInstance = new HttpRequestQueue();
}
void HttpRequestQueue::term()
{
- if (sInstance)
- {
- sInstance->release();
- sInstance = NULL;
- }
+ if (sInstance)
+ {
+ sInstance->release();
+ sInstance = NULL;
+ }
}
HttpStatus HttpRequestQueue::addOp(const HttpRequestQueue::opPtr_t &op)
{
- bool wake(false);
- {
- HttpScopedLock lock(mQueueMutex);
-
- if (mQueueStopped)
- {
- // Return op and error to caller
- return HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN);
- }
- wake = mQueue.empty();
- mQueue.push_back(op);
- }
- if (wake)
- {
- mQueueCV.notify_all();
- }
- return HttpStatus();
+ bool wake(false);
+ {
+ HttpScopedLock lock(mQueueMutex);
+
+ if (mQueueStopped)
+ {
+ // Return op and error to caller
+ return HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN);
+ }
+ wake = mQueue.empty();
+ mQueue.push_back(op);
+ }
+ if (wake)
+ {
+ mQueueCV.notify_all();
+ }
+ return HttpStatus();
}
HttpRequestQueue::opPtr_t HttpRequestQueue::fetchOp(bool wait)
{
- HttpOperation::ptr_t result;
+ HttpOperation::ptr_t result;
- {
- HttpScopedLock lock(mQueueMutex);
+ {
+ HttpScopedLock lock(mQueueMutex);
- while (mQueue.empty())
- {
- if (! wait || mQueueStopped)
+ while (mQueue.empty())
+ {
+ if (! wait || mQueueStopped)
return HttpOperation::ptr_t();
- mQueueCV.wait(lock);
- }
+ mQueueCV.wait(lock);
+ }
- result = mQueue.front();
- mQueue.erase(mQueue.begin());
- }
+ result = mQueue.front();
+ mQueue.erase(mQueue.begin());
+ }
- // Caller also acquires the reference count
- return result;
+ // Caller also acquires the reference count
+ return result;
}
void HttpRequestQueue::fetchAll(bool wait, OpContainer & ops)
{
- // Not valid putting something back on the queue...
- llassert_always(ops.empty());
+ // Not valid putting something back on the queue...
+ llassert_always(ops.empty());
- {
- HttpScopedLock lock(mQueueMutex);
+ {
+ HttpScopedLock lock(mQueueMutex);
- while (mQueue.empty())
- {
- if (! wait || mQueueStopped)
- return;
- mQueueCV.wait(lock);
- }
+ while (mQueue.empty())
+ {
+ if (! wait || mQueueStopped)
+ return;
+ mQueueCV.wait(lock);
+ }
- mQueue.swap(ops);
- }
+ mQueue.swap(ops);
+ }
- // Caller also acquires the reference counts on each op.
- return;
+ // Caller also acquires the reference counts on each op.
+ return;
}
void HttpRequestQueue::wakeAll()
{
- mQueueCV.notify_all();
+ mQueueCV.notify_all();
}
bool HttpRequestQueue::stopQueue()
{
- {
- HttpScopedLock lock(mQueueMutex);
+ {
+ HttpScopedLock lock(mQueueMutex);
if (!mQueueStopped)
{
@@ -155,7 +155,7 @@ bool HttpRequestQueue::stopQueue()
}
wakeAll();
return false;
- }
+ }
}
diff --git a/indra/llcorehttp/_httprequestqueue.h b/indra/llcorehttp/_httprequestqueue.h
index 52369df174..0823126f78 100644
--- a/indra/llcorehttp/_httprequestqueue.h
+++ b/indra/llcorehttp/_httprequestqueue.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_REQUEST_QUEUE_H_
-#define _LLCORE_HTTP_REQUEST_QUEUE_H_
+#ifndef _LLCORE_HTTP_REQUEST_QUEUE_H_
+#define _LLCORE_HTTP_REQUEST_QUEUE_H_
#include <vector>
@@ -50,94 +50,94 @@ class HttpOperation;
class HttpRequestQueue : public LLCoreInt::RefCounted
{
protected:
- /// Caller acquires a Refcount on construction
- HttpRequestQueue();
+ /// Caller acquires a Refcount on construction
+ HttpRequestQueue();
protected:
- virtual ~HttpRequestQueue(); // Use release()
+ virtual ~HttpRequestQueue(); // Use release()
private:
- HttpRequestQueue(const HttpRequestQueue &); // Not defined
- void operator=(const HttpRequestQueue &); // Not defined
+ HttpRequestQueue(const HttpRequestQueue &); // Not defined
+ void operator=(const HttpRequestQueue &); // Not defined
public:
typedef std::shared_ptr<HttpOperation> opPtr_t;
- static void init();
- static void term();
-
- /// Threading: callable by any thread once inited.
- inline static HttpRequestQueue * instanceOf()
- {
- return sInstance;
- }
-
+ static void init();
+ static void term();
+
+ /// Threading: callable by any thread once inited.
+ inline static HttpRequestQueue * instanceOf()
+ {
+ return sInstance;
+ }
+
public:
typedef std::vector<opPtr_t> OpContainer;
- /// Insert an object at the back of the request queue.
- ///
- /// Caller must provide one refcount to the queue which takes
- /// possession of the count on success.
- ///
- /// @return Standard status. On failure, caller
- /// must dispose of the operation with
- /// an explicit release() call.
- ///
- /// Threading: callable by any thread.
+ /// Insert an object at the back of the request queue.
+ ///
+ /// Caller must provide one refcount to the queue which takes
+ /// possession of the count on success.
+ ///
+ /// @return Standard status. On failure, caller
+ /// must dispose of the operation with
+ /// an explicit release() call.
+ ///
+ /// Threading: callable by any thread.
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
- /// immediately and a NULL pointer is returned. If true,
- /// caller will sleep until explicitly woken. Wakeups
- /// can be spurious and callers must expect NULL pointers
- /// even if waiting is indicated.
- ///
- /// Caller acquires reference count any returned operation
- ///
- /// Threading: callable by any thread.
+ /// Return the operation on the front of the queue. If
+ /// the queue is empty and @wait is false, call returns
+ /// immediately and a NULL pointer is returned. If true,
+ /// caller will sleep until explicitly woken. Wakeups
+ /// can be spurious and callers must expect NULL pointers
+ /// even if waiting is indicated.
+ ///
+ /// Caller acquires reference count any returned operation
+ ///
+ /// Threading: callable by any thread.
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
- /// current contents. Handling of the @wait argument is
- /// identical to @fetchOp.
- ///
- /// Caller acquires reference count on each returned operation
- ///
- /// Threading: callable by any thread.
- void fetchAll(bool wait, OpContainer & ops);
-
- /// Wake any sleeping threads. Normal queuing operations
- /// won't require this but it may be necessary for termination
- /// requests.
- ///
- /// Threading: callable by any thread.
- void wakeAll();
-
- /// Disallow further request queuing. Callers to @addOp will
- /// get a failure status (LLCORE, HE_SHUTTING_DOWN). Callers
- /// to @fetchAll or @fetchOp will get requests that are on the
- /// queue but the calls will no longer wait. Instead they'll
- /// return immediately. Also wakes up all sleepers to send
- /// them on their way.
- ///
- /// Threading: callable by any thread.
- bool stopQueue();
-
+ /// Return all queued requests to caller. The @ops argument
+ /// should be empty when called and will be swap()'d with
+ /// current contents. Handling of the @wait argument is
+ /// identical to @fetchOp.
+ ///
+ /// Caller acquires reference count on each returned operation
+ ///
+ /// Threading: callable by any thread.
+ void fetchAll(bool wait, OpContainer & ops);
+
+ /// Wake any sleeping threads. Normal queuing operations
+ /// won't require this but it may be necessary for termination
+ /// requests.
+ ///
+ /// Threading: callable by any thread.
+ void wakeAll();
+
+ /// Disallow further request queuing. Callers to @addOp will
+ /// get a failure status (LLCORE, HE_SHUTTING_DOWN). Callers
+ /// to @fetchAll or @fetchOp will get requests that are on the
+ /// queue but the calls will no longer wait. Instead they'll
+ /// return immediately. Also wakes up all sleepers to send
+ /// them on their way.
+ ///
+ /// Threading: callable by any thread.
+ bool stopQueue();
+
protected:
- static HttpRequestQueue * sInstance;
-
+ static HttpRequestQueue * sInstance;
+
protected:
- OpContainer mQueue;
- LLCoreInt::HttpMutex mQueueMutex;
- LLCoreInt::HttpConditionVariable mQueueCV;
- bool mQueueStopped;
-
+ OpContainer mQueue;
+ LLCoreInt::HttpMutex mQueueMutex;
+ LLCoreInt::HttpConditionVariable mQueueCV;
+ bool mQueueStopped;
+
}; // end class HttpRequestQueue
} // end namespace LLCore
-#endif // _LLCORE_HTTP_REQUEST_QUEUE_H_
+#endif // _LLCORE_HTTP_REQUEST_QUEUE_H_
diff --git a/indra/llcorehttp/_httpretryqueue.h b/indra/llcorehttp/_httpretryqueue.h
index 5d8c529cff..8545368d9e 100644
--- a/indra/llcorehttp/_httpretryqueue.h
+++ b/indra/llcorehttp/_httpretryqueue.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_RETRY_QUEUE_H_
-#define _LLCORE_HTTP_RETRY_QUEUE_H_
+#ifndef _LLCORE_HTTP_RETRY_QUEUE_H_
+#define _LLCORE_HTTP_RETRY_QUEUE_H_
#include <queue>
@@ -49,41 +49,41 @@ namespace LLCore
struct HttpOpRetryCompare
{
- bool operator()(const HttpOpRequest::ptr_t &lhs, const HttpOpRequest::ptr_t &rhs)
- {
- return lhs->mPolicyRetryAt < rhs->mPolicyRetryAt;
- }
+ bool operator()(const HttpOpRequest::ptr_t &lhs, const HttpOpRequest::ptr_t &rhs)
+ {
+ return lhs->mPolicyRetryAt < rhs->mPolicyRetryAt;
+ }
};
-
+
typedef std::priority_queue<HttpOpRequest::ptr_t,
- std::deque<HttpOpRequest::ptr_t>,
- LLCore::HttpOpRetryCompare> HttpRetryQueueBase;
+ std::deque<HttpOpRequest::ptr_t>,
+ LLCore::HttpOpRetryCompare> HttpRetryQueueBase;
class HttpRetryQueue : public HttpRetryQueueBase
{
public:
- HttpRetryQueue()
- : HttpRetryQueueBase()
- {}
-
- ~HttpRetryQueue()
- {}
-
+ HttpRetryQueue()
+ : HttpRetryQueueBase()
+ {}
+
+ ~HttpRetryQueue()
+ {}
+
protected:
- HttpRetryQueue(const HttpRetryQueue &); // Not defined
- void operator=(const HttpRetryQueue &); // Not defined
+ HttpRetryQueue(const HttpRetryQueue &); // Not defined
+ void operator=(const HttpRetryQueue &); // Not defined
public:
- const container_type & get_container() const
- {
- return c;
- }
+ const container_type & get_container() const
+ {
+ return c;
+ }
- container_type & get_container()
- {
- return c;
- }
+ container_type & get_container()
+ {
+ return c;
+ }
}; // end class HttpRetryQueue
@@ -91,4 +91,4 @@ public:
} // end namespace LLCore
-#endif // _LLCORE_HTTP_RETRY_QUEUE_H_
+#endif // _LLCORE_HTTP_RETRY_QUEUE_H_
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index d7ae8dc65c..10a8c87550 100644
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -1,581 +1,581 @@
-/**
- * @file _httpservice.cpp
- * @brief Internal definitions of the Http service thread
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2012-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 "_httpservice.h"
-
-#include <boost/bind.hpp>
-#include <boost/function.hpp>
-
-#include "_httpoperation.h"
-#include "_httprequestqueue.h"
-#include "_httppolicy.h"
-#include "_httplibcurl.h"
-#include "_thread.h"
-#include "_httpinternal.h"
-
-#include "lltimer.h"
-#include "llthread.h"
-#include "llexception.h"
-#include "llmemory.h"
-
-namespace
-{
-
-static const char * const LOG_CORE("CoreHttp");
-
-} // end anonymous namespace
-
-
-namespace LLCore
-{
-
-const HttpService::OptionDescriptor HttpService::sOptionDesc[] =
-{ // isLong isDynamic isGlobal isClass
- { true, true, true, true, false }, // PO_CONNECTION_LIMIT
- { true, true, false, true, false }, // PO_PER_HOST_CONNECTION_LIMIT
- { false, false, true, false, false }, // PO_CA_PATH
- { false, false, true, false, false }, // PO_CA_FILE
- { false, true, true, false, false }, // PO_HTTP_PROXY
- { true, true, true, false, false }, // PO_LLPROXY
- { true, true, true, false, false }, // PO_TRACE
- { true, true, false, true, false }, // PO_ENABLE_PIPELINING
- { true, true, false, true, false }, // PO_THROTTLE_RATE
- { false, false, true, false, true } // PO_SSL_VERIFY_CALLBACK
-};
-HttpService * HttpService::sInstance(NULL);
-volatile HttpService::EState HttpService::sState(NOT_INITIALIZED);
-
-HttpService::HttpService()
- : mRequestQueue(NULL),
- mExitRequested(0U),
- mThread(NULL),
- mPolicy(NULL),
- mTransport(NULL),
- mLastPolicy(0)
-{}
-
-
-HttpService::~HttpService()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- mExitRequested = 1U;
- if (RUNNING == sState)
- {
- // Trying to kill the service object with a running thread
- // is a bit tricky.
- if (mRequestQueue)
- {
- if (mRequestQueue->stopQueue())
- {
- // Give mRequestQueue a chance to finish
- ms_sleep(10);
- }
- }
-
- if (mThread)
- {
- if (! mThread->timedJoin(250))
- {
- // Failed to join, expect problems ahead so do a hard termination.
- LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread. Expect problems." << LL_NEWLINE
- << "State: " << S32(sState)
- << " Last policy: " << U32(mLastPolicy)
- << LL_ENDL;
-
- mThread->cancel();
- }
- }
- }
-
- if (mRequestQueue)
- {
- mRequestQueue->release();
- mRequestQueue = NULL;
- }
-
- delete mTransport;
- mTransport = NULL;
-
- delete mPolicy;
- mPolicy = NULL;
-
- if (mThread)
- {
- mThread->release();
- mThread = NULL;
- }
-}
-
-
-void HttpService::init(HttpRequestQueue * queue)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- llassert_always(! sInstance);
- llassert_always(NOT_INITIALIZED == sState);
- sInstance = new HttpService();
-
- queue->addRef();
- sInstance->mRequestQueue = queue;
- sInstance->mPolicy = new HttpPolicy(sInstance);
- sInstance->mTransport = new HttpLibcurl(sInstance);
- sState = INITIALIZED;
-}
-
-
-void HttpService::term()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- if (sInstance)
- {
- if (RUNNING == sState && sInstance->mThread)
- {
- // Unclean termination. Thread appears to be running. We'll
- // try to give the worker thread a chance to cancel using the
- // exit flag...
- sInstance->mExitRequested = 1U;
- sInstance->mRequestQueue->stopQueue();
-
- // And a little sleep
- for (int i(0); i < 10 && RUNNING == sState; ++i)
- {
- ms_sleep(100);
- }
- }
-
- delete sInstance;
- sInstance = NULL;
- }
- sState = NOT_INITIALIZED;
-}
-
-
-HttpRequest::policy_t HttpService::createPolicyClass()
-{
- mLastPolicy = mPolicy->createPolicyClass();
- return mLastPolicy;
-}
-
-
-bool HttpService::isStopped()
-{
- // What is really wanted here is something like:
- //
- // HttpService * service = instanceOf();
- // return STOPPED == sState && (! service || ! service->mThread || ! service->mThread->joinable());
- //
- // But boost::thread is not giving me a consistent story on joinability
- // of a thread after it returns. Debug and non-debug builds are showing
- // different behavior on Linux/Etch so we do a weaker test that may
- // not be globally correct (i.e. thread *is* stopping, may not have
- // stopped but will very soon):
-
- return STOPPED == sState;
-}
-
-
-/// Threading: callable by consumer thread *once*.
-void HttpService::startThread()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- llassert_always(! mThread || STOPPED == sState);
- llassert_always(INITIALIZED == sState || STOPPED == sState);
-
- if (mThread)
- {
- mThread->release();
- }
-
- // Push current policy definitions, enable policy & transport components
- mPolicy->start();
- mTransport->start(mLastPolicy + 1);
-
- mThread = new LLCoreInt::HttpThread(boost::bind(&HttpService::threadRun, this, _1));
- sState = RUNNING;
-}
-
-
-/// Threading: callable by worker thread.
-void HttpService::stopRequested()
-{
- mExitRequested = 1U;
-}
-
-
-/// Try to find the given request handle on any of the request
-/// queues and cancel the operation.
-///
-/// @return True if the request was canceled.
-///
-/// Threading: callable by worker thread.
-bool HttpService::cancel(HttpHandle handle)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- bool canceled(false);
-
- // Request can't be on request queue so skip that.
-
- // Check the policy component's queues first
- canceled = mPolicy->cancel(handle);
-
- if (! canceled)
- {
- // If that didn't work, check transport's.
- canceled = mTransport->cancel(handle);
- }
-
- return canceled;
-}
-
-
-/// Threading: callable by worker thread.
-void HttpService::shutdown()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- // Disallow future enqueue of requests
- mRequestQueue->stopQueue();
-
- // Cancel requests already on the request queue
- HttpRequestQueue::OpContainer ops;
- mRequestQueue->fetchAll(false, ops);
-
- for (HttpRequestQueue::OpContainer::iterator it = ops.begin();
- it != ops.end(); ++it)
- {
- (*it)->cancel();
- }
- ops.clear();
-
- // Shutdown transport canceling requests, freeing resources
- mTransport->shutdown();
-
- // And now policy
- mPolicy->shutdown();
-}
-
-
-// Working thread loop-forever method. Gives time to
-// each of the request queue, policy layer and transport
-// layer pieces and then either sleeps for a small time
-// or waits for a request to come in. Repeats until
-// requested to stop.
-void HttpService::threadRun(LLCoreInt::HttpThread * thread)
-{
- LL_PROFILER_SET_THREAD_NAME("HttpService");
-
- boost::this_thread::disable_interruption di;
-
- LLThread::registerThreadID();
-
- ELoopSpeed loop(REQUEST_SLEEP);
- while (! mExitRequested)
- {
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- try
- {
- loop = processRequestQueue(loop);
-
- // Process ready queue issuing new requests as needed
- ELoopSpeed new_loop = mPolicy->processReadyQueue();
- loop = (std::min)(loop, new_loop);
-
- // Give libcurl some cycles
- new_loop = mTransport->processTransport();
- loop = (std::min)(loop, new_loop);
-
- // Determine whether to spin, sleep briefly or sleep for next request
- if (REQUEST_SLEEP != loop)
- {
- ms_sleep(HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS);
- }
- }
- catch (const LLContinueError&)
- {
- LOG_UNHANDLED_EXCEPTION("");
- }
- catch (std::bad_alloc&)
- {
- LLMemory::logMemoryInfo(true);
-
- //output possible call stacks to log file.
- LLError::LLUserWarningMsg::showOutOfMemory();
- LLError::LLCallStacks::print();
-
- LL_ERRS() << "Bad memory allocation in HttpService::threadRun()!" << LL_ENDL;
- }
- catch (...)
- {
- CRASH_ON_UNHANDLED_EXCEPTION("");
- }
- }
-
- shutdown();
- sState = STOPPED;
-}
-
-
-HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- HttpRequestQueue::OpContainer ops;
- const bool wait_for_req(REQUEST_SLEEP == loop);
-
- mRequestQueue->fetchAll(wait_for_req, ops);
- while (! ops.empty())
- {
- HttpOperation::ptr_t op(ops.front());
- ops.erase(ops.begin());
-
- // Process operation
- if (! mExitRequested)
- {
- // Setup for subsequent tracing
- long tracing(HTTP_TRACE_OFF);
- mPolicy->getGlobalOptions().get(HttpRequest::PO_TRACE, &tracing);
- op->mTracing = (std::max)(op->mTracing, int(tracing));
-
- if (op->mTracing > HTTP_TRACE_OFF)
- {
- LL_INFOS(LOG_CORE) << "TRACE, FromRequestQueue, Handle: "
- << op->getHandle()
- << LL_ENDL;
- }
-
- // Stage
- op->stageFromRequest(this);
- }
-
- // Done with operation
- op.reset();
- }
-
- // Queue emptied, allow polling loop to sleep
- return REQUEST_SLEEP;
-}
-
-
-HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
- long * ret_value)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
- || opt >= HttpRequest::PO_LAST // ditto
- || (! sOptionDesc[opt].mIsLong) // datatype is long
- || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
- || (pclass == HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsGlobal) // global setting permitted
- || (pclass != HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsClass)) // class setting permitted
- // can always get, no dynamic check
- {
- return HttpStatus(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
- }
-
- HttpStatus status;
- if (pclass == HttpRequest::GLOBAL_POLICY_ID)
- {
- HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
-
- status = opts.get(opt, ret_value);
- }
- else
- {
- HttpPolicyClass & opts(mPolicy->getClassOptions(pclass));
-
- status = opts.get(opt, ret_value);
- }
-
- return status;
-}
-
-
-HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
- std::string * ret_value)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
-
- if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
- || opt >= HttpRequest::PO_LAST // ditto
- || (sOptionDesc[opt].mIsLong) // datatype is string
- || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
- || (pclass == HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsGlobal) // global setting permitted
- || (pclass != HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsClass)) // class setting permitted
- // can always get, no dynamic check
- {
- return status;
- }
-
- // Only global has string values
- if (pclass == HttpRequest::GLOBAL_POLICY_ID)
- {
- HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
-
- status = opts.get(opt, ret_value);
- }
-
- return status;
-}
-
-HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
- HttpRequest::policyCallback_t * ret_value)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
-
- if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
- || opt >= HttpRequest::PO_LAST // ditto
- || (sOptionDesc[opt].mIsLong) // datatype is string
- || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
- || (pclass == HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsGlobal) // global setting permitted
- || (pclass != HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsClass)) // class setting permitted
- // can always get, no dynamic check
- {
- return status;
- }
-
- // Only global has callback values
- if (pclass == HttpRequest::GLOBAL_POLICY_ID)
- {
- HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
-
- status = opts.get(opt, ret_value);
- }
-
- return status;
-}
-
-
-
-HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
- long value, long * ret_value)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
-
- if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
- || opt >= HttpRequest::PO_LAST // ditto
- || (! sOptionDesc[opt].mIsLong) // datatype is long
- || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
- || (pclass == HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsGlobal) // global setting permitted
- || (pclass != HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsClass) // class setting permitted
- || (RUNNING == sState && ! sOptionDesc[opt].mIsDynamic)) // dynamic setting permitted
- {
- return status;
- }
-
- if (pclass == HttpRequest::GLOBAL_POLICY_ID)
- {
- HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
-
- status = opts.set(opt, value);
- if (status && ret_value)
- {
- status = opts.get(opt, ret_value);
- }
- }
- else
- {
- HttpPolicyClass & opts(mPolicy->getClassOptions(pclass));
-
- status = opts.set(opt, value);
- if (status)
- {
- mTransport->policyUpdated(pclass);
- if (ret_value)
- {
- status = opts.get(opt, ret_value);
- }
- }
- }
-
- return status;
-}
-
-
-HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
- const std::string & value, std::string * ret_value)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
-
- if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
- || opt >= HttpRequest::PO_LAST // ditto
- || (sOptionDesc[opt].mIsLong) // datatype is string
- || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
- || (pclass == HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsGlobal) // global setting permitted
- || (pclass != HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsClass) // class setting permitted
- || (RUNNING == sState && ! sOptionDesc[opt].mIsDynamic)) // dynamic setting permitted
- {
- return status;
- }
-
- // String values are always global (at this time).
- if (pclass == HttpRequest::GLOBAL_POLICY_ID)
- {
- HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
-
- status = opts.set(opt, value);
- if (status && ret_value)
- {
- status = opts.get(opt, ret_value);
- }
- }
-
- return status;
-}
-
-HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
- HttpRequest::policyCallback_t value, HttpRequest::policyCallback_t * ret_value)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
-
- if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
- || opt >= HttpRequest::PO_LAST // ditto
- || (sOptionDesc[opt].mIsLong) // datatype is string
- || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
- || (pclass == HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsGlobal) // global setting permitted
- || (pclass != HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsClass) // class setting permitted
- || (RUNNING == sState && !sOptionDesc[opt].mIsDynamic)) // dynamic setting permitted
- {
- return status;
- }
-
- // Callbacks values are always global (at this time).
- if (pclass == HttpRequest::GLOBAL_POLICY_ID)
- {
- HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
-
- status = opts.set(opt, value);
- if (status && ret_value)
- {
- status = opts.get(opt, ret_value);
- }
- }
-
- return status;
-}
-
-
-} // end namespace LLCore
+/**
+ * @file _httpservice.cpp
+ * @brief Internal definitions of the Http service thread
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012-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 "_httpservice.h"
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+
+#include "_httpoperation.h"
+#include "_httprequestqueue.h"
+#include "_httppolicy.h"
+#include "_httplibcurl.h"
+#include "_thread.h"
+#include "_httpinternal.h"
+
+#include "lltimer.h"
+#include "llthread.h"
+#include "llexception.h"
+#include "llmemory.h"
+
+namespace
+{
+
+static const char * const LOG_CORE("CoreHttp");
+
+} // end anonymous namespace
+
+
+namespace LLCore
+{
+
+const HttpService::OptionDescriptor HttpService::sOptionDesc[] =
+{ // isLong isDynamic isGlobal isClass
+ { true, true, true, true, false }, // PO_CONNECTION_LIMIT
+ { true, true, false, true, false }, // PO_PER_HOST_CONNECTION_LIMIT
+ { false, false, true, false, false }, // PO_CA_PATH
+ { false, false, true, false, false }, // PO_CA_FILE
+ { false, true, true, false, false }, // PO_HTTP_PROXY
+ { true, true, true, false, false }, // PO_LLPROXY
+ { true, true, true, false, false }, // PO_TRACE
+ { true, true, false, true, false }, // PO_ENABLE_PIPELINING
+ { true, true, false, true, false }, // PO_THROTTLE_RATE
+ { false, false, true, false, true } // PO_SSL_VERIFY_CALLBACK
+};
+HttpService * HttpService::sInstance(NULL);
+volatile HttpService::EState HttpService::sState(NOT_INITIALIZED);
+
+HttpService::HttpService()
+ : mRequestQueue(NULL),
+ mExitRequested(0U),
+ mThread(NULL),
+ mPolicy(NULL),
+ mTransport(NULL),
+ mLastPolicy(0)
+{}
+
+
+HttpService::~HttpService()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ mExitRequested = 1U;
+ if (RUNNING == sState)
+ {
+ // Trying to kill the service object with a running thread
+ // is a bit tricky.
+ if (mRequestQueue)
+ {
+ if (mRequestQueue->stopQueue())
+ {
+ // Give mRequestQueue a chance to finish
+ ms_sleep(10);
+ }
+ }
+
+ if (mThread)
+ {
+ if (! mThread->timedJoin(250))
+ {
+ // Failed to join, expect problems ahead so do a hard termination.
+ LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread. Expect problems." << LL_NEWLINE
+ << "State: " << S32(sState)
+ << " Last policy: " << U32(mLastPolicy)
+ << LL_ENDL;
+
+ mThread->cancel();
+ }
+ }
+ }
+
+ if (mRequestQueue)
+ {
+ mRequestQueue->release();
+ mRequestQueue = NULL;
+ }
+
+ delete mTransport;
+ mTransport = NULL;
+
+ delete mPolicy;
+ mPolicy = NULL;
+
+ if (mThread)
+ {
+ mThread->release();
+ mThread = NULL;
+ }
+}
+
+
+void HttpService::init(HttpRequestQueue * queue)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ llassert_always(! sInstance);
+ llassert_always(NOT_INITIALIZED == sState);
+ sInstance = new HttpService();
+
+ queue->addRef();
+ sInstance->mRequestQueue = queue;
+ sInstance->mPolicy = new HttpPolicy(sInstance);
+ sInstance->mTransport = new HttpLibcurl(sInstance);
+ sState = INITIALIZED;
+}
+
+
+void HttpService::term()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ if (sInstance)
+ {
+ if (RUNNING == sState && sInstance->mThread)
+ {
+ // Unclean termination. Thread appears to be running. We'll
+ // try to give the worker thread a chance to cancel using the
+ // exit flag...
+ sInstance->mExitRequested = 1U;
+ sInstance->mRequestQueue->stopQueue();
+
+ // And a little sleep
+ for (int i(0); i < 10 && RUNNING == sState; ++i)
+ {
+ ms_sleep(100);
+ }
+ }
+
+ delete sInstance;
+ sInstance = NULL;
+ }
+ sState = NOT_INITIALIZED;
+}
+
+
+HttpRequest::policy_t HttpService::createPolicyClass()
+{
+ mLastPolicy = mPolicy->createPolicyClass();
+ return mLastPolicy;
+}
+
+
+bool HttpService::isStopped()
+{
+ // What is really wanted here is something like:
+ //
+ // HttpService * service = instanceOf();
+ // return STOPPED == sState && (! service || ! service->mThread || ! service->mThread->joinable());
+ //
+ // But boost::thread is not giving me a consistent story on joinability
+ // of a thread after it returns. Debug and non-debug builds are showing
+ // different behavior on Linux/Etch so we do a weaker test that may
+ // not be globally correct (i.e. thread *is* stopping, may not have
+ // stopped but will very soon):
+
+ return STOPPED == sState;
+}
+
+
+/// Threading: callable by consumer thread *once*.
+void HttpService::startThread()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ llassert_always(! mThread || STOPPED == sState);
+ llassert_always(INITIALIZED == sState || STOPPED == sState);
+
+ if (mThread)
+ {
+ mThread->release();
+ }
+
+ // Push current policy definitions, enable policy & transport components
+ mPolicy->start();
+ mTransport->start(mLastPolicy + 1);
+
+ mThread = new LLCoreInt::HttpThread(boost::bind(&HttpService::threadRun, this, _1));
+ sState = RUNNING;
+}
+
+
+/// Threading: callable by worker thread.
+void HttpService::stopRequested()
+{
+ mExitRequested = 1U;
+}
+
+
+/// Try to find the given request handle on any of the request
+/// queues and cancel the operation.
+///
+/// @return True if the request was canceled.
+///
+/// Threading: callable by worker thread.
+bool HttpService::cancel(HttpHandle handle)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ bool canceled(false);
+
+ // Request can't be on request queue so skip that.
+
+ // Check the policy component's queues first
+ canceled = mPolicy->cancel(handle);
+
+ if (! canceled)
+ {
+ // If that didn't work, check transport's.
+ canceled = mTransport->cancel(handle);
+ }
+
+ return canceled;
+}
+
+
+/// Threading: callable by worker thread.
+void HttpService::shutdown()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ // Disallow future enqueue of requests
+ mRequestQueue->stopQueue();
+
+ // Cancel requests already on the request queue
+ HttpRequestQueue::OpContainer ops;
+ mRequestQueue->fetchAll(false, ops);
+
+ for (HttpRequestQueue::OpContainer::iterator it = ops.begin();
+ it != ops.end(); ++it)
+ {
+ (*it)->cancel();
+ }
+ ops.clear();
+
+ // Shutdown transport canceling requests, freeing resources
+ mTransport->shutdown();
+
+ // And now policy
+ mPolicy->shutdown();
+}
+
+
+// Working thread loop-forever method. Gives time to
+// each of the request queue, policy layer and transport
+// layer pieces and then either sleeps for a small time
+// or waits for a request to come in. Repeats until
+// requested to stop.
+void HttpService::threadRun(LLCoreInt::HttpThread * thread)
+{
+ LL_PROFILER_SET_THREAD_NAME("HttpService");
+
+ boost::this_thread::disable_interruption di;
+
+ LLThread::registerThreadID();
+
+ ELoopSpeed loop(REQUEST_SLEEP);
+ while (! mExitRequested)
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ try
+ {
+ loop = processRequestQueue(loop);
+
+ // Process ready queue issuing new requests as needed
+ ELoopSpeed new_loop = mPolicy->processReadyQueue();
+ loop = (std::min)(loop, new_loop);
+
+ // Give libcurl some cycles
+ new_loop = mTransport->processTransport();
+ loop = (std::min)(loop, new_loop);
+
+ // Determine whether to spin, sleep briefly or sleep for next request
+ if (REQUEST_SLEEP != loop)
+ {
+ ms_sleep(HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS);
+ }
+ }
+ catch (const LLContinueError&)
+ {
+ LOG_UNHANDLED_EXCEPTION("");
+ }
+ catch (std::bad_alloc&)
+ {
+ LLMemory::logMemoryInfo(true);
+
+ //output possible call stacks to log file.
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LLError::LLCallStacks::print();
+
+ LL_ERRS() << "Bad memory allocation in HttpService::threadRun()!" << LL_ENDL;
+ }
+ catch (...)
+ {
+ CRASH_ON_UNHANDLED_EXCEPTION("");
+ }
+ }
+
+ shutdown();
+ sState = STOPPED;
+}
+
+
+HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ HttpRequestQueue::OpContainer ops;
+ const bool wait_for_req(REQUEST_SLEEP == loop);
+
+ mRequestQueue->fetchAll(wait_for_req, ops);
+ while (! ops.empty())
+ {
+ HttpOperation::ptr_t op(ops.front());
+ ops.erase(ops.begin());
+
+ // Process operation
+ if (! mExitRequested)
+ {
+ // Setup for subsequent tracing
+ long tracing(HTTP_TRACE_OFF);
+ mPolicy->getGlobalOptions().get(HttpRequest::PO_TRACE, &tracing);
+ op->mTracing = (std::max)(op->mTracing, int(tracing));
+
+ if (op->mTracing > HTTP_TRACE_OFF)
+ {
+ LL_INFOS(LOG_CORE) << "TRACE, FromRequestQueue, Handle: "
+ << op->getHandle()
+ << LL_ENDL;
+ }
+
+ // Stage
+ op->stageFromRequest(this);
+ }
+
+ // Done with operation
+ op.reset();
+ }
+
+ // Queue emptied, allow polling loop to sleep
+ return REQUEST_SLEEP;
+}
+
+
+HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+ long * ret_value)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
+ || opt >= HttpRequest::PO_LAST // ditto
+ || (! sOptionDesc[opt].mIsLong) // datatype is long
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
+ || (pclass == HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsGlobal) // global setting permitted
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsClass)) // class setting permitted
+ // can always get, no dynamic check
+ {
+ return HttpStatus(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
+ }
+
+ HttpStatus status;
+ if (pclass == HttpRequest::GLOBAL_POLICY_ID)
+ {
+ HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
+
+ status = opts.get(opt, ret_value);
+ }
+ else
+ {
+ HttpPolicyClass & opts(mPolicy->getClassOptions(pclass));
+
+ status = opts.get(opt, ret_value);
+ }
+
+ return status;
+}
+
+
+HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+ std::string * ret_value)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
+
+ if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
+ || opt >= HttpRequest::PO_LAST // ditto
+ || (sOptionDesc[opt].mIsLong) // datatype is string
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
+ || (pclass == HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsGlobal) // global setting permitted
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsClass)) // class setting permitted
+ // can always get, no dynamic check
+ {
+ return status;
+ }
+
+ // Only global has string values
+ if (pclass == HttpRequest::GLOBAL_POLICY_ID)
+ {
+ HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
+
+ status = opts.get(opt, ret_value);
+ }
+
+ return status;
+}
+
+HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+ HttpRequest::policyCallback_t * ret_value)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
+
+ if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
+ || opt >= HttpRequest::PO_LAST // ditto
+ || (sOptionDesc[opt].mIsLong) // datatype is string
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
+ || (pclass == HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsGlobal) // global setting permitted
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsClass)) // class setting permitted
+ // can always get, no dynamic check
+ {
+ return status;
+ }
+
+ // Only global has callback values
+ if (pclass == HttpRequest::GLOBAL_POLICY_ID)
+ {
+ HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
+
+ status = opts.get(opt, ret_value);
+ }
+
+ return status;
+}
+
+
+
+HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+ long value, long * ret_value)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
+
+ if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
+ || opt >= HttpRequest::PO_LAST // ditto
+ || (! sOptionDesc[opt].mIsLong) // datatype is long
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
+ || (pclass == HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsGlobal) // global setting permitted
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsClass) // class setting permitted
+ || (RUNNING == sState && ! sOptionDesc[opt].mIsDynamic)) // dynamic setting permitted
+ {
+ return status;
+ }
+
+ if (pclass == HttpRequest::GLOBAL_POLICY_ID)
+ {
+ HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
+
+ status = opts.set(opt, value);
+ if (status && ret_value)
+ {
+ status = opts.get(opt, ret_value);
+ }
+ }
+ else
+ {
+ HttpPolicyClass & opts(mPolicy->getClassOptions(pclass));
+
+ status = opts.set(opt, value);
+ if (status)
+ {
+ mTransport->policyUpdated(pclass);
+ if (ret_value)
+ {
+ status = opts.get(opt, ret_value);
+ }
+ }
+ }
+
+ return status;
+}
+
+
+HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+ const std::string & value, std::string * ret_value)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
+
+ if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
+ || opt >= HttpRequest::PO_LAST // ditto
+ || (sOptionDesc[opt].mIsLong) // datatype is string
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
+ || (pclass == HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsGlobal) // global setting permitted
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsClass) // class setting permitted
+ || (RUNNING == sState && ! sOptionDesc[opt].mIsDynamic)) // dynamic setting permitted
+ {
+ return status;
+ }
+
+ // String values are always global (at this time).
+ if (pclass == HttpRequest::GLOBAL_POLICY_ID)
+ {
+ HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
+
+ status = opts.set(opt, value);
+ if (status && ret_value)
+ {
+ status = opts.get(opt, ret_value);
+ }
+ }
+
+ return status;
+}
+
+HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+ HttpRequest::policyCallback_t value, HttpRequest::policyCallback_t * ret_value)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
+
+ if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
+ || opt >= HttpRequest::PO_LAST // ditto
+ || (sOptionDesc[opt].mIsLong) // datatype is string
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
+ || (pclass == HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsGlobal) // global setting permitted
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsClass) // class setting permitted
+ || (RUNNING == sState && !sOptionDesc[opt].mIsDynamic)) // dynamic setting permitted
+ {
+ return status;
+ }
+
+ // Callbacks values are always global (at this time).
+ if (pclass == HttpRequest::GLOBAL_POLICY_ID)
+ {
+ HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
+
+ status = opts.set(opt, value);
+ if (status && ret_value)
+ {
+ status = opts.get(opt, ret_value);
+ }
+ }
+
+ return status;
+}
+
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h
index 551a718f20..13eb034f0e 100644
--- a/indra/llcorehttp/_httpservice.h
+++ b/indra/llcorehttp/_httpservice.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_SERVICE_H_
-#define _LLCORE_HTTP_SERVICE_H_
+#ifndef _LLCORE_HTTP_SERVICE_H_
+#define _LLCORE_HTTP_SERVICE_H_
#include <vector>
@@ -82,151 +82,151 @@ class HttpOpSetGet;
class HttpService
{
protected:
- HttpService();
- virtual ~HttpService();
+ HttpService();
+ virtual ~HttpService();
private:
- HttpService(const HttpService &); // Not defined
- void operator=(const HttpService &); // Not defined
+ HttpService(const HttpService &); // Not defined
+ void operator=(const HttpService &); // Not defined
public:
- enum EState
- {
- NOT_INITIALIZED = -1,
- INITIALIZED, ///< init() has been called
- RUNNING, ///< thread created and running
- STOPPED ///< thread has committed to exiting
- };
-
- // Ordered enumeration of idling strategies available to
- // threadRun's loop. Ordered so that std::min on values
- // produces the most conservative result of multiple
- // requests.
- enum ELoopSpeed
- {
- NORMAL, ///< continuous polling of request, ready, active queues
- REQUEST_SLEEP ///< can sleep indefinitely waiting for request queue write
- };
-
- static void init(HttpRequestQueue *);
- static void term();
-
- /// Threading: callable by any thread once inited.
- inline static HttpService * instanceOf()
- {
- return sInstance;
- }
-
- /// Return the state of the worker thread. Note that the
- /// transition from RUNNING to STOPPED is performed by the
- /// worker thread itself. This has two weaknesses:
- /// - race where the thread hasn't really stopped but will
- /// - data ordering between threads where a non-worker thread
- /// may see a stale RUNNING status.
- ///
- /// This transition is generally of interest only to unit tests
- /// and these weaknesses shouldn't be any real burden.
- ///
- /// Threading: callable by any thread with above exceptions.
- static EState getState()
- {
- return sState;
- }
-
- /// Threading: callable by any thread but uses @see getState() and
- /// acquires its weaknesses.
- static bool isStopped();
-
- /// Threading: callable by init thread *once*.
- void startThread();
-
- /// Threading: callable by worker thread.
- void stopRequested();
-
- /// Threading: callable by worker thread.
- void shutdown();
-
- /// Try to find the given request handle on any of the request
- /// queues and cancel the operation.
- ///
- /// @return True if the request was found and canceled.
- ///
- /// Threading: callable by worker thread.
- bool cancel(HttpHandle handle);
-
- /// Threading: callable by worker thread.
- HttpPolicy & getPolicy()
- {
- return *mPolicy;
- }
-
- /// Threading: callable by worker thread.
- HttpLibcurl & getTransport()
- {
- return *mTransport;
- }
-
- /// Threading: callable by worker thread.
- HttpRequestQueue & getRequestQueue()
- {
- return *mRequestQueue;
- }
-
- /// Threading: callable by consumer thread.
- HttpRequest::policy_t createPolicyClass();
-
+ enum EState
+ {
+ NOT_INITIALIZED = -1,
+ INITIALIZED, ///< init() has been called
+ RUNNING, ///< thread created and running
+ STOPPED ///< thread has committed to exiting
+ };
+
+ // Ordered enumeration of idling strategies available to
+ // threadRun's loop. Ordered so that std::min on values
+ // produces the most conservative result of multiple
+ // requests.
+ enum ELoopSpeed
+ {
+ NORMAL, ///< continuous polling of request, ready, active queues
+ REQUEST_SLEEP ///< can sleep indefinitely waiting for request queue write
+ };
+
+ static void init(HttpRequestQueue *);
+ static void term();
+
+ /// Threading: callable by any thread once inited.
+ inline static HttpService * instanceOf()
+ {
+ return sInstance;
+ }
+
+ /// Return the state of the worker thread. Note that the
+ /// transition from RUNNING to STOPPED is performed by the
+ /// worker thread itself. This has two weaknesses:
+ /// - race where the thread hasn't really stopped but will
+ /// - data ordering between threads where a non-worker thread
+ /// may see a stale RUNNING status.
+ ///
+ /// This transition is generally of interest only to unit tests
+ /// and these weaknesses shouldn't be any real burden.
+ ///
+ /// Threading: callable by any thread with above exceptions.
+ static EState getState()
+ {
+ return sState;
+ }
+
+ /// Threading: callable by any thread but uses @see getState() and
+ /// acquires its weaknesses.
+ static bool isStopped();
+
+ /// Threading: callable by init thread *once*.
+ void startThread();
+
+ /// Threading: callable by worker thread.
+ void stopRequested();
+
+ /// Threading: callable by worker thread.
+ void shutdown();
+
+ /// Try to find the given request handle on any of the request
+ /// queues and cancel the operation.
+ ///
+ /// @return True if the request was found and canceled.
+ ///
+ /// Threading: callable by worker thread.
+ bool cancel(HttpHandle handle);
+
+ /// Threading: callable by worker thread.
+ HttpPolicy & getPolicy()
+ {
+ return *mPolicy;
+ }
+
+ /// Threading: callable by worker thread.
+ HttpLibcurl & getTransport()
+ {
+ return *mTransport;
+ }
+
+ /// Threading: callable by worker thread.
+ HttpRequestQueue & getRequestQueue()
+ {
+ return *mRequestQueue;
+ }
+
+ /// Threading: callable by consumer thread.
+ HttpRequest::policy_t createPolicyClass();
+
protected:
- void threadRun(LLCoreInt::HttpThread * thread);
-
- ELoopSpeed processRequestQueue(ELoopSpeed loop);
+ void threadRun(LLCoreInt::HttpThread * thread);
+
+ ELoopSpeed processRequestQueue(ELoopSpeed loop);
protected:
- friend class HttpOpSetGet;
- friend class HttpRequest;
-
- // Used internally to describe what operations are allowed
- // on each policy option.
- struct OptionDescriptor
- {
- bool mIsLong;
- bool mIsDynamic;
- bool mIsGlobal;
- bool mIsClass;
- bool mIsCallback;
- };
-
- HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
- long * ret_value);
- HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
- std::string * ret_value);
- HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
- HttpRequest::policyCallback_t * ret_value);
-
- HttpStatus setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
- long value, long * ret_value);
- HttpStatus setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
- const std::string & value, std::string * ret_value);
- HttpStatus setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
- HttpRequest::policyCallback_t value,
- HttpRequest::policyCallback_t * ret_value);
+ friend class HttpOpSetGet;
+ friend class HttpRequest;
+
+ // Used internally to describe what operations are allowed
+ // on each policy option.
+ struct OptionDescriptor
+ {
+ bool mIsLong;
+ bool mIsDynamic;
+ bool mIsGlobal;
+ bool mIsClass;
+ bool mIsCallback;
+ };
+
+ HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
+ long * ret_value);
+ HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
+ std::string * ret_value);
+ HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
+ HttpRequest::policyCallback_t * ret_value);
+
+ HttpStatus setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
+ long value, long * ret_value);
+ HttpStatus setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
+ const std::string & value, std::string * ret_value);
+ HttpStatus setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
+ HttpRequest::policyCallback_t value,
+ HttpRequest::policyCallback_t * ret_value);
protected:
- static const OptionDescriptor sOptionDesc[HttpRequest::PO_LAST];
- static HttpService * sInstance;
-
- // === shared data ===
- static volatile EState sState;
- HttpRequestQueue * mRequestQueue; // Refcounted
- LLAtomicU32 mExitRequested;
- LLCoreInt::HttpThread * mThread;
-
- // === working-thread-only data ===
- HttpPolicy * mPolicy; // Simple pointer, has ownership
- HttpLibcurl * mTransport; // Simple pointer, has ownership
-
- // === main-thread-only data ===
- HttpRequest::policy_t mLastPolicy;
-
+ static const OptionDescriptor sOptionDesc[HttpRequest::PO_LAST];
+ static HttpService * sInstance;
+
+ // === shared data ===
+ static volatile EState sState;
+ HttpRequestQueue * mRequestQueue; // Refcounted
+ LLAtomicU32 mExitRequested;
+ LLCoreInt::HttpThread * mThread;
+
+ // === working-thread-only data ===
+ HttpPolicy * mPolicy; // Simple pointer, has ownership
+ HttpLibcurl * mTransport; // Simple pointer, has ownership
+
+ // === main-thread-only data ===
+ HttpRequest::policy_t mLastPolicy;
+
}; // end class HttpService
} // end namespace LLCore
diff --git a/indra/llcorehttp/_mutex.h b/indra/llcorehttp/_mutex.h
index 4be4d016d4..5e0164eb51 100644
--- a/indra/llcorehttp/_mutex.h
+++ b/indra/llcorehttp/_mutex.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file _mutex.hpp
* @brief mutex type abstraction
*
@@ -51,5 +51,5 @@ typedef boost::unique_lock<HttpMutex> HttpScopedLock;
}
-#endif // LLCOREINT_MUTEX_H
+#endif // LLCOREINT_MUTEX_H
diff --git a/indra/llcorehttp/_refcounted.cpp b/indra/llcorehttp/_refcounted.cpp
index e7d0b72741..94b28102f3 100644
--- a/indra/llcorehttp/_refcounted.cpp
+++ b/indra/llcorehttp/_refcounted.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file _refcounted.cpp
* @brief Atomic, thread-safe ref counting and destruction mixin class
*
@@ -30,11 +30,11 @@
namespace LLCoreInt
{
-#if ! LL_WINDOWS
+#if ! LL_WINDOWS
const S32 RefCounted::NOT_REF_COUNTED;
-#endif // ! LL_WINDOWS
+#endif // ! LL_WINDOWS
RefCounted::~RefCounted()
{}
diff --git a/indra/llcorehttp/_refcounted.h b/indra/llcorehttp/_refcounted.h
index 5cc8914395..7470965a7f 100644
--- a/indra/llcorehttp/_refcounted.h
+++ b/indra/llcorehttp/_refcounted.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file _refcounted.h
* @brief Atomic, thread-safe ref counting and destruction mixin class
*
@@ -44,81 +44,81 @@ namespace LLCoreInt
class RefCounted
{
private:
- RefCounted(); // Not defined - may not be default constructed
- void operator=(const RefCounted &); // Not defined
-
+ RefCounted(); // Not defined - may not be default constructed
+ void operator=(const RefCounted &); // Not defined
+
public:
- explicit RefCounted(bool const implicit)
- : mRefCount(implicit)
- {}
-
- // ref-count interface
- void addRef() const;
- void release() const;
- bool isLastRef() const;
- S32 getRefCount() const;
- void noRef() const;
-
- static const S32 NOT_REF_COUNTED = -1;
-
+ explicit RefCounted(bool const implicit)
+ : mRefCount(implicit)
+ {}
+
+ // ref-count interface
+ void addRef() const;
+ void release() const;
+ bool isLastRef() const;
+ S32 getRefCount() const;
+ void noRef() const;
+
+ static const S32 NOT_REF_COUNTED = -1;
+
protected:
- virtual ~RefCounted();
- virtual void destroySelf();
+ virtual ~RefCounted();
+ virtual void destroySelf();
private:
- mutable LLAtomicS32 mRefCount;
+ mutable LLAtomicS32 mRefCount;
}; // end class RefCounted
inline void RefCounted::addRef() const
{
- S32 count(++mRefCount);
- llassert_always(count >= 0);
+ S32 count(++mRefCount);
+ llassert_always(count >= 0);
}
inline void RefCounted::release() const
{
- S32 count(mRefCount);
- llassert_always(count != NOT_REF_COUNTED);
- llassert_always(count > 0);
- count = --mRefCount;
-
- // clean ourselves up if that was the last reference
- if (0 == count)
- {
- const_cast<RefCounted *>(this)->destroySelf();
- }
+ S32 count(mRefCount);
+ llassert_always(count != NOT_REF_COUNTED);
+ llassert_always(count > 0);
+ count = --mRefCount;
+
+ // clean ourselves up if that was the last reference
+ if (0 == count)
+ {
+ const_cast<RefCounted *>(this)->destroySelf();
+ }
}
inline bool RefCounted::isLastRef() const
{
- const S32 count(mRefCount);
- llassert_always(count != NOT_REF_COUNTED);
- llassert_always(count >= 1);
- return (1 == count);
+ const S32 count(mRefCount);
+ llassert_always(count != NOT_REF_COUNTED);
+ llassert_always(count >= 1);
+ return (1 == count);
}
inline S32 RefCounted::getRefCount() const
{
- const S32 result(mRefCount);
- return result;
+ const S32 result(mRefCount);
+ return result;
}
inline void RefCounted::noRef() const
{
- llassert_always(mRefCount <= 1);
- mRefCount = NOT_REF_COUNTED;
+ llassert_always(mRefCount <= 1);
+ mRefCount = NOT_REF_COUNTED;
}
inline void RefCounted::destroySelf()
{
- delete this;
+ delete this;
}
/**
@@ -131,26 +131,26 @@ inline void RefCounted::destroySelf()
template <typename T>
struct IntrusivePtr: public boost::intrusive_ptr<T>
{
- IntrusivePtr():
- boost::intrusive_ptr<T>()
- {}
- IntrusivePtr(T* p):
- boost::intrusive_ptr<T>(p, false)
- {}
+ IntrusivePtr():
+ boost::intrusive_ptr<T>()
+ {}
+ IntrusivePtr(T* p):
+ boost::intrusive_ptr<T>(p, false)
+ {}
};
inline void intrusive_ptr_add_ref(RefCounted* p)
{
- p->addRef();
+ p->addRef();
}
inline void intrusive_ptr_release(RefCounted* p)
{
- p->release();
+ p->release();
}
} // end namespace LLCoreInt
-#endif // LLCOREINT__REFCOUNTED_H_
+#endif // LLCOREINT__REFCOUNTED_H_
diff --git a/indra/llcorehttp/_thread.h b/indra/llcorehttp/_thread.h
index 22b7750bad..6c0e39cf92 100644
--- a/indra/llcorehttp/_thread.h
+++ b/indra/llcorehttp/_thread.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file _thread.h
* @brief thread type abstraction
*
@@ -42,79 +42,79 @@ namespace LLCoreInt
class HttpThread : public RefCounted
{
private:
- HttpThread(); // Not defined
- void operator=(const HttpThread &); // Not defined
+ HttpThread(); // Not defined
+ void operator=(const HttpThread &); // Not defined
- void at_exit()
- {
- // the thread function has exited so we need to release our reference
- // to ourself so that we will be automagically cleaned up.
- release();
- }
+ void at_exit()
+ {
+ // the thread function has exited so we need to release our reference
+ // to ourself so that we will be automagically cleaned up.
+ release();
+ }
- void run()
- { // THREAD CONTEXT
+ void run()
+ { // THREAD CONTEXT
- // Take out additional reference for the at_exit handler
- addRef();
- boost::this_thread::at_thread_exit(boost::bind(&HttpThread::at_exit, this));
+ // Take out additional reference for the at_exit handler
+ addRef();
+ boost::this_thread::at_thread_exit(boost::bind(&HttpThread::at_exit, this));
- // run the thread function
- mThreadFunc(this);
+ // run the thread function
+ mThreadFunc(this);
- } // THREAD CONTEXT
+ } // THREAD CONTEXT
protected:
- virtual ~HttpThread()
- {
- delete mThread;
- }
+ virtual ~HttpThread()
+ {
+ delete mThread;
+ }
public:
- /// Constructs a thread object for concurrent execution but does
- /// not start running. Caller receives on refcount on the thread
- /// instance. If the thread is started, another will be taken
- /// out for the exit handler.
- explicit HttpThread(boost::function<void (HttpThread *)> threadFunc)
- : RefCounted(true), // implicit reference
- mThreadFunc(threadFunc)
- {
- // this creates a boost thread that will call HttpThread::run on this instance
- // and pass it the threadfunc callable...
- boost::function<void()> f = boost::bind(&HttpThread::run, this);
-
- mThread = new boost::thread(f);
- }
-
- inline void join()
- {
- mThread->join();
- }
-
- inline bool timedJoin(S32 millis)
- {
- return mThread->timed_join(boost::posix_time::milliseconds(millis));
- }
-
- inline bool joinable() const
- {
- return mThread->joinable();
- }
-
- // A very hostile method to force a thread to quit
- inline void cancel()
- {
- boost::thread::native_handle_type thread(mThread->native_handle());
-#if LL_WINDOWS
- TerminateThread(thread, 0);
+ /// Constructs a thread object for concurrent execution but does
+ /// not start running. Caller receives on refcount on the thread
+ /// instance. If the thread is started, another will be taken
+ /// out for the exit handler.
+ explicit HttpThread(boost::function<void (HttpThread *)> threadFunc)
+ : RefCounted(true), // implicit reference
+ mThreadFunc(threadFunc)
+ {
+ // this creates a boost thread that will call HttpThread::run on this instance
+ // and pass it the threadfunc callable...
+ boost::function<void()> f = boost::bind(&HttpThread::run, this);
+
+ mThread = new boost::thread(f);
+ }
+
+ inline void join()
+ {
+ mThread->join();
+ }
+
+ inline bool timedJoin(S32 millis)
+ {
+ return mThread->timed_join(boost::posix_time::milliseconds(millis));
+ }
+
+ inline bool joinable() const
+ {
+ return mThread->joinable();
+ }
+
+ // A very hostile method to force a thread to quit
+ inline void cancel()
+ {
+ boost::thread::native_handle_type thread(mThread->native_handle());
+#if LL_WINDOWS
+ TerminateThread(thread, 0);
#else
- pthread_cancel(thread);
+ pthread_cancel(thread);
#endif
- }
-
+ }
+
private:
- boost::function<void(HttpThread *)> mThreadFunc;
- boost::thread * mThread;
+ boost::function<void(HttpThread *)> mThreadFunc;
+ boost::thread * mThread;
}; // end class HttpThread
} // end namespace LLCoreInt
diff --git a/indra/llcorehttp/bufferarray.cpp b/indra/llcorehttp/bufferarray.cpp
index 1903e85e1c..c35f44c2c9 100644
--- a/indra/llcorehttp/bufferarray.cpp
+++ b/indra/llcorehttp/bufferarray.cpp
@@ -1,368 +1,368 @@
-/**
- * @file bufferarray.cpp
- * @brief Implements the BufferArray scatter/gather buffer
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2012, 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 "bufferarray.h"
-#include "llexception.h"
-#include "llmemory.h"
-
-
-// BufferArray is a list of chunks, each a BufferArray::Block, of contiguous
-// data presented as a single array. Chunks are at least BufferArray::BLOCK_ALLOC_SIZE
-// in length and can be larger. Any chunk may be partially filled or even
-// empty.
-//
-// The BufferArray itself is sharable as a RefCounted entity. As shared
-// reads don't work with the concept of a current position/seek value,
-// none is kept with the object. Instead, the read and write operations
-// all take position arguments. Single write/shared read isn't supported
-// directly and any such attempts have to be serialized outside of this
-// implementation.
-
-namespace LLCore
-{
-
-
-// ==================================
-// BufferArray::Block Declaration
-// ==================================
-
-class BufferArray::Block
-{
-public:
- ~Block();
-
- void operator delete(void *);
- void operator delete(void *, size_t len);
-
-protected:
- Block(size_t len);
-
- Block(const Block &); // Not defined
- void operator=(const Block &); // Not defined
-
- // Allocate the block with the additional space for the
- // buffered data at the end of the object.
- void * operator new(size_t len, size_t addl_len);
-
-public:
- // Only public entry to get a block.
- static Block * alloc(size_t len);
-
-public:
- size_t mUsed;
- size_t mAlloced;
-
- // *NOTE: Must be last member of the object. We'll
- // overallocate as requested via operator new and index
- // into the array at will.
- char mData[1];
-};
-
-
-// ==================================
-// BufferArray Definitions
-// ==================================
-
-
-#if ! LL_WINDOWS
-const size_t BufferArray::BLOCK_ALLOC_SIZE;
-#endif // ! LL_WINDOWS
-
-BufferArray::BufferArray()
- : LLCoreInt::RefCounted(true),
- mLen(0)
-{}
-
-
-BufferArray::~BufferArray()
-{
- for (container_t::iterator it(mBlocks.begin());
- it != mBlocks.end();
- ++it)
- {
- delete *it;
- *it = NULL;
- }
- mBlocks.clear();
-}
-
-
-size_t BufferArray::append(const void * src, size_t len)
-{
- const size_t ret(len);
- const char * c_src(static_cast<const char *>(src));
-
- // First, try to copy into the last block
- if (len && ! mBlocks.empty())
- {
- Block & last(*mBlocks.back());
- if (last.mUsed < last.mAlloced)
- {
- // Some will fit...
- const size_t copy_len((std::min)(len, (last.mAlloced - last.mUsed)));
-
- memcpy(&last.mData[last.mUsed], c_src, copy_len);
- last.mUsed += copy_len;
- llassert_always(last.mUsed <= last.mAlloced);
- mLen += copy_len;
- c_src += copy_len;
- len -= copy_len;
- }
- }
-
- // Then get new blocks as needed
- while (len)
- {
- const size_t copy_len((std::min)(len, BLOCK_ALLOC_SIZE));
-
- if (mBlocks.size() >= mBlocks.capacity())
- {
- mBlocks.reserve(mBlocks.size() + 5);
- }
- Block * block;
- try
- {
- block = Block::alloc(BLOCK_ALLOC_SIZE);
- }
- catch (std::bad_alloc&)
- {
- LLMemory::logMemoryInfo(true);
-
- //output possible call stacks to log file.
- LLError::LLCallStacks::print();
-
- LL_WARNS() << "Bad memory allocation in thrown by Block::alloc in read!" << LL_ENDL;
- break;
- }
- memcpy(block->mData, c_src, copy_len);
- block->mUsed = copy_len;
- llassert_always(block->mUsed <= block->mAlloced);
- mBlocks.push_back(block);
- mLen += copy_len;
- c_src += copy_len;
- len -= copy_len;
- }
- return ret - len;
-}
-
-
-void * BufferArray::appendBufferAlloc(size_t len)
-{
- // If someone asks for zero-length, we give them a valid pointer.
- if (mBlocks.size() >= mBlocks.capacity())
- {
- mBlocks.reserve(mBlocks.size() + 5);
- }
- Block * block = Block::alloc((std::max)(BLOCK_ALLOC_SIZE, len));
- block->mUsed = len;
- mBlocks.push_back(block);
- mLen += len;
- return block->mData;
-}
-
-
-size_t BufferArray::read(size_t pos, void * dst, size_t len)
-{
- char * c_dst(static_cast<char *>(dst));
-
- if (pos >= mLen)
- return 0;
- size_t len_limit(mLen - pos);
- len = (std::min)(len, len_limit);
- if (0 == len)
- return 0;
-
- size_t result(0), offset(0);
- const auto block_limit(mBlocks.size());
- int block_start(findBlock(pos, &offset));
- if (block_start < 0)
- return 0;
-
- do
- {
- Block & block(*mBlocks[block_start]);
- size_t block_limit(block.mUsed - offset);
- size_t block_len((std::min)(block_limit, len));
-
- memcpy(c_dst, &block.mData[offset], block_len);
- result += block_len;
- len -= block_len;
- c_dst += block_len;
- offset = 0;
- ++block_start;
- }
- while (len && block_start < block_limit);
-
- return result;
-}
-
-
-size_t BufferArray::write(size_t pos, const void * src, size_t len)
-{
- const char * c_src(static_cast<const char *>(src));
-
- if (pos > mLen || 0 == len)
- return 0;
-
- size_t result(0), offset(0);
- const auto block_limit(mBlocks.size());
- int block_start(findBlock(pos, &offset));
-
- if (block_start >= 0)
- {
- // Some or all of the write will be on top of
- // existing data.
- do
- {
- Block & block(*mBlocks[block_start]);
- size_t block_limit(block.mUsed - offset);
- size_t block_len((std::min)(block_limit, len));
-
- memcpy(&block.mData[offset], c_src, block_len);
- result += block_len;
- c_src += block_len;
- len -= block_len;
- offset = 0;
- ++block_start;
- }
- while (len && block_start < block_limit);
- }
-
- // Something left, see if it will fit in the free
- // space of the last block.
- if (len && ! mBlocks.empty())
- {
- Block & last(*mBlocks.back());
- if (last.mUsed < last.mAlloced)
- {
- // Some will fit...
- const size_t copy_len((std::min)(len, (last.mAlloced - last.mUsed)));
-
- memcpy(&last.mData[last.mUsed], c_src, copy_len);
- last.mUsed += copy_len;
- result += copy_len;
- llassert_always(last.mUsed <= last.mAlloced);
- mLen += copy_len;
- c_src += copy_len;
- len -= copy_len;
- }
- }
-
- if (len)
- {
- // Some or all of the remaining write data will
- // be an append.
- result += append(c_src, len);
- }
-
- return result;
-}
-
-
-int BufferArray::findBlock(size_t pos, size_t * ret_offset)
-{
- *ret_offset = 0;
- if (pos >= mLen)
- return -1; // Doesn't exist
-
- const int block_limit(narrow<size_t>(mBlocks.size()));
- for (int i(0); i < block_limit; ++i)
- {
- if (pos < mBlocks[i]->mUsed)
- {
- *ret_offset = pos;
- return i;
- }
- pos -= mBlocks[i]->mUsed;
- }
-
- // Shouldn't get here but...
- return -1;
-}
-
-
-bool BufferArray::getBlockStartEnd(int block, const char ** start, const char ** end)
-{
- if (block < 0 || block >= mBlocks.size())
- {
- return false;
- }
-
- const Block & b(*mBlocks[block]);
- *start = &b.mData[0];
- *end = &b.mData[b.mUsed];
- return true;
-}
-
-
-// ==================================
-// BufferArray::Block Definitions
-// ==================================
-
-
-BufferArray::Block::Block(size_t len)
- : mUsed(0),
- mAlloced(len)
-{
- memset(mData, 0, len);
-}
-
-
-BufferArray::Block::~Block()
-{
- mUsed = 0;
- mAlloced = 0;
-}
-
-
-void * BufferArray::Block::operator new(size_t len, size_t addl_len)
-{
- void * mem = new char[len + addl_len + sizeof(void *)];
- return mem;
-}
-
-
-void BufferArray::Block::operator delete(void * mem)
-{
- char * cmem = static_cast<char *>(mem);
- delete [] cmem;
-}
-
-
-void BufferArray::Block::operator delete(void * mem, size_t)
-{
- operator delete(mem);
-}
-
-
-BufferArray::Block * BufferArray::Block::alloc(size_t len)
-{
- Block * block = new (len) Block(len);
- return block;
-}
-
-
-} // end namespace LLCore
+/**
+ * @file bufferarray.cpp
+ * @brief Implements the BufferArray scatter/gather buffer
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "bufferarray.h"
+#include "llexception.h"
+#include "llmemory.h"
+
+
+// BufferArray is a list of chunks, each a BufferArray::Block, of contiguous
+// data presented as a single array. Chunks are at least BufferArray::BLOCK_ALLOC_SIZE
+// in length and can be larger. Any chunk may be partially filled or even
+// empty.
+//
+// The BufferArray itself is sharable as a RefCounted entity. As shared
+// reads don't work with the concept of a current position/seek value,
+// none is kept with the object. Instead, the read and write operations
+// all take position arguments. Single write/shared read isn't supported
+// directly and any such attempts have to be serialized outside of this
+// implementation.
+
+namespace LLCore
+{
+
+
+// ==================================
+// BufferArray::Block Declaration
+// ==================================
+
+class BufferArray::Block
+{
+public:
+ ~Block();
+
+ void operator delete(void *);
+ void operator delete(void *, size_t len);
+
+protected:
+ Block(size_t len);
+
+ Block(const Block &); // Not defined
+ void operator=(const Block &); // Not defined
+
+ // Allocate the block with the additional space for the
+ // buffered data at the end of the object.
+ void * operator new(size_t len, size_t addl_len);
+
+public:
+ // Only public entry to get a block.
+ static Block * alloc(size_t len);
+
+public:
+ size_t mUsed;
+ size_t mAlloced;
+
+ // *NOTE: Must be last member of the object. We'll
+ // overallocate as requested via operator new and index
+ // into the array at will.
+ char mData[1];
+};
+
+
+// ==================================
+// BufferArray Definitions
+// ==================================
+
+
+#if ! LL_WINDOWS
+const size_t BufferArray::BLOCK_ALLOC_SIZE;
+#endif // ! LL_WINDOWS
+
+BufferArray::BufferArray()
+ : LLCoreInt::RefCounted(true),
+ mLen(0)
+{}
+
+
+BufferArray::~BufferArray()
+{
+ for (container_t::iterator it(mBlocks.begin());
+ it != mBlocks.end();
+ ++it)
+ {
+ delete *it;
+ *it = NULL;
+ }
+ mBlocks.clear();
+}
+
+
+size_t BufferArray::append(const void * src, size_t len)
+{
+ const size_t ret(len);
+ const char * c_src(static_cast<const char *>(src));
+
+ // First, try to copy into the last block
+ if (len && ! mBlocks.empty())
+ {
+ Block & last(*mBlocks.back());
+ if (last.mUsed < last.mAlloced)
+ {
+ // Some will fit...
+ const size_t copy_len((std::min)(len, (last.mAlloced - last.mUsed)));
+
+ memcpy(&last.mData[last.mUsed], c_src, copy_len);
+ last.mUsed += copy_len;
+ llassert_always(last.mUsed <= last.mAlloced);
+ mLen += copy_len;
+ c_src += copy_len;
+ len -= copy_len;
+ }
+ }
+
+ // Then get new blocks as needed
+ while (len)
+ {
+ const size_t copy_len((std::min)(len, BLOCK_ALLOC_SIZE));
+
+ if (mBlocks.size() >= mBlocks.capacity())
+ {
+ mBlocks.reserve(mBlocks.size() + 5);
+ }
+ Block * block;
+ try
+ {
+ block = Block::alloc(BLOCK_ALLOC_SIZE);
+ }
+ catch (std::bad_alloc&)
+ {
+ LLMemory::logMemoryInfo(true);
+
+ //output possible call stacks to log file.
+ LLError::LLCallStacks::print();
+
+ LL_WARNS() << "Bad memory allocation in thrown by Block::alloc in read!" << LL_ENDL;
+ break;
+ }
+ memcpy(block->mData, c_src, copy_len);
+ block->mUsed = copy_len;
+ llassert_always(block->mUsed <= block->mAlloced);
+ mBlocks.push_back(block);
+ mLen += copy_len;
+ c_src += copy_len;
+ len -= copy_len;
+ }
+ return ret - len;
+}
+
+
+void * BufferArray::appendBufferAlloc(size_t len)
+{
+ // If someone asks for zero-length, we give them a valid pointer.
+ if (mBlocks.size() >= mBlocks.capacity())
+ {
+ mBlocks.reserve(mBlocks.size() + 5);
+ }
+ Block * block = Block::alloc((std::max)(BLOCK_ALLOC_SIZE, len));
+ block->mUsed = len;
+ mBlocks.push_back(block);
+ mLen += len;
+ return block->mData;
+}
+
+
+size_t BufferArray::read(size_t pos, void * dst, size_t len)
+{
+ char * c_dst(static_cast<char *>(dst));
+
+ if (pos >= mLen)
+ return 0;
+ size_t len_limit(mLen - pos);
+ len = (std::min)(len, len_limit);
+ if (0 == len)
+ return 0;
+
+ size_t result(0), offset(0);
+ const auto block_limit(mBlocks.size());
+ int block_start(findBlock(pos, &offset));
+ if (block_start < 0)
+ return 0;
+
+ do
+ {
+ Block & block(*mBlocks[block_start]);
+ size_t block_limit(block.mUsed - offset);
+ size_t block_len((std::min)(block_limit, len));
+
+ memcpy(c_dst, &block.mData[offset], block_len);
+ result += block_len;
+ len -= block_len;
+ c_dst += block_len;
+ offset = 0;
+ ++block_start;
+ }
+ while (len && block_start < block_limit);
+
+ return result;
+}
+
+
+size_t BufferArray::write(size_t pos, const void * src, size_t len)
+{
+ const char * c_src(static_cast<const char *>(src));
+
+ if (pos > mLen || 0 == len)
+ return 0;
+
+ size_t result(0), offset(0);
+ const auto block_limit(mBlocks.size());
+ int block_start(findBlock(pos, &offset));
+
+ if (block_start >= 0)
+ {
+ // Some or all of the write will be on top of
+ // existing data.
+ do
+ {
+ Block & block(*mBlocks[block_start]);
+ size_t block_limit(block.mUsed - offset);
+ size_t block_len((std::min)(block_limit, len));
+
+ memcpy(&block.mData[offset], c_src, block_len);
+ result += block_len;
+ c_src += block_len;
+ len -= block_len;
+ offset = 0;
+ ++block_start;
+ }
+ while (len && block_start < block_limit);
+ }
+
+ // Something left, see if it will fit in the free
+ // space of the last block.
+ if (len && ! mBlocks.empty())
+ {
+ Block & last(*mBlocks.back());
+ if (last.mUsed < last.mAlloced)
+ {
+ // Some will fit...
+ const size_t copy_len((std::min)(len, (last.mAlloced - last.mUsed)));
+
+ memcpy(&last.mData[last.mUsed], c_src, copy_len);
+ last.mUsed += copy_len;
+ result += copy_len;
+ llassert_always(last.mUsed <= last.mAlloced);
+ mLen += copy_len;
+ c_src += copy_len;
+ len -= copy_len;
+ }
+ }
+
+ if (len)
+ {
+ // Some or all of the remaining write data will
+ // be an append.
+ result += append(c_src, len);
+ }
+
+ return result;
+}
+
+
+int BufferArray::findBlock(size_t pos, size_t * ret_offset)
+{
+ *ret_offset = 0;
+ if (pos >= mLen)
+ return -1; // Doesn't exist
+
+ const int block_limit(narrow<size_t>(mBlocks.size()));
+ for (int i(0); i < block_limit; ++i)
+ {
+ if (pos < mBlocks[i]->mUsed)
+ {
+ *ret_offset = pos;
+ return i;
+ }
+ pos -= mBlocks[i]->mUsed;
+ }
+
+ // Shouldn't get here but...
+ return -1;
+}
+
+
+bool BufferArray::getBlockStartEnd(int block, const char ** start, const char ** end)
+{
+ if (block < 0 || block >= mBlocks.size())
+ {
+ return false;
+ }
+
+ const Block & b(*mBlocks[block]);
+ *start = &b.mData[0];
+ *end = &b.mData[b.mUsed];
+ return true;
+}
+
+
+// ==================================
+// BufferArray::Block Definitions
+// ==================================
+
+
+BufferArray::Block::Block(size_t len)
+ : mUsed(0),
+ mAlloced(len)
+{
+ memset(mData, 0, len);
+}
+
+
+BufferArray::Block::~Block()
+{
+ mUsed = 0;
+ mAlloced = 0;
+}
+
+
+void * BufferArray::Block::operator new(size_t len, size_t addl_len)
+{
+ void * mem = new char[len + addl_len + sizeof(void *)];
+ return mem;
+}
+
+
+void BufferArray::Block::operator delete(void * mem)
+{
+ char * cmem = static_cast<char *>(mem);
+ delete [] cmem;
+}
+
+
+void BufferArray::Block::operator delete(void * mem, size_t)
+{
+ operator delete(mem);
+}
+
+
+BufferArray::Block * BufferArray::Block::alloc(size_t len)
+{
+ Block * block = new (len) Block(len);
+ return block;
+}
+
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/bufferarray.h b/indra/llcorehttp/bufferarray.h
index 320adf2b8b..0269d1785e 100644
--- a/indra/llcorehttp/bufferarray.h
+++ b/indra/llcorehttp/bufferarray.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_BUFFER_ARRAY_H_
-#define _LLCORE_BUFFER_ARRAY_H_
+#ifndef _LLCORE_BUFFER_ARRAY_H_
+#define _LLCORE_BUFFER_ARRAY_H_
#include <cstdlib>
@@ -67,75 +67,75 @@ class BufferArrayStreamBuf;
class BufferArray : public LLCoreInt::RefCounted
{
public:
- // BufferArrayStreamBuf has intimate knowledge of this
- // implementation to implement a buffer-free adapter.
- // Changes here will likely need to be reflected there.
- friend class BufferArrayStreamBuf;
-
- BufferArray();
+ // BufferArrayStreamBuf has intimate knowledge of this
+ // implementation to implement a buffer-free adapter.
+ // Changes here will likely need to be reflected there.
+ friend class BufferArrayStreamBuf;
- typedef LLCoreInt::IntrusivePtr<BufferArray> ptr_t;
+ BufferArray();
+
+ typedef LLCoreInt::IntrusivePtr<BufferArray> ptr_t;
protected:
- virtual ~BufferArray(); // Use release()
+ virtual ~BufferArray(); // Use release()
private:
- BufferArray(const BufferArray &); // Not defined
- void operator=(const BufferArray &); // Not defined
+ BufferArray(const BufferArray &); // Not defined
+ void operator=(const BufferArray &); // Not defined
public:
- // Internal magic number, may be used by unit tests.
- static const size_t BLOCK_ALLOC_SIZE = 65540;
-
- /// Appends the indicated data to the BufferArray
- /// modifying current position and total size. New
- /// position is one beyond the final byte of the buffer.
- ///
- /// @return Count of bytes copied to BufferArray
- size_t append(const void * src, size_t len);
-
- /// Similar to @see append(), this call guarantees a
- /// contiguous block of memory of requested size placed
- /// at the current end of the BufferArray. On return,
- /// the data in the memory is considered valid whether
- /// the caller writes to it or not.
- ///
- /// @return Pointer to contiguous region at end
- /// of BufferArray of 'len' size.
- void * appendBufferAlloc(size_t len);
-
- /// Current count of bytes in BufferArray instance.
- size_t size() const
- {
- return mLen;
- }
-
- /// Copies data from the given position in the instance
- /// to the caller's buffer. Will return a short count of
- /// bytes copied if the 'len' extends beyond the data.
- size_t read(size_t pos, void * dst, size_t len);
-
- /// Copies data from the caller's buffer to the instance
- /// at the current position. May overwrite existing data,
- /// append data when current position is equal to the
- /// size of the instance or do a mix of both.
- size_t write(size_t pos, const void * src, size_t len);
-
+ // Internal magic number, may be used by unit tests.
+ static const size_t BLOCK_ALLOC_SIZE = 65540;
+
+ /// Appends the indicated data to the BufferArray
+ /// modifying current position and total size. New
+ /// position is one beyond the final byte of the buffer.
+ ///
+ /// @return Count of bytes copied to BufferArray
+ size_t append(const void * src, size_t len);
+
+ /// Similar to @see append(), this call guarantees a
+ /// contiguous block of memory of requested size placed
+ /// at the current end of the BufferArray. On return,
+ /// the data in the memory is considered valid whether
+ /// the caller writes to it or not.
+ ///
+ /// @return Pointer to contiguous region at end
+ /// of BufferArray of 'len' size.
+ void * appendBufferAlloc(size_t len);
+
+ /// Current count of bytes in BufferArray instance.
+ size_t size() const
+ {
+ return mLen;
+ }
+
+ /// Copies data from the given position in the instance
+ /// to the caller's buffer. Will return a short count of
+ /// bytes copied if the 'len' extends beyond the data.
+ size_t read(size_t pos, void * dst, size_t len);
+
+ /// Copies data from the caller's buffer to the instance
+ /// at the current position. May overwrite existing data,
+ /// append data when current position is equal to the
+ /// size of the instance or do a mix of both.
+ size_t write(size_t pos, const void * src, size_t len);
+
protected:
- int findBlock(size_t pos, size_t * ret_offset);
+ int findBlock(size_t pos, size_t * ret_offset);
+
+ bool getBlockStartEnd(int block, const char ** start, const char ** end);
- bool getBlockStartEnd(int block, const char ** start, const char ** end);
-
protected:
- class Block;
- typedef std::vector<Block *> container_t;
+ class Block;
+ typedef std::vector<Block *> container_t;
- container_t mBlocks;
- size_t mLen;
+ container_t mBlocks;
+ size_t mLen;
}; // end class BufferArray
} // end namespace LLCore
-#endif // _LLCORE_BUFFER_ARRAY_H_
+#endif // _LLCORE_BUFFER_ARRAY_H_
diff --git a/indra/llcorehttp/bufferstream.cpp b/indra/llcorehttp/bufferstream.cpp
index 678bf5ea9f..ea92f2f71d 100644
--- a/indra/llcorehttp/bufferstream.cpp
+++ b/indra/llcorehttp/bufferstream.cpp
@@ -33,250 +33,250 @@ namespace LLCore
{
BufferArrayStreamBuf::BufferArrayStreamBuf(BufferArray * array)
- : mBufferArray(array),
- mReadCurPos(0),
- mReadCurBlock(-1),
- mReadBegin(NULL),
- mReadCur(NULL),
- mReadEnd(NULL),
- mWriteCurPos(0)
+ : mBufferArray(array),
+ mReadCurPos(0),
+ mReadCurBlock(-1),
+ mReadBegin(NULL),
+ mReadCur(NULL),
+ mReadEnd(NULL),
+ mWriteCurPos(0)
{
- if (array)
- {
- array->addRef();
- mWriteCurPos = array->mLen;
- }
+ if (array)
+ {
+ array->addRef();
+ mWriteCurPos = array->mLen;
+ }
}
BufferArrayStreamBuf::~BufferArrayStreamBuf()
{
- if (mBufferArray)
- {
- mBufferArray->release();
- mBufferArray = NULL;
- }
+ if (mBufferArray)
+ {
+ mBufferArray->release();
+ mBufferArray = NULL;
+ }
}
-
+
BufferArrayStreamBuf::int_type BufferArrayStreamBuf::underflow()
{
- if (! mBufferArray)
- {
- return traits_type::eof();
- }
-
- if (mReadCur == mReadEnd)
- {
- // Find the next block with actual data or leave
- // mCurBlock/mCur/mEnd unchanged if we're at the end
- // of any block chain.
- const char * new_begin(NULL), * new_end(NULL);
- int new_cur_block(mReadCurBlock + 1);
-
- while (mBufferArray->getBlockStartEnd(new_cur_block, &new_begin, &new_end))
- {
- if (new_begin != new_end)
- {
- break;
- }
- ++new_cur_block;
- }
- if (new_begin == new_end)
- {
- return traits_type::eof();
- }
-
- mReadCurBlock = new_cur_block;
- mReadBegin = mReadCur = new_begin;
- mReadEnd = new_end;
- }
-
- return traits_type::to_int_type(*mReadCur);
+ if (! mBufferArray)
+ {
+ return traits_type::eof();
+ }
+
+ if (mReadCur == mReadEnd)
+ {
+ // Find the next block with actual data or leave
+ // mCurBlock/mCur/mEnd unchanged if we're at the end
+ // of any block chain.
+ const char * new_begin(NULL), * new_end(NULL);
+ int new_cur_block(mReadCurBlock + 1);
+
+ while (mBufferArray->getBlockStartEnd(new_cur_block, &new_begin, &new_end))
+ {
+ if (new_begin != new_end)
+ {
+ break;
+ }
+ ++new_cur_block;
+ }
+ if (new_begin == new_end)
+ {
+ return traits_type::eof();
+ }
+
+ mReadCurBlock = new_cur_block;
+ mReadBegin = mReadCur = new_begin;
+ mReadEnd = new_end;
+ }
+
+ return traits_type::to_int_type(*mReadCur);
}
BufferArrayStreamBuf::int_type BufferArrayStreamBuf::uflow()
{
- const int_type ret(underflow());
-
- if (traits_type::eof() != ret)
- {
- ++mReadCur;
- ++mReadCurPos;
- }
- return ret;
+ const int_type ret(underflow());
+
+ if (traits_type::eof() != ret)
+ {
+ ++mReadCur;
+ ++mReadCurPos;
+ }
+ return ret;
}
BufferArrayStreamBuf::int_type BufferArrayStreamBuf::pbackfail(int_type ch)
{
- if (! mBufferArray)
- {
- return traits_type::eof();
- }
-
- if (mReadCur == mReadBegin)
- {
- // Find the previous block with actual data or leave
- // mCurBlock/mBegin/mCur/mEnd unchanged if we're at the
- // beginning of any block chain.
- const char * new_begin(NULL), * new_end(NULL);
- int new_cur_block(mReadCurBlock - 1);
-
- while (mBufferArray->getBlockStartEnd(new_cur_block, &new_begin, &new_end))
- {
- if (new_begin != new_end)
- {
- break;
- }
- --new_cur_block;
- }
- if (new_begin == new_end)
- {
- return traits_type::eof();
- }
-
- mReadCurBlock = new_cur_block;
- mReadBegin = new_begin;
- mReadEnd = mReadCur = new_end;
- }
-
- if (traits_type::eof() != ch && mReadCur[-1] != ch)
- {
- return traits_type::eof();
- }
- --mReadCurPos;
- return traits_type::to_int_type(*--mReadCur);
+ if (! mBufferArray)
+ {
+ return traits_type::eof();
+ }
+
+ if (mReadCur == mReadBegin)
+ {
+ // Find the previous block with actual data or leave
+ // mCurBlock/mBegin/mCur/mEnd unchanged if we're at the
+ // beginning of any block chain.
+ const char * new_begin(NULL), * new_end(NULL);
+ int new_cur_block(mReadCurBlock - 1);
+
+ while (mBufferArray->getBlockStartEnd(new_cur_block, &new_begin, &new_end))
+ {
+ if (new_begin != new_end)
+ {
+ break;
+ }
+ --new_cur_block;
+ }
+ if (new_begin == new_end)
+ {
+ return traits_type::eof();
+ }
+
+ mReadCurBlock = new_cur_block;
+ mReadBegin = new_begin;
+ mReadEnd = mReadCur = new_end;
+ }
+
+ if (traits_type::eof() != ch && mReadCur[-1] != ch)
+ {
+ return traits_type::eof();
+ }
+ --mReadCurPos;
+ return traits_type::to_int_type(*--mReadCur);
}
std::streamsize BufferArrayStreamBuf::showmanyc()
{
- if (! mBufferArray)
- {
- return -1;
- }
- return mBufferArray->mLen - mReadCurPos;
+ if (! mBufferArray)
+ {
+ return -1;
+ }
+ return mBufferArray->mLen - mReadCurPos;
}
BufferArrayStreamBuf::int_type BufferArrayStreamBuf::overflow(int c)
{
- if (! mBufferArray || mWriteCurPos > mBufferArray->mLen)
- {
- return traits_type::eof();
- }
- const size_t wrote(mBufferArray->write(mWriteCurPos, &c, 1));
- mWriteCurPos += wrote;
- return wrote ? c : traits_type::eof();
+ if (! mBufferArray || mWriteCurPos > mBufferArray->mLen)
+ {
+ return traits_type::eof();
+ }
+ const size_t wrote(mBufferArray->write(mWriteCurPos, &c, 1));
+ mWriteCurPos += wrote;
+ return wrote ? c : traits_type::eof();
}
std::streamsize BufferArrayStreamBuf::xsputn(const char * src, std::streamsize count)
{
- if (! mBufferArray || mWriteCurPos > mBufferArray->mLen)
- {
- return 0;
- }
- const size_t wrote(mBufferArray->write(mWriteCurPos, src, count));
- mWriteCurPos += wrote;
- return wrote;
+ if (! mBufferArray || mWriteCurPos > mBufferArray->mLen)
+ {
+ return 0;
+ }
+ const size_t wrote(mBufferArray->write(mWriteCurPos, src, count));
+ mWriteCurPos += wrote;
+ return wrote;
}
std::streampos BufferArrayStreamBuf::seekoff(std::streamoff off,
- std::ios_base::seekdir way,
- std::ios_base::openmode which)
+ std::ios_base::seekdir way,
+ std::ios_base::openmode which)
{
- std::streampos ret(-1);
-
- if (! mBufferArray)
- {
- return ret;
- }
-
- if (std::ios_base::in == which)
- {
- size_t pos(0);
-
- switch (way)
- {
- case std::ios_base::beg:
- pos = off;
- break;
-
- case std::ios_base::cur:
- pos = mReadCurPos += off;
- break;
-
- case std::ios_base::end:
- pos = mBufferArray->mLen - off;
- break;
-
- default:
- return ret;
- }
-
- if (pos >= mBufferArray->size())
- {
- pos = (std::max)(size_t(0), mBufferArray->size() - 1);
- }
- size_t ba_offset(0);
- int block(mBufferArray->findBlock(pos, &ba_offset));
- if (block < 0)
- return ret;
- const char * start(NULL), * end(NULL);
- if (! mBufferArray->getBlockStartEnd(block, &start, &end))
- return ret;
- mReadCurBlock = block;
- mReadBegin = start;
- mReadCur = start + ba_offset;
- mReadEnd = end;
- ret = mReadCurPos = pos;
- }
- else if (std::ios_base::out == which)
- {
- size_t pos(0);
-
- switch (way)
- {
- case std::ios_base::beg:
- pos = off;
- break;
-
- case std::ios_base::cur:
- pos = mWriteCurPos += off;
- break;
-
- case std::ios_base::end:
- pos = mBufferArray->mLen - off;
- break;
-
- default:
- return ret;
- }
-
- if (pos > mBufferArray->size())
- {
- pos = mBufferArray->size();
- }
- ret = mWriteCurPos = pos;
- }
-
- return ret;
+ std::streampos ret(-1);
+
+ if (! mBufferArray)
+ {
+ return ret;
+ }
+
+ if (std::ios_base::in == which)
+ {
+ size_t pos(0);
+
+ switch (way)
+ {
+ case std::ios_base::beg:
+ pos = off;
+ break;
+
+ case std::ios_base::cur:
+ pos = mReadCurPos += off;
+ break;
+
+ case std::ios_base::end:
+ pos = mBufferArray->mLen - off;
+ break;
+
+ default:
+ return ret;
+ }
+
+ if (pos >= mBufferArray->size())
+ {
+ pos = (std::max)(size_t(0), mBufferArray->size() - 1);
+ }
+ size_t ba_offset(0);
+ int block(mBufferArray->findBlock(pos, &ba_offset));
+ if (block < 0)
+ return ret;
+ const char * start(NULL), * end(NULL);
+ if (! mBufferArray->getBlockStartEnd(block, &start, &end))
+ return ret;
+ mReadCurBlock = block;
+ mReadBegin = start;
+ mReadCur = start + ba_offset;
+ mReadEnd = end;
+ ret = mReadCurPos = pos;
+ }
+ else if (std::ios_base::out == which)
+ {
+ size_t pos(0);
+
+ switch (way)
+ {
+ case std::ios_base::beg:
+ pos = off;
+ break;
+
+ case std::ios_base::cur:
+ pos = mWriteCurPos += off;
+ break;
+
+ case std::ios_base::end:
+ pos = mBufferArray->mLen - off;
+ break;
+
+ default:
+ return ret;
+ }
+
+ if (pos > mBufferArray->size())
+ {
+ pos = mBufferArray->size();
+ }
+ ret = mWriteCurPos = pos;
+ }
+
+ return ret;
}
BufferArrayStream::BufferArrayStream(BufferArray * ba)
- : std::iostream(&mStreamBuf),
- mStreamBuf(ba)
+ : std::iostream(&mStreamBuf),
+ mStreamBuf(ba)
{}
-
-
+
+
BufferArrayStream::~BufferArrayStream()
{}
-
+
} // end namespace LLCore
diff --git a/indra/llcorehttp/bufferstream.h b/indra/llcorehttp/bufferstream.h
index 9327a798aa..93891810aa 100644
--- a/indra/llcorehttp/bufferstream.h
+++ b/indra/llcorehttp/bufferstream.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_BUFFER_STREAM_H_
-#define _LLCORE_BUFFER_STREAM_H_
+#ifndef _LLCORE_BUFFER_STREAM_H_
+#define _LLCORE_BUFFER_STREAM_H_
#include <sstream>
@@ -85,38 +85,38 @@ namespace LLCore
class BufferArrayStreamBuf : public std::streambuf
{
public:
- /// Constructor increments the reference count on the
- /// BufferArray argument and calls release() on destruction.
- BufferArrayStreamBuf(BufferArray * array);
- virtual ~BufferArrayStreamBuf();
+ /// Constructor increments the reference count on the
+ /// BufferArray argument and calls release() on destruction.
+ BufferArrayStreamBuf(BufferArray * array);
+ virtual ~BufferArrayStreamBuf();
private:
- BufferArrayStreamBuf(const BufferArrayStreamBuf &); // Not defined
- void operator=(const BufferArrayStreamBuf &); // Not defined
+ BufferArrayStreamBuf(const BufferArrayStreamBuf &); // Not defined
+ void operator=(const BufferArrayStreamBuf &); // Not defined
public:
- // Input interfaces from std::streambuf
- int_type underflow();
- int_type uflow();
- int_type pbackfail(int_type ch);
- std::streamsize showmanyc();
-
- // Output interfaces from std::streambuf
- int_type overflow(int c);
- std::streamsize xsputn(const char * src, std::streamsize count);
-
- // Common/misc interfaces from std::streambuf
- std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which);
-
+ // Input interfaces from std::streambuf
+ int_type underflow();
+ int_type uflow();
+ int_type pbackfail(int_type ch);
+ std::streamsize showmanyc();
+
+ // Output interfaces from std::streambuf
+ int_type overflow(int c);
+ std::streamsize xsputn(const char * src, std::streamsize count);
+
+ // Common/misc interfaces from std::streambuf
+ std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which);
+
protected:
- BufferArray * mBufferArray; // Ref counted
- size_t mReadCurPos;
- int mReadCurBlock;
- const char * mReadBegin;
- const char * mReadCur;
- const char * mReadEnd;
- size_t mWriteCurPos;
-
+ BufferArray * mBufferArray; // Ref counted
+ size_t mReadCurPos;
+ int mReadCurBlock;
+ const char * mReadBegin;
+ const char * mReadCur;
+ const char * mReadEnd;
+ size_t mWriteCurPos;
+
}; // end class BufferArrayStreamBuf
@@ -134,20 +134,20 @@ protected:
class BufferArrayStream : public std::iostream
{
public:
- /// Constructor increments the reference count on the
- /// BufferArray argument and calls release() on destruction.
- BufferArrayStream(BufferArray * ba);
- ~BufferArrayStream();
+ /// Constructor increments the reference count on the
+ /// BufferArray argument and calls release() on destruction.
+ BufferArrayStream(BufferArray * ba);
+ ~BufferArrayStream();
protected:
- BufferArrayStream(const BufferArrayStream &);
- void operator=(const BufferArrayStream &);
+ BufferArrayStream(const BufferArrayStream &);
+ void operator=(const BufferArrayStream &);
protected:
- BufferArrayStreamBuf mStreamBuf;
+ BufferArrayStreamBuf mStreamBuf;
}; // end class BufferArrayStream
} // end namespace LLCore
-#endif // _LLCORE_BUFFER_STREAM_H_
+#endif // _LLCORE_BUFFER_STREAM_H_
diff --git a/indra/llcorehttp/examples/http_texture_load.cpp b/indra/llcorehttp/examples/http_texture_load.cpp
index cc53b20add..4d1e52b766 100644
--- a/indra/llcorehttp/examples/http_texture_load.cpp
+++ b/indra/llcorehttp/examples/http_texture_load.cpp
@@ -5,21 +5,21 @@
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2012-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$
*/
@@ -65,8 +65,8 @@ static char url_format[1024] = "http://example.com/some/path?texture_id=%s.textu
#if defined(WIN32)
-#define strncpy(_a, _b, _c) strncpy_s(_a, _b, _c)
-#define strtok_r(_a, _b, _c) strtok_s(_a, _b, _c)
+#define strncpy(_a, _b, _c) strncpy_s(_a, _b, _c)
+#define strtok_r(_a, _b, _c) strtok_s(_a, _b, _c)
int getopt(int argc, char * const argv[], const char *optstring);
char *optarg(NULL);
@@ -80,48 +80,48 @@ int optind(1);
class WorkingSet : public LLCore::HttpHandler
{
public:
- WorkingSet();
- ~WorkingSet();
+ WorkingSet();
+ ~WorkingSet();
+
+ bool reload(LLCore::HttpRequest *, LLCore::HttpOptions::ptr_t &);
+
+ virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
- bool reload(LLCore::HttpRequest *, LLCore::HttpOptions::ptr_t &);
-
- virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
+ void loadAssetUuids(FILE * in);
- void loadAssetUuids(FILE * in);
-
public:
- struct Spec
- {
- std::string mUuid;
- int mOffset;
- int mLength;
- };
- typedef std::set<LLCore::HttpHandle> handle_set_t;
- typedef std::vector<Spec> asset_list_t;
-
+ struct Spec
+ {
+ std::string mUuid;
+ int mOffset;
+ int mLength;
+ };
+ typedef std::set<LLCore::HttpHandle> handle_set_t;
+ typedef std::vector<Spec> asset_list_t;
+
public:
- bool mVerbose;
- bool mRandomRange;
- bool mNoRange;
- int mRequestLowWater;
- int mRequestHighWater;
- handle_set_t mHandles;
- int mRemaining;
- int mLimit;
- int mAt;
- std::string mUrl;
- asset_list_t mAssets;
- int mErrorsApi;
- int mErrorsHttp;
- int mErrorsHttp404;
- int mErrorsHttp416;
- int mErrorsHttp500;
- int mErrorsHttp503;
- int mRetries;
- int mRetriesHttp503;
- int mSuccesses;
- long mByteCount;
- LLCore::HttpHeaders::ptr_t mHeaders;
+ bool mVerbose;
+ bool mRandomRange;
+ bool mNoRange;
+ int mRequestLowWater;
+ int mRequestHighWater;
+ handle_set_t mHandles;
+ int mRemaining;
+ int mLimit;
+ int mAt;
+ std::string mUrl;
+ asset_list_t mAssets;
+ int mErrorsApi;
+ int mErrorsHttp;
+ int mErrorsHttp404;
+ int mErrorsHttp416;
+ int mErrorsHttp500;
+ int mErrorsHttp503;
+ int mRetries;
+ int mRetriesHttp503;
+ int mSuccesses;
+ long mByteCount;
+ LLCore::HttpHeaders::ptr_t mHeaders;
};
@@ -131,28 +131,28 @@ public:
class Metrics
{
public:
- class MetricsImpl;
-
+ class MetricsImpl;
+
public:
- Metrics();
- ~Metrics();
+ Metrics();
+ ~Metrics();
- void init();
- void sample();
- void term();
+ void init();
+ void sample();
+ void term();
protected:
- MetricsImpl * mImpl;
+ MetricsImpl * mImpl;
public:
- U64 mMaxVSZ;
- U64 mMinVSZ;
- U64 mStartWallTime;
- U64 mEndWallTime;
- U64 mStartUTime;
- U64 mEndUTime;
- U64 mStartSTime;
- U64 mEndSTime;
+ U64 mMaxVSZ;
+ U64 mMinVSZ;
+ U64 mStartWallTime;
+ U64 mEndWallTime;
+ U64 mStartUTime;
+ U64 mEndUTime;
+ U64 mStartSTime;
+ U64 mEndSTime;
};
@@ -161,273 +161,273 @@ public:
//
int main(int argc, char** argv)
{
- LLCore::HttpStatus status;
- bool do_random(false);
- bool do_whole(false);
- bool do_verbose(false);
-
- int option(-1);
- while (-1 != (option = getopt(argc, argv, "u:c:h?RwvH:p:t:")))
- {
- switch (option)
- {
- case 'u':
- strncpy(url_format, optarg, sizeof(url_format));
- url_format[sizeof(url_format) - 1] = '\0';
- break;
-
- case 'c':
- {
- unsigned long value;
- char * end;
-
- value = strtoul(optarg, &end, 10);
- if (value < 1 || value > 100 || *end != '\0')
- {
- usage(std::cerr);
- return 1;
- }
- concurrency_limit = value;
- }
- break;
-
- case 'H':
- {
- unsigned long value;
- char * end;
-
- value = strtoul(optarg, &end, 10);
- if (value < 1 || value > 200 || *end != '\0')
- {
- usage(std::cerr);
- return 1;
- }
- highwater = value;
- }
- break;
-
- case 'p':
- {
- unsigned long value;
- char * end;
-
- value = strtoul(optarg, &end, 10);
- if (value > 100 || *end != '\0')
- {
- usage(std::cerr);
- return 1;
- }
- pipeline_depth = value;
- }
- break;
-
- case '5':
- {
- unsigned long value;
- char * end;
-
- value = strtoul(optarg, &end, 10);
- if (value > 3 || *end != '\0')
- {
- usage(std::cerr);
- return 1;
- }
- tracing = value;
- }
- break;
-
- case 'R':
- do_random = true;
- do_whole = false;
- break;
-
- case 'w':
- do_whole = true;
- do_random = false;
- break;
-
- case 'v':
- do_verbose = true;
- break;
-
- case 'h':
- case '?':
- usage(std::cout);
- return 0;
- }
- }
-
- if ((optind + 1) != argc)
- {
- usage(std::cerr);
- return 1;
- }
-
- FILE * uuids(fopen(argv[optind], "r"));
- if (! uuids)
- {
- const char * errstr(strerror(errno));
-
- std::cerr << "Couldn't open UUID file '" << argv[optind] << "'. Reason: "
- << errstr << std::endl;
- return 1;
- }
-
- // Initialization
- init_curl();
- LLCore::HttpRequest::createService();
- LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_CONNECTION_LIMIT,
- LLCore::HttpRequest::DEFAULT_POLICY_ID,
- concurrency_limit,
- NULL);
- LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_PER_HOST_CONNECTION_LIMIT,
- LLCore::HttpRequest::DEFAULT_POLICY_ID,
- concurrency_limit,
- NULL);
- if (pipeline_depth)
- {
- LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_PIPELINING_DEPTH,
- LLCore::HttpRequest::DEFAULT_POLICY_ID,
- pipeline_depth,
- NULL);
- }
- if (tracing)
- {
- LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_TRACE,
- LLCore::HttpRequest::DEFAULT_POLICY_ID,
- tracing,
- NULL);
- }
- LLCore::HttpRequest::startThread();
-
- // Get service point
- LLCore::HttpRequest * hr = new LLCore::HttpRequest();
-
- // Get request options
- LLCore::HttpOptions::ptr_t opt = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions());
- opt->setRetries(12);
- opt->setUseRetryAfter(true);
-
- // Get a handler/working set
- WorkingSet ws;
-
- // Fill the working set with work
- ws.mUrl = url_format;
- ws.loadAssetUuids(uuids);
- ws.mRandomRange = do_random;
- ws.mNoRange = do_whole;
- ws.mVerbose = do_verbose;
- ws.mRequestHighWater = highwater;
- ws.mRequestLowWater = ws.mRequestHighWater / 2;
-
- if (! ws.mAssets.size())
- {
- std::cerr << "No UUIDs found in file '" << argv[optind] << "'." << std::endl;
- return 1;
- }
-
- // Setup metrics
- Metrics metrics;
- metrics.init();
-
- // Run it
- int passes(0);
- while (! ws.reload(hr, opt))
- {
- hr->update(0);
- ms_sleep(2);
- if (0 == (++passes % 200))
- {
- metrics.sample();
- }
- }
- metrics.sample();
- metrics.term();
-
- // Report
- std::cout << "HTTP errors: " << ws.mErrorsHttp << " API errors: " << ws.mErrorsApi
- << " Successes: " << ws.mSuccesses << " Byte count: " << ws.mByteCount
- << std::endl;
- std::cout << "HTTP 404 errors: " << ws.mErrorsHttp404 << " HTTP 416 errors: " << ws.mErrorsHttp416
- << " HTTP 500 errors: " << ws.mErrorsHttp500 << " HTTP 503 errors: " << ws.mErrorsHttp503
- << std::endl;
- std::cout << "Retries: " << ws.mRetries << " Retries on 503: " << ws.mRetriesHttp503
- << std::endl;
- std::cout << "User CPU: " << (metrics.mEndUTime - metrics.mStartUTime)
- << " uS System CPU: " << (metrics.mEndSTime - metrics.mStartSTime)
- << " uS Wall Time: " << (metrics.mEndWallTime - metrics.mStartWallTime)
- << " uS Maximum VSZ: " << metrics.mMaxVSZ
- << " Bytes Minimum VSZ: " << metrics.mMinVSZ << " Bytes"
- << std::endl;
-
- // Clean up
- hr->requestStopThread(LLCore::HttpHandler::ptr_t());
- ms_sleep(1000);
+ LLCore::HttpStatus status;
+ bool do_random(false);
+ bool do_whole(false);
+ bool do_verbose(false);
+
+ int option(-1);
+ while (-1 != (option = getopt(argc, argv, "u:c:h?RwvH:p:t:")))
+ {
+ switch (option)
+ {
+ case 'u':
+ strncpy(url_format, optarg, sizeof(url_format));
+ url_format[sizeof(url_format) - 1] = '\0';
+ break;
+
+ case 'c':
+ {
+ unsigned long value;
+ char * end;
+
+ value = strtoul(optarg, &end, 10);
+ if (value < 1 || value > 100 || *end != '\0')
+ {
+ usage(std::cerr);
+ return 1;
+ }
+ concurrency_limit = value;
+ }
+ break;
+
+ case 'H':
+ {
+ unsigned long value;
+ char * end;
+
+ value = strtoul(optarg, &end, 10);
+ if (value < 1 || value > 200 || *end != '\0')
+ {
+ usage(std::cerr);
+ return 1;
+ }
+ highwater = value;
+ }
+ break;
+
+ case 'p':
+ {
+ unsigned long value;
+ char * end;
+
+ value = strtoul(optarg, &end, 10);
+ if (value > 100 || *end != '\0')
+ {
+ usage(std::cerr);
+ return 1;
+ }
+ pipeline_depth = value;
+ }
+ break;
+
+ case '5':
+ {
+ unsigned long value;
+ char * end;
+
+ value = strtoul(optarg, &end, 10);
+ if (value > 3 || *end != '\0')
+ {
+ usage(std::cerr);
+ return 1;
+ }
+ tracing = value;
+ }
+ break;
+
+ case 'R':
+ do_random = true;
+ do_whole = false;
+ break;
+
+ case 'w':
+ do_whole = true;
+ do_random = false;
+ break;
+
+ case 'v':
+ do_verbose = true;
+ break;
+
+ case 'h':
+ case '?':
+ usage(std::cout);
+ return 0;
+ }
+ }
+
+ if ((optind + 1) != argc)
+ {
+ usage(std::cerr);
+ return 1;
+ }
+
+ FILE * uuids(fopen(argv[optind], "r"));
+ if (! uuids)
+ {
+ const char * errstr(strerror(errno));
+
+ std::cerr << "Couldn't open UUID file '" << argv[optind] << "'. Reason: "
+ << errstr << std::endl;
+ return 1;
+ }
+
+ // Initialization
+ init_curl();
+ LLCore::HttpRequest::createService();
+ LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_CONNECTION_LIMIT,
+ LLCore::HttpRequest::DEFAULT_POLICY_ID,
+ concurrency_limit,
+ NULL);
+ LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_PER_HOST_CONNECTION_LIMIT,
+ LLCore::HttpRequest::DEFAULT_POLICY_ID,
+ concurrency_limit,
+ NULL);
+ if (pipeline_depth)
+ {
+ LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_PIPELINING_DEPTH,
+ LLCore::HttpRequest::DEFAULT_POLICY_ID,
+ pipeline_depth,
+ NULL);
+ }
+ if (tracing)
+ {
+ LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_TRACE,
+ LLCore::HttpRequest::DEFAULT_POLICY_ID,
+ tracing,
+ NULL);
+ }
+ LLCore::HttpRequest::startThread();
+
+ // Get service point
+ LLCore::HttpRequest * hr = new LLCore::HttpRequest();
+
+ // Get request options
+ LLCore::HttpOptions::ptr_t opt = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions());
+ opt->setRetries(12);
+ opt->setUseRetryAfter(true);
+
+ // Get a handler/working set
+ WorkingSet ws;
+
+ // Fill the working set with work
+ ws.mUrl = url_format;
+ ws.loadAssetUuids(uuids);
+ ws.mRandomRange = do_random;
+ ws.mNoRange = do_whole;
+ ws.mVerbose = do_verbose;
+ ws.mRequestHighWater = highwater;
+ ws.mRequestLowWater = ws.mRequestHighWater / 2;
+
+ if (! ws.mAssets.size())
+ {
+ std::cerr << "No UUIDs found in file '" << argv[optind] << "'." << std::endl;
+ return 1;
+ }
+
+ // Setup metrics
+ Metrics metrics;
+ metrics.init();
+
+ // Run it
+ int passes(0);
+ while (! ws.reload(hr, opt))
+ {
+ hr->update(0);
+ ms_sleep(2);
+ if (0 == (++passes % 200))
+ {
+ metrics.sample();
+ }
+ }
+ metrics.sample();
+ metrics.term();
+
+ // Report
+ std::cout << "HTTP errors: " << ws.mErrorsHttp << " API errors: " << ws.mErrorsApi
+ << " Successes: " << ws.mSuccesses << " Byte count: " << ws.mByteCount
+ << std::endl;
+ std::cout << "HTTP 404 errors: " << ws.mErrorsHttp404 << " HTTP 416 errors: " << ws.mErrorsHttp416
+ << " HTTP 500 errors: " << ws.mErrorsHttp500 << " HTTP 503 errors: " << ws.mErrorsHttp503
+ << std::endl;
+ std::cout << "Retries: " << ws.mRetries << " Retries on 503: " << ws.mRetriesHttp503
+ << std::endl;
+ std::cout << "User CPU: " << (metrics.mEndUTime - metrics.mStartUTime)
+ << " uS System CPU: " << (metrics.mEndSTime - metrics.mStartSTime)
+ << " uS Wall Time: " << (metrics.mEndWallTime - metrics.mStartWallTime)
+ << " uS Maximum VSZ: " << metrics.mMaxVSZ
+ << " Bytes Minimum VSZ: " << metrics.mMinVSZ << " Bytes"
+ << std::endl;
+
+ // Clean up
+ hr->requestStopThread(LLCore::HttpHandler::ptr_t());
+ ms_sleep(1000);
opt.reset();
- delete hr;
- LLCore::HttpRequest::destroyService();
- term_curl();
-
+ delete hr;
+ LLCore::HttpRequest::destroyService();
+ term_curl();
+
return 0;
}
void usage(std::ostream & out)
{
- out << "\n"
- "usage:\thttp_texture_load [options] uuid_file\n"
- "\n"
- "This is a standalone program to drive the New Platform HTTP Library.\n"
- "The program is supplied with a file of texture UUIDs, one per line\n"
- "These are fetched sequentially using a pool of concurrent connection\n"
- "until all are fetched. The default URL format is only useful from\n"
- "within Linden Lab but this can be overriden with a printf-style\n"
- "URL formatting string on the command line.\n"
- "\n"
- "Options:\n"
- "\n"
- " -u <url_format> printf-style format string for URL generation\n"
- " Default: " << url_format << "\n"
- " -R Issue GETs with random Range: headers\n"
- " -w Issue GETs without Range: headers to get whole object\n"
- " -c <limit> Maximum connection concurrency. Range: [1..100]\n"
- " Default: " << concurrency_limit << "\n"
- " -H <limit> HTTP request highwater (requests fed to llcorehttp).\n"
- " Range: [1..200] Default: " << highwater << "\n"
- " -p <depth> If <depth> is positive, enables and sets pipelineing\n"
- " depth on HTTP requests. Default: " << pipeline_depth << "\n"
- " -t <level> If <level> is positive ([1..3]), enables and sets HTTP\n"
- " tracing on HTTP requests. Default: " << tracing << "\n"
- " -v Verbose mode. Issue some chatter while running\n"
- " -h print this help\n"
- "\n"
- << std::endl;
+ out << "\n"
+ "usage:\thttp_texture_load [options] uuid_file\n"
+ "\n"
+ "This is a standalone program to drive the New Platform HTTP Library.\n"
+ "The program is supplied with a file of texture UUIDs, one per line\n"
+ "These are fetched sequentially using a pool of concurrent connection\n"
+ "until all are fetched. The default URL format is only useful from\n"
+ "within Linden Lab but this can be overriden with a printf-style\n"
+ "URL formatting string on the command line.\n"
+ "\n"
+ "Options:\n"
+ "\n"
+ " -u <url_format> printf-style format string for URL generation\n"
+ " Default: " << url_format << "\n"
+ " -R Issue GETs with random Range: headers\n"
+ " -w Issue GETs without Range: headers to get whole object\n"
+ " -c <limit> Maximum connection concurrency. Range: [1..100]\n"
+ " Default: " << concurrency_limit << "\n"
+ " -H <limit> HTTP request highwater (requests fed to llcorehttp).\n"
+ " Range: [1..200] Default: " << highwater << "\n"
+ " -p <depth> If <depth> is positive, enables and sets pipelineing\n"
+ " depth on HTTP requests. Default: " << pipeline_depth << "\n"
+ " -t <level> If <level> is positive ([1..3]), enables and sets HTTP\n"
+ " tracing on HTTP requests. Default: " << tracing << "\n"
+ " -v Verbose mode. Issue some chatter while running\n"
+ " -h print this help\n"
+ "\n"
+ << std::endl;
}
WorkingSet::WorkingSet()
- : LLCore::HttpHandler(),
- mVerbose(false),
- mRandomRange(false),
- mNoRange(false),
- mRemaining(200),
- mLimit(200),
- mAt(0),
- mErrorsApi(0),
- mErrorsHttp(0),
- mErrorsHttp404(0),
- mErrorsHttp416(0),
- mErrorsHttp500(0),
- mErrorsHttp503(0),
- mRetries(0),
- mRetriesHttp503(0),
- mSuccesses(0),
- mByteCount(0L)
+ : LLCore::HttpHandler(),
+ mVerbose(false),
+ mRandomRange(false),
+ mNoRange(false),
+ mRemaining(200),
+ mLimit(200),
+ mAt(0),
+ mErrorsApi(0),
+ mErrorsHttp(0),
+ mErrorsHttp404(0),
+ mErrorsHttp416(0),
+ mErrorsHttp500(0),
+ mErrorsHttp503(0),
+ mRetries(0),
+ mRetriesHttp503(0),
+ mSuccesses(0),
+ mByteCount(0L)
{
- mAssets.reserve(30000);
+ mAssets.reserve(30000);
- mHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
- mHeaders->append("Accept", "image/x-j2c");
+ mHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
+ mHeaders->append("Accept", "image/x-j2c");
}
@@ -443,166 +443,166 @@ namespace
bool WorkingSet::reload(LLCore::HttpRequest * hr, LLCore::HttpOptions::ptr_t & opt)
{
- if (mRequestLowWater <= mHandles.size())
- {
- // Haven't fallen below low-water level yet.
- return false;
- }
-
- int to_do((std::min)(mRemaining, mRequestHighWater - int(mHandles.size())));
-
- for (int i(0); i < to_do; ++i)
- {
- char buffer[1024];
-#if defined(WIN32)
- _snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, mUrl.c_str(), mAssets[mAt].mUuid.c_str());
+ if (mRequestLowWater <= mHandles.size())
+ {
+ // Haven't fallen below low-water level yet.
+ return false;
+ }
+
+ int to_do((std::min)(mRemaining, mRequestHighWater - int(mHandles.size())));
+
+ for (int i(0); i < to_do; ++i)
+ {
+ char buffer[1024];
+#if defined(WIN32)
+ _snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, mUrl.c_str(), mAssets[mAt].mUuid.c_str());
#else
- snprintf(buffer, sizeof(buffer), mUrl.c_str(), mAssets[mAt].mUuid.c_str());
+ snprintf(buffer, sizeof(buffer), mUrl.c_str(), mAssets[mAt].mUuid.c_str());
#endif
- int offset(mNoRange
- ? 0
- : (mRandomRange ? ((unsigned long) rand()) % 1000000UL : mAssets[mAt].mOffset));
- int length(mNoRange
- ? 0
- : (mRandomRange ? ((unsigned long) rand()) % 1000000UL : mAssets[mAt].mLength));
-
- LLCore::HttpHandle handle;
- if (offset || length)
- {
- handle = hr->requestGetByteRange(0, buffer, offset, length, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor));
- }
- else
- {
+ int offset(mNoRange
+ ? 0
+ : (mRandomRange ? ((unsigned long) rand()) % 1000000UL : mAssets[mAt].mOffset));
+ int length(mNoRange
+ ? 0
+ : (mRandomRange ? ((unsigned long) rand()) % 1000000UL : mAssets[mAt].mLength));
+
+ LLCore::HttpHandle handle;
+ if (offset || length)
+ {
+ handle = hr->requestGetByteRange(0, buffer, offset, length, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor));
+ }
+ else
+ {
handle = hr->requestGet(0, buffer, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor));
- }
- if (! handle)
- {
- // Fatal. Couldn't queue up something.
- std::cerr << "Failed to queue work to HTTP Service. Reason: "
- << hr->getStatus().toString() << std::endl;
- exit(1);
- }
- else
- {
- mHandles.insert(handle);
- }
- mAt++;
- mRemaining--;
-
- if (mVerbose)
- {
- static int count(0);
- ++count;
- if (0 == (count %5))
- std::cout << "Queued " << count << std::endl;
- }
- }
-
- // Are we done?
- return (! mRemaining) && mHandles.empty();
+ }
+ if (! handle)
+ {
+ // Fatal. Couldn't queue up something.
+ std::cerr << "Failed to queue work to HTTP Service. Reason: "
+ << hr->getStatus().toString() << std::endl;
+ exit(1);
+ }
+ else
+ {
+ mHandles.insert(handle);
+ }
+ mAt++;
+ mRemaining--;
+
+ if (mVerbose)
+ {
+ static int count(0);
+ ++count;
+ if (0 == (count %5))
+ std::cout << "Queued " << count << std::endl;
+ }
+ }
+
+ // Are we done?
+ return (! mRemaining) && mHandles.empty();
}
-
+
void WorkingSet::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
{
- handle_set_t::iterator it(mHandles.find(handle));
- if (mHandles.end() == it)
- {
- // Wha?
- std::cerr << "Failed to find handle in request list. Fatal." << std::endl;
- exit(1);
- }
- else
- {
- LLCore::HttpStatus status(response->getStatus());
- if (status)
- {
- // More success
- LLCore::BufferArray * data(response->getBody());
- mByteCount += data ? data->size() : 0;
- ++mSuccesses;
- }
- else
- {
- // Something in this library or libcurl
- if (status.isHttpStatus())
- {
- static const LLCore::HttpStatus hs404(404);
- static const LLCore::HttpStatus hs416(416);
- static const LLCore::HttpStatus hs500(500);
- static const LLCore::HttpStatus hs503(503);
-
- ++mErrorsHttp;
- if (hs404 == status)
- {
- ++mErrorsHttp404;
- }
- else if (hs416 == status)
- {
- ++mErrorsHttp416;
- }
- else if (hs500 == status)
- {
- ++mErrorsHttp500;
- }
- else if (hs503 == status)
- {
- ++mErrorsHttp503;
- }
- }
- else
- {
- ++mErrorsApi;
- }
- }
- unsigned int retry(0U), retry_503(0U);
- response->getRetries(&retry, &retry_503);
- mRetries += int(retry);
- mRetriesHttp503 += int(retry_503);
- mHandles.erase(it);
- }
-
- if (mVerbose)
- {
- static int count(0);
- ++count;
- if (0 == (count %5))
- std::cout << "Handled " << count << std::endl;
- }
+ handle_set_t::iterator it(mHandles.find(handle));
+ if (mHandles.end() == it)
+ {
+ // Wha?
+ std::cerr << "Failed to find handle in request list. Fatal." << std::endl;
+ exit(1);
+ }
+ else
+ {
+ LLCore::HttpStatus status(response->getStatus());
+ if (status)
+ {
+ // More success
+ LLCore::BufferArray * data(response->getBody());
+ mByteCount += data ? data->size() : 0;
+ ++mSuccesses;
+ }
+ else
+ {
+ // Something in this library or libcurl
+ if (status.isHttpStatus())
+ {
+ static const LLCore::HttpStatus hs404(404);
+ static const LLCore::HttpStatus hs416(416);
+ static const LLCore::HttpStatus hs500(500);
+ static const LLCore::HttpStatus hs503(503);
+
+ ++mErrorsHttp;
+ if (hs404 == status)
+ {
+ ++mErrorsHttp404;
+ }
+ else if (hs416 == status)
+ {
+ ++mErrorsHttp416;
+ }
+ else if (hs500 == status)
+ {
+ ++mErrorsHttp500;
+ }
+ else if (hs503 == status)
+ {
+ ++mErrorsHttp503;
+ }
+ }
+ else
+ {
+ ++mErrorsApi;
+ }
+ }
+ unsigned int retry(0U), retry_503(0U);
+ response->getRetries(&retry, &retry_503);
+ mRetries += int(retry);
+ mRetriesHttp503 += int(retry_503);
+ mHandles.erase(it);
+ }
+
+ if (mVerbose)
+ {
+ static int count(0);
+ ++count;
+ if (0 == (count %5))
+ std::cout << "Handled " << count << std::endl;
+ }
}
void WorkingSet::loadAssetUuids(FILE * in)
{
- char buffer[1024];
-
- while (fgets(buffer, sizeof(buffer), in))
- {
- WorkingSet::Spec asset;
- char * state(NULL);
- char * token = strtok_r(buffer, " \t\n,", &state);
- if (token && 36 == strlen(token))
- {
- // Close enough for this function
- asset.mUuid = token;
- asset.mOffset = 0;
- asset.mLength = 0;
- token = strtok_r(buffer, " \t\n,", &state);
- if (token)
- {
- int offset(atoi(token));
- token = strtok_r(buffer, " \t\n,", &state);
- if (token)
- {
- int length(atoi(token));
- asset.mOffset = offset;
- asset.mLength = length;
- }
- }
- mAssets.push_back(asset);
- }
- }
- mRemaining = mLimit = mAssets.size();
+ char buffer[1024];
+
+ while (fgets(buffer, sizeof(buffer), in))
+ {
+ WorkingSet::Spec asset;
+ char * state(NULL);
+ char * token = strtok_r(buffer, " \t\n,", &state);
+ if (token && 36 == strlen(token))
+ {
+ // Close enough for this function
+ asset.mUuid = token;
+ asset.mOffset = 0;
+ asset.mLength = 0;
+ token = strtok_r(buffer, " \t\n,", &state);
+ if (token)
+ {
+ int offset(atoi(token));
+ token = strtok_r(buffer, " \t\n,", &state);
+ if (token)
+ {
+ int length(atoi(token));
+ asset.mOffset = offset;
+ asset.mLength = length;
+ }
+ }
+ mAssets.push_back(asset);
+ }
+ }
+ mRemaining = mLimit = mAssets.size();
}
@@ -611,58 +611,58 @@ LLCoreInt::HttpMutex ** ssl_mutex_list = NULL;
void init_curl()
{
- curl_global_init(CURL_GLOBAL_ALL);
-
- ssl_mutex_count = CRYPTO_num_locks();
- if (ssl_mutex_count > 0)
- {
- ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count];
-
- for (int i(0); i < ssl_mutex_count; ++i)
- {
- ssl_mutex_list[i] = new LLCoreInt::HttpMutex;
- }
-
- CRYPTO_set_locking_callback(ssl_locking_callback);
- CRYPTO_THREADID_set_callback(ssl_thread_id_callback);
- }
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ ssl_mutex_count = CRYPTO_num_locks();
+ if (ssl_mutex_count > 0)
+ {
+ ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count];
+
+ for (int i(0); i < ssl_mutex_count; ++i)
+ {
+ ssl_mutex_list[i] = new LLCoreInt::HttpMutex;
+ }
+
+ CRYPTO_set_locking_callback(ssl_locking_callback);
+ CRYPTO_THREADID_set_callback(ssl_thread_id_callback);
+ }
}
void term_curl()
{
- CRYPTO_set_locking_callback(NULL);
- for (int i(0); i < ssl_mutex_count; ++i)
- {
- delete ssl_mutex_list[i];
- }
- delete [] ssl_mutex_list;
+ CRYPTO_set_locking_callback(NULL);
+ for (int i(0); i < ssl_mutex_count; ++i)
+ {
+ delete ssl_mutex_list[i];
+ }
+ delete [] ssl_mutex_list;
}
void ssl_thread_id_callback(CRYPTO_THREADID* pthreadid)
{
#if defined(WIN32)
- CRYPTO_THREADID_set_pointer(pthreadid, GetCurrentThread());
+ CRYPTO_THREADID_set_pointer(pthreadid, GetCurrentThread());
#else
- CRYPTO_THREADID_set_pointer(pthreadid, pthread_self());
+ CRYPTO_THREADID_set_pointer(pthreadid, pthread_self());
#endif
}
void ssl_locking_callback(int mode, int type, const char * /* file */, int /* line */)
{
- if (type >= 0 && type < ssl_mutex_count)
- {
- if (mode & CRYPTO_LOCK)
- {
- ssl_mutex_list[type]->lock();
- }
- else
- {
- ssl_mutex_list[type]->unlock();
- }
- }
+ if (type >= 0 && type < ssl_mutex_count)
+ {
+ if (mode & CRYPTO_LOCK)
+ {
+ ssl_mutex_list[type]->lock();
+ }
+ else
+ {
+ ssl_mutex_list[type]->unlock();
+ }
+ }
}
@@ -672,41 +672,41 @@ void ssl_locking_callback(int mode, int type, const char * /* file */, int /* li
// it too hard...
int getopt(int argc, char * const argv[], const char *optstring)
{
- static int pos(0);
- while (optind < argc)
- {
- if (pos == 0)
- {
- if (argv[optind][0] != '-')
- return -1;
- pos = 1;
- }
- if (! argv[optind][pos])
- {
- ++optind;
- pos = 0;
- continue;
- }
- const char * thing(strchr(optstring, argv[optind][pos]));
- if (! thing)
- {
- ++optind;
- return -1;
- }
- if (thing[1] == ':')
- {
- optarg = argv[++optind];
- ++optind;
- pos = 0;
- }
- else
- {
- optarg = NULL;
- ++pos;
- }
- return *thing;
- }
- return -1;
+ static int pos(0);
+ while (optind < argc)
+ {
+ if (pos == 0)
+ {
+ if (argv[optind][0] != '-')
+ return -1;
+ pos = 1;
+ }
+ if (! argv[optind][pos])
+ {
+ ++optind;
+ pos = 0;
+ continue;
+ }
+ const char * thing(strchr(optstring, argv[optind][pos]));
+ if (! thing)
+ {
+ ++optind;
+ return -1;
+ }
+ if (thing[1] == ':')
+ {
+ optarg = argv[++optind];
+ ++optind;
+ pos = 0;
+ }
+ else
+ {
+ optarg = NULL;
+ ++pos;
+ }
+ return *thing;
+ }
+ return -1;
}
#endif
@@ -715,63 +715,63 @@ int getopt(int argc, char * const argv[], const char *optstring)
#if LL_WINDOWS
-#define PSAPI_VERSION 1
+#define PSAPI_VERSION 1
#include "windows.h"
#include "psapi.h"
class Metrics::MetricsImpl
{
public:
- MetricsImpl()
- {}
-
- ~MetricsImpl()
- {}
-
- void init(Metrics * metrics)
- {
- HANDLE self(GetCurrentProcess()); // Does not have to be closed
- FILETIME ft_dummy, ft_system, ft_user;
- GetProcessTimes(self, &ft_dummy, &ft_dummy, &ft_system, &ft_user);
- ULARGE_INTEGER uli;
- uli.u.LowPart = ft_system.dwLowDateTime;
- uli.u.HighPart = ft_system.dwHighDateTime;
- metrics->mStartSTime = uli.QuadPart / U64L(10); // Convert to uS
- uli.u.LowPart = ft_user.dwLowDateTime;
- uli.u.HighPart = ft_user.dwHighDateTime;
- metrics->mStartUTime = uli.QuadPart / U64L(10);
- metrics->mStartWallTime = totalTime();
- }
-
- void sample(Metrics * metrics)
- {
- PROCESS_MEMORY_COUNTERS_EX counters;
-
- GetProcessMemoryInfo(GetCurrentProcess(),
- (PROCESS_MEMORY_COUNTERS *) &counters,
- sizeof(counters));
- // Okay, PrivateUsage isn't truly VSZ but it will be
- // a good tracker for leaks and fragmentation. Work on
- // a better estimator later...
- SIZE_T vsz(counters.PrivateUsage);
- metrics->mMaxVSZ = (std::max)(metrics->mMaxVSZ, U64(vsz));
- metrics->mMinVSZ = (std::min)(metrics->mMinVSZ, U64(vsz));
- }
-
- void term(Metrics * metrics)
- {
- HANDLE self(GetCurrentProcess()); // Does not have to be closed
- FILETIME ft_dummy, ft_system, ft_user;
- GetProcessTimes(self, &ft_dummy, &ft_dummy, &ft_system, &ft_user);
- ULARGE_INTEGER uli;
- uli.u.LowPart = ft_system.dwLowDateTime;
- uli.u.HighPart = ft_system.dwHighDateTime;
- metrics->mEndSTime = uli.QuadPart / U64L(10);
- uli.u.LowPart = ft_user.dwLowDateTime;
- uli.u.HighPart = ft_user.dwHighDateTime;
- metrics->mEndUTime = uli.QuadPart / U64L(10);
- metrics->mEndWallTime = totalTime();
- }
+ MetricsImpl()
+ {}
+
+ ~MetricsImpl()
+ {}
+
+ void init(Metrics * metrics)
+ {
+ HANDLE self(GetCurrentProcess()); // Does not have to be closed
+ FILETIME ft_dummy, ft_system, ft_user;
+ GetProcessTimes(self, &ft_dummy, &ft_dummy, &ft_system, &ft_user);
+ ULARGE_INTEGER uli;
+ uli.u.LowPart = ft_system.dwLowDateTime;
+ uli.u.HighPart = ft_system.dwHighDateTime;
+ metrics->mStartSTime = uli.QuadPart / U64L(10); // Convert to uS
+ uli.u.LowPart = ft_user.dwLowDateTime;
+ uli.u.HighPart = ft_user.dwHighDateTime;
+ metrics->mStartUTime = uli.QuadPart / U64L(10);
+ metrics->mStartWallTime = totalTime();
+ }
+
+ void sample(Metrics * metrics)
+ {
+ PROCESS_MEMORY_COUNTERS_EX counters;
+
+ GetProcessMemoryInfo(GetCurrentProcess(),
+ (PROCESS_MEMORY_COUNTERS *) &counters,
+ sizeof(counters));
+ // Okay, PrivateUsage isn't truly VSZ but it will be
+ // a good tracker for leaks and fragmentation. Work on
+ // a better estimator later...
+ SIZE_T vsz(counters.PrivateUsage);
+ metrics->mMaxVSZ = (std::max)(metrics->mMaxVSZ, U64(vsz));
+ metrics->mMinVSZ = (std::min)(metrics->mMinVSZ, U64(vsz));
+ }
+
+ void term(Metrics * metrics)
+ {
+ HANDLE self(GetCurrentProcess()); // Does not have to be closed
+ FILETIME ft_dummy, ft_system, ft_user;
+ GetProcessTimes(self, &ft_dummy, &ft_dummy, &ft_system, &ft_user);
+ ULARGE_INTEGER uli;
+ uli.u.LowPart = ft_system.dwLowDateTime;
+ uli.u.HighPart = ft_system.dwHighDateTime;
+ metrics->mEndSTime = uli.QuadPart / U64L(10);
+ uli.u.LowPart = ft_user.dwLowDateTime;
+ uli.u.HighPart = ft_user.dwHighDateTime;
+ metrics->mEndUTime = uli.QuadPart / U64L(10);
+ metrics->mEndWallTime = totalTime();
+ }
protected:
};
@@ -780,82 +780,82 @@ protected:
#include <sys/resource.h>
#include <mach/mach.h>
-
+
class Metrics::MetricsImpl
{
public:
- MetricsImpl()
- {}
-
- ~MetricsImpl()
- {}
-
- void init(Metrics * metrics)
- {
- U64 utime, stime;
-
- if (getTimes(&utime, &stime))
- {
- metrics->mStartSTime = stime;
- metrics->mStartUTime = utime;
- }
- metrics->mStartWallTime = totalTime();
- sample(metrics);
- }
-
- void sample(Metrics * metrics)
- {
- U64 vsz;
-
- if (getVM(&vsz))
- {
- metrics->mMaxVSZ = (std::max)(metrics->mMaxVSZ, vsz);
- metrics->mMinVSZ = (std::min)(metrics->mMinVSZ, vsz);
- }
- }
-
- void term(Metrics * metrics)
- {
- U64 utime, stime;
-
- if (getTimes(&utime, &stime))
- {
- metrics->mEndSTime = stime;
- metrics->mEndUTime = utime;
- }
- metrics->mEndWallTime = totalTime();
- }
+ MetricsImpl()
+ {}
+
+ ~MetricsImpl()
+ {}
+
+ void init(Metrics * metrics)
+ {
+ U64 utime, stime;
+
+ if (getTimes(&utime, &stime))
+ {
+ metrics->mStartSTime = stime;
+ metrics->mStartUTime = utime;
+ }
+ metrics->mStartWallTime = totalTime();
+ sample(metrics);
+ }
+
+ void sample(Metrics * metrics)
+ {
+ U64 vsz;
+
+ if (getVM(&vsz))
+ {
+ metrics->mMaxVSZ = (std::max)(metrics->mMaxVSZ, vsz);
+ metrics->mMinVSZ = (std::min)(metrics->mMinVSZ, vsz);
+ }
+ }
+
+ void term(Metrics * metrics)
+ {
+ U64 utime, stime;
+
+ if (getTimes(&utime, &stime))
+ {
+ metrics->mEndSTime = stime;
+ metrics->mEndUTime = utime;
+ }
+ metrics->mEndWallTime = totalTime();
+ }
protected:
- bool getVM(U64 * vsz)
- {
- task_basic_info task_info_block;
- mach_msg_type_number_t task_info_count(TASK_BASIC_INFO_COUNT);
-
- if (KERN_SUCCESS != task_info(mach_task_self(),
- TASK_BASIC_INFO,
- (task_info_t) &task_info_block,
- &task_info_count))
- {
- return false;
- }
- * vsz = task_info_block.virtual_size;
- return true;
- }
-
- bool getTimes(U64 * utime, U64 * stime)
- {
- struct rusage usage;
-
- if (getrusage(RUSAGE_SELF, &usage))
- {
- return false;
- }
- * utime = U64(usage.ru_utime.tv_sec) * U64L(1000000) + usage.ru_utime.tv_usec;
- * stime = U64(usage.ru_stime.tv_sec) * U64L(1000000) + usage.ru_stime.tv_usec;
- return true;
- }
-
+ bool getVM(U64 * vsz)
+ {
+ task_basic_info task_info_block;
+ mach_msg_type_number_t task_info_count(TASK_BASIC_INFO_COUNT);
+
+ if (KERN_SUCCESS != task_info(mach_task_self(),
+ TASK_BASIC_INFO,
+ (task_info_t) &task_info_block,
+ &task_info_count))
+ {
+ return false;
+ }
+ * vsz = task_info_block.virtual_size;
+ return true;
+ }
+
+ bool getTimes(U64 * utime, U64 * stime)
+ {
+ struct rusage usage;
+
+ if (getrusage(RUSAGE_SELF, &usage))
+ {
+ return false;
+ }
+ * utime = U64(usage.ru_utime.tv_sec) * U64L(1000000) + usage.ru_utime.tv_usec;
+ * stime = U64(usage.ru_stime.tv_sec) * U64L(1000000) + usage.ru_stime.tv_usec;
+ return true;
+ }
+
};
#else
@@ -863,198 +863,198 @@ protected:
class Metrics::MetricsImpl
{
public:
- MetricsImpl()
- : mProcFS(NULL),
- mUsecsPerTick(U64L(0))
- {}
-
-
- ~MetricsImpl()
- {
- if (mProcFS)
- {
- fclose(mProcFS);
- mProcFS = NULL;
- }
- }
-
- void init(Metrics * metrics)
- {
- if (! mProcFS)
- {
- mProcFS = fopen("/proc/self/stat", "r");
- if (! mProcFS)
- {
- const int errnum(errno);
- LL_ERRS("Main") << "Error opening proc fs: " << strerror(errnum) << LL_ENDL;
- }
- }
-
- long ticks_per_sec(sysconf(_SC_CLK_TCK));
- mUsecsPerTick = U64L(1000000) / ticks_per_sec;
- U64 usecs_per_sec(mUsecsPerTick * ticks_per_sec);
- if (900000 > usecs_per_sec || 1100000 < usecs_per_sec)
- {
- LL_ERRS("Main") << "Resolution problems using uSecs for ticks" << LL_ENDL;
- }
-
- U64 utime, stime;
- if (scanProcFS(&utime, &stime, NULL))
- {
- metrics->mStartSTime = stime;
- metrics->mStartUTime = utime;
- }
- metrics->mStartWallTime = totalTime();
-
- sample(metrics);
- }
-
-
- void sample(Metrics * metrics)
- {
- U64 vsz;
- if (scanProcFS(NULL, NULL, &vsz))
- {
- metrics->mMaxVSZ = (std::max)(metrics->mMaxVSZ, vsz);
- metrics->mMinVSZ = (std::min)(metrics->mMinVSZ, vsz);
- }
- }
-
-
- void term(Metrics * metrics)
- {
- U64 utime, stime;
- if (scanProcFS(&utime, &stime, NULL))
- {
- metrics->mEndSTime = stime;
- metrics->mEndUTime = utime;
- }
- metrics->mEndWallTime = totalTime();
-
- sample(metrics);
-
- if (mProcFS)
- {
- fclose(mProcFS);
- mProcFS = NULL;
- }
- }
-
+ MetricsImpl()
+ : mProcFS(NULL),
+ mUsecsPerTick(U64L(0))
+ {}
+
+
+ ~MetricsImpl()
+ {
+ if (mProcFS)
+ {
+ fclose(mProcFS);
+ mProcFS = NULL;
+ }
+ }
+
+ void init(Metrics * metrics)
+ {
+ if (! mProcFS)
+ {
+ mProcFS = fopen("/proc/self/stat", "r");
+ if (! mProcFS)
+ {
+ const int errnum(errno);
+ LL_ERRS("Main") << "Error opening proc fs: " << strerror(errnum) << LL_ENDL;
+ }
+ }
+
+ long ticks_per_sec(sysconf(_SC_CLK_TCK));
+ mUsecsPerTick = U64L(1000000) / ticks_per_sec;
+ U64 usecs_per_sec(mUsecsPerTick * ticks_per_sec);
+ if (900000 > usecs_per_sec || 1100000 < usecs_per_sec)
+ {
+ LL_ERRS("Main") << "Resolution problems using uSecs for ticks" << LL_ENDL;
+ }
+
+ U64 utime, stime;
+ if (scanProcFS(&utime, &stime, NULL))
+ {
+ metrics->mStartSTime = stime;
+ metrics->mStartUTime = utime;
+ }
+ metrics->mStartWallTime = totalTime();
+
+ sample(metrics);
+ }
+
+
+ void sample(Metrics * metrics)
+ {
+ U64 vsz;
+ if (scanProcFS(NULL, NULL, &vsz))
+ {
+ metrics->mMaxVSZ = (std::max)(metrics->mMaxVSZ, vsz);
+ metrics->mMinVSZ = (std::min)(metrics->mMinVSZ, vsz);
+ }
+ }
+
+
+ void term(Metrics * metrics)
+ {
+ U64 utime, stime;
+ if (scanProcFS(&utime, &stime, NULL))
+ {
+ metrics->mEndSTime = stime;
+ metrics->mEndUTime = utime;
+ }
+ metrics->mEndWallTime = totalTime();
+
+ sample(metrics);
+
+ if (mProcFS)
+ {
+ fclose(mProcFS);
+ mProcFS = NULL;
+ }
+ }
+
protected:
- bool scanProcFS(U64 * utime, U64 * stime, U64 * vsz)
- {
- if (mProcFS)
- {
- int i_dummy;
- unsigned int ui_dummy;
- unsigned long ul_dummy, user_ticks, sys_ticks, vsize;
- long l_dummy, rss;
- unsigned long long ull_dummy;
- char c_dummy;
-
- char buffer[256];
-
- static const char * format("%d %*s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %llu %lu %ld");
-
- fseek(mProcFS, 0L, SEEK_SET);
- size_t len = fread(buffer, 1, sizeof(buffer) - 1, mProcFS);
- if (! len)
- {
- return false;
- }
- buffer[len] = '\0';
- if (23 == sscanf(buffer, format,
- &i_dummy, // pid
- // &s_dummy, // command name
- &c_dummy, // state
- &i_dummy, // ppid
- &i_dummy, // pgrp
- &i_dummy, // session
- &i_dummy, // terminal
- &i_dummy, // terminal group id
- &ui_dummy, // flags
- &ul_dummy, // minor faults
- &ul_dummy, // minor faults in children
- &ul_dummy, // major faults
- &ul_dummy, // major faults in children
- &user_ticks,
- &sys_ticks,
- &l_dummy, // cutime
- &l_dummy, // cstime
- &l_dummy, // process priority
- &l_dummy, // nice value
- &l_dummy, // thread count
- &l_dummy, // time to SIGALRM
- &ull_dummy, // start time
- &vsize,
- &rss))
- {
- // Looks like we understand the line
- if (utime)
- {
- *utime = user_ticks * mUsecsPerTick;
- }
-
- if (stime)
- {
- *stime = sys_ticks * mUsecsPerTick;
- }
-
- if (vsz)
- {
- *vsz = vsize;
- }
- return true;
- }
- }
- return false;
- }
-
+ bool scanProcFS(U64 * utime, U64 * stime, U64 * vsz)
+ {
+ if (mProcFS)
+ {
+ int i_dummy;
+ unsigned int ui_dummy;
+ unsigned long ul_dummy, user_ticks, sys_ticks, vsize;
+ long l_dummy, rss;
+ unsigned long long ull_dummy;
+ char c_dummy;
+
+ char buffer[256];
+
+ static const char * format("%d %*s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %llu %lu %ld");
+
+ fseek(mProcFS, 0L, SEEK_SET);
+ size_t len = fread(buffer, 1, sizeof(buffer) - 1, mProcFS);
+ if (! len)
+ {
+ return false;
+ }
+ buffer[len] = '\0';
+ if (23 == sscanf(buffer, format,
+ &i_dummy, // pid
+ // &s_dummy, // command name
+ &c_dummy, // state
+ &i_dummy, // ppid
+ &i_dummy, // pgrp
+ &i_dummy, // session
+ &i_dummy, // terminal
+ &i_dummy, // terminal group id
+ &ui_dummy, // flags
+ &ul_dummy, // minor faults
+ &ul_dummy, // minor faults in children
+ &ul_dummy, // major faults
+ &ul_dummy, // major faults in children
+ &user_ticks,
+ &sys_ticks,
+ &l_dummy, // cutime
+ &l_dummy, // cstime
+ &l_dummy, // process priority
+ &l_dummy, // nice value
+ &l_dummy, // thread count
+ &l_dummy, // time to SIGALRM
+ &ull_dummy, // start time
+ &vsize,
+ &rss))
+ {
+ // Looks like we understand the line
+ if (utime)
+ {
+ *utime = user_ticks * mUsecsPerTick;
+ }
+
+ if (stime)
+ {
+ *stime = sys_ticks * mUsecsPerTick;
+ }
+
+ if (vsz)
+ {
+ *vsz = vsize;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
protected:
- FILE * mProcFS;
- U64 mUsecsPerTick;
-
+ FILE * mProcFS;
+ U64 mUsecsPerTick;
+
};
#endif // LL_WINDOWS
Metrics::Metrics()
- : mMaxVSZ(U64(0)),
- mMinVSZ(U64L(0xffffffffffffffff)),
- mStartWallTime(U64(0)),
- mEndWallTime(U64(0)),
- mStartUTime(U64(0)),
- mEndUTime(U64(0)),
- mStartSTime(U64(0)),
- mEndSTime(U64(0))
+ : mMaxVSZ(U64(0)),
+ mMinVSZ(U64L(0xffffffffffffffff)),
+ mStartWallTime(U64(0)),
+ mEndWallTime(U64(0)),
+ mStartUTime(U64(0)),
+ mEndUTime(U64(0)),
+ mStartSTime(U64(0)),
+ mEndSTime(U64(0))
{
- mImpl = new MetricsImpl();
+ mImpl = new MetricsImpl();
}
Metrics::~Metrics()
{
- delete mImpl;
- mImpl = NULL;
+ delete mImpl;
+ mImpl = NULL;
}
void Metrics::init()
{
- mImpl->init(this);
+ mImpl->init(this);
}
void Metrics::sample()
{
- mImpl->sample(this);
+ mImpl->sample(this);
}
void Metrics::term()
{
- mImpl->term(this);
+ mImpl->term(this);
}
-
+
diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp
index 61ba83594e..315ff15ebb 100644
--- a/indra/llcorehttp/httpcommon.cpp
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -1,6 +1,6 @@
/**
* @file httpcommon.cpp
- * @brief
+ * @brief
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -24,7 +24,7 @@
* $/LicenseInfo$
*/
-#include "linden_common.h" // Modifies curl/curl.h interfaces
+#include "linden_common.h" // Modifies curl/curl.h interfaces
#include "httpcommon.h"
#include "llmutex.h"
#include "llthread.h"
@@ -42,184 +42,184 @@ HttpStatus::type_enum_t LLCORE;
HttpStatus::operator U32() const
{
- // Effectively, concatenate mType (high) with mStatus (low).
- static const int shift(sizeof(mDetails->mStatus) * 8);
+ // Effectively, concatenate mType (high) with mStatus (low).
+ static const int shift(sizeof(mDetails->mStatus) * 8);
- U32 result(U32(mDetails->mType) << shift | U32((int)mDetails->mStatus));
- return result;
+ U32 result(U32(mDetails->mType) << shift | U32((int)mDetails->mStatus));
+ return result;
}
std::string HttpStatus::toHex() const
{
- std::ostringstream result;
- result.width(8);
- result.fill('0');
- result << std::hex << operator U32();
- return result.str();
+ std::ostringstream result;
+ result.width(8);
+ result.fill('0');
+ result << std::hex << operator U32();
+ return result.str();
}
std::string HttpStatus::toString() const
{
- static const char * llcore_errors[] =
- {
- "",
- "HTTP error reply status",
- "Services shutting down",
- "Operation canceled",
- "Invalid Content-Range header encountered",
- "Request handle not found",
- "Invalid datatype for argument or option",
- "Option has not been explicitly set",
- "Option is not dynamic and must be set early",
- "Invalid HTTP status code received from server",
- "Could not allocate required resource"
- };
- static const int llcore_errors_count(sizeof(llcore_errors) / sizeof(llcore_errors[0]));
-
- static const struct
- {
- type_enum_t mCode;
- const char * mText;
- }
- http_errors[] =
- {
- // Keep sorted by mCode, we binary search this list.
- { 100, "Continue" },
- { 101, "Switching Protocols" },
- { 200, "OK" },
- { 201, "Created" },
- { 202, "Accepted" },
- { 203, "Non-Authoritative Information" },
- { 204, "No Content" },
- { 205, "Reset Content" },
- { 206, "Partial Content" },
- { 300, "Multiple Choices" },
- { 301, "Moved Permanently" },
- { 302, "Found" },
- { 303, "See Other" },
- { 304, "Not Modified" },
- { 305, "Use Proxy" },
- { 307, "Temporary Redirect" },
- { 400, "Bad Request" },
- { 401, "Unauthorized" },
- { 402, "Payment Required" },
- { 403, "Forbidden" },
- { 404, "Not Found" },
- { 405, "Method Not Allowed" },
- { 406, "Not Acceptable" },
- { 407, "Proxy Authentication Required" },
- { 408, "Request Time-out" },
- { 409, "Conflict" },
- { 410, "Gone" },
- { 411, "Length Required" },
- { 412, "Precondition Failed" },
- { 413, "Request Entity Too Large" },
- { 414, "Request-URI Too Large" },
- { 415, "Unsupported Media Type" },
- { 416, "Requested range not satisfiable" },
- { 417, "Expectation Failed" },
- { 499, "Linden Catch-All" },
- { 500, "Internal Server Error" },
- { 501, "Not Implemented" },
- { 502, "Bad Gateway" },
- { 503, "Service Unavailable" },
- { 504, "Gateway Time-out" },
- { 505, "HTTP Version not supported" }
- };
- static const int http_errors_count(sizeof(http_errors) / sizeof(http_errors[0]));
-
- if (*this)
- {
- return std::string("");
- }
- switch (getType())
- {
- case EXT_CURL_EASY:
- return std::string(curl_easy_strerror(CURLcode(getStatus())));
-
- case EXT_CURL_MULTI:
- return std::string(curl_multi_strerror(CURLMcode(getStatus())));
-
- case LLCORE:
- if (getStatus() >= 0 && getStatus() < llcore_errors_count)
- {
- return std::string(llcore_errors[getStatus()]);
- }
- break;
-
- default:
- if (isHttpStatus())
- {
- // special handling for status 499 "Linden Catchall"
- if ((getType() == 499) && (!getMessage().empty()))
- return getMessage();
-
- // Binary search for the error code and string
- int bottom(0), top(http_errors_count);
- while (true)
- {
- int at((bottom + top) / 2);
- if (getType() == http_errors[at].mCode)
- {
- return std::string(http_errors[at].mText);
- }
- if (at == bottom)
- {
- break;
- }
- else if (getType() < http_errors[at].mCode)
- {
- top = at;
- }
- else
- {
- bottom = at;
- }
- }
- }
- break;
- }
- return std::string("Unknown error");
+ static const char * llcore_errors[] =
+ {
+ "",
+ "HTTP error reply status",
+ "Services shutting down",
+ "Operation canceled",
+ "Invalid Content-Range header encountered",
+ "Request handle not found",
+ "Invalid datatype for argument or option",
+ "Option has not been explicitly set",
+ "Option is not dynamic and must be set early",
+ "Invalid HTTP status code received from server",
+ "Could not allocate required resource"
+ };
+ static const int llcore_errors_count(sizeof(llcore_errors) / sizeof(llcore_errors[0]));
+
+ static const struct
+ {
+ type_enum_t mCode;
+ const char * mText;
+ }
+ http_errors[] =
+ {
+ // Keep sorted by mCode, we binary search this list.
+ { 100, "Continue" },
+ { 101, "Switching Protocols" },
+ { 200, "OK" },
+ { 201, "Created" },
+ { 202, "Accepted" },
+ { 203, "Non-Authoritative Information" },
+ { 204, "No Content" },
+ { 205, "Reset Content" },
+ { 206, "Partial Content" },
+ { 300, "Multiple Choices" },
+ { 301, "Moved Permanently" },
+ { 302, "Found" },
+ { 303, "See Other" },
+ { 304, "Not Modified" },
+ { 305, "Use Proxy" },
+ { 307, "Temporary Redirect" },
+ { 400, "Bad Request" },
+ { 401, "Unauthorized" },
+ { 402, "Payment Required" },
+ { 403, "Forbidden" },
+ { 404, "Not Found" },
+ { 405, "Method Not Allowed" },
+ { 406, "Not Acceptable" },
+ { 407, "Proxy Authentication Required" },
+ { 408, "Request Time-out" },
+ { 409, "Conflict" },
+ { 410, "Gone" },
+ { 411, "Length Required" },
+ { 412, "Precondition Failed" },
+ { 413, "Request Entity Too Large" },
+ { 414, "Request-URI Too Large" },
+ { 415, "Unsupported Media Type" },
+ { 416, "Requested range not satisfiable" },
+ { 417, "Expectation Failed" },
+ { 499, "Linden Catch-All" },
+ { 500, "Internal Server Error" },
+ { 501, "Not Implemented" },
+ { 502, "Bad Gateway" },
+ { 503, "Service Unavailable" },
+ { 504, "Gateway Time-out" },
+ { 505, "HTTP Version not supported" }
+ };
+ static const int http_errors_count(sizeof(http_errors) / sizeof(http_errors[0]));
+
+ if (*this)
+ {
+ return std::string("");
+ }
+ switch (getType())
+ {
+ case EXT_CURL_EASY:
+ return std::string(curl_easy_strerror(CURLcode(getStatus())));
+
+ case EXT_CURL_MULTI:
+ return std::string(curl_multi_strerror(CURLMcode(getStatus())));
+
+ case LLCORE:
+ if (getStatus() >= 0 && getStatus() < llcore_errors_count)
+ {
+ return std::string(llcore_errors[getStatus()]);
+ }
+ break;
+
+ default:
+ if (isHttpStatus())
+ {
+ // special handling for status 499 "Linden Catchall"
+ if ((getType() == 499) && (!getMessage().empty()))
+ return getMessage();
+
+ // Binary search for the error code and string
+ int bottom(0), top(http_errors_count);
+ while (true)
+ {
+ int at((bottom + top) / 2);
+ if (getType() == http_errors[at].mCode)
+ {
+ return std::string(http_errors[at].mText);
+ }
+ if (at == bottom)
+ {
+ break;
+ }
+ else if (getType() < http_errors[at].mCode)
+ {
+ top = at;
+ }
+ else
+ {
+ bottom = at;
+ }
+ }
+ }
+ break;
+ }
+ return std::string("Unknown error");
}
std::string HttpStatus::toTerseString() const
{
- std::ostringstream result;
-
- unsigned int error_value((unsigned short)getStatus());
-
- switch (getType())
- {
- case EXT_CURL_EASY:
- result << "Easy_";
- break;
-
- case EXT_CURL_MULTI:
- result << "Multi_";
- break;
-
- case LLCORE:
- result << "Core_";
- break;
-
- default:
- if (isHttpStatus())
- {
- result << "Http_";
- error_value = getType();
- }
- else
- {
- result << "Unknown_";
- }
- break;
- }
-
- result << error_value;
- return result.str();
+ std::ostringstream result;
+
+ unsigned int error_value((unsigned short)getStatus());
+
+ switch (getType())
+ {
+ case EXT_CURL_EASY:
+ result << "Easy_";
+ break;
+
+ case EXT_CURL_MULTI:
+ result << "Multi_";
+ break;
+
+ case LLCORE:
+ result << "Core_";
+ break;
+
+ default:
+ if (isHttpStatus())
+ {
+ result << "Http_";
+ error_value = getType();
+ }
+ else
+ {
+ result << "Unknown_";
+ }
+ break;
+ }
+
+ result << error_value;
+ return result.str();
}
@@ -235,35 +235,35 @@ std::string HttpStatus::toTerseString() const
// for details.
bool HttpStatus::isRetryable() const
{
- static const HttpStatus cant_connect(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
- static const HttpStatus cant_res_proxy(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_PROXY);
- static const HttpStatus cant_res_host(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_HOST);
- static const HttpStatus send_error(HttpStatus::EXT_CURL_EASY, CURLE_SEND_ERROR);
- static const HttpStatus recv_error(HttpStatus::EXT_CURL_EASY, CURLE_RECV_ERROR);
- static const HttpStatus upload_failed(HttpStatus::EXT_CURL_EASY, CURLE_UPLOAD_FAILED);
- static const HttpStatus op_timedout(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT);
- static const HttpStatus post_error(HttpStatus::EXT_CURL_EASY, CURLE_HTTP_POST_ERROR);
- static const HttpStatus partial_file(HttpStatus::EXT_CURL_EASY, CURLE_PARTIAL_FILE);
- static const HttpStatus inv_cont_range(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
- static const HttpStatus inv_status(HttpStatus::LLCORE, HE_INVALID_HTTP_STATUS);
-
- // *DEBUG: For "[curl:bugs] #1420" tests.
- // Disable the '*this == inv_status' test and look for 'Core_9'
- // failures in log files.
-
- return ((isHttpStatus() && getType() >= 499 && getType() <= 599) || // Include special 499 in retryables
- *this == cant_connect || // Connection reset/endpoint problems
- *this == cant_res_proxy || // DNS problems
- *this == cant_res_host || // DNS problems
- *this == send_error || // General socket problems
- *this == recv_error || // General socket problems
- *this == upload_failed || // Transport problem
- *this == op_timedout || // Timer expired
- *this == post_error || // Transport problem
- *this == partial_file || // Data inconsistency in response
- // *DEBUG: Comment out 'inv_status' test for [curl:bugs] #1420 testing.
- *this == inv_status || // Inv status can reflect internal state problem in libcurl
- *this == inv_cont_range); // Short data read disagrees with content-range
+ static const HttpStatus cant_connect(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
+ static const HttpStatus cant_res_proxy(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_PROXY);
+ static const HttpStatus cant_res_host(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_HOST);
+ static const HttpStatus send_error(HttpStatus::EXT_CURL_EASY, CURLE_SEND_ERROR);
+ static const HttpStatus recv_error(HttpStatus::EXT_CURL_EASY, CURLE_RECV_ERROR);
+ static const HttpStatus upload_failed(HttpStatus::EXT_CURL_EASY, CURLE_UPLOAD_FAILED);
+ static const HttpStatus op_timedout(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT);
+ static const HttpStatus post_error(HttpStatus::EXT_CURL_EASY, CURLE_HTTP_POST_ERROR);
+ static const HttpStatus partial_file(HttpStatus::EXT_CURL_EASY, CURLE_PARTIAL_FILE);
+ static const HttpStatus inv_cont_range(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
+ static const HttpStatus inv_status(HttpStatus::LLCORE, HE_INVALID_HTTP_STATUS);
+
+ // *DEBUG: For "[curl:bugs] #1420" tests.
+ // Disable the '*this == inv_status' test and look for 'Core_9'
+ // failures in log files.
+
+ return ((isHttpStatus() && getType() >= 499 && getType() <= 599) || // Include special 499 in retryables
+ *this == cant_connect || // Connection reset/endpoint problems
+ *this == cant_res_proxy || // DNS problems
+ *this == cant_res_host || // DNS problems
+ *this == send_error || // General socket problems
+ *this == recv_error || // General socket problems
+ *this == upload_failed || // Transport problem
+ *this == op_timedout || // Timer expired
+ *this == post_error || // Transport problem
+ *this == partial_file || // Data inconsistency in response
+ // *DEBUG: Comment out 'inv_status' test for [curl:bugs] #1420 testing.
+ *this == inv_status || // Inv status can reflect internal state problem in libcurl
+ *this == inv_cont_range); // Short data read disagrees with content-range
}
namespace LLHttp
@@ -275,7 +275,7 @@ CURL *getCurlTemplateHandle()
static CURL *curlpTemplateHandle = NULL;
if (curlpTemplateHandle == NULL)
- { // Late creation of the template curl handle
+ { // Late creation of the template curl handle
curlpTemplateHandle = curl_easy_init();
if (curlpTemplateHandle == NULL)
{
@@ -313,7 +313,7 @@ CURL *getCurlTemplateHandle()
return curlpTemplateHandle;
}
-
+
LLMutex *getCurlMutex()
{
static LLMutex* sHandleMutexp = NULL;
@@ -338,7 +338,7 @@ void deallocateEasyCurl(CURL *curlp)
void initialize()
{
- // Do not change this "unless you are familiar with and mean to control
+ // 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);
diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
index 7fe5c48edf..0a1c5ed101 100644
--- a/indra/llcorehttp/httpcommon.h
+++ b/indra/llcorehttp/httpcommon.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_COMMON_H_
-#define _LLCORE_HTTP_COMMON_H_
+#ifndef _LLCORE_HTTP_COMMON_H_
+#define _LLCORE_HTTP_COMMON_H_
/// @package LLCore::HTTP
///
@@ -42,7 +42,7 @@
/// - Scatter/gather (a.k.a. buffer array) model for bulk data movement.
/// - Reference counting used for many object instance lifetimes.
/// - Minimal data sharing across threads for correctness and low latency.
-///
+///
/// The public interface is declared in a few key header files:
/// - "llcorehttp/bufferarray.h"
/// - "llcorehttp/httpcommon.h"
@@ -100,7 +100,7 @@
/// yet functional tool to do GET request performance testing.
/// With four calls:
///
-/// init_curl();
+/// init_curl();
/// LLCore::HttpRequest::createService();
/// LLCore::HttpRequest::startThread();
/// LLCore::HttpRequest * hr = new LLCore::HttpRequest();
@@ -133,9 +133,9 @@
/// Issuing requests. Using 'hr' above,
///
/// hr->requestGet(HttpRequest::DEFAULT_POLICY_ID,
-/// 0, // Priority, not used yet
+/// 0, // Priority, not used yet
/// url,
-/// NULL, // options
+/// NULL, // options
/// NULL, // additional headers
/// handler);
///
@@ -162,11 +162,11 @@
/// constraints which programmers must follow and which are
/// defined as follows:
///
-/// consumer Any thread that has instanced HttpRequest and is
+/// consumer Any thread that has instanced HttpRequest and is
/// issuing requests. A particular instance can only
/// be used by one consumer thread but a consumer may
/// have many instances available to it.
-/// init Special consumer thread, usually the main thread,
+/// init Special consumer thread, usually the main thread,
/// involved in setting up the library at startup.
/// worker Thread used internally by the library to perform
/// HTTP operations. Consumers will not have to deal
@@ -187,7 +187,7 @@
/// only here are mutexes used.
///
-#include "linden_common.h" // Modifies curl/curl.h interfaces
+#include "linden_common.h" // Modifies curl/curl.h interfaces
#include "llsd.h"
#include "boost/intrusive_ptr.hpp"
#include "boost/shared_ptr.hpp"
@@ -212,7 +212,7 @@ namespace LLCore
typedef void * HttpHandle;
-#define LLCORE_HTTP_HANDLE_INVALID (NULL)
+#define LLCORE_HTTP_HANDLE_INVALID (NULL)
/// For internal scheduling and metrics, we use a microsecond
/// timebase compatible with the environment.
@@ -222,41 +222,41 @@ typedef U64 HttpTime;
/// libcurl (or any other transport provider).
enum HttpError
{
- // Successful value compatible with the libcurl codes.
- HE_SUCCESS = 0,
-
- // Intended for HTTP reply codes 100-999, indicates that
- // the reply should be considered an error by the application.
- HE_REPLY_ERROR = 1,
-
- // Service is shutting down and requested operation will
- // not be queued or performed.
- HE_SHUTTING_DOWN = 2,
-
- // Operation was canceled by request.
- HE_OP_CANCELED = 3,
-
- // Invalid content range header received.
- HE_INV_CONTENT_RANGE_HDR = 4,
-
- // Request handle not found
- HE_HANDLE_NOT_FOUND = 5,
-
- // Invalid datatype for option/setting
- HE_INVALID_ARG = 6,
-
- // Option hasn't been explicitly set
- HE_OPT_NOT_SET = 7,
-
- // Option not dynamic, must be set during init phase
- HE_OPT_NOT_DYNAMIC = 8,
-
- // Invalid HTTP status code returned by server
- HE_INVALID_HTTP_STATUS = 9,
-
- // Couldn't allocate resource, typically libcurl handle
- HE_BAD_ALLOC = 10
-
+ // Successful value compatible with the libcurl codes.
+ HE_SUCCESS = 0,
+
+ // Intended for HTTP reply codes 100-999, indicates that
+ // the reply should be considered an error by the application.
+ HE_REPLY_ERROR = 1,
+
+ // Service is shutting down and requested operation will
+ // not be queued or performed.
+ HE_SHUTTING_DOWN = 2,
+
+ // Operation was canceled by request.
+ HE_OP_CANCELED = 3,
+
+ // Invalid content range header received.
+ HE_INV_CONTENT_RANGE_HDR = 4,
+
+ // Request handle not found
+ HE_HANDLE_NOT_FOUND = 5,
+
+ // Invalid datatype for option/setting
+ HE_INVALID_ARG = 6,
+
+ // Option hasn't been explicitly set
+ HE_OPT_NOT_SET = 7,
+
+ // Option not dynamic, must be set during init phase
+ HE_OPT_NOT_DYNAMIC = 8,
+
+ // Invalid HTTP status code returned by server
+ HE_INVALID_HTTP_STATUS = 9,
+
+ // Couldn't allocate resource, typically libcurl handle
+ HE_BAD_ALLOC = 10
+
}; // end enum HttpError
@@ -278,223 +278,223 @@ enum HttpError
/// Examples:
///
/// 1. Construct a default, successful status code:
-/// HttpStatus();
+/// HttpStatus();
///
/// 2. Construct a successful, HTTP 200 status code:
-/// HttpStatus(200);
+/// HttpStatus(200);
///
/// 3. Construct a failed, HTTP 404 not-found status code:
-/// HttpStatus(404);
+/// HttpStatus(404);
///
/// 4. Construct a failed libcurl couldn't connect status code:
-/// HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
+/// HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
///
/// 5. Construct an HTTP 301 status code to be treated as success:
-/// HttpStatus(301, HE_SUCCESS);
+/// HttpStatus(301, HE_SUCCESS);
///
-/// 6. Construct a failed status of HTTP Status 499 with a custom error message
-/// HttpStatus(499, "Failed LLSD Response");
+/// 6. Construct a failed status of HTTP Status 499 with a custom error message
+/// HttpStatus(499, "Failed LLSD Response");
struct HttpStatus
{
- typedef unsigned short type_enum_t;
-
- HttpStatus()
- {
- mDetails = std::shared_ptr<Details>(new Details(LLCORE, HE_SUCCESS));
+ typedef unsigned short type_enum_t;
+
+ HttpStatus()
+ {
+ mDetails = std::shared_ptr<Details>(new Details(LLCORE, HE_SUCCESS));
}
- HttpStatus(type_enum_t type, short status)
- {
+ HttpStatus(type_enum_t type, short status)
+ {
mDetails = std::shared_ptr<Details>(new Details(type, status));
- }
-
- HttpStatus(int http_status)
- {
- mDetails = std::shared_ptr<Details>(new Details(http_status,
- (http_status >= 200 && http_status <= 299) ? HE_SUCCESS : HE_REPLY_ERROR));
- llassert(http_status >= 100 && http_status <= 999);
- }
-
- HttpStatus(int http_status, const std::string &message)
- {
+ }
+
+ HttpStatus(int http_status)
+ {
mDetails = std::shared_ptr<Details>(new Details(http_status,
- (http_status >= 200 && http_status <= 299) ? HE_SUCCESS : HE_REPLY_ERROR));
- llassert(http_status >= 100 && http_status <= 999);
- mDetails->mMessage = message;
- }
-
- HttpStatus(const HttpStatus & rhs)
- {
- mDetails = rhs.mDetails;
- }
-
- ~HttpStatus()
- {
- }
-
- HttpStatus & operator=(const HttpStatus & rhs)
- {
+ (http_status >= 200 && http_status <= 299) ? HE_SUCCESS : HE_REPLY_ERROR));
+ llassert(http_status >= 100 && http_status <= 999);
+ }
+
+ HttpStatus(int http_status, const std::string &message)
+ {
+ mDetails = std::shared_ptr<Details>(new Details(http_status,
+ (http_status >= 200 && http_status <= 299) ? HE_SUCCESS : HE_REPLY_ERROR));
+ llassert(http_status >= 100 && http_status <= 999);
+ mDetails->mMessage = message;
+ }
+
+ HttpStatus(const HttpStatus & rhs)
+ {
+ mDetails = rhs.mDetails;
+ }
+
+ ~HttpStatus()
+ {
+ }
+
+ HttpStatus & operator=(const HttpStatus & rhs)
+ {
mDetails = rhs.mDetails;
- return *this;
- }
+ return *this;
+ }
HttpStatus & clone(const HttpStatus &rhs)
{
mDetails = std::shared_ptr<Details>(new Details(*rhs.mDetails));
return *this;
}
-
- static const type_enum_t EXT_CURL_EASY = 0; ///< mStatus is an error from a curl_easy_*() call
- static const type_enum_t EXT_CURL_MULTI = 1; ///< mStatus is an error from a curl_multi_*() call
- static const type_enum_t LLCORE = 2; ///< mStatus is an HE_* error code
- ///< 100-999 directly represent HTTP status codes
- /// Test for successful status in the code regardless
- /// of error source (internal, libcurl).
- ///
- /// @return 'true' when status is successful.
- ///
- operator bool() const
- {
- return 0 == mDetails->mStatus;
- }
-
- /// Inverse of previous operator.
- ///
- /// @return 'true' on any error condition
- bool operator !() const
- {
- return 0 != mDetails->mStatus;
- }
-
- /// Equality and inequality tests to bypass bool conversion
- /// which will do the wrong thing in conditional expressions.
- bool operator==(const HttpStatus & rhs) const
- {
- return (*mDetails == *rhs.mDetails);
- }
-
- bool operator!=(const HttpStatus & rhs) const
- {
- return ! operator==(rhs);
- }
-
- /// Convert to single numeric representation. Mainly
- /// for logging or other informal purposes. Also
- /// creates an ambiguous second path to integer conversion
- /// which tends to find programming errors such as formatting
- /// the status to a stream (operator<<).
- operator U32() const;
- U32 toULong() const
- {
- return operator U32();
- }
-
- /// And to convert to a hex string.
- std::string toHex() const;
-
- /// Convert status to a string representation. For
- /// success, returns an empty string. For failure
- /// statuses, a string as appropriate for the source of
- /// the error code (libcurl easy, libcurl multi, or
- /// LLCore itself).
- std::string toString() const;
-
- /// Convert status to a compact string representation
- /// of the form: "<type>_<value>". The <type> will be
- /// one of: Core, Http, Easy, Multi, Unknown. And
- /// <value> will be an unsigned integer. More easily
- /// interpreted than the hex representation, it's still
- /// compact and easily searched.
- std::string toTerseString() const;
-
- /// Returns true if the status value represents an
- /// HTTP response status (100 - 999).
- bool isHttpStatus() const
- {
- return mDetails->mType >= type_enum_t(100) && mDetails->mType <= type_enum_t(999);
- }
-
- /// Returns true if the status is one that will be retried
- /// internally. Provided for external consumption for cases
- /// where that logic needs to be replicated. Only applies
- /// to failed statuses, successful statuses will return false.
- bool isRetryable() const;
-
- /// Returns the currently set status code as a raw number
- ///
- short getStatus() const
- {
- return mDetails->mStatus;
- }
-
- /// Returns the currently set status type
- ///
- type_enum_t getType() const
- {
- return mDetails->mType;
- }
-
- /// Returns an optional error message if one has been set.
- ///
- std::string getMessage() const
- {
- return mDetails->mMessage;
- }
-
- /// Sets an optional error message
- ///
- void setMessage(const std::string &message)
- {
- mDetails->mMessage = message;
- }
-
- /// Retrieves data about an optionally recorded SSL certificate.
- LLSD getErrorData() const
- {
- return mDetails->mErrorData;
- }
-
- /// Optionally sets an SSL certificate on this status.
- void setErrorData(LLSD data)
- {
- mDetails->mErrorData = data;
- }
+
+ static const type_enum_t EXT_CURL_EASY = 0; ///< mStatus is an error from a curl_easy_*() call
+ static const type_enum_t EXT_CURL_MULTI = 1; ///< mStatus is an error from a curl_multi_*() call
+ static const type_enum_t LLCORE = 2; ///< mStatus is an HE_* error code
+ ///< 100-999 directly represent HTTP status codes
+ /// Test for successful status in the code regardless
+ /// of error source (internal, libcurl).
+ ///
+ /// @return 'true' when status is successful.
+ ///
+ operator bool() const
+ {
+ return 0 == mDetails->mStatus;
+ }
+
+ /// Inverse of previous operator.
+ ///
+ /// @return 'true' on any error condition
+ bool operator !() const
+ {
+ return 0 != mDetails->mStatus;
+ }
+
+ /// Equality and inequality tests to bypass bool conversion
+ /// which will do the wrong thing in conditional expressions.
+ bool operator==(const HttpStatus & rhs) const
+ {
+ return (*mDetails == *rhs.mDetails);
+ }
+
+ bool operator!=(const HttpStatus & rhs) const
+ {
+ return ! operator==(rhs);
+ }
+
+ /// Convert to single numeric representation. Mainly
+ /// for logging or other informal purposes. Also
+ /// creates an ambiguous second path to integer conversion
+ /// which tends to find programming errors such as formatting
+ /// the status to a stream (operator<<).
+ operator U32() const;
+ U32 toULong() const
+ {
+ return operator U32();
+ }
+
+ /// And to convert to a hex string.
+ std::string toHex() const;
+
+ /// Convert status to a string representation. For
+ /// success, returns an empty string. For failure
+ /// statuses, a string as appropriate for the source of
+ /// the error code (libcurl easy, libcurl multi, or
+ /// LLCore itself).
+ std::string toString() const;
+
+ /// Convert status to a compact string representation
+ /// of the form: "<type>_<value>". The <type> will be
+ /// one of: Core, Http, Easy, Multi, Unknown. And
+ /// <value> will be an unsigned integer. More easily
+ /// interpreted than the hex representation, it's still
+ /// compact and easily searched.
+ std::string toTerseString() const;
+
+ /// Returns true if the status value represents an
+ /// HTTP response status (100 - 999).
+ bool isHttpStatus() const
+ {
+ return mDetails->mType >= type_enum_t(100) && mDetails->mType <= type_enum_t(999);
+ }
+
+ /// Returns true if the status is one that will be retried
+ /// internally. Provided for external consumption for cases
+ /// where that logic needs to be replicated. Only applies
+ /// to failed statuses, successful statuses will return false.
+ bool isRetryable() const;
+
+ /// Returns the currently set status code as a raw number
+ ///
+ short getStatus() const
+ {
+ return mDetails->mStatus;
+ }
+
+ /// Returns the currently set status type
+ ///
+ type_enum_t getType() const
+ {
+ return mDetails->mType;
+ }
+
+ /// Returns an optional error message if one has been set.
+ ///
+ std::string getMessage() const
+ {
+ return mDetails->mMessage;
+ }
+
+ /// Sets an optional error message
+ ///
+ void setMessage(const std::string &message)
+ {
+ mDetails->mMessage = message;
+ }
+
+ /// Retrieves data about an optionally recorded SSL certificate.
+ LLSD getErrorData() const
+ {
+ return mDetails->mErrorData;
+ }
+
+ /// Optionally sets an SSL certificate on this status.
+ void setErrorData(LLSD data)
+ {
+ mDetails->mErrorData = data;
+ }
private:
- struct Details
- {
- Details(type_enum_t type, short status):
- mType(type),
- mStatus(status),
- mMessage(),
- mErrorData()
- {}
-
- Details(const Details &rhs) :
- mType(rhs.mType),
- mStatus(rhs.mStatus),
- mMessage(rhs.mMessage),
- mErrorData(rhs.mErrorData)
- {}
+ struct Details
+ {
+ Details(type_enum_t type, short status):
+ mType(type),
+ mStatus(status),
+ mMessage(),
+ mErrorData()
+ {}
+
+ Details(const Details &rhs) :
+ mType(rhs.mType),
+ mStatus(rhs.mStatus),
+ mMessage(rhs.mMessage),
+ mErrorData(rhs.mErrorData)
+ {}
bool operator == (const Details &rhs) const
{
return (mType == rhs.mType) && (mStatus == rhs.mStatus);
}
- type_enum_t mType;
- short mStatus;
- std::string mMessage;
- LLSD mErrorData;
- };
+ type_enum_t mType;
+ short mStatus;
+ std::string mMessage;
+ LLSD mErrorData;
+ };
std::shared_ptr<Details> mDetails;
}; // end struct HttpStatus
-/// A namespace for several free methods and low level utilities.
+/// A namespace for several free methods and low level utilities.
namespace LLHttp
{
typedef std::shared_ptr<CURL> CURL_ptr;
@@ -510,4 +510,4 @@ namespace LLHttp
} // end namespace LLCore
-#endif // _LLCORE_HTTP_COMMON_H_
+#endif // _LLCORE_HTTP_COMMON_H_
diff --git a/indra/llcorehttp/httphandler.h b/indra/llcorehttp/httphandler.h
index 4cfb2598c7..1bc1e9cfac 100644
--- a/indra/llcorehttp/httphandler.h
+++ b/indra/llcorehttp/httphandler.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_HANDLER_H_
-#define _LLCORE_HTTP_HANDLER_H_
+#ifndef _LLCORE_HTTP_HANDLER_H_
+#define _LLCORE_HTTP_HANDLER_H_
#include "httpcommon.h"
@@ -55,38 +55,38 @@ class HttpResponse;
/// dangling pointer if lifetimes aren't managed correctly.
///
/// *TODO: public std::enable_shared_from_this<HttpHandler>
-class HttpHandler
+class HttpHandler
{
public:
typedef std::shared_ptr<HttpHandler> ptr_t;
typedef std::weak_ptr<HttpHandler> wptr_t;
- virtual ~HttpHandler()
- { }
+ virtual ~HttpHandler()
+ { }
- /// Method invoked during calls to @see update(). Each invocation
- /// represents the completion of some requested operation. Caller
- /// can identify the request from the handle and interrogate the
- /// response argument for success/failure, data and other information.
- ///
- /// @param handle Identifier of the request generating
- /// the notification.
- /// @param response Supplies detailed information about
- /// the request including status codes
- /// (both programming and HTTP), HTTP body
- /// data and encodings, headers, etc.
- /// The response object is refcounted and
- /// the called code may retain the object
- /// by invoking @see addRef() on it. The
- /// library itself drops all references to
- /// to object on return and never touches
- /// it again.
- ///
- virtual void onCompleted(HttpHandle handle, HttpResponse * response) = 0;
+ /// Method invoked during calls to @see update(). Each invocation
+ /// represents the completion of some requested operation. Caller
+ /// can identify the request from the handle and interrogate the
+ /// response argument for success/failure, data and other information.
+ ///
+ /// @param handle Identifier of the request generating
+ /// the notification.
+ /// @param response Supplies detailed information about
+ /// the request including status codes
+ /// (both programming and HTTP), HTTP body
+ /// data and encodings, headers, etc.
+ /// The response object is refcounted and
+ /// the called code may retain the object
+ /// by invoking @see addRef() on it. The
+ /// library itself drops all references to
+ /// to object on return and never touches
+ /// it again.
+ ///
+ virtual void onCompleted(HttpHandle handle, HttpResponse * response) = 0;
}; // end class HttpHandler
} // end namespace LLCore
-#endif // _LLCORE_HTTP_HANDLER_H_
+#endif // _LLCORE_HTTP_HANDLER_H_
diff --git a/indra/llcorehttp/httpheaders.cpp b/indra/llcorehttp/httpheaders.cpp
index f586191a7c..6f1d0db370 100644
--- a/indra/llcorehttp/httpheaders.cpp
+++ b/indra/llcorehttp/httpheaders.cpp
@@ -44,61 +44,61 @@ HttpHeaders::~HttpHeaders()
void
HttpHeaders::clear()
{
- mHeaders.clear();
+ mHeaders.clear();
}
void HttpHeaders::append(const std::string & name, const std::string & value)
{
- mHeaders.push_back(value_type(name, value));
+ mHeaders.push_back(value_type(name, value));
}
void HttpHeaders::append(const char * name, const char * value)
{
- mHeaders.push_back(value_type(name, value));
+ mHeaders.push_back(value_type(name, value));
}
void HttpHeaders::appendNormal(const char * header, size_t size)
{
- std::string name;
- std::string value;
-
- int col_pos(0);
- for (; col_pos < size; ++col_pos)
- {
- if (':' == header[col_pos])
- break;
- }
-
- if (col_pos < size)
- {
- // Looks like a header, split it and normalize.
- // Name is everything before the colon, may be zero-length.
- name.assign(header, col_pos);
-
- // Value is everything after the colon, may also be zero-length.
- const size_t val_len(size - col_pos - 1);
- if (val_len)
- {
- value.assign(header + col_pos + 1, val_len);
- }
-
- // Clean the strings
- LLStringUtil::toLower(name);
- LLStringUtil::trim(name);
- LLStringUtil::trimHead(value);
- }
- else
- {
- // Uncertain what this is, we'll pack it as
- // a name without a value. Won't clean as we don't
- // know what it is...
- name.assign(header, size);
- }
-
- mHeaders.push_back(value_type(name, value));
+ std::string name;
+ std::string value;
+
+ int col_pos(0);
+ for (; col_pos < size; ++col_pos)
+ {
+ if (':' == header[col_pos])
+ break;
+ }
+
+ if (col_pos < size)
+ {
+ // Looks like a header, split it and normalize.
+ // Name is everything before the colon, may be zero-length.
+ name.assign(header, col_pos);
+
+ // Value is everything after the colon, may also be zero-length.
+ const size_t val_len(size - col_pos - 1);
+ if (val_len)
+ {
+ value.assign(header + col_pos + 1, val_len);
+ }
+
+ // Clean the strings
+ LLStringUtil::toLower(name);
+ LLStringUtil::trim(name);
+ LLStringUtil::trimHead(value);
+ }
+ else
+ {
+ // Uncertain what this is, we'll pack it as
+ // a name without a value. Won't clean as we don't
+ // know what it is...
+ name.assign(header, size);
+ }
+
+ mHeaders.push_back(value_type(name, value));
}
@@ -106,15 +106,15 @@ void HttpHeaders::appendNormal(const char * header, size_t size)
// std::map for this in the past.
const std::string * HttpHeaders::find(const std::string &name) const
{
- const_reverse_iterator iend(rend());
- for (const_reverse_iterator iter(rbegin()); iend != iter; ++iter)
- {
- if ((*iter).first == name)
- {
- return &(*iter).second;
- }
- }
- return NULL;
+ const_reverse_iterator iend(rend());
+ for (const_reverse_iterator iter(rbegin()); iend != iter; ++iter)
+ {
+ if ((*iter).first == name)
+ {
+ return &(*iter).second;
+ }
+ }
+ return NULL;
}
void HttpHeaders::remove(const char *name)
@@ -139,50 +139,50 @@ void HttpHeaders::remove(const std::string &name)
// Standard Iterators
HttpHeaders::iterator HttpHeaders::begin()
{
- return mHeaders.begin();
+ return mHeaders.begin();
}
HttpHeaders::const_iterator HttpHeaders::begin() const
{
- return mHeaders.begin();
+ return mHeaders.begin();
}
HttpHeaders::iterator HttpHeaders::end()
{
- return mHeaders.end();
+ return mHeaders.end();
}
HttpHeaders::const_iterator HttpHeaders::end() const
{
- return mHeaders.end();
+ return mHeaders.end();
}
// Standard Reverse Iterators
HttpHeaders::reverse_iterator HttpHeaders::rbegin()
{
- return mHeaders.rbegin();
+ return mHeaders.rbegin();
}
HttpHeaders::const_reverse_iterator HttpHeaders::rbegin() const
{
- return mHeaders.rbegin();
+ return mHeaders.rbegin();
}
HttpHeaders::reverse_iterator HttpHeaders::rend()
{
- return mHeaders.rend();
+ return mHeaders.rend();
}
HttpHeaders::const_reverse_iterator HttpHeaders::rend() const
{
- return mHeaders.rend();
+ return mHeaders.rend();
}
@@ -192,7 +192,7 @@ HttpHeaders::const_reverse_iterator HttpHeaders::rend() const
//
HttpHeaders::container_t & HttpHeaders::getContainerTESTONLY()
{
- return mHeaders;
+ return mHeaders;
}
diff --git a/indra/llcorehttp/httpheaders.h b/indra/llcorehttp/httpheaders.h
index e7cf4037bf..a5ca7749b0 100644
--- a/indra/llcorehttp/httpheaders.h
+++ b/indra/llcorehttp/httpheaders.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_HEADERS_H_
-#define _LLCORE_HTTP_HEADERS_H_
+#ifndef _LLCORE_HTTP_HEADERS_H_
+#define _LLCORE_HTTP_HEADERS_H_
#include "httpcommon.h"
@@ -77,115 +77,115 @@ namespace LLCore
class HttpHeaders: private boost::noncopyable
{
public:
- typedef std::pair<std::string, std::string> header_t;
- typedef std::vector<header_t> container_t;
- typedef container_t::iterator iterator;
- typedef container_t::const_iterator const_iterator;
- typedef container_t::reverse_iterator reverse_iterator;
- typedef container_t::const_reverse_iterator const_reverse_iterator;
- typedef container_t::value_type value_type;
- typedef container_t::size_type size_type;
+ typedef std::pair<std::string, std::string> header_t;
+ typedef std::vector<header_t> container_t;
+ typedef container_t::iterator iterator;
+ typedef container_t::const_iterator const_iterator;
+ typedef container_t::reverse_iterator reverse_iterator;
+ typedef container_t::const_reverse_iterator const_reverse_iterator;
+ typedef container_t::value_type value_type;
+ typedef container_t::size_type size_type;
typedef std::shared_ptr<HttpHeaders> ptr_t;
public:
- /// @post In addition to the instance, caller has a refcount
- /// to the instance. A call to @see release() will destroy
- /// the instance.
- HttpHeaders();
- virtual ~HttpHeaders(); // Use release()
+ /// @post In addition to the instance, caller has a refcount
+ /// to the instance. A call to @see release() will destroy
+ /// the instance.
+ HttpHeaders();
+ virtual ~HttpHeaders(); // Use release()
- //typedef LLCoreInt::IntrusivePtr<HttpHeaders> ptr_t;
+ //typedef LLCoreInt::IntrusivePtr<HttpHeaders> ptr_t;
protected:
- HttpHeaders(const HttpHeaders &); // Not defined
- void operator=(const HttpHeaders &); // Not defined
+ HttpHeaders(const HttpHeaders &); // Not defined
+ void operator=(const HttpHeaders &); // Not defined
public:
- // Empty the list of headers.
- void clear();
-
- // Append a name/value pair supplied as either std::strings
- // or NUL-terminated char * to the header list. No normalization
- // is performed on the strings. No conformance test is
- // performed (names may contain spaces, colons, etc.).
- //
- void append(const std::string & name, const std::string & value);
- void append(const char * name, const char * value);
-
- // Extract a name/value pair from a raw byte array using
- // the first colon character as a separator. Input string
- // does not need to be NUL-terminated. Resulting name/value
- // pair is appended to the header list.
- //
- // Normalization is performed on the name/value pair as
- // follows:
- // - name is lower-cased according to mostly ASCII rules
- // - name is left- and right-trimmed of spaces and tabs
- // - value is left-trimmed of spaces and tabs
- // - either or both of name and value may be zero-length
- //
- // By convention, headers read from the wire will be normalized
- // in this fashion prior to delivery to any HttpHandler code.
- // Headers to be written to the wire are left as appended to
- // the list.
- void appendNormal(const char * header, size_t size);
-
- // Perform a simple, case-sensitive search of the header list
- // returning a pointer to the value of the last matching header
- // in the header list. If none is found, a NULL pointer is returned.
- //
- // Any pointer returned references objects in the container itself
- // and will have the same lifetime as this class. If you want
- // the value beyond the lifetime of this instance, make a copy.
- //
- // @arg name C-style string giving the name of a header
- // to search. The comparison is case-sensitive
- // though list entries may have been normalized
- // to lower-case.
- //
- // @return NULL if the header wasn't found otherwise
- // a pointer to a std::string in the container.
- // Pointer is valid only for the lifetime of
- // the container or until container is modifed.
- const std::string * find(const std::string &name) const;
- const std::string * find(const char * name) const
- {
- return find(std::string(name));
- }
+ // Empty the list of headers.
+ void clear();
+
+ // Append a name/value pair supplied as either std::strings
+ // or NUL-terminated char * to the header list. No normalization
+ // is performed on the strings. No conformance test is
+ // performed (names may contain spaces, colons, etc.).
+ //
+ void append(const std::string & name, const std::string & value);
+ void append(const char * name, const char * value);
+
+ // Extract a name/value pair from a raw byte array using
+ // the first colon character as a separator. Input string
+ // does not need to be NUL-terminated. Resulting name/value
+ // pair is appended to the header list.
+ //
+ // Normalization is performed on the name/value pair as
+ // follows:
+ // - name is lower-cased according to mostly ASCII rules
+ // - name is left- and right-trimmed of spaces and tabs
+ // - value is left-trimmed of spaces and tabs
+ // - either or both of name and value may be zero-length
+ //
+ // By convention, headers read from the wire will be normalized
+ // in this fashion prior to delivery to any HttpHandler code.
+ // Headers to be written to the wire are left as appended to
+ // the list.
+ void appendNormal(const char * header, size_t size);
+
+ // Perform a simple, case-sensitive search of the header list
+ // returning a pointer to the value of the last matching header
+ // in the header list. If none is found, a NULL pointer is returned.
+ //
+ // Any pointer returned references objects in the container itself
+ // and will have the same lifetime as this class. If you want
+ // the value beyond the lifetime of this instance, make a copy.
+ //
+ // @arg name C-style string giving the name of a header
+ // to search. The comparison is case-sensitive
+ // though list entries may have been normalized
+ // to lower-case.
+ //
+ // @return NULL if the header wasn't found otherwise
+ // a pointer to a std::string in the container.
+ // Pointer is valid only for the lifetime of
+ // the container or until container is modifed.
+ const std::string * find(const std::string &name) const;
+ const std::string * find(const char * name) const
+ {
+ return find(std::string(name));
+ }
// Remove the header from the list if found.
- //
+ //
void remove(const std::string &name);
void remove(const char *name);
- // Count of headers currently in the list.
- size_type size() const
- {
- return mHeaders.size();
- }
+ // Count of headers currently in the list.
+ size_type size() const
+ {
+ return mHeaders.size();
+ }
- // Standard std::vector-based forward iterators.
- iterator begin();
- const_iterator begin() const;
- iterator end();
- const_iterator end() const;
+ // Standard std::vector-based forward iterators.
+ iterator begin();
+ const_iterator begin() const;
+ iterator end();
+ const_iterator end() const;
- // Standard std::vector-based reverse iterators.
- reverse_iterator rbegin();
- const_reverse_iterator rbegin() const;
- reverse_iterator rend();
- const_reverse_iterator rend() const;
+ // Standard std::vector-based reverse iterators.
+ reverse_iterator rbegin();
+ const_reverse_iterator rbegin() const;
+ reverse_iterator rend();
+ const_reverse_iterator rend() const;
public:
- // For unit tests only - not a public API
- container_t & getContainerTESTONLY();
-
+ // For unit tests only - not a public API
+ container_t & getContainerTESTONLY();
+
protected:
- container_t mHeaders;
-
+ container_t mHeaders;
+
}; // end class HttpHeaders
} // end namespace LLCore
-#endif // _LLCORE_HTTP_HEADERS_H_
+#endif // _LLCORE_HTTP_HEADERS_H_
diff --git a/indra/llcorehttp/httpoptions.cpp b/indra/llcorehttp/httpoptions.cpp
index c6365e5091..d85f6039b1 100644
--- a/indra/llcorehttp/httpoptions.cpp
+++ b/indra/llcorehttp/httpoptions.cpp
@@ -57,66 +57,66 @@ HttpOptions::~HttpOptions()
void HttpOptions::setWantHeaders(bool wanted)
{
- mWantHeaders = wanted;
+ mWantHeaders = wanted;
}
void HttpOptions::setTrace(long level)
{
- mTracing = int(level);
+ mTracing = int(level);
}
void HttpOptions::setTimeout(unsigned int timeout)
{
- mTimeout = timeout;
+ mTimeout = timeout;
}
void HttpOptions::setTransferTimeout(unsigned int timeout)
{
- mTransferTimeout = timeout;
+ mTransferTimeout = timeout;
}
void HttpOptions::setRetries(unsigned int retries)
{
- mRetries = retries;
+ mRetries = retries;
}
void HttpOptions::setMinBackoff(HttpTime delay)
{
- mMinRetryBackoff = delay;
+ mMinRetryBackoff = delay;
}
void HttpOptions::setMaxBackoff(HttpTime delay)
{
- mMaxRetryBackoff = delay;
+ mMaxRetryBackoff = delay;
}
void HttpOptions::setUseRetryAfter(bool use_retry)
{
- mUseRetryAfter = use_retry;
+ mUseRetryAfter = use_retry;
}
void HttpOptions::setFollowRedirects(bool follow_redirect)
{
- mFollowRedirects = follow_redirect;
+ mFollowRedirects = follow_redirect;
}
void HttpOptions::setSSLVerifyPeer(bool verify)
{
- mVerifyPeer = verify;
+ mVerifyPeer = verify;
}
void HttpOptions::setSSLVerifyHost(bool verify)
{
- mVerifyHost = verify;
+ mVerifyHost = verify;
}
void HttpOptions::setDNSCacheTimeout(int timeout)
{
- mDNSCacheTimeout = timeout;
+ mDNSCacheTimeout = timeout;
}
void HttpOptions::setHeadersOnly(bool nobody)
diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h
index fa993c857b..56a28013cb 100644
--- a/indra/llcorehttp/httpoptions.h
+++ b/indra/llcorehttp/httpoptions.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_OPTIONS_H_
-#define _LLCORE_HTTP_OPTIONS_H_
+#ifndef _LLCORE_HTTP_OPTIONS_H_
+#define _LLCORE_HTTP_OPTIONS_H_
#include "httpcommon.h"
@@ -58,118 +58,118 @@ namespace LLCore
class HttpOptions : private boost::noncopyable
{
public:
- HttpOptions();
+ HttpOptions();
- typedef std::shared_ptr<HttpOptions> ptr_t;
+ typedef std::shared_ptr<HttpOptions> ptr_t;
- virtual ~HttpOptions(); // Use release()
+ virtual ~HttpOptions(); // Use release()
protected:
-
- HttpOptions(const HttpOptions &); // Not defined
- void operator=(const HttpOptions &); // Not defined
+
+ HttpOptions(const HttpOptions &); // Not defined
+ void operator=(const HttpOptions &); // Not defined
public:
- // Default: false
- void setWantHeaders(bool wanted);
- bool getWantHeaders() const
- {
- return mWantHeaders;
- }
-
- // Default: 0
- void setTrace(int long);
- int getTrace() const
- {
- return mTracing;
- }
-
- // Default: 30
- void setTimeout(unsigned int timeout);
- unsigned int getTimeout() const
- {
- return mTimeout;
- }
-
- // Default: 0
- void setTransferTimeout(unsigned int timeout);
- unsigned int getTransferTimeout() const
- {
- return mTransferTimeout;
- }
-
- /// Sets the number of retries on an LLCore::HTTPRequest before the
+ // Default: false
+ void setWantHeaders(bool wanted);
+ bool getWantHeaders() const
+ {
+ return mWantHeaders;
+ }
+
+ // Default: 0
+ void setTrace(int long);
+ int getTrace() const
+ {
+ return mTracing;
+ }
+
+ // Default: 30
+ void setTimeout(unsigned int timeout);
+ unsigned int getTimeout() const
+ {
+ return mTimeout;
+ }
+
+ // Default: 0
+ void setTransferTimeout(unsigned int timeout);
+ unsigned int getTransferTimeout() const
+ {
+ return mTransferTimeout;
+ }
+
+ /// Sets the number of retries on an LLCore::HTTPRequest before the
/// request fails.
- // Default: 5
- void setRetries(unsigned int retries);
- unsigned int getRetries() const
- {
- return mRetries;
- }
-
- /// Sets minimal delay before request retries. In microseconds.
- /// HttpPolicy will increase delay from min to max with each retry
- // Default: 1 000 000 mcs
- void setMinBackoff(HttpTime delay);
- HttpTime getMinBackoff() const
- {
- return mMinRetryBackoff;
- }
-
- /// Sets maximum delay before request retries. In microseconds.
- /// HttpPolicy will increase delay from min to max with each retry
- // Default: 5 000 000 mcs
- void setMaxBackoff(HttpTime delay);
- HttpTime getMaxBackoff() const
- {
- return mMaxRetryBackoff;
- }
-
- // Default: true
- void setUseRetryAfter(bool use_retry);
- bool getUseRetryAfter() const
- {
- return mUseRetryAfter;
- }
-
- /// Instructs the LLCore::HTTPRequest to follow redirects
- /// Default: false
- void setFollowRedirects(bool follow_redirect);
- bool getFollowRedirects() const
- {
- return mFollowRedirects;
- }
+ // Default: 5
+ void setRetries(unsigned int retries);
+ unsigned int getRetries() const
+ {
+ return mRetries;
+ }
+
+ /// Sets minimal delay before request retries. In microseconds.
+ /// HttpPolicy will increase delay from min to max with each retry
+ // Default: 1 000 000 mcs
+ void setMinBackoff(HttpTime delay);
+ HttpTime getMinBackoff() const
+ {
+ return mMinRetryBackoff;
+ }
+
+ /// Sets maximum delay before request retries. In microseconds.
+ /// HttpPolicy will increase delay from min to max with each retry
+ // Default: 5 000 000 mcs
+ void setMaxBackoff(HttpTime delay);
+ HttpTime getMaxBackoff() const
+ {
+ return mMaxRetryBackoff;
+ }
+
+ // Default: true
+ void setUseRetryAfter(bool use_retry);
+ bool getUseRetryAfter() const
+ {
+ return mUseRetryAfter;
+ }
+
+ /// Instructs the LLCore::HTTPRequest to follow redirects
+ /// Default: false
+ void setFollowRedirects(bool follow_redirect);
+ bool getFollowRedirects() const
+ {
+ return mFollowRedirects;
+ }
/// Instructs the LLCore::HTTPRequest to verify that the exchanged security
- /// certificate is authentic.
+ /// certificate is authentic.
/// Default: sDefaultVerifyPeer
- void setSSLVerifyPeer(bool verify);
- bool getSSLVerifyPeer() const
- {
- return mVerifyPeer;
- }
+ void setSSLVerifyPeer(bool verify);
+ bool getSSLVerifyPeer() const
+ {
+ return mVerifyPeer;
+ }
- /// Instructs the LLCore::HTTPRequest to verify that the name in the
+ /// Instructs the LLCore::HTTPRequest to verify that the name in the
/// security certificate matches the name of the host contacted.
/// Default: false
- void setSSLVerifyHost(bool verify);
- bool getSSLVerifyHost() const
- {
- return mVerifyHost;
- }
+ void setSSLVerifyHost(bool verify);
+ bool getSSLVerifyHost() const
+ {
+ return mVerifyHost;
+ }
/// Sets the time for DNS name caching in seconds. Setting this value
- /// to 0 will disable name caching. Setting this value to -1 causes the
+ /// to 0 will disable name caching. Setting this value to -1 causes the
/// name cache to never time out.
/// Default: -1
- void setDNSCacheTimeout(int timeout);
- int getDNSCacheTimeout() const
- {
- return mDNSCacheTimeout;
- }
+ void setDNSCacheTimeout(int timeout);
+ int getDNSCacheTimeout() const
+ {
+ return mDNSCacheTimeout;
+ }
- /// Retrieve only the headers and status from the request. Setting this
+ /// Retrieve only the headers and status from the request. Setting this
/// to true implies setWantHeaders(true) as well.
/// Default: false
void setHeadersOnly(bool nobody);
@@ -178,26 +178,26 @@ public:
return mNoBody;
}
- /// Sets default behavior for verifying that the name in the
+ /// Sets default behavior for verifying that the name in the
/// security certificate matches the name of the host contacted.
/// Defaults false if not set, but should be set according to
/// viewer's initialization options and command argunments, see
/// NoVerifySSLCert
static void setDefaultSSLVerifyPeer(bool verify);
-
+
protected:
- bool mWantHeaders;
- int mTracing;
- unsigned int mTimeout;
- unsigned int mTransferTimeout;
- unsigned int mRetries;
- HttpTime mMinRetryBackoff;
- HttpTime mMaxRetryBackoff;
- bool mUseRetryAfter;
- bool mFollowRedirects;
- bool mVerifyPeer;
- bool mVerifyHost;
- int mDNSCacheTimeout;
+ bool mWantHeaders;
+ int mTracing;
+ unsigned int mTimeout;
+ unsigned int mTransferTimeout;
+ unsigned int mRetries;
+ HttpTime mMinRetryBackoff;
+ HttpTime mMaxRetryBackoff;
+ bool mUseRetryAfter;
+ bool mFollowRedirects;
+ bool mVerifyPeer;
+ bool mVerifyHost;
+ int mDNSCacheTimeout;
bool mNoBody;
static bool sDefaultVerifyPeer;
@@ -206,4 +206,4 @@ protected:
} // end namespace HttpOptions
-#endif // _LLCORE_HTTP_OPTIONS_H_
+#endif // _LLCORE_HTTP_OPTIONS_H_
diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp
index de3854a101..216d407deb 100644
--- a/indra/llcorehttp/httprequest.cpp
+++ b/indra/llcorehttp/httprequest.cpp
@@ -54,13 +54,13 @@ namespace LLCore
HttpRequest::HttpRequest()
- : mReplyQueue(),
- mRequestQueue(NULL)
+ : mReplyQueue(),
+ mRequestQueue(NULL)
{
- mRequestQueue = HttpRequestQueue::instanceOf();
- mRequestQueue->addRef();
+ mRequestQueue = HttpRequestQueue::instanceOf();
+ mRequestQueue->addRef();
- mReplyQueue.reset( new HttpReplyQueue() );
+ mReplyQueue.reset( new HttpReplyQueue() );
HTTPStats::instance().recordHTTPRequest();
}
@@ -68,11 +68,11 @@ HttpRequest::HttpRequest()
HttpRequest::~HttpRequest()
{
- if (mRequestQueue)
- {
- mRequestQueue->release();
- mRequestQueue = NULL;
- }
+ if (mRequestQueue)
+ {
+ mRequestQueue->release();
+ mRequestQueue = NULL;
+ }
mReplyQueue.reset();
}
@@ -85,88 +85,88 @@ HttpRequest::~HttpRequest()
HttpRequest::policy_t HttpRequest::createPolicyClass()
{
- if (HttpService::RUNNING == HttpService::instanceOf()->getState())
- {
- return 0;
- }
- return HttpService::instanceOf()->createPolicyClass();
+ if (HttpService::RUNNING == HttpService::instanceOf()->getState())
+ {
+ return 0;
+ }
+ return HttpService::instanceOf()->createPolicyClass();
}
HttpStatus HttpRequest::setStaticPolicyOption(EPolicyOption opt, policy_t pclass,
- long value, long * ret_value)
+ long value, long * ret_value)
{
- if (HttpService::RUNNING == HttpService::instanceOf()->getState())
- {
- return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
- }
- return HttpService::instanceOf()->setPolicyOption(opt, pclass, value, ret_value);
+ if (HttpService::RUNNING == HttpService::instanceOf()->getState())
+ {
+ return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
+ }
+ return HttpService::instanceOf()->setPolicyOption(opt, pclass, value, ret_value);
}
HttpStatus HttpRequest::setStaticPolicyOption(EPolicyOption opt, policy_t pclass,
- const std::string & value, std::string * ret_value)
+ const std::string & value, std::string * ret_value)
{
- if (HttpService::RUNNING == HttpService::instanceOf()->getState())
- {
- return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
- }
- return HttpService::instanceOf()->setPolicyOption(opt, pclass, value, ret_value);
+ if (HttpService::RUNNING == HttpService::instanceOf()->getState())
+ {
+ return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
+ }
+ return HttpService::instanceOf()->setPolicyOption(opt, pclass, value, ret_value);
}
HttpStatus HttpRequest::setStaticPolicyOption(EPolicyOption opt, policy_t pclass, policyCallback_t value, policyCallback_t * ret_value)
{
- if (HttpService::RUNNING == HttpService::instanceOf()->getState())
- {
- return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
- }
+ if (HttpService::RUNNING == HttpService::instanceOf()->getState())
+ {
+ return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
+ }
- return HttpService::instanceOf()->setPolicyOption(opt, pclass, value, ret_value);
+ return HttpService::instanceOf()->setPolicyOption(opt, pclass, value, ret_value);
}
HttpHandle HttpRequest::setPolicyOption(EPolicyOption opt, policy_t pclass,
- long value, HttpHandler::ptr_t handler)
+ long value, HttpHandler::ptr_t handler)
{
- HttpStatus status;
+ HttpStatus status;
HttpOpSetGet::ptr_t op(new HttpOpSetGet());
- if (! (status = op->setupSet(opt, pclass, value)))
- {
- mLastReqStatus = status;
+ if (! (status = op->setupSet(opt, pclass, value)))
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
- op->setReplyPath(mReplyQueue, handler);
- if (! (status = mRequestQueue->addOp(op))) // transfers refcount
- {
- mLastReqStatus = status;
+ }
+ op->setReplyPath(mReplyQueue, handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
-
- mLastReqStatus = status;
- return op->getHandle();
+ }
+
+ mLastReqStatus = status;
+ return op->getHandle();
}
HttpHandle HttpRequest::setPolicyOption(EPolicyOption opt, policy_t pclass,
- const std::string & value, HttpHandler::ptr_t handler)
+ const std::string & value, HttpHandler::ptr_t handler)
{
- HttpStatus status;
+ HttpStatus status;
- HttpOpSetGet::ptr_t op (new HttpOpSetGet());
- if (! (status = op->setupSet(opt, pclass, value)))
- {
- mLastReqStatus = status;
+ HttpOpSetGet::ptr_t op (new HttpOpSetGet());
+ if (! (status = op->setupSet(opt, pclass, value)))
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
- op->setReplyPath(mReplyQueue, handler);
- if (! (status = mRequestQueue->addOp(op))) // transfers refcount
- {
- mLastReqStatus = status;
+ }
+ op->setReplyPath(mReplyQueue, handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
-
- mLastReqStatus = status;
- return op->getHandle();
+ }
+
+ mLastReqStatus = status;
+ return op->getHandle();
}
@@ -177,116 +177,116 @@ HttpHandle HttpRequest::setPolicyOption(EPolicyOption opt, policy_t pclass,
HttpStatus HttpRequest::getStatus() const
{
- return mLastReqStatus;
+ return mLastReqStatus;
}
HttpHandle HttpRequest::requestGet(policy_t policy_id,
- const std::string & url,
+ const std::string & url,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers,
- HttpHandler::ptr_t user_handler)
+ const HttpHeaders::ptr_t & headers,
+ HttpHandler::ptr_t user_handler)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- HttpStatus status;
+ HttpStatus status;
- HttpOpRequest::ptr_t op(new HttpOpRequest());
- if (! (status = op->setupGet(policy_id, url, options, headers)))
- {
- mLastReqStatus = status;
+ HttpOpRequest::ptr_t op(new HttpOpRequest());
+ if (! (status = op->setupGet(policy_id, url, options, headers)))
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
- op->setReplyPath(mReplyQueue, user_handler);
- if (! (status = mRequestQueue->addOp(op))) // transfers refcount
- {
- mLastReqStatus = status;
+ }
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
-
- mLastReqStatus = status;
+ }
+
+ mLastReqStatus = status;
return op->getHandle();
}
HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id,
- const std::string & url,
- size_t offset,
- size_t len,
+ const std::string & url,
+ size_t offset,
+ size_t len,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers,
- HttpHandler::ptr_t user_handler)
+ const HttpHeaders::ptr_t & headers,
+ HttpHandler::ptr_t user_handler)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- HttpStatus status;
+ HttpStatus status;
- HttpOpRequest::ptr_t op(new HttpOpRequest());
- if (! (status = op->setupGetByteRange(policy_id, url, offset, len, options, headers)))
- {
- mLastReqStatus = status;
+ HttpOpRequest::ptr_t op(new HttpOpRequest());
+ if (! (status = op->setupGetByteRange(policy_id, url, offset, len, options, headers)))
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
- op->setReplyPath(mReplyQueue, user_handler);
- if (! (status = mRequestQueue->addOp(op))) // transfers refcount
- {
- mLastReqStatus = status;
+ }
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
-
- mLastReqStatus = status;
- return op->getHandle();
+ }
+
+ mLastReqStatus = status;
+ return op->getHandle();
}
HttpHandle HttpRequest::requestPost(policy_t policy_id,
- const std::string & url,
- BufferArray * body,
+ const std::string & url,
+ BufferArray * body,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers,
- HttpHandler::ptr_t user_handler)
+ const HttpHeaders::ptr_t & headers,
+ HttpHandler::ptr_t user_handler)
{
- HttpStatus status;
+ HttpStatus status;
- HttpOpRequest::ptr_t op(new HttpOpRequest());
- if (! (status = op->setupPost(policy_id, url, body, options, headers)))
- {
- mLastReqStatus = status;
+ HttpOpRequest::ptr_t op(new HttpOpRequest());
+ if (! (status = op->setupPost(policy_id, url, body, options, headers)))
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
- op->setReplyPath(mReplyQueue, user_handler);
- if (! (status = mRequestQueue->addOp(op))) // transfers refcount
- {
- mLastReqStatus = status;
+ }
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
-
- mLastReqStatus = status;
- return op->getHandle();
+ }
+
+ mLastReqStatus = status;
+ return op->getHandle();
}
HttpHandle HttpRequest::requestPut(policy_t policy_id,
- const std::string & url,
- BufferArray * body,
+ const std::string & url,
+ BufferArray * body,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers,
- HttpHandler::ptr_t user_handler)
+ const HttpHeaders::ptr_t & headers,
+ HttpHandler::ptr_t user_handler)
{
- HttpStatus status;
+ HttpStatus status;
- HttpOpRequest::ptr_t op (new HttpOpRequest());
- if (! (status = op->setupPut(policy_id, url, body, options, headers)))
- {
- mLastReqStatus = status;
+ HttpOpRequest::ptr_t op (new HttpOpRequest());
+ if (! (status = op->setupPut(policy_id, url, body, options, headers)))
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
- op->setReplyPath(mReplyQueue, user_handler);
- if (! (status = mRequestQueue->addOp(op))) // transfers refcount
- {
- mLastReqStatus = status;
+ }
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
-
- mLastReqStatus = status;
+ }
+
+ mLastReqStatus = status;
return op->getHandle();
}
@@ -305,7 +305,7 @@ HttpHandle HttpRequest::requestDelete(policy_t policy_id,
return LLCORE_HTTP_HANDLE_INVALID;
}
op->setReplyPath(mReplyQueue, user_handler);
- if (!(status = mRequestQueue->addOp(op))) // transfers refcount
+ if (!(status = mRequestQueue->addOp(op))) // transfers refcount
{
mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
@@ -331,7 +331,7 @@ HttpHandle HttpRequest::requestPatch(policy_t policy_id,
return LLCORE_HTTP_HANDLE_INVALID;
}
op->setReplyPath(mReplyQueue, user_handler);
- if (!(status = mRequestQueue->addOp(op))) // transfers refcount
+ if (!(status = mRequestQueue->addOp(op))) // transfers refcount
{
mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
@@ -356,7 +356,7 @@ HttpHandle HttpRequest::requestCopy(policy_t policy_id,
return LLCORE_HTTP_HANDLE_INVALID;
}
op->setReplyPath(mReplyQueue, user_handler);
- if (!(status = mRequestQueue->addOp(op))) // transfers refcount
+ if (!(status = mRequestQueue->addOp(op))) // transfers refcount
{
mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
@@ -382,7 +382,7 @@ HttpHandle HttpRequest::requestMove(policy_t policy_id,
return LLCORE_HTTP_HANDLE_INVALID;
}
op->setReplyPath(mReplyQueue, user_handler);
- if (!(status = mRequestQueue->addOp(op))) // transfers refcount
+ if (!(status = mRequestQueue->addOp(op))) // transfers refcount
{
mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
@@ -395,61 +395,61 @@ HttpHandle HttpRequest::requestMove(policy_t policy_id,
HttpHandle HttpRequest::requestNoOp(HttpHandler::ptr_t user_handler)
{
- HttpStatus status;
+ HttpStatus status;
- HttpOperation::ptr_t op (new HttpOpNull());
- op->setReplyPath(mReplyQueue, user_handler);
- if (! (status = mRequestQueue->addOp(op))) // transfers refcount
- {
- mLastReqStatus = status;
+ HttpOperation::ptr_t op (new HttpOpNull());
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
+ }
- mLastReqStatus = status;
- return op->getHandle();
+ mLastReqStatus = status;
+ return op->getHandle();
}
HttpStatus HttpRequest::update(long usecs)
{
- HttpOperation::ptr_t op;
-
- if (usecs)
- {
- const HttpTime limit(totalTime() + HttpTime(usecs));
- while (limit >= totalTime() && (op = mReplyQueue->fetchOp()))
- {
- // Process operation
- op->visitNotifier(this);
-
- // We're done with the operation
+ HttpOperation::ptr_t op;
+
+ if (usecs)
+ {
+ const HttpTime limit(totalTime() + HttpTime(usecs));
+ while (limit >= totalTime() && (op = mReplyQueue->fetchOp()))
+ {
+ // Process operation
+ op->visitNotifier(this);
+
+ // We're done with the operation
op.reset();
- }
- }
- else
- {
- // Same as above, just no time limit
- HttpReplyQueue::OpContainer replies;
- mReplyQueue->fetchAll(replies);
- if (! replies.empty())
- {
- for (HttpReplyQueue::OpContainer::iterator iter(replies.begin());
- replies.end() != iter;
- ++iter)
- {
- // Swap op pointer for NULL;
+ }
+ }
+ else
+ {
+ // Same as above, just no time limit
+ HttpReplyQueue::OpContainer replies;
+ mReplyQueue->fetchAll(replies);
+ if (! replies.empty())
+ {
+ for (HttpReplyQueue::OpContainer::iterator iter(replies.begin());
+ replies.end() != iter;
+ ++iter)
+ {
+ // Swap op pointer for NULL;
op.reset();
op.swap(*iter);
-
- // Process operation
- op->visitNotifier(this);
-
- // We're done with the operation
- }
- }
- }
-
- return HttpStatus();
+
+ // Process operation
+ op->visitNotifier(this);
+
+ // We're done with the operation
+ }
+ }
+ }
+
+ return HttpStatus();
}
@@ -461,18 +461,18 @@ HttpStatus HttpRequest::update(long usecs)
HttpHandle HttpRequest::requestCancel(HttpHandle request, HttpHandler::ptr_t user_handler)
{
- HttpStatus status;
+ HttpStatus status;
- HttpOperation::ptr_t op(new HttpOpCancel(request));
- op->setReplyPath(mReplyQueue, user_handler);
- if (! (status = mRequestQueue->addOp(op))) // transfers refcount
- {
- mLastReqStatus = status;
+ HttpOperation::ptr_t op(new HttpOpCancel(request));
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ mLastReqStatus = status;
return LLCORE_HTTP_HANDLE_INVALID;
- }
+ }
- mLastReqStatus = status;
- return op->getHandle();
+ mLastReqStatus = status;
+ return op->getHandle();
}
@@ -482,82 +482,82 @@ HttpHandle HttpRequest::requestCancel(HttpHandle request, HttpHandler::ptr_t use
HttpStatus HttpRequest::createService()
{
- HttpStatus status;
-
- if (! has_inited)
- {
- HttpRequestQueue::init();
- HttpRequestQueue * rq = HttpRequestQueue::instanceOf();
- HttpService::init(rq);
- has_inited = true;
- }
-
- return status;
+ HttpStatus status;
+
+ if (! has_inited)
+ {
+ HttpRequestQueue::init();
+ HttpRequestQueue * rq = HttpRequestQueue::instanceOf();
+ HttpService::init(rq);
+ has_inited = true;
+ }
+
+ return status;
}
HttpStatus HttpRequest::destroyService()
{
- HttpStatus status;
-
- if (has_inited)
- {
- HttpService::term();
- HttpRequestQueue::term();
- has_inited = false;
- }
-
- return status;
+ HttpStatus status;
+
+ if (has_inited)
+ {
+ HttpService::term();
+ HttpRequestQueue::term();
+ has_inited = false;
+ }
+
+ return status;
}
HttpStatus HttpRequest::startThread()
{
- HttpStatus status;
+ HttpStatus status;
+
+ HttpService::instanceOf()->startThread();
- HttpService::instanceOf()->startThread();
-
- return status;
+ return status;
}
HttpHandle HttpRequest::requestStopThread(HttpHandler::ptr_t user_handler)
{
- HttpStatus status;
- HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+ HttpStatus status;
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
- HttpOperation::ptr_t op(new HttpOpStop());
- op->setReplyPath(mReplyQueue, user_handler);
- if (! (status = mRequestQueue->addOp(op))) // transfers refcount
- {
- mLastReqStatus = status;
- return handle;
- }
+ HttpOperation::ptr_t op(new HttpOpStop());
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ mLastReqStatus = status;
+ return handle;
+ }
- mLastReqStatus = status;
- handle = op->getHandle();
+ mLastReqStatus = status;
+ handle = op->getHandle();
- return handle;
+ return handle;
}
HttpHandle HttpRequest::requestSpin(int mode)
{
- HttpStatus status;
- HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+ HttpStatus status;
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
- HttpOperation::ptr_t op(new HttpOpSpin(mode));
+ HttpOperation::ptr_t op(new HttpOpSpin(mode));
op->setReplyPath(mReplyQueue, HttpHandler::ptr_t());
- if (! (status = mRequestQueue->addOp(op))) // transfers refcount
- {
- mLastReqStatus = status;
- return handle;
- }
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ mLastReqStatus = status;
+ return handle;
+ }
- mLastReqStatus = status;
- handle = op->getHandle();
+ mLastReqStatus = status;
+ handle = op->getHandle();
- return handle;
+ return handle;
}
diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h
index 857a034a7b..e6e051410e 100644
--- a/indra/llcorehttp/httprequest.h
+++ b/indra/llcorehttp/httprequest.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_REQUEST_H_
-#define _LLCORE_HTTP_REQUEST_H_
+#ifndef _LLCORE_HTTP_REQUEST_H_
+#define _LLCORE_HTTP_REQUEST_H_
#include "httpcommon.h"
@@ -86,398 +86,398 @@ class BufferArray;
class HttpRequest
{
public:
- HttpRequest();
- virtual ~HttpRequest();
+ HttpRequest();
+ virtual ~HttpRequest();
private:
- HttpRequest(const HttpRequest &); // Disallowed
- void operator=(const HttpRequest &); // Disallowed
+ HttpRequest(const HttpRequest &); // Disallowed
+ void operator=(const HttpRequest &); // Disallowed
public:
- typedef unsigned int policy_t;
-
- typedef std::shared_ptr<HttpRequest> ptr_t;
+ typedef unsigned int policy_t;
+
+ typedef std::shared_ptr<HttpRequest> ptr_t;
typedef std::weak_ptr<HttpRequest> wptr_t;
public:
- /// @name PolicyMethods
- /// @{
-
- /// Represents a default, catch-all policy class that guarantees
- /// eventual service for any HTTP request.
- static const policy_t DEFAULT_POLICY_ID = 0;
- static const policy_t INVALID_POLICY_ID = 0xFFFFFFFFU;
- static const policy_t GLOBAL_POLICY_ID = 0xFFFFFFFEU;
-
- /// Create a new policy class into which requests can be made.
- ///
- /// All class creation must occur before threads are started and
- /// transport begins. Policy classes are limited to a small value.
- /// Currently that limit is the default class + 1.
- ///
- /// @return If positive, the policy_id used to reference
- /// the class in other methods. If 0, requests
- /// for classes have exceeded internal limits
- /// or caller has tried to create a class after
- /// threads have been started. Caller must fallback
- /// and recover.
- ///
- static policy_t createPolicyClass();
-
- enum EPolicyOption
- {
- /// Maximum number of connections the library will use to
- /// perform operations. This is somewhat soft as the underlying
- /// transport will cache some connections (up to 5).
-
- /// A long value setting the maximum number of connections
- /// allowed over all policy classes. Note that this will be
- /// a somewhat soft value. There may be an additional five
- /// connections per policy class depending upon runtime
- /// behavior.
- ///
- /// Both global and per-class
- PO_CONNECTION_LIMIT,
-
- /// Limits the number of connections used for a single
- /// literal address/port pair within the class.
- ///
- /// Per-class only
- PO_PER_HOST_CONNECTION_LIMIT,
-
- /// String containing a system-appropriate directory name
- /// where SSL certs are stored.
- ///
- /// Global only
- PO_CA_PATH,
-
- /// String giving a full path to a file containing SSL certs.
- ///
- /// Global only
- PO_CA_FILE,
-
- /// String of host/port to use as simple HTTP proxy. This is
- /// going to change in the future into something more elaborate
- /// that may support richer schemes.
- ///
- /// Global only
- PO_HTTP_PROXY,
-
- /// Long value that if non-zero enables the use of the
- /// traditional LLProxy code for http/socks5 support. If
- /// enabled, has priority over GP_HTTP_PROXY.
- ///
- /// Global only
- PO_LLPROXY,
-
- /// Long value setting the logging trace level for the
- /// library. Possible values are:
- /// 0 - No tracing (default)
- /// 1 - Basic tracing of request start, stop and major events.
- /// 2 - Connection, header and payload size information from
- /// HTTP transactions.
- /// 3 - Partial logging of payload itself.
- ///
- /// These values are also used in the trace modes for
- /// individual requests in HttpOptions. Also be aware that
- /// tracing tends to impact performance of the viewer.
- ///
- /// Global only
- PO_TRACE,
-
- /// If greater than 1, suitable requests are allowed to
- /// pipeline on their connections when they ask for it.
- /// Value gives the maximum number of outstanding requests
- /// on a connection.
- ///
- /// There is some interaction between PO_CONNECTION_LIMIT,
- /// PO_PER_HOST_CONNECTION_LIMIT, and PO_PIPELINING_DEPTH.
- /// When PIPELINING_DEPTH is 0 or 1 (no pipelining), this
- /// library manages connection lifecycle and honors the
- /// PO_CONNECTION_LIMIT setting as the maximum in-flight
- /// request limit. Libcurl itself may be caching additional
- /// connections under its connection cache policy.
- ///
- /// When PIPELINING_DEPTH is 2 or more, libcurl performs
- /// connection management and both PO_CONNECTION_LIMIT and
- /// PO_PER_HOST_CONNECTION_LIMIT should be set and non-zero.
- /// In this case (as of libcurl 7.37.0), libcurl will
- /// open new connections in preference to pipelining, up
- /// to the above limits at which time pipelining begins.
- /// And as usual, an additional cache of open but inactive
- /// connections may still be maintained within libcurl.
- /// For SL, a good rule-of-thumb is to set
- /// PO_PER_HOST_CONNECTION_LIMIT to the user-visible
- /// concurrency value and PO_CONNECTION_LIMIT to twice
- /// that for baked texture loads and region crossings where
- /// additional connection load will be tolerated. If
- /// either limit is 0, libcurl will prefer pipelining
- /// over connection creation, which is still interesting,
- /// but won't be pursued at this time.
- ///
- /// Per-class only
- PO_PIPELINING_DEPTH,
-
- /// Controls whether client-side throttling should be
- /// performed on this policy class. Positive values
- /// enable throttling and specify the request rate
- /// (requests per second) that should be targeted.
- /// A value of zero, the default, specifies no throttling.
- ///
- /// Per-class only
- PO_THROTTLE_RATE,
-
- /// Controls the callback function used to control SSL CTX
- /// certificate verification.
- ///
- /// Global only
- PO_SSL_VERIFY_CALLBACK,
-
- PO_LAST // Always at end
- };
-
- /// 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.
+ /// @name PolicyMethods
+ /// @{
+
+ /// Represents a default, catch-all policy class that guarantees
+ /// eventual service for any HTTP request.
+ static const policy_t DEFAULT_POLICY_ID = 0;
+ static const policy_t INVALID_POLICY_ID = 0xFFFFFFFFU;
+ static const policy_t GLOBAL_POLICY_ID = 0xFFFFFFFEU;
+
+ /// Create a new policy class into which requests can be made.
+ ///
+ /// All class creation must occur before threads are started and
+ /// transport begins. Policy classes are limited to a small value.
+ /// Currently that limit is the default class + 1.
+ ///
+ /// @return If positive, the policy_id used to reference
+ /// the class in other methods. If 0, requests
+ /// for classes have exceeded internal limits
+ /// or caller has tried to create a class after
+ /// threads have been started. Caller must fallback
+ /// and recover.
+ ///
+ static policy_t createPolicyClass();
+
+ enum EPolicyOption
+ {
+ /// Maximum number of connections the library will use to
+ /// perform operations. This is somewhat soft as the underlying
+ /// transport will cache some connections (up to 5).
+
+ /// A long value setting the maximum number of connections
+ /// allowed over all policy classes. Note that this will be
+ /// a somewhat soft value. There may be an additional five
+ /// connections per policy class depending upon runtime
+ /// behavior.
+ ///
+ /// Both global and per-class
+ PO_CONNECTION_LIMIT,
+
+ /// Limits the number of connections used for a single
+ /// literal address/port pair within the class.
+ ///
+ /// Per-class only
+ PO_PER_HOST_CONNECTION_LIMIT,
+
+ /// String containing a system-appropriate directory name
+ /// where SSL certs are stored.
+ ///
+ /// Global only
+ PO_CA_PATH,
+
+ /// String giving a full path to a file containing SSL certs.
+ ///
+ /// Global only
+ PO_CA_FILE,
+
+ /// String of host/port to use as simple HTTP proxy. This is
+ /// going to change in the future into something more elaborate
+ /// that may support richer schemes.
+ ///
+ /// Global only
+ PO_HTTP_PROXY,
+
+ /// Long value that if non-zero enables the use of the
+ /// traditional LLProxy code for http/socks5 support. If
+ /// enabled, has priority over GP_HTTP_PROXY.
+ ///
+ /// Global only
+ PO_LLPROXY,
+
+ /// Long value setting the logging trace level for the
+ /// library. Possible values are:
+ /// 0 - No tracing (default)
+ /// 1 - Basic tracing of request start, stop and major events.
+ /// 2 - Connection, header and payload size information from
+ /// HTTP transactions.
+ /// 3 - Partial logging of payload itself.
+ ///
+ /// These values are also used in the trace modes for
+ /// individual requests in HttpOptions. Also be aware that
+ /// tracing tends to impact performance of the viewer.
+ ///
+ /// Global only
+ PO_TRACE,
+
+ /// If greater than 1, suitable requests are allowed to
+ /// pipeline on their connections when they ask for it.
+ /// Value gives the maximum number of outstanding requests
+ /// on a connection.
+ ///
+ /// There is some interaction between PO_CONNECTION_LIMIT,
+ /// PO_PER_HOST_CONNECTION_LIMIT, and PO_PIPELINING_DEPTH.
+ /// When PIPELINING_DEPTH is 0 or 1 (no pipelining), this
+ /// library manages connection lifecycle and honors the
+ /// PO_CONNECTION_LIMIT setting as the maximum in-flight
+ /// request limit. Libcurl itself may be caching additional
+ /// connections under its connection cache policy.
+ ///
+ /// When PIPELINING_DEPTH is 2 or more, libcurl performs
+ /// connection management and both PO_CONNECTION_LIMIT and
+ /// PO_PER_HOST_CONNECTION_LIMIT should be set and non-zero.
+ /// In this case (as of libcurl 7.37.0), libcurl will
+ /// open new connections in preference to pipelining, up
+ /// to the above limits at which time pipelining begins.
+ /// And as usual, an additional cache of open but inactive
+ /// connections may still be maintained within libcurl.
+ /// For SL, a good rule-of-thumb is to set
+ /// PO_PER_HOST_CONNECTION_LIMIT to the user-visible
+ /// concurrency value and PO_CONNECTION_LIMIT to twice
+ /// that for baked texture loads and region crossings where
+ /// additional connection load will be tolerated. If
+ /// either limit is 0, libcurl will prefer pipelining
+ /// over connection creation, which is still interesting,
+ /// but won't be pursued at this time.
+ ///
+ /// Per-class only
+ PO_PIPELINING_DEPTH,
+
+ /// Controls whether client-side throttling should be
+ /// performed on this policy class. Positive values
+ /// enable throttling and specify the request rate
+ /// (requests per second) that should be targeted.
+ /// A value of zero, the default, specifies no throttling.
+ ///
+ /// Per-class only
+ PO_THROTTLE_RATE,
+
+ /// Controls the callback function used to control SSL CTX
+ /// certificate verification.
+ ///
+ /// Global only
+ PO_SSL_VERIFY_CALLBACK,
+
+ PO_LAST // Always at end
+ };
+
+ /// 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 &, const HttpHandler::ptr_t &, void *)> policyCallback_t;
- /// Set a policy option for a global or class parameter at
- /// startup time (prior to thread start).
- ///
- /// @param opt Enum of option to be set.
- /// @param pclass For class-based options, the policy class ID to
- /// be changed. For globals, specify GLOBAL_POLICY_ID.
- /// @param value Desired value of option.
- /// @param ret_value Pointer to receive effective set value
- /// if successful. May be NULL if effective
- /// value not wanted.
- /// @return Standard status code.
- static HttpStatus setStaticPolicyOption(EPolicyOption opt, policy_t pclass,
- long value, long * ret_value);
- static HttpStatus setStaticPolicyOption(EPolicyOption opt, policy_t pclass,
- const std::string & value, std::string * ret_value);
- static HttpStatus setStaticPolicyOption(EPolicyOption opt, policy_t pclass,
- policyCallback_t value, policyCallback_t * ret_value);;
-
- /// Set a parameter on a class-based policy option. Calls
- /// made after the start of the servicing thread are
- /// not honored and return an error status.
- ///
- /// @param opt Enum of option to be set.
- /// @param pclass For class-based options, the policy class ID to
- /// be changed. Ignored for globals but recommend
- /// using INVALID_POLICY_ID in this case.
- /// @param value Desired value of option.
- /// @return Handle of dynamic request. Use @see getStatus() if
- /// the returned handle is invalid.
- HttpHandle setPolicyOption(EPolicyOption opt, policy_t pclass, long value,
- HttpHandler::ptr_t handler);
- HttpHandle setPolicyOption(EPolicyOption opt, policy_t pclass, const std::string & value,
- HttpHandler::ptr_t handler);
-
- /// @}
-
- /// @name RequestMethods
- ///
- /// @{
-
- /// Some calls expect to succeed as the normal part of operation and so
- /// return a useful value rather than a status. When they do fail, the
- /// status is saved and can be fetched with this method.
- ///
- /// @return Status of the failing method invocation. If the
- /// preceding call succeeded or other HttpStatus
- /// returning calls immediately preceded this method,
- /// the returned value may not be reliable.
- ///
- HttpStatus getStatus() const;
-
- /// Queue a full HTTP GET request to be issued for entire entity.
- /// The request is queued and serviced by the working thread and
- /// notification of completion delivered to the optional HttpHandler
- /// argument during @see update() calls.
- ///
- /// With a valid handle returned, it can be used to reference the
- /// request in other requests (like cancellation) and will be an
- /// argument when any HttpHandler object is invoked.
- ///
- /// Headers supplied by default:
- /// - Connection: keep-alive
- /// - Accept: */*
- /// - Accept-Encoding: deflate, gzip
- /// - Keep-alive: 300
- /// - Host: <stuff>
- ///
- /// Some headers excluded by default:
- /// - Pragma:
- /// - Cache-control:
- /// - Range:
- /// - Transfer-Encoding:
- /// - Referer:
- ///
- /// @param policy_id Default or user-defined policy class under
- /// which this request is to be serviced.
- /// @param url URL with any encoded query parameters to
- /// be accessed.
- /// @param options Optional instance of an HttpOptions object
- /// to provide additional controls over the request
- /// function for this request only. Any such
- /// object then becomes shared-read across threads
- /// and no code should modify the HttpOptions
- /// instance.
- /// @param headers Optional instance of an HttpHeaders object
- /// to provide additional and/or overridden
- /// headers for the request. As with options,
- /// the instance becomes shared-read across threads
- /// and no code should modify the HttpHeaders
- /// instance.
- /// @param handler Optional pointer to an HttpHandler instance
- /// whose onCompleted() method will be invoked
- /// during calls to update(). This is a non-
- /// reference-counted object which would be a
- /// problem for shutdown and other edge cases but
- /// the pointer is only dereferenced during
- /// calls to update().
- ///
- /// @return The handle of the request if successfully
- /// queued or LLCORE_HTTP_HANDLE_INVALID if the
- /// request could not be queued. In the latter
- /// case, @see getStatus() will return more info.
- ///
- HttpHandle requestGet(policy_t policy_id,
- const std::string & url,
+ /// Set a policy option for a global or class parameter at
+ /// startup time (prior to thread start).
+ ///
+ /// @param opt Enum of option to be set.
+ /// @param pclass For class-based options, the policy class ID to
+ /// be changed. For globals, specify GLOBAL_POLICY_ID.
+ /// @param value Desired value of option.
+ /// @param ret_value Pointer to receive effective set value
+ /// if successful. May be NULL if effective
+ /// value not wanted.
+ /// @return Standard status code.
+ static HttpStatus setStaticPolicyOption(EPolicyOption opt, policy_t pclass,
+ long value, long * ret_value);
+ static HttpStatus setStaticPolicyOption(EPolicyOption opt, policy_t pclass,
+ const std::string & value, std::string * ret_value);
+ static HttpStatus setStaticPolicyOption(EPolicyOption opt, policy_t pclass,
+ policyCallback_t value, policyCallback_t * ret_value);;
+
+ /// Set a parameter on a class-based policy option. Calls
+ /// made after the start of the servicing thread are
+ /// not honored and return an error status.
+ ///
+ /// @param opt Enum of option to be set.
+ /// @param pclass For class-based options, the policy class ID to
+ /// be changed. Ignored for globals but recommend
+ /// using INVALID_POLICY_ID in this case.
+ /// @param value Desired value of option.
+ /// @return Handle of dynamic request. Use @see getStatus() if
+ /// the returned handle is invalid.
+ HttpHandle setPolicyOption(EPolicyOption opt, policy_t pclass, long value,
+ HttpHandler::ptr_t handler);
+ HttpHandle setPolicyOption(EPolicyOption opt, policy_t pclass, const std::string & value,
+ HttpHandler::ptr_t handler);
+
+ /// @}
+
+ /// @name RequestMethods
+ ///
+ /// @{
+
+ /// Some calls expect to succeed as the normal part of operation and so
+ /// return a useful value rather than a status. When they do fail, the
+ /// status is saved and can be fetched with this method.
+ ///
+ /// @return Status of the failing method invocation. If the
+ /// preceding call succeeded or other HttpStatus
+ /// returning calls immediately preceded this method,
+ /// the returned value may not be reliable.
+ ///
+ HttpStatus getStatus() const;
+
+ /// Queue a full HTTP GET request to be issued for entire entity.
+ /// The request is queued and serviced by the working thread and
+ /// notification of completion delivered to the optional HttpHandler
+ /// argument during @see update() calls.
+ ///
+ /// With a valid handle returned, it can be used to reference the
+ /// request in other requests (like cancellation) and will be an
+ /// argument when any HttpHandler object is invoked.
+ ///
+ /// Headers supplied by default:
+ /// - Connection: keep-alive
+ /// - Accept: */*
+ /// - Accept-Encoding: deflate, gzip
+ /// - Keep-alive: 300
+ /// - Host: <stuff>
+ ///
+ /// Some headers excluded by default:
+ /// - Pragma:
+ /// - Cache-control:
+ /// - Range:
+ /// - Transfer-Encoding:
+ /// - Referer:
+ ///
+ /// @param policy_id Default or user-defined policy class under
+ /// which this request is to be serviced.
+ /// @param url URL with any encoded query parameters to
+ /// be accessed.
+ /// @param options Optional instance of an HttpOptions object
+ /// to provide additional controls over the request
+ /// function for this request only. Any such
+ /// object then becomes shared-read across threads
+ /// and no code should modify the HttpOptions
+ /// instance.
+ /// @param headers Optional instance of an HttpHeaders object
+ /// to provide additional and/or overridden
+ /// headers for the request. As with options,
+ /// the instance becomes shared-read across threads
+ /// and no code should modify the HttpHeaders
+ /// instance.
+ /// @param handler Optional pointer to an HttpHandler instance
+ /// whose onCompleted() method will be invoked
+ /// during calls to update(). This is a non-
+ /// reference-counted object which would be a
+ /// problem for shutdown and other edge cases but
+ /// the pointer is only dereferenced during
+ /// calls to update().
+ ///
+ /// @return The handle of the request if successfully
+ /// queued or LLCORE_HTTP_HANDLE_INVALID if the
+ /// request could not be queued. In the latter
+ /// case, @see getStatus() will return more info.
+ ///
+ HttpHandle requestGet(policy_t policy_id,
+ const std::string & url,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers,
- HttpHandler::ptr_t handler);
-
-
- /// Queue a full HTTP GET request to be issued with a 'Range' header.
- /// The request is queued and serviced by the working thread and
- /// notification of completion delivered to the optional HttpHandler
- /// argument during @see update() calls.
- ///
- /// With a valid handle returned, it can be used to reference the
- /// request in other requests (like cancellation) and will be an
- /// argument when any HttpHandler object is invoked.
- ///
- /// Headers supplied by default:
- /// - Connection: keep-alive
- /// - Accept: */*
- /// - Accept-Encoding: deflate, gzip
- /// - Keep-alive: 300
- /// - Host: <stuff>
- /// - Range: <stuff> (will be omitted if offset == 0 and len == 0)
- ///
- /// Some headers excluded by default:
- /// - Pragma:
- /// - Cache-control:
- /// - Transfer-Encoding:
- /// - Referer:
- ///
- /// @param policy_id @see requestGet()
- /// @param url "
- /// @param offset Offset of first byte into resource to be returned.
- /// @param len Count of bytes to be returned
- /// @param options @see requestGet()
- /// @param headers "
- /// @param handler "
- /// @return "
- ///
- HttpHandle requestGetByteRange(policy_t policy_id,
- const std::string & url,
- size_t offset,
- size_t len,
+ const HttpHeaders::ptr_t & headers,
+ HttpHandler::ptr_t handler);
+
+
+ /// Queue a full HTTP GET request to be issued with a 'Range' header.
+ /// The request is queued and serviced by the working thread and
+ /// notification of completion delivered to the optional HttpHandler
+ /// argument during @see update() calls.
+ ///
+ /// With a valid handle returned, it can be used to reference the
+ /// request in other requests (like cancellation) and will be an
+ /// argument when any HttpHandler object is invoked.
+ ///
+ /// Headers supplied by default:
+ /// - Connection: keep-alive
+ /// - Accept: */*
+ /// - Accept-Encoding: deflate, gzip
+ /// - Keep-alive: 300
+ /// - Host: <stuff>
+ /// - Range: <stuff> (will be omitted if offset == 0 and len == 0)
+ ///
+ /// Some headers excluded by default:
+ /// - Pragma:
+ /// - Cache-control:
+ /// - Transfer-Encoding:
+ /// - Referer:
+ ///
+ /// @param policy_id @see requestGet()
+ /// @param url "
+ /// @param offset Offset of first byte into resource to be returned.
+ /// @param len Count of bytes to be returned
+ /// @param options @see requestGet()
+ /// @param headers "
+ /// @param handler "
+ /// @return "
+ ///
+ HttpHandle requestGetByteRange(policy_t policy_id,
+ const std::string & url,
+ size_t offset,
+ size_t len,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers,
- HttpHandler::ptr_t handler);
-
-
- /// Queue a full HTTP POST. Query arguments and body may
- /// be provided. Caller is responsible for escaping and
- /// encoding and communicating the content types.
- ///
- /// Headers supplied by default:
- /// - Connection: keep-alive
- /// - Accept: */*
- /// - Accept-Encoding: deflate, gzip
- /// - Keep-Alive: 300
- /// - Host: <stuff>
- /// - Content-Length: <digits>
- /// - Content-Type: application/x-www-form-urlencoded
- ///
- /// Some headers excluded by default:
- /// - Pragma:
- /// - Cache-Control:
- /// - Transfer-Encoding: ... chunked ...
- /// - Referer:
- /// - Content-Encoding:
- /// - Expect:
- ///
- /// @param policy_id @see requestGet()
- /// @param url "
- /// @param body Byte stream to be sent as the body. No
- /// further encoding or escaping will be done
- /// to the content.
- /// @param options @see requestGet()K(optional)
- /// @param headers "
- /// @param handler "
- /// @return "
- ///
- HttpHandle requestPost(policy_t policy_id,
- const std::string & url,
- BufferArray * body,
+ const HttpHeaders::ptr_t & headers,
+ HttpHandler::ptr_t handler);
+
+
+ /// Queue a full HTTP POST. Query arguments and body may
+ /// be provided. Caller is responsible for escaping and
+ /// encoding and communicating the content types.
+ ///
+ /// Headers supplied by default:
+ /// - Connection: keep-alive
+ /// - Accept: */*
+ /// - Accept-Encoding: deflate, gzip
+ /// - Keep-Alive: 300
+ /// - Host: <stuff>
+ /// - Content-Length: <digits>
+ /// - Content-Type: application/x-www-form-urlencoded
+ ///
+ /// Some headers excluded by default:
+ /// - Pragma:
+ /// - Cache-Control:
+ /// - Transfer-Encoding: ... chunked ...
+ /// - Referer:
+ /// - Content-Encoding:
+ /// - Expect:
+ ///
+ /// @param policy_id @see requestGet()
+ /// @param url "
+ /// @param body Byte stream to be sent as the body. No
+ /// further encoding or escaping will be done
+ /// to the content.
+ /// @param options @see requestGet()K(optional)
+ /// @param headers "
+ /// @param handler "
+ /// @return "
+ ///
+ HttpHandle requestPost(policy_t policy_id,
+ const std::string & url,
+ BufferArray * body,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers,
- HttpHandler::ptr_t handler);
-
-
- /// Queue a full HTTP PUT. Query arguments and body may
- /// be provided. Caller is responsible for escaping and
- /// encoding and communicating the content types.
- ///
- /// Headers supplied by default:
- /// - Connection: keep-alive
- /// - Accept: */*
- /// - Accept-Encoding: deflate, gzip
- /// - Keep-Alive: 300
- /// - Host: <stuff>
- /// - Content-Length: <digits>
- ///
- /// Some headers excluded by default:
- /// - Pragma:
- /// - Cache-Control:
- /// - Transfer-Encoding: ... chunked ...
- /// - Referer:
- /// - Content-Encoding:
- /// - Expect:
- /// - Content-Type:
- ///
- /// @param policy_id @see requestGet()
- /// @param url "
- /// @param body Byte stream to be sent as the body. No
- /// further encoding or escaping will be done
- /// to the content.
- /// @param options @see requestGet()K(optional)
- /// @param headers "
- /// @param handler "
- /// @return "
- ///
- HttpHandle requestPut(policy_t policy_id,
- const std::string & url,
- BufferArray * body,
+ const HttpHeaders::ptr_t & headers,
+ HttpHandler::ptr_t handler);
+
+
+ /// Queue a full HTTP PUT. Query arguments and body may
+ /// be provided. Caller is responsible for escaping and
+ /// encoding and communicating the content types.
+ ///
+ /// Headers supplied by default:
+ /// - Connection: keep-alive
+ /// - Accept: */*
+ /// - Accept-Encoding: deflate, gzip
+ /// - Keep-Alive: 300
+ /// - Host: <stuff>
+ /// - Content-Length: <digits>
+ ///
+ /// Some headers excluded by default:
+ /// - Pragma:
+ /// - Cache-Control:
+ /// - Transfer-Encoding: ... chunked ...
+ /// - Referer:
+ /// - Content-Encoding:
+ /// - Expect:
+ /// - Content-Type:
+ ///
+ /// @param policy_id @see requestGet()
+ /// @param url "
+ /// @param body Byte stream to be sent as the body. No
+ /// further encoding or escaping will be done
+ /// to the content.
+ /// @param options @see requestGet()K(optional)
+ /// @param headers "
+ /// @param handler "
+ /// @return "
+ ///
+ HttpHandle requestPut(policy_t policy_id,
+ const std::string & url,
+ BufferArray * body,
const HttpOptions::ptr_t & options,
- const HttpHeaders::ptr_t & headers,
- HttpHandler::ptr_t handler);
+ const HttpHeaders::ptr_t & headers,
+ HttpHandler::ptr_t handler);
/// Queue a full HTTP DELETE. Query arguments and body may
/// be provided. Caller is responsible for escaping and
/// encoding and communicating the content types.
///
- /// @param policy_id @see requestGet()
- /// @param url "
- /// @param options @see requestGet()K(optional)
- /// @param headers "
- /// @param handler "
- /// @return "
+ /// @param policy_id @see requestGet()
+ /// @param url "
+ /// @param options @see requestGet()K(optional)
+ /// @param headers "
+ /// @param handler "
+ /// @return "
///
HttpHandle requestDelete(policy_t policy_id,
const std::string & url,
@@ -489,15 +489,15 @@ public:
/// be provided. Caller is responsible for escaping and
/// encoding and communicating the content types.
///
- /// @param policy_id @see requestGet()
- /// @param url "
- /// @param body Byte stream to be sent as the body. No
- /// further encoding or escaping will be done
- /// to the content.
- /// @param options @see requestGet()K(optional)
- /// @param headers "
- /// @param handler "
- /// @return "
+ /// @param policy_id @see requestGet()
+ /// @param url "
+ /// @param body Byte stream to be sent as the body. No
+ /// further encoding or escaping will be done
+ /// to the content.
+ /// @param options @see requestGet()K(optional)
+ /// @param headers "
+ /// @param handler "
+ /// @return "
///
HttpHandle requestPatch(policy_t policy_id,
const std::string & url,
@@ -510,12 +510,12 @@ public:
/// be provided. Caller is responsible for escaping and
/// encoding and communicating the content types.
///
- /// @param policy_id @see requestGet()
- /// @param url "
- /// @param options @see requestGet()K(optional)
- /// @param headers "
- /// @param handler "
- /// @return "
+ /// @param policy_id @see requestGet()
+ /// @param url "
+ /// @param options @see requestGet()K(optional)
+ /// @param headers "
+ /// @param handler "
+ /// @return "
///
HttpHandle requestCopy(policy_t policy_id,
const std::string & url,
@@ -527,12 +527,12 @@ public:
/// be provided. Caller is responsible for escaping and
/// encoding and communicating the content types.
///
- /// @param policy_id @see requestGet()
- /// @param url "
- /// @param options @see requestGet()K(optional)
- /// @param headers "
- /// @param handler "
- /// @return "
+ /// @param policy_id @see requestGet()
+ /// @param url "
+ /// @param options @see requestGet()K(optional)
+ /// @param headers "
+ /// @param handler "
+ /// @return "
///
HttpHandle requestMove(policy_t policy_id,
const std::string & url,
@@ -541,115 +541,115 @@ public:
HttpHandler::ptr_t user_handler);
/// Queue a NoOp request.
- /// The request is queued and serviced by the working thread which
- /// immediately processes it and returns the request to the reply
- /// queue.
- ///
- /// @param handler @see requestGet()
- /// @return "
- ///
- 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
- /// are done synchronously during calls to this method which gives the
- /// library control so notification can be performed. Application handlers
- /// are expected to return 'quickly' and do any significant processing
- /// outside of the notification callback to onCompleted().
- ///
- /// @param usecs Maximum number of wallclock microseconds to
- /// spend in the call. As hinted at above, this
- /// is partly a function of application code so it's
- /// a soft limit. A '0' value will run without
- /// time limit until everything queued has been
- /// delivered.
- ///
- /// @return Standard status code.
- HttpStatus update(long usecs);
-
- /// @}
-
- /// @name RequestMgmtMethods
- ///
- /// @{
-
- HttpHandle requestCancel(HttpHandle request, HttpHandler::ptr_t);
-
- /// @}
-
- /// @name UtilityMethods
- ///
- /// @{
-
- /// Initialization method that needs to be called before queueing any
- /// requests. Doesn't start the worker thread and may be called befoer
- /// or after policy setup.
- static HttpStatus createService();
-
- /// Mostly clean shutdown of services prior to exit. Caller is expected
- /// to have stopped a running worker thread before calling this.
- static HttpStatus destroyService();
-
- /// Called once after @see createService() to start the worker thread.
- /// Stopping the thread is achieved by requesting it via @see requestStopThread().
- /// May be called before or after requests are issued.
- static HttpStatus startThread();
-
- /// Queues a request to the worker thread to have it stop processing
- /// and exit (without exiting the program). When the operation is
- /// picked up by the worker thread, it immediately processes it and
- /// begins detaching from refcounted resources like request and
- /// reply queues and then returns to the host OS. It *does* queue a
- /// reply to give the calling application thread a notification that
- /// the operation has been performed.
- ///
- /// @param handler (optional)
- /// @return The handle of the request if successfully
- /// queued or LLCORE_HTTP_HANDLE_INVALID if the
- /// request could not be queued. In the latter
- /// case, @see getStatus() will return more info.
- /// As the request cannot be cancelled, the handle
- /// is generally not useful.
- ///
- HttpHandle requestStopThread(HttpHandler::ptr_t handler);
-
- /// Queue a Spin request.
- /// DEBUG/TESTING ONLY. This puts the worker into a CPU spin for
- /// test purposes.
- ///
- /// @param mode 0 for hard spin, 1 for soft spin
- /// @return Standard handle return cases.
- ///
- HttpHandle requestSpin(int mode);
-
- /// @}
-
+ /// The request is queued and serviced by the working thread which
+ /// immediately processes it and returns the request to the reply
+ /// queue.
+ ///
+ /// @param handler @see requestGet()
+ /// @return "
+ ///
+ 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
+ /// are done synchronously during calls to this method which gives the
+ /// library control so notification can be performed. Application handlers
+ /// are expected to return 'quickly' and do any significant processing
+ /// outside of the notification callback to onCompleted().
+ ///
+ /// @param usecs Maximum number of wallclock microseconds to
+ /// spend in the call. As hinted at above, this
+ /// is partly a function of application code so it's
+ /// a soft limit. A '0' value will run without
+ /// time limit until everything queued has been
+ /// delivered.
+ ///
+ /// @return Standard status code.
+ HttpStatus update(long usecs);
+
+ /// @}
+
+ /// @name RequestMgmtMethods
+ ///
+ /// @{
+
+ HttpHandle requestCancel(HttpHandle request, HttpHandler::ptr_t);
+
+ /// @}
+
+ /// @name UtilityMethods
+ ///
+ /// @{
+
+ /// Initialization method that needs to be called before queueing any
+ /// requests. Doesn't start the worker thread and may be called befoer
+ /// or after policy setup.
+ static HttpStatus createService();
+
+ /// Mostly clean shutdown of services prior to exit. Caller is expected
+ /// to have stopped a running worker thread before calling this.
+ static HttpStatus destroyService();
+
+ /// Called once after @see createService() to start the worker thread.
+ /// Stopping the thread is achieved by requesting it via @see requestStopThread().
+ /// May be called before or after requests are issued.
+ static HttpStatus startThread();
+
+ /// Queues a request to the worker thread to have it stop processing
+ /// and exit (without exiting the program). When the operation is
+ /// picked up by the worker thread, it immediately processes it and
+ /// begins detaching from refcounted resources like request and
+ /// reply queues and then returns to the host OS. It *does* queue a
+ /// reply to give the calling application thread a notification that
+ /// the operation has been performed.
+ ///
+ /// @param handler (optional)
+ /// @return The handle of the request if successfully
+ /// queued or LLCORE_HTTP_HANDLE_INVALID if the
+ /// request could not be queued. In the latter
+ /// case, @see getStatus() will return more info.
+ /// As the request cannot be cancelled, the handle
+ /// is generally not useful.
+ ///
+ HttpHandle requestStopThread(HttpHandler::ptr_t handler);
+
+ /// Queue a Spin request.
+ /// DEBUG/TESTING ONLY. This puts the worker into a CPU spin for
+ /// test purposes.
+ ///
+ /// @param mode 0 for hard spin, 1 for soft spin
+ /// @return Standard handle return cases.
+ ///
+ HttpHandle requestSpin(int mode);
+
+ /// @}
+
protected:
private:
typedef std::shared_ptr<HttpReplyQueue> HttpReplyQueuePtr_t;
- /// @name InstanceData
- ///
- /// @{
- HttpStatus mLastReqStatus;
- HttpReplyQueuePtr_t mReplyQueue;
- HttpRequestQueue * mRequestQueue;
-
- /// @}
-
- // ====================================
- /// @name GlobalState
- ///
- /// @{
- ///
- /// Must be established before any threading is allowed to
- /// start.
- ///
-
- /// @}
- // End Global State
- // ====================================
+ /// @name InstanceData
+ ///
+ /// @{
+ HttpStatus mLastReqStatus;
+ HttpReplyQueuePtr_t mReplyQueue;
+ HttpRequestQueue * mRequestQueue;
+
+ /// @}
+
+ // ====================================
+ /// @name GlobalState
+ ///
+ /// @{
+ ///
+ /// Must be established before any threading is allowed to
+ /// start.
+ ///
+
+ /// @}
+ // End Global State
+ // ====================================
}; // end class HttpRequest
@@ -658,4 +658,4 @@ private:
-#endif // _LLCORE_HTTP_REQUEST_H_
+#endif // _LLCORE_HTTP_REQUEST_H_
diff --git a/indra/llcorehttp/httpresponse.cpp b/indra/llcorehttp/httpresponse.cpp
index f5ad2ebd47..1436054c0b 100644
--- a/indra/llcorehttp/httpresponse.cpp
+++ b/indra/llcorehttp/httpresponse.cpp
@@ -1,6 +1,6 @@
/**
* @file httpresponse.cpp
- * @brief
+ * @brief
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -34,41 +34,41 @@ namespace LLCore
HttpResponse::HttpResponse()
- : LLCoreInt::RefCounted(true),
- mReplyOffset(0U),
- mReplyLength(0U),
- mReplyFullLength(0U),
- mBufferArray(NULL),
- mHeaders(),
- mRetries(0U),
- m503Retries(0U),
+ : LLCoreInt::RefCounted(true),
+ mReplyOffset(0U),
+ mReplyLength(0U),
+ mReplyFullLength(0U),
+ mBufferArray(NULL),
+ mHeaders(),
+ mRetries(0U),
+ m503Retries(0U),
mRequestUrl()
{}
HttpResponse::~HttpResponse()
{
- setBody(NULL);
- //setHeaders();
+ setBody(NULL);
+ //setHeaders();
}
void HttpResponse::setBody(BufferArray * ba)
{
- if (mBufferArray == ba)
- return;
-
- if (mBufferArray)
- {
- mBufferArray->release();
- }
-
- if (ba)
- {
- ba->addRef();
- }
-
- mBufferArray = ba;
+ if (mBufferArray == ba)
+ return;
+
+ if (mBufferArray)
+ {
+ mBufferArray->release();
+ }
+
+ if (ba)
+ {
+ ba->addRef();
+ }
+
+ mBufferArray = ba;
}
@@ -79,7 +79,7 @@ void HttpResponse::setHeaders(HttpHeaders::ptr_t &headers)
size_t HttpResponse::getBodySize() const
{
- return (mBufferArray) ? mBufferArray->size() : 0;
+ return (mBufferArray) ? mBufferArray->size() : 0;
}
} // end namespace LLCore
diff --git a/indra/llcorehttp/httpresponse.h b/indra/llcorehttp/httpresponse.h
index ef98fbef2b..99c8f1d2f9 100644
--- a/indra/llcorehttp/httpresponse.h
+++ b/indra/llcorehttp/httpresponse.h
@@ -24,8 +24,8 @@
* $/LicenseInfo$
*/
-#ifndef _LLCORE_HTTP_RESPONSE_H_
-#define _LLCORE_HTTP_RESPONSE_H_
+#ifndef _LLCORE_HTTP_RESPONSE_H_
+#define _LLCORE_HTTP_RESPONSE_H_
#include <string>
@@ -60,139 +60,139 @@ class HttpHeaders;
class HttpResponse : public LLCoreInt::RefCounted
{
public:
- HttpResponse();
+ HttpResponse();
protected:
- virtual ~HttpResponse(); // Use release()
-
- HttpResponse(const HttpResponse &); // Not defined
- void operator=(const HttpResponse &); // Not defined
-
+ virtual ~HttpResponse(); // Use release()
+
+ HttpResponse(const HttpResponse &); // Not defined
+ void operator=(const HttpResponse &); // Not defined
+
public:
- /// Statistics for the HTTP
- struct TransferStats
- {
- typedef std::shared_ptr<TransferStats> ptr_t;
-
- TransferStats() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {}
- F64 mSizeDownload;
- F64 mTotalTime;
- F64 mSpeedDownload;
- };
-
-
- /// Returns the final status of the requested operation.
- ///
- HttpStatus getStatus() const
- {
- return mStatus;
- }
-
- void setStatus(const HttpStatus & status)
- {
- mStatus = status;
- }
-
- /// Simple getter for the response body returned as a scatter/gather
- /// buffer. If the operation doesn't produce data (such as the Null
- /// or StopThread operations), this may be NULL.
- ///
- /// Caller can hold onto the response by incrementing the reference
- /// count of the returned object.
- BufferArray * getBody() const
- {
- return mBufferArray;
- }
-
- /// Safely get the size of the body buffer. If the body buffer is missing
- /// return 0 as the size.
- size_t getBodySize() const;
-
- /// Set the response data in the instance. Will drop the reference
- /// count to any existing data and increment the count of that passed
- /// in. It is legal to set the data to NULL.
- void setBody(BufferArray * ba);
-
- /// And a getter for the headers. And as with @see getResponse(),
- /// if headers aren't available because the operation doesn't produce
- /// any or delivery of headers wasn't requested in the options, this
- /// will be NULL.
- ///
- /// Caller can hold onto the headers by incrementing the reference
- /// count of the returned object.
- HttpHeaders::ptr_t getHeaders() const
- {
- return mHeaders;
- }
-
- /// Behaves like @see setResponse() but for header data.
- void setHeaders(HttpHeaders::ptr_t &headers);
-
- /// If a 'Range:' header was used, these methods are involved
- /// in setting and returning data about the actual response.
- /// If both @offset and @length are returned as 0, we probably
- /// didn't get a Content-Range header in the response. This
- /// occurs with various Capabilities-based services and the
- /// caller is going to have to make assumptions on receipt of
- /// a 206 status. The @full value may also be zero in cases of
- /// parsing problems or a wild-carded length response.
- ///
- /// These values will not necessarily agree with the data in
- /// the body itself (if present). The BufferArray object
- /// is authoritative for actual data length.
- void getRange(unsigned int * offset, unsigned int * length, unsigned int * full) const
- {
- *offset = mReplyOffset;
- *length = mReplyLength;
- *full = mReplyFullLength;
- }
-
- void setRange(unsigned int offset, unsigned int length, unsigned int full_length)
- {
- mReplyOffset = offset;
- mReplyLength = length;
- mReplyFullLength = full_length;
- }
-
- ///
- const std::string & getContentType() const
- {
- return mContentType;
- }
-
- void setContentType(const std::string & con_type)
- {
- mContentType = con_type;
- }
-
- /// Get and set retry attempt information on the request.
- void getRetries(unsigned int * retries, unsigned int * retries_503) const
- {
- if (retries)
- {
- *retries = mRetries;
- }
- if (retries_503)
- {
- *retries_503 = m503Retries;
- }
- }
-
- void setRetries(unsigned int retries, unsigned int retries_503)
- {
- mRetries = retries;
- m503Retries = retries_503;
- }
-
- void setTransferStats(TransferStats::ptr_t &stats)
- {
- mStats = stats;
- }
-
- TransferStats::ptr_t getTransferStats()
- {
- return mStats;
- }
+ /// Statistics for the HTTP
+ struct TransferStats
+ {
+ typedef std::shared_ptr<TransferStats> ptr_t;
+
+ TransferStats() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {}
+ F64 mSizeDownload;
+ F64 mTotalTime;
+ F64 mSpeedDownload;
+ };
+
+
+ /// Returns the final status of the requested operation.
+ ///
+ HttpStatus getStatus() const
+ {
+ return mStatus;
+ }
+
+ void setStatus(const HttpStatus & status)
+ {
+ mStatus = status;
+ }
+
+ /// Simple getter for the response body returned as a scatter/gather
+ /// buffer. If the operation doesn't produce data (such as the Null
+ /// or StopThread operations), this may be NULL.
+ ///
+ /// Caller can hold onto the response by incrementing the reference
+ /// count of the returned object.
+ BufferArray * getBody() const
+ {
+ return mBufferArray;
+ }
+
+ /// Safely get the size of the body buffer. If the body buffer is missing
+ /// return 0 as the size.
+ size_t getBodySize() const;
+
+ /// Set the response data in the instance. Will drop the reference
+ /// count to any existing data and increment the count of that passed
+ /// in. It is legal to set the data to NULL.
+ void setBody(BufferArray * ba);
+
+ /// And a getter for the headers. And as with @see getResponse(),
+ /// if headers aren't available because the operation doesn't produce
+ /// any or delivery of headers wasn't requested in the options, this
+ /// will be NULL.
+ ///
+ /// Caller can hold onto the headers by incrementing the reference
+ /// count of the returned object.
+ HttpHeaders::ptr_t getHeaders() const
+ {
+ return mHeaders;
+ }
+
+ /// Behaves like @see setResponse() but for header data.
+ void setHeaders(HttpHeaders::ptr_t &headers);
+
+ /// If a 'Range:' header was used, these methods are involved
+ /// in setting and returning data about the actual response.
+ /// If both @offset and @length are returned as 0, we probably
+ /// didn't get a Content-Range header in the response. This
+ /// occurs with various Capabilities-based services and the
+ /// caller is going to have to make assumptions on receipt of
+ /// a 206 status. The @full value may also be zero in cases of
+ /// parsing problems or a wild-carded length response.
+ ///
+ /// These values will not necessarily agree with the data in
+ /// the body itself (if present). The BufferArray object
+ /// is authoritative for actual data length.
+ void getRange(unsigned int * offset, unsigned int * length, unsigned int * full) const
+ {
+ *offset = mReplyOffset;
+ *length = mReplyLength;
+ *full = mReplyFullLength;
+ }
+
+ void setRange(unsigned int offset, unsigned int length, unsigned int full_length)
+ {
+ mReplyOffset = offset;
+ mReplyLength = length;
+ mReplyFullLength = full_length;
+ }
+
+ ///
+ const std::string & getContentType() const
+ {
+ return mContentType;
+ }
+
+ void setContentType(const std::string & con_type)
+ {
+ mContentType = con_type;
+ }
+
+ /// Get and set retry attempt information on the request.
+ void getRetries(unsigned int * retries, unsigned int * retries_503) const
+ {
+ if (retries)
+ {
+ *retries = mRetries;
+ }
+ if (retries_503)
+ {
+ *retries_503 = m503Retries;
+ }
+ }
+
+ void setRetries(unsigned int retries, unsigned int retries_503)
+ {
+ mRetries = retries;
+ m503Retries = retries_503;
+ }
+
+ void setTransferStats(TransferStats::ptr_t &stats)
+ {
+ mStats = stats;
+ }
+
+ TransferStats::ptr_t getTransferStats()
+ {
+ return mStats;
+ }
void setRequestURL(const std::string &url)
{
@@ -215,23 +215,23 @@ public:
}
protected:
- // Response data here
- HttpStatus mStatus;
- unsigned int mReplyOffset;
- unsigned int mReplyLength;
- unsigned int mReplyFullLength;
- BufferArray * mBufferArray;
- HttpHeaders::ptr_t mHeaders;
- std::string mContentType;
- unsigned int mRetries;
- unsigned int m503Retries;
+ // Response data here
+ HttpStatus mStatus;
+ unsigned int mReplyOffset;
+ unsigned int mReplyLength;
+ unsigned int mReplyFullLength;
+ BufferArray * mBufferArray;
+ HttpHeaders::ptr_t mHeaders;
+ std::string mContentType;
+ unsigned int mRetries;
+ unsigned int m503Retries;
std::string mRequestUrl;
std::string mRequestMethod;
- TransferStats::ptr_t mStats;
+ TransferStats::ptr_t mStats;
};
} // end namespace LLCore
-#endif // _LLCORE_HTTP_RESPONSE_H_
+#endif // _LLCORE_HTTP_RESPONSE_H_
diff --git a/indra/llcorehttp/httpstats.cpp b/indra/llcorehttp/httpstats.cpp
index 19eceae5ef..dc2ac35c71 100644
--- a/indra/llcorehttp/httpstats.cpp
+++ b/indra/llcorehttp/httpstats.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewerstats.cpp
* @brief LLViewerStats class implementation
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -97,7 +97,7 @@ void HTTPStats::dumpStats()
out << "Result Codes:" << std::endl << "--- -----" << std::endl;
for (std::map<S32, S32>::iterator it = mResutCodes.begin(); it != mResutCodes.end(); ++it)
- {
+ {
out << (*it).first << " " << (*it).second << std::endl;
}
diff --git a/indra/llcorehttp/httpstats.h b/indra/llcorehttp/httpstats.h
index 2c713cb548..e1387d9df5 100644
--- a/indra/llcorehttp/httpstats.h
+++ b/indra/llcorehttp/httpstats.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llviewerim_peningtats.h
* @brief LLViewerStats class header file
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
diff --git a/indra/llcorehttp/llhttpconstants.cpp b/indra/llcorehttp/llhttpconstants.cpp
index 71d4f19408..40d6c7506c 100755
--- a/indra/llcorehttp/llhttpconstants.cpp
+++ b/indra/llcorehttp/llhttpconstants.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @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$
*/
diff --git a/indra/llcorehttp/llhttpconstants.h b/indra/llcorehttp/llhttpconstants.h
index 121448854e..583f9fbcb7 100755
--- a/indra/llcorehttp/llhttpconstants.h
+++ b/indra/llcorehttp/llhttpconstants.h
@@ -1,25 +1,25 @@
-/**
+/**
* @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$
*/
@@ -103,17 +103,17 @@ 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
+ 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.
diff --git a/indra/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp
index 362b2309ee..c0cc2c8030 100755
--- a/indra/llcorehttp/tests/llcorehttp_test.cpp
+++ b/indra/llcorehttp/tests/llcorehttp_test.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llcorehttp_test
* @brief Main test runner
*
@@ -56,26 +56,26 @@
void ssl_thread_id_callback(CRYPTO_THREADID*);
void ssl_locking_callback(int mode, int type, const char * file, int line);
-#if 0 // lltut provides main and runner
+#if 0 // lltut provides main and runner
namespace tut
{
- test_runner_singleton runner;
+ test_runner_singleton runner;
}
int main()
{
- curl_global_init(CURL_GLOBAL_ALL);
+ curl_global_init(CURL_GLOBAL_ALL);
- // *FIXME: Need threaded/SSL curl setup here.
-
- tut::reporter reporter;
+ // *FIXME: Need threaded/SSL curl setup here.
- tut::runner.get().set_callback(&reporter);
- tut::runner.get().run_tests();
- return !reporter.all_ok();
+ tut::reporter reporter;
- curl_global_cleanup();
+ tut::runner.get().set_callback(&reporter);
+ tut::runner.get().run_tests();
+ return !reporter.all_ok();
+
+ curl_global_cleanup();
}
#endif // 0
@@ -85,95 +85,95 @@ LLCoreInt::HttpMutex ** ssl_mutex_list = NULL;
void init_curl()
{
- curl_global_init(CURL_GLOBAL_ALL);
-
- ssl_mutex_count = CRYPTO_num_locks();
- if (ssl_mutex_count > 0)
- {
- ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count];
-
- for (int i(0); i < ssl_mutex_count; ++i)
- {
- ssl_mutex_list[i] = new LLCoreInt::HttpMutex;
- }
-
- CRYPTO_set_locking_callback(ssl_locking_callback);
- CRYPTO_THREADID_set_callback(ssl_thread_id_callback);
- }
-
- LLProxy::getInstance();
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ ssl_mutex_count = CRYPTO_num_locks();
+ if (ssl_mutex_count > 0)
+ {
+ ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count];
+
+ for (int i(0); i < ssl_mutex_count; ++i)
+ {
+ ssl_mutex_list[i] = new LLCoreInt::HttpMutex;
+ }
+
+ CRYPTO_set_locking_callback(ssl_locking_callback);
+ CRYPTO_THREADID_set_callback(ssl_thread_id_callback);
+ }
+
+ LLProxy::getInstance();
}
void term_curl()
{
- SUBSYSTEM_CLEANUP(LLProxy);
-
- CRYPTO_set_locking_callback(NULL);
- for (int i(0); i < ssl_mutex_count; ++i)
- {
- delete ssl_mutex_list[i];
- }
- delete [] ssl_mutex_list;
+ SUBSYSTEM_CLEANUP(LLProxy);
+
+ CRYPTO_set_locking_callback(NULL);
+ for (int i(0); i < ssl_mutex_count; ++i)
+ {
+ delete ssl_mutex_list[i];
+ }
+ delete [] ssl_mutex_list;
}
void ssl_thread_id_callback(CRYPTO_THREADID* pthreadid)
{
#if defined(WIN32)
- CRYPTO_THREADID_set_pointer(pthreadid, GetCurrentThread());
+ CRYPTO_THREADID_set_pointer(pthreadid, GetCurrentThread());
#else
- CRYPTO_THREADID_set_pointer(pthreadid, pthread_self());
+ CRYPTO_THREADID_set_pointer(pthreadid, pthread_self());
#endif
}
void ssl_locking_callback(int mode, int type, const char * /* file */, int /* line */)
{
- if (type >= 0 && type < ssl_mutex_count)
- {
- if (mode & CRYPTO_LOCK)
- {
- ssl_mutex_list[type]->lock();
- }
- else
- {
- ssl_mutex_list[type]->unlock();
- }
- }
+ if (type >= 0 && type < ssl_mutex_count)
+ {
+ if (mode & CRYPTO_LOCK)
+ {
+ ssl_mutex_list[type]->lock();
+ }
+ else
+ {
+ ssl_mutex_list[type]->unlock();
+ }
+ }
}
std::string get_base_url()
{
- const char * env(getenv("LL_TEST_PORT"));
-
- if (! env)
- {
- std::cerr << "LL_TEST_PORT environment variable missing." << std::endl;
- std::cerr << "Test expects to run in test_llcorehttp_peer.py script." << std::endl;
- tut::ensure("LL_TEST_PORT set in environment", NULL != env);
- }
-
- int port(atoi(env));
- std::ostringstream out;
- out << "http://localhost:" << port << "/";
- return out.str();
+ const char * env(getenv("LL_TEST_PORT"));
+
+ if (! env)
+ {
+ std::cerr << "LL_TEST_PORT environment variable missing." << std::endl;
+ std::cerr << "Test expects to run in test_llcorehttp_peer.py script." << std::endl;
+ tut::ensure("LL_TEST_PORT set in environment", NULL != env);
+ }
+
+ int port(atoi(env));
+ std::ostringstream out;
+ out << "http://localhost:" << port << "/";
+ return out.str();
}
void stop_thread(LLCore::HttpRequest * req)
{
- if (req)
- {
- req->requestStopThread(LLCore::HttpHandler::ptr_t());
-
- int count = 0;
- int limit = 10;
- while (count++ < limit && ! HttpService::isStopped())
- {
- req->update(1000);
- usleep(100000);
- }
- }
+ if (req)
+ {
+ req->requestStopThread(LLCore::HttpHandler::ptr_t());
+
+ int count = 0;
+ int limit = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ req->update(1000);
+ usleep(100000);
+ }
+ }
}
diff --git a/indra/llcorehttp/tests/llcorehttp_test.h b/indra/llcorehttp/tests/llcorehttp_test.h
index a9567435ce..133cb3121a 100644
--- a/indra/llcorehttp/tests/llcorehttp_test.h
+++ b/indra/llcorehttp/tests/llcorehttp_test.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file llcorehttp_test.h
* @brief Main test runner
*
@@ -26,9 +26,9 @@
#ifndef _LLCOREHTTP_TEST_H_
-#define _LLCOREHTTP_TEST_H_
+#define _LLCOREHTTP_TEST_H_
-#include "linden_common.h" // Modifies curl interfaces
+#include "linden_common.h" // Modifies curl interfaces
#include <curl/curl.h>
#include <openssl/crypto.h>
@@ -49,16 +49,16 @@ extern void stop_thread(LLCore::HttpRequest * req);
class ScopedCurlInit
{
public:
- ScopedCurlInit()
- {
- init_curl();
- }
+ ScopedCurlInit()
+ {
+ init_curl();
+ }
- ~ScopedCurlInit()
- {
- term_curl();
- }
+ ~ScopedCurlInit()
+ {
+ term_curl();
+ }
};
-
-#endif // _LLCOREHTTP_TEST_H_
+
+#endif // _LLCOREHTTP_TEST_H_
diff --git a/indra/llcorehttp/tests/test_allocator.cpp b/indra/llcorehttp/tests/test_allocator.cpp
index 597e0d2fc9..757736acbb 100644
--- a/indra/llcorehttp/tests/test_allocator.cpp
+++ b/indra/llcorehttp/tests/test_allocator.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file test_allocator.cpp
* @brief quick and dirty allocator for tracking memory allocations
*
@@ -45,15 +45,15 @@
struct BlockHeader
{
- struct Block * next;
- std::size_t size;
- bool in_use;
+ struct Block * next;
+ std::size_t size;
+ bool in_use;
};
struct Block
{
- BlockHeader hdr;
- unsigned char data[1];
+ BlockHeader hdr;
+ unsigned char data[1];
};
#define TRACE_MSG(val) std::cout << __FUNCTION__ << "(" << val << ") [" << __FILE__ << ":" << __LINE__ << "]" << std::endl;
@@ -66,109 +66,109 @@ volatile std::size_t MemTotal = 0;
static bool CAS(void * volatile * ptr, void * expected, void * new_value)
{
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
- return OSAtomicCompareAndSwapPtr( expected, new_value, ptr );
+ return OSAtomicCompareAndSwapPtr( expected, new_value, ptr );
#elif defined(_MSC_VER)
- return expected == InterlockedCompareExchangePointer( ptr, new_value, expected );
+ return expected == InterlockedCompareExchangePointer( ptr, new_value, expected );
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ ) > 40100
- return __sync_bool_compare_and_swap( ptr, expected, new_value );
+ return __sync_bool_compare_and_swap( ptr, expected, new_value );
#endif
}
static void * GetMem(std::size_t size)
{
- // TRACE_MSG(size);
- volatile Block * pBlock = NULL;
- volatile Block * pNewNext = NULL;
-
- // do a lock-free update of the global next pointer
- do
- {
- pBlock = pNext;
- pNewNext = (volatile Block *)(pBlock->data + size);
-
- } while(! CAS((void * volatile *) &pNext, (void *) pBlock, (void *) pNewNext));
-
- // if we get here, we safely carved out a block of memory in the
- // memory pool...
-
- // initialize our block
- pBlock->hdr.next = (Block *)(pBlock->data + size);
- pBlock->hdr.size = size;
- pBlock->hdr.in_use = true;
- memset((void *) pBlock->data, 0, pBlock->hdr.size);
-
- // do a lock-free update of the global memory total
- volatile size_t total = 0;
- volatile size_t new_total = 0;
- do
- {
- total = MemTotal;
- new_total = total + size;
-
- } while (! CAS((void * volatile *) &MemTotal, (void *) total, (void *) new_total));
-
- return (void *) pBlock->data;
+ // TRACE_MSG(size);
+ volatile Block * pBlock = NULL;
+ volatile Block * pNewNext = NULL;
+
+ // do a lock-free update of the global next pointer
+ do
+ {
+ pBlock = pNext;
+ pNewNext = (volatile Block *)(pBlock->data + size);
+
+ } while(! CAS((void * volatile *) &pNext, (void *) pBlock, (void *) pNewNext));
+
+ // if we get here, we safely carved out a block of memory in the
+ // memory pool...
+
+ // initialize our block
+ pBlock->hdr.next = (Block *)(pBlock->data + size);
+ pBlock->hdr.size = size;
+ pBlock->hdr.in_use = true;
+ memset((void *) pBlock->data, 0, pBlock->hdr.size);
+
+ // do a lock-free update of the global memory total
+ volatile size_t total = 0;
+ volatile size_t new_total = 0;
+ do
+ {
+ total = MemTotal;
+ new_total = total + size;
+
+ } while (! CAS((void * volatile *) &MemTotal, (void *) total, (void *) new_total));
+
+ return (void *) pBlock->data;
}
static void FreeMem(void * p)
{
- // get the pointer to the block record
- Block * pBlock = (Block *)((unsigned char *) p - sizeof(BlockHeader));
-
- // TRACE_MSG(pBlock->hdr.size);
- bool * cur_in_use = &(pBlock->hdr.in_use);
- volatile bool in_use = false;
- bool new_in_use = false;
- do
- {
- in_use = pBlock->hdr.in_use;
- } while (! CAS((void * volatile *) cur_in_use, (void *) in_use, (void *) new_in_use));
-
- // do a lock-free update of the global memory total
- volatile size_t total = 0;
- volatile size_t new_total = 0;
- do
- {
- total = MemTotal;
- new_total = total - pBlock->hdr.size;
- } while (! CAS((void * volatile *)&MemTotal, (void *) total, (void *) new_total));
+ // get the pointer to the block record
+ Block * pBlock = (Block *)((unsigned char *) p - sizeof(BlockHeader));
+
+ // TRACE_MSG(pBlock->hdr.size);
+ bool * cur_in_use = &(pBlock->hdr.in_use);
+ volatile bool in_use = false;
+ bool new_in_use = false;
+ do
+ {
+ in_use = pBlock->hdr.in_use;
+ } while (! CAS((void * volatile *) cur_in_use, (void *) in_use, (void *) new_in_use));
+
+ // do a lock-free update of the global memory total
+ volatile size_t total = 0;
+ volatile size_t new_total = 0;
+ do
+ {
+ total = MemTotal;
+ new_total = total - pBlock->hdr.size;
+ } while (! CAS((void * volatile *)&MemTotal, (void *) total, (void *) new_total));
}
std::size_t GetMemTotal()
{
- return MemTotal;
+ return MemTotal;
}
void * operator new(std::size_t size) //throw(std::bad_alloc)
{
- return GetMem( size );
+ return GetMem( size );
}
void * operator new[](std::size_t size) //throw(std::bad_alloc)
{
- return GetMem( size );
+ return GetMem( size );
}
void operator delete(void * p) throw()
{
- if (p)
- {
- FreeMem( p );
- }
+ if (p)
+ {
+ FreeMem( p );
+ }
}
void operator delete[](void * p) throw()
{
- if (p)
- {
- FreeMem( p );
- }
+ if (p)
+ {
+ FreeMem( p );
+ }
}
diff --git a/indra/llcorehttp/tests/test_allocator.h b/indra/llcorehttp/tests/test_allocator.h
index abd88f4c98..2a06431d1b 100644
--- a/indra/llcorehttp/tests/test_allocator.h
+++ b/indra/llcorehttp/tests/test_allocator.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file test_allocator.h
* @brief quick and dirty allocator for tracking memory allocations
*
diff --git a/indra/llcorehttp/tests/test_bufferarray.hpp b/indra/llcorehttp/tests/test_bufferarray.hpp
index cc4ad2a906..2a272e73d7 100644
--- a/indra/llcorehttp/tests/test_bufferarray.hpp
+++ b/indra/llcorehttp/tests/test_bufferarray.hpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file test_bufferarray.hpp
* @brief unit tests for the LLCore::BufferArray class
*
@@ -40,8 +40,8 @@ namespace tut
struct BufferArrayTestData
{
- // the test objects inherit from this so the member functions and variables
- // can be referenced directly inside of the test functions.
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
};
typedef test_group<BufferArrayTestData> BufferArrayTestGroupType;
@@ -51,327 +51,327 @@ BufferArrayTestGroupType BufferArrayTestGroup("BufferArray Tests");
template <> template <>
void BufferArrayTestObjectType::test<1>()
{
- set_test_name("BufferArray construction");
-
- // create a new ref counted object with an implicit reference
- BufferArray * ba = new BufferArray();
- ensure("One ref on construction of BufferArray", ba->getRefCount() == 1);
- ensure("Nothing in BA", 0 == ba->size());
-
- // Try to read
- char buffer[20];
- size_t read_len(ba->read(0, buffer, sizeof(buffer)));
- ensure("Read returns empty", 0 == read_len);
-
- // release the implicit reference, causing the object to be released
- ba->release();
+ set_test_name("BufferArray construction");
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+ ensure("One ref on construction of BufferArray", ba->getRefCount() == 1);
+ ensure("Nothing in BA", 0 == ba->size());
+
+ // Try to read
+ char buffer[20];
+ size_t read_len(ba->read(0, buffer, sizeof(buffer)));
+ ensure("Read returns empty", 0 == read_len);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
}
template <> template <>
void BufferArrayTestObjectType::test<2>()
{
- set_test_name("BufferArray single write");
-
- // create a new ref counted object with an implicit reference
- BufferArray * ba = new BufferArray();
-
- // write some data to the buffer
- char str1[] = "abcdefghij";
- char buffer[256];
-
- size_t len = ba->write(0, str1, strlen(str1));
- ensure("Wrote length correct", strlen(str1) == len);
- ensure("Recorded size correct", strlen(str1) == ba->size());
-
- // read some data back
- memset(buffer, 'X', sizeof(buffer));
- len = ba->read(2, buffer, 2);
- ensure("Read length correct", 2 == len);
- ensure("Read content correct", 'c' == buffer[0] && 'd' == buffer[1]);
- ensure("Read didn't overwrite", 'X' == buffer[2]);
-
- // release the implicit reference, causing the object to be released
- ba->release();
+ set_test_name("BufferArray single write");
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ char buffer[256];
+
+ size_t len = ba->write(0, str1, strlen(str1));
+ ensure("Wrote length correct", strlen(str1) == len);
+ ensure("Recorded size correct", strlen(str1) == ba->size());
+
+ // read some data back
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(2, buffer, 2);
+ ensure("Read length correct", 2 == len);
+ ensure("Read content correct", 'c' == buffer[0] && 'd' == buffer[1]);
+ ensure("Read didn't overwrite", 'X' == buffer[2]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
}
template <> template <>
void BufferArrayTestObjectType::test<3>()
{
- set_test_name("BufferArray multiple writes");
-
- // create a new ref counted object with an implicit reference
- BufferArray * ba = new BufferArray();
-
- // write some data to the buffer
- char str1[] = "abcdefghij";
- size_t str1_len(strlen(str1));
- char buffer[256];
-
- size_t len = ba->write(0, str1, str1_len);
- ensure("Wrote length correct", str1_len == len);
- ensure("Recorded size correct", str1_len == ba->size());
-
- // again...
- len = ba->write(str1_len, str1, strlen(str1));
- ensure("Wrote length correct", str1_len == len);
- ensure("Recorded size correct", (2 * str1_len) == ba->size());
-
- // read some data back
- memset(buffer, 'X', sizeof(buffer));
- len = ba->read(8, buffer, 4);
- ensure("Read length correct", 4 == len);
- ensure("Read content correct", 'i' == buffer[0] && 'j' == buffer[1]);
- ensure("Read content correct", 'a' == buffer[2] && 'b' == buffer[3]);
- ensure("Read didn't overwrite", 'X' == buffer[4]);
-
- // Read whole thing
- memset(buffer, 'X', sizeof(buffer));
- len = ba->read(0, buffer, sizeof(buffer));
- ensure("Read length correct", (2 * str1_len) == len);
- ensure("Read content correct (3)", 0 == strncmp(buffer, str1, str1_len));
- ensure("Read content correct (4)", 0 == strncmp(&buffer[str1_len], str1, str1_len));
- ensure("Read didn't overwrite (5)", 'X' == buffer[2 * str1_len]);
-
- // release the implicit reference, causing the object to be released
- ba->release();
+ set_test_name("BufferArray multiple writes");
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ size_t str1_len(strlen(str1));
+ char buffer[256];
+
+ size_t len = ba->write(0, str1, str1_len);
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", str1_len == ba->size());
+
+ // again...
+ len = ba->write(str1_len, str1, strlen(str1));
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", (2 * str1_len) == ba->size());
+
+ // read some data back
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(8, buffer, 4);
+ ensure("Read length correct", 4 == len);
+ ensure("Read content correct", 'i' == buffer[0] && 'j' == buffer[1]);
+ ensure("Read content correct", 'a' == buffer[2] && 'b' == buffer[3]);
+ ensure("Read didn't overwrite", 'X' == buffer[4]);
+
+ // Read whole thing
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(0, buffer, sizeof(buffer));
+ ensure("Read length correct", (2 * str1_len) == len);
+ ensure("Read content correct (3)", 0 == strncmp(buffer, str1, str1_len));
+ ensure("Read content correct (4)", 0 == strncmp(&buffer[str1_len], str1, str1_len));
+ ensure("Read didn't overwrite (5)", 'X' == buffer[2 * str1_len]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
}
template <> template <>
void BufferArrayTestObjectType::test<4>()
{
- set_test_name("BufferArray overwriting");
-
- // create a new ref counted object with an implicit reference
- BufferArray * ba = new BufferArray();
-
- // write some data to the buffer
- char str1[] = "abcdefghij";
- size_t str1_len(strlen(str1));
- char str2[] = "ABCDEFGHIJ";
- char buffer[256];
-
- size_t len = ba->write(0, str1, str1_len);
- ensure("Wrote length correct", str1_len == len);
- ensure("Recorded size correct", str1_len == ba->size());
-
- // again...
- len = ba->write(str1_len, str1, strlen(str1));
- ensure("Wrote length correct", str1_len == len);
- ensure("Recorded size correct", (2 * str1_len) == ba->size());
-
- // reposition and overwrite
- len = ba->write(8, str2, 4);
- ensure("Overwrite length correct", 4 == len);
-
- // Leave position and read verifying content (stale really from seek() days)
- memset(buffer, 'X', sizeof(buffer));
- len = ba->read(12, buffer, 4);
- ensure("Read length correct", 4 == len);
- ensure("Read content correct", 'c' == buffer[0] && 'd' == buffer[1]);
- ensure("Read content correct.2", 'e' == buffer[2] && 'f' == buffer[3]);
- ensure("Read didn't overwrite", 'X' == buffer[4]);
-
- // reposition and check
- len = ba->read(6, buffer, 8);
- ensure("Read length correct.2", 8 == len);
- ensure("Read content correct.3", 'g' == buffer[0] && 'h' == buffer[1]);
- ensure("Read content correct.4", 'A' == buffer[2] && 'B' == buffer[3]);
- ensure("Read content correct.5", 'C' == buffer[4] && 'D' == buffer[5]);
- ensure("Read content correct.6", 'c' == buffer[6] && 'd' == buffer[7]);
- ensure("Read didn't overwrite.7", 'X' == buffer[8]);
-
- // release the implicit reference, causing the object to be released
- ba->release();
+ set_test_name("BufferArray overwriting");
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ size_t str1_len(strlen(str1));
+ char str2[] = "ABCDEFGHIJ";
+ char buffer[256];
+
+ size_t len = ba->write(0, str1, str1_len);
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", str1_len == ba->size());
+
+ // again...
+ len = ba->write(str1_len, str1, strlen(str1));
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", (2 * str1_len) == ba->size());
+
+ // reposition and overwrite
+ len = ba->write(8, str2, 4);
+ ensure("Overwrite length correct", 4 == len);
+
+ // Leave position and read verifying content (stale really from seek() days)
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(12, buffer, 4);
+ ensure("Read length correct", 4 == len);
+ ensure("Read content correct", 'c' == buffer[0] && 'd' == buffer[1]);
+ ensure("Read content correct.2", 'e' == buffer[2] && 'f' == buffer[3]);
+ ensure("Read didn't overwrite", 'X' == buffer[4]);
+
+ // reposition and check
+ len = ba->read(6, buffer, 8);
+ ensure("Read length correct.2", 8 == len);
+ ensure("Read content correct.3", 'g' == buffer[0] && 'h' == buffer[1]);
+ ensure("Read content correct.4", 'A' == buffer[2] && 'B' == buffer[3]);
+ ensure("Read content correct.5", 'C' == buffer[4] && 'D' == buffer[5]);
+ ensure("Read content correct.6", 'c' == buffer[6] && 'd' == buffer[7]);
+ ensure("Read didn't overwrite.7", 'X' == buffer[8]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
}
template <> template <>
void BufferArrayTestObjectType::test<5>()
{
- set_test_name("BufferArray multiple writes - sequential reads");
-
- // create a new ref counted object with an implicit reference
- BufferArray * ba = new BufferArray();
-
- // write some data to the buffer
- char str1[] = "abcdefghij";
- size_t str1_len(strlen(str1));
- char buffer[256];
-
- size_t len = ba->write(0, str1, str1_len);
- ensure("Wrote length correct", str1_len == len);
- ensure("Recorded size correct", str1_len == ba->size());
-
- // again...
- len = ba->write(str1_len, str1, str1_len);
- ensure("Wrote length correct", str1_len == len);
- ensure("Recorded size correct", (2 * str1_len) == ba->size());
-
- // read some data back
- memset(buffer, 'X', sizeof(buffer));
- len = ba->read(8, buffer, 4);
- ensure("Read length correct", 4 == len);
- ensure("Read content correct", 'i' == buffer[0] && 'j' == buffer[1]);
- ensure("Read content correct.2", 'a' == buffer[2] && 'b' == buffer[3]);
- ensure("Read didn't overwrite", 'X' == buffer[4]);
-
- // Read some more without repositioning
- memset(buffer, 'X', sizeof(buffer));
- len = ba->read(12, buffer, sizeof(buffer));
- ensure("Read length correct", (str1_len - 2) == len);
- ensure("Read content correct.3", 0 == strncmp(buffer, str1+2, str1_len-2));
- ensure("Read didn't overwrite.2", 'X' == buffer[str1_len-1]);
-
- // release the implicit reference, causing the object to be released
- ba->release();
+ set_test_name("BufferArray multiple writes - sequential reads");
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ size_t str1_len(strlen(str1));
+ char buffer[256];
+
+ size_t len = ba->write(0, str1, str1_len);
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", str1_len == ba->size());
+
+ // again...
+ len = ba->write(str1_len, str1, str1_len);
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", (2 * str1_len) == ba->size());
+
+ // read some data back
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(8, buffer, 4);
+ ensure("Read length correct", 4 == len);
+ ensure("Read content correct", 'i' == buffer[0] && 'j' == buffer[1]);
+ ensure("Read content correct.2", 'a' == buffer[2] && 'b' == buffer[3]);
+ ensure("Read didn't overwrite", 'X' == buffer[4]);
+
+ // Read some more without repositioning
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(12, buffer, sizeof(buffer));
+ ensure("Read length correct", (str1_len - 2) == len);
+ ensure("Read content correct.3", 0 == strncmp(buffer, str1+2, str1_len-2));
+ ensure("Read didn't overwrite.2", 'X' == buffer[str1_len-1]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
}
template <> template <>
void BufferArrayTestObjectType::test<6>()
{
- set_test_name("BufferArray overwrite spanning blocks and appending");
-
- // create a new ref counted object with an implicit reference
- BufferArray * ba = new BufferArray();
-
- // write some data to the buffer
- char str1[] = "abcdefghij";
- size_t str1_len(strlen(str1));
- char str2[] = "ABCDEFGHIJKLMNOPQRST";
- size_t str2_len(strlen(str2));
- char buffer[256];
-
- size_t len = ba->write(0, str1, str1_len);
- ensure("Wrote length correct", str1_len == len);
- ensure("Recorded size correct", str1_len == ba->size());
-
- // again...
- len = ba->write(str1_len, str1, strlen(str1));
- ensure("Wrote length correct", str1_len == len);
- ensure("Recorded size correct", (2 * str1_len) == ba->size());
-
- // reposition and overwrite
- len = ba->write(8, str2, str2_len);
- ensure("Overwrite length correct", str2_len == len);
-
- // Leave position and read verifying content
- memset(buffer, 'X', sizeof(buffer));
- len = ba->read(8 + str2_len, buffer, 0);
- ensure("Read length correct", 0 == len);
- ensure("Read didn't overwrite", 'X' == buffer[0]);
-
- // reposition and check
- len = ba->read(0, buffer, sizeof(buffer));
- ensure("Read length correct.2", (str1_len + str2_len - 2) == len);
- ensure("Read content correct", 0 == strncmp(buffer, str1, str1_len-2));
- ensure("Read content correct.2", 0 == strncmp(buffer+str1_len-2, str2, str2_len));
- ensure("Read didn't overwrite.2", 'X' == buffer[str1_len + str2_len - 2]);
-
- // release the implicit reference, causing the object to be released
- ba->release();
+ set_test_name("BufferArray overwrite spanning blocks and appending");
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ size_t str1_len(strlen(str1));
+ char str2[] = "ABCDEFGHIJKLMNOPQRST";
+ size_t str2_len(strlen(str2));
+ char buffer[256];
+
+ size_t len = ba->write(0, str1, str1_len);
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", str1_len == ba->size());
+
+ // again...
+ len = ba->write(str1_len, str1, strlen(str1));
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", (2 * str1_len) == ba->size());
+
+ // reposition and overwrite
+ len = ba->write(8, str2, str2_len);
+ ensure("Overwrite length correct", str2_len == len);
+
+ // Leave position and read verifying content
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(8 + str2_len, buffer, 0);
+ ensure("Read length correct", 0 == len);
+ ensure("Read didn't overwrite", 'X' == buffer[0]);
+
+ // reposition and check
+ len = ba->read(0, buffer, sizeof(buffer));
+ ensure("Read length correct.2", (str1_len + str2_len - 2) == len);
+ ensure("Read content correct", 0 == strncmp(buffer, str1, str1_len-2));
+ ensure("Read content correct.2", 0 == strncmp(buffer+str1_len-2, str2, str2_len));
+ ensure("Read didn't overwrite.2", 'X' == buffer[str1_len + str2_len - 2]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
}
template <> template <>
void BufferArrayTestObjectType::test<7>()
{
- set_test_name("BufferArray overwrite spanning blocks and sequential writes");
-
- // create a new ref counted object with an implicit reference
- BufferArray * ba = new BufferArray();
-
- // write some data to the buffer
- char str1[] = "abcdefghij";
- size_t str1_len(strlen(str1));
- char str2[] = "ABCDEFGHIJKLMNOPQRST";
- size_t str2_len(strlen(str2));
- char buffer[256];
-
- // 2x str1
- size_t len = ba->write(0, str1, str1_len);
- len = ba->write(str1_len, str1, str1_len);
-
- // reposition and overwrite
- len = ba->write(6, str2, 2);
- ensure("Overwrite length correct", 2 == len);
-
- len = ba->write(8, str2, 2);
- ensure("Overwrite length correct.2", 2 == len);
-
- len = ba->write(10, str2, 2);
- ensure("Overwrite length correct.3", 2 == len);
-
- // append some data
- len = ba->append(str2, str2_len);
- ensure("Append length correct", str2_len == len);
-
- // append some more
- void * out_buf(ba->appendBufferAlloc(str1_len));
- memcpy(out_buf, str1, str1_len);
-
- // And some final writes
- len = ba->write(3 * str1_len + str2_len, str2, 2);
- ensure("Write length correct.2", 2 == len);
-
- // Check contents
- memset(buffer, 'X', sizeof(buffer));
- len = ba->read(0, buffer, sizeof(buffer));
- ensure("Final buffer length correct", (3 * str1_len + str2_len + 2) == len);
- ensure("Read content correct", 0 == strncmp(buffer, str1, 6));
- ensure("Read content correct.2", 0 == strncmp(buffer + 6, str2, 2));
- ensure("Read content correct.3", 0 == strncmp(buffer + 8, str2, 2));
- ensure("Read content correct.4", 0 == strncmp(buffer + 10, str2, 2));
- ensure("Read content correct.5", 0 == strncmp(buffer + str1_len + 2, str1 + 2, str1_len - 2));
- ensure("Read content correct.6", 0 == strncmp(buffer + str1_len + str1_len, str2, str2_len));
- ensure("Read content correct.7", 0 == strncmp(buffer + str1_len + str1_len + str2_len, str1, str1_len));
- ensure("Read content correct.8", 0 == strncmp(buffer + str1_len + str1_len + str2_len + str1_len, str2, 2));
- ensure("Read didn't overwrite", 'X' == buffer[str1_len + str1_len + str2_len + str1_len + 2]);
-
- // release the implicit reference, causing the object to be released
- ba->release();
+ set_test_name("BufferArray overwrite spanning blocks and sequential writes");
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ size_t str1_len(strlen(str1));
+ char str2[] = "ABCDEFGHIJKLMNOPQRST";
+ size_t str2_len(strlen(str2));
+ char buffer[256];
+
+ // 2x str1
+ size_t len = ba->write(0, str1, str1_len);
+ len = ba->write(str1_len, str1, str1_len);
+
+ // reposition and overwrite
+ len = ba->write(6, str2, 2);
+ ensure("Overwrite length correct", 2 == len);
+
+ len = ba->write(8, str2, 2);
+ ensure("Overwrite length correct.2", 2 == len);
+
+ len = ba->write(10, str2, 2);
+ ensure("Overwrite length correct.3", 2 == len);
+
+ // append some data
+ len = ba->append(str2, str2_len);
+ ensure("Append length correct", str2_len == len);
+
+ // append some more
+ void * out_buf(ba->appendBufferAlloc(str1_len));
+ memcpy(out_buf, str1, str1_len);
+
+ // And some final writes
+ len = ba->write(3 * str1_len + str2_len, str2, 2);
+ ensure("Write length correct.2", 2 == len);
+
+ // Check contents
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(0, buffer, sizeof(buffer));
+ ensure("Final buffer length correct", (3 * str1_len + str2_len + 2) == len);
+ ensure("Read content correct", 0 == strncmp(buffer, str1, 6));
+ ensure("Read content correct.2", 0 == strncmp(buffer + 6, str2, 2));
+ ensure("Read content correct.3", 0 == strncmp(buffer + 8, str2, 2));
+ ensure("Read content correct.4", 0 == strncmp(buffer + 10, str2, 2));
+ ensure("Read content correct.5", 0 == strncmp(buffer + str1_len + 2, str1 + 2, str1_len - 2));
+ ensure("Read content correct.6", 0 == strncmp(buffer + str1_len + str1_len, str2, str2_len));
+ ensure("Read content correct.7", 0 == strncmp(buffer + str1_len + str1_len + str2_len, str1, str1_len));
+ ensure("Read content correct.8", 0 == strncmp(buffer + str1_len + str1_len + str2_len + str1_len, str2, 2));
+ ensure("Read didn't overwrite", 'X' == buffer[str1_len + str1_len + str2_len + str1_len + 2]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
}
template <> template <>
void BufferArrayTestObjectType::test<8>()
{
- set_test_name("BufferArray zero-length appendBufferAlloc");
-
- // create a new ref counted object with an implicit reference
- BufferArray * ba = new BufferArray();
-
- // write some data to the buffer
- char str1[] = "abcdefghij";
- size_t str1_len(strlen(str1));
- char str2[] = "ABCDEFGHIJKLMNOPQRST";
- size_t str2_len(strlen(str2));
- char buffer[256];
-
- // 2x str1
- size_t len = ba->write(0, str1, str1_len);
- len = ba->write(str1_len, str1, str1_len);
-
- // zero-length allocate (we allow this with a valid pointer returned)
- void * out_buf(ba->appendBufferAlloc(0));
- ensure("Buffer from zero-length appendBufferAlloc non-NULL", NULL != out_buf);
-
- // Do it again
- void * out_buf2(ba->appendBufferAlloc(0));
- ensure("Buffer from zero-length appendBufferAlloc non-NULL.2", NULL != out_buf2);
- ensure("Two zero-length appendBufferAlloc buffers distinct", out_buf != out_buf2);
-
- // And some final writes
- len = ba->write(2 * str1_len, str2, str2_len);
-
- // Check contents
- memset(buffer, 'X', sizeof(buffer));
- len = ba->read(0, buffer, sizeof(buffer));
- ensure("Final buffer length correct", (2 * str1_len + str2_len) == len);
- ensure("Read content correct.1", 0 == strncmp(buffer, str1, str1_len));
- ensure("Read content correct.2", 0 == strncmp(buffer + str1_len, str1, str1_len));
- ensure("Read content correct.3", 0 == strncmp(buffer + str1_len + str1_len, str2, str2_len));
- ensure("Read didn't overwrite", 'X' == buffer[str1_len + str1_len + str2_len]);
-
- // release the implicit reference, causing the object to be released
- ba->release();
+ set_test_name("BufferArray zero-length appendBufferAlloc");
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ size_t str1_len(strlen(str1));
+ char str2[] = "ABCDEFGHIJKLMNOPQRST";
+ size_t str2_len(strlen(str2));
+ char buffer[256];
+
+ // 2x str1
+ size_t len = ba->write(0, str1, str1_len);
+ len = ba->write(str1_len, str1, str1_len);
+
+ // zero-length allocate (we allow this with a valid pointer returned)
+ void * out_buf(ba->appendBufferAlloc(0));
+ ensure("Buffer from zero-length appendBufferAlloc non-NULL", NULL != out_buf);
+
+ // Do it again
+ void * out_buf2(ba->appendBufferAlloc(0));
+ ensure("Buffer from zero-length appendBufferAlloc non-NULL.2", NULL != out_buf2);
+ ensure("Two zero-length appendBufferAlloc buffers distinct", out_buf != out_buf2);
+
+ // And some final writes
+ len = ba->write(2 * str1_len, str2, str2_len);
+
+ // Check contents
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(0, buffer, sizeof(buffer));
+ ensure("Final buffer length correct", (2 * str1_len + str2_len) == len);
+ ensure("Read content correct.1", 0 == strncmp(buffer, str1, str1_len));
+ ensure("Read content correct.2", 0 == strncmp(buffer + str1_len, str1, str1_len));
+ ensure("Read content correct.3", 0 == strncmp(buffer + str1_len + str1_len, str2, str2_len));
+ ensure("Read didn't overwrite", 'X' == buffer[str1_len + str1_len + str2_len]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
}
} // end namespace tut
diff --git a/indra/llcorehttp/tests/test_bufferstream.hpp b/indra/llcorehttp/tests/test_bufferstream.hpp
index 2739a6e38e..556abf45a2 100644
--- a/indra/llcorehttp/tests/test_bufferstream.hpp
+++ b/indra/llcorehttp/tests/test_bufferstream.hpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file test_bufferstream.hpp
* @brief unit tests for the LLCore::BufferArrayStreamBuf/BufferArrayStream classes
*
@@ -42,8 +42,8 @@ namespace tut
struct BufferStreamTestData
{
- // the test objects inherit from this so the member functions and variables
- // can be referenced directly inside of the test functions.
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
};
typedef test_group<BufferStreamTestData> BufferStreamTestGroupType;
@@ -55,194 +55,194 @@ typedef BufferArrayStreamBuf::traits_type tst_traits_t;
template <> template <>
void BufferStreamTestObjectType::test<1>()
{
- set_test_name("BufferArrayStreamBuf construction with NULL BufferArray");
-
- // create a new ref counted object with an implicit reference
- BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(NULL);
-
- // Not much will work with a NULL
- ensure("underflow() on NULL fails", tst_traits_t::eof() == bsb->underflow());
- ensure("uflow() on NULL fails", tst_traits_t::eof() == bsb->uflow());
- ensure("pbackfail() on NULL fails", tst_traits_t::eof() == bsb->pbackfail('c'));
- ensure("showmanyc() on NULL fails", bsb->showmanyc() == -1);
- ensure("overflow() on NULL fails", tst_traits_t::eof() == bsb->overflow('c'));
- ensure("xsputn() on NULL fails", bsb->xsputn("blah", 4) == 0);
- ensure("seekoff() on NULL fails", bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(-1));
-
- // release the implicit reference, causing the object to be released
- delete bsb;
- bsb = NULL;
+ set_test_name("BufferArrayStreamBuf construction with NULL BufferArray");
+
+ // create a new ref counted object with an implicit reference
+ BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(NULL);
+
+ // Not much will work with a NULL
+ ensure("underflow() on NULL fails", tst_traits_t::eof() == bsb->underflow());
+ ensure("uflow() on NULL fails", tst_traits_t::eof() == bsb->uflow());
+ ensure("pbackfail() on NULL fails", tst_traits_t::eof() == bsb->pbackfail('c'));
+ ensure("showmanyc() on NULL fails", bsb->showmanyc() == -1);
+ ensure("overflow() on NULL fails", tst_traits_t::eof() == bsb->overflow('c'));
+ ensure("xsputn() on NULL fails", bsb->xsputn("blah", 4) == 0);
+ ensure("seekoff() on NULL fails", bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(-1));
+
+ // release the implicit reference, causing the object to be released
+ delete bsb;
+ bsb = NULL;
}
template <> template <>
void BufferStreamTestObjectType::test<2>()
{
- set_test_name("BufferArrayStream construction with NULL BufferArray");
-
- // create a new ref counted object with an implicit reference
- BufferArrayStream * bas = new BufferArrayStream(NULL);
-
- // Not much will work with a NULL here
- ensure("eof() is false on NULL", ! bas->eof());
- ensure("fail() is false on NULL", ! bas->fail());
- ensure("good() on NULL", bas->good());
-
- // release the implicit reference, causing the object to be released
- delete bas;
- bas = NULL;
+ set_test_name("BufferArrayStream construction with NULL BufferArray");
+
+ // create a new ref counted object with an implicit reference
+ BufferArrayStream * bas = new BufferArrayStream(NULL);
+
+ // Not much will work with a NULL here
+ ensure("eof() is false on NULL", ! bas->eof());
+ ensure("fail() is false on NULL", ! bas->fail());
+ ensure("good() on NULL", bas->good());
+
+ // release the implicit reference, causing the object to be released
+ delete bas;
+ bas = NULL;
}
template <> template <>
void BufferStreamTestObjectType::test<3>()
{
- set_test_name("BufferArrayStreamBuf construction with empty BufferArray");
-
- // create a new ref counted BufferArray with implicit reference
- BufferArray * ba = new BufferArray;
- BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba);
-
- // I can release my ref on the BA
- ba->release();
- ba = NULL;
-
- // release the implicit reference, causing the object to be released
- delete bsb;
- bsb = NULL;
+ set_test_name("BufferArrayStreamBuf construction with empty BufferArray");
+
+ // create a new ref counted BufferArray with implicit reference
+ BufferArray * ba = new BufferArray;
+ BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba);
+
+ // I can release my ref on the BA
+ ba->release();
+ ba = NULL;
+
+ // release the implicit reference, causing the object to be released
+ delete bsb;
+ bsb = NULL;
}
template <> template <>
void BufferStreamTestObjectType::test<4>()
{
- set_test_name("BufferArrayStream construction with empty BufferArray");
+ set_test_name("BufferArrayStream construction with empty BufferArray");
- // create a new ref counted BufferArray with implicit reference
- BufferArray * ba = new BufferArray;
+ // create a new ref counted BufferArray with implicit reference
+ BufferArray * ba = new BufferArray;
- {
- // create a new ref counted object with an implicit reference
- BufferArrayStream bas(ba);
- }
+ {
+ // create a new ref counted object with an implicit reference
+ BufferArrayStream bas(ba);
+ }
- // release the implicit reference, causing the object to be released
- ba->release();
- ba = NULL;
+ // release the implicit reference, causing the object to be released
+ ba->release();
+ ba = NULL;
}
template <> template <>
void BufferStreamTestObjectType::test<5>()
{
- set_test_name("BufferArrayStreamBuf construction with real BufferArray");
-
- // create a new ref counted BufferArray with implicit reference
- BufferArray * ba = new BufferArray;
- const char * content("This is a string. A fragment.");
- const size_t c_len(strlen(content));
- ba->append(content, c_len);
-
- // Creat an adapter for the BufferArray
- BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba);
-
- // I can release my ref on the BA
- ba->release();
- ba = NULL;
-
- // Various static state
- ensure("underflow() returns 'T'", bsb->underflow() == 'T');
- ensure("underflow() returns 'T' again", bsb->underflow() == 'T');
- ensure("uflow() returns 'T'", bsb->uflow() == 'T');
- ensure("uflow() returns 'h'", bsb->uflow() == 'h');
- ensure("pbackfail('i') fails", tst_traits_t::eof() == bsb->pbackfail('i'));
- ensure("pbackfail('T') fails", tst_traits_t::eof() == bsb->pbackfail('T'));
- ensure("pbackfail('h') succeeds", bsb->pbackfail('h') == 'h');
- ensure("showmanyc() is everything but the 'T'", bsb->showmanyc() == (c_len - 1));
- ensure("overflow() appends", bsb->overflow('c') == 'c');
- ensure("showmanyc() reflects append", bsb->showmanyc() == (c_len - 1 + 1));
- ensure("xsputn() appends some more", bsb->xsputn("bla!", 4) == 4);
- ensure("showmanyc() reflects 2nd append", bsb->showmanyc() == (c_len - 1 + 5));
- ensure("seekoff() succeeds", bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(0));
- ensure("seekoff() succeeds 2", bsb->seekoff(4, std::ios_base::cur, std::ios_base::in) == std::streampos(4));
- ensure("showmanyc() picks up seekoff", bsb->showmanyc() == (c_len + 5 - 4));
- ensure("seekoff() succeeds 3", bsb->seekoff(0, std::ios_base::end, std::ios_base::in) == std::streampos(c_len + 4));
- ensure("pbackfail('!') succeeds", tst_traits_t::eof() == bsb->pbackfail('!'));
-
- // release the implicit reference, causing the object to be released
- delete bsb;
- bsb = NULL;
+ set_test_name("BufferArrayStreamBuf construction with real BufferArray");
+
+ // create a new ref counted BufferArray with implicit reference
+ BufferArray * ba = new BufferArray;
+ const char * content("This is a string. A fragment.");
+ const size_t c_len(strlen(content));
+ ba->append(content, c_len);
+
+ // Creat an adapter for the BufferArray
+ BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba);
+
+ // I can release my ref on the BA
+ ba->release();
+ ba = NULL;
+
+ // Various static state
+ ensure("underflow() returns 'T'", bsb->underflow() == 'T');
+ ensure("underflow() returns 'T' again", bsb->underflow() == 'T');
+ ensure("uflow() returns 'T'", bsb->uflow() == 'T');
+ ensure("uflow() returns 'h'", bsb->uflow() == 'h');
+ ensure("pbackfail('i') fails", tst_traits_t::eof() == bsb->pbackfail('i'));
+ ensure("pbackfail('T') fails", tst_traits_t::eof() == bsb->pbackfail('T'));
+ ensure("pbackfail('h') succeeds", bsb->pbackfail('h') == 'h');
+ ensure("showmanyc() is everything but the 'T'", bsb->showmanyc() == (c_len - 1));
+ ensure("overflow() appends", bsb->overflow('c') == 'c');
+ ensure("showmanyc() reflects append", bsb->showmanyc() == (c_len - 1 + 1));
+ ensure("xsputn() appends some more", bsb->xsputn("bla!", 4) == 4);
+ ensure("showmanyc() reflects 2nd append", bsb->showmanyc() == (c_len - 1 + 5));
+ ensure("seekoff() succeeds", bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(0));
+ ensure("seekoff() succeeds 2", bsb->seekoff(4, std::ios_base::cur, std::ios_base::in) == std::streampos(4));
+ ensure("showmanyc() picks up seekoff", bsb->showmanyc() == (c_len + 5 - 4));
+ ensure("seekoff() succeeds 3", bsb->seekoff(0, std::ios_base::end, std::ios_base::in) == std::streampos(c_len + 4));
+ ensure("pbackfail('!') succeeds", tst_traits_t::eof() == bsb->pbackfail('!'));
+
+ // release the implicit reference, causing the object to be released
+ delete bsb;
+ bsb = NULL;
}
template <> template <>
void BufferStreamTestObjectType::test<6>()
{
- set_test_name("BufferArrayStream construction with real BufferArray");
-
- // create a new ref counted BufferArray with implicit reference
- BufferArray * ba = new BufferArray;
- //const char * content("This is a string. A fragment.");
- //const size_t c_len(strlen(content));
- //ba->append(content, strlen(content));
-
- {
- // Creat an adapter for the BufferArray
- BufferArrayStream bas(ba);
-
- // Basic operations
- bas << "Hello" << 27 << ".";
- ensure("BA length 8", ba->size() == 8);
-
- std::string str;
- bas >> str;
- ensure("reads correctly", str == "Hello27.");
- }
-
- // release the implicit reference, causing the object to be released
- ba->release();
- ba = NULL;
+ set_test_name("BufferArrayStream construction with real BufferArray");
+
+ // create a new ref counted BufferArray with implicit reference
+ BufferArray * ba = new BufferArray;
+ //const char * content("This is a string. A fragment.");
+ //const size_t c_len(strlen(content));
+ //ba->append(content, strlen(content));
+
+ {
+ // Creat an adapter for the BufferArray
+ BufferArrayStream bas(ba);
+
+ // Basic operations
+ bas << "Hello" << 27 << ".";
+ ensure("BA length 8", ba->size() == 8);
+
+ std::string str;
+ bas >> str;
+ ensure("reads correctly", str == "Hello27.");
+ }
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
+ ba = NULL;
}
template <> template <>
void BufferStreamTestObjectType::test<7>()
{
- set_test_name("BufferArrayStream with LLSD serialization");
+ set_test_name("BufferArrayStream with LLSD serialization");
+
+ // create a new ref counted BufferArray with implicit reference
+ BufferArray * ba = new BufferArray;
- // create a new ref counted BufferArray with implicit reference
- BufferArray * ba = new BufferArray;
+ {
+ // Creat an adapter for the BufferArray
+ BufferArrayStream bas(ba);
- {
- // Creat an adapter for the BufferArray
- BufferArrayStream bas(ba);
+ // LLSD
+ LLSD llsd = LLSD::emptyMap();
- // LLSD
- LLSD llsd = LLSD::emptyMap();
+ llsd["int"] = LLSD::Integer(3);
+ llsd["float"] = LLSD::Real(923289.28992);
+ llsd["string"] = LLSD::String("aksjdl;ajsdgfjgfal;sdgjakl;sdfjkl;ajsdfkl;ajsdfkl;jaskl;dfj");
- llsd["int"] = LLSD::Integer(3);
- llsd["float"] = LLSD::Real(923289.28992);
- llsd["string"] = LLSD::String("aksjdl;ajsdgfjgfal;sdgjakl;sdfjkl;ajsdfkl;ajsdfkl;jaskl;dfj");
+ LLSD llsd_map = LLSD::emptyMap();
+ llsd_map["int"] = LLSD::Integer(-2889);
+ llsd_map["float"] = LLSD::Real(2.37829e32);
+ llsd_map["string"] = LLSD::String("OHIGODHSPDGHOSDHGOPSHDGP");
- LLSD llsd_map = LLSD::emptyMap();
- llsd_map["int"] = LLSD::Integer(-2889);
- llsd_map["float"] = LLSD::Real(2.37829e32);
- llsd_map["string"] = LLSD::String("OHIGODHSPDGHOSDHGOPSHDGP");
+ llsd["map"] = llsd_map;
- llsd["map"] = llsd_map;
-
- // Serialize it
- LLSDSerialize::toXML(llsd, bas);
+ // Serialize it
+ LLSDSerialize::toXML(llsd, bas);
- std::string str;
- bas >> str;
- // std::cout << "SERIALIZED LLSD: " << str << std::endl;
- ensure("Extracted string has reasonable length", str.size() > 60);
- }
+ std::string str;
+ bas >> str;
+ // std::cout << "SERIALIZED LLSD: " << str << std::endl;
+ ensure("Extracted string has reasonable length", str.size() > 60);
+ }
- // release the implicit reference, causing the object to be released
- ba->release();
- ba = NULL;
+ // release the implicit reference, causing the object to be released
+ ba->release();
+ ba = NULL;
}
diff --git a/indra/llcorehttp/tests/test_httpheaders.hpp b/indra/llcorehttp/tests/test_httpheaders.hpp
index 6aefb5054b..d8eff78ca5 100644
--- a/indra/llcorehttp/tests/test_httpheaders.hpp
+++ b/indra/llcorehttp/tests/test_httpheaders.hpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file test_httpheaders.hpp
* @brief unit tests for the LLCore::HttpHeaders class
*
@@ -39,8 +39,8 @@ namespace tut
struct HttpHeadersTestData
{
- // the test objects inherit from this so the member functions and variables
- // can be referenced directly inside of the test functions.
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
};
typedef test_group<HttpHeadersTestData> HttpHeadersTestGroupType;
@@ -50,181 +50,181 @@ HttpHeadersTestGroupType HttpHeadersTestGroup("HttpHeaders Tests");
template <> template <>
void HttpHeadersTestObjectType::test<1>()
{
- set_test_name("HttpHeaders construction");
+ set_test_name("HttpHeaders construction");
- // create a new ref counted object with an implicit reference
- HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders());
- ensure("Nothing in headers", 0 == headers->size());
+ // create a new ref counted object with an implicit reference
+ HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders());
+ ensure("Nothing in headers", 0 == headers->size());
- // release the implicit reference, causing the object to be released
+ // release the implicit reference, causing the object to be released
headers.reset();
}
template <> template <>
void HttpHeadersTestObjectType::test<2>()
{
- set_test_name("HttpHeaders construction");
-
- // create a new ref counted object with an implicit reference
- HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders());
-
- {
- // Append a few strings
- std::string str1n("Pragma");
- std::string str1v("");
- headers->append(str1n, str1v);
- std::string str2n("Accept");
- std::string str2v("application/json");
- headers->append(str2n, str2v);
-
- ensure("Headers retained", 2 == headers->size());
- HttpHeaders::container_t & c(headers->getContainerTESTONLY());
-
- ensure("First name is first name", c[0].first == str1n);
- ensure("First value is first value", c[0].second == str1v);
- ensure("Second name is second name", c[1].first == str2n);
- ensure("Second value is second value", c[1].second == str2v);
- }
-
- // release the implicit reference, causing the object to be released
+ set_test_name("HttpHeaders construction");
+
+ // create a new ref counted object with an implicit reference
+ HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders());
+
+ {
+ // Append a few strings
+ std::string str1n("Pragma");
+ std::string str1v("");
+ headers->append(str1n, str1v);
+ std::string str2n("Accept");
+ std::string str2v("application/json");
+ headers->append(str2n, str2v);
+
+ ensure("Headers retained", 2 == headers->size());
+ HttpHeaders::container_t & c(headers->getContainerTESTONLY());
+
+ ensure("First name is first name", c[0].first == str1n);
+ ensure("First value is first value", c[0].second == str1v);
+ ensure("Second name is second name", c[1].first == str2n);
+ ensure("Second value is second value", c[1].second == str2v);
+ }
+
+ // release the implicit reference, causing the object to be released
headers.reset();
}
template <> template <>
void HttpHeadersTestObjectType::test<3>()
{
- set_test_name("HttpHeaders basic find");
-
- // create a new ref counted object with an implicit reference
- HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders());
-
- {
- // Append a few strings
- std::string str1n("Uno");
- std::string str1v("1");
- headers->append(str1n, str1v);
- std::string str2n("doS");
- std::string str2v("2-2-2-2");
- headers->append(str2n, str2v);
- std::string str3n("TRES");
- std::string str3v("trois gymnopedie");
- headers->append(str3n, str3v);
-
- ensure("Headers retained", 3 == headers->size());
-
- const std::string * result(NULL);
-
- // Find a header
- result = headers->find("TRES");
- ensure("Found the last item", result != NULL);
- ensure("Last item is a nice", result != NULL && str3v == *result);
-
- // appends above are raw and find is case sensitive
- result = headers->find("TReS");
- ensure("Last item not found due to case", result == NULL);
-
- result = headers->find("TRE");
- ensure("Last item not found due to prefixing (1)", result == NULL);
-
- result = headers->find("TRESS");
- ensure("Last item not found due to prefixing (2)", result == NULL);
- }
-
- // release the implicit reference, causing the object to be released
+ set_test_name("HttpHeaders basic find");
+
+ // create a new ref counted object with an implicit reference
+ HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders());
+
+ {
+ // Append a few strings
+ std::string str1n("Uno");
+ std::string str1v("1");
+ headers->append(str1n, str1v);
+ std::string str2n("doS");
+ std::string str2v("2-2-2-2");
+ headers->append(str2n, str2v);
+ std::string str3n("TRES");
+ std::string str3v("trois gymnopedie");
+ headers->append(str3n, str3v);
+
+ ensure("Headers retained", 3 == headers->size());
+
+ const std::string * result(NULL);
+
+ // Find a header
+ result = headers->find("TRES");
+ ensure("Found the last item", result != NULL);
+ ensure("Last item is a nice", result != NULL && str3v == *result);
+
+ // appends above are raw and find is case sensitive
+ result = headers->find("TReS");
+ ensure("Last item not found due to case", result == NULL);
+
+ result = headers->find("TRE");
+ ensure("Last item not found due to prefixing (1)", result == NULL);
+
+ result = headers->find("TRESS");
+ ensure("Last item not found due to prefixing (2)", result == NULL);
+ }
+
+ // release the implicit reference, causing the object to be released
headers.reset();
}
template <> template <>
void HttpHeadersTestObjectType::test<4>()
{
- set_test_name("HttpHeaders normalized header entry");
+ set_test_name("HttpHeaders normalized header entry");
- // create a new ref counted object with an implicit reference
+ // create a new ref counted object with an implicit reference
HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders());
- {
- static char line1[] = " AcCePT : image/yourfacehere";
- static char line1v[] = "image/yourfacehere";
- headers->appendNormal(line1, sizeof(line1) - 1);
-
- ensure("First append worked in some fashion", 1 == headers->size());
-
- const std::string * result(NULL);
-
- // Find a header
- result = headers->find("accept");
- ensure("Found 'accept'", result != NULL);
- ensure("accept value has face", result != NULL && *result == line1v);
-
- // Left-clean on value
- static char line2[] = " next : \t\tlinejunk \t";
- headers->appendNormal(line2, sizeof(line2) - 1);
- ensure("Second append worked", 2 == headers->size());
- result = headers->find("next");
- ensure("Found 'next'", result != NULL);
- ensure("next value is left-clean", result != NULL &&
- *result == "linejunk \t");
-
- // First value unmolested
- result = headers->find("accept");
- ensure("Found 'accept' again", result != NULL);
- ensure("accept value has face", result != NULL && *result == line1v);
-
- // Colons in value are okay
- static char line3[] = "FancY-PANTs::plop:-neuf-=vleem=";
- static char line3v[] = ":plop:-neuf-=vleem=";
- headers->appendNormal(line3, sizeof(line3) - 1);
- ensure("Third append worked", 3 == headers->size());
- result = headers->find("fancy-pants");
- ensure("Found 'fancy-pants'", result != NULL);
- ensure("fancy-pants value has colons", result != NULL && *result == line3v);
-
- // Zero-length value
- static char line4[] = "all-talk-no-walk:";
- headers->appendNormal(line4, sizeof(line4) - 1);
- ensure("Fourth append worked", 4 == headers->size());
- result = headers->find("all-talk-no-walk");
- ensure("Found 'all-talk'", result != NULL);
- ensure("al-talk value is zero-length", result != NULL && result->size() == 0);
-
- // Zero-length name
- static char line5[] = ":all-talk-no-walk";
- static char line5v[] = "all-talk-no-walk";
- headers->appendNormal(line5, sizeof(line5) - 1);
- ensure("Fifth append worked", 5 == headers->size());
- result = headers->find("");
- ensure("Found no-name", result != NULL);
- ensure("no-name value is something", result != NULL && *result == line5v);
-
- // Lone colon is still something
- headers->clear();
- static char line6[] = " :";
- headers->appendNormal(line6, sizeof(line6) - 1);
- ensure("Sixth append worked", 1 == headers->size());
- result = headers->find("");
- ensure("Found 2nd no-name", result != NULL);
- ensure("2nd no-name value is nothing", result != NULL && result->size() == 0);
-
- // Line without colons is taken as-is and unstripped in name
- static char line7[] = " \toskdgioasdghaosdghoowg28342908tg8902hg0hwedfhqew890v7qh0wdebv78q0wdevbhq>?M>BNM<ZV>?NZ? \t";
- headers->appendNormal(line7, sizeof(line7) - 1);
- ensure("Seventh append worked", 2 == headers->size());
- result = headers->find(line7);
- ensure("Found whatsit line", result != NULL);
- ensure("Whatsit line has no value", result != NULL && result->size() == 0);
-
- // Normaling interface heeds the byte count, doesn't look for NUL-terminator
- static char line8[] = "binary:ignorestuffontheendofthis";
- headers->appendNormal(line8, 13);
- ensure("Eighth append worked", 3 == headers->size());
- result = headers->find("binary");
- ensure("Found 'binary'", result != NULL);
- ensure("binary value was limited to 'ignore'", result != NULL &&
- *result == "ignore");
-
- }
-
- // release the implicit reference, causing the object to be released
+ {
+ static char line1[] = " AcCePT : image/yourfacehere";
+ static char line1v[] = "image/yourfacehere";
+ headers->appendNormal(line1, sizeof(line1) - 1);
+
+ ensure("First append worked in some fashion", 1 == headers->size());
+
+ const std::string * result(NULL);
+
+ // Find a header
+ result = headers->find("accept");
+ ensure("Found 'accept'", result != NULL);
+ ensure("accept value has face", result != NULL && *result == line1v);
+
+ // Left-clean on value
+ static char line2[] = " next : \t\tlinejunk \t";
+ headers->appendNormal(line2, sizeof(line2) - 1);
+ ensure("Second append worked", 2 == headers->size());
+ result = headers->find("next");
+ ensure("Found 'next'", result != NULL);
+ ensure("next value is left-clean", result != NULL &&
+ *result == "linejunk \t");
+
+ // First value unmolested
+ result = headers->find("accept");
+ ensure("Found 'accept' again", result != NULL);
+ ensure("accept value has face", result != NULL && *result == line1v);
+
+ // Colons in value are okay
+ static char line3[] = "FancY-PANTs::plop:-neuf-=vleem=";
+ static char line3v[] = ":plop:-neuf-=vleem=";
+ headers->appendNormal(line3, sizeof(line3) - 1);
+ ensure("Third append worked", 3 == headers->size());
+ result = headers->find("fancy-pants");
+ ensure("Found 'fancy-pants'", result != NULL);
+ ensure("fancy-pants value has colons", result != NULL && *result == line3v);
+
+ // Zero-length value
+ static char line4[] = "all-talk-no-walk:";
+ headers->appendNormal(line4, sizeof(line4) - 1);
+ ensure("Fourth append worked", 4 == headers->size());
+ result = headers->find("all-talk-no-walk");
+ ensure("Found 'all-talk'", result != NULL);
+ ensure("al-talk value is zero-length", result != NULL && result->size() == 0);
+
+ // Zero-length name
+ static char line5[] = ":all-talk-no-walk";
+ static char line5v[] = "all-talk-no-walk";
+ headers->appendNormal(line5, sizeof(line5) - 1);
+ ensure("Fifth append worked", 5 == headers->size());
+ result = headers->find("");
+ ensure("Found no-name", result != NULL);
+ ensure("no-name value is something", result != NULL && *result == line5v);
+
+ // Lone colon is still something
+ headers->clear();
+ static char line6[] = " :";
+ headers->appendNormal(line6, sizeof(line6) - 1);
+ ensure("Sixth append worked", 1 == headers->size());
+ result = headers->find("");
+ ensure("Found 2nd no-name", result != NULL);
+ ensure("2nd no-name value is nothing", result != NULL && result->size() == 0);
+
+ // Line without colons is taken as-is and unstripped in name
+ static char line7[] = " \toskdgioasdghaosdghoowg28342908tg8902hg0hwedfhqew890v7qh0wdebv78q0wdevbhq>?M>BNM<ZV>?NZ? \t";
+ headers->appendNormal(line7, sizeof(line7) - 1);
+ ensure("Seventh append worked", 2 == headers->size());
+ result = headers->find(line7);
+ ensure("Found whatsit line", result != NULL);
+ ensure("Whatsit line has no value", result != NULL && result->size() == 0);
+
+ // Normaling interface heeds the byte count, doesn't look for NUL-terminator
+ static char line8[] = "binary:ignorestuffontheendofthis";
+ headers->appendNormal(line8, 13);
+ ensure("Eighth append worked", 3 == headers->size());
+ result = headers->find("binary");
+ ensure("Found 'binary'", result != NULL);
+ ensure("binary value was limited to 'ignore'", result != NULL &&
+ *result == "ignore");
+
+ }
+
+ // release the implicit reference, causing the object to be released
headers.reset();
}
@@ -232,79 +232,79 @@ void HttpHeadersTestObjectType::test<4>()
template <> template <>
void HttpHeadersTestObjectType::test<5>()
{
- set_test_name("HttpHeaders iterator tests");
+ set_test_name("HttpHeaders iterator tests");
- // create a new ref counted object with an implicit reference
+ // create a new ref counted object with an implicit reference
HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders());
- HttpHeaders::iterator end(headers->end()), begin(headers->begin());
- ensure("Empty container has equal begin/end const iterators", end == begin);
- HttpHeaders::const_iterator cend(headers->end()), cbegin(headers->begin());
- ensure("Empty container has equal rbegin/rend const iterators", cend == cbegin);
-
- ensure("Empty container has equal begin/end iterators", headers->end() == headers->begin());
-
- {
- static char line1[] = " AcCePT : image/yourfacehere";
- static char line1v[] = "image/yourfacehere";
- headers->appendNormal(line1, sizeof(line1) - 1);
-
- static char line2[] = " next : \t\tlinejunk \t";
- static char line2v[] = "linejunk \t";
- headers->appendNormal(line2, sizeof(line2) - 1);
-
- static char line3[] = "FancY-PANTs::plop:-neuf-=vleem=";
- static char line3v[] = ":plop:-neuf-=vleem=";
- headers->appendNormal(line3, sizeof(line3) - 1);
-
- static char line4[] = "all-talk-no-walk:";
- static char line4v[] = "";
- headers->appendNormal(line4, sizeof(line4) - 1);
-
- static char line5[] = ":all-talk-no-walk";
- static char line5v[] = "all-talk-no-walk";
- headers->appendNormal(line5, sizeof(line5) - 1);
-
- static char line6[] = " :";
- static char line6v[] = "";
- headers->appendNormal(line6, sizeof(line6) - 1);
-
- ensure("All entries accounted for", 6 == headers->size());
-
- static char * values[] = {
- line1v,
- line2v,
- line3v,
- line4v,
- line5v,
- line6v
- };
-
- int i(0);
- HttpHeaders::const_iterator cend(headers->end());
- for (HttpHeaders::const_iterator it(headers->begin());
- cend != it;
- ++it, ++i)
- {
- std::ostringstream str;
- str << "Const Iterator value # " << i << " was " << values[i];
- ensure(str.str(), (*it).second == values[i]);
- }
-
- // Rewind, do non-consts
- i = 0;
- HttpHeaders::iterator end(headers->end());
- for (HttpHeaders::iterator it(headers->begin());
- end != it;
- ++it, ++i)
- {
- std::ostringstream str;
- str << "Const Iterator value # " << i << " was " << values[i];
- ensure(str.str(), (*it).second == values[i]);
- }
- }
-
- // release the implicit reference, causing the object to be released
+ HttpHeaders::iterator end(headers->end()), begin(headers->begin());
+ ensure("Empty container has equal begin/end const iterators", end == begin);
+ HttpHeaders::const_iterator cend(headers->end()), cbegin(headers->begin());
+ ensure("Empty container has equal rbegin/rend const iterators", cend == cbegin);
+
+ ensure("Empty container has equal begin/end iterators", headers->end() == headers->begin());
+
+ {
+ static char line1[] = " AcCePT : image/yourfacehere";
+ static char line1v[] = "image/yourfacehere";
+ headers->appendNormal(line1, sizeof(line1) - 1);
+
+ static char line2[] = " next : \t\tlinejunk \t";
+ static char line2v[] = "linejunk \t";
+ headers->appendNormal(line2, sizeof(line2) - 1);
+
+ static char line3[] = "FancY-PANTs::plop:-neuf-=vleem=";
+ static char line3v[] = ":plop:-neuf-=vleem=";
+ headers->appendNormal(line3, sizeof(line3) - 1);
+
+ static char line4[] = "all-talk-no-walk:";
+ static char line4v[] = "";
+ headers->appendNormal(line4, sizeof(line4) - 1);
+
+ static char line5[] = ":all-talk-no-walk";
+ static char line5v[] = "all-talk-no-walk";
+ headers->appendNormal(line5, sizeof(line5) - 1);
+
+ static char line6[] = " :";
+ static char line6v[] = "";
+ headers->appendNormal(line6, sizeof(line6) - 1);
+
+ ensure("All entries accounted for", 6 == headers->size());
+
+ static char * values[] = {
+ line1v,
+ line2v,
+ line3v,
+ line4v,
+ line5v,
+ line6v
+ };
+
+ int i(0);
+ HttpHeaders::const_iterator cend(headers->end());
+ for (HttpHeaders::const_iterator it(headers->begin());
+ cend != it;
+ ++it, ++i)
+ {
+ std::ostringstream str;
+ str << "Const Iterator value # " << i << " was " << values[i];
+ ensure(str.str(), (*it).second == values[i]);
+ }
+
+ // Rewind, do non-consts
+ i = 0;
+ HttpHeaders::iterator end(headers->end());
+ for (HttpHeaders::iterator it(headers->begin());
+ end != it;
+ ++it, ++i)
+ {
+ std::ostringstream str;
+ str << "Const Iterator value # " << i << " was " << values[i];
+ ensure(str.str(), (*it).second == values[i]);
+ }
+ }
+
+ // release the implicit reference, causing the object to be released
headers.reset();
}
@@ -312,77 +312,77 @@ void HttpHeadersTestObjectType::test<5>()
template <> template <>
void HttpHeadersTestObjectType::test<6>()
{
- set_test_name("HttpHeaders reverse iterator tests");
+ set_test_name("HttpHeaders reverse iterator tests");
- // create a new ref counted object with an implicit reference
+ // create a new ref counted object with an implicit reference
HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders());
- HttpHeaders::reverse_iterator rend(headers->rend()), rbegin(headers->rbegin());
- ensure("Empty container has equal rbegin/rend const iterators", rend == rbegin);
- HttpHeaders::const_reverse_iterator crend(headers->rend()), crbegin(headers->rbegin());
- ensure("Empty container has equal rbegin/rend const iterators", crend == crbegin);
-
- {
- static char line1[] = " AcCePT : image/yourfacehere";
- static char line1v[] = "image/yourfacehere";
- headers->appendNormal(line1, sizeof(line1) - 1);
-
- static char line2[] = " next : \t\tlinejunk \t";
- static char line2v[] = "linejunk \t";
- headers->appendNormal(line2, sizeof(line2) - 1);
-
- static char line3[] = "FancY-PANTs::plop:-neuf-=vleem=";
- static char line3v[] = ":plop:-neuf-=vleem=";
- headers->appendNormal(line3, sizeof(line3) - 1);
-
- static char line4[] = "all-talk-no-walk:";
- static char line4v[] = "";
- headers->appendNormal(line4, sizeof(line4) - 1);
-
- static char line5[] = ":all-talk-no-walk";
- static char line5v[] = "all-talk-no-walk";
- headers->appendNormal(line5, sizeof(line5) - 1);
-
- static char line6[] = " :";
- static char line6v[] = "";
- headers->appendNormal(line6, sizeof(line6) - 1);
-
- ensure("All entries accounted for", 6 == headers->size());
-
- static char * values[] = {
- line6v,
- line5v,
- line4v,
- line3v,
- line2v,
- line1v
- };
-
- int i(0);
- HttpHeaders::const_reverse_iterator cend(headers->rend());
- for (HttpHeaders::const_reverse_iterator it(headers->rbegin());
- cend != it;
- ++it, ++i)
- {
- std::ostringstream str;
- str << "Const Iterator value # " << i << " was " << values[i];
- ensure(str.str(), (*it).second == values[i]);
- }
-
- // Rewind, do non-consts
- i = 0;
- HttpHeaders::reverse_iterator end(headers->rend());
- for (HttpHeaders::reverse_iterator it(headers->rbegin());
- end != it;
- ++it, ++i)
- {
- std::ostringstream str;
- str << "Iterator value # " << i << " was " << values[i];
- ensure(str.str(), (*it).second == values[i]);
- }
- }
-
- // release the implicit reference, causing the object to be released
+ HttpHeaders::reverse_iterator rend(headers->rend()), rbegin(headers->rbegin());
+ ensure("Empty container has equal rbegin/rend const iterators", rend == rbegin);
+ HttpHeaders::const_reverse_iterator crend(headers->rend()), crbegin(headers->rbegin());
+ ensure("Empty container has equal rbegin/rend const iterators", crend == crbegin);
+
+ {
+ static char line1[] = " AcCePT : image/yourfacehere";
+ static char line1v[] = "image/yourfacehere";
+ headers->appendNormal(line1, sizeof(line1) - 1);
+
+ static char line2[] = " next : \t\tlinejunk \t";
+ static char line2v[] = "linejunk \t";
+ headers->appendNormal(line2, sizeof(line2) - 1);
+
+ static char line3[] = "FancY-PANTs::plop:-neuf-=vleem=";
+ static char line3v[] = ":plop:-neuf-=vleem=";
+ headers->appendNormal(line3, sizeof(line3) - 1);
+
+ static char line4[] = "all-talk-no-walk:";
+ static char line4v[] = "";
+ headers->appendNormal(line4, sizeof(line4) - 1);
+
+ static char line5[] = ":all-talk-no-walk";
+ static char line5v[] = "all-talk-no-walk";
+ headers->appendNormal(line5, sizeof(line5) - 1);
+
+ static char line6[] = " :";
+ static char line6v[] = "";
+ headers->appendNormal(line6, sizeof(line6) - 1);
+
+ ensure("All entries accounted for", 6 == headers->size());
+
+ static char * values[] = {
+ line6v,
+ line5v,
+ line4v,
+ line3v,
+ line2v,
+ line1v
+ };
+
+ int i(0);
+ HttpHeaders::const_reverse_iterator cend(headers->rend());
+ for (HttpHeaders::const_reverse_iterator it(headers->rbegin());
+ cend != it;
+ ++it, ++i)
+ {
+ std::ostringstream str;
+ str << "Const Iterator value # " << i << " was " << values[i];
+ ensure(str.str(), (*it).second == values[i]);
+ }
+
+ // Rewind, do non-consts
+ i = 0;
+ HttpHeaders::reverse_iterator end(headers->rend());
+ for (HttpHeaders::reverse_iterator it(headers->rbegin());
+ end != it;
+ ++it, ++i)
+ {
+ std::ostringstream str;
+ str << "Iterator value # " << i << " was " << values[i];
+ ensure(str.str(), (*it).second == values[i]);
+ }
+ }
+
+ // release the implicit reference, causing the object to be released
headers.reset();
}
diff --git a/indra/llcorehttp/tests/test_httpoperation.hpp b/indra/llcorehttp/tests/test_httpoperation.hpp
index c6407e8d04..6778c3440b 100644
--- a/indra/llcorehttp/tests/test_httpoperation.hpp
+++ b/indra/llcorehttp/tests/test_httpoperation.hpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file test_httpoperation.hpp
* @brief unit tests for the LLCore::HttpOperation-derived classes
*
@@ -41,11 +41,11 @@ namespace
class TestHandler : public LLCore::HttpHandler
{
public:
- virtual void onCompleted(HttpHandle, HttpResponse *)
- {
- std::cout << "TestHandler::onCompleted() invoked" << std::endl;
- }
-
+ virtual void onCompleted(HttpHandle, HttpResponse *)
+ {
+ std::cout << "TestHandler::onCompleted() invoked" << std::endl;
+ }
+
};
@@ -54,53 +54,53 @@ public:
namespace tut
{
- struct HttpOperationTestData
- {
- // the test objects inherit from this so the member functions and variables
- // can be referenced directly inside of the test functions.
- };
-
- typedef test_group<HttpOperationTestData> HttpOperationTestGroupType;
- typedef HttpOperationTestGroupType::object HttpOperationTestObjectType;
- HttpOperationTestGroupType HttpOperationTestGroup("HttpOperation Tests");
-
- template <> template <>
- void HttpOperationTestObjectType::test<1>()
- {
- set_test_name("HttpOpNull construction");
-
- // create a new ref counted object with an implicit reference
- HttpOperation::ptr_t op (new HttpOpNull());
- ensure(op.use_count() == 1);
-
- // release the implicit reference, causing the object to be released
- op.reset();
- }
-
- template <> template <>
- void HttpOperationTestObjectType::test<2>()
- {
- set_test_name("HttpOpNull construction with handlers");
-
- // Get some handlers
- LLCore::HttpHandler::ptr_t h1 (new TestHandler());
-
- // create a new ref counted object with an implicit reference
- HttpOperation::ptr_t op (new HttpOpNull());
-
- // Add the handlers
- op->setReplyPath(LLCore::HttpOperation::HttpReplyQueuePtr_t(), h1);
-
- // Check ref count
- ensure(op.unique() == 1);
-
- // release the reference, releasing the operation but
- // not the handlers.
- op.reset();
-
- // release the handlers
- h1.reset();
- }
+ struct HttpOperationTestData
+ {
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
+ };
+
+ typedef test_group<HttpOperationTestData> HttpOperationTestGroupType;
+ typedef HttpOperationTestGroupType::object HttpOperationTestObjectType;
+ HttpOperationTestGroupType HttpOperationTestGroup("HttpOperation Tests");
+
+ template <> template <>
+ void HttpOperationTestObjectType::test<1>()
+ {
+ set_test_name("HttpOpNull construction");
+
+ // create a new ref counted object with an implicit reference
+ HttpOperation::ptr_t op (new HttpOpNull());
+ ensure(op.use_count() == 1);
+
+ // release the implicit reference, causing the object to be released
+ op.reset();
+ }
+
+ template <> template <>
+ void HttpOperationTestObjectType::test<2>()
+ {
+ set_test_name("HttpOpNull construction with handlers");
+
+ // Get some handlers
+ LLCore::HttpHandler::ptr_t h1 (new TestHandler());
+
+ // create a new ref counted object with an implicit reference
+ HttpOperation::ptr_t op (new HttpOpNull());
+
+ // Add the handlers
+ op->setReplyPath(LLCore::HttpOperation::HttpReplyQueuePtr_t(), h1);
+
+ // Check ref count
+ ensure(op.unique() == 1);
+
+ // release the reference, releasing the operation but
+ // not the handlers.
+ op.reset();
+
+ // release the handlers
+ h1.reset();
+ }
}
diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp
index 3eaac10aeb..aed906bb8f 100644
--- a/indra/llcorehttp/tests/test_httprequest.hpp
+++ b/indra/llcorehttp/tests/test_httprequest.hpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file test_httprequest.hpp
* @brief unit tests for the LLCore::HttpRequest class
*
@@ -51,8 +51,8 @@ using namespace LLCoreInt;
// loaded system where the unit test is in competition with
// other programs.
static const int LOOP_SLEEP_INTERVAL(10000);
-static const int LOOP_COUNT_SHORT(500); // 5-second dwell time
-static const int LOOP_COUNT_LONG(3000); // 30-second dwell time
+static const int LOOP_COUNT_SHORT(500); // 5-second dwell time
+static const int LOOP_COUNT_LONG(3000); // 30-second dwell time
namespace
{
@@ -72,117 +72,117 @@ typedef std::vector<std::pair<boost::regex, boost::regex> > regex_container_t;
struct HttpRequestTestData
{
- // the test objects inherit from this so the member functions and variables
- // can be referenced directly inside of the test functions.
- int mHandlerCalls;
- HttpStatus mStatus;
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
+ int mHandlerCalls;
+ HttpStatus mStatus;
};
class TestHandler2 : public LLCore::HttpHandler
{
public:
- TestHandler2(HttpRequestTestData * state,
- const std::string & name)
- : mState(state),
- mName(name),
- mExpectHandle(LLCORE_HTTP_HANDLE_INVALID)
- {}
-
- virtual void onCompleted(HttpHandle handle, HttpResponse * response)
- {
- if (LLCORE_HTTP_HANDLE_INVALID != mExpectHandle)
- {
- ensure("Expected handle received in handler", mExpectHandle == handle);
- }
- ensure("Handler got a response", NULL != response);
- if (response && mState)
- {
- const HttpStatus actual_status(response->getStatus());
- std::ostringstream test;
- test << "Expected HttpStatus received in response. Wanted: "
- << mState->mStatus.toHex() << " Received: " << actual_status.toHex();
- ensure(test.str().c_str(), actual_status == mState->mStatus);
- }
- if (mState)
- {
- mState->mHandlerCalls++;
- }
- if (! mHeadersRequired.empty() || ! mHeadersDisallowed.empty())
- {
- ensure("Response required with header check", response != NULL);
- HttpHeaders::ptr_t header(response->getHeaders()); // Will not hold onto this
- ensure("Some quantity of headers returned", header != NULL);
-
- if (! mHeadersRequired.empty())
- {
- for (int i(0); i < mHeadersRequired.size(); ++i)
- {
- bool found = false;
- for (HttpHeaders::const_iterator iter(header->begin());
- header->end() != iter;
- ++iter)
- {
- // std::cerr << "Header: " << (*iter).first
- // << ": " << (*iter).second << std::endl;
-
- if (boost::regex_match((*iter).first,
- mHeadersRequired[i].first) &&
- boost::regex_match((*iter).second,
- mHeadersRequired[i].second))
- {
- found = true;
- break;
- }
- }
- std::ostringstream str;
- str << "Required header #" << i << " "
- << mHeadersRequired[i].first << "=" << mHeadersRequired[i].second
- << " not found in response";
- ensure(str.str(), found);
- }
- }
-
- if (! mHeadersDisallowed.empty())
- {
- for (int i(0); i < mHeadersDisallowed.size(); ++i)
- {
- for (HttpHeaders::const_iterator iter(header->begin());
- header->end() != iter;
- ++iter)
- {
- if (boost::regex_match((*iter).first,
- mHeadersDisallowed[i].first) &&
- boost::regex_match((*iter).second,
- mHeadersDisallowed[i].second))
- {
- std::ostringstream str;
- str << "Disallowed header #" << i << " "
- << mHeadersDisallowed[i].first << "=" << mHeadersDisallowed[i].second
- << " found in response";
- ensure(str.str(), false);
- }
- }
- }
- }
- }
-
- if (! mCheckContentType.empty())
- {
- ensure("Response required with content type check", response != NULL);
- std::string con_type(response->getContentType());
- ensure("Content-Type as expected (" + mCheckContentType + ")",
- mCheckContentType == con_type);
- }
-
- // std::cout << "TestHandler2::onCompleted() invoked" << std::endl;
- }
-
- HttpRequestTestData * mState;
- std::string mName;
- HttpHandle mExpectHandle;
- std::string mCheckContentType;
- regex_container_t mHeadersRequired;
- regex_container_t mHeadersDisallowed;
+ TestHandler2(HttpRequestTestData * state,
+ const std::string & name)
+ : mState(state),
+ mName(name),
+ mExpectHandle(LLCORE_HTTP_HANDLE_INVALID)
+ {}
+
+ virtual void onCompleted(HttpHandle handle, HttpResponse * response)
+ {
+ if (LLCORE_HTTP_HANDLE_INVALID != mExpectHandle)
+ {
+ ensure("Expected handle received in handler", mExpectHandle == handle);
+ }
+ ensure("Handler got a response", NULL != response);
+ if (response && mState)
+ {
+ const HttpStatus actual_status(response->getStatus());
+ std::ostringstream test;
+ test << "Expected HttpStatus received in response. Wanted: "
+ << mState->mStatus.toHex() << " Received: " << actual_status.toHex();
+ ensure(test.str().c_str(), actual_status == mState->mStatus);
+ }
+ if (mState)
+ {
+ mState->mHandlerCalls++;
+ }
+ if (! mHeadersRequired.empty() || ! mHeadersDisallowed.empty())
+ {
+ ensure("Response required with header check", response != NULL);
+ HttpHeaders::ptr_t header(response->getHeaders()); // Will not hold onto this
+ ensure("Some quantity of headers returned", header != NULL);
+
+ if (! mHeadersRequired.empty())
+ {
+ for (int i(0); i < mHeadersRequired.size(); ++i)
+ {
+ bool found = false;
+ for (HttpHeaders::const_iterator iter(header->begin());
+ header->end() != iter;
+ ++iter)
+ {
+ // std::cerr << "Header: " << (*iter).first
+ // << ": " << (*iter).second << std::endl;
+
+ if (boost::regex_match((*iter).first,
+ mHeadersRequired[i].first) &&
+ boost::regex_match((*iter).second,
+ mHeadersRequired[i].second))
+ {
+ found = true;
+ break;
+ }
+ }
+ std::ostringstream str;
+ str << "Required header #" << i << " "
+ << mHeadersRequired[i].first << "=" << mHeadersRequired[i].second
+ << " not found in response";
+ ensure(str.str(), found);
+ }
+ }
+
+ if (! mHeadersDisallowed.empty())
+ {
+ for (int i(0); i < mHeadersDisallowed.size(); ++i)
+ {
+ for (HttpHeaders::const_iterator iter(header->begin());
+ header->end() != iter;
+ ++iter)
+ {
+ if (boost::regex_match((*iter).first,
+ mHeadersDisallowed[i].first) &&
+ boost::regex_match((*iter).second,
+ mHeadersDisallowed[i].second))
+ {
+ std::ostringstream str;
+ str << "Disallowed header #" << i << " "
+ << mHeadersDisallowed[i].first << "=" << mHeadersDisallowed[i].second
+ << " found in response";
+ ensure(str.str(), false);
+ }
+ }
+ }
+ }
+ }
+
+ if (! mCheckContentType.empty())
+ {
+ ensure("Response required with content type check", response != NULL);
+ std::string con_type(response->getContentType());
+ ensure("Content-Type as expected (" + mCheckContentType + ")",
+ mCheckContentType == con_type);
+ }
+
+ // std::cout << "TestHandler2::onCompleted() invoked" << std::endl;
+ }
+
+ HttpRequestTestData * mState;
+ std::string mName;
+ HttpHandle mExpectHandle;
+ std::string mCheckContentType;
+ regex_container_t mHeadersRequired;
+ regex_container_t mHeadersDisallowed;
};
typedef test_group<HttpRequestTestData> HttpRequestTestGroupType;
@@ -192,72 +192,72 @@ HttpRequestTestGroupType HttpRequestTestGroup("HttpRequest Tests");
template <> template <>
void HttpRequestTestObjectType::test<1>()
{
- ScopedCurlInit ready;
-
- set_test_name("HttpRequest construction");
-
- HttpRequest * req = NULL;
-
- try
- {
- // Get singletons created
- HttpRequest::createService();
-
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
-
- // release the request object
- delete req;
- req = NULL;
-
- HttpRequest::destroyService();
- }
- catch (...)
- {
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ ScopedCurlInit ready;
+
+ set_test_name("HttpRequest construction");
+
+ HttpRequest * req = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
template <> template <>
void HttpRequestTestObjectType::test<2>()
{
- ScopedCurlInit ready;
-
- set_test_name("HttpRequest and Null Op queued");
-
- HttpRequest * req = NULL;
-
- try
- {
- // Get singletons created
- HttpRequest::createService();
-
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
-
- // Issue a NoOp
- HttpHandle handle = req->requestNoOp(LLCore::HttpHandler::ptr_t());
- ensure("Request issued", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // release the request object
- delete req;
- req = NULL;
-
- // Request queue should have two references: global singleton & service object
- ensure("Two references to request queue", 2 == HttpRequestQueue::instanceOf()->getRefCount());
-
- // Okay, tear it down
- HttpRequest::destroyService();
- }
- catch (...)
- {
- stop_thread(req);
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ ScopedCurlInit ready;
+
+ set_test_name("HttpRequest and Null Op queued");
+
+ HttpRequest * req = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // Issue a NoOp
+ HttpHandle handle = req->requestNoOp(LLCore::HttpHandler::ptr_t());
+ ensure("Request issued", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Request queue should have two references: global singleton & service object
+ ensure("Two references to request queue", 2 == HttpRequestQueue::instanceOf()->getRefCount());
+
+ // Okay, tear it down
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
namespace
@@ -268,1243 +268,1243 @@ namespace
template <> template <>
void HttpRequestTestObjectType::test<3>()
{
- ScopedCurlInit ready;
-
- set_test_name("HttpRequest NoOp + Stop execution");
-
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ ScopedCurlInit ready;
+
+ set_test_name("HttpRequest NoOp + Stop execution");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
+ mHandlerCalls = 0;
- HttpRequest * req = NULL;
-
- try
- {
- // Get singletons created
+ HttpRequest * req = NULL;
+
+ try
+ {
+ // Get singletons created
HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
-
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
-
- // Issue a NoOp
- HttpHandle handle = req->requestNoOp(handlerp);
- ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_SHORT);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
- // Okay, request a shutdown of the servicing thread
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
-
- ensure("Two handler calls on the way out", 2 == mHandlerCalls);
- }
- catch (...)
- {
- stop_thread(req);
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // Issue a NoOp
+ HttpHandle handle = req->requestNoOp(handlerp);
+ ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_SHORT);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
template <> template <>
void HttpRequestTestObjectType::test<4>()
{
- ScopedCurlInit ready;
+ ScopedCurlInit ready;
- set_test_name("2 HttpRequest instances, one thread");
+ set_test_name("2 HttpRequest instances, one thread");
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- TestHandler2 handler1(this, "handler1");
- TestHandler2 handler2(this, "handler2");
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
-
- HttpRequest * req1 = NULL;
- HttpRequest * req2 = NULL;
-
- try
- {
-
- // Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
-
- // create a new ref counted object with an implicit reference
- req1 = new HttpRequest();
- req2 = new HttpRequest();
-
- // Issue some NoOps
- HttpHandle handle = req1->requestNoOp(handler1p);
- ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID);
- handler1.mExpectHandle = handle;
-
- handle = req2->requestNoOp(handler2p);
- ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID);
- handler2.mExpectHandle = handle;
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 2)
- {
- req1->update(1000000);
- req2->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 2);
-
- // Okay, request a shutdown of the servicing thread
- handle = req2->requestStopThread(handler2p);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
- handler2.mExpectHandle = handle;
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 3)
- {
- req1->update(1000000);
- req2->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 3);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release the request object
- delete req1;
- req1 = NULL;
- delete req2;
- req2 = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
-
- ensure("Two handler calls on the way out", 3 == mHandlerCalls);
- }
- catch (...)
- {
- stop_thread(req1);
- delete req1;
- delete req2;
- HttpRequest::destroyService();
- throw;
- }
+ mHandlerCalls = 0;
+
+ HttpRequest * req1 = NULL;
+ HttpRequest * req2 = NULL;
+
+ try
+ {
+
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req1 = new HttpRequest();
+ req2 = new HttpRequest();
+
+ // Issue some NoOps
+ HttpHandle handle = req1->requestNoOp(handler1p);
+ ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ handler1.mExpectHandle = handle;
+
+ handle = req2->requestNoOp(handler2p);
+ ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ handler2.mExpectHandle = handle;
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req1->update(1000000);
+ req2->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 2);
+
+ // Okay, request a shutdown of the servicing thread
+ handle = req2->requestStopThread(handler2p);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ handler2.mExpectHandle = handle;
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 3)
+ {
+ req1->update(1000000);
+ req2->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 3);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req1;
+ req1 = NULL;
+ delete req2;
+ req2 = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 3 == mHandlerCalls);
+ }
+ catch (...)
+ {
+ stop_thread(req1);
+ delete req1;
+ delete req2;
+ HttpRequest::destroyService();
+ throw;
+ }
}
template <> template <>
void HttpRequestTestObjectType::test<5>()
{
- ScopedCurlInit ready;
-
- set_test_name("HttpRequest Spin (soft) + NoOp + hard termination");
-
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ ScopedCurlInit ready;
+
+ set_test_name("HttpRequest Spin (soft) + NoOp + hard termination");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
-
- HttpRequest * req = NULL;
-
- try
- {
- // Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
-
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
-
- // Issue a Spin
- HttpHandle handle = req->requestSpin(1);
- ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Issue a NoOp
- handle = req->requestNoOp(handlerp);
- ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_SHORT);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("NoOp notification received", mHandlerCalls == 1);
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
- }
- catch (...)
- {
- stop_thread(req);
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // Issue a Spin
+ HttpHandle handle = req->requestSpin(1);
+ ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Issue a NoOp
+ handle = req->requestNoOp(handlerp);
+ ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_SHORT);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("NoOp notification received", mHandlerCalls == 1);
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
template <> template <>
void HttpRequestTestObjectType::test<6>()
{
- ScopedCurlInit ready;
-
- set_test_name("HttpRequest Spin + NoOp + hard termination");
-
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
- mHandlerCalls = 0;
-
- HttpRequest * req = NULL;
-
- try
- {
+ ScopedCurlInit ready;
+
+ set_test_name("HttpRequest Spin + NoOp + hard termination");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+
+ try
+ {
LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor);
- // Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
-
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
-
- // Issue a Spin
- HttpHandle handle = req->requestSpin(0); // Hard spin
- ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Issue a NoOp
- handle = req->requestNoOp(handlerp);
- ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_SHORT);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("No notifications received", mHandlerCalls == 0);
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
- }
- catch (...)
- {
- stop_thread(req);
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // Issue a Spin
+ HttpHandle handle = req->requestSpin(0); // Hard spin
+ ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Issue a NoOp
+ handle = req->requestNoOp(handlerp);
+ ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_SHORT);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("No notifications received", mHandlerCalls == 0);
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
template <> template <>
void HttpRequestTestObjectType::test<7>()
{
- ScopedCurlInit ready;
+ ScopedCurlInit ready;
- set_test_name("HttpRequest GET to dead port + Stop execution");
+ set_test_name("HttpRequest GET to dead port + Stop execution");
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions::ptr_t opts;
- HttpRequest * req = NULL;
- HttpOptions::ptr_t opts;
-
- try
- {
+ try
+ {
// Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
opts = HttpOptions::ptr_t(new HttpOptions());
- opts->setRetries(1); // Don't try for too long - default retries take about 18S
-
- // Issue a GET that can't connect
- mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
- HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
- "http://127.0.0.1:2/nothing/here",
- 0,
- 0,
- opts,
- HttpHeaders::ptr_t(),
- handlerp);
- ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release options
+ opts->setRetries(1); // Don't try for too long - default retries take about 18S
+
+ // Issue a GET that can't connect
+ mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ "http://127.0.0.1:2/nothing/here",
+ 0,
+ 0,
+ opts,
+ HttpHeaders::ptr_t(),
+ handlerp);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options
opts.reset();
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
-
- ensure("Two handler calls on the way out", 2 == mHandlerCalls);
- }
- catch (...)
- {
- stop_thread(req);
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+ }
+ catch (...)
+ {
+ stop_thread(req);
opts.reset();
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
template <> template <>
void HttpRequestTestObjectType::test<8>()
{
- ScopedCurlInit ready;
+ ScopedCurlInit ready;
- std::string url_base(get_base_url());
- // std::cerr << "Base: " << url_base << std::endl;
-
- set_test_name("HttpRequest GET to real service");
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ set_test_name("HttpRequest GET to real service");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
+ mHandlerCalls = 0;
- HttpRequest * req = NULL;
+ HttpRequest * req = NULL;
- try
- {
+ try
+ {
// Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
-
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
-
- // Issue a GET that *can* connect
- mStatus = HttpStatus(200);
- HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
- url_base,
- HttpOptions::ptr_t(),
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // Issue a GET that *can* connect
+ mStatus = HttpStatus(200);
+ HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
+ url_base,
+ HttpOptions::ptr_t(),
HttpHeaders::ptr_t(),
- handlerp);
- ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
-
- ensure("Two handler calls on the way out", 2 == mHandlerCalls);
- }
- catch (...)
- {
- stop_thread(req);
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ handlerp);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
template <> template <>
void HttpRequestTestObjectType::test<9>()
{
- ScopedCurlInit ready;
+ ScopedCurlInit ready;
+
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
- std::string url_base(get_base_url());
- // std::cerr << "Base: " << url_base << std::endl;
-
- set_test_name("HttpRequest GET with Range: header to real service");
+ set_test_name("HttpRequest GET with Range: header to real service");
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
+ mHandlerCalls = 0;
- HttpRequest * req = NULL;
+ HttpRequest * req = NULL;
- try
- {
+ try
+ {
// Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
-
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
-
- // Issue a GET that *can* connect
- mStatus = HttpStatus(200);
- HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
- url_base,
- 0,
- 0,
- HttpOptions::ptr_t(),
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // Issue a GET that *can* connect
+ mStatus = HttpStatus(200);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ url_base,
+ 0,
+ 0,
+ HttpOptions::ptr_t(),
HttpHeaders::ptr_t(),
- handlerp);
- ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
-
- ensure("Two handler calls on the way out", 2 == mHandlerCalls);
- }
- catch (...)
- {
- stop_thread(req);
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ handlerp);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
template <> template <>
void HttpRequestTestObjectType::test<10>()
{
- ScopedCurlInit ready;
+ ScopedCurlInit ready;
- std::string url_base(get_base_url());
- // std::cerr << "Base: " << url_base << std::endl;
-
- set_test_name("HttpRequest PUT to real service");
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ set_test_name("HttpRequest PUT to real service");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ BufferArray * body = new BufferArray;
- HttpRequest * req = NULL;
- BufferArray * body = new BufferArray;
-
- try
- {
+ try
+ {
// Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
-
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
-
- // Issue a GET that *can* connect
- static const char * body_text("Now is the time for all good men...");
- body->append(body_text, strlen(body_text));
- mStatus = HttpStatus(200);
- HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
- url_base,
- body,
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // Issue a GET that *can* connect
+ static const char * body_text("Now is the time for all good men...");
+ body->append(body_text, strlen(body_text));
+ mStatus = HttpStatus(200);
+ HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
+ url_base,
+ body,
HttpOptions::ptr_t(),
HttpHeaders::ptr_t(),
handlerp);
- ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // Lose the request body
- body->release();
- body = NULL;
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
-
- ensure("Two handler calls on the way out", 2 == mHandlerCalls);
- }
- catch (...)
- {
- if (body)
- {
- body->release();
- }
- stop_thread(req);
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // Lose the request body
+ body->release();
+ body = NULL;
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+ }
+ catch (...)
+ {
+ if (body)
+ {
+ body->release();
+ }
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
template <> template <>
void HttpRequestTestObjectType::test<11>()
{
- ScopedCurlInit ready;
+ ScopedCurlInit ready;
+
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
- std::string url_base(get_base_url());
- // std::cerr << "Base: " << url_base << std::endl;
-
- set_test_name("HttpRequest POST to real service");
+ set_test_name("HttpRequest POST to real service");
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
+ mHandlerCalls = 0;
- HttpRequest * req = NULL;
- BufferArray * body = new BufferArray;
-
- try
- {
+ HttpRequest * req = NULL;
+ BufferArray * body = new BufferArray;
+
+ try
+ {
// Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
-
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
-
- // Issue a GET that *can* connect
- static const char * body_text("Now is the time for all good men...");
- body->append(body_text, strlen(body_text));
- mStatus = HttpStatus(200);
- HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
- url_base,
- body,
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // Issue a GET that *can* connect
+ static const char * body_text("Now is the time for all good men...");
+ body->append(body_text, strlen(body_text));
+ mStatus = HttpStatus(200);
+ HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
+ url_base,
+ body,
HttpOptions::ptr_t(),
HttpHeaders::ptr_t(),
handlerp);
- ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // Lose the request body
- body->release();
- body = NULL;
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
-
- ensure("Two handler calls on the way out", 2 == mHandlerCalls);
- }
- catch (...)
- {
- if (body)
- {
- body->release();
- }
- stop_thread(req);
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // Lose the request body
+ body->release();
+ body = NULL;
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+ }
+ catch (...)
+ {
+ if (body)
+ {
+ body->release();
+ }
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
template <> template <>
void HttpRequestTestObjectType::test<12>()
{
- ScopedCurlInit ready;
+ ScopedCurlInit ready;
- std::string url_base(get_base_url());
- // std::cerr << "Base: " << url_base << std::endl;
-
- set_test_name("HttpRequest GET with some tracing");
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ set_test_name("HttpRequest GET with some tracing");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
+ mHandlerCalls = 0;
- HttpRequest * req = NULL;
+ HttpRequest * req = NULL;
- try
- {
+ try
+ {
// Get singletons created
- HttpRequest::createService();
+ HttpRequest::createService();
- // Enable tracing
- HttpRequest::setStaticPolicyOption(HttpRequest::PO_TRACE, HttpRequest::DEFAULT_POLICY_ID, 2, NULL);
+ // Enable tracing
+ HttpRequest::setStaticPolicyOption(HttpRequest::PO_TRACE, HttpRequest::DEFAULT_POLICY_ID, 2, NULL);
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
- // Issue a GET that *can* connect
- mStatus = HttpStatus(200);
- HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
- url_base,
- 0,
- 0,
+ // Issue a GET that *can* connect
+ mStatus = HttpStatus(200);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ url_base,
+ 0,
+ 0,
HttpOptions::ptr_t(),
HttpHeaders::ptr_t(),
handlerp);
- ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
-
- ensure("Two handler calls on the way out", 2 == mHandlerCalls);
- }
- catch (...)
- {
- stop_thread(req);
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
template <> template <>
void HttpRequestTestObjectType::test<13>()
{
- ScopedCurlInit ready;
-
- // Warmup boost::regex to pre-alloc memory for memory size tests
- boost::regex warmup("askldjflasdj;f", boost::regex::icase);
- boost::regex_match("akl;sjflajfk;ajsk", warmup);
-
- std::string url_base(get_base_url());
- // std::cerr << "Base: " << url_base << std::endl;
-
- set_test_name("HttpRequest GET with returned headers");
-
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
- handler.mHeadersRequired.reserve(20); // Avoid memory leak test failure
+ ScopedCurlInit ready;
+
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
+
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
+
+ set_test_name("HttpRequest GET with returned headers");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // 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);
- mHandlerCalls = 0;
+ mHandlerCalls = 0;
- HttpRequest * req = NULL;
- HttpOptions::ptr_t opts;
+ HttpRequest * req = NULL;
+ HttpOptions::ptr_t opts;
- try
- {
+ try
+ {
// Get singletons created
- HttpRequest::createService();
+ HttpRequest::createService();
- // Enable tracing
- HttpRequest::setStaticPolicyOption(HttpRequest::PO_TRACE, HttpRequest::DEFAULT_POLICY_ID, 2, NULL);
+ // Enable tracing
+ HttpRequest::setStaticPolicyOption(HttpRequest::PO_TRACE, HttpRequest::DEFAULT_POLICY_ID, 2, NULL);
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
opts = HttpOptions::ptr_t(new HttpOptions());
- opts->setWantHeaders(true);
-
- // Issue a GET that succeeds
- mStatus = HttpStatus(200);
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(boost::regex("X-LL-Special", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
- url_base,
- 0,
- 0,
- opts,
+ opts->setWantHeaders(true);
+
+ // Issue a GET that succeeds
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(boost::regex("X-LL-Special", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ url_base,
+ 0,
+ 0,
+ opts,
HttpHeaders::ptr_t(),
handlerp);
- ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
- // release options
+ // release options
opts.reset();
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handler.mHeadersRequired.clear();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
-
- ensure("Two handler calls on the way out", 2 == mHandlerCalls);
- }
- catch (...)
- {
- stop_thread(req);
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+ }
+ catch (...)
+ {
+ stop_thread(req);
opts.reset();
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
template <> template <>
void HttpRequestTestObjectType::test<14>()
{
- ScopedCurlInit ready;
-
- set_test_name("HttpRequest GET timeout");
-
- // Handler can be stack-allocated *if* there are no dangling
- // 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);
- std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep
- mHandlerCalls = 0;
-
- HttpRequest * req = NULL;
- HttpOptions::ptr_t opts;
-
- try
- {
- // Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
-
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
-
- opts = HttpOptions::ptr_t(new HttpOptions);
- opts->setRetries(0); // Don't retry
- opts->setTimeout(2);
-
- // Issue a GET that sleeps
- mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT);
- HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
- url_base,
- 0,
- 0,
- opts,
- HttpHeaders::ptr_t(),
- handlerp);
- ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release options
- opts.reset();
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
-
- ensure("Two handler calls on the way out", 2 == mHandlerCalls);
- }
- catch (...)
- {
- stop_thread(req);
- opts.reset();
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ ScopedCurlInit ready;
+
+ set_test_name("HttpRequest GET timeout");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
+ std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions::ptr_t opts;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ opts = HttpOptions::ptr_t(new HttpOptions);
+ opts->setRetries(0); // Don't retry
+ opts->setTimeout(2);
+
+ // Issue a GET that sleeps
+ mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ url_base,
+ 0,
+ 0,
+ opts,
+ HttpHeaders::ptr_t(),
+ handlerp);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options
+ opts.reset();
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ opts.reset();
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
// Test retrieval of Content-Type/Content-Encoding headers
template <> template <>
void HttpRequestTestObjectType::test<15>()
{
- ScopedCurlInit ready;
+ ScopedCurlInit ready;
+
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
- std::string url_base(get_base_url());
- // std::cerr << "Base: " << url_base << std::endl;
-
- set_test_name("HttpRequest GET with Content-Type");
+ set_test_name("HttpRequest GET with Content-Type");
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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.
- handler.mCheckContentType = "application/llsd+xml";
- handler.mCheckContentType.clear();
- mHandlerCalls = 0;
+ // Load and clear the string setting to preload std::string object
+ // for memory return tests.
+ handler.mCheckContentType = "application/llsd+xml";
+ handler.mCheckContentType.clear();
+ mHandlerCalls = 0;
- HttpRequest * req = NULL;
+ HttpRequest * req = NULL;
- try
- {
+ try
+ {
// Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
-
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
-
- // Issue a GET that *can* connect
- mStatus = HttpStatus(200);
- handler.mCheckContentType = "application/llsd+xml";
- HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
- url_base,
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // Issue a GET that *can* connect
+ mStatus = HttpStatus(200);
+ handler.mCheckContentType = "application/llsd+xml";
+ HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
+ url_base,
HttpOptions::ptr_t(),
HttpHeaders::ptr_t(),
handlerp);
- ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handler.mCheckContentType.clear();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
-
- ensure("Two handler calls on the way out", 2 == mHandlerCalls);
- }
- catch (...)
- {
- stop_thread(req);
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mCheckContentType.clear();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
@@ -1512,236 +1512,236 @@ void HttpRequestTestObjectType::test<15>()
template <> template <>
void HttpRequestTestObjectType::test<16>()
{
- ScopedCurlInit ready;
+ ScopedCurlInit ready;
- // Warmup boost::regex to pre-alloc memory for memory size tests
- boost::regex warmup("askldjflasdj;f", boost::regex::icase);
- boost::regex_match("akl;sjflajfk;ajsk", warmup);
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
- std::string url_base(get_base_url());
-
- set_test_name("Header generation for HttpRequest GET");
+ std::string url_base(get_base_url());
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ set_test_name("Header generation for HttpRequest GET");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
+ mHandlerCalls = 0;
- HttpRequest * req = NULL;
- HttpOptions::ptr_t options;
- HttpHeaders::ptr_t headers;
+ HttpRequest * req = NULL;
+ HttpOptions::ptr_t options;
+ HttpHeaders::ptr_t headers;
- try
- {
+ try
+ {
// Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
- // options set
+ // options set
options = HttpOptions::ptr_t(new HttpOptions());
- options->setWantHeaders(true);
-
- // Issue a GET that *can* connect
- mStatus = HttpStatus(200);
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-connection", boost::regex::icase),
- boost::regex("keep-alive", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept", boost::regex::icase),
- boost::regex("\\*/\\*", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
- boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-keep-alive", boost::regex::icase),
- boost::regex("\\d+", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-host", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-cache-control", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-pragma", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-range", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-transfer-encoding", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-referer", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-type", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-encoding", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
- url_base + "reflect/",
- options,
- HttpHeaders::ptr_t(),
- handlerp);
- ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
- // Do a texture-style fetch
- headers = HttpHeaders::ptr_t(new HttpHeaders);
- headers->append("Accept", "image/x-j2c");
-
- mStatus = HttpStatus(200);
- handler.mHeadersRequired.clear();
- handler.mHeadersDisallowed.clear();
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-connection", boost::regex::icase),
- boost::regex("keep-alive", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept", boost::regex::icase),
- boost::regex("image/x-j2c", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
- boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-keep-alive", boost::regex::icase),
- boost::regex("\\d+", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-host", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("\\W*X-Reflect-range", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
-
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-cache-control", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-pragma", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-transfer-encoding", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-referer", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-type", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-encoding", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
- url_base + "reflect/",
- 0,
- 47,
- options,
- headers,
- handlerp);
- ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 2);
-
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handler.mHeadersRequired.clear();
- handler.mHeadersDisallowed.clear();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 3)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 3);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release options & headers
+ options->setWantHeaders(true);
+
+ // Issue a GET that *can* connect
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-connection", boost::regex::icase),
+ boost::regex("keep-alive", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept", boost::regex::icase),
+ boost::regex("\\*/\\*", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
+ boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-keep-alive", boost::regex::icase),
+ boost::regex("\\d+", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-host", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-cache-control", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-pragma", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-range", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-transfer-encoding", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-referer", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-type", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-encoding", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
+ url_base + "reflect/",
+ options,
+ HttpHeaders::ptr_t(),
+ handlerp);
+ ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Do a texture-style fetch
+ headers = HttpHeaders::ptr_t(new HttpHeaders);
+ headers->append("Accept", "image/x-j2c");
+
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-connection", boost::regex::icase),
+ boost::regex("keep-alive", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept", boost::regex::icase),
+ boost::regex("image/x-j2c", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
+ boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-keep-alive", boost::regex::icase),
+ boost::regex("\\d+", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-host", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("\\W*X-Reflect-range", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-cache-control", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-pragma", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-transfer-encoding", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-referer", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-type", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-encoding", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ url_base + "reflect/",
+ 0,
+ 47,
+ options,
+ headers,
+ handlerp);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 2);
+
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 3)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 3);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options & headers
options.reset();
headers.reset();
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
- }
- catch (...)
- {
- stop_thread(req);
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
options.reset();
headers.reset();
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
@@ -1749,183 +1749,183 @@ void HttpRequestTestObjectType::test<16>()
template <> template <>
void HttpRequestTestObjectType::test<17>()
{
- ScopedCurlInit ready;
+ ScopedCurlInit ready;
+
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
- // Warmup boost::regex to pre-alloc memory for memory size tests
- boost::regex warmup("askldjflasdj;f", boost::regex::icase);
- boost::regex_match("akl;sjflajfk;ajsk", warmup);
+ std::string url_base(get_base_url());
- std::string url_base(get_base_url());
-
- set_test_name("Header generation for HttpRequest POST");
+ set_test_name("Header generation for HttpRequest POST");
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
-
- HttpRequest * req = NULL;
- HttpOptions::ptr_t options;
- HttpHeaders::ptr_t headers;
- BufferArray * ba = NULL;
-
- try
- {
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions::ptr_t options;
+ HttpHeaders::ptr_t headers;
+ BufferArray * ba = NULL;
+
+ try
+ {
// Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
- // options set
+ // options set
options = HttpOptions::ptr_t(new HttpOptions());
- options->setWantHeaders(true);
-
- // And a buffer array
- const char * msg("It was the best of times, it was the worst of times.");
- ba = new BufferArray;
- ba->append(msg, strlen(msg));
-
- // Issue a default POST
- mStatus = HttpStatus(200);
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-connection", boost::regex::icase),
- boost::regex("keep-alive", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept", boost::regex::icase),
- boost::regex("\\*/\\*", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
- boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-keep-alive", boost::regex::icase),
- boost::regex("\\d+", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-host", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-length", boost::regex::icase),
- boost::regex("\\d+", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-type", boost::regex::icase),
- boost::regex("application/x-www-form-urlencoded", boost::regex::icase)));
-
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-cache-control", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-pragma", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-range", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-referer", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-encoding", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-expect", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-transfer_encoding", boost::regex::icase),
- boost::regex(".*chunked.*", boost::regex::icase)));
- HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
- url_base + "reflect/",
- ba,
- options,
- HttpHeaders::ptr_t(),
- handlerp);
- ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
- ba->release();
- ba = NULL;
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handler.mHeadersRequired.clear();
- handler.mHeadersDisallowed.clear();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release options & headers
+ options->setWantHeaders(true);
+
+ // And a buffer array
+ const char * msg("It was the best of times, it was the worst of times.");
+ ba = new BufferArray;
+ ba->append(msg, strlen(msg));
+
+ // Issue a default POST
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-connection", boost::regex::icase),
+ boost::regex("keep-alive", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept", boost::regex::icase),
+ boost::regex("\\*/\\*", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
+ boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-keep-alive", boost::regex::icase),
+ boost::regex("\\d+", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-host", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-length", boost::regex::icase),
+ boost::regex("\\d+", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-type", boost::regex::icase),
+ boost::regex("application/x-www-form-urlencoded", boost::regex::icase)));
+
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-cache-control", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-pragma", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-range", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-referer", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-encoding", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-expect", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-transfer_encoding", boost::regex::icase),
+ boost::regex(".*chunked.*", boost::regex::icase)));
+ HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
+ url_base + "reflect/",
+ ba,
+ options,
+ HttpHeaders::ptr_t(),
+ handlerp);
+ ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ ba->release();
+ ba = NULL;
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options & headers
options.reset();
headers.reset();
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
- }
- catch (...)
- {
- stop_thread(req);
- if (ba)
- {
- ba->release();
- ba = NULL;
- }
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ if (ba)
+ {
+ ba->release();
+ ba = NULL;
+ }
options.reset();
headers.reset();
delete req;
- HttpRequest::destroyService();
- throw;
- }
+ HttpRequest::destroyService();
+ throw;
+ }
}
@@ -1933,184 +1933,184 @@ void HttpRequestTestObjectType::test<17>()
template <> template <>
void HttpRequestTestObjectType::test<18>()
{
- ScopedCurlInit ready;
+ ScopedCurlInit ready;
- // Warmup boost::regex to pre-alloc memory for memory size tests
- boost::regex warmup("askldjflasdj;f", boost::regex::icase);
- boost::regex_match("akl;sjflajfk;ajsk", warmup);
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
- std::string url_base(get_base_url());
-
- set_test_name("Header generation for HttpRequest PUT");
+ std::string url_base(get_base_url());
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ set_test_name("Header generation for HttpRequest PUT");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
-
- HttpRequest * req = NULL;
- HttpOptions::ptr_t options;
- HttpHeaders::ptr_t headers;
- BufferArray * ba = NULL;
-
- try
- {
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions::ptr_t options;
+ HttpHeaders::ptr_t headers;
+ BufferArray * ba = NULL;
+
+ try
+ {
// Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
-
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
-
- // options set
- options = HttpOptions::ptr_t(new HttpOptions());
- options->setWantHeaders(true);
-
- // And a buffer array
- const char * msg("It was the best of times, it was the worst of times.");
- ba = new BufferArray;
- ba->append(msg, strlen(msg));
-
- // Issue a default PUT
- mStatus = HttpStatus(200);
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-connection", boost::regex::icase),
- boost::regex("keep-alive", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept", boost::regex::icase),
- boost::regex("\\*/\\*", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
- boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-keep-alive", boost::regex::icase),
- boost::regex("\\d+", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-host", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-length", boost::regex::icase),
- boost::regex("\\d+", boost::regex::icase)));
-
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-cache-control", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-pragma", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-range", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-referer", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-encoding", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-expect", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-transfer-encoding", boost::regex::icase),
- boost::regex(".*chunked.*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-type", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
-
- HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
- url_base + "reflect/",
- ba,
- options,
- HttpHeaders::ptr_t(),
- handlerp);
- ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
- ba->release();
- ba = NULL;
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handler.mHeadersRequired.clear();
- handler.mHeadersDisallowed.clear();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release options & headers
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // options set
+ options = HttpOptions::ptr_t(new HttpOptions());
+ options->setWantHeaders(true);
+
+ // And a buffer array
+ const char * msg("It was the best of times, it was the worst of times.");
+ ba = new BufferArray;
+ ba->append(msg, strlen(msg));
+
+ // Issue a default PUT
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-connection", boost::regex::icase),
+ boost::regex("keep-alive", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept", boost::regex::icase),
+ boost::regex("\\*/\\*", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
+ boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-keep-alive", boost::regex::icase),
+ boost::regex("\\d+", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-host", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-length", boost::regex::icase),
+ boost::regex("\\d+", boost::regex::icase)));
+
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-cache-control", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-pragma", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-range", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-referer", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-encoding", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-expect", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-transfer-encoding", boost::regex::icase),
+ boost::regex(".*chunked.*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-type", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+
+ HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
+ url_base + "reflect/",
+ ba,
+ options,
+ HttpHeaders::ptr_t(),
+ handlerp);
+ ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ ba->release();
+ ba = NULL;
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options & headers
options.reset();
headers.reset();
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
- }
- catch (...)
- {
- stop_thread(req);
- if (ba)
- {
- ba->release();
- ba = NULL;
- }
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ if (ba)
+ {
+ ba->release();
+ ba = NULL;
+ }
options.reset();
headers.reset();
delete req;
- HttpRequest::destroyService();
- throw;
- }
+ HttpRequest::destroyService();
+ throw;
+ }
}
@@ -2118,189 +2118,189 @@ void HttpRequestTestObjectType::test<18>()
template <> template <>
void HttpRequestTestObjectType::test<19>()
{
- // It appears that HttpRequest is fully capable of sending duplicate header values in violation of
- // this test's expectations. Something needs to budge: is sending duplicate header values desired?
- //
- // Test server /reflect/ response headers (mirrored from request)
- //
- // X-Reflect-content-type: text/plain
- // X-Reflect-content-type: text/html
- // X-Reflect-content-type: application/llsd+xml
- //
- skip("FIXME: Bad assertions or broken functionality.");
-
- ScopedCurlInit ready;
-
- // Warmup boost::regex to pre-alloc memory for memory size tests
- boost::regex warmup("askldjflasdj;f", boost::regex::icase);
- boost::regex_match("akl;sjflajfk;ajsk", warmup);
-
- std::string url_base(get_base_url());
-
- set_test_name("Header generation for HttpRequest GET with header overrides");
-
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ // It appears that HttpRequest is fully capable of sending duplicate header values in violation of
+ // this test's expectations. Something needs to budge: is sending duplicate header values desired?
+ //
+ // Test server /reflect/ response headers (mirrored from request)
+ //
+ // X-Reflect-content-type: text/plain
+ // X-Reflect-content-type: text/html
+ // X-Reflect-content-type: application/llsd+xml
+ //
+ skip("FIXME: Bad assertions or broken functionality.");
+
+ ScopedCurlInit ready;
+
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
+
+ std::string url_base(get_base_url());
+
+ set_test_name("Header generation for HttpRequest GET with header overrides");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
+ mHandlerCalls = 0;
- HttpRequest * req = NULL;
- HttpOptions::ptr_t options;
- HttpHeaders::ptr_t headers;
+ HttpRequest * req = NULL;
+ HttpOptions::ptr_t options;
+ HttpHeaders::ptr_t headers;
- try
- {
+ try
+ {
// Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
- // options set
+ // options set
options = HttpOptions::ptr_t(new HttpOptions());
- options->setWantHeaders(true);
-
- // headers
- headers = HttpHeaders::ptr_t(new HttpHeaders);
- headers->append("Keep-Alive", "120");
- headers->append("Accept-encoding", "deflate");
- headers->append("Accept", "text/plain");
-
- // Issue a GET with modified headers
- mStatus = HttpStatus(200);
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-connection", boost::regex::icase),
- boost::regex("keep-alive", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept", boost::regex::icase),
- boost::regex("text/plain", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
- boost::regex("deflate", boost::regex::icase))); // close enough
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-keep-alive", boost::regex::icase),
- boost::regex("120", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-host", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
-
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
- boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-keep-alive", boost::regex::icase),
- boost::regex("300", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept", boost::regex::icase),
- boost::regex("\\*/\\*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-cache-control", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-pragma", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-range", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-transfer-encoding", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-referer", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-type", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-encoding", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
- url_base + "reflect/",
- options,
- headers,
- handlerp);
- ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handler.mHeadersRequired.clear();
- handler.mHeadersDisallowed.clear();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release options & headers
+ options->setWantHeaders(true);
+
+ // headers
+ headers = HttpHeaders::ptr_t(new HttpHeaders);
+ headers->append("Keep-Alive", "120");
+ headers->append("Accept-encoding", "deflate");
+ headers->append("Accept", "text/plain");
+
+ // Issue a GET with modified headers
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-connection", boost::regex::icase),
+ boost::regex("keep-alive", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept", boost::regex::icase),
+ boost::regex("text/plain", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
+ boost::regex("deflate", boost::regex::icase))); // close enough
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-keep-alive", boost::regex::icase),
+ boost::regex("120", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-host", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
+ boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-keep-alive", boost::regex::icase),
+ boost::regex("300", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept", boost::regex::icase),
+ boost::regex("\\*/\\*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-cache-control", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-pragma", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-range", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-transfer-encoding", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-referer", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-type", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-encoding", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
+ url_base + "reflect/",
+ options,
+ headers,
+ handlerp);
+ ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options & headers
options.reset();
headers.reset();
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
- }
- catch (...)
- {
- stop_thread(req);
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
options.reset();
headers.reset();
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
@@ -2308,214 +2308,214 @@ void HttpRequestTestObjectType::test<19>()
template <> template <>
void HttpRequestTestObjectType::test<20>()
{
- // It appears that HttpRequest is fully capable of sending duplicate header values in violation of
- // this test's expectations. Something needs to budge: is sending duplicate header values desired?
- //
- // Test server /reflect/ response headers (mirrored from request)
- //
- // X-Reflect-content-type: text/plain
- // X-Reflect-content-type: text/html
- // X-Reflect-content-type: application/llsd+xml
- //
- skip("FIXME: Bad assertions or broken functionality.");
-
- ScopedCurlInit ready;
-
- // Warmup boost::regex to pre-alloc memory for memory size tests
- boost::regex warmup("askldjflasdj;f", boost::regex::icase);
- boost::regex_match("akl;sjflajfk;ajsk", warmup);
-
- std::string url_base(get_base_url());
-
- set_test_name("Header generation for HttpRequest POST with header overrides");
-
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ // It appears that HttpRequest is fully capable of sending duplicate header values in violation of
+ // this test's expectations. Something needs to budge: is sending duplicate header values desired?
+ //
+ // Test server /reflect/ response headers (mirrored from request)
+ //
+ // X-Reflect-content-type: text/plain
+ // X-Reflect-content-type: text/html
+ // X-Reflect-content-type: application/llsd+xml
+ //
+ skip("FIXME: Bad assertions or broken functionality.");
+
+ ScopedCurlInit ready;
+
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
+
+ std::string url_base(get_base_url());
+
+ set_test_name("Header generation for HttpRequest POST with header overrides");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
+ mHandlerCalls = 0;
- HttpRequest * req = NULL;
- HttpOptions::ptr_t options;
- HttpHeaders::ptr_t headers;
- BufferArray * ba = NULL;
-
- try
- {
+ HttpRequest * req = NULL;
+ HttpOptions::ptr_t options;
+ HttpHeaders::ptr_t headers;
+ BufferArray * ba = NULL;
+
+ try
+ {
// Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
+ HttpRequest::createService();
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
- // options set
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // options set
options = HttpOptions::ptr_t(new HttpOptions());
- options->setWantHeaders(true);
-
- // headers
- headers = HttpHeaders::ptr_t(new HttpHeaders());
- headers->append("keep-Alive", "120");
- headers->append("Accept", "text/html");
- headers->append("content-type", "application/llsd+xml");
- headers->append("cache-control", "no-store");
-
- // And a buffer array
- const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>");
- ba = new BufferArray;
- ba->append(msg, strlen(msg));
-
- // Issue a default POST
- mStatus = HttpStatus(200);
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-connection", boost::regex::icase),
- boost::regex("keep-alive", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept", boost::regex::icase),
- boost::regex("text/html", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
- boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-keep-alive", boost::regex::icase),
- boost::regex("120", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-host", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-length", boost::regex::icase),
- boost::regex("\\d+", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-type", boost::regex::icase),
- boost::regex("application/llsd\\+xml", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-cache-control", boost::regex::icase),
- boost::regex("no-store", boost::regex::icase)));
-
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-type", boost::regex::icase),
- boost::regex("application/x-www-form-urlencoded", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept", boost::regex::icase),
- boost::regex("\\*/\\*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-keep-alive", boost::regex::icase),
- boost::regex("300", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-pragma", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-range", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-referer", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-encoding", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-expect", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-transfer-encoding", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
-
- HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
- url_base + "reflect/",
- ba,
- options,
- headers,
- handlerp);
- ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
- ba->release();
- ba = NULL;
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handler.mHeadersRequired.clear();
- handler.mHeadersDisallowed.clear();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release options & headers
+ options->setWantHeaders(true);
+
+ // headers
+ headers = HttpHeaders::ptr_t(new HttpHeaders());
+ headers->append("keep-Alive", "120");
+ headers->append("Accept", "text/html");
+ headers->append("content-type", "application/llsd+xml");
+ headers->append("cache-control", "no-store");
+
+ // And a buffer array
+ const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>");
+ ba = new BufferArray;
+ ba->append(msg, strlen(msg));
+
+ // Issue a default POST
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-connection", boost::regex::icase),
+ boost::regex("keep-alive", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept", boost::regex::icase),
+ boost::regex("text/html", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
+ boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-keep-alive", boost::regex::icase),
+ boost::regex("120", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-host", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-length", boost::regex::icase),
+ boost::regex("\\d+", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-type", boost::regex::icase),
+ boost::regex("application/llsd\\+xml", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-cache-control", boost::regex::icase),
+ boost::regex("no-store", boost::regex::icase)));
+
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-type", boost::regex::icase),
+ boost::regex("application/x-www-form-urlencoded", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept", boost::regex::icase),
+ boost::regex("\\*/\\*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-keep-alive", boost::regex::icase),
+ boost::regex("300", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-pragma", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-range", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-referer", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-encoding", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-expect", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-transfer-encoding", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+
+ HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
+ url_base + "reflect/",
+ ba,
+ options,
+ headers,
+ handlerp);
+ ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ ba->release();
+ ba = NULL;
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options & headers
options.reset();
headers.reset();
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
- }
- catch (...)
- {
- stop_thread(req);
- if (ba)
- {
- ba->release();
- ba = NULL;
- }
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ if (ba)
+ {
+ ba->release();
+ ba = NULL;
+ }
options.reset();
headers.reset();
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
@@ -2523,516 +2523,516 @@ void HttpRequestTestObjectType::test<20>()
template <> template <>
void HttpRequestTestObjectType::test<21>()
{
- // It appears that HttpRequest is fully capable of sending duplicate header values in violation of
- // this test's expectations. Something needs to budge: is sending duplicate header values desired?
- //
- // Test server /reflect/ response headers (mirrored from request)
- //
- // X-Reflect-content-type: text/plain
- // X-Reflect-content-type: text/html
- // X-Reflect-content-type: application/llsd+xml
- //
- skip("FIXME: Bad assertions or broken functionality.");
-
- ScopedCurlInit ready;
-
- // Warmup boost::regex to pre-alloc memory for memory size tests
- boost::regex warmup("askldjflasdj;f", boost::regex::icase);
- boost::regex_match("akl;sjflajfk;ajsk", warmup);
-
- std::string url_base(get_base_url());
-
- set_test_name("Header generation for HttpRequest PUT with header overrides");
-
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ // It appears that HttpRequest is fully capable of sending duplicate header values in violation of
+ // this test's expectations. Something needs to budge: is sending duplicate header values desired?
+ //
+ // Test server /reflect/ response headers (mirrored from request)
+ //
+ // X-Reflect-content-type: text/plain
+ // X-Reflect-content-type: text/html
+ // X-Reflect-content-type: application/llsd+xml
+ //
+ skip("FIXME: Bad assertions or broken functionality.");
+
+ ScopedCurlInit ready;
+
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
+
+ std::string url_base(get_base_url());
+
+ set_test_name("Header generation for HttpRequest PUT with header overrides");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
-
- HttpRequest * req = NULL;
- HttpOptions::ptr_t options;
- HttpHeaders::ptr_t headers;
- BufferArray * ba = NULL;
-
- try
- {
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions::ptr_t options;
+ HttpHeaders::ptr_t headers;
+ BufferArray * ba = NULL;
+
+ try
+ {
// Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
+ HttpRequest::createService();
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
- // options set
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // options set
options = HttpOptions::ptr_t(new HttpOptions());
- options->setWantHeaders(true);
-
- // headers
- headers = HttpHeaders::ptr_t(new HttpHeaders);
- headers->append("content-type", "text/plain");
- headers->append("content-type", "text/html");
- headers->append("content-type", "application/llsd+xml");
-
- // And a buffer array
- const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>");
- ba = new BufferArray;
- ba->append(msg, strlen(msg));
-
- // Issue a default PUT
- mStatus = HttpStatus(200);
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-connection", boost::regex::icase),
- boost::regex("keep-alive", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept", boost::regex::icase),
- boost::regex("\\*/\\*", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
- boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-keep-alive", boost::regex::icase),
- boost::regex("\\d+", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-host", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-length", boost::regex::icase),
- boost::regex("\\d+", boost::regex::icase)));
- handler.mHeadersRequired.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-type", boost::regex::icase),
- boost::regex("application/llsd\\+xml", boost::regex::icase)));
-
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-cache-control", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-pragma", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-range", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-referer", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-encoding", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-expect", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-transfer-encoding", boost::regex::icase),
- boost::regex(".*", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-type", boost::regex::icase),
- boost::regex("text/plain", boost::regex::icase)));
- handler.mHeadersDisallowed.push_back(
- regex_container_t::value_type(
- boost::regex("X-Reflect-content-type", boost::regex::icase),
- boost::regex("text/html", boost::regex::icase)));
- HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
- url_base + "reflect/",
- ba,
- options,
- headers,
- handlerp);
- ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
- ba->release();
- ba = NULL;
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == 1);
-
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- handler.mHeadersRequired.clear();
- handler.mHeadersDisallowed.clear();
- handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 2)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 2);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release options & headers
+ options->setWantHeaders(true);
+
+ // headers
+ headers = HttpHeaders::ptr_t(new HttpHeaders);
+ headers->append("content-type", "text/plain");
+ headers->append("content-type", "text/html");
+ headers->append("content-type", "application/llsd+xml");
+
+ // And a buffer array
+ const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>");
+ ba = new BufferArray;
+ ba->append(msg, strlen(msg));
+
+ // Issue a default PUT
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-connection", boost::regex::icase),
+ boost::regex("keep-alive", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept", boost::regex::icase),
+ boost::regex("\\*/\\*", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-accept-encoding", boost::regex::icase),
+ boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-keep-alive", boost::regex::icase),
+ boost::regex("\\d+", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-host", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-length", boost::regex::icase),
+ boost::regex("\\d+", boost::regex::icase)));
+ handler.mHeadersRequired.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-type", boost::regex::icase),
+ boost::regex("application/llsd\\+xml", boost::regex::icase)));
+
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-cache-control", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-pragma", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-range", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-referer", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-encoding", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-expect", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-transfer-encoding", boost::regex::icase),
+ boost::regex(".*", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-type", boost::regex::icase),
+ boost::regex("text/plain", boost::regex::icase)));
+ handler.mHeadersDisallowed.push_back(
+ regex_container_t::value_type(
+ boost::regex("X-Reflect-content-type", boost::regex::icase),
+ boost::regex("text/html", boost::regex::icase)));
+ HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
+ url_base + "reflect/",
+ ba,
+ options,
+ headers,
+ handlerp);
+ ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ ba->release();
+ ba = NULL;
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options & headers
options.reset();
headers.reset();
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
- }
- catch (...)
- {
- stop_thread(req);
- if (ba)
- {
- ba->release();
- ba = NULL;
- }
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ if (ba)
+ {
+ ba->release();
+ ba = NULL;
+ }
options.reset();
headers.reset();
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
// BUG-2295 Tests - Content-Range header received but no body
template <> template <>
void HttpRequestTestObjectType::test<22>()
{
- ScopedCurlInit ready;
+ ScopedCurlInit ready;
+
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
- std::string url_base(get_base_url());
- // std::cerr << "Base: " << url_base << std::endl;
-
- set_test_name("BUG-2295");
+ set_test_name("BUG-2295");
#if LL_WINDOWS && ADDRESS_SIZE == 64
- // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it
- if (getenv("TEAMCITY_PROJECT_NAME"))
- {
- skip("BUG-2295 - partial load on W64 causes freeze");
- }
+ // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it
+ if (getenv("TEAMCITY_PROJECT_NAME"))
+ {
+ skip("BUG-2295 - partial load on W64 causes freeze");
+ }
#endif
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- mHandlerCalls = 0;
+ mHandlerCalls = 0;
- HttpOptions::ptr_t options;
- HttpRequest * req = NULL;
+ HttpOptions::ptr_t options;
+ HttpRequest * req = NULL;
- try
- {
+ try
+ {
// options set
options = HttpOptions::ptr_t(new HttpOptions());
- options->setRetries(1); // Partial_File is retryable and can timeout in here
- options->setDNSCacheTimeout(30);
-
- // Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
-
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
-
- // ======================================
- // Issue bug2295 GETs that will get a 206
- // ======================================
- mStatus = HttpStatus(206);
- static const int test_count(3);
- for (int i(0); i < test_count; ++i)
- {
- char buffer[128];
- sprintf(buffer, "/bug2295/%d/", i);
- HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
- url_base + buffer,
- 0,
- 25,
- options,
+ options->setRetries(1); // Partial_File is retryable and can timeout in here
+ options->setDNSCacheTimeout(30);
+
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // ======================================
+ // Issue bug2295 GETs that will get a 206
+ // ======================================
+ mStatus = HttpStatus(206);
+ static const int test_count(3);
+ for (int i(0); i < test_count; ++i)
+ {
+ char buffer[128];
+ sprintf(buffer, "/bug2295/%d/", i);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ url_base + buffer,
+ 0,
+ 25,
+ options,
+ HttpHeaders::ptr_t(),
+ handlerp);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ }
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < test_count)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time - ms1", count < limit);
+ ensure("One handler invocation for each request - ms1", mHandlerCalls == test_count);
+
+ // ======================================
+ // Issue bug2295 GETs that will get a libcurl 18 (PARTIAL_FILE)
+ // ======================================
+ mHandlerCalls = 0;
+ mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_PARTIAL_FILE);
+ static const int test2_count(1);
+ for (int i(0); i < test2_count; ++i)
+ {
+ char buffer[128];
+ sprintf(buffer, "/bug2295/00000012/%d/", i);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ url_base + buffer,
+ 0,
+ 25,
+ options,
HttpHeaders::ptr_t(),
handlerp);
- ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
- }
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < test_count)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time - ms1", count < limit);
- ensure("One handler invocation for each request - ms1", mHandlerCalls == test_count);
-
- // ======================================
- // Issue bug2295 GETs that will get a libcurl 18 (PARTIAL_FILE)
- // ======================================
- mHandlerCalls = 0;
- mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_PARTIAL_FILE);
- static const int test2_count(1);
- for (int i(0); i < test2_count; ++i)
- {
- char buffer[128];
- sprintf(buffer, "/bug2295/00000012/%d/", i);
- HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
- url_base + buffer,
- 0,
- 25,
- options,
- HttpHeaders::ptr_t(),
- handlerp);
- ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
- }
-
- // Run the notification pump.
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < test2_count)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time - ms2", count < limit);
- ensure("One handler invocation for each request - ms2", mHandlerCalls == test2_count);
-
- // ======================================
- // Issue bug2295 GETs that will get an llcorehttp HE_INV_CONTENT_RANGE_HDR status
- // ======================================
- mHandlerCalls = 0;
- mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
- static const int test3_count(1);
- for (int i(0); i < test3_count; ++i)
- {
- char buffer[128];
- sprintf(buffer, "/bug2295/inv_cont_range/%d/", i);
- HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
- url_base + buffer,
- 0,
- 25,
- options,
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ }
+
+ // Run the notification pump.
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < test2_count)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time - ms2", count < limit);
+ ensure("One handler invocation for each request - ms2", mHandlerCalls == test2_count);
+
+ // ======================================
+ // Issue bug2295 GETs that will get an llcorehttp HE_INV_CONTENT_RANGE_HDR status
+ // ======================================
+ mHandlerCalls = 0;
+ mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
+ static const int test3_count(1);
+ for (int i(0); i < test3_count; ++i)
+ {
+ char buffer[128];
+ sprintf(buffer, "/bug2295/inv_cont_range/%d/", i);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ url_base + buffer,
+ 0,
+ 25,
+ options,
HttpHeaders::ptr_t(),
handlerp);
- ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
- }
-
- // Run the notification pump.
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < test3_count)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time - ms3", count < limit);
- ensure("One handler invocation for each request - ms3", mHandlerCalls == test3_count);
-
- // ======================================
- // Okay, request a shutdown of the servicing thread
- // ======================================
- mStatus = HttpStatus();
- mHandlerCalls = 0;
- HttpHandle handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Shutdown request executed in reasonable time", count < limit);
- ensure("Shutdown handler invocation", mHandlerCalls == 1);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release options
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ }
+
+ // Run the notification pump.
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < test3_count)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time - ms3", count < limit);
+ ensure("One handler invocation for each request - ms3", mHandlerCalls == test3_count);
+
+ // ======================================
+ // Okay, request a shutdown of the servicing thread
+ // ======================================
+ mStatus = HttpStatus();
+ mHandlerCalls = 0;
+ HttpHandle handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Shutdown request executed in reasonable time", count < limit);
+ ensure("Shutdown handler invocation", mHandlerCalls == 1);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options
options.reset();
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
- }
- catch (...)
- {
- stop_thread(req);
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
template <> template <>
void HttpRequestTestObjectType::test<23>()
{
- ScopedCurlInit ready;
+ ScopedCurlInit ready;
- set_test_name("HttpRequest GET 503s with 'Retry-After'");
+ set_test_name("HttpRequest GET 503s with 'Retry-After'");
#if LL_WINDOWS && ADDRESS_SIZE == 64
- // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it
- if (getenv("TEAMCITY_PROJECT_NAME"))
- {
- skip("llcorehttp 503-with-retry test hangs on Windows 64");
- }
+ // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it
+ if (getenv("TEAMCITY_PROJECT_NAME"))
+ {
+ skip("llcorehttp 503-with-retry test hangs on Windows 64");
+ }
#endif
- // This tests mainly that the code doesn't fall over if
- // various well- and mis-formed Retry-After headers are
- // sent along with the response. Direct inspection of
- // the parsing result isn't supported.
-
- // Handler can be stack-allocated *if* there are no dangling
- // references to it after completion of this method.
- // Create before memory record as the string copy will bump numbers.
- TestHandler2 handler(this, "handler");
+ // This tests mainly that the code doesn't fall over if
+ // various well- and mis-formed Retry-After headers are
+ // sent along with the response. Direct inspection of
+ // the parsing result isn't supported.
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // 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);
- std::string url_base(get_base_url() + "/503/"); // path to 503 generators
- mHandlerCalls = 0;
-
- HttpRequest * req = NULL;
- HttpOptions::ptr_t opts;
-
- try
- {
+ std::string url_base(get_base_url() + "/503/"); // path to 503 generators
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions::ptr_t opts;
+
+ try
+ {
// Get singletons created
- HttpRequest::createService();
-
- // Start threading early so that thread memory is invariant
- // over the test.
- HttpRequest::startThread();
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
- // create a new ref counted object with an implicit reference
- req = new HttpRequest();
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
opts = HttpOptions::ptr_t(new HttpOptions());
- opts->setRetries(1); // Retry once only
- opts->setUseRetryAfter(true); // Try to parse the retry-after header
-
- // Issue a GET that 503s with valid retry-after
- mStatus = HttpStatus(503);
- int url_limit(6);
- for (int i(0); i < url_limit; ++i)
- {
- std::ostringstream url;
- url << url_base << i << "/";
- HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
- url.str(),
- 0,
- 0,
- opts,
+ opts->setRetries(1); // Retry once only
+ opts->setUseRetryAfter(true); // Try to parse the retry-after header
+
+ // Issue a GET that 503s with valid retry-after
+ mStatus = HttpStatus(503);
+ int url_limit(6);
+ for (int i(0); i < url_limit; ++i)
+ {
+ std::ostringstream url;
+ url << url_base << i << "/";
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ url.str(),
+ 0,
+ 0,
+ opts,
HttpHeaders::ptr_t(),
handlerp);
- std::ostringstream testtag;
- testtag << "Valid handle returned for 503 request #" << i;
- ensure(testtag.str(), handle != LLCORE_HTTP_HANDLE_INVALID);
- }
-
-
- // Run the notification pump.
- int count(0);
- int limit(LOOP_COUNT_LONG);
- while (count++ < limit && mHandlerCalls < url_limit)
- {
- req->update(0);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Request executed in reasonable time", count < limit);
- ensure("One handler invocation for request", mHandlerCalls == url_limit);
-
- // Okay, request a shutdown of the servicing thread
- mStatus = HttpStatus();
- mHandlerCalls = 0;
- HttpHandle handle = req->requestStopThread(handlerp);
- ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-
- // Run the notification pump again
- count = 0;
- limit = LOOP_COUNT_LONG;
- while (count++ < limit && mHandlerCalls < 1)
- {
- req->update(1000000);
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Second request executed in reasonable time", count < limit);
- ensure("Second handler invocation", mHandlerCalls == 1);
-
- // See that we actually shutdown the thread
- count = 0;
- limit = LOOP_COUNT_SHORT;
- while (count++ < limit && ! HttpService::isStopped())
- {
- usleep(LOOP_SLEEP_INTERVAL);
- }
- ensure("Thread actually stopped running", HttpService::isStopped());
-
- // release options
+ std::ostringstream testtag;
+ testtag << "Valid handle returned for 503 request #" << i;
+ ensure(testtag.str(), handle != LLCORE_HTTP_HANDLE_INVALID);
+ }
+
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < url_limit)
+ {
+ req->update(0);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == url_limit);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ mHandlerCalls = 0;
+ HttpHandle handle = req->requestStopThread(handlerp);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 1);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options
opts.reset();
-
- // release the request object
- delete req;
- req = NULL;
-
- // Shut down service
- HttpRequest::destroyService();
- }
- catch (...)
- {
- stop_thread(req);
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
opts.reset();
- delete req;
- HttpRequest::destroyService();
- throw;
- }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
}
@@ -3045,7 +3045,7 @@ namespace
void usleep(unsigned long usec)
{
- Sleep((DWORD) (usec / 1000UL));
+ Sleep((DWORD) (usec / 1000UL));
}
#endif
diff --git a/indra/llcorehttp/tests/test_httprequestqueue.hpp b/indra/llcorehttp/tests/test_httprequestqueue.hpp
index dba9e0b250..c6fa1b7534 100644
--- a/indra/llcorehttp/tests/test_httprequestqueue.hpp
+++ b/indra/llcorehttp/tests/test_httprequestqueue.hpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file test_httprequestqueue.hpp
* @brief unit tests for the LLCore::HttpRequestQueue class
*
@@ -42,8 +42,8 @@ namespace tut
struct HttpRequestqueueTestData
{
- // the test objects inherit from this so the member functions and variables
- // can be referenced directly inside of the test functions.
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
};
typedef test_group<HttpRequestqueueTestData> HttpRequestqueueTestGroupType;
@@ -53,102 +53,102 @@ HttpRequestqueueTestGroupType HttpRequestqueueTestGroup("HttpRequestqueue Tests"
template <> template <>
void HttpRequestqueueTestObjectType::test<1>()
{
- set_test_name("HttpRequestQueue construction");
+ set_test_name("HttpRequestQueue construction");
- // create a new ref counted object with an implicit reference
- HttpRequestQueue::init();
-
- ensure("One ref on construction of HttpRequestQueue", HttpRequestQueue::instanceOf()->getRefCount() == 1);
+ // create a new ref counted object with an implicit reference
+ HttpRequestQueue::init();
- // release the implicit reference, causing the object to be released
- HttpRequestQueue::term();
+ ensure("One ref on construction of HttpRequestQueue", HttpRequestQueue::instanceOf()->getRefCount() == 1);
+
+ // release the implicit reference, causing the object to be released
+ HttpRequestQueue::term();
}
template <> template <>
void HttpRequestqueueTestObjectType::test<2>()
{
- set_test_name("HttpRequestQueue refcount works");
+ set_test_name("HttpRequestQueue refcount works");
+
+ // create a new ref counted object with an implicit reference
+ HttpRequestQueue::init();
+
+ HttpRequestQueue * rq = HttpRequestQueue::instanceOf();
+ rq->addRef();
- // create a new ref counted object with an implicit reference
- HttpRequestQueue::init();
+ // release the singleton, hold on to the object
+ HttpRequestQueue::term();
- HttpRequestQueue * rq = HttpRequestQueue::instanceOf();
- rq->addRef();
-
- // release the singleton, hold on to the object
- HttpRequestQueue::term();
-
- ensure("One ref after term() called", rq->getRefCount() == 1);
+ ensure("One ref after term() called", rq->getRefCount() == 1);
- // Drop ref
- rq->release();
+ // Drop ref
+ rq->release();
}
template <> template <>
void HttpRequestqueueTestObjectType::test<3>()
{
- set_test_name("HttpRequestQueue addOp/fetchOp work");
+ set_test_name("HttpRequestQueue addOp/fetchOp work");
- // create a new ref counted object with an implicit reference
- HttpRequestQueue::init();
+ // create a new ref counted object with an implicit reference
+ HttpRequestQueue::init();
- HttpRequestQueue * rq = HttpRequestQueue::instanceOf();
+ HttpRequestQueue * rq = HttpRequestQueue::instanceOf();
- HttpOperation::ptr_t op(new HttpOpNull());
+ HttpOperation::ptr_t op(new HttpOpNull());
- rq->addOp(op); // transfer my refcount
+ rq->addOp(op); // transfer my refcount
- op = rq->fetchOp(true); // Potentially hangs the test on failure
- ensure("One goes in, one comes out", static_cast<bool>(op));
+ op = rq->fetchOp(true); // Potentially hangs the test on failure
+ ensure("One goes in, one comes out", static_cast<bool>(op));
op.reset();
- op = rq->fetchOp(false);
- ensure("Better not be two of them", !op);
-
- // release the singleton, hold on to the object
- HttpRequestQueue::term();
+ op = rq->fetchOp(false);
+ ensure("Better not be two of them", !op);
+
+ // release the singleton, hold on to the object
+ HttpRequestQueue::term();
}
template <> template <>
void HttpRequestqueueTestObjectType::test<4>()
{
- set_test_name("HttpRequestQueue addOp/fetchAll work");
+ set_test_name("HttpRequestQueue addOp/fetchAll work");
+
+ // create a new ref counted object with an implicit reference
+ HttpRequestQueue::init();
- // create a new ref counted object with an implicit reference
- HttpRequestQueue::init();
+ HttpRequestQueue * rq = HttpRequestQueue::instanceOf();
- HttpRequestQueue * rq = HttpRequestQueue::instanceOf();
+ HttpOperation::ptr_t op (new HttpOpNull());
+ rq->addOp(op); // transfer my refcount
- HttpOperation::ptr_t op (new HttpOpNull());
- rq->addOp(op); // transfer my refcount
+ op.reset(new HttpOpNull());
+ rq->addOp(op); // transfer my refcount
- op.reset(new HttpOpNull());
- rq->addOp(op); // transfer my refcount
+ op.reset(new HttpOpNull());
+ rq->addOp(op); // transfer my refcount
- op.reset(new HttpOpNull());
- rq->addOp(op); // transfer my refcount
-
- {
- HttpRequestQueue::OpContainer ops;
- rq->fetchAll(true, ops); // Potentially hangs the test on failure
- ensure("Three go in, three come out", 3 == ops.size());
+ {
+ HttpRequestQueue::OpContainer ops;
+ rq->fetchAll(true, ops); // Potentially hangs the test on failure
+ ensure("Three go in, three come out", 3 == ops.size());
- op = rq->fetchOp(false);
- ensure("Better not be any more of them", !op);
+ op = rq->fetchOp(false);
+ ensure("Better not be any more of them", !op);
op.reset();
- // release the singleton, hold on to the object
- HttpRequestQueue::term();
+ // release the singleton, hold on to the object
+ HttpRequestQueue::term();
- // Release them
+ // Release them
ops.clear();
-// while (! ops.empty())
-// {
-// HttpOperation * op = ops.front();
-// ops.erase(ops.begin());
-// op->release();
-// }
- }
+// while (! ops.empty())
+// {
+// HttpOperation * op = ops.front();
+// ops.erase(ops.begin());
+// op->release();
+// }
+ }
}
} // end namespace tut
diff --git a/indra/llcorehttp/tests/test_httpstatus.hpp b/indra/llcorehttp/tests/test_httpstatus.hpp
index cbe3f574d4..eac7ba8557 100644
--- a/indra/llcorehttp/tests/test_httpstatus.hpp
+++ b/indra/llcorehttp/tests/test_httpstatus.hpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file test_llrefcounted
* @brief unit tests for HttpStatus struct
*
@@ -39,8 +39,8 @@ namespace tut
struct HttpStatusTestData
{
- HttpStatusTestData()
- {}
+ HttpStatusTestData()
+ {}
};
typedef test_group<HttpStatusTestData> HttpStatusTestGroupType;
@@ -51,250 +51,250 @@ HttpStatusTestGroupType HttpStatusTestGroup("HttpStatus Tests");
template <> template <>
void HttpStatusTestObjectType::test<1>()
{
- set_test_name("HttpStatus construction");
-
- // auto allocation fine for this
- HttpStatus status;
+ set_test_name("HttpStatus construction");
- status = HttpStatus(HttpStatus::EXT_CURL_EASY, 0);
-
- ensure(bool(status));
- ensure(false == !(status));
+ // auto allocation fine for this
+ HttpStatus status;
- status = HttpStatus(HttpStatus::EXT_CURL_MULTI, 0);
+ status = HttpStatus(HttpStatus::EXT_CURL_EASY, 0);
- ensure(bool(status));
- ensure(false == !(status));
+ ensure(bool(status));
+ ensure(false == !(status));
- status = HttpStatus(HttpStatus::LLCORE, HE_SUCCESS);
-
- ensure(bool(status));
- ensure(false == !(status));
+ status = HttpStatus(HttpStatus::EXT_CURL_MULTI, 0);
- status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -1);
+ ensure(bool(status));
+ ensure(false == !(status));
- ensure(false == bool(status));
- ensure(!(status));
+ status = HttpStatus(HttpStatus::LLCORE, HE_SUCCESS);
- status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_DOWNLOAD_RESUME);
+ ensure(bool(status));
+ ensure(false == !(status));
- ensure(false == bool(status));
- ensure(!(status));
+ status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -1);
+
+ ensure(false == bool(status));
+ ensure(!(status));
+
+ status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_DOWNLOAD_RESUME);
+
+ ensure(false == bool(status));
+ ensure(!(status));
}
// template <> template <>
// void HttpStatusTestObjectType::test<2>()
// {
-// set_test_name("HttpStatus memory structure");
-//
-// // Require that an HttpStatus object can be trivially
-// // returned as a function return value in registers.
-// // One should fit in an int on all platforms.
-//
-// //ensure(sizeof(HttpStatus) <= sizeof(int));
+// set_test_name("HttpStatus memory structure");
+//
+// // Require that an HttpStatus object can be trivially
+// // returned as a function return value in registers.
+// // One should fit in an int on all platforms.
+//
+// //ensure(sizeof(HttpStatus) <= sizeof(int));
// }
template <> template <>
void HttpStatusTestObjectType::test<2>()
{
- set_test_name("HttpStatus valid status string conversion");
-
- HttpStatus status = HttpStatus(HttpStatus::EXT_CURL_EASY, 0);
- std::string msg = status.toString();
- // std::cout << "Result: " << msg << std::endl;
- ensure(msg.empty());
-
- status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_FUNCTION_ARGUMENT);
- msg = status.toString();
- // std::cout << "Result: " << msg << std::endl;
- ensure(! msg.empty());
-
- status = HttpStatus(HttpStatus::EXT_CURL_MULTI, CURLM_OUT_OF_MEMORY);
- msg = status.toString();
- // std::cout << "Result: " << msg << std::endl;
- ensure(! msg.empty());
-
- status = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN);
- msg = status.toString();
- // std::cout << "Result: " << msg << std::endl;
- ensure(! msg.empty());
+ set_test_name("HttpStatus valid status string conversion");
+
+ HttpStatus status = HttpStatus(HttpStatus::EXT_CURL_EASY, 0);
+ std::string msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(msg.empty());
+
+ status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_FUNCTION_ARGUMENT);
+ msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(! msg.empty());
+
+ status = HttpStatus(HttpStatus::EXT_CURL_MULTI, CURLM_OUT_OF_MEMORY);
+ msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(! msg.empty());
+
+ status = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN);
+ msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(! msg.empty());
}
template <> template <>
void HttpStatusTestObjectType::test<3>()
{
- set_test_name("HttpStatus invalid status string conversion");
-
- HttpStatus status = HttpStatus(HttpStatus::EXT_CURL_EASY, 32726);
- std::string msg = status.toString();
- // std::cout << "Result: " << msg << std::endl;
- ensure(! msg.empty());
-
- status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -470);
- msg = status.toString();
- // std::cout << "Result: " << msg << std::endl;
- ensure(! msg.empty());
-
- status = HttpStatus(HttpStatus::LLCORE, 923);
- msg = status.toString();
- // std::cout << "Result: " << msg << std::endl;
- ensure(! msg.empty());
+ set_test_name("HttpStatus invalid status string conversion");
+
+ HttpStatus status = HttpStatus(HttpStatus::EXT_CURL_EASY, 32726);
+ std::string msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(! msg.empty());
+
+ status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -470);
+ msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(! msg.empty());
+
+ status = HttpStatus(HttpStatus::LLCORE, 923);
+ msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(! msg.empty());
}
template <> template <>
void HttpStatusTestObjectType::test<4>()
{
- set_test_name("HttpStatus equality/inequality testing");
+ set_test_name("HttpStatus equality/inequality testing");
- // Make certain equality/inequality tests do not pass
- // through the bool conversion. Distinct successful
- // and error statuses should compare unequal.
+ // Make certain equality/inequality tests do not pass
+ // through the bool conversion. Distinct successful
+ // and error statuses should compare unequal.
- HttpStatus status1(HttpStatus::LLCORE, HE_SUCCESS);
- HttpStatus status2(HttpStatus::EXT_CURL_EASY, HE_SUCCESS);
- ensure(status1 != status2);
+ HttpStatus status1(HttpStatus::LLCORE, HE_SUCCESS);
+ HttpStatus status2(HttpStatus::EXT_CURL_EASY, HE_SUCCESS);
+ ensure(status1 != status2);
- status1 = HttpStatus(HttpStatus::LLCORE, HE_REPLY_ERROR);
- status1 = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN);
+ status1 = HttpStatus(HttpStatus::LLCORE, HE_REPLY_ERROR);
+ status1 = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN);
- ensure(status1 != status2);
+ ensure(status1 != status2);
}
template <> template <>
void HttpStatusTestObjectType::test<5>()
{
- set_test_name("HttpStatus basic HTTP status encoding");
-
- HttpStatus status;
-
- status = HttpStatus(200, HE_SUCCESS);
- std::string msg = status.toString();
- ensure(msg.empty());
- ensure(bool(status));
-
- // Normally a success but application says error
- status = HttpStatus(200, HE_REPLY_ERROR);
- msg = status.toString();
- ensure(! msg.empty());
- ensure(! bool(status));
- ensure(status.toULong() > 1UL); // Biggish number, not a bool-to-ulong
-
- // Same statuses with distinct success/fail are distinct
- status = HttpStatus(200, HE_SUCCESS);
- HttpStatus status2(200, HE_REPLY_ERROR);
- ensure(status != status2);
-
- // Normally an error but application says okay
- status = HttpStatus(406, HE_SUCCESS);
- msg = status.toString();
- ensure(msg.empty());
- ensure(bool(status));
-
- // Different statuses but both successful are distinct
- status = HttpStatus(200, HE_SUCCESS);
- status2 = HttpStatus(201, HE_SUCCESS);
- ensure(status != status2);
-
- // Different statuses but both failed are distinct
- status = HttpStatus(200, HE_REPLY_ERROR);
- status2 = HttpStatus(201, HE_REPLY_ERROR);
- ensure(status != status2);
+ set_test_name("HttpStatus basic HTTP status encoding");
+
+ HttpStatus status;
+
+ status = HttpStatus(200, HE_SUCCESS);
+ std::string msg = status.toString();
+ ensure(msg.empty());
+ ensure(bool(status));
+
+ // Normally a success but application says error
+ status = HttpStatus(200, HE_REPLY_ERROR);
+ msg = status.toString();
+ ensure(! msg.empty());
+ ensure(! bool(status));
+ ensure(status.toULong() > 1UL); // Biggish number, not a bool-to-ulong
+
+ // Same statuses with distinct success/fail are distinct
+ status = HttpStatus(200, HE_SUCCESS);
+ HttpStatus status2(200, HE_REPLY_ERROR);
+ ensure(status != status2);
+
+ // Normally an error but application says okay
+ status = HttpStatus(406, HE_SUCCESS);
+ msg = status.toString();
+ ensure(msg.empty());
+ ensure(bool(status));
+
+ // Different statuses but both successful are distinct
+ status = HttpStatus(200, HE_SUCCESS);
+ status2 = HttpStatus(201, HE_SUCCESS);
+ ensure(status != status2);
+
+ // Different statuses but both failed are distinct
+ status = HttpStatus(200, HE_REPLY_ERROR);
+ status2 = HttpStatus(201, HE_REPLY_ERROR);
+ ensure(status != status2);
}
template <> template <>
void HttpStatusTestObjectType::test<6>()
{
- set_test_name("HttpStatus HTTP status text strings");
+ set_test_name("HttpStatus HTTP status text strings");
- HttpStatus status(100, HE_REPLY_ERROR);
- std::string msg(status.toString());
- ensure(! msg.empty()); // Should be something
- ensure(msg == "Continue");
+ HttpStatus status(100, HE_REPLY_ERROR);
+ std::string msg(status.toString());
+ ensure(! msg.empty()); // Should be something
+ ensure(msg == "Continue");
- status = HttpStatus(200, HE_SUCCESS);
- msg = status.toString();
- ensure(msg.empty()); // Success is empty
+ status = HttpStatus(200, HE_SUCCESS);
+ msg = status.toString();
+ ensure(msg.empty()); // Success is empty
- status = HttpStatus(199, HE_REPLY_ERROR);
- msg = status.toString();
- ensure(msg == "Unknown error");
+ status = HttpStatus(199, HE_REPLY_ERROR);
+ msg = status.toString();
+ ensure(msg == "Unknown error");
- status = HttpStatus(505, HE_REPLY_ERROR);
- msg = status.toString();
- ensure(msg == "HTTP Version not supported");
+ status = HttpStatus(505, HE_REPLY_ERROR);
+ msg = status.toString();
+ ensure(msg == "HTTP Version not supported");
- status = HttpStatus(506, HE_REPLY_ERROR);
- msg = status.toString();
- ensure(msg == "Unknown error");
+ status = HttpStatus(506, HE_REPLY_ERROR);
+ msg = status.toString();
+ ensure(msg == "Unknown error");
- status = HttpStatus(999, HE_REPLY_ERROR);
- msg = status.toString();
- ensure(msg == "Unknown error");
+ status = HttpStatus(999, HE_REPLY_ERROR);
+ msg = status.toString();
+ ensure(msg == "Unknown error");
}
template <> template <>
void HttpStatusTestObjectType::test<7>()
{
- set_test_name("HttpStatus toHex() nominal function");
-
- HttpStatus status(404);
- std::string msg = status.toHex();
- // std::cout << "Result: " << msg << std::endl;
- ensure_equals(msg, "01940001");
+ set_test_name("HttpStatus toHex() nominal function");
+
+ HttpStatus status(404);
+ std::string msg = status.toHex();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure_equals(msg, "01940001");
}
template <> template <>
void HttpStatusTestObjectType::test<8>()
{
- set_test_name("HttpStatus toTerseString() nominal function");
-
- HttpStatus status(404);
- std::string msg = status.toTerseString();
- // std::cout << "Result: " << msg << std::endl;
- ensure("Normal HTTP 404", msg == "Http_404");
-
- status = HttpStatus(200);
- msg = status.toTerseString();
- // std::cout << "Result: " << msg << std::endl;
- ensure("Normal HTTP 200", msg == "Http_200");
-
- status = HttpStatus(200, HE_REPLY_ERROR);
- msg = status.toTerseString();
- // std::cout << "Result: " << msg << std::endl;
- ensure("Unsuccessful HTTP 200", msg == "Http_200"); // No distinction for error
-
- status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
- msg = status.toTerseString();
- // std::cout << "Result: " << msg << std::endl;
- ensure("Easy couldn't connect error", msg == "Easy_7");
-
- status = HttpStatus(HttpStatus::EXT_CURL_MULTI, CURLM_OUT_OF_MEMORY);
- msg = status.toTerseString();
- // std::cout << "Result: " << msg << std::endl;
- ensure("Multi out-of-memory error", msg == "Multi_3");
-
- status = HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_SET);
- msg = status.toTerseString();
- // std::cout << "Result: " << msg << std::endl;
- ensure("Core option not set error", msg == "Core_7");
-
- status = HttpStatus(22000, 1);
- msg = status.toTerseString();
- // std::cout << "Result: " << msg << std::endl;
- ensure("Undecodable error", msg == "Unknown_1");
-
- status = HttpStatus(22000, -1);
- msg = status.toTerseString();
- // std::cout << "Result: " << msg << std::endl;
- ensure("Undecodable error 65535", msg == "Unknown_65535");
+ set_test_name("HttpStatus toTerseString() nominal function");
+
+ HttpStatus status(404);
+ std::string msg = status.toTerseString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure("Normal HTTP 404", msg == "Http_404");
+
+ status = HttpStatus(200);
+ msg = status.toTerseString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure("Normal HTTP 200", msg == "Http_200");
+
+ status = HttpStatus(200, HE_REPLY_ERROR);
+ msg = status.toTerseString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure("Unsuccessful HTTP 200", msg == "Http_200"); // No distinction for error
+
+ status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
+ msg = status.toTerseString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure("Easy couldn't connect error", msg == "Easy_7");
+
+ status = HttpStatus(HttpStatus::EXT_CURL_MULTI, CURLM_OUT_OF_MEMORY);
+ msg = status.toTerseString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure("Multi out-of-memory error", msg == "Multi_3");
+
+ status = HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_SET);
+ msg = status.toTerseString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure("Core option not set error", msg == "Core_7");
+
+ status = HttpStatus(22000, 1);
+ msg = status.toTerseString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure("Undecodable error", msg == "Unknown_1");
+
+ status = HttpStatus(22000, -1);
+ msg = status.toTerseString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure("Undecodable error 65535", msg == "Unknown_65535");
}
} // end namespace tut
-#endif // TEST_HTTP_STATUS_H
+#endif // TEST_HTTP_STATUS_H
diff --git a/indra/llcorehttp/tests/test_llcorehttp_peer.py b/indra/llcorehttp/tests/test_llcorehttp_peer.py
index b9992538ba..b2805fda11 100755
--- a/indra/llcorehttp/tests/test_llcorehttp_peer.py
+++ b/indra/llcorehttp/tests/test_llcorehttp_peer.py
@@ -50,12 +50,12 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
"""This subclass of BaseHTTPRequestHandler is to receive and echo
LLSD-flavored messages sent by the C++ LLHTTPClient.
- Target URLs are fairly free-form and are assembled by
+ Target URLs are fairly free-form and are assembled by
concatinating fragments. Currently defined fragments
are:
- '/reflect/' Request headers are bounced back to caller
after prefixing with 'X-Reflect-'
- - '/fail/' Body of request can contain LLSD with
+ - '/fail/' Body of request can contain LLSD with
'reason' string and 'status' integer
which will become response header.
- '/bug2295/' 206 response, no data in body:
@@ -69,7 +69,7 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
-- '/bug2295/inv_cont_range/0/' Generates HE_INVALID_CONTENT_RANGE error in llcorehttp.
- '/503/' Generate 503 responses with various kinds
of 'retry-after' headers
- -- '/503/0/' "Retry-After: 2"
+ -- '/503/0/' "Retry-After: 2"
-- '/503/1/' "Retry-After: Thu, 31 Dec 2043 23:59:59 GMT"
-- '/503/2/' "Retry-After: Fri, 31 Dec 1999 23:59:59 GMT"
-- '/503/3/' "Retry-After: "
diff --git a/indra/llcorehttp/tests/test_refcounted.hpp b/indra/llcorehttp/tests/test_refcounted.hpp
index 2310812d5a..c0c8e78413 100644
--- a/indra/llcorehttp/tests/test_refcounted.hpp
+++ b/indra/llcorehttp/tests/test_refcounted.hpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file test_refcounted.hpp
* @brief unit tests for the LLCoreInt::RefCounted class
*
@@ -34,93 +34,93 @@ using namespace LLCoreInt;
namespace tut
{
- struct RefCountedTestData
- {
- // the test objects inherit from this so the member functions and variables
- // can be referenced directly inside of the test functions.
- };
+ struct RefCountedTestData
+ {
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
+ };
- typedef test_group<RefCountedTestData> RefCountedTestGroupType;
- typedef RefCountedTestGroupType::object RefCountedTestObjectType;
- RefCountedTestGroupType RefCountedTestGroup("RefCounted Tests");
+ typedef test_group<RefCountedTestData> RefCountedTestGroupType;
+ typedef RefCountedTestGroupType::object RefCountedTestObjectType;
+ RefCountedTestGroupType RefCountedTestGroup("RefCounted Tests");
- template <> template <>
- void RefCountedTestObjectType::test<1>()
- {
- set_test_name("RefCounted construction with implicit count");
+ template <> template <>
+ void RefCountedTestObjectType::test<1>()
+ {
+ set_test_name("RefCounted construction with implicit count");
- // create a new ref counted object with an implicit reference
- RefCounted * rc = new RefCounted(true);
- ensure(rc->getRefCount() == 1);
+ // create a new ref counted object with an implicit reference
+ RefCounted * rc = new RefCounted(true);
+ ensure(rc->getRefCount() == 1);
- // release the implicit reference, causing the object to be released
- rc->release();
- }
+ // release the implicit reference, causing the object to be released
+ rc->release();
+ }
- template <> template <>
- void RefCountedTestObjectType::test<2>()
- {
- set_test_name("RefCounted construction without implicit count");
+ template <> template <>
+ void RefCountedTestObjectType::test<2>()
+ {
+ set_test_name("RefCounted construction without implicit count");
- // create a new ref counted object with an implicit reference
- RefCounted * rc = new RefCounted(false);
- ensure(rc->getRefCount() == 0);
+ // create a new ref counted object with an implicit reference
+ RefCounted * rc = new RefCounted(false);
+ ensure(rc->getRefCount() == 0);
- // add a reference
- rc->addRef();
- ensure(rc->getRefCount() == 1);
+ // add a reference
+ rc->addRef();
+ ensure(rc->getRefCount() == 1);
- // release the implicit reference, causing the object to be released
- rc->release();
- }
+ // release the implicit reference, causing the object to be released
+ rc->release();
+ }
- template <> template <>
- void RefCountedTestObjectType::test<3>()
- {
- set_test_name("RefCounted addRef and release");
+ template <> template <>
+ void RefCountedTestObjectType::test<3>()
+ {
+ set_test_name("RefCounted addRef and release");
- RefCounted * rc = new RefCounted(false);
+ RefCounted * rc = new RefCounted(false);
- for (int i = 0; i < 1024; ++i)
- {
- rc->addRef();
- }
+ for (int i = 0; i < 1024; ++i)
+ {
+ rc->addRef();
+ }
- ensure(rc->getRefCount() == 1024);
+ ensure(rc->getRefCount() == 1024);
- for (int i = 0; i < 1024; ++i)
- {
- rc->release();
- }
- }
+ for (int i = 0; i < 1024; ++i)
+ {
+ rc->release();
+ }
+ }
- template <> template <>
- void RefCountedTestObjectType::test<4>()
- {
- set_test_name("RefCounted isLastRef check");
+ template <> template <>
+ void RefCountedTestObjectType::test<4>()
+ {
+ set_test_name("RefCounted isLastRef check");
- RefCounted * rc = new RefCounted(true);
+ RefCounted * rc = new RefCounted(true);
- // with only one reference, isLastRef should be true
- ensure(rc->isLastRef());
+ // with only one reference, isLastRef should be true
+ ensure(rc->isLastRef());
- // release it to clean up memory
- rc->release();
- }
+ // release it to clean up memory
+ rc->release();
+ }
- template <> template <>
- void RefCountedTestObjectType::test<5>()
- {
- set_test_name("RefCounted noRef check");
+ template <> template <>
+ void RefCountedTestObjectType::test<5>()
+ {
+ set_test_name("RefCounted noRef check");
- RefCounted * rc = new RefCounted(false);
+ RefCounted * rc = new RefCounted(false);
- // set the noRef
- rc->noRef();
+ // set the noRef
+ rc->noRef();
- // with only one reference, isLastRef should be true
- ensure(rc->getRefCount() == RefCounted::NOT_REF_COUNTED);
- }
+ // with only one reference, isLastRef should be true
+ ensure(rc->getRefCount() == RefCounted::NOT_REF_COUNTED);
+ }
}
#endif // disabling on Win64
-#endif // TEST_LLCOREINT_REF_COUNTED_H_
+#endif // TEST_LLCOREINT_REF_COUNTED_H_