diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index 12ecbb36eb8ea85862fe1e723daaa1c27ffc9bf0..345b76d1a1940d95c97432707d16fd4b586ce55d 100644
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -31,7 +31,7 @@
  */
 
 #include "linden_common.h"
-
+#include <openssl/x509_vfy.h>
 #include "llhttpclient.h"
 
 #include "llassetstorage.h"
@@ -46,7 +46,10 @@
 #include "message.h"
 #include <curl/curl.h>
 
+
 const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
+LLURLRequest::SSLCertVerifyCallback LLHTTPClient::mCertVerifyCallback = NULL;
+
 ////////////////////////////////////////////////////////////////////////////
 
 // Responder class moved to LLCurl
@@ -206,13 +209,19 @@ namespace
 	LLPumpIO* theClientPump = NULL;
 }
 
+void LLHTTPClient::setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback)
+{
+	LLHTTPClient::mCertVerifyCallback = callback;
+}
+
 static void request(
 	const std::string& url,
 	LLURLRequest::ERequestAction method,
 	Injector* body_injector,
 	LLCurl::ResponderPtr responder,
 	const F32 timeout = HTTP_REQUEST_EXPIRY_SECS,
-	const LLSD& headers = LLSD())
+	const LLSD& headers = LLSD()
+    )
 {
 	if (!LLHTTPClient::hasPump())
 	{
@@ -222,7 +231,7 @@ static void request(
 	LLPumpIO::chain_t chain;
 
 	LLURLRequest* req = new LLURLRequest(method, url);
-	req->checkRootCertificate(true);
+	req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
 
 	
 	lldebugs << LLURLRequest::actionAsVerb(method) << " " << url << " "
@@ -417,7 +426,6 @@ static LLSD blocking_request(
 	std::string body_str;
 	
 	// other request method checks root cert first, we skip?
-	//req->checkRootCertificate(true);
 	
 	// * Set curl handle options
 	curl_easy_setopt(curlp, CURLOPT_NOSIGNAL, 1);	// don't use SIGALRM for timeouts
diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h
index 3d0646e5fe9b53b436f5fc9c7166ca47845b767d..8afbc9e0fc274f84dfbb5bd85c9b6694d4dfe3fc 100644
--- a/indra/llmessage/llhttpclient.h
+++ b/indra/llmessage/llhttpclient.h
@@ -40,7 +40,8 @@
 #include <string>
 
 #include <boost/intrusive_ptr.hpp>
-
+#include <openssl/x509_vfy.h>
+#include "llurlrequest.h"
 #include "llassettype.h"
 #include "llcurl.h"
 #include "lliopipe.h"
@@ -61,6 +62,7 @@ class LLHTTPClient
 	typedef LLCurl::Responder Responder;
 	typedef LLCurl::ResponderPtr ResponderPtr;
 
+	
 	/** @name non-blocking API */
 	//@{
 	static void head(
@@ -155,7 +157,12 @@ class LLHTTPClient
 	static void setPump(LLPumpIO& pump);
 		///< must be called before any of the above calls are made
 	static bool hasPump();
-		///< for testing
+
+	static void setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback);
+	static  LLURLRequest::SSLCertVerifyCallback getCertVerifyCallback() { return mCertVerifyCallback; }
+
+protected:
+	static LLURLRequest::SSLCertVerifyCallback mCertVerifyCallback;
 };
 
 #endif // LL_LLHTTPCLIENT_H
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index 81b7761ed5fdec3b2263ab3c6c6da23d2f471f31..752be49663db2858ee4c26fd2b0de160770eb8fb 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -36,7 +36,8 @@
 #include "llurlrequest.h"
 
 #include <algorithm>
-
+#include <openssl/x509_vfy.h>
+#include <openssl/ssl.h>
 #include "llcurl.h"
 #include "llioutil.h"
 #include "llmemtype.h"
@@ -56,6 +57,8 @@ const std::string CONTEXT_TRANSFERED_BYTES("transfered_bytes");
 
 static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user);
 
+
+
 /**
  * class LLURLRequestDetail
  */
@@ -72,6 +75,8 @@ class LLURLRequestDetail
 	U32 mBodyLimit;
 	S32 mByteAccumulator;
 	bool mIsBodyLimitSet;
+	LLURLRequest::SSLCertVerifyCallback mSSLVerifyCallback;
+	void * mSSLVerifyParam;
 };
 
 LLURLRequestDetail::LLURLRequestDetail() :
@@ -80,7 +85,8 @@ LLURLRequestDetail::LLURLRequestDetail() :
 	mLastRead(NULL),
 	mBodyLimit(0),
 	mByteAccumulator(0),
-	mIsBodyLimitSet(false)
+	mIsBodyLimitSet(false),
+    mSSLVerifyCallback(NULL)
 {
 	LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
 	mCurlRequest = new LLCurlEasyRequest();
@@ -94,6 +100,37 @@ LLURLRequestDetail::~LLURLRequestDetail()
 	mLastRead = NULL;
 }
 
+void LLURLRequest::setSSLVerifyCallback(SSLCertVerifyCallback callback, void *param)
+{
+	mDetail->mSSLVerifyCallback = callback;
+	mDetail->mSSLVerifyParam = param;
+	mDetail->mCurlRequest->setSSLCtxCallback(LLURLRequest::_sslCtxCallback, (void *)this);
+	mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, true);
+	mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, 2);	
+}
+
+
+// _sslCtxFunction
+// Callback function called when an SSL Context is created via CURL
+// used to configure the context for custom cert validation
+
+CURLcode LLURLRequest::_sslCtxCallback(CURL * curl, void *sslctx, void *param)
+{	
+	LLURLRequest *req = (LLURLRequest *)param;
+	if(req == NULL || req->mDetail->mSSLVerifyCallback == NULL)
+	{
+		SSL_CTX_set_cert_verify_callback((SSL_CTX *)sslctx, NULL, NULL);
+		return CURLE_OK;
+	}
+	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, req->mDetail->mSSLVerifyCallback, (void *)req);
+	// the calls are void
+	return CURLE_OK;
+	
+}
 
 /**
  * class LLURLRequest
@@ -148,6 +185,11 @@ void LLURLRequest::setURL(const std::string& url)
 	mDetail->mURL = url;
 }
 
+std::string LLURLRequest::getURL() const
+{
+	return mDetail->mURL;
+}
+
 void LLURLRequest::addHeader(const char* header)
 {
 	LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
@@ -160,12 +202,6 @@ void LLURLRequest::setBodyLimit(U32 size)
 	mDetail->mIsBodyLimitSet = true;
 }
 
-void LLURLRequest::checkRootCertificate(bool check)
-{
-	mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, (check? TRUE : FALSE));
-	mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, "");
-}
-
 void LLURLRequest::setCallback(LLURLRequestComplete* callback)
 {
 	LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h
index cb3c46644062cbb26530cc4fbc4e13c90a99309e..69fd22e5928ebaba6980fad8e0547cf5de491c50 100644
--- a/indra/llmessage/llurlrequest.h
+++ b/indra/llmessage/llurlrequest.h
@@ -44,6 +44,8 @@
 #include "lliopipe.h"
 #include "llchainio.h"
 #include "llerror.h"
+#include <openssl/x509_vfy.h>
+#include "llcurl.h"
 
 
 extern const std::string CONTEXT_REQUEST;
@@ -72,6 +74,8 @@ class LLURLRequest : public LLIOPipe
 {
 	LOG_CLASS(LLURLRequest);
 public:
+
+	typedef int (* SSLCertVerifyCallback)(X509_STORE_CTX *ctx, void *param);
 	/** 
 	 * @brief This enumeration is for specifying the type of request.
 	 */
@@ -125,7 +129,7 @@ class LLURLRequest : public LLIOPipe
 	 * 
 	 */
 	void setURL(const std::string& url);
-
+	std::string getURL() const;
 	/** 
 	 * @brief Add a header to the http post.
 	 *
@@ -143,8 +147,9 @@ class LLURLRequest : public LLIOPipe
 	 * Set whether request will check that remote server
 	 * certificates are signed by a known root CA when using HTTPS.
 	 */
-	void checkRootCertificate(bool check);
+	void setSSLVerifyCallback(SSLCertVerifyCallback callback, void * param);
 
+	
 	/**
 	 * @brief Return at most size bytes of body.
 	 *
@@ -189,6 +194,7 @@ class LLURLRequest : public LLIOPipe
 	 * @brief Give this pipe a chance to handle a generated error
 	 */
 	virtual EStatus handleError(EStatus status, LLPumpIO* pump);
+
 	
 protected:
 	/** 
@@ -217,6 +223,8 @@ class LLURLRequest : public LLIOPipe
 	 S32 mRequestTransferedBytes;
 	 S32 mResponseTransferedBytes;
 
+	static CURLcode _sslCtxCallback(CURL * curl, void *sslctx, void *param);
+	
 private:
 	/** 
 	 * @brief Initialize the object. Called during construction.
@@ -364,62 +372,6 @@ class LLURLRequestComplete : public LLIOPipe
 };
 
 
-/** 
- * @class LLURLRequestClientFactory
- * @brief Template class to build url request based client chains 
- *
- * This class eases construction of a basic sd rpc client. Here is an
- * example of it's use:
- * <code>
- *  class LLUsefulService : public LLService { ... }<br>
- *  LLService::registerCreator(<br>
- *    "useful",<br>
- *    LLService::creator_t(new LLURLRequestClientFactory<LLUsefulService>))<br>
- * </code>
- *
- * This class should work, but I never got around to using/testing it.
- *
- */
-#if 0
-template<class Client>
-class LLURLRequestClientFactory : public LLChainIOFactory
-{
-public:
-	LLURLRequestClientFactory(LLURLRequest::ERequestAction action) {}
-	LLURLRequestClientFactory(
-		LLURLRequest::ERequestAction action,
-		const std::string& fixed_url) :
-		mAction(action),
-		mURL(fixed_url)
-	{
-	}
-	virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
-	{
-		lldebugs << "LLURLRequestClientFactory::build" << llendl;
-		LLIOPipe::ptr_t service(new Client);
-		chain.push_back(service);
-		LLURLRequest* http(new LLURLRequest(mAction));
-		LLIOPipe::ptr_t http_pipe(http);
-		// *FIX: how do we know the content type?
-		//http->addHeader("Content-Type: text/llsd");
-		if(mURL.empty())
-		{
-			chain.push_back(LLIOPipe::ptr_t(new LLContextURLExtractor(http)));
-		}
-		else
-		{
-			http->setURL(mURL);
-		}
-		chain.push_back(http_pipe);
-		chain.push_back(service);
-		return true;
-	}
-
-protected:
-	LLURLRequest::ERequestAction mAction;
-	std::string mURL;
-};
-#endif
 
 /**
  * External constants
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index d1e33fa91a6cdf49aeae4ef2df2e66246398a784..187038ab15ec979c6b0ce3ccb984aec6cbdafb24 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -621,6 +621,7 @@ bool LLAppViewer::init()
 
     initThreads();
     initializeSecHandler();
+	LLHTTPClient::setCertVerifyCallback(secapiSSLCertVerifyCallback);
     writeSystemInfo();
 
 	// Build a string representing the current version number.
diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp
index 70c247c2de7a752d3e9257d58f1bfa8825764f1a..26bdfd19da70a6dfb71704e9dacc81f5d5688ba6 100644
--- a/indra/newview/llsecapi.cpp
+++ b/indra/newview/llsecapi.cpp
@@ -36,6 +36,8 @@
 #include "llsechandler_basic.h"
 #include <openssl/evp.h>
 #include <map>
+#include "llhttpclient.h"
+
 
 
 std::map<std::string, LLPointer<LLSecAPIHandler> > gHandlerMap;
@@ -79,7 +81,42 @@ std::ostream& operator <<(std::ostream& s, const LLCredential& cred)
 	return s << (std::string)cred;
 }
 
+	
+// secapiSSLCertVerifyCallback
+// basic callback called when a cert verification is requested.
+// calls SECAPI to validate the context
+// not initialized in the above initialization function, due to unit tests
+// see llappviewer
 
+int secapiSSLCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
+{
+	LLURLRequest *req = (LLURLRequest *)param;
+	LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore("");
+	LLPointer<LLCertificateChain> chain = gSecAPIHandler->getCertificateChain(ctx);
+	LLSD validation_params = LLSD::emptyMap();
+	LLURI uri(req->getURL());
+	validation_params[CERT_HOSTNAME] = uri.hostName();
+	try
+	{
+		chain->validate(VALIDATION_POLICY_SSL, store, validation_params);
+	}
+	catch (LLCertValidationTrustException& cert_exception)
+	{
+		LL_WARNS("AppInit") << "Cert not trusted: " << cert_exception.getMessage() << LL_ENDL;
+		return 0;		
+	}
+	catch (LLCertException& cert_exception)
+	{
+		LL_WARNS("AppInit") << "cert error " << cert_exception.getMessage() << LL_ENDL;
+		return 0;
+	}
+	catch (...)
+	{
+		LL_WARNS("AppInit") << "cert error " << LL_ENDL;
+		return 0;
+	}
+	return 1;
+}
 
 LLSD LLCredential::getLoginParams()
 {
diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h
index 6fd12c044af7b0fbcc756c6a35ce7e2ecd34ac2e..d3fb3c4c076a68a1bf1080b0acc61261509eda8a 100644
--- a/indra/newview/llsecapi.h
+++ b/indra/newview/llsecapi.h
@@ -474,4 +474,8 @@ void registerSecHandler(const std::string& handler_type,
 
 extern LLPointer<LLSecAPIHandler> gSecAPIHandler;
 
+
+int secapiSSLCertVerifyCallback(X509_STORE_CTX *ctx, void *param);
+
+
 #endif // LL_SECAPI_H
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 118d7f8d08d603809a4bee3a4844f07735f49f1e..ed70be7b9fd9e15ec93edfe316ae67214587903f 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -132,10 +132,11 @@ void LLWorld::destroyClass()
 LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
 {
 	LLMemType mt(LLMemType::MTYPE_REGIONS);
-	
+	llinfos << "Add region with handle: " << region_handle << " on host " << host << llendl;
 	LLViewerRegion *regionp = getRegionFromHandle(region_handle);
 	if (regionp)
 	{
+		llinfos << "Region exists, removing it " << llendl;
 		LLHost old_host = regionp->getHost();
 		// region already exists!
 		if (host == old_host && regionp->isAlive())