diff options
| author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-15 11:16:27 +0300 | 
|---|---|---|
| committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-15 11:16:27 +0300 | 
| commit | bccc10db9a90d365c353baebf443fde2030ce970 (patch) | |
| tree | 2c2e1fd94b29667a809f8d7285d049f5ff5d424d /indra/llcorehttp | |
| parent | 531cd34f670170ade57f8813fe48012b61a1d3c2 (diff) | |
| parent | bb3c36f5cbc0c3b542045fd27255eee24e03da22 (diff) | |
Merge branch 'main' into marchcat/x-b-merge
# Conflicts:
#	autobuild.xml
#	indra/cmake/ConfigurePkgConfig.cmake
#	indra/cmake/ICU4C.cmake
#	indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
#	indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h
#	indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h
#	indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
#	indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h
#	indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
#	indra/newview/llappviewerlinux_api.h
#	indra/newview/llappviewerlinux_api_dbus.cpp
#	indra/newview/llappviewerlinux_api_dbus.h
#	indra/newview/llfloateremojipicker.cpp
#	indra/newview/lloutfitslist.cpp
Diffstat (limited to 'indra/llcorehttp')
64 files changed, 10079 insertions, 10079 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 517076804d..d543512ec4 100644 --- a/indra/llcorehttp/_httpservice.cpp +++ b/indra/llcorehttp/_httpservice.cpp @@ -54,145 +54,145 @@ 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 +    {   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) +    : 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) -		{ +    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; -	} +        } + +        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; +    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; +    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; +    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; +    // 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;  } @@ -200,66 +200,66 @@ bool HttpService::isStopped()  void HttpService::startThread()  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; -	llassert_always(! mThread || STOPPED == sState); -	llassert_always(INITIALIZED == sState || STOPPED == sState); +    llassert_always(! mThread || STOPPED == sState); +    llassert_always(INITIALIZED == sState || STOPPED == sState); -	if (mThread) -	{ -		mThread->release(); -	} +    if (mThread) +    { +        mThread->release(); +    } -	// Push current policy definitions, enable policy & transport components -	mPolicy->start(); -	mTransport->start(mLastPolicy + 1); +    // 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; +    mThread = new LLCoreInt::HttpThread(boost::bind(&HttpService::threadRun, this, _1)); +    sState = RUNNING;  }  /// Threading:  callable by worker thread.  void HttpService::stopRequested()  { -	mExitRequested = 1U; +    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. +/// @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); +    bool canceled(false); + +    // Request can't be on request queue so skip that. -	// Request can't be on request queue so skip that. +    // Check the policy component's queues first +    canceled = mPolicy->cancel(handle); -	// 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); +    } -	if (! canceled) -	{ -		// If that didn't work, check transport's. -		canceled = mTransport->cancel(handle); -	} -	 -	return canceled; +    return canceled;  } -	 +  /// Threading:  callable by worker thread.  void HttpService::shutdown()  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; -	// Disallow future enqueue of requests -	mRequestQueue->stopQueue(); +    // Disallow future enqueue of requests +    mRequestQueue->stopQueue(); -	// Cancel requests already on the request queue -	HttpRequestQueue::OpContainer ops; -	mRequestQueue->fetchAll(false, ops); +    // 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) @@ -268,11 +268,11 @@ void HttpService::shutdown()      }      ops.clear(); -	// Shutdown transport canceling requests, freeing resources -	mTransport->shutdown(); +    // Shutdown transport canceling requests, freeing resources +    mTransport->shutdown(); -	// And now policy -	mPolicy->shutdown(); +    // And now policy +    mPolicy->shutdown();  } @@ -285,31 +285,31 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)  {      LL_PROFILER_SET_THREAD_NAME("HttpService"); -	boost::this_thread::disable_interruption di; +    boost::this_thread::disable_interruption di; + +    LLThread::registerThreadID(); -	LLThread::registerThreadID(); -	 -	ELoopSpeed loop(REQUEST_SLEEP); -	while (! mExitRequested) -	{ +    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); -		    } +            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&)          { @@ -331,250 +331,250 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)          }      } -	shutdown(); -	sState = STOPPED; +    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 +    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; +    // Queue emptied, allow polling loop to sleep +    return REQUEST_SLEEP;  }  HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass, -										long * ret_value) +                                        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; +    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) +                                        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 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) +    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 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) +                                        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 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) +                                        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 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) +    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; +    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;  } 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 c780c06b4e..50a8d461a7 100644 --- a/indra/llcorehttp/bufferarray.cpp +++ b/indra/llcorehttp/bufferarray.cpp @@ -52,33 +52,33 @@ namespace LLCore  class BufferArray::Block  {  public: -	~Block(); +    ~Block(); -	void operator delete(void *); -	void operator delete(void *, size_t len); +    void operator delete(void *); +    void operator delete(void *, size_t len);  protected: -	Block(size_t len); +    Block(size_t len); -	Block(const Block &);						// Not defined -	void operator=(const Block &);				// Not defined +    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); -	// 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); +    // Only public entry to get a block. +    static Block * alloc(size_t len);  public: -	size_t mUsed; -	size_t mAlloced; +    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];		 +    // *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];  }; @@ -87,61 +87,61 @@ public:  // ================================== -#if	! LL_WINDOWS +#if ! LL_WINDOWS  const size_t BufferArray::BLOCK_ALLOC_SIZE; -#endif	// ! LL_WINDOWS +#endif  // ! LL_WINDOWS  BufferArray::BufferArray() -	: LLCoreInt::RefCounted(true), -	  mLen(0) +    : LLCoreInt::RefCounted(true), +      mLen(0)  {}  BufferArray::~BufferArray()  { -	for (container_t::iterator it(mBlocks.begin()); -		 it != mBlocks.end(); -		 ++it) -	{ -		delete *it; -		*it = NULL; -	} -	mBlocks.clear(); +    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); -		} +    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          { @@ -158,163 +158,163 @@ size_t BufferArray::append(const void * src, size_t len)              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; +        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; +    // 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; +    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; +    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; +    *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; +    if (block < 0 || block >= mBlocks.size()) +    { +        return false; +    } + +    const Block & b(*mBlocks[block]); +    *start = &b.mData[0]; +    *end = &b.mData[b.mUsed]; +    return true;  } @@ -324,45 +324,45 @@ bool BufferArray::getBlockStartEnd(int block, const char ** start, const char **  BufferArray::Block::Block(size_t len) -	: mUsed(0), -	  mAlloced(len) +    : mUsed(0), +      mAlloced(len)  { -	memset(mData, 0, len); +    memset(mData, 0, len);  } -			 +  BufferArray::Block::~Block()  { -	mUsed = 0; -	mAlloced = 0; +    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 * 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; +    char * cmem = static_cast<char *>(mem); +    delete [] cmem;  }  void BufferArray::Block::operator delete(void * mem, size_t)  { -	operator delete(mem); +    operator delete(mem);  }  BufferArray::Block * BufferArray::Block::alloc(size_t len)  { -	Block * block = new (len) Block(len); -	return block; +    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_  | 
