From 6f4d36634e980bb989b9a8b762c3c622804c43dd Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Mon, 16 Mar 2015 17:14:34 -0700
Subject: Removal of RPCXML dep on LLCurl switching to LLCore::Html

---
 indra/llcorehttp/_httpoprequest.cpp    |  95 +++++++++++++++++++++++----
 indra/llcorehttp/_httpoprequest.h      |  11 +++-
 indra/llcorehttp/_httppolicyglobal.cpp |  30 +++++++++
 indra/llcorehttp/_httppolicyglobal.h   |   3 +
 indra/llcorehttp/_httpservice.cpp      |  80 ++++++++++++++++++++---
 indra/llcorehttp/_httpservice.h        |   9 ++-
 indra/llcorehttp/_refcounted.h         |  11 ++++
 indra/llcorehttp/bufferarray.h         |   2 +
 indra/llcorehttp/httpcommon.cpp        |  24 +++----
 indra/llcorehttp/httpcommon.h          | 116 ++++++++++++++++++++++++++-------
 indra/llcorehttp/httphandler.h         |   4 +-
 indra/llcorehttp/httpheaders.h         |   1 +
 indra/llcorehttp/httpoptions.cpp       |  39 ++++++++---
 indra/llcorehttp/httpoptions.h         |  31 +++++++++
 indra/llcorehttp/httprequest.cpp       |  17 +++--
 indra/llcorehttp/httprequest.h         |  17 ++++-
 indra/llcorehttp/httpresponse.h        |  25 +++++++
 17 files changed, 435 insertions(+), 80 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index b9632a7921..48e22468cd 100755
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -115,8 +115,9 @@ namespace LLCore
 {
 
 
-HttpOpRequest::HttpOpRequest()
+HttpOpRequest::HttpOpRequest(HttpRequest const * const request)
 	: HttpOperation(),
+	  mRequest(request),
 	  mProcFlags(0U),
 	  mReqMethod(HOR_GET),
 	  mReqBody(NULL),
@@ -139,7 +140,8 @@ HttpOpRequest::HttpOpRequest()
 	  mPolicyRetries(0),
 	  mPolicy503Retries(0),
 	  mPolicyRetryAt(HttpTime(0)),
-	  mPolicyRetryLimit(HTTP_RETRY_COUNT_DEFAULT)
+	  mPolicyRetryLimit(HTTP_RETRY_COUNT_DEFAULT),
+	  mCallbackSSLVerify(NULL)
 {
 	// *NOTE:  As members are added, retry initialization/cleanup
 	// may need to be extended in @see prepareRequest().
@@ -267,6 +269,14 @@ void HttpOpRequest::visitNotifier(HttpRequest * request)
 		response->setContentType(mReplyConType);
 		response->setRetries(mPolicyRetries, mPolicy503Retries);
 		
+		HttpResponse::TransferStats::ptr_t stats = HttpResponse::TransferStats::ptr_t(new HttpResponse::TransferStats);
+
+		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);
+
+		response->setTransferStats(stats);
+
 		mUserHandler->onCompleted(static_cast<HttpHandle>(this), response);
 
 		response->release();
@@ -452,18 +462,8 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
 	check_curl_easy_code(code, CURLOPT_ENCODING);
 
-	// 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.
-	code = curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 15);
-	check_curl_easy_code(code, CURLOPT_DNS_CACHE_TIMEOUT);
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1);
 	check_curl_easy_code(code, CURLOPT_AUTOREFERER);
-	code = curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, 1);
-	check_curl_easy_code(code, CURLOPT_FOLLOWLOCATION);
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT);
 	check_curl_easy_code(code, CURLOPT_MAXREDIRS);
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback);
@@ -474,11 +474,49 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 	check_curl_easy_code(code, CURLOPT_READFUNCTION);
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, this);
 	check_curl_easy_code(code, CURLOPT_READDATA);
-	code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, 1);
+
+	code = curl_easy_setopt(mCurlHandle, CURLOPT_COOKIEFILE, "");
+	check_curl_easy_code(code, CURLOPT_COOKIEFILE);
+
+	if (gpolicy.mSslCtxCallback)
+	{
+		code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_FUNCTION, curlSslCtxCallback);
+		check_curl_easy_code(code, CURLOPT_SSL_CTX_FUNCTION);
+		code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_DATA, this);
+		check_curl_easy_code(code, CURLOPT_SSL_CTX_DATA);
+		mCallbackSSLVerify = gpolicy.mSslCtxCallback;
+	}
+
+	long follow_redirect(1L);
+	long sslPeerV(0L);
+	long sslHostV(0L);
+	long dnsCacheTimeout(15L);
+
+	if (mReqOptions)
+	{
+		follow_redirect = mReqOptions->getFollowRedirects() ? 1L : 0L;
+		sslPeerV = mReqOptions->getSSLVerifyHost() ? 0L : 1L;
+		sslHostV = mReqOptions->getSSLVerifyHost();
+		dnsCacheTimeout = mReqOptions->getDNSCacheTimeout();
+	}
+	code = curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect);
+	check_curl_easy_code(code, CURLOPT_FOLLOWLOCATION);
+
+	code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, sslPeerV);
 	check_curl_easy_code(code, CURLOPT_SSL_VERIFYPEER);
-	code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, 0);
+	code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, sslHostV);
 	check_curl_easy_code(code, CURLOPT_SSL_VERIFYHOST);
 
+	// The Linksys WRT54G V5 router has an issue with frequent
+	// DNS lookups from LAN machines.  If they happen too often,
+	// like for every HTTP request, the router gets annoyed after
+	// about 700 or so requests and starts issuing TCP RSTs to
+	// new connections.  Reuse the DNS lookups for even a few
+	// seconds and no RSTs.
+	code = curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, dnsCacheTimeout);
+	check_curl_easy_code(code, CURLOPT_DNS_CACHE_TIMEOUT);
+
+
 	if (gpolicy.mUseLLProxy)
 	{
 		// Use the viewer-based thread-safe API which has a
@@ -873,6 +911,35 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi
 }
 
 
+CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userdata)
+{
+	HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata));
+
+	if (op->mCallbackSSLVerify)
+	{
+		SSL_CTX * ctx = (SSL_CTX *)sslctx;
+		// disable any default verification for server certs
+		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
+	}
+
+	return CURLE_OK;
+}
+
+int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
+{
+	HttpOpRequest * op(static_cast<HttpOpRequest *>(param));
+
+	if (op->mCallbackSSLVerify)
+	{
+		op->mStatus = op->mCallbackSSLVerify(op->mReqURL, op->mUserHandler, ctx);
+	}
+
+	return (op->mStatus) ? 1 : 0;
+}
+
 int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffer, size_t len, void * userdata)
 {
 	HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata));
diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h
index 2f628b5aba..7a4b7c189e 100755
--- a/indra/llcorehttp/_httpoprequest.h
+++ b/indra/llcorehttp/_httpoprequest.h
@@ -33,6 +33,9 @@
 #include <string>
 #include <curl/curl.h>
 
+#include <openssl/x509_vfy.h>
+#include <openssl/ssl.h>
+
 #include "httpcommon.h"
 #include "httprequest.h"
 #include "_httpoperation.h"
@@ -63,7 +66,7 @@ class HttpOptions;
 class HttpOpRequest : public HttpOperation
 {
 public:
-	HttpOpRequest();
+	HttpOpRequest(HttpRequest const * const request);
 
 protected:
 	virtual ~HttpOpRequest();							// Use release()
@@ -151,6 +154,9 @@ protected:
 	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 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);
 
 protected:
@@ -159,8 +165,11 @@ protected:
 	static const unsigned int	PF_SAVE_HEADERS = 0x00000002U;
 	static const unsigned int	PF_USE_RETRY_AFTER = 0x00000004U;
 
+	HttpRequest::policyCallback	mCallbackSSLVerify;
+
 public:
 	// Request data
+	HttpRequest const * const mRequest;
 	EMethod				mReqMethod;
 	std::string			mReqURL;
 	BufferArray *		mReqBody;
diff --git a/indra/llcorehttp/_httppolicyglobal.cpp b/indra/llcorehttp/_httppolicyglobal.cpp
index 1dc95f3dce..c4ef38a815 100755
--- a/indra/llcorehttp/_httppolicyglobal.cpp
+++ b/indra/llcorehttp/_httppolicyglobal.cpp
@@ -106,6 +106,20 @@ HttpStatus HttpPolicyGlobal::set(HttpRequest::EPolicyOption opt, const std::stri
 	return HttpStatus();
 }
 
+HttpStatus HttpPolicyGlobal::set(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback value)
+{
+	switch (opt)
+	{
+	case HttpRequest::PO_SSL_VERIFY_CALLBACK:
+		mSslCtxCallback = value;
+		break;
+
+	default:
+		return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+	}
+
+	return HttpStatus();
+}
 
 HttpStatus HttpPolicyGlobal::get(HttpRequest::EPolicyOption opt, long * value) const
 {
@@ -154,4 +168,20 @@ HttpStatus HttpPolicyGlobal::get(HttpRequest::EPolicyOption opt, std::string * v
 	return HttpStatus();
 }
 
+
+HttpStatus HttpPolicyGlobal::get(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback * value) const
+{
+	switch (opt)
+	{
+	case HttpRequest::PO_SSL_VERIFY_CALLBACK:
+		*value = mSslCtxCallback;
+		break;
+
+	default:
+		return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+	}
+
+	return HttpStatus();
+}
+
 }  // end namespace LLCore
diff --git a/indra/llcorehttp/_httppolicyglobal.h b/indra/llcorehttp/_httppolicyglobal.h
index 67c4ba9481..1696238814 100755
--- a/indra/llcorehttp/_httppolicyglobal.h
+++ b/indra/llcorehttp/_httppolicyglobal.h
@@ -60,8 +60,10 @@ private:
 public:
 	HttpStatus set(HttpRequest::EPolicyOption opt, long value);
 	HttpStatus set(HttpRequest::EPolicyOption opt, const std::string & value);
+	HttpStatus set(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback 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 * value) const;
 	
 public:
 	long				mConnectionLimit;
@@ -70,6 +72,7 @@ public:
 	std::string			mHttpProxy;
 	long				mTrace;
 	long				mUseLLProxy;
+	HttpRequest::policyCallback	mSslCtxCallback;
 };  // end class HttpPolicyGlobal
 
 }  // end namespace LLCore
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index c673e1be1d..7b8aac35a8 100755
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -53,15 +53,16 @@ namespace LLCore
 
 const HttpService::OptionDescriptor HttpService::sOptionDesc[] =
 { //    isLong     isDynamic  isGlobal    isClass
-	{	true,		true,		true,		true	},		// PO_CONNECTION_LIMIT
-	{	true,		true,		false,		true	},		// PO_PER_HOST_CONNECTION_LIMIT
-	{	false,		false,		true,		false	},		// PO_CA_PATH
-	{	false,		false,		true,		false	},		// PO_CA_FILE
-	{	false,		true,		true,		false	},		// PO_HTTP_PROXY
-	{	true,		true,		true,		false	},		// PO_LLPROXY
-	{	true,		true,		true,		false	},		// PO_TRACE
-	{	true,		true,		false,		true	},		// PO_ENABLE_PIPELINING
-	{	true,		true,		false,		true	}		// PO_THROTTLE_RATE
+	{	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);
@@ -413,6 +414,34 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
 	return status;
 }
 
+HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+	HttpRequest::policyCallback * ret_value)
+{
+	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)
@@ -489,6 +518,37 @@ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
 
 	return status;
 }
-	
+
+HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+	HttpRequest::policyCallback value, HttpRequest::policyCallback * ret_value)
+{
+	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
+
+	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range
+		|| opt >= HttpRequest::PO_LAST													// ditto
+		|| (sOptionDesc[opt].mIsLong)													// datatype is string
+		|| (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy)			// pclass in valid range
+		|| (pclass == HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsGlobal)	// global setting permitted
+		|| (pclass != HttpRequest::GLOBAL_POLICY_ID && !sOptionDesc[opt].mIsClass)		// class setting permitted
+		|| (RUNNING == sState && !sOptionDesc[opt].mIsDynamic))						// dynamic setting permitted
+	{
+		return status;
+	}
+
+	// Callbacks values are always global (at this time).
+	if (pclass == HttpRequest::GLOBAL_POLICY_ID)
+	{
+		HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
+
+		status = opts.set(opt, value);
+		if (status && ret_value)
+		{
+			status = opts.get(opt, ret_value);
+		}
+	}
+
+	return status;
+}
+
 
 }  // end namespace LLCore
diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h
index cf23f3ab61..699a8eaa4f 100755
--- a/indra/llcorehttp/_httpservice.h
+++ b/indra/llcorehttp/_httpservice.h
@@ -201,17 +201,24 @@ protected:
 		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 * 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 value, 
+								HttpRequest::policyCallback * ret_value);
+
 protected:
 	static const OptionDescriptor		sOptionDesc[HttpRequest::PO_LAST];
 	static HttpService *				sInstance;
diff --git a/indra/llcorehttp/_refcounted.h b/indra/llcorehttp/_refcounted.h
index 402e725152..cd16e2e2b4 100755
--- a/indra/llcorehttp/_refcounted.h
+++ b/indra/llcorehttp/_refcounted.h
@@ -120,7 +120,18 @@ inline void RefCounted::destroySelf()
 	delete this;
 }
 
+inline void intrusive_ptr_add_ref(RefCounted* p)
+{
+	p->addRef();
+}
+
+inline void intrusive_ptr_release(RefCounted* p)
+{
+	p->release();
+}
+
 } // end namespace LLCoreInt
 
+
 #endif	// LLCOREINT__REFCOUNTED_H_
 
diff --git a/indra/llcorehttp/bufferarray.h b/indra/llcorehttp/bufferarray.h
index 1094a435b4..9c2b991de6 100755
--- a/indra/llcorehttp/bufferarray.h
+++ b/indra/llcorehttp/bufferarray.h
@@ -73,6 +73,8 @@ public:
 	
 	BufferArray();
 
+	typedef boost::intrusive_ptr<BufferArray> ptr_t;
+
 protected:
 	virtual ~BufferArray();						// Use release()
 
diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp
index 7907e958a4..1aece696e3 100755
--- a/indra/llcorehttp/httpcommon.cpp
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -42,7 +42,7 @@ HttpStatus::operator unsigned long() const
 {
 	static const int shift(sizeof(unsigned long) * 4);
 
-	unsigned long result(((unsigned long) mType) << shift | (unsigned long) (int) mStatus);
+	unsigned long result(((unsigned long)mDetails->mType) << shift | (unsigned long)(int)mDetails->mStatus);
 	return result;
 }
 
@@ -131,18 +131,18 @@ std::string HttpStatus::toString() const
 	{
 		return std::string("");
 	}
-	switch (mType)
+	switch (mDetails->mType)
 	{
 	case EXT_CURL_EASY:
-		return std::string(curl_easy_strerror(CURLcode(mStatus)));
+		return std::string(curl_easy_strerror(CURLcode(mDetails->mStatus)));
 
 	case EXT_CURL_MULTI:
-		return std::string(curl_multi_strerror(CURLMcode(mStatus)));
+		return std::string(curl_multi_strerror(CURLMcode(mDetails->mStatus)));
 
 	case LLCORE:
-		if (mStatus >= 0 && mStatus < llcore_errors_count)
+		if (mDetails->mStatus >= 0 && mDetails->mStatus < llcore_errors_count)
 		{
-			return std::string(llcore_errors[mStatus]);
+			return std::string(llcore_errors[mDetails->mStatus]);
 		}
 		break;
 
@@ -154,7 +154,7 @@ std::string HttpStatus::toString() const
 			while (true)
 			{
 				int at((bottom + top) / 2);
-				if (mType == http_errors[at].mCode)
+				if (mDetails->mType == http_errors[at].mCode)
 				{
 					return std::string(http_errors[at].mText);
 				}
@@ -162,7 +162,7 @@ std::string HttpStatus::toString() const
 				{
 					break;
 				}
-				else if (mType < http_errors[at].mCode)
+				else if (mDetails->mType < http_errors[at].mCode)
 				{
 					top = at;
 				}
@@ -182,9 +182,9 @@ std::string HttpStatus::toTerseString() const
 {
 	std::ostringstream result;
 
-	unsigned int error_value((unsigned short) mStatus);
+	unsigned int error_value((unsigned short)mDetails->mStatus);
 	
-	switch (mType)
+	switch (mDetails->mType)
 	{
 	case EXT_CURL_EASY:
 		result << "Easy_";
@@ -202,7 +202,7 @@ std::string HttpStatus::toTerseString() const
 		if (isHttpStatus())
 		{
 			result << "Http_";
-			error_value = mType;
+			error_value = mDetails->mType;
 		}
 		else
 		{
@@ -244,7 +244,7 @@ bool HttpStatus::isRetryable() const
 	// Disable the '*this == inv_status' test and look for 'Core_9'
 	// failures in log files.
 
-	return ((isHttpStatus() && mType >= 499 && mType <= 599) ||	// Include special 499 in retryables
+	return ((isHttpStatus() && mDetails->mType >= 499 && mDetails->mType <= 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
diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
index 9601f94125..0244755272 100755
--- a/indra/llcorehttp/httpcommon.h
+++ b/indra/llcorehttp/httpcommon.h
@@ -191,7 +191,6 @@
 
 #include <string>
 
-
 namespace LLCore
 {
 
@@ -292,35 +291,35 @@ struct HttpStatus
 	typedef unsigned short type_enum_t;
 	
 	HttpStatus()
-		: mType(LLCORE),
-		  mStatus(HE_SUCCESS)
-		{}
+		{
+			mDetails = std::unique_ptr<Details>(new Details(LLCORE, HE_SUCCESS));
+		}
 
 	HttpStatus(type_enum_t type, short status)
-		: mType(type),
-		  mStatus(status)
-		{}
+		{
+			mDetails = std::unique_ptr<Details>(new Details(type, status));
+		}
 	
 	HttpStatus(int http_status)
-		: mType(http_status),
-		  mStatus(http_status >= 200 && http_status <= 299
-				  ? HE_SUCCESS
-				  : HE_REPLY_ERROR)
 		{
+			mDetails = std::unique_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(const HttpStatus & rhs)
-		: mType(rhs.mType),
-		  mStatus(rhs.mStatus)
-		{}
+		{
+			mDetails = std::unique_ptr<Details>(new Details(*rhs.mDetails));
+		}
 
 	HttpStatus & operator=(const HttpStatus & rhs)
 		{
 			// Don't care if lhs & rhs are the same object
+			mDetails->mType = rhs.mDetails->mType;
+			mDetails->mStatus = rhs.mDetails->mStatus;
+			mDetails->mMessage = rhs.mDetails->mMessage;
+			mDetails->mErrorData = rhs.mDetails->mErrorData;
 
-			mType = rhs.mType;
-			mStatus = rhs.mStatus;
 			return *this;
 		}
 	
@@ -328,10 +327,6 @@ struct HttpStatus
 	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
-	
-	type_enum_t			mType;
-	short				mStatus;
-
 	/// Test for successful status in the code regardless
 	/// of error source (internal, libcurl).
 	///
@@ -339,7 +334,7 @@ struct HttpStatus
 	///
 	operator bool() const
 	{
-		return 0 == mStatus;
+		return 0 == mDetails->mStatus;
 	}
 
 	/// Inverse of previous operator.
@@ -347,14 +342,15 @@ struct HttpStatus
 	/// @return			'true' on any error condition
 	bool operator !() const
 	{
-		return 0 != mStatus;
+		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 mType == rhs.mType && mStatus == rhs.mStatus;
+		return (mDetails->mType == rhs.mDetails->mType) && 
+			(mDetails->mStatus == rhs.mDetails->mStatus);
 	}
 
 	bool operator!=(const HttpStatus & rhs) const
@@ -395,7 +391,7 @@ struct HttpStatus
 	/// HTTP response status (100 - 999).
 	bool isHttpStatus() const
 	{
-		return 	mType >= type_enum_t(100) && mType <= type_enum_t(999);
+		return 	mDetails->mType >= type_enum_t(100) && mDetails->mType <= type_enum_t(999);
 	}
 
 	/// Returns true if the status is one that will be retried
@@ -403,7 +399,77 @@ struct HttpStatus
 	/// 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;
+	}
+
+	// TODO: There must be a better way to do this.  Don't want to set these 
+	// values here since they increase the size of a structure that is already 
+	// being passed on the stack.  Consider my options
+	/// 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 an optionally recorded SSL certificate.
+	void * getErrorData() const
+	{
+		return mDetails->mErrorData;
+	}
+
+	/// Optionally sets an SSL certificate on this status.
+	void setErrorData(void *data)
+	{
+		mDetails->mErrorData = data;
+	}
+
+private:
+
+	struct Details
+	{
+		Details(type_enum_t type, short status):
+			mType(type),
+			mStatus(status),
+			mMessage(),
+			mErrorData(NULL)
+		{}
+
+		Details(const Details &rhs) :
+			mType(rhs.mType),
+			mStatus(rhs.mStatus),
+			mMessage(rhs.mMessage),
+			mErrorData(rhs.mErrorData)
+		{}
+
+
+		type_enum_t	mType;
+		short		mStatus;
+		std::string	mMessage;
+		void *		mErrorData;
+	};
+
+	std::unique_ptr<Details>	mDetails;
+
 }; // end struct HttpStatus
 
 }  // end namespace LLCore
diff --git a/indra/llcorehttp/httphandler.h b/indra/llcorehttp/httphandler.h
index 9171e4e7b9..740e986dec 100755
--- a/indra/llcorehttp/httphandler.h
+++ b/indra/llcorehttp/httphandler.h
@@ -45,7 +45,7 @@ class HttpResponse;
 /// be shared by any number of requests and across instances
 /// of HttpRequest running in the same thread.
 ///
-/// Threading:  HttpHandler itself is pure interface and is
+/// Threading:  HttpHandler itself is interface and is
 /// tread-compatible.  Most derivations, however, will have
 /// different constraints.
 ///
@@ -58,7 +58,7 @@ class HttpHandler
 {
 public:
 	virtual ~HttpHandler()
-		{}
+	{ }
 
 	/// Method invoked during calls to @see update().  Each invocation
 	/// represents the completion of some requested operation.  Caller
diff --git a/indra/llcorehttp/httpheaders.h b/indra/llcorehttp/httpheaders.h
index f70cd898f3..c89d6af222 100755
--- a/indra/llcorehttp/httpheaders.h
+++ b/indra/llcorehttp/httpheaders.h
@@ -92,6 +92,7 @@ public:
 	/// the instance.
 	HttpHeaders();
 
+	typedef boost::intrusive_ptr<HttpHeaders> ptr_t;
 protected:
 	virtual ~HttpHeaders();						// Use release()
 
diff --git a/indra/llcorehttp/httpoptions.cpp b/indra/llcorehttp/httpoptions.cpp
index 5bf1ecb4a5..28c2c25e92 100755
--- a/indra/llcorehttp/httpoptions.cpp
+++ b/indra/llcorehttp/httpoptions.cpp
@@ -25,7 +25,7 @@
  */
 
 #include "httpoptions.h"
-
+#include "lldefs.h"
 #include "_httpinternal.h"
 
 
@@ -33,14 +33,17 @@ namespace LLCore
 {
 
 
-HttpOptions::HttpOptions()
-	: RefCounted(true),
-	  mWantHeaders(false),
-	  mTracing(HTTP_TRACE_OFF),
-	  mTimeout(HTTP_REQUEST_TIMEOUT_DEFAULT),
-	  mTransferTimeout(HTTP_REQUEST_XFER_TIMEOUT_DEFAULT),
-	  mRetries(HTTP_RETRY_COUNT_DEFAULT),
-	  mUseRetryAfter(HTTP_USE_RETRY_AFTER_DEFAULT)
+HttpOptions::HttpOptions() : RefCounted(true),
+	mWantHeaders(false),
+	mTracing(HTTP_TRACE_OFF),
+	mTimeout(HTTP_REQUEST_TIMEOUT_DEFAULT),
+	mTransferTimeout(HTTP_REQUEST_XFER_TIMEOUT_DEFAULT),
+	mRetries(HTTP_RETRY_COUNT_DEFAULT),
+	mUseRetryAfter(HTTP_USE_RETRY_AFTER_DEFAULT),
+	mFollowRedirects(false),
+	mVerifyPeer(false),
+	mVerifyHost(0),
+	mDNSCacheTimeout(15)
 {}
 
 
@@ -82,5 +85,23 @@ void HttpOptions::setUseRetryAfter(bool use_retry)
 	mUseRetryAfter = use_retry;
 }
 
+void HttpOptions::setFollowRedirects(bool follow_redirect)
+{
+	mFollowRedirects = follow_redirect;
+}
+
+void HttpOptions::setSSLVerifyPeer(bool verify)
+{
+	mVerifyPeer = verify;
+}
 
+void HttpOptions::setSSLVerifyHost(unsigned int type)
+{
+	mVerifyHost = llclamp<unsigned int>(type, 0, 2);
+}
+
+void HttpOptions::setDNSCacheTimeout(int timeout)
+{
+	mDNSCacheTimeout = timeout;
+}
 }   // end namespace LLCore
diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h
index 4ab5ff18c4..d6d892213d 100755
--- a/indra/llcorehttp/httpoptions.h
+++ b/indra/llcorehttp/httpoptions.h
@@ -61,6 +61,8 @@ class HttpOptions : public LLCoreInt::RefCounted
 public:
 	HttpOptions();
 
+	typedef boost::intrusive_ptr<HttpOptions> ptr_t;
+
 protected:
 	virtual ~HttpOptions();						// Use release()
 	
@@ -109,6 +111,31 @@ public:
 		{
 			return mUseRetryAfter;
 		}
+
+	// Default: false
+	void				setFollowRedirects(bool follow_redirect);
+	bool				getFollowRedirects() const
+		{
+			return mFollowRedirects;
+		}
+
+	void				setSSLVerifyPeer(bool verify);
+	bool				getSSLVerifyPeer() const
+		{
+			return mVerifyPeer;
+		}
+
+	void				setSSLVerifyHost(unsigned int type);
+	unsigned int		getSSLVerifyHost() const
+		{
+			return mVerifyHost;
+		}
+
+	void				setDNSCacheTimeout(int timeout);
+	int					getDNSCacheTimeout() const
+		{
+			return mDNSCacheTimeout;
+		}
 	
 protected:
 	bool				mWantHeaders;
@@ -117,6 +144,10 @@ protected:
 	unsigned int		mTransferTimeout;
 	unsigned int		mRetries;
 	bool				mUseRetryAfter;
+	bool				mFollowRedirects;
+	bool				mVerifyPeer;
+	unsigned int		mVerifyHost;
+	int					mDNSCacheTimeout;
 }; // end class HttpOptions
 
 
diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp
index 7b1888e3eb..5f1ed3d43b 100755
--- a/indra/llcorehttp/httprequest.cpp
+++ b/indra/llcorehttp/httprequest.cpp
@@ -117,6 +117,15 @@ HttpStatus HttpRequest::setStaticPolicyOption(EPolicyOption opt, policy_t pclass
 	return HttpService::instanceOf()->setPolicyOption(opt, pclass, value, ret_value);
 }
 
+HttpStatus HttpRequest::setStaticPolicyOption(EPolicyOption opt, policy_t pclass, policyCallback value, policyCallback * 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);
+}
 
 HttpHandle HttpRequest::setPolicyOption(EPolicyOption opt, policy_t pclass,
 										long value, HttpHandler * handler)
@@ -195,7 +204,7 @@ HttpHandle HttpRequest::requestGet(policy_t policy_id,
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
 
-	HttpOpRequest * op = new HttpOpRequest();
+	HttpOpRequest * op = new HttpOpRequest(this);
 	if (! (status = op->setupGet(policy_id, priority, url, options, headers)))
 	{
 		op->release();
@@ -229,7 +238,7 @@ HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id,
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
 
-	HttpOpRequest * op = new HttpOpRequest();
+	HttpOpRequest * op = new HttpOpRequest(this);
 	if (! (status = op->setupGetByteRange(policy_id, priority, url, offset, len, options, headers)))
 	{
 		op->release();
@@ -262,7 +271,7 @@ HttpHandle HttpRequest::requestPost(policy_t policy_id,
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
 
-	HttpOpRequest * op = new HttpOpRequest();
+	HttpOpRequest * op = new HttpOpRequest(this);
 	if (! (status = op->setupPost(policy_id, priority, url, body, options, headers)))
 	{
 		op->release();
@@ -295,7 +304,7 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id,
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
 
-	HttpOpRequest * op = new HttpOpRequest();
+	HttpOpRequest * op = new HttpOpRequest(this);
 	if (! (status = op->setupPut(policy_id, priority, url, body, options, headers)))
 	{
 		op->release();
diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h
index 7f23723b0b..c90e056d62 100755
--- a/indra/llcorehttp/httprequest.h
+++ b/indra/llcorehttp/httprequest.h
@@ -97,6 +97,7 @@ public:
 	typedef unsigned int policy_t;
 	typedef unsigned int priority_t;
 	
+	typedef std::shared_ptr<HttpRequest> ptr_t;
 public:
 	/// @name PolicyMethods
 	/// @{
@@ -163,7 +164,7 @@ public:
 
 		/// 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.
+		/// enabled, has priority over GP_HTTP_PROXY.
 		///
 		/// Global only
 		PO_LLPROXY,
@@ -219,15 +220,25 @@ public:
 		/// 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 targetted.
+		/// (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 HttpStatus(*policyCallback)(const std::string &, HttpHandler const * const, void *);
+
 	/// Set a policy option for a global or class parameter at
 	/// startup time (prior to thread start).
 	///
@@ -243,6 +254,8 @@ public:
 											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 value, policyCallback * ret_value);;
 
 	/// Set a parameter on a class-based policy option.  Calls
 	/// made after the start of the servicing thread are
diff --git a/indra/llcorehttp/httpresponse.h b/indra/llcorehttp/httpresponse.h
index aee64e2878..01e9dd2bc6 100755
--- a/indra/llcorehttp/httpresponse.h
+++ b/indra/llcorehttp/httpresponse.h
@@ -69,6 +69,18 @@ protected:
 	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
@@ -168,6 +180,17 @@ public:
 			m503Retries = retries_503;
 		}
 
+	void setTransferStats(TransferStats::ptr_t &stats) 
+		{
+			mStats = stats;
+		}
+
+	TransferStats::ptr_t getTransferStats()
+		{
+			return mStats;
+		}
+
+
 protected:
 	// Response data here
 	HttpStatus			mStatus;
@@ -179,6 +202,8 @@ protected:
 	std::string			mContentType;
 	unsigned int		mRetries;
 	unsigned int		m503Retries;
+
+	TransferStats::ptr_t	mStats;
 };
 
 
-- 
cgit v1.2.3


From 6b8c814df3141fa705b9921ba0a73aeaa3fe63b6 Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Thu, 19 Mar 2015 17:01:21 -0700
Subject: Adding new HTTP handling for material manager.

---
 indra/llcorehttp/bufferarray.h    | 1 +
 indra/llcorehttp/httpheaders.cpp  | 2 +-
 indra/llcorehttp/httpheaders.h    | 8 ++++++--
 indra/llcorehttp/httpresponse.cpp | 4 ++++
 indra/llcorehttp/httpresponse.h   | 4 ++++
 5 files changed, 16 insertions(+), 3 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/bufferarray.h b/indra/llcorehttp/bufferarray.h
index 9c2b991de6..1da807b0a6 100755
--- a/indra/llcorehttp/bufferarray.h
+++ b/indra/llcorehttp/bufferarray.h
@@ -131,6 +131,7 @@ protected:
 
 	container_t			mBlocks;
 	size_t				mLen;
+
 };  // end class BufferArray
 
 
diff --git a/indra/llcorehttp/httpheaders.cpp b/indra/llcorehttp/httpheaders.cpp
index 23ebea361c..73c92c8f10 100755
--- a/indra/llcorehttp/httpheaders.cpp
+++ b/indra/llcorehttp/httpheaders.cpp
@@ -105,7 +105,7 @@ void HttpHeaders::appendNormal(const char * header, size_t size)
 
 // Find from end to simulate a tradition of using single-valued
 // std::map for this in the past.
-const std::string * HttpHeaders::find(const char * name) const
+const std::string * HttpHeaders::find(const std::string &name) const
 {
 	const_reverse_iterator iend(rend());
 	for (const_reverse_iterator iter(rbegin()); iend != iter; ++iter)
diff --git a/indra/llcorehttp/httpheaders.h b/indra/llcorehttp/httpheaders.h
index c89d6af222..41832c4931 100755
--- a/indra/llcorehttp/httpheaders.h
+++ b/indra/llcorehttp/httpheaders.h
@@ -146,8 +146,12 @@ public:
 	//					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 char * name) const;
+	
+	const std::string * find(const std::string &name) const;
+	const std::string * find(const char * name) const
+	{
+		return find(std::string(name));
+	}
 
 	// Count of headers currently in the list.
 	size_type size() const
diff --git a/indra/llcorehttp/httpresponse.cpp b/indra/llcorehttp/httpresponse.cpp
index c974395b0a..87e3426415 100755
--- a/indra/llcorehttp/httpresponse.cpp
+++ b/indra/llcorehttp/httpresponse.cpp
@@ -89,5 +89,9 @@ void HttpResponse::setHeaders(HttpHeaders * headers)
 	mHeaders = headers;
 }
 
+size_t HttpResponse::getBodySize() const
+{
+	return (mBufferArray) ? mBufferArray->size() : 0;
+}
 
 }   // end namespace LLCore
diff --git a/indra/llcorehttp/httpresponse.h b/indra/llcorehttp/httpresponse.h
index 01e9dd2bc6..c6b470ee3f 100755
--- a/indra/llcorehttp/httpresponse.h
+++ b/indra/llcorehttp/httpresponse.h
@@ -104,6 +104,10 @@ public:
 			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.
-- 
cgit v1.2.3


From 9d676ce5b97d7ce09630d7d6ab8abd562b958cae Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Fri, 20 Mar 2015 13:16:25 -0700
Subject: Clean up and use policies for Material transfer.

---
 indra/llcorehttp/_httpinternal.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/_httpinternal.h b/indra/llcorehttp/_httpinternal.h
index a2a60ca056..79c89d6c92 100755
--- a/indra/llcorehttp/_httpinternal.h
+++ b/indra/llcorehttp/_httpinternal.h
@@ -104,8 +104,9 @@ namespace LLCore
 {
 
 // Maxium number of policy classes that can be defined.
-// *TODO:  Currently limited to the default class + 1, extend.
-const int HTTP_POLICY_CLASS_LIMIT = 8;
+// *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;
 
 // Debug/informational tracing.  Used both
 // as a global option and in per-request traces.
-- 
cgit v1.2.3


From 3b923962f8e0a065052f40d029bce42a6fe37e68 Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Mon, 23 Mar 2015 12:23:35 -0700
Subject: Reogranized some headers for GCC added <memory> to the
 linden_common.h for shared_ptr

---
 indra/llcorehttp/bufferarray.h | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/bufferarray.h b/indra/llcorehttp/bufferarray.h
index 1da807b0a6..076f341736 100755
--- a/indra/llcorehttp/bufferarray.h
+++ b/indra/llcorehttp/bufferarray.h
@@ -30,6 +30,7 @@
 
 #include <cstdlib>
 #include <vector>
+#include "boost/intrusive_ptr.hpp"
 
 #include "_refcounted.h"
 
-- 
cgit v1.2.3


From 530bf560b2c2c9bf534bb3ba4f588c72a59be703 Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Mon, 23 Mar 2015 13:28:24 -0700
Subject: Continue with gcc issues.

---
 indra/llcorehttp/httpcommon.cpp | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp
index 1aece696e3..c201400423 100755
--- a/indra/llcorehttp/httpcommon.cpp
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -131,18 +131,18 @@ std::string HttpStatus::toString() const
 	{
 		return std::string("");
 	}
-	switch (mDetails->mType)
+	switch (this->mDetails->mType)
 	{
 	case EXT_CURL_EASY:
-		return std::string(curl_easy_strerror(CURLcode(mDetails->mStatus)));
+		return std::string(curl_easy_strerror(CURLcode(this->mDetails->mStatus)));
 
 	case EXT_CURL_MULTI:
-		return std::string(curl_multi_strerror(CURLMcode(mDetails->mStatus)));
+		return std::string(curl_multi_strerror(CURLMcode(this->mDetails->mStatus)));
 
 	case LLCORE:
-		if (mDetails->mStatus >= 0 && mDetails->mStatus < llcore_errors_count)
+		if (this->mDetails->mStatus >= 0 && this->mDetails->mStatus < llcore_errors_count)
 		{
-			return std::string(llcore_errors[mDetails->mStatus]);
+			return std::string(llcore_errors[this->mDetails->mStatus]);
 		}
 		break;
 
@@ -154,7 +154,7 @@ std::string HttpStatus::toString() const
 			while (true)
 			{
 				int at((bottom + top) / 2);
-				if (mDetails->mType == http_errors[at].mCode)
+				if (this->mDetails->mType == http_errors[at].mCode)
 				{
 					return std::string(http_errors[at].mText);
 				}
@@ -162,7 +162,7 @@ std::string HttpStatus::toString() const
 				{
 					break;
 				}
-				else if (mDetails->mType < http_errors[at].mCode)
+				else if (this->mDetails->mType < http_errors[at].mCode)
 				{
 					top = at;
 				}
@@ -182,9 +182,9 @@ std::string HttpStatus::toTerseString() const
 {
 	std::ostringstream result;
 
-	unsigned int error_value((unsigned short)mDetails->mStatus);
+	unsigned int error_value((unsigned short)(this->mDetails->mStatus));
 	
-	switch (mDetails->mType)
+	switch (this->mDetails->mType)
 	{
 	case EXT_CURL_EASY:
 		result << "Easy_";
@@ -202,7 +202,7 @@ std::string HttpStatus::toTerseString() const
 		if (isHttpStatus())
 		{
 			result << "Http_";
-			error_value = mDetails->mType;
+			error_value = this->mDetails->mType;
 		}
 		else
 		{
@@ -244,7 +244,7 @@ bool HttpStatus::isRetryable() const
 	// Disable the '*this == inv_status' test and look for 'Core_9'
 	// failures in log files.
 
-	return ((isHttpStatus() && mDetails->mType >= 499 && mDetails->mType <= 599) ||	// Include special 499 in retryables
+	return ((isHttpStatus() && this->mDetails->mType >= 499 && this->mDetails->mType <= 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
-- 
cgit v1.2.3


From e7a1e6198b9bf1b42d60bff9559494887e22d5e7 Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Mon, 23 Mar 2015 13:39:33 -0700
Subject: Slightly cleaner than this-> ing everythnig.

---
 indra/llcorehttp/httpcommon.cpp | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp
index c201400423..d923dfa5d6 100755
--- a/indra/llcorehttp/httpcommon.cpp
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -131,18 +131,18 @@ std::string HttpStatus::toString() const
 	{
 		return std::string("");
 	}
-	switch (this->mDetails->mType)
+	switch (getType())
 	{
 	case EXT_CURL_EASY:
-		return std::string(curl_easy_strerror(CURLcode(this->mDetails->mStatus)));
+		return std::string(curl_easy_strerror(CURLcode(getStatus())));
 
 	case EXT_CURL_MULTI:
-		return std::string(curl_multi_strerror(CURLMcode(this->mDetails->mStatus)));
+		return std::string(curl_multi_strerror(CURLMcode(getStatus())));
 
 	case LLCORE:
-		if (this->mDetails->mStatus >= 0 && this->mDetails->mStatus < llcore_errors_count)
+		if (getStatus() >= 0 && getStatus() < llcore_errors_count)
 		{
-			return std::string(llcore_errors[this->mDetails->mStatus]);
+			return std::string(llcore_errors[getStatus()]);
 		}
 		break;
 
@@ -154,7 +154,7 @@ std::string HttpStatus::toString() const
 			while (true)
 			{
 				int at((bottom + top) / 2);
-				if (this->mDetails->mType == http_errors[at].mCode)
+				if (getType() == http_errors[at].mCode)
 				{
 					return std::string(http_errors[at].mText);
 				}
@@ -162,7 +162,7 @@ std::string HttpStatus::toString() const
 				{
 					break;
 				}
-				else if (this->mDetails->mType < http_errors[at].mCode)
+				else if (getType() < http_errors[at].mCode)
 				{
 					top = at;
 				}
@@ -182,9 +182,9 @@ std::string HttpStatus::toTerseString() const
 {
 	std::ostringstream result;
 
-	unsigned int error_value((unsigned short)(this->mDetails->mStatus));
+	unsigned int error_value((unsigned short)getStatus());
 	
-	switch (this->mDetails->mType)
+	switch (getType())
 	{
 	case EXT_CURL_EASY:
 		result << "Easy_";
@@ -202,7 +202,7 @@ std::string HttpStatus::toTerseString() const
 		if (isHttpStatus())
 		{
 			result << "Http_";
-			error_value = this->mDetails->mType;
+			error_value = getType();
 		}
 		else
 		{
@@ -244,7 +244,7 @@ bool HttpStatus::isRetryable() const
 	// Disable the '*this == inv_status' test and look for 'Core_9'
 	// failures in log files.
 
-	return ((isHttpStatus() && this->mDetails->mType >= 499 && this->mDetails->mType <= 599) ||	// Include special 499 in retryables
+	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
-- 
cgit v1.2.3


From 379c49fc898961b52f98855c926e958df14e98c3 Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Mon, 23 Mar 2015 13:50:07 -0700
Subject: Scratch the unique_ptr for the moment.

---
 indra/llcorehttp/httpcommon.h | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
index 0244755272..2aded492ea 100755
--- a/indra/llcorehttp/httpcommon.h
+++ b/indra/llcorehttp/httpcommon.h
@@ -188,7 +188,6 @@
 ///
 
 #include "linden_common.h"		// Modifies curl/curl.h interfaces
-
 #include <string>
 
 namespace LLCore
@@ -292,24 +291,29 @@ struct HttpStatus
 	
 	HttpStatus()
 		{
-			mDetails = std::unique_ptr<Details>(new Details(LLCORE, HE_SUCCESS));
-		}
+			mDetails = new Details(LLCORE, HE_SUCCESS);
+	}
 
 	HttpStatus(type_enum_t type, short status)
 		{
-			mDetails = std::unique_ptr<Details>(new Details(type, status));
+			mDetails = new Details(type, status);
 		}
 	
 	HttpStatus(int http_status)
 		{
-			mDetails = std::unique_ptr<Details>(new Details(http_status, 
-				(http_status >= 200 && http_status <= 299) ? HE_SUCCESS : HE_REPLY_ERROR));
+			mDetails = new Details(http_status, 
+				(http_status >= 200 && http_status <= 299) ? HE_SUCCESS : HE_REPLY_ERROR);
 			llassert(http_status >= 100 && http_status <= 999);
 		}
 	
 	HttpStatus(const HttpStatus & rhs)
 		{
-			mDetails = std::unique_ptr<Details>(new Details(*rhs.mDetails));
+			mDetails = new Details(*rhs.mDetails);
+		}
+
+	~HttpStatus()
+		{
+			delete mDetails;
 		}
 
 	HttpStatus & operator=(const HttpStatus & rhs)
@@ -468,7 +472,8 @@ private:
 		void *		mErrorData;
 	};
 
-	std::unique_ptr<Details>	mDetails;
+	//boost::unique_ptr<Details>	mDetails;
+	Details * mDetails;
 
 }; // end struct HttpStatus
 
-- 
cgit v1.2.3


From 90ae8b84c6bf515486ec94038abc598520e2320f Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Mon, 23 Mar 2015 14:22:07 -0700
Subject: Fix headers for gcc build

---
 indra/llcorehttp/httpcommon.h  | 1 +
 indra/llcorehttp/httpheaders.h | 2 +-
 indra/llcorehttp/httpoptions.h | 1 -
 3 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
index 2aded492ea..e806201798 100755
--- a/indra/llcorehttp/httpcommon.h
+++ b/indra/llcorehttp/httpcommon.h
@@ -188,6 +188,7 @@
 ///
 
 #include "linden_common.h"		// Modifies curl/curl.h interfaces
+#include "boost/intrusive_ptr.hpp"
 #include <string>
 
 namespace LLCore
diff --git a/indra/llcorehttp/httpheaders.h b/indra/llcorehttp/httpheaders.h
index 41832c4931..940f92183c 100755
--- a/indra/llcorehttp/httpheaders.h
+++ b/indra/llcorehttp/httpheaders.h
@@ -28,8 +28,8 @@
 #define	_LLCORE_HTTP_HEADERS_H_
 
 
+#include "httpcommon.h"
 #include <string>
-
 #include "_refcounted.h"
 
 
diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h
index d6d892213d..3b9ad9598b 100755
--- a/indra/llcorehttp/httpoptions.h
+++ b/indra/llcorehttp/httpoptions.h
@@ -29,7 +29,6 @@
 
 
 #include "httpcommon.h"
-
 #include "_refcounted.h"
 
 
-- 
cgit v1.2.3


From d46fe1a1bb0c375ebcfe3c1fe9701e37135acd65 Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Mon, 23 Mar 2015 14:48:34 -0700
Subject: Microsoft is not nearly picky enough. Headder issues caught by gcc MS
 likes fine.

---
 indra/llcorehttp/httpcommon.h   | 1 +
 indra/llcorehttp/httprequest.h  | 2 +-
 indra/llcorehttp/httpresponse.h | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
index e806201798..e673d7b589 100755
--- a/indra/llcorehttp/httpcommon.h
+++ b/indra/llcorehttp/httpcommon.h
@@ -189,6 +189,7 @@
 
 #include "linden_common.h"		// Modifies curl/curl.h interfaces
 #include "boost/intrusive_ptr.hpp"
+#include "boost/shared_ptr.hpp"
 #include <string>
 
 namespace LLCore
diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h
index c90e056d62..4cacb3a20b 100755
--- a/indra/llcorehttp/httprequest.h
+++ b/indra/llcorehttp/httprequest.h
@@ -97,7 +97,7 @@ public:
 	typedef unsigned int policy_t;
 	typedef unsigned int priority_t;
 	
-	typedef std::shared_ptr<HttpRequest> ptr_t;
+	typedef boost::shared_ptr<HttpRequest> ptr_t;
 public:
 	/// @name PolicyMethods
 	/// @{
diff --git a/indra/llcorehttp/httpresponse.h b/indra/llcorehttp/httpresponse.h
index c6b470ee3f..39b582ff85 100755
--- a/indra/llcorehttp/httpresponse.h
+++ b/indra/llcorehttp/httpresponse.h
@@ -72,7 +72,7 @@ public:
 	/// Statistics for the HTTP 
 	struct TransferStats
 	{
-		typedef std::shared_ptr<TransferStats> ptr_t;
+		typedef boost::shared_ptr<TransferStats> ptr_t;
 
 		TransferStats() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {}
 		F64 mSizeDownload;
-- 
cgit v1.2.3


From d9e886809685cc207a52d0429d1badf6d537e5d7 Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Mon, 23 Mar 2015 15:41:40 -0700
Subject: Fix the tests to not directly access HttpsStatus' internals.

---
 indra/llcorehttp/tests/test_httpstatus.hpp | 90 +++++++++++-------------------
 1 file changed, 33 insertions(+), 57 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/tests/test_httpstatus.hpp b/indra/llcorehttp/tests/test_httpstatus.hpp
index 0b379836c9..5f8ed14c51 100755
--- a/indra/llcorehttp/tests/test_httpstatus.hpp
+++ b/indra/llcorehttp/tests/test_httpstatus.hpp
@@ -55,32 +55,28 @@ void HttpStatusTestObjectType::test<1>()
 	
 	// auto allocation fine for this
 	HttpStatus status;
-	status.mType = HttpStatus::EXT_CURL_EASY;
-	status.mStatus = 0;
+
+	status = HttpStatus(HttpStatus::EXT_CURL_EASY, 0);
 	
 	ensure(bool(status));
 	ensure(false == !(status));
 
-	status.mType = HttpStatus::EXT_CURL_MULTI;
-	status.mStatus = 0;
+	status = HttpStatus(HttpStatus::EXT_CURL_MULTI, 0);
 
 	ensure(bool(status));
 	ensure(false == !(status));
-	
-	status.mType = HttpStatus::LLCORE;
-	status.mStatus = HE_SUCCESS;
+
+	status = HttpStatus(HttpStatus::LLCORE, HE_SUCCESS);
 	
 	ensure(bool(status));
 	ensure(false == !(status));
 
-	status.mType = HttpStatus::EXT_CURL_MULTI;
-	status.mStatus = -1;
+	status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -1);
 
 	ensure(false == bool(status));
 	ensure(!(status));
 
-	status.mType = HttpStatus::EXT_CURL_EASY;
-	status.mStatus = CURLE_BAD_DOWNLOAD_RESUME;
+	status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_DOWNLOAD_RESUME);
 
 	ensure(false == bool(status));
 	ensure(!(status));
@@ -105,27 +101,22 @@ void HttpStatusTestObjectType::test<3>()
 {
 	set_test_name("HttpStatus valid status string conversion");
 	
-	HttpStatus status;
-	status.mType = HttpStatus::EXT_CURL_EASY;
-	status.mStatus = 0;
+	HttpStatus status = HttpStatus(HttpStatus::EXT_CURL_EASY, 0);
 	std::string msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(msg.empty());
-	
-	status.mType = HttpStatus::EXT_CURL_EASY;
-	status.mStatus = CURLE_BAD_FUNCTION_ARGUMENT;
+
+	status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_FUNCTION_ARGUMENT);
 	msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(! msg.empty());
 
-	status.mType = HttpStatus::EXT_CURL_MULTI;
-	status.mStatus = CURLM_OUT_OF_MEMORY;
+	status = HttpStatus(HttpStatus::EXT_CURL_MULTI, CURLM_OUT_OF_MEMORY);
 	msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(! msg.empty());
 
-	status.mType = HttpStatus::LLCORE;
-	status.mStatus = HE_SHUTTING_DOWN;
+	status = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN);
 	msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(! msg.empty());
@@ -137,21 +128,17 @@ void HttpStatusTestObjectType::test<4>()
 {
 	set_test_name("HttpStatus invalid status string conversion");
 	
-	HttpStatus status;
-	status.mType = HttpStatus::EXT_CURL_EASY;
-	status.mStatus = 32726;
+	HttpStatus status = HttpStatus(HttpStatus::EXT_CURL_EASY, 32726);
 	std::string msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(! msg.empty());
-	
-	status.mType = HttpStatus::EXT_CURL_MULTI;
-	status.mStatus = -470;
+
+	status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -470);
 	msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(! msg.empty());
 
-	status.mType = HttpStatus::LLCORE;
-	status.mStatus = 923;
+	status = HttpStatus(HttpStatus::LLCORE, 923);
 	msg = status.toString();
 	// std::cout << "Result:  " << msg << std::endl;
 	ensure(! msg.empty());
@@ -170,10 +157,9 @@ void HttpStatusTestObjectType::test<5>()
 	HttpStatus status2(HttpStatus::EXT_CURL_EASY, HE_SUCCESS);
 	ensure(status1 != status2);
 
-	status1.mType = HttpStatus::LLCORE;
-	status1.mStatus = HE_REPLY_ERROR;
-	status2.mType = HttpStatus::LLCORE;
-	status2.mStatus= HE_SHUTTING_DOWN;
+	status1 = HttpStatus(HttpStatus::LLCORE, HE_REPLY_ERROR);
+	status1 = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN);
+
 	ensure(status1 != status2);
 }
 
@@ -183,44 +169,38 @@ void HttpStatusTestObjectType::test<6>()
 	set_test_name("HttpStatus basic HTTP status encoding");
 	
 	HttpStatus status;
-	status.mType = 200;
-	status.mStatus = HE_SUCCESS;
+
+	status = HttpStatus(200, HE_SUCCESS);
 	std::string msg = status.toString();
 	ensure(msg.empty());
 	ensure(bool(status));
 
 	// Normally a success but application says error
-	status.mStatus = HE_REPLY_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.mType = 200;
-	status.mStatus = HE_SUCCESS;
+	status = HttpStatus(200, HE_SUCCESS);
 	HttpStatus status2(200, HE_REPLY_ERROR);
 	ensure(status != status2);
 
 	// Normally an error but application says okay
-	status.mType = 406;
-	status.mStatus = HE_SUCCESS;
+	status = HttpStatus(406, HE_SUCCESS);
 	msg = status.toString();
 	ensure(msg.empty());
 	ensure(bool(status));
 
 	// Different statuses but both successful are distinct
-	status.mType = 200;
-	status.mStatus = HE_SUCCESS;
-	status2.mType = 201;
-	status2.mStatus = HE_SUCCESS;
+	status = HttpStatus(200, HE_SUCCESS);
+	status2 = HttpStatus(201, HE_SUCCESS);
 	ensure(status != status2);
 
 	// Different statuses but both failed are distinct
-	status.mType = 200;
-	status.mStatus = HE_REPLY_ERROR;
-	status2.mType = 201;
-	status2.mStatus = HE_REPLY_ERROR;
+	status = HttpStatus(200, HE_REPLY_ERROR);
+	status2 = HttpStatus(201, HE_REPLY_ERROR);
 	ensure(status != status2);
 }
 
@@ -234,27 +214,23 @@ void HttpStatusTestObjectType::test<7>()
 	ensure(! msg.empty());				// Should be something
 	ensure(msg == "Continue");
 
-	status.mStatus = HE_SUCCESS;
+	status = HttpStatus(200, HE_SUCCESS);
 	msg = status.toString();
 	ensure(msg.empty());				// Success is empty
 
-	status.mType = 199;
-	status.mStatus = HE_REPLY_ERROR;
+	status = HttpStatus(199, HE_REPLY_ERROR);
 	msg = status.toString();
 	ensure(msg == "Unknown error");
 
-	status.mType = 505;					// Last defined string
-	status.mStatus = HE_REPLY_ERROR;
+	status = HttpStatus(505, HE_REPLY_ERROR);
 	msg = status.toString();
 	ensure(msg == "HTTP Version not supported");
 
-	status.mType = 506;					// One beyond
-	status.mStatus = HE_REPLY_ERROR;
+	status = HttpStatus(506, HE_REPLY_ERROR);
 	msg = status.toString();
 	ensure(msg == "Unknown error");
 
-	status.mType = 999;					// Last HTTP status
-	status.mStatus = HE_REPLY_ERROR;
+	status = HttpStatus(999, HE_REPLY_ERROR);
 	msg = status.toString();
 	ensure(msg == "Unknown error");
 }
-- 
cgit v1.2.3


From e140118fc41b79e403b299cabe1653af1971e87a Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Wed, 25 Mar 2015 11:31:11 -0700
Subject: Replace appearance responder with new LLCore Appearance Handler. Prep
 for some slight cleanup of the code. Add AP_AVATAR Policy

---
 indra/llcorehttp/httpcommon.cpp |  4 ++++
 indra/llcorehttp/httpcommon.h   | 13 ++++++++++---
 2 files changed, 14 insertions(+), 3 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp
index d923dfa5d6..99238ea920 100755
--- a/indra/llcorehttp/httpcommon.cpp
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -149,6 +149,10 @@ std::string HttpStatus::toString() const
 	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)
diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
index e673d7b589..64075f5f20 100755
--- a/indra/llcorehttp/httpcommon.h
+++ b/indra/llcorehttp/httpcommon.h
@@ -286,6 +286,8 @@ enum HttpError
 /// 5.  Construct an HTTP 301 status code to be treated as success:
 ///				HttpStatus(301, HE_SUCCESS);
 ///
+/// 6.	Construct a failed status of HTTP Status 499 with a custom error message
+///				HttpStatus(499, "Failed LLSD Response");
 
 struct HttpStatus
 {
@@ -307,6 +309,14 @@ struct HttpStatus
 				(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 = 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)
 		{
@@ -420,9 +430,6 @@ struct HttpStatus
 		return mDetails->mType;
 	}
 
-	// TODO: There must be a better way to do this.  Don't want to set these 
-	// values here since they increase the size of a structure that is already 
-	// being passed on the stack.  Consider my options
 	/// Returns an optional error message if one has been set.
 	///
 	std::string getMessage() const
-- 
cgit v1.2.3


From 735364038767694ea29d9b6a168410e6482cc9c2 Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Fri, 27 Mar 2015 17:00:02 -0700
Subject: first set of chnages from code review from Nat

---
 indra/llcorehttp/_httpoprequest.cpp    | 10 ++--
 indra/llcorehttp/_httpoprequest.h      |  5 +-
 indra/llcorehttp/_httppolicyglobal.cpp |  4 +-
 indra/llcorehttp/_httppolicyglobal.h   |  6 +--
 indra/llcorehttp/_httpservice.cpp      |  4 +-
 indra/llcorehttp/_httpservice.h        |  6 +--
 indra/llcorehttp/httpcommon.h          | 75 ++++++++++++++--------------
 indra/llcorehttp/httpoptions.cpp       |  8 +--
 indra/llcorehttp/httpoptions.h         | 90 ++++++++++++++++++++--------------
 indra/llcorehttp/httprequest.cpp       | 10 ++--
 indra/llcorehttp/httprequest.h         |  4 +-
 11 files changed, 118 insertions(+), 104 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 48e22468cd..5768fe5a90 100755
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -115,9 +115,8 @@ namespace LLCore
 {
 
 
-HttpOpRequest::HttpOpRequest(HttpRequest const * const request)
+HttpOpRequest::HttpOpRequest()
 	: HttpOperation(),
-	  mRequest(request),
 	  mProcFlags(0U),
 	  mReqMethod(HOR_GET),
 	  mReqBody(NULL),
@@ -490,13 +489,13 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 	long follow_redirect(1L);
 	long sslPeerV(0L);
 	long sslHostV(0L);
-	long dnsCacheTimeout(15L);
+    long dnsCacheTimeout(-1L);
 
 	if (mReqOptions)
 	{
 		follow_redirect = mReqOptions->getFollowRedirects() ? 1L : 0L;
-		sslPeerV = mReqOptions->getSSLVerifyHost() ? 0L : 1L;
-		sslHostV = mReqOptions->getSSLVerifyHost();
+		sslPeerV = mReqOptions->getSSLVerifyPeer() ? 1L : 0L;
+		sslHostV = mReqOptions->getSSLVerifyHost() ? 2L : 0L;
 		dnsCacheTimeout = mReqOptions->getDNSCacheTimeout();
 	}
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect);
@@ -516,7 +515,6 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, dnsCacheTimeout);
 	check_curl_easy_code(code, CURLOPT_DNS_CACHE_TIMEOUT);
 
-
 	if (gpolicy.mUseLLProxy)
 	{
 		// Use the viewer-based thread-safe API which has a
diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h
index 7a4b7c189e..e71d1d1edf 100755
--- a/indra/llcorehttp/_httpoprequest.h
+++ b/indra/llcorehttp/_httpoprequest.h
@@ -66,7 +66,7 @@ class HttpOptions;
 class HttpOpRequest : public HttpOperation
 {
 public:
-	HttpOpRequest(HttpRequest const * const request);
+	HttpOpRequest();
 
 protected:
 	virtual ~HttpOpRequest();							// Use release()
@@ -165,11 +165,10 @@ protected:
 	static const unsigned int	PF_SAVE_HEADERS = 0x00000002U;
 	static const unsigned int	PF_USE_RETRY_AFTER = 0x00000004U;
 
-	HttpRequest::policyCallback	mCallbackSSLVerify;
+	HttpRequest::policyCallback_t	mCallbackSSLVerify;
 
 public:
 	// Request data
-	HttpRequest const * const mRequest;
 	EMethod				mReqMethod;
 	std::string			mReqURL;
 	BufferArray *		mReqBody;
diff --git a/indra/llcorehttp/_httppolicyglobal.cpp b/indra/llcorehttp/_httppolicyglobal.cpp
index c4ef38a815..3d0df96ade 100755
--- a/indra/llcorehttp/_httppolicyglobal.cpp
+++ b/indra/llcorehttp/_httppolicyglobal.cpp
@@ -106,7 +106,7 @@ HttpStatus HttpPolicyGlobal::set(HttpRequest::EPolicyOption opt, const std::stri
 	return HttpStatus();
 }
 
-HttpStatus HttpPolicyGlobal::set(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback value)
+HttpStatus HttpPolicyGlobal::set(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback_t value)
 {
 	switch (opt)
 	{
@@ -169,7 +169,7 @@ HttpStatus HttpPolicyGlobal::get(HttpRequest::EPolicyOption opt, std::string * v
 }
 
 
-HttpStatus HttpPolicyGlobal::get(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback * value) const
+HttpStatus HttpPolicyGlobal::get(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback_t * value) const
 {
 	switch (opt)
 	{
diff --git a/indra/llcorehttp/_httppolicyglobal.h b/indra/llcorehttp/_httppolicyglobal.h
index 1696238814..e02da4386a 100755
--- a/indra/llcorehttp/_httppolicyglobal.h
+++ b/indra/llcorehttp/_httppolicyglobal.h
@@ -60,10 +60,10 @@ private:
 public:
 	HttpStatus set(HttpRequest::EPolicyOption opt, long value);
 	HttpStatus set(HttpRequest::EPolicyOption opt, const std::string & value);
-	HttpStatus set(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback 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 * value) const;
+	HttpStatus get(HttpRequest::EPolicyOption opt, HttpRequest::policyCallback_t * value) const;
 	
 public:
 	long				mConnectionLimit;
@@ -72,7 +72,7 @@ public:
 	std::string			mHttpProxy;
 	long				mTrace;
 	long				mUseLLProxy;
-	HttpRequest::policyCallback	mSslCtxCallback;
+	HttpRequest::policyCallback_t	mSslCtxCallback;
 };  // end class HttpPolicyGlobal
 
 }  // end namespace LLCore
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index 7b8aac35a8..252db78c89 100755
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -415,7 +415,7 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
 }
 
 HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
-	HttpRequest::policyCallback * ret_value)
+	HttpRequest::policyCallback_t * ret_value)
 {
 	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
 
@@ -520,7 +520,7 @@ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ
 }
 
 HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
-	HttpRequest::policyCallback value, HttpRequest::policyCallback * ret_value)
+	HttpRequest::policyCallback_t value, HttpRequest::policyCallback_t * ret_value)
 {
 	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
 
diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h
index 699a8eaa4f..ac518a5de7 100755
--- a/indra/llcorehttp/_httpservice.h
+++ b/indra/llcorehttp/_httpservice.h
@@ -209,15 +209,15 @@ protected:
 	HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
 							   std::string * ret_value);
 	HttpStatus getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t,
-								HttpRequest::policyCallback * ret_value);
+								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 value, 
-								HttpRequest::policyCallback * ret_value);
+								HttpRequest::policyCallback_t value, 
+								HttpRequest::policyCallback_t * ret_value);
 
 protected:
 	static const OptionDescriptor		sOptionDesc[HttpRequest::PO_LAST];
diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
index 64075f5f20..ada5c1bbe7 100755
--- a/indra/llcorehttp/httpcommon.h
+++ b/indra/llcorehttp/httpcommon.h
@@ -190,6 +190,7 @@
 #include "linden_common.h"		// Modifies curl/curl.h interfaces
 #include "boost/intrusive_ptr.hpp"
 #include "boost/shared_ptr.hpp"
+#include "boost/function.hpp"
 #include <string>
 
 namespace LLCore
@@ -294,50 +295,50 @@ struct HttpStatus
 	typedef unsigned short type_enum_t;
 	
 	HttpStatus()
-		{
-			mDetails = new Details(LLCORE, HE_SUCCESS);
-	}
+	{
+		mDetails = boost::shared_ptr<Details>(new Details(LLCORE, HE_SUCCESS));
+    }
 
 	HttpStatus(type_enum_t type, short status)
-		{
-			mDetails = new Details(type, status);
-		}
+	{
+        mDetails = boost::shared_ptr<Details>(new Details(type, status));
+	}
 	
 	HttpStatus(int http_status)
-		{
-			mDetails = new Details(http_status, 
-				(http_status >= 200 && http_status <= 299) ? HE_SUCCESS : HE_REPLY_ERROR);
-			llassert(http_status >= 100 && http_status <= 999);
-		}
+	{
+        mDetails = boost::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)
-		{
-			mDetails = 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;
-		}
+	{
+        mDetails = boost::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 = new Details(*rhs.mDetails);
-		}
+	{
+		mDetails = rhs.mDetails;
+	}
 
 	~HttpStatus()
-		{
-			delete mDetails;
-		}
+	{
+	}
 
 	HttpStatus & operator=(const HttpStatus & rhs)
-		{
-			// Don't care if lhs & rhs are the same object
-			mDetails->mType = rhs.mDetails->mType;
-			mDetails->mStatus = rhs.mDetails->mStatus;
-			mDetails->mMessage = rhs.mDetails->mMessage;
-			mDetails->mErrorData = rhs.mDetails->mErrorData;
-
-			return *this;
-		}
+	{
+        mDetails = rhs.mDetails;
+		return *this;
+	}
+
+    HttpStatus & clone(const HttpStatus &rhs)
+    {
+        mDetails = boost::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
@@ -365,8 +366,7 @@ struct HttpStatus
 	/// which will do the wrong thing in conditional expressions.
 	bool operator==(const HttpStatus & rhs) const
 	{
-		return (mDetails->mType == rhs.mDetails->mType) && 
-			(mDetails->mStatus == rhs.mDetails->mStatus);
+        return (*mDetails == *rhs.mDetails); 
 	}
 
 	bool operator!=(const HttpStatus & rhs) const
@@ -474,6 +474,10 @@ private:
 			mErrorData(rhs.mErrorData)
 		{}
 
+        bool operator == (const Details &rhs) const
+        {
+            return (mType == rhs.mType) && (mStatus == rhs.mStatus);
+        }
 
 		type_enum_t	mType;
 		short		mStatus;
@@ -481,8 +485,7 @@ private:
 		void *		mErrorData;
 	};
 
-	//boost::unique_ptr<Details>	mDetails;
-	Details * mDetails;
+    boost::shared_ptr<Details> mDetails;
 
 }; // end struct HttpStatus
 
diff --git a/indra/llcorehttp/httpoptions.cpp b/indra/llcorehttp/httpoptions.cpp
index 28c2c25e92..a4d08a80df 100755
--- a/indra/llcorehttp/httpoptions.cpp
+++ b/indra/llcorehttp/httpoptions.cpp
@@ -42,8 +42,8 @@ HttpOptions::HttpOptions() : RefCounted(true),
 	mUseRetryAfter(HTTP_USE_RETRY_AFTER_DEFAULT),
 	mFollowRedirects(false),
 	mVerifyPeer(false),
-	mVerifyHost(0),
-	mDNSCacheTimeout(15)
+	mVerifyHost(false),
+    mDNSCacheTimeout(-1L)
 {}
 
 
@@ -95,9 +95,9 @@ void HttpOptions::setSSLVerifyPeer(bool verify)
 	mVerifyPeer = verify;
 }
 
-void HttpOptions::setSSLVerifyHost(unsigned int type)
+void HttpOptions::setSSLVerifyHost(bool verify)
 {
-	mVerifyHost = llclamp<unsigned int>(type, 0, 2);
+	mVerifyHost = verify;
 }
 
 void HttpOptions::setDNSCacheTimeout(int timeout)
diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h
index 3b9ad9598b..765d2431bb 100755
--- a/indra/llcorehttp/httpoptions.h
+++ b/indra/llcorehttp/httpoptions.h
@@ -69,72 +69,86 @@ protected:
 	void operator=(const HttpOptions &);		// Not defined
 
 public:
+
 	// Default:   false
 	void				setWantHeaders(bool wanted);
 	bool				getWantHeaders() const
-		{
-			return mWantHeaders;
-		}
+	{
+		return mWantHeaders;
+	}
 
 	// Default:  0
 	void				setTrace(int long);
 	int					getTrace() const
-		{
-			return mTracing;
-		}
+	{
+		return mTracing;
+	}
 
 	// Default:  30
 	void				setTimeout(unsigned int timeout);
 	unsigned int		getTimeout() const
-		{
-			return mTimeout;
-		}
+	{
+		return mTimeout;
+	}
 
 	// Default:  0
 	void				setTransferTimeout(unsigned int timeout);
 	unsigned int		getTransferTimeout() const
-		{
-			return mTransferTimeout;
-		}
+	{
+		return mTransferTimeout;
+	}
 
+    /// Sets the number of retries on an LLCore::HTTPRequest before the 
+    /// request fails.
 	// Default:  8
 	void				setRetries(unsigned int retries);
 	unsigned int		getRetries() const
-		{
-			return mRetries;
-		}
+	{
+		return mRetries;
+	}
 
 	// Default:  true
 	void				setUseRetryAfter(bool use_retry);
 	bool				getUseRetryAfter() const
-		{
-			return mUseRetryAfter;
-		}
+	{
+		return mUseRetryAfter;
+	}
 
-	// Default: false
+    /// Instructs the LLCore::HTTPRequest to follow redirects 
+	/// Default: false
 	void				setFollowRedirects(bool follow_redirect);
 	bool				getFollowRedirects() const
-		{
-			return mFollowRedirects;
-		}
-
-	void				setSSLVerifyPeer(bool verify);
+	{
+		return mFollowRedirects;
+	}
+
+    /// Instructs the LLCore::HTTPRequest to verify that the exchanged security
+    /// certificate is authentic. 
+    /// Default: false
+    void				setSSLVerifyPeer(bool verify);
 	bool				getSSLVerifyPeer() const
-		{
-			return mVerifyPeer;
-		}
-
-	void				setSSLVerifyHost(unsigned int type);
-	unsigned int		getSSLVerifyHost() const
-		{
-			return mVerifyHost;
-		}
-
+	{
+		return mVerifyPeer;
+	}
+
+    /// 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;
+	}
+
+    /// 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 
+    /// name cache to never time out.
+    /// Default: -1
 	void				setDNSCacheTimeout(int timeout);
 	int					getDNSCacheTimeout() const
-		{
-			return mDNSCacheTimeout;
-		}
+	{
+		return mDNSCacheTimeout;
+	}
 	
 protected:
 	bool				mWantHeaders;
@@ -145,7 +159,7 @@ protected:
 	bool				mUseRetryAfter;
 	bool				mFollowRedirects;
 	bool				mVerifyPeer;
-	unsigned int		mVerifyHost;
+	bool        		mVerifyHost;
 	int					mDNSCacheTimeout;
 }; // end class HttpOptions
 
diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp
index 5f1ed3d43b..df8502b947 100755
--- a/indra/llcorehttp/httprequest.cpp
+++ b/indra/llcorehttp/httprequest.cpp
@@ -117,7 +117,7 @@ HttpStatus HttpRequest::setStaticPolicyOption(EPolicyOption opt, policy_t pclass
 	return HttpService::instanceOf()->setPolicyOption(opt, pclass, value, ret_value);
 }
 
-HttpStatus HttpRequest::setStaticPolicyOption(EPolicyOption opt, policy_t pclass, policyCallback value, policyCallback * ret_value)
+HttpStatus HttpRequest::setStaticPolicyOption(EPolicyOption opt, policy_t pclass, policyCallback_t value, policyCallback_t * ret_value)
 {
 	if (HttpService::RUNNING == HttpService::instanceOf()->getState())
 	{
@@ -204,7 +204,7 @@ HttpHandle HttpRequest::requestGet(policy_t policy_id,
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
 
-	HttpOpRequest * op = new HttpOpRequest(this);
+	HttpOpRequest * op = new HttpOpRequest();
 	if (! (status = op->setupGet(policy_id, priority, url, options, headers)))
 	{
 		op->release();
@@ -238,7 +238,7 @@ HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id,
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
 
-	HttpOpRequest * op = new HttpOpRequest(this);
+	HttpOpRequest * op = new HttpOpRequest();
 	if (! (status = op->setupGetByteRange(policy_id, priority, url, offset, len, options, headers)))
 	{
 		op->release();
@@ -271,7 +271,7 @@ HttpHandle HttpRequest::requestPost(policy_t policy_id,
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
 
-	HttpOpRequest * op = new HttpOpRequest(this);
+	HttpOpRequest * op = new HttpOpRequest();
 	if (! (status = op->setupPost(policy_id, priority, url, body, options, headers)))
 	{
 		op->release();
@@ -304,7 +304,7 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id,
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
 
-	HttpOpRequest * op = new HttpOpRequest(this);
+	HttpOpRequest * op = new HttpOpRequest();
 	if (! (status = op->setupPut(policy_id, priority, url, body, options, headers)))
 	{
 		op->release();
diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h
index 4cacb3a20b..f7ce82d412 100755
--- a/indra/llcorehttp/httprequest.h
+++ b/indra/llcorehttp/httprequest.h
@@ -237,7 +237,7 @@ public:
 
 	/// Prototype for policy based callbacks.  The callback methods will be executed
 	/// on the worker thread so no modifications should be made to the HttpHandler object.
-	typedef HttpStatus(*policyCallback)(const std::string &, HttpHandler const * const, void *);
+    typedef boost::function<HttpStatus(const std::string &, HttpHandler const * const, void *)> policyCallback_t;
 
 	/// Set a policy option for a global or class parameter at
 	/// startup time (prior to thread start).
@@ -255,7 +255,7 @@ public:
 	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 value, policyCallback * ret_value);;
+											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
-- 
cgit v1.2.3


From 0b02b36b651987d5d24c225fa9472e0d35803559 Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Fri, 27 Mar 2015 17:38:00 -0700
Subject: Remove test for size of HttpStatus

---
 indra/llcorehttp/tests/test_httpstatus.hpp | 36 +++++++++++++++---------------
 1 file changed, 18 insertions(+), 18 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/tests/test_httpstatus.hpp b/indra/llcorehttp/tests/test_httpstatus.hpp
index 5f8ed14c51..4502d32fe1 100755
--- a/indra/llcorehttp/tests/test_httpstatus.hpp
+++ b/indra/llcorehttp/tests/test_httpstatus.hpp
@@ -83,21 +83,21 @@ void HttpStatusTestObjectType::test<1>()
 }
 
 
-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));
-}
+// 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));
+// }
 
 
 template <> template <>
-void HttpStatusTestObjectType::test<3>()
+void HttpStatusTestObjectType::test<2>()
 {
 	set_test_name("HttpStatus valid status string conversion");
 	
@@ -124,7 +124,7 @@ void HttpStatusTestObjectType::test<3>()
 
 
 template <> template <>
-void HttpStatusTestObjectType::test<4>()
+void HttpStatusTestObjectType::test<3>()
 {
 	set_test_name("HttpStatus invalid status string conversion");
 	
@@ -145,7 +145,7 @@ void HttpStatusTestObjectType::test<4>()
 }
 
 template <> template <>
-void HttpStatusTestObjectType::test<5>()
+void HttpStatusTestObjectType::test<4>()
 {
 	set_test_name("HttpStatus equality/inequality testing");
 
@@ -164,7 +164,7 @@ void HttpStatusTestObjectType::test<5>()
 }
 
 template <> template <>
-void HttpStatusTestObjectType::test<6>()
+void HttpStatusTestObjectType::test<5>()
 {
 	set_test_name("HttpStatus basic HTTP status encoding");
 	
@@ -205,7 +205,7 @@ void HttpStatusTestObjectType::test<6>()
 }
 
 template <> template <>
-void HttpStatusTestObjectType::test<7>()
+void HttpStatusTestObjectType::test<6>()
 {
 	set_test_name("HttpStatus HTTP status text strings");
 
@@ -237,7 +237,7 @@ void HttpStatusTestObjectType::test<7>()
 
 
 template <> template <>
-void HttpStatusTestObjectType::test<8>()
+void HttpStatusTestObjectType::test<7>()
 {
 	set_test_name("HttpStatus toHex() nominal function");
 	
@@ -249,7 +249,7 @@ void HttpStatusTestObjectType::test<8>()
 
 
 template <> template <>
-void HttpStatusTestObjectType::test<9>()
+void HttpStatusTestObjectType::test<8>()
 {
 	set_test_name("HttpStatus toTerseString() nominal function");
 	
-- 
cgit v1.2.3


From edc1439bd633bdac183fbecc131edd55074b5442 Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Wed, 1 Apr 2015 16:37:00 -0700
Subject: Added AvatarNameCache as coroutine, with LLCore::HttpHandler to
 respond correctly to Event Pumps. Added get/setRequestURL() to
 LLCore::HttpResponse Removed URI from the HttpSDHandler.

---
 indra/llcorehttp/_httpoprequest.cpp |  4 +++-
 indra/llcorehttp/httpresponse.cpp   |  3 ++-
 indra/llcorehttp/httpresponse.h     | 11 +++++++++++
 3 files changed, 16 insertions(+), 2 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 5768fe5a90..7c2309b31d 100755
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -260,7 +260,9 @@ void HttpOpRequest::visitNotifier(HttpRequest * request)
 		response->setStatus(mStatus);
 		response->setBody(mReplyBody);
 		response->setHeaders(mReplyHeaders);
-		if (mReplyOffset || mReplyLength)
+        response->setRequestURL(mReqURL);
+
+        if (mReplyOffset || mReplyLength)
 		{
 			// Got an explicit offset/length in response
 			response->setRange(mReplyOffset, mReplyLength, mReplyFullLength);
diff --git a/indra/llcorehttp/httpresponse.cpp b/indra/llcorehttp/httpresponse.cpp
index 87e3426415..7d88f02527 100755
--- a/indra/llcorehttp/httpresponse.cpp
+++ b/indra/llcorehttp/httpresponse.cpp
@@ -41,7 +41,8 @@ HttpResponse::HttpResponse()
 	  mBufferArray(NULL),
 	  mHeaders(NULL),
 	  mRetries(0U),
-	  m503Retries(0U)
+	  m503Retries(0U),
+      mRequestUrl()
 {}
 
 
diff --git a/indra/llcorehttp/httpresponse.h b/indra/llcorehttp/httpresponse.h
index 39b582ff85..6c3b4da5e6 100755
--- a/indra/llcorehttp/httpresponse.h
+++ b/indra/llcorehttp/httpresponse.h
@@ -194,6 +194,16 @@ public:
 			return mStats;
 		}
 
+    void setRequestURL(const std::string &url)
+        {
+            mRequestUrl = url;
+        }
+
+    const std::string &getRequestURL() const
+        {
+            return mRequestUrl;
+        }
+
 
 protected:
 	// Response data here
@@ -206,6 +216,7 @@ protected:
 	std::string			mContentType;
 	unsigned int		mRetries;
 	unsigned int		m503Retries;
+    std::string         mRequestUrl;
 
 	TransferStats::ptr_t	mStats;
 };
-- 
cgit v1.2.3


From 1c91c8a106a78f2087a3fb4312e428a0128283b4 Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Wed, 8 Apr 2015 10:17:34 -0700
Subject: Adding weak pointer support. Event polling as a coroutine.
 (incomplete) Groundwork for canceling HttpCoroutineAdapter yields.

---
 indra/llcorehttp/httpcommon.h  | 1 +
 indra/llcorehttp/httprequest.h | 1 +
 2 files changed, 2 insertions(+)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
index ada5c1bbe7..898d3d47fa 100755
--- a/indra/llcorehttp/httpcommon.h
+++ b/indra/llcorehttp/httpcommon.h
@@ -190,6 +190,7 @@
 #include "linden_common.h"		// Modifies curl/curl.h interfaces
 #include "boost/intrusive_ptr.hpp"
 #include "boost/shared_ptr.hpp"
+#include "boost/weak_ptr.hpp"
 #include "boost/function.hpp"
 #include <string>
 
diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h
index f7ce82d412..6688f06eb5 100755
--- a/indra/llcorehttp/httprequest.h
+++ b/indra/llcorehttp/httprequest.h
@@ -98,6 +98,7 @@ public:
 	typedef unsigned int priority_t;
 	
 	typedef boost::shared_ptr<HttpRequest> ptr_t;
+    typedef boost::weak_ptr<HttpRequest>   wptr_t;
 public:
 	/// @name PolicyMethods
 	/// @{
-- 
cgit v1.2.3


From d0c85b6dd964164b6d92103ad65b5cd859197de2 Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Fri, 10 Apr 2015 17:23:58 -0700
Subject: Adding support for DELETE, PATCH and COPY

---
 indra/llcorehttp/_httpoprequest.cpp | 68 +++++++++++++++++++++++----
 indra/llcorehttp/_httpoprequest.h   | 26 +++++++++-
 indra/llcorehttp/httprequest.cpp    | 94 +++++++++++++++++++++++++++++++++++++
 indra/llcorehttp/httprequest.h      | 63 ++++++++++++++++++++++++-
 4 files changed, 240 insertions(+), 11 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 7c2309b31d..b1b05dc285 100755
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -357,6 +357,46 @@ HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id,
 }
 
 
+HttpStatus HttpOpRequest::setupDelete(HttpRequest::policy_t policy_id,
+    HttpRequest::priority_t priority,
+    const std::string & url,
+    HttpOptions * options,
+    HttpHeaders * headers)
+{
+    setupCommon(policy_id, priority, url, NULL, options, headers);
+    mReqMethod = HOR_DELETE;
+
+    return HttpStatus();
+}
+
+
+HttpStatus HttpOpRequest::setupPatch(HttpRequest::policy_t policy_id,
+    HttpRequest::priority_t priority,
+    const std::string & url,
+    BufferArray * body,
+    HttpOptions * options,
+    HttpHeaders * headers)
+{
+    setupCommon(policy_id, priority, url, body, options, headers);
+    mReqMethod = HOR_PATCH;
+
+    return HttpStatus();
+}
+
+
+HttpStatus HttpOpRequest::setupCopy(HttpRequest::policy_t policy_id,
+    HttpRequest::priority_t priority,
+    const std::string & url,
+    HttpOptions * options,
+    HttpHeaders * headers)
+{
+    setupCommon(policy_id, priority, url, NULL, options, headers);
+    mReqMethod = HOR_COPY;
+
+    return HttpStatus();
+}
+
+
 void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
 								HttpRequest::priority_t priority,
 								const std::string & url,
@@ -549,8 +589,6 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 	case HOR_GET:
 		code = curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1);
 		check_curl_easy_code(code, CURLOPT_HTTPGET);
-		mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
-		mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
 		break;
 		
 	case HOR_POST:
@@ -569,12 +607,14 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 			code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size);
 			check_curl_easy_code(code, CURLOPT_POSTFIELDSIZE);
 			mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
-			mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
-			mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
 		}
 		break;
 		
-	case HOR_PUT:
+    case HOR_PATCH:
+        code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "PATCH");
+        check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);
+        // fall through.  The rest is the same as PUT
+    case HOR_PUT:
 		{
 			code = curl_easy_setopt(mCurlHandle, CURLOPT_UPLOAD, 1);
 			check_curl_easy_code(code, CURLOPT_UPLOAD);
@@ -588,12 +628,19 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 			code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, (void *) NULL);
 			check_curl_easy_code(code, CURLOPT_POSTFIELDS);
 			mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
-			// *TODO: Should this be 'Keep-Alive' ?
-			mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
-			mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
 		}
 		break;
 		
+    case HOR_DELETE:
+        code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
+        check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);
+        break;
+
+    case HOR_COPY:
+        code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "COPY");
+        check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);
+        break;
+
 	default:
 		LL_ERRS(LOG_CORE) << "Invalid HTTP method in request:  "
 						  << int(mReqMethod)  << ".  Can't recover."
@@ -601,6 +648,11 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 		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)
 	{
diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h
index e71d1d1edf..ca40898a81 100755
--- a/indra/llcorehttp/_httpoprequest.h
+++ b/indra/llcorehttp/_httpoprequest.h
@@ -80,7 +80,10 @@ public:
 	{
 		HOR_GET,
 		HOR_POST,
-		HOR_PUT
+		HOR_PUT,
+        HOR_DELETE,
+        HOR_PATCH,
+        HOR_COPY
 	};
 	
 	virtual void stageFromRequest(HttpService *);
@@ -126,7 +129,26 @@ public:
 						HttpOptions * options,
 						HttpHeaders * headers);
 
-	// Internal method used to setup the libcurl options for a request.
+    HttpStatus setupDelete(HttpRequest::policy_t policy_id,
+                        HttpRequest::priority_t priority,
+                        const std::string & url,
+                        HttpOptions * options,
+                        HttpHeaders * headers);
+
+    HttpStatus setupPatch(HttpRequest::policy_t policy_id,
+                        HttpRequest::priority_t priority,
+                        const std::string & url,
+                        BufferArray * body,
+                        HttpOptions * options,
+                        HttpHeaders * headers);
+
+    HttpStatus setupCopy(HttpRequest::policy_t policy_id,
+                        HttpRequest::priority_t priority,
+                        const std::string & url,
+                        HttpOptions * options,
+                        HttpHeaders * 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
diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp
index df8502b947..d4c60a6f14 100755
--- a/indra/llcorehttp/httprequest.cpp
+++ b/indra/llcorehttp/httprequest.cpp
@@ -325,6 +325,100 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id,
 	return handle;
 }
 
+HttpHandle HttpRequest::requestDelete(policy_t policy_id,
+    priority_t priority,
+    const std::string & url,
+    HttpOptions * options,
+    HttpHeaders * headers,
+    HttpHandler * user_handler)
+{
+    HttpStatus status;
+    HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+    HttpOpRequest * op = new HttpOpRequest();
+    if (!(status = op->setupDelete(policy_id, priority, url, options, headers)))
+    {
+        op->release();
+        mLastReqStatus = status;
+        return handle;
+    }
+    op->setReplyPath(mReplyQueue, user_handler);
+    if (!(status = mRequestQueue->addOp(op)))			// transfers refcount
+    {
+        op->release();
+        mLastReqStatus = status;
+        return handle;
+    }
+
+    mLastReqStatus = status;
+    handle = static_cast<HttpHandle>(op);
+
+    return handle;
+}
+
+HttpHandle HttpRequest::requestPatch(policy_t policy_id,
+    priority_t priority,
+    const std::string & url,
+    BufferArray * body,
+    HttpOptions * options,
+    HttpHeaders * headers,
+    HttpHandler * user_handler)
+{
+    HttpStatus status;
+    HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+    HttpOpRequest * op = new HttpOpRequest();
+    if (!(status = op->setupPatch(policy_id, priority, url, body, options, headers)))
+    {
+        op->release();
+        mLastReqStatus = status;
+        return handle;
+    }
+    op->setReplyPath(mReplyQueue, user_handler);
+    if (!(status = mRequestQueue->addOp(op)))			// transfers refcount
+    {
+        op->release();
+        mLastReqStatus = status;
+        return handle;
+    }
+
+    mLastReqStatus = status;
+    handle = static_cast<HttpHandle>(op);
+
+    return handle;
+}
+
+HttpHandle HttpRequest::requestCopy(policy_t policy_id,
+    priority_t priority,
+    const std::string & url,
+    HttpOptions * options,
+    HttpHeaders * headers,
+    HttpHandler * user_handler)
+{
+    HttpStatus status;
+    HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+    HttpOpRequest * op = new HttpOpRequest();
+    if (!(status = op->setupCopy(policy_id, priority, url, options, headers)))
+    {
+        op->release();
+        mLastReqStatus = status;
+        return handle;
+    }
+    op->setReplyPath(mReplyQueue, user_handler);
+    if (!(status = mRequestQueue->addOp(op)))			// transfers refcount
+    {
+        op->release();
+        mLastReqStatus = status;
+        return handle;
+    }
+
+    mLastReqStatus = status;
+    handle = static_cast<HttpHandle>(op);
+
+    return handle;
+}
+
 
 HttpHandle HttpRequest::requestNoOp(HttpHandler * user_handler)
 {
diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h
index 6688f06eb5..e87a8b691a 100755
--- a/indra/llcorehttp/httprequest.h
+++ b/indra/llcorehttp/httprequest.h
@@ -478,7 +478,68 @@ public:
 						  HttpHandler * handler);
 
 
-	/// Queue a NoOp request.
+    /// Queue a full HTTP PUT.  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	priority		"
+    /// @param	url				"
+    /// @param	options			@see requestGet()K(optional)
+    /// @param	headers			"
+    /// @param	handler			"
+    /// @return					"
+    ///
+    HttpHandle requestDelete(policy_t policy_id,
+            priority_t priority,
+            const std::string & url,
+            HttpOptions * options,
+            HttpHeaders * headers,
+            HttpHandler * user_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.
+    ///
+    /// @param	policy_id		@see requestGet()
+    /// @param	priority		"
+    /// @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,
+            priority_t priority,
+            const std::string & url,
+            BufferArray * body,
+            HttpOptions * options,
+            HttpHeaders * headers,
+            HttpHandler * user_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.
+    ///
+    /// @param	policy_id		@see requestGet()
+    /// @param	priority		"
+    /// @param	url				"
+    /// @param	options			@see requestGet()K(optional)
+    /// @param	headers			"
+    /// @param	handler			"
+    /// @return					"
+    ///
+    HttpHandle requestCopy(policy_t policy_id,
+            priority_t priority,
+            const std::string & url,
+            HttpOptions * options,
+            HttpHeaders * headers,
+            HttpHandler * 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.
-- 
cgit v1.2.3


From da32de179d50d85cd815c545282d274d18c9dc3e Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Tue, 28 Apr 2015 09:39:47 -0700
Subject: Converting llmediaclient to new order. Temp disable llmediaclient's
 unit tests for link issues.

---
 indra/llcorehttp/httphandler.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/httphandler.h b/indra/llcorehttp/httphandler.h
index 740e986dec..7bc9096703 100755
--- a/indra/llcorehttp/httphandler.h
+++ b/indra/llcorehttp/httphandler.h
@@ -53,8 +53,9 @@ class HttpResponse;
 /// that is rarely a good idea.  Queued requests and replies keep
 /// a naked pointer to the handler and this can result in a
 /// dangling pointer if lifetimes aren't managed correctly.
-
-class HttpHandler
+///
+/// *TODO: public std::enable_shared_from_this<HttpHandler>
+class HttpHandler 
 {
 public:
 	virtual ~HttpHandler()
-- 
cgit v1.2.3


From c437a9c4ec865c38366c8057010d24311888ecb1 Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Wed, 20 May 2015 17:37:27 -0700
Subject: Webprofile converted to coroutine. Added JSON->LLSD converter Added
 corohandler for JSON data

---
 indra/llcorehttp/httpheaders.cpp | 18 ++++++++++++++++++
 indra/llcorehttp/httpheaders.h   |  6 +++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/httpheaders.cpp b/indra/llcorehttp/httpheaders.cpp
index 73c92c8f10..e03b1b080d 100755
--- a/indra/llcorehttp/httpheaders.cpp
+++ b/indra/llcorehttp/httpheaders.cpp
@@ -118,6 +118,24 @@ const std::string * HttpHeaders::find(const std::string &name) const
 	return NULL;
 }
 
+void HttpHeaders::remove(const char *name)
+{
+    remove(std::string(name));
+}
+
+void HttpHeaders::remove(const std::string &name)
+{
+    iterator iend(end());
+    for (iterator iter(begin()); iend != iter; ++iter)
+    {
+        if ((*iter).first == name)
+        {
+            mHeaders.erase(iter);
+            return;
+        }
+    }
+}
+
 
 // Standard Iterators
 HttpHeaders::iterator HttpHeaders::begin()
diff --git a/indra/llcorehttp/httpheaders.h b/indra/llcorehttp/httpheaders.h
index 940f92183c..51bd76a01d 100755
--- a/indra/llcorehttp/httpheaders.h
+++ b/indra/llcorehttp/httpheaders.h
@@ -146,13 +146,17 @@ public:
 	//					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
 		{
-- 
cgit v1.2.3


From 83543e556cba8753077c9f004bb0dc71b4509007 Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Wed, 27 May 2015 17:15:01 -0700
Subject: Memory leak (extra ref) in webprofile Viewer media routines to
 coroutine. Post with raw respons in llcorehttputil LLCore::Http added headers
 only option (applies only on get)

---
 indra/llcorehttp/_httpoprequest.cpp |  8 +++++++-
 indra/llcorehttp/httpoptions.cpp    | 29 +++++++++++++++++++----------
 indra/llcorehttp/httpoptions.h      | 10 ++++++++++
 3 files changed, 36 insertions(+), 11 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index b1b05dc285..3b6647882e 100755
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -532,6 +532,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 	long sslPeerV(0L);
 	long sslHostV(0L);
     long dnsCacheTimeout(-1L);
+    long nobody(0L);
 
 	if (mReqOptions)
 	{
@@ -539,6 +540,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 		sslPeerV = mReqOptions->getSSLVerifyPeer() ? 1L : 0L;
 		sslHostV = mReqOptions->getSSLVerifyHost() ? 2L : 0L;
 		dnsCacheTimeout = mReqOptions->getDNSCacheTimeout();
+        nobody = mReqOptions->getHeadersOnly() ? 1L : 0L;
 	}
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect);
 	check_curl_easy_code(code, CURLOPT_FOLLOWLOCATION);
@@ -548,6 +550,9 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, sslHostV);
 	check_curl_easy_code(code, CURLOPT_SSL_VERIFYHOST);
 
+    code = curl_easy_setopt(mCurlHandle, CURLOPT_NOBODY, nobody);
+    check_curl_easy_code(code, CURLOPT_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
@@ -587,7 +592,8 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 	switch (mReqMethod)
 	{
 	case HOR_GET:
-		code = curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1);
+        if (nobody == 0)
+            code = curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1);
 		check_curl_easy_code(code, CURLOPT_HTTPGET);
 		break;
 		
diff --git a/indra/llcorehttp/httpoptions.cpp b/indra/llcorehttp/httpoptions.cpp
index a4d08a80df..2b42bcaf6d 100755
--- a/indra/llcorehttp/httpoptions.cpp
+++ b/indra/llcorehttp/httpoptions.cpp
@@ -34,16 +34,17 @@ namespace LLCore
 
 
 HttpOptions::HttpOptions() : RefCounted(true),
-	mWantHeaders(false),
-	mTracing(HTTP_TRACE_OFF),
-	mTimeout(HTTP_REQUEST_TIMEOUT_DEFAULT),
-	mTransferTimeout(HTTP_REQUEST_XFER_TIMEOUT_DEFAULT),
-	mRetries(HTTP_RETRY_COUNT_DEFAULT),
-	mUseRetryAfter(HTTP_USE_RETRY_AFTER_DEFAULT),
-	mFollowRedirects(false),
-	mVerifyPeer(false),
-	mVerifyHost(false),
-    mDNSCacheTimeout(-1L)
+    mWantHeaders(false),
+    mTracing(HTTP_TRACE_OFF),
+    mTimeout(HTTP_REQUEST_TIMEOUT_DEFAULT),
+    mTransferTimeout(HTTP_REQUEST_XFER_TIMEOUT_DEFAULT),
+    mRetries(HTTP_RETRY_COUNT_DEFAULT),
+    mUseRetryAfter(HTTP_USE_RETRY_AFTER_DEFAULT),
+    mFollowRedirects(false),
+    mVerifyPeer(false),
+    mVerifyHost(false),
+    mDNSCacheTimeout(-1L),
+    mNoBody(false)
 {}
 
 
@@ -104,4 +105,12 @@ void HttpOptions::setDNSCacheTimeout(int timeout)
 {
 	mDNSCacheTimeout = timeout;
 }
+
+void HttpOptions::setHeadersOnly(bool nobody)
+{
+    mNoBody = nobody;
+    if (mNoBody)
+        setWantHeaders(true);
+}
+
 }   // end namespace LLCore
diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h
index 765d2431bb..21ecff85af 100755
--- a/indra/llcorehttp/httpoptions.h
+++ b/indra/llcorehttp/httpoptions.h
@@ -149,6 +149,15 @@ public:
 	{
 		return mDNSCacheTimeout;
 	}
+
+    /// Retrieve only the headers and status from the request. Setting this 
+    /// to true implies setWantHeaders(true) as well.
+    /// Default: false
+    void                setHeadersOnly(bool nobody);
+    bool                getHeadersOnly() const
+    {
+        return mNoBody;
+    }
 	
 protected:
 	bool				mWantHeaders;
@@ -161,6 +170,7 @@ protected:
 	bool				mVerifyPeer;
 	bool        		mVerifyHost;
 	int					mDNSCacheTimeout;
+    bool                mNoBody;
 }; // end class HttpOptions
 
 
-- 
cgit v1.2.3


From 68da6fa846fee1e3c5fb478945ef54f83a86aacd Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Mon, 1 Jun 2015 16:54:53 -0700
Subject: Set follow redirects so that the default is the same when no options
 are are specified and when follow redirects is not specified on the options
 object.

---
 indra/llcorehttp/httpoptions.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/httpoptions.cpp b/indra/llcorehttp/httpoptions.cpp
index 2b42bcaf6d..3459a37aff 100755
--- a/indra/llcorehttp/httpoptions.cpp
+++ b/indra/llcorehttp/httpoptions.cpp
@@ -40,7 +40,7 @@ HttpOptions::HttpOptions() : RefCounted(true),
     mTransferTimeout(HTTP_REQUEST_XFER_TIMEOUT_DEFAULT),
     mRetries(HTTP_RETRY_COUNT_DEFAULT),
     mUseRetryAfter(HTTP_USE_RETRY_AFTER_DEFAULT),
-    mFollowRedirects(false),
+    mFollowRedirects(true),
     mVerifyPeer(false),
     mVerifyHost(false),
     mDNSCacheTimeout(-1L),
-- 
cgit v1.2.3


From daf4d167b66c6124b96dee585b43060e2ea06b42 Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Fri, 5 Jun 2015 15:19:24 -0700
Subject: Added a seek method to LLCore::Http for data rewind. A couple of
 minor changes to merchant out box in hopes that the would fix the issues.

---
 indra/llcorehttp/_httpoprequest.cpp | 35 +++++++++++++++++++++++++++++++++++
 indra/llcorehttp/_httpoprequest.h   |  1 +
 2 files changed, 36 insertions(+)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 3b6647882e..3a51f898ab 100755
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -515,6 +515,10 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 	check_curl_easy_code(code, CURLOPT_READFUNCTION);
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, this);
 	check_curl_easy_code(code, CURLOPT_READDATA);
+    code = curl_easy_setopt(mCurlHandle, CURLOPT_SEEKFUNCTION, seekCallback);
+    check_curl_easy_code(code, CURLOPT_SEEKFUNCTION);
+    code = curl_easy_setopt(mCurlHandle, CURLOPT_SEEKDATA, this);
+    check_curl_easy_code(code, CURLOPT_SEEKDATA);
 
 	code = curl_easy_setopt(mCurlHandle, CURLOPT_COOKIEFILE, "");
 	check_curl_easy_code(code, CURLOPT_COOKIEFILE);
@@ -819,6 +823,37 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void
 	return read_size;
 }
 
+
+int HttpOpRequest::seekCallback(void *userdata, curl_off_t offset, int origin)
+{
+    HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata));
+
+    if (!op->mReqBody)
+    {
+        return 0;
+    }
+
+    size_t newPos = 0;
+    if (origin == SEEK_SET)
+        newPos = offset;
+    else if (origin == SEEK_END)
+        newPos = static_cast<curl_off_t>(op->mReqBody->size()) + offset;
+    else if (origin == SEEK_CUR)
+        newPos = static_cast<curl_off_t>(op->mCurlBodyPos) + offset;
+    else
+        return 2;
+
+    if ((newPos < 0) || (newPos >= op->mReqBody->size()))
+    {
+        LL_WARNS(LOG_CORE) << "Attempt to seek to position outside post body." << LL_ENDL;
+        return 2;
+    }
+
+    op->mCurlBodyPos = (size_t)newPos;
+
+    return 0;
+}
+
 		
 size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, void * userdata)
 {
diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h
index ca40898a81..b1bb101bea 100755
--- a/indra/llcorehttp/_httpoprequest.h
+++ b/indra/llcorehttp/_httpoprequest.h
@@ -175,6 +175,7 @@ protected:
 	//
 	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);
-- 
cgit v1.2.3


From dde75d76210c9e4df0516b89f8f199fe081a5e87 Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Fri, 5 Jun 2015 16:11:27 -0700
Subject: Mac builds are very picking about testing an unsigned for < 0

---
 indra/llcorehttp/_httpoprequest.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 3a51f898ab..503c04dfa7 100755
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -843,7 +843,7 @@ int HttpOpRequest::seekCallback(void *userdata, curl_off_t offset, int origin)
     else
         return 2;
 
-    if ((newPos < 0) || (newPos >= op->mReqBody->size()))
+    if (newPos >= op->mReqBody->size())
     {
         LL_WARNS(LOG_CORE) << "Attempt to seek to position outside post body." << LL_ENDL;
         return 2;
-- 
cgit v1.2.3


From 97033975510d0514821f943287d91708eefa9c92 Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Wed, 24 Jun 2015 10:10:22 -0700
Subject: MAINT-5295 Remove POSTFIELDS from PUT operation.

---
 indra/llcorehttp/_httpoprequest.cpp | 2 --
 1 file changed, 2 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 503c04dfa7..799587ff22 100755
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -635,8 +635,6 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 			}
 			code = curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size);
 			check_curl_easy_code(code, CURLOPT_INFILESIZE);
-			code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, (void *) NULL);
-			check_curl_easy_code(code, CURLOPT_POSTFIELDS);
 			mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
 		}
 		break;
-- 
cgit v1.2.3


From 76cb1fcf0b5b9d8415e2517c482bab0c6c6602fb Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 29 Jun 2015 15:37:32 -0400
Subject: MAINT-4952: Add IntrusivePtr wrapper for boost::intrusive_ptr. For a
 RefCounted subclass T, boost::intrusive_ptr<T> must be instantiated as
 boost::intrusive_ptr<T>(raw ptr, false) to avoid immortal instances.
 Forgetting that final bool parameter is both easy and extremely hard to spot
 with desk checking or code review. IntrusivePtr<T> provides constructors that
 Do The Right Thing, so we can typedef a subclass T's ptr_t to IntrusivePtr<T>
 rather than directly to boost::intrusive_ptr<T>.

---
 indra/llcorehttp/_refcounted.h | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/_refcounted.h b/indra/llcorehttp/_refcounted.h
index cd16e2e2b4..7f713f2298 100755
--- a/indra/llcorehttp/_refcounted.h
+++ b/indra/llcorehttp/_refcounted.h
@@ -32,6 +32,7 @@
 
 #include "fix_macros.h"
 #include <boost/thread.hpp>
+#include <boost/intrusive_ptr.hpp>
 
 #include "llapr.h"
 
@@ -120,6 +121,24 @@ inline void RefCounted::destroySelf()
 	delete this;
 }
 
+/**
+ * boost::intrusive_ptr may be used to manage RefCounted classes.
+ * Unfortunately RefCounted and boost::intrusive_ptr use different conventions
+ * for the initial refcount value. To avoid leaky (immortal) objects, you
+ * should really construct boost::intrusive_ptr<RefCounted*>(rawptr, false).
+ * IntrusivePtr<T> encapsulates that for you.
+ */
+template <typename T>
+struct IntrusivePtr: public boost::intrusive_ptr<T>
+{
+	IntrusivePtr():
+		boost::intrusive_ptr<T>()
+	{}
+	IntrusivePtr(T* p):
+		boost::intrusive_ptr<T>(p, false)
+	{}
+};
+
 inline void intrusive_ptr_add_ref(RefCounted* p)
 {
 	p->addRef();
-- 
cgit v1.2.3


From 80d17b2dd9cdd7a9445480fdb0e12774396751eb Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 29 Jun 2015 17:19:51 -0400
Subject: MAINT-4952: Use IntrusivePtr for BufferArray,HttpHeaders,HttpOptions.
 Specifically, change the ptr_t typedefs for these LLCore classes to use
 IntrusivePtr rather than directly using boost::intrusive_ptr. This allows us
 to use a simple ptr_t(raw ptr) constructor rather than having to remember to
 code ptr_t(raw ptr, false) everywhere. In fact, the latter form is now
 invalid: remove the now-extraneous 'false' constructor parameters.

---
 indra/llcorehttp/bufferarray.h | 2 +-
 indra/llcorehttp/httpheaders.h | 2 +-
 indra/llcorehttp/httpoptions.h | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra/llcorehttp')

diff --git a/indra/llcorehttp/bufferarray.h b/indra/llcorehttp/bufferarray.h
index 076f341736..320adf2b8b 100755
--- a/indra/llcorehttp/bufferarray.h
+++ b/indra/llcorehttp/bufferarray.h
@@ -74,7 +74,7 @@ public:
 	
 	BufferArray();
 
-	typedef boost::intrusive_ptr<BufferArray> ptr_t;
+	typedef LLCoreInt::IntrusivePtr<BufferArray> ptr_t;
 
 protected:
 	virtual ~BufferArray();						// Use release()
diff --git a/indra/llcorehttp/httpheaders.h b/indra/llcorehttp/httpheaders.h
index 51bd76a01d..8f14568fa3 100755
--- a/indra/llcorehttp/httpheaders.h
+++ b/indra/llcorehttp/httpheaders.h
@@ -92,7 +92,7 @@ public:
 	/// the instance.
 	HttpHeaders();
 
-	typedef boost::intrusive_ptr<HttpHeaders> ptr_t;
+	typedef LLCoreInt::IntrusivePtr<HttpHeaders> ptr_t;
 protected:
 	virtual ~HttpHeaders();						// Use release()
 
diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h
index 21ecff85af..2fe05a65ff 100755
--- a/indra/llcorehttp/httpoptions.h
+++ b/indra/llcorehttp/httpoptions.h
@@ -60,7 +60,7 @@ class HttpOptions : public LLCoreInt::RefCounted
 public:
 	HttpOptions();
 
-	typedef boost::intrusive_ptr<HttpOptions> ptr_t;
+	typedef LLCoreInt::IntrusivePtr<HttpOptions> ptr_t;
 
 protected:
 	virtual ~HttpOptions();						// Use release()
-- 
cgit v1.2.3